From 27bd7bce0cdb3dfbfca9930bffaaec69b6d594ef Mon Sep 17 00:00:00 2001 From: spl0k Date: Wed, 8 Nov 2017 23:21:52 +0100 Subject: [PATCH] Added playlist tests --- tests/api/__init__.py | 2 + tests/api/apitestbase.py | 19 +-- tests/api/test_playlist.py | 250 +++++++++++++++++++++++++++++++++++++ tests/api/test_search.py | 114 ++++++++--------- tests/base/test_db.py | 12 +- 5 files changed, 325 insertions(+), 72 deletions(-) create mode 100644 tests/api/test_playlist.py diff --git a/tests/api/__init__.py b/tests/api/__init__.py index 5eda1a3..c78f9d3 100644 --- a/tests/api/__init__.py +++ b/tests/api/__init__.py @@ -16,6 +16,7 @@ from .test_system import SystemTestCase from .test_user import UserTestCase from .test_chat import ChatTestCase from .test_search import SearchTestCase +from .test_playlist import PlaylistTestCase def suite(): suite = unittest.TestSuite() @@ -26,6 +27,7 @@ def suite(): suite.addTest(unittest.makeSuite(UserTestCase)) suite.addTest(unittest.makeSuite(ChatTestCase)) suite.addTest(unittest.makeSuite(SearchTestCase)) + suite.addTest(unittest.makeSuite(PlaylistTestCase)) return suite diff --git a/tests/api/apitestbase.py b/tests/api/apitestbase.py index 8321a5c..3d22f22 100644 --- a/tests/api/apitestbase.py +++ b/tests/api/apitestbase.py @@ -21,7 +21,8 @@ from .appmock import AppMock path_replace_regexp = re.compile(r'/(\w+)') -NS = '{http://subsonic.org/restapi}' +NS = 'http://subsonic.org/restapi' +NSMAP = { 'sub': NS } class ApiTestBase(unittest.TestCase): def setUp(self): @@ -47,19 +48,19 @@ class ApiTestBase(unittest.TestCase): def _find(self, xml, path): """ - Helper method that insert the namespace in XPath 'path' + Helper method that insert the namespace in ElementPath 'path' """ - path = path_replace_regexp.sub(r'/{}\1'.format(NS), path) + path = path_replace_regexp.sub(r'/{{{}}}\1'.format(NS), path) return xml.find(path) - def _findall(self, xml, path): + def _xpath(self, elem, path): """ - Helper method that insert the namespace in XPath 'path' + Helper method that insert a prefix and map the namespace in XPath 'path' """ - path = path_replace_regexp.sub(r'/{}\1'.format(NS), path) - return xml.findall(path) + path = path_replace_regexp.sub(r'/sub:\1', path) + return elem.xpath(path, namespaces = NSMAP) def _make_request(self, endpoint, args = {}, tag = None, error = None, skip_post = False): """ @@ -99,14 +100,14 @@ class ApiTestBase(unittest.TestCase): if 'status="ok"' in rg.data: self.assertIsNone(error) if tag: - self.assertEqual(xml[0].tag, NS + tag) + self.assertEqual(xml[0].tag, '{{{}}}{}'.format(NS, tag)) return rg, xml[0] else: self.assertEqual(len(xml), 0) return rg, None else: self.assertIsNone(tag) - self.assertEqual(xml[0].tag, NS + 'error') + self.assertEqual(xml[0].tag, '{{{}}}error'.format(NS)) self.assertEqual(xml[0].get('code'), str(error)) return rg diff --git a/tests/api/test_playlist.py b/tests/api/test_playlist.py new file mode 100644 index 0000000..3e164b5 --- /dev/null +++ b/tests/api/test_playlist.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# vim:fenc=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 uuid + +from supysonic.db import Folder, Artist, Album, Track, Playlist, User + +from .apitestbase import ApiTestBase + +class PlaylistTestCase(ApiTestBase): + def setUp(self): + super(PlaylistTestCase, self).setUp() + + root = Folder() + root.root = True + root.name = 'Root folder' + root.path = 'tests/assets' + self.store.add(root) + + artist = Artist() + artist.name = 'Artist' + + album = Album() + album.name = 'Album' + album.artist = artist + + songs = {} + for num, song in enumerate([ 'One', 'Two', 'Three', 'Four' ]): + track = Track() + track.disc = 1 + track.number = num + track.title = song + track.duration = 2 + track.album = album + track.artist = artist + track.bitrate = 320 + track.path = 'tests/assets/empty' + track.content_type = 'audio/mpeg' + track.last_modification = 0 + track.root_folder = root + track.folder = root + + self.store.add(track) + songs[song] = track + + users = { u.name: u for u in self.store.find(User) } + + playlist = Playlist() + playlist.user = users['alice'] + playlist.name = "Alice's" + playlist.add(songs['One']) + playlist.add(songs['Three']) + self.store.add(playlist) + + playlist = Playlist() + playlist.user = users['alice'] + playlist.public = True + playlist.name = "Alice's public" + playlist.add(songs['One']) + playlist.add(songs['Two']) + self.store.add(playlist) + + playlist = Playlist() + playlist.user = users['bob'] + playlist.name = "Bob's" + playlist.add(songs['Two']) + playlist.add(songs['Four']) + self.store.add(playlist) + + self.store.commit() + + def test_get_playlists(self): + # get own playlists + rv, child = self._make_request('getPlaylists', tag = 'playlists') + self.assertEqual(len(child), 2) + self.assertEqual(child[0].get('owner'), 'alice') + self.assertEqual(child[1].get('owner'), 'alice') + + # get own and public + rv, child = self._make_request('getPlaylists', { 'u': 'bob', 'p': 'B0b' }, tag = 'playlists') + self.assertEqual(len(child), 2) + self.assertTrue(child[0].get('owner') == 'alice' or child[1].get('owner') == 'alice') + self.assertTrue(child[0].get('owner') == 'bob' or child[1].get('owner') == 'bob') + self.assertIsNotNone(self._find(child, "./playlist[@owner='alice'][@public='true']")) + + # get other + rv, child = self._make_request('getPlaylists', { 'username': 'bob' }, tag = 'playlists') + self.assertEqual(len(child), 1) + self.assertEqual(child[0].get('owner'), 'bob') + + # get other when not admin + self._make_request('getPlaylists', { 'u': 'bob', 'p': 'B0b', 'username': 'alice' }, error = 50) + + # get from unknown user + self._make_request('getPlaylists', { 'username': 'johndoe' }, error = 70) + + def test_get_playlist(self): + # missing param + self._make_request('getPlaylist', error = 10) + + # invalid id + self._make_request('getPlaylist', { 'id': 1234 }, error = 0) + + # unknown + self._make_request('getPlaylist', { 'id': str(uuid.uuid4()) }, error = 70) + + # other's private from non admin + playlist = self.store.find(Playlist, Playlist.public == False, Playlist.user_id == User.id, User.name == 'alice').one() + self._make_request('getPlaylist', { 'u': 'bob', 'p': 'B0b', 'id': str(playlist.id) }, error = 50) + + # standard + rv, child = self._make_request('getPlaylists', tag = 'playlists') + rv, child = self._make_request('getPlaylist', { 'id': child[0].get('id') }, tag = 'playlist') + self.assertEqual(child.get('songCount'), '2') + self.assertEqual(self._xpath(child, 'count(./entry)'), 2) # don't count children, there may be 'allowedUser's (even though not supported by supysonic) + self.assertEqual(child.get('duration'), '4') + self.assertEqual(child[0].get('title'), 'One') + self.assertTrue(child[1].get('title') == 'Two' or child[1].get('title') == 'Three') # depending on 'getPlaylists' result ordering + + def test_create_playlist(self): + self._make_request('createPlaylist', error = 10) + self._make_request('createPlaylist', { 'name': 'wrongId', 'songId': 'abc' }, error = 0) + self._make_request('createPlaylist', { 'name': 'unknownId', 'songId': str(uuid.uuid4()) }, error = 70) + self._make_request('createPlaylist', { 'playlistId': 'abc' }, error = 0) + self._make_request('createPlaylist', { 'playlistId': str(uuid.uuid4()) }, error = 70) + + # create + self._make_request('createPlaylist', { 'name': 'new playlist' }, skip_post = True) + rv, child = self._make_request('getPlaylists', tag = 'playlists') + self.assertEqual(len(child), 3) + playlist = self._find(child, "./playlist[@name='new playlist']") + self.assertEqual(len(playlist), 0) + + # "update" newly created + self._make_request('createPlaylist', { 'playlistId': playlist.get('id') }) + rv, child = self._make_request('getPlaylists', tag = 'playlists') + self.assertEqual(len(child), 3) + + # renaming + self._make_request('createPlaylist', { 'playlistId': playlist.get('id'), 'name': 'renamed' }) + rv, child = self._make_request('getPlaylists', tag = 'playlists') + self.assertEqual(len(child), 3) + self.assertIsNone(self._find(child, "./playlist[@name='new playlist']")) + playlist = self._find(child, "./playlist[@name='renamed']") + self.assertIsNotNone(playlist) + + # update from other user + self._make_request('createPlaylist', { 'u': 'bob', 'p': 'B0b', 'playlistId': playlist.get('id') }, error = 50) + + # create more useful playlist + songs = { s.title: str(s.id) for s in self.store.find(Track) } + self._make_request('createPlaylist', { 'name': 'songs', 'songId': map(lambda s: songs[s], [ 'Three', 'One', 'Two' ]) }, skip_post = True) + playlist = self.store.find(Playlist, Playlist.name == 'songs').one() + self.assertIsNotNone(playlist) + rv, child = self._make_request('getPlaylist', { 'id': str(playlist.id) }, tag = 'playlist') + self.assertEqual(child.get('songCount'), '3') + self.assertEqual(self._xpath(child, 'count(./entry)'), 3) + self.assertEqual(child[0].get('title'), 'Three') + self.assertEqual(child[1].get('title'), 'One') + self.assertEqual(child[2].get('title'), 'Two') + + # update + self._make_request('createPlaylist', { 'playlistId': str(playlist.id), 'songId': songs['Two'] }, skip_post = True) + rv, child = self._make_request('getPlaylist', { 'id': str(playlist.id) }, tag = 'playlist') + self.assertEqual(child.get('songCount'), '1') + self.assertEqual(self._xpath(child, 'count(./entry)'), 1) + self.assertEqual(child[0].get('title'), 'Two') + + def test_delete_playlist(self): + # check params + self._make_request('deletePlaylist', error = 10) + self._make_request('deletePlaylist', { 'id': 'string' }, error = 0) + self._make_request('deletePlaylist', { 'id': str(uuid.uuid4()) }, error = 70) + + # delete unowned when not admin + playlist = self.store.find(Playlist, Playlist.user_id == User.id, User.name == 'alice')[0] + self._make_request('deletePlaylist', { 'u': 'bob', 'p': 'B0b', 'id': str(playlist.id) }, error = 50) + self.assertEqual(self.store.find(Playlist).count(), 3) + + # delete owned + self._make_request('deletePlaylist', { 'id': str(playlist.id) }, skip_post = True) + self.assertEqual(self.store.find(Playlist).count(), 2) + self._make_request('deletePlaylist', { 'id': str(playlist.id) }, error = 70) + self.assertEqual(self.store.find(Playlist).count(), 2) + + # delete unowned when admin + playlist = self.store.find(Playlist, Playlist.user_id == User.id, User.name == 'bob').one() + self._make_request('deletePlaylist', { 'id': str(playlist.id) }, skip_post = True) + self.assertEqual(self.store.find(Playlist).count(), 1) + + def test_update_playlist(self): + self._make_request('updatePlaylist', error = 10) + self._make_request('updatePlaylist', { 'playlistId': 1234 }, error = 0) + self._make_request('updatePlaylist', { 'playlistId': str(uuid.uuid4()) }, error = 70) + + playlist = self.store.find(Playlist, Playlist.user_id == User.id, User.name == 'alice')[0] + pid = str(playlist.id) + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIdToAdd': 'string' }, error = 0) + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIndexToRemove': 'string' }, error = 0) + + name = str(playlist.name) + self._make_request('updatePlaylist', { 'u': 'bob', 'p': 'B0b', 'playlistId': pid, 'name': 'new name' }, error = 50) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertEqual(child.get('name'), name) + self.assertEqual(self._xpath(child, 'count(./entry)'), 2) + + self._make_request('updatePlaylist', { 'playlistId': pid, 'name': 'new name' }, skip_post = True) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertEqual(child.get('name'), 'new name') + self.assertEqual(self._xpath(child, 'count(./entry)'), 2) + + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIndexToRemove': [ -1, 2 ] }, skip_post = True) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertEqual(self._xpath(child, 'count(./entry)'), 2) + + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIndexToRemove': [ 0, 2 ] }, skip_post = True) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertEqual(self._xpath(child, 'count(./entry)'), 1) + self.assertEqual(self._find(child, './entry').get('title'), 'Three') + + songs = { s.title: str(s.id) for s in self.store.find(Track) } + + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIdToAdd': [ songs['One'], songs['Two'], songs['Two'] ] }, skip_post = True) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertSequenceEqual(self._xpath(child, './entry/@title'), [ 'Three', 'One', 'Two', 'Two' ]) + + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIndexToRemove': [ 2, 1 ] }, skip_post = True) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertSequenceEqual(self._xpath(child, './entry/@title'), [ 'Three', 'Two' ]) + + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIdToAdd': songs['One'] }, skip_post = True) + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIndexToRemove': [ 1, 1 ] }, skip_post = True) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertSequenceEqual(self._xpath(child, './entry/@title'), [ 'Three', 'One' ]) + + self._make_request('updatePlaylist', { 'playlistId': pid, 'songIdToAdd': str(uuid.uuid4()) }, error = 70) + rv, child = self._make_request('getPlaylist', { 'id': pid }, tag = 'playlist') + self.assertEqual(self._xpath(child, 'count(./entry)'), 2) + +if __name__ == '__main__': + unittest.main() + diff --git a/tests/api/test_search.py b/tests/api/test_search.py index d930da7..8a52268 100644 --- a/tests/api/test_search.py +++ b/tests/api/test_search.py @@ -165,7 +165,7 @@ class SearchTestCase(ApiTestBase): self.assertEqual(child.get('offset'), str(offset)) for song in map(self.__track_as_pseudo_unique_str, child): self.assertNotIn(song, songs) - songs += list(map(self.__track_as_pseudo_unique_str, child)) + songs.append(song) def test_search2(self): # invalid parameters @@ -186,72 +186,72 @@ class SearchTestCase(ApiTestBase): # artist search rv, child = self._make_request('search2', { 'query': 'Artist' }, tag = 'searchResult2') self.assertEqual(len(child), 1) - self.assertEqual(len(self._findall(child, './artist')), 1) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 3) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 1) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 6) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 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._findall(child, './artist')), 3) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 6) + 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') - elems = self._findall(child, './artist') - self.assertLessEqual(len(elems), 2) - for artist in map(lambda a: a.get('name'), elems): - self.assertNotIn(artist, artists) - artists += list(map(lambda a: a.get('name'), elems)) + 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._findall(child, './song') + 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 += list(map(self.__track_as_pseudo_unique_str, elems)) + 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 @@ -274,72 +274,72 @@ class SearchTestCase(ApiTestBase): # artist search rv, child = self._make_request('search3', { 'query': 'Artist' }, tag = 'searchResult3') self.assertEqual(len(child), 1) - self.assertEqual(len(self._findall(child, './artist')), 1) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 3) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 1) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 6) - self.assertEqual(len(self._findall(child, './song')), 0) + 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 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._findall(child, './artist')), 0) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 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._findall(child, './artist')), 3) - self.assertEqual(len(self._findall(child, './album')), 0) - self.assertEqual(len(self._findall(child, './song')), 6) + 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') - elems = self._findall(child, './artist') - self.assertLessEqual(len(elems), 2) - for artist in map(lambda a: a.get('name'), elems): - self.assertNotIn(artist, artists) - artists += list(map(lambda a: a.get('name'), elems)) + 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._findall(child, './song') + 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 += list(map(self.__track_as_pseudo_unique_str, elems)) + songs.append(song) if __name__ == '__main__': unittest.main() diff --git a/tests/base/test_db.py b/tests/base/test_db.py index 8263d48..99f054c 100644 --- a/tests/base/test_db.py +++ b/tests/base/test_db.py @@ -23,7 +23,7 @@ class DbTestCase(unittest.TestCase): self.store = db.get_store(u'sqlite:') with io.open(u'schema/sqlite.sql', u'r') as f: for statement in f.read().split(u';'): - self.store.execute(statement) + self.store.execute(statement) def tearDown(self): self.store.close() @@ -51,13 +51,13 @@ class DbTestCase(unittest.TestCase): root, child = self.create_some_folders() if not artist: - artist = db.Artist() - artist.name = u'Test Artist' + artist = db.Artist() + artist.name = u'Test Artist' if not album: - album = db.Album() - album.artist = artist - album.name = u'Test Album' + album = db.Album() + album.artist = artist + album.name = u'Test Album' track1 = db.Track() track1.title = u'Track Title'