Add tests for SearchService
Test cases related to current issues or points that need confirmation after Lucene update.
This commit is contained in:
+69
-2
@@ -1,6 +1,7 @@
|
||||
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -412,7 +413,7 @@ public class AnalyzerFactoryTestCase {
|
||||
* Case using test resource name
|
||||
*/
|
||||
|
||||
// title
|
||||
// Semicolon , comma and hyphen.
|
||||
String query = "Bach: Goldberg Variations, BWV 988 - Aria";
|
||||
List<String> terms = toTermString(query);
|
||||
assertEquals(6, terms.size());
|
||||
@@ -423,7 +424,7 @@ public class AnalyzerFactoryTestCase {
|
||||
assertEquals("988", terms.get(4));
|
||||
assertEquals("aria", terms.get(5));
|
||||
|
||||
// artist
|
||||
// Underbars around words, ascii and semicolon.
|
||||
query = "_ID3_ARTIST_ Céline Frisch: Café Zimmermann";
|
||||
terms = toTermString(query);
|
||||
assertEquals(5, terms.size());
|
||||
@@ -433,6 +434,72 @@ public class AnalyzerFactoryTestCase {
|
||||
assertEquals("cafe", terms.get(3));
|
||||
assertEquals("zimmermann", terms.get(4));
|
||||
|
||||
// Underbars around words and slashes
|
||||
query = "_ID3_ARTIST_ Sarah Walker/Nash Ensemble";
|
||||
terms = toTermString(query);
|
||||
assertEquals(5, terms.size());
|
||||
assertEquals("id3_artist", terms.get(0));
|
||||
assertEquals("sarah", terms.get(1));
|
||||
assertEquals("walker", terms.get(2));
|
||||
assertEquals("nash", terms.get(3));
|
||||
assertEquals("ensemble", terms.get(4));
|
||||
|
||||
// space
|
||||
assertEquals(asList("abc", "def"), toTermString(" ABC DEF "));
|
||||
assertEquals(asList("abc1", "def"), toTermString(" ABC1 DEF "));
|
||||
|
||||
// trim and delimiter
|
||||
assertEquals(asList("abc", "def"), toTermString("+ABC+DEF+"));
|
||||
assertEquals(asList("abc", "def"), toTermString("|ABC|DEF|"));
|
||||
assertEquals(asList("abc", "def"), toTermString("!ABC!DEF!"));
|
||||
assertEquals(asList("abc", "def"), toTermString("(ABC(DEF("));
|
||||
assertEquals(asList("abc", "def"), toTermString(")ABC)DEF)"));
|
||||
assertEquals(asList("abc", "def"), toTermString("{ABC{DEF{"));
|
||||
assertEquals(asList("abc", "def"), toTermString("}ABC}DEF}"));
|
||||
assertEquals(asList("abc", "def"), toTermString("[ABC[DEF["));
|
||||
assertEquals(asList("abc", "def"), toTermString("]ABC]DEF]"));
|
||||
assertEquals(asList("abc", "def"), toTermString("^ABC^DEF^"));
|
||||
assertEquals(asList("abc", "def"), toTermString("\\ABC\\DEF\\"));
|
||||
assertEquals(asList("abc", "def"), toTermString("\"ABC\"DEF\""));
|
||||
assertEquals(asList("abc", "def"), toTermString("~ABC~DEF~"));
|
||||
assertEquals(asList("abc", "def"), toTermString("*ABC*DEF*"));
|
||||
assertEquals(asList("abc", "def"), toTermString("?ABC?DEF?"));
|
||||
assertEquals(asList("abc", "def"), toTermString(":ABC:DEF:"));
|
||||
assertEquals(asList("abc", "def"), toTermString("-ABC-DEF-"));
|
||||
assertEquals(asList("abc", "def"), toTermString("/ABC/DEF/"));
|
||||
assertEquals(asList("abc", "def"), toTermString("_ABC_DEF_"));
|
||||
assertEquals(asList("abc", "def"), toTermString(",ABC,DEF,"));
|
||||
assertEquals(asList("abc.def"), toTermString(".ABC.DEF."));
|
||||
assertEquals(asList("abc&def"), toTermString("&ABC&DEF&"));
|
||||
assertEquals(asList("abc@def"), toTermString("@ABC@DEF@"));
|
||||
assertEquals(asList("abc'def"), toTermString("'ABC'DEF'"));
|
||||
|
||||
// trim and delimiter and number
|
||||
assertEquals(asList("abc1", "def"), toTermString("+ABC1+DEF+"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("|ABC1|DEF|"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("!ABC1!DEF!"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("(ABC1(DEF("));
|
||||
assertEquals(asList("abc1", "def"), toTermString(")ABC1)DEF)"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("{ABC1{DEF{"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("}ABC1}DEF}"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("[ABC1[DEF["));
|
||||
assertEquals(asList("abc1", "def"), toTermString("]ABC1]DEF]"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("^ABC1^DEF^"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("\\ABC1\\DEF\\"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("\"ABC1\"DEF\""));
|
||||
assertEquals(asList("abc1", "def"), toTermString("~ABC1~DEF~"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("*ABC1*DEF*"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("?ABC1?DEF?"));
|
||||
assertEquals(asList("abc1", "def"), toTermString(":ABC1:DEF:"));
|
||||
assertEquals(asList("abc1,def"), toTermString(",ABC1,DEF,"));
|
||||
assertEquals(asList("abc1-def"), toTermString("-ABC1-DEF-"));
|
||||
assertEquals(asList("abc1/def"), toTermString("/ABC1/DEF/"));
|
||||
assertEquals(asList("abc1_def"), toTermString("_ABC1_DEF_"));
|
||||
assertEquals(asList("abc1.def"), toTermString(".ABC1.DEF."));
|
||||
assertEquals(asList("abc1", "def"), toTermString("&ABC1&DEF&"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("@ABC1@DEF@"));
|
||||
assertEquals(asList("abc1", "def"), toTermString("'ABC1'DEF'"));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.dao.MusicFolderTestData;
|
||||
import org.airsonic.player.domain.MediaFile;
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
import org.airsonic.player.domain.RandomSearchCriteria;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SearchService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
@ContextConfiguration(
|
||||
locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml",
|
||||
"/applicationContext-mockSonos.xml" })
|
||||
@DirtiesContext(
|
||||
classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
/*
|
||||
* Tests to clarify strings that can be used in genre.
|
||||
*/
|
||||
public class SearchServiceSpecialGenreTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
|
||||
@Autowired
|
||||
private MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
private MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
private DaoHelper daoHelper;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@Autowired
|
||||
private SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
ResourceLoader resourceLoader;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabase();
|
||||
}
|
||||
|
||||
private static boolean dataBasePopulated;
|
||||
|
||||
private static Function<String, String> resolvePath = (childPath) ->{
|
||||
return MusicFolderTestData.resolveBaseMediaPath() + childPath;
|
||||
};
|
||||
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
private List<MusicFolder> getTestMusicFolders() {
|
||||
if (isEmpty(musicFolders)) {
|
||||
musicFolders = new ArrayList<>();
|
||||
|
||||
File musicDir = new File(resolvePath.apply("Search/SpecialGenre"));
|
||||
musicFolders.add(new MusicFolder(1, musicDir, "accessible", true, new Date()));
|
||||
|
||||
}
|
||||
return musicFolders;
|
||||
}
|
||||
|
||||
private int count = 1;
|
||||
|
||||
private synchronized void populateDatabase() {
|
||||
|
||||
try {
|
||||
Thread.sleep(300 * count++);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!dataBasePopulated) {
|
||||
getTestMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s -> s.equals("MEDIA_FILE") // 20
|
||||
| s.equals("ARTIST") // 5
|
||||
| s.equals("MUSIC_FOLDER")// 3
|
||||
| s.equals("ALBUM"))// 5
|
||||
.forEach(tableName -> System.out
|
||||
.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
System.out.println("--- *********************** ---");
|
||||
dataBasePopulated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQueryEscapeRequires() {
|
||||
|
||||
/*
|
||||
* Legacy is not searchable. (FILE01 - FILE16)
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBrackets() {
|
||||
|
||||
/*
|
||||
* Jaudiotagger applies special treatment to bracket (FILE17).
|
||||
*
|
||||
*/
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
|
||||
RandomSearchCriteria criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"-(GENRE)-", // genre,
|
||||
null, // fromYear
|
||||
null, // toYear
|
||||
folders // musicFolders
|
||||
);
|
||||
|
||||
List<MediaFile> songs = searchService.getRandomSongs(criteria);
|
||||
Assert.assertEquals(0, songs.size());
|
||||
|
||||
criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
" genre", // genre,
|
||||
null, // fromYear
|
||||
null, // toYear
|
||||
folders // musicFolders
|
||||
);
|
||||
|
||||
songs = searchService.getRandomSongs(criteria);
|
||||
Assert.assertEquals(1, songs.size());
|
||||
Assert.assertEquals("Consistency with Tag Parser 1", songs.get(0).getTitle());
|
||||
Assert.assertEquals("-GENRE -", songs.get(0).getGenre());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNumericMapping() {
|
||||
|
||||
/*
|
||||
* Jaudiotagger applies special treatment to numeric. (FILE18)
|
||||
*/
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
|
||||
RandomSearchCriteria criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"Rock", // genre,
|
||||
null, // fromYear
|
||||
null, // toYear
|
||||
folders // musicFolders
|
||||
);
|
||||
|
||||
List<MediaFile> songs = searchService.getRandomSongs(criteria);
|
||||
Assert.assertEquals(1, songs.size());
|
||||
Assert.assertEquals("Numeric mapping specification of genre 1", songs.get(0).getTitle());
|
||||
|
||||
// The value registered in the file is 17
|
||||
Assert.assertEquals("Rock", songs.get(0).getGenre());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOthers() {
|
||||
|
||||
/*
|
||||
* Other special strings. (FILE19)
|
||||
*
|
||||
* {'“『【【】】[︴○◎@ $〒→+]FULL-WIDTHCæsar's
|
||||
*
|
||||
* Legacy stores with Analyze,
|
||||
* so searchable characters are different.
|
||||
*
|
||||
*/
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
|
||||
RandomSearchCriteria criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"{'“『【【】】[︴○◎@ $〒→+]FULL-WIDTHCæsar's", // genre,
|
||||
null, // fromYear
|
||||
null, // toYear
|
||||
folders // musicFolders
|
||||
);
|
||||
|
||||
List<MediaFile> songs = searchService.getRandomSongs(criteria);
|
||||
Assert.assertEquals(0, songs.size());
|
||||
|
||||
criteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"widthcaesar", // genre,
|
||||
null, // fromYear
|
||||
null, // toYear
|
||||
folders // musicFolders
|
||||
);
|
||||
|
||||
songs = searchService.getRandomSongs(criteria);
|
||||
Assert.assertEquals(1, songs.size());
|
||||
Assert.assertEquals("Other special strings 1", songs.get(0).getTitle());
|
||||
Assert.assertEquals("{'“『【【】】[︴○◎@ $〒→+]FULL-WIDTHCæsar's", songs.get(0).getGenre());
|
||||
|
||||
}
|
||||
}
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.dao.MusicFolderTestData;
|
||||
import org.airsonic.player.domain.MediaFile;
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SearchService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
@ContextConfiguration(
|
||||
locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml",
|
||||
"/applicationContext-mockSonos.xml" })
|
||||
@DirtiesContext(
|
||||
classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
/*
|
||||
* Test cases related to #1139.
|
||||
* Confirming whether shuffle search can be performed correctly in MusicFolder containing special strings.
|
||||
*
|
||||
* (Since the query of getRandomAlbums consists of folder paths only,
|
||||
* this verification is easy to perform.)
|
||||
*
|
||||
* This test case is a FalsePattern for search,
|
||||
* but there may be problems with the data flow prior to creating the search index.
|
||||
*/
|
||||
public class SearchServiceSpecialPathTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
|
||||
@Autowired
|
||||
private MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
private MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
private DaoHelper daoHelper;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@Autowired
|
||||
private SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
ResourceLoader resourceLoader;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabase();
|
||||
}
|
||||
|
||||
private static boolean dataBasePopulated;
|
||||
|
||||
private static Function<String, String> resolvePath = (childPath) ->{
|
||||
return MusicFolderTestData.resolveBaseMediaPath() + childPath;
|
||||
};
|
||||
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
private List<MusicFolder> getTestMusicFolders() {
|
||||
if (isEmpty(musicFolders)) {
|
||||
musicFolders = new ArrayList<>();
|
||||
|
||||
File musicDir = new File(resolvePath.apply("Search/SpecialPath/accessible"));
|
||||
musicFolders.add(new MusicFolder(1, musicDir, "accessible", true, new Date()));
|
||||
|
||||
File music2Dir = new File(resolvePath.apply("Search/SpecialPath/accessible's"));
|
||||
musicFolders.add(new MusicFolder(2, music2Dir, "accessible's", true, new Date()));
|
||||
|
||||
File music3Dir = new File(resolvePath.apply("Search/SpecialPath/accessible+s"));
|
||||
musicFolders.add(new MusicFolder(3, music3Dir, "accessible+s", true, new Date()));
|
||||
}
|
||||
return musicFolders;
|
||||
}
|
||||
|
||||
private synchronized void populateDatabase() {
|
||||
|
||||
if (!dataBasePopulated) {
|
||||
getTestMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s -> s.equals("MEDIA_FILE") // 20
|
||||
| s.equals("ARTIST") // 5
|
||||
| s.equals("MUSIC_FOLDER")// 3
|
||||
| s.equals("ALBUM"))// 5
|
||||
.forEach(tableName -> System.out
|
||||
.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
System.out.println("--- *********************** ---");
|
||||
dataBasePopulated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpecialCharactersInDirName() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
|
||||
// ALL Songs
|
||||
List<MediaFile> randomAlbums = searchService.getRandomAlbums(Integer.MAX_VALUE, folders);
|
||||
Assert.assertEquals("ALL Albums ", 3, randomAlbums.size());
|
||||
|
||||
// dir - accessible
|
||||
List<MusicFolder> folder01 = folders.stream()
|
||||
.filter(m -> "accessible".equals(m.getName()))
|
||||
.collect(Collectors.toList());
|
||||
randomAlbums = searchService.getRandomAlbums(Integer.MAX_VALUE, folder01);
|
||||
Assert.assertEquals("Albums in \"accessible\" ", 3, randomAlbums.size());
|
||||
|
||||
// dir - accessible's
|
||||
List<MusicFolder> folder02 = folders.stream()
|
||||
.filter(m -> "accessible's".equals(m.getName()))
|
||||
.collect(Collectors.toList());
|
||||
randomAlbums = searchService.getRandomAlbums(Integer.MAX_VALUE, folder02);
|
||||
Assert.assertEquals("Albums in \"accessible's\" ", 0, randomAlbums.size());
|
||||
|
||||
// dir - accessible+s
|
||||
List<MusicFolder> folder03 = folders.stream()
|
||||
.filter(m -> "accessible+s".equals(m.getName()))
|
||||
.collect(Collectors.toList());
|
||||
randomAlbums = searchService.getRandomAlbums(Integer.MAX_VALUE, folder03);
|
||||
Assert.assertEquals("Albums in \"accessible+s\" ", 1, folder03.size());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
|
||||
package org.airsonic.player.service.search;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.airsonic.player.TestCaseUtils;
|
||||
import org.airsonic.player.dao.DaoHelper;
|
||||
import org.airsonic.player.dao.MusicFolderDao;
|
||||
import org.airsonic.player.dao.MusicFolderTestData;
|
||||
import org.airsonic.player.domain.MusicFolder;
|
||||
import org.airsonic.player.domain.SearchCriteria;
|
||||
import org.airsonic.player.domain.SearchResult;
|
||||
import org.airsonic.player.service.MediaScannerService;
|
||||
import org.airsonic.player.service.SearchService;
|
||||
import org.airsonic.player.service.SettingsService;
|
||||
import org.airsonic.player.util.HomeRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.Description;
|
||||
import org.junit.runners.model.Statement;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.rules.SpringClassRule;
|
||||
import org.springframework.test.context.junit4.rules.SpringMethodRule;
|
||||
import static org.springframework.util.ObjectUtils.isEmpty;
|
||||
|
||||
@ContextConfiguration(
|
||||
locations = {
|
||||
"/applicationContext-service.xml",
|
||||
"/applicationContext-cache.xml",
|
||||
"/applicationContext-testdb.xml",
|
||||
"/applicationContext-mockSonos.xml" })
|
||||
@DirtiesContext(
|
||||
classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
|
||||
/*
|
||||
* Test cases related to #1142.
|
||||
* The filter is not properly applied when analyzing the query,
|
||||
*
|
||||
* In the process of hardening the Analyzer implementation,
|
||||
* this problem is solved side by side.
|
||||
*/
|
||||
public class SearchServiceStartWithStopwardsTestCase {
|
||||
|
||||
@ClassRule
|
||||
public static final SpringClassRule classRule = new SpringClassRule() {
|
||||
HomeRule homeRule = new HomeRule();
|
||||
|
||||
@Override
|
||||
public Statement apply(Statement base, Description description) {
|
||||
Statement spring = super.apply(base, description);
|
||||
return homeRule.apply(spring, description);
|
||||
}
|
||||
};
|
||||
|
||||
@Rule
|
||||
public final SpringMethodRule springMethodRule = new SpringMethodRule();
|
||||
|
||||
@Autowired
|
||||
private MediaScannerService mediaScannerService;
|
||||
|
||||
@Autowired
|
||||
private MusicFolderDao musicFolderDao;
|
||||
|
||||
@Autowired
|
||||
private DaoHelper daoHelper;
|
||||
|
||||
@Autowired
|
||||
private SearchService searchService;
|
||||
|
||||
@Autowired
|
||||
private SettingsService settingsService;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temporaryFolder = new TemporaryFolder();
|
||||
|
||||
@Autowired
|
||||
ResourceLoader resourceLoader;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
populateDatabase();
|
||||
}
|
||||
|
||||
private static boolean dataBasePopulated;
|
||||
|
||||
private static Function<String, String> resolvePath = (childPath) ->{
|
||||
return MusicFolderTestData.resolveBaseMediaPath() + childPath;
|
||||
};
|
||||
|
||||
private List<MusicFolder> musicFolders;
|
||||
|
||||
private List<MusicFolder> getTestMusicFolders() {
|
||||
if (isEmpty(musicFolders)) {
|
||||
musicFolders = new ArrayList<>();
|
||||
|
||||
File musicDir = new File(resolvePath.apply("Search/StartWithStopwards"));
|
||||
musicFolders.add(new MusicFolder(1, musicDir, "accessible", true, new Date()));
|
||||
|
||||
}
|
||||
return musicFolders;
|
||||
}
|
||||
|
||||
private synchronized void populateDatabase() {
|
||||
|
||||
if (!dataBasePopulated) {
|
||||
getTestMusicFolders().forEach(musicFolderDao::createMusicFolder);
|
||||
settingsService.clearMusicFolderCache();
|
||||
TestCaseUtils.execScan(mediaScannerService);
|
||||
System.out.println("--- Report of records count per table ---");
|
||||
Map<String, Integer> records = TestCaseUtils.recordsInAllTables(daoHelper);
|
||||
records.keySet().stream().filter(s -> s.equals("MEDIA_FILE") // 20
|
||||
| s.equals("ARTIST") // 5
|
||||
| s.equals("MUSIC_FOLDER")// 3
|
||||
| s.equals("ALBUM"))// 5
|
||||
.forEach(tableName -> System.out
|
||||
.println("\t" + tableName + " : " + records.get(tableName).toString()));
|
||||
System.out.println("--- *********************** ---");
|
||||
dataBasePopulated = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartWithStopwards() {
|
||||
|
||||
List<MusicFolder> folders = getTestMusicFolders();
|
||||
|
||||
final SearchCriteria criteria = new SearchCriteria();
|
||||
criteria.setCount(Integer.MAX_VALUE);
|
||||
criteria.setOffset(0);
|
||||
|
||||
criteria.setQuery("will");
|
||||
SearchResult result = searchService.search(criteria, folders, IndexType.ARTIST_ID3);
|
||||
Assert.assertEquals("Williams hit by \"will\" ", 1, result.getTotalHits());
|
||||
|
||||
criteria.setQuery("the");
|
||||
result = searchService.search(criteria, folders, IndexType.SONG);
|
||||
Assert.assertEquals("Theater hit by \"the\" ", 1, result.getTotalHits());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+23
-9
@@ -319,16 +319,30 @@ public class SearchServiceTestCase {
|
||||
Assert.assertEquals("(24) Specify music as 'genre', and randomly acquire songs.", 0,
|
||||
allRandomSongs.size());
|
||||
|
||||
/*
|
||||
* Genre including blank.
|
||||
* Regardless of the Lucene version, It should be 2.
|
||||
*/
|
||||
randomSearchCriteria = new RandomSearchCriteria(Integer.MAX_VALUE, // count
|
||||
"Baroque Instrumental", // genre,
|
||||
null, // fromYear
|
||||
null, // toYear
|
||||
allMusicFolders // musicFolders
|
||||
);
|
||||
allRandomSongs = searchService.getRandomSongs(randomSearchCriteria);
|
||||
Assert.assertEquals("(25) Search by specifying genres including spaces and hyphens.", 2,
|
||||
allRandomSongs.size());
|
||||
|
||||
// *** testGetRandomAlbums() ***
|
||||
|
||||
/*
|
||||
* Acquisition of maximum number(5).
|
||||
*/
|
||||
List<Album> allAlbums = albumDao.getAlphabeticalAlbums(0, 0, true, true, allMusicFolders);
|
||||
Assert.assertEquals("(25) Get all albums with Dao.", 5, allAlbums.size());
|
||||
Assert.assertEquals("(26) Get all albums with Dao.", 5, allAlbums.size());
|
||||
List<MediaFile> allRandomAlbums = searchService.getRandomAlbums(Integer.MAX_VALUE,
|
||||
allMusicFolders);
|
||||
Assert.assertEquals("(26) Specify Integer.MAX_VALUE as the upper limit,"
|
||||
Assert.assertEquals("(27) Specify Integer.MAX_VALUE as the upper limit,"
|
||||
+ "and randomly acquire albums(file struct).", 5, allRandomAlbums.size());
|
||||
|
||||
/*
|
||||
@@ -337,7 +351,7 @@ public class SearchServiceTestCase {
|
||||
List<Album> allRandomAlbumsId3 = searchService.getRandomAlbumsId3(Integer.MAX_VALUE,
|
||||
allMusicFolders);
|
||||
Assert.assertEquals(
|
||||
"(27) Specify Integer.MAX_VALUE as the upper limit, and randomly acquire albums(ID3).",
|
||||
"(28) Specify Integer.MAX_VALUE as the upper limit, and randomly acquire albums(ID3).",
|
||||
5, allRandomAlbumsId3.size());
|
||||
|
||||
/*
|
||||
@@ -346,13 +360,13 @@ public class SearchServiceTestCase {
|
||||
query = "ID 3 ARTIST";
|
||||
searchCriteria.setQuery(query);
|
||||
result = searchService.search(searchCriteria, allMusicFolders, IndexType.ARTIST_ID3);
|
||||
Assert.assertEquals("(28) Specify '" + query + "', total Hits is", 4,
|
||||
Assert.assertEquals("(29) Specify '" + query + "', total Hits is", 4,
|
||||
result.getTotalHits());
|
||||
Assert.assertEquals("(29) Specify '" + query + "', and get an artists. Artist SIZE is ", 4,
|
||||
Assert.assertEquals("(30) Specify '" + query + "', and get an artists. Artist SIZE is ", 4,
|
||||
result.getArtists().size());
|
||||
Assert.assertEquals("(30) Specify '" + query + "', and get a artists. Album SIZE is ", 0,
|
||||
Assert.assertEquals("(31) Specify '" + query + "', and get a artists. Album SIZE is ", 0,
|
||||
result.getAlbums().size());
|
||||
Assert.assertEquals("(31) Specify '" + query + "', and get a artists. MediaFile SIZE is ",
|
||||
Assert.assertEquals("(32) Specify '" + query + "', and get a artists. MediaFile SIZE is ",
|
||||
0, result.getMediaFiles().size());
|
||||
|
||||
/*
|
||||
@@ -362,7 +376,7 @@ public class SearchServiceTestCase {
|
||||
*/
|
||||
long count = result.getArtists().stream()
|
||||
.filter(a -> a.getName().startsWith("_ID3_ARTIST_")).count();
|
||||
Assert.assertEquals("(32) Artist whose name contains \\\"_ID3_ARTIST_\\\" is 3 records.",
|
||||
Assert.assertEquals("(33) Artist whose name contains \\\"_ID3_ARTIST_\\\" is 3 records.",
|
||||
3L, count);
|
||||
|
||||
/*
|
||||
@@ -373,7 +387,7 @@ public class SearchServiceTestCase {
|
||||
*/
|
||||
count = result.getArtists().stream()
|
||||
.filter(a -> a.getName().startsWith("_ID3_ALBUMARTIST_")).count();
|
||||
Assert.assertEquals("(33) Artist whose name is \"_ID3_ARTIST_\" is 1 records.", 1L, count);
|
||||
Assert.assertEquals("(34) Artist whose name is \"_ID3_ARTIST_\" is 1 records.", 1L, count);
|
||||
|
||||
/*
|
||||
* Below is a simple loop test.
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user