1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-22 08:56:17 +00:00
supysonic/tests/api/test_search.py

426 lines
17 KiB
Python
Raw Permalink Normal View History

2017-11-03 22:15:48 +00:00
# This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API.
#
# Copyright (C) 2017-2022 Alban 'spl0k' Féron
2017-11-03 22:15:48 +00:00
#
# Distributed under terms of the GNU AGPLv3 license.
import time
import unittest
from supysonic.db import Folder, Artist, Album, Track
2017-11-03 22:15:48 +00:00
from .apitestbase import ApiTestBase
2019-06-29 15:25:44 +00:00
2017-11-03 22:15:48 +00:00
class SearchTestCase(ApiTestBase):
def setUp(self):
2020-11-22 15:12:14 +00:00
super().setUp()
2017-11-03 22:15:48 +00:00
2022-12-30 15:41:00 +00:00
root = Folder.create(root=True, name="Root folder", path="tests/assets")
Folder.create(root=True, name="Empty", path="/tmp")
for letter in "ABC":
folder = Folder.create(
name=letter + "rtist",
2023-01-08 15:16:28 +00:00
path=f"tests/assets/{letter}rtist",
2022-12-30 15:41:00 +00:00
root=False,
parent=root,
)
artist = Artist.create(name=letter + "rtist")
for lether in "AB":
afolder = Folder.create(
name=letter + lether + "lbum",
path="tests/assets/{0}rtist/{0}{1}lbum".format(letter, lether),
root=False,
parent=folder,
2019-06-29 15:25:44 +00:00
)
2017-11-03 22:15:48 +00:00
2022-12-30 15:41:00 +00:00
album = Album.create(name=letter + lether + "lbum", artist=artist)
for num, song in enumerate(["One", "Two", "Three"]):
Track.create(
disc=1,
number=num,
title=song,
duration=2,
album=album,
artist=artist,
bitrate=320,
path="tests/assets/{0}rtist/{0}{1}lbum/{2}".format(
letter, lether, song
),
last_modification=0,
root_folder=root,
folder=afolder,
2017-12-21 22:29:00 +00:00
)
2017-11-03 22:15:48 +00:00
2022-12-30 15:41:00 +00:00
self.assertEqual(Folder.select().count(), 11)
self.assertEqual(Artist.select().count(), 3)
self.assertEqual(Album.select().count(), 6)
self.assertEqual(Track.select().count(), 18)
2017-11-03 22:15:48 +00:00
def __track_as_pseudo_unique_str(self, elem):
2019-06-29 15:25:44 +00:00
return elem.get("artist") + elem.get("album") + elem.get("title")
2017-11-03 22:15:48 +00:00
def test_search(self):
# invalid parameters
2019-06-29 15:25:44 +00:00
self._make_request("search", {"count": "string"}, error=0)
self._make_request("search", {"offset": "sstring"}, error=0)
self._make_request("search", {"newerThan": "ssstring"}, error=0)
2017-11-03 22:15:48 +00:00
# no search
2019-06-29 15:25:44 +00:00
self._make_request("search", error=10)
2017-11-03 22:15:48 +00:00
# non existent artist (but searched string present in other fields)
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"artist": "One"}, tag="searchResult")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
2019-06-29 15:25:44 +00:00
self.assertEqual(child.get("totalHits"), "0")
self.assertEqual(child.get("offset"), "0")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"artist": "AAlbum"}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# non existent album (but search present in other fields)
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"album": "One"}, tag="searchResult")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"album": "Artist"}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# non existent title (but search present in other fields)
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"title": "AAlbum"}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"title": "Artist"}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# non existent anything
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"any": "Chaos"}, tag="searchResult")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# artist search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"artist": "Artist"}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 1)
2019-06-29 15:25:44 +00:00
self.assertEqual(child.get("totalHits"), "1")
self.assertEqual(child[0].get("title"), "Artist")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"artist": "rti"}, tag="searchResult")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 3)
2019-06-29 15:25:44 +00:00
self.assertEqual(child.get("totalHits"), "3")
2017-11-03 22:15:48 +00:00
# same as above, but created in the future
future = int(time.time() * 1000 + 1000)
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"artist": "rti", "newerThan": future}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# album search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"album": "AAlbum"}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 1)
2019-06-29 15:25:44 +00:00
self.assertEqual(child[0].get("title"), "AAlbum")
self.assertEqual(child[0].get("artist"), "Artist")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"album": "lbu"}, tag="searchResult")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 6)
# same as above, but created in the future
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"album": "lbu", "newerThan": future}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# song search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"title": "One"}, tag="searchResult")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 6)
for i in range(6):
2019-06-29 15:25:44 +00:00
self.assertEqual(child[i].get("title"), "One")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"title": "e"}, tag="searchResult")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 12)
# same as above, but created in the future
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"title": "e", "newerThan": future}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# any field search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search", {"any": "r"}, tag="searchResult")
self.assertEqual(len(child), 10) # root + 3 artists (*rtist) + 6 songs (Three)
2017-11-03 22:15:48 +00:00
# same as above, but created in the future
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search", {"any": "r", "newerThan": future}, tag="searchResult"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# paging
songs = []
for offset in range(0, 12, 2):
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search",
{"title": "e", "count": 2, "offset": offset},
tag="searchResult",
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 2)
2019-06-29 15:25:44 +00:00
self.assertEqual(child.get("totalHits"), "12")
self.assertEqual(child.get("offset"), str(offset))
2017-11-03 22:15:48 +00:00
for song in map(self.__track_as_pseudo_unique_str, child):
self.assertNotIn(song, songs)
2017-11-08 22:21:52 +00:00
songs.append(song)
2017-11-03 22:15:48 +00:00
def test_search2(self):
# invalid parameters
2019-06-29 15:25:44 +00:00
self._make_request("search2", {"query": "a", "artistCount": "string"}, error=0)
self._make_request(
"search2", {"query": "a", "artistOffset": "sstring"}, error=0
)
self._make_request("search2", {"query": "a", "albumCount": "string"}, error=0)
self._make_request("search2", {"query": "a", "albumOffset": "sstring"}, error=0)
self._make_request("search2", {"query": "a", "songCount": "string"}, error=0)
self._make_request("search2", {"query": "a", "songOffset": "sstring"}, error=0)
self._make_request(
"search2", {"query": "a", "musicFolderId": "sstring"}, error=0
)
self._make_request("search2", {"query": "a", "musicFolderId": -2}, error=70)
2017-11-03 22:15:48 +00:00
# no search
2019-06-29 15:25:44 +00:00
self._make_request("search2", error=10)
2017-11-03 22:15:48 +00:00
# non existent anything
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search2", {"query": "Chaos"}, tag="searchResult2"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# artist search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search2", {"query": "Artist"}, tag="searchResult2"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 1)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 1)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 0)
self.assertEqual(child[0].get("name"), "Artist")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search2", {"query": "rti"}, tag="searchResult2")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 3)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 3)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 0)
2017-11-03 22:15:48 +00:00
# album search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search2", {"query": "AAlbum"}, tag="searchResult2"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 1)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 1)
self.assertEqual(len(self._xpath(child, "./song")), 0)
self.assertEqual(child[0].get("title"), "AAlbum")
self.assertEqual(child[0].get("artist"), "Artist")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search2", {"query": "lbu"}, tag="searchResult2")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 6)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 6)
self.assertEqual(len(self._xpath(child, "./song")), 0)
2017-11-03 22:15:48 +00:00
# song search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search2", {"query": "One"}, tag="searchResult2")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 6)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 6)
2017-11-03 22:15:48 +00:00
for i in range(6):
2019-06-29 15:25:44 +00:00
self.assertEqual(child[i].get("title"), "One")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search2", {"query": "e"}, tag="searchResult2")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 12)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 12)
2017-11-03 22:15:48 +00:00
# any field search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search2", {"query": "r"}, tag="searchResult2")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 9)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 3)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 6)
2017-11-03 22:15:48 +00:00
# paging
artists = []
for offset in range(0, 4, 2):
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search2",
{"query": "r", "artistCount": 2, "artistOffset": offset},
tag="searchResult2",
)
names = self._xpath(child, "./artist/@name")
2017-11-08 22:21:52 +00:00
self.assertLessEqual(len(names), 2)
for name in names:
self.assertNotIn(name, artists)
artists.append(name)
2017-11-03 22:15:48 +00:00
songs = []
for offset in range(0, 6, 2):
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search2",
{"query": "r", "songCount": 2, "songOffset": offset},
tag="searchResult2",
)
elems = self._xpath(child, "./song")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(elems), 2)
for song in map(self.__track_as_pseudo_unique_str, elems):
self.assertNotIn(song, songs)
2017-11-08 22:21:52 +00:00
songs.append(song)
2017-11-03 22:15:48 +00:00
# root filtering
_, child = self._make_request(
"search2", {"query": "One", "musicFolderId": 1}, tag="searchResult2"
)
self.assertEqual(len(self._xpath(child, "./song")), 6)
_, child = self._make_request(
"search2", {"query": "One", "musicFolderId": 2}, tag="searchResult2"
)
self.assertEqual(len(self._xpath(child, "./song")), 0)
2017-11-03 22:15:48 +00:00
# Almost identical as above. Test dataset (and tests) should probably be changed
# to have folders that don't share names with artists or albums
def test_search3(self):
# invalid parameters
2019-06-29 15:25:44 +00:00
self._make_request("search3", {"query": "a", "artistCount": "string"}, error=0)
self._make_request(
"search3", {"query": "a", "artistOffset": "sstring"}, error=0
)
self._make_request("search3", {"query": "a", "albumCount": "string"}, error=0)
self._make_request("search3", {"query": "a", "albumOffset": "sstring"}, error=0)
self._make_request("search3", {"query": "a", "songCount": "string"}, error=0)
self._make_request("search3", {"query": "a", "songOffset": "sstring"}, error=0)
self._make_request(
"search3", {"query": "a", "musicFolderId": "sstring"}, error=0
)
self._make_request("search3", {"query": "a", "musicFolderId": -2}, error=70)
2017-11-03 22:15:48 +00:00
# no search
2019-06-29 15:25:44 +00:00
self._make_request("search3", error=10)
2017-11-03 22:15:48 +00:00
# non existent anything
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search3", {"query": "Chaos"}, tag="searchResult3"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 0)
# artist search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search3", {"query": "Artist"}, tag="searchResult3"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 1)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 1)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 0)
self.assertEqual(child[0].get("name"), "Artist")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search3", {"query": "rti"}, tag="searchResult3")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 3)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 3)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 0)
2017-11-03 22:15:48 +00:00
# album search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search3", {"query": "AAlbum"}, tag="searchResult3"
)
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 1)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 1)
self.assertEqual(len(self._xpath(child, "./song")), 0)
self.assertEqual(child[0].get("name"), "AAlbum")
self.assertEqual(child[0].get("artist"), "Artist")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search3", {"query": "lbu"}, tag="searchResult3")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 6)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 6)
self.assertEqual(len(self._xpath(child, "./song")), 0)
2017-11-03 22:15:48 +00:00
# song search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search3", {"query": "One"}, tag="searchResult3")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 6)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 6)
2017-11-03 22:15:48 +00:00
for i in range(6):
2019-06-29 15:25:44 +00:00
self.assertEqual(child[i].get("title"), "One")
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search3", {"query": "e"}, tag="searchResult3")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 12)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 0)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 12)
2017-11-03 22:15:48 +00:00
# any field search
2019-06-29 15:25:44 +00:00
rv, child = self._make_request("search3", {"query": "r"}, tag="searchResult3")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(child), 9)
2019-06-29 15:25:44 +00:00
self.assertEqual(len(self._xpath(child, "./artist")), 3)
self.assertEqual(len(self._xpath(child, "./album")), 0)
self.assertEqual(len(self._xpath(child, "./song")), 6)
2017-11-03 22:15:48 +00:00
# paging
artists = []
for offset in range(0, 4, 2):
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search3",
{"query": "r", "artistCount": 2, "artistOffset": offset},
tag="searchResult3",
)
names = self._xpath(child, "./artist/@name")
2017-11-08 22:21:52 +00:00
self.assertLessEqual(len(names), 2)
for name in names:
self.assertNotIn(name, artists)
artists.append(name)
2017-11-03 22:15:48 +00:00
songs = []
for offset in range(0, 6, 2):
2019-06-29 15:25:44 +00:00
rv, child = self._make_request(
"search3",
{"query": "r", "songCount": 2, "songOffset": offset},
tag="searchResult3",
)
elems = self._xpath(child, "./song")
2017-11-03 22:15:48 +00:00
self.assertEqual(len(elems), 2)
for song in map(self.__track_as_pseudo_unique_str, elems):
self.assertNotIn(song, songs)
2017-11-08 22:21:52 +00:00
songs.append(song)
2017-11-03 22:15:48 +00:00
# root filtering
_, child = self._make_request(
"search3", {"query": "One", "musicFolderId": 1}, tag="searchResult3"
)
self.assertEqual(len(self._xpath(child, "./song")), 6)
_, child = self._make_request(
"search3", {"query": "One", "musicFolderId": 2}, tag="searchResult3"
)
self.assertEqual(len(self._xpath(child, "./song")), 0)
2017-11-03 22:15:48 +00:00
2019-06-29 15:25:44 +00:00
if __name__ == "__main__":
unittest.main()