1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-23 09:26:18 +00:00
supysonic/tests/api/test_search.py
spl0k 38f718b4df Using new pony on_connect decorator
Revert "Restore SQLite case insensitive LIKE"
This reverts commit a08689e8c0.
2018-08-11 16:16:34 +02:00

339 lines
15 KiB
Python

#!/usr/bin/env python
# coding: utf-8
#
# This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API.
#
# Copyright (C) 2017 Alban 'spl0k' Féron
#
# Distributed under terms of the GNU AGPLv3 license.
import time
import unittest
from pony.orm import db_session, commit
from supysonic.db import Folder, Artist, Album, Track
from .apitestbase import ApiTestBase
class SearchTestCase(ApiTestBase):
def setUp(self):
super(SearchTestCase, self).setUp()
with db_session:
root = Folder(root = True, name = 'Root folder', path = 'tests/assets')
for letter in 'ABC':
folder = Folder(name = letter + 'rtist', path = 'tests/assets/{}rtist'.format(letter), parent = root)
artist = Artist(name = letter + 'rtist')
for lether in 'AB':
afolder = Folder(
name = letter + lether + 'lbum',
path = 'tests/assets/{0}rtist/{0}{1}lbum'.format(letter, lether),
parent = folder
)
album = Album(name = letter + lether + 'lbum', artist = artist)
for num, song in enumerate([ 'One', 'Two', 'Three' ]):
track = Track(
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),
content_type = 'audio/mpeg',
last_modification = 0,
root_folder = root,
folder = afolder
)
commit()
self.assertEqual(Folder.select().count(), 10)
self.assertEqual(Artist.select().count(), 3)
self.assertEqual(Album.select().count(), 6)
self.assertEqual(Track.select().count(), 18)
def __track_as_pseudo_unique_str(self, elem):
return elem.get('artist') + elem.get('album') + elem.get('title')
def test_search(self):
# invalid parameters
self._make_request('search', { 'count': 'string' }, error = 0)
self._make_request('search', { 'offset': 'sstring' }, error = 0)
self._make_request('search', { 'newerThan': 'ssstring' }, error = 0)
# no search
self._make_request('search', error = 10)
# non existent artist (but searched string present in other fields)
rv, child = self._make_request('search', { 'artist': 'One' }, tag = 'searchResult')
self.assertEqual(len(child), 0)
self.assertEqual(child.get('totalHits'), '0')
self.assertEqual(child.get('offset'), '0')
rv, child = self._make_request('search', { 'artist': 'AAlbum' }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# non existent album (but search present in other fields)
rv, child = self._make_request('search', { 'album': 'One' }, tag = 'searchResult')
self.assertEqual(len(child), 0)
rv, child = self._make_request('search', { 'album': 'Artist' }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# non existent title (but search present in other fields)
rv, child = self._make_request('search', { 'title': 'AAlbum' }, tag = 'searchResult')
self.assertEqual(len(child), 0)
rv, child = self._make_request('search', { 'title': 'Artist' }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# non existent anything
rv, child = self._make_request('search', { 'any': 'Chaos' }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# artist search
rv, child = self._make_request('search', { 'artist': 'Artist' }, tag = 'searchResult')
self.assertEqual(len(child), 1)
self.assertEqual(child.get('totalHits'), '1')
self.assertEqual(child[0].get('title'), 'Artist')
rv, child = self._make_request('search', { 'artist': 'rti' }, tag = 'searchResult')
self.assertEqual(len(child), 3)
self.assertEqual(child.get('totalHits'), '3')
# same as above, but created in the future
future = int(time.time() * 1000 + 1000)
rv, child = self._make_request('search', { 'artist': 'rti', 'newerThan': future }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# album search
rv, child = self._make_request('search', { 'album': 'AAlbum' }, tag = 'searchResult')
self.assertEqual(len(child), 1)
self.assertEqual(child[0].get('title'), 'AAlbum')
self.assertEqual(child[0].get('artist'), 'Artist')
rv, child = self._make_request('search', { 'album': 'lbu' }, tag = 'searchResult')
self.assertEqual(len(child), 6)
# same as above, but created in the future
rv, child = self._make_request('search', { 'album': 'lbu', 'newerThan': future }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# song search
rv, child = self._make_request('search', { 'title': 'One' }, tag = 'searchResult')
self.assertEqual(len(child), 6)
for i in range(6):
self.assertEqual(child[i].get('title'), 'One')
rv, child = self._make_request('search', { 'title': 'e' }, tag = 'searchResult')
self.assertEqual(len(child), 12)
# same as above, but created in the future
rv, child = self._make_request('search', { 'title': 'e', 'newerThan': future }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# any field search
rv, child = self._make_request('search', { 'any': 'r' }, tag = 'searchResult')
self.assertEqual(len(child), 10) # root + 3 artists (*rtist) + 6 songs (Three)
# same as above, but created in the future
rv, child = self._make_request('search', { 'any': 'r', 'newerThan': future }, tag = 'searchResult')
self.assertEqual(len(child), 0)
# paging
songs = []
for offset in range(0, 12, 2):
rv, child = self._make_request('search', { 'title': 'e', 'count': 2, 'offset': offset }, tag = 'searchResult')
self.assertEqual(len(child), 2)
self.assertEqual(child.get('totalHits'), '12')
self.assertEqual(child.get('offset'), str(offset))
for song in map(self.__track_as_pseudo_unique_str, child):
self.assertNotIn(song, songs)
songs.append(song)
def test_search2(self):
# invalid parameters
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)
# no search
self._make_request('search2', error = 10)
# non existent anything
rv, child = self._make_request('search2', { 'query': 'Chaos' }, tag = 'searchResult2')
self.assertEqual(len(child), 0)
# artist search
rv, child = self._make_request('search2', { 'query': 'Artist' }, tag = 'searchResult2')
self.assertEqual(len(child), 1)
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')
rv, child = self._make_request('search2', { 'query': 'rti' }, tag = 'searchResult2')
self.assertEqual(len(child), 3)
self.assertEqual(len(self._xpath(child, './artist')), 3)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 0)
# album search
rv, child = self._make_request('search2', { 'query': 'AAlbum' }, tag = 'searchResult2')
self.assertEqual(len(child), 1)
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')
rv, child = self._make_request('search2', { 'query': 'lbu' }, tag = 'searchResult2')
self.assertEqual(len(child), 6)
self.assertEqual(len(self._xpath(child, './artist')), 0)
self.assertEqual(len(self._xpath(child, './album')), 6)
self.assertEqual(len(self._xpath(child, './song')), 0)
# song search
rv, child = self._make_request('search2', { 'query': 'One' }, tag = 'searchResult2')
self.assertEqual(len(child), 6)
self.assertEqual(len(self._xpath(child, './artist')), 0)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 6)
for i in range(6):
self.assertEqual(child[i].get('title'), 'One')
rv, child = self._make_request('search2', { 'query': 'e' }, tag = 'searchResult2')
self.assertEqual(len(child), 12)
self.assertEqual(len(self._xpath(child, './artist')), 0)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 12)
# any field search
rv, child = self._make_request('search2', { 'query': 'r' }, tag = 'searchResult2')
self.assertEqual(len(child), 9)
self.assertEqual(len(self._xpath(child, './artist')), 3)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 6)
# paging
artists = []
for offset in range(0, 4, 2):
rv, child = self._make_request('search2', { 'query': 'r', 'artistCount': 2, 'artistOffset': offset }, tag = 'searchResult2')
names = self._xpath(child, './artist/@name')
self.assertLessEqual(len(names), 2)
for name in names:
self.assertNotIn(name, artists)
artists.append(name)
songs = []
for offset in range(0, 6, 2):
rv, child = self._make_request('search2', { 'query': 'r', 'songCount': 2, 'songOffset': offset }, tag = 'searchResult2')
elems = self._xpath(child, './song')
self.assertEqual(len(elems), 2)
for song in map(self.__track_as_pseudo_unique_str, elems):
self.assertNotIn(song, songs)
songs.append(song)
# 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
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)
# no search
self._make_request('search3', error = 10)
# non existent anything
rv, child = self._make_request('search3', { 'query': 'Chaos' }, tag = 'searchResult3')
self.assertEqual(len(child), 0)
# artist search
rv, child = self._make_request('search3', { 'query': 'Artist' }, tag = 'searchResult3')
self.assertEqual(len(child), 1)
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')
rv, child = self._make_request('search3', { 'query': 'rti' }, tag = 'searchResult3')
self.assertEqual(len(child), 3)
self.assertEqual(len(self._xpath(child, './artist')), 3)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 0)
# album search
rv, child = self._make_request('search3', { 'query': 'AAlbum' }, tag = 'searchResult3')
self.assertEqual(len(child), 1)
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')
rv, child = self._make_request('search3', { 'query': 'lbu' }, tag = 'searchResult3')
self.assertEqual(len(child), 6)
self.assertEqual(len(self._xpath(child, './artist')), 0)
self.assertEqual(len(self._xpath(child, './album')), 6)
self.assertEqual(len(self._xpath(child, './song')), 0)
# song search
rv, child = self._make_request('search3', { 'query': 'One' }, tag = 'searchResult3')
self.assertEqual(len(child), 6)
self.assertEqual(len(self._xpath(child, './artist')), 0)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 6)
for i in range(6):
self.assertEqual(child[i].get('title'), 'One')
rv, child = self._make_request('search3', { 'query': 'e' }, tag = 'searchResult3')
self.assertEqual(len(child), 12)
self.assertEqual(len(self._xpath(child, './artist')), 0)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 12)
# any field search
rv, child = self._make_request('search3', { 'query': 'r' }, tag = 'searchResult3')
self.assertEqual(len(child), 9)
self.assertEqual(len(self._xpath(child, './artist')), 3)
self.assertEqual(len(self._xpath(child, './album')), 0)
self.assertEqual(len(self._xpath(child, './song')), 6)
# paging
artists = []
for offset in range(0, 4, 2):
rv, child = self._make_request('search3', { 'query': 'r', 'artistCount': 2, 'artistOffset': offset }, tag = 'searchResult3')
names = self._xpath(child, './artist/@name')
self.assertLessEqual(len(names), 2)
for name in names:
self.assertNotIn(name, artists)
artists.append(name)
songs = []
for offset in range(0, 6, 2):
rv, child = self._make_request('search3', { 'query': 'r', 'songCount': 2, 'songOffset': offset }, tag = 'searchResult3')
elems = self._xpath(child, './song')
self.assertEqual(len(elems), 2)
for song in map(self.__track_as_pseudo_unique_str, elems):
self.assertNotIn(song, songs)
songs.append(song)
if __name__ == '__main__':
unittest.main()