My fork of airsonic with experimental fixes and improvements. See branch "custom"
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
airsonic-custom/airsonic-main/src/test/java/org/airsonic/player/service/search/SearchServiceSpecialGenreTe...

293 lines
12 KiB

package org.airsonic.player.service.search;
import com.google.common.base.Function;
import org.airsonic.player.domain.MediaFile;
import org.airsonic.player.domain.MusicFolder;
import org.airsonic.player.domain.RandomSearchCriteria;
import org.airsonic.player.service.SearchService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.springframework.util.ObjectUtils.isEmpty;
/*
* Tests to prove what kind of strings/chars can be used in the genre field.
*/
public class SearchServiceSpecialGenreTestCase extends AbstractAirsonicHomeTest {
private List<MusicFolder> musicFolders;
@Autowired
private SearchService searchService;
@Override
public List<MusicFolder> getMusicFolders() {
if (isEmpty(musicFolders)) {
musicFolders = new ArrayList<>();
File musicDir = new File(resolveBaseMediaPath.apply("Search/SpecialGenre"));
musicFolders.add(new MusicFolder(1, musicDir, "accessible", true, new Date()));
}
return musicFolders;
}
@Before
public void setup() {
populateDatabaseOnlyOnce();
}
/*
* There are 19 files
* in src/test/resources/MEDIAS/Search/SpecialGenre/ARTIST1/ALBUM_A.
* In FILE01 to FILE16, Special strings for Lucene syntax are stored
* as tag values of Genre.
*
* Legacy can not search all these genres.
* (Strictly speaking, the genre field is not created at index creation.)
*
* // XXX 3.x -> 8.x : Do the process more strictly.
*
* - Values that can be cross-referenced with DB are stored in the index.
* - Search is also possible with user's readable value (file tag value).
* - However, there is an exception in parentheses.
*/
@Test
public void testQueryEscapeRequires() {
Function<String, RandomSearchCriteria> simpleStringCriteria = s ->
new RandomSearchCriteria(Integer.MAX_VALUE, // count
s, // genre,
null, // fromYear
null, // toYear
getMusicFolders() // musicFolders
);
List<MediaFile> songs = searchService.getRandomSongs(simpleStringCriteria.apply("+"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("+", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 1", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("-"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("-", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 2", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("&&"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("&&", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 3", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("||"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("||", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 4", songs.get(0).getTitle());
/*
* // XXX 3.x -> 8.x : Brackets ()
*
* Lucene can handle these.
* However, brackets are specially parsed before the index creation process.
*
* This string is never stored in the index.
* This is the only exception.
*/
songs = searchService.getRandomSongs(simpleStringCriteria.apply(" ("));// space & bracket
Assert.assertEquals(0, songs.size());
songs = searchService.getRandomSongs(simpleStringCriteria.apply(")"));
Assert.assertEquals(0, songs.size());
/*
* // XXX 3.x -> 8.x : Brackets {}[]
*
* Lucene can handle these.
* However, brackets are specially parsed before the index creation process.
*
* This can be done with a filter that performs the reverse process
* on the input values when searching.
* As a result, the values stored in the file can be retrieved by search.
*
* @see AnalyzerFactory
*
* >>>>>
*/
songs = searchService.getRandomSongs(simpleStringCriteria.apply("{}"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
/*
* This is the result of the tag parser and domain value.
* It is different from the tag value in file.
*/
Assert.assertEquals("{ }", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 7", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("{ }"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("Query Escape Requires 7", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("[]"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
/*
* This is the result of the tag parser and domain value.
* It is different from the tag value in file.
*/
Assert.assertEquals("[ ]", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 8", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("[ ]"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("Query Escape Requires 8", songs.get(0).getTitle());
// <<<<<
songs = searchService.getRandomSongs(simpleStringCriteria.apply("^"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("^", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 9", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("\""));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("\"", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 10", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("~"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("~", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 11", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("*"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("*", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 12", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("?"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("?", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 13", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply(":"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals(":", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 14", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("\\"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("\\", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 15", songs.get(0).getTitle());
songs = searchService.getRandomSongs(simpleStringCriteria.apply("/"));
Assert.assertEquals(1, songs.size());// XXX 3.x -> 8.x : Searchable
Assert.assertEquals("/", songs.get(0).getGenre());
Assert.assertEquals("Query Escape Requires 16", songs.get(0).getTitle());
}
/*
* Jaudiotagger applies special treatment to bracket (FILE17).
* XXX 3.x -> 8.x : Specification of genre search became more natural.
*/
@Test
public void testBrackets() {
Function<String, RandomSearchCriteria> simpleStringCriteria = s ->
new RandomSearchCriteria(Integer.MAX_VALUE, // count
s, // genre,
null, // fromYear
null, // toYear
getMusicFolders() // musicFolders
);
// -(GENRE)- is registered as genre of FILE17.
/*
* Search by genre string registered in file.
*
* The value stored in the index is different from legacy.
* Domain value is kept as it is.
*/
List<MediaFile> songs = searchService.getRandomSongs(simpleStringCriteria.apply("-(GENRE)-"));
Assert.assertEquals(1, songs.size());
Assert.assertEquals("-GENRE -", songs.get(0).getGenre());
Assert.assertEquals("Consistency with Tag Parser 1", songs.get(0).getTitle());
/*
* Search by Domain value.
*/
songs = searchService.getRandomSongs(simpleStringCriteria.apply("-GENRE -"));
Assert.assertEquals(1, songs.size());
Assert.assertEquals("-GENRE -", songs.get(0).getGenre());
Assert.assertEquals("Consistency with Tag Parser 1", songs.get(0).getTitle());
/*
* Legacy genre search
*/
songs = searchService.getRandomSongs(simpleStringCriteria.apply(" genre"));
// Strong unique parsing rules have been removed.
Assert.assertEquals(0, songs.size());
}
/*
* Jaudiotagger applies special treatment to numeric. (FILE18)
*/
@Test
public void testNumericMapping() {
List<MusicFolder> folders = getMusicFolders();
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());
}
/*
* Other special strings. (FILE19)
*
* {'“『【【】】[︴○◎@ $〒→+]FULL-WIDTHCæsar's
*
* Legacy stores with Analyze,
* so searchable characters are different.
*
*/
@Test
public void testOthers() {
Function<String, RandomSearchCriteria> simpleStringCriteria = s ->
new RandomSearchCriteria(Integer.MAX_VALUE, // count
s, // genre,
null, // fromYear
null, // toYear
getMusicFolders() // musicFolders
);
// XXX 3.x -> 8.x : Do the process more strictly.
List<MediaFile> songs = searchService
.getRandomSongs(simpleStringCriteria.apply("{'“『【【】】[︴○◎@ $〒→+]FULL-WIDTHCæsar's"));
Assert.assertEquals(1, songs.size());
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());
/*
* Legacy kept "widthcaesar" using their own rules.
* The previous rule has been discarded.
*/
songs = searchService.getRandomSongs(simpleStringCriteria.apply("widthcaesar"));
Assert.assertEquals(0, songs.size());
}
}