def test_eq(self, lib_mock): sp_search = spotify.ffi.cast('sp_search *', 42) search1 = spotify.Search(self.session, sp_search=sp_search) search2 = spotify.Search(self.session, sp_search=sp_search) self.assertTrue(search1 == search2) self.assertFalse(search1 == 'foo')
def test_load(self, load_mock, lib_mock): sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) search.load(10) load_mock.assert_called_with(self.session, search, timeout=10)
def test_search_type_defaults_to_standard(self, lib_mock): sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.search_type self.assertEqual(result, spotify.SearchType.STANDARD)
def test_search_type_defaults_to_standard(self, lib_mock): sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = search.search_type self.assertEqual(result, spotify.SearchType.STANDARD)
def test_playlists(self, playlist_lib_mock, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_num_playlists.return_value = 1 lib_mock.sp_search_playlist_name.return_value = spotify.ffi.new( 'char[]', b'The Party List') lib_mock.sp_search_playlist_uri.return_value = spotify.ffi.new( 'char[]', b'spotify:playlist:foo') lib_mock.sp_search_playlist_image_uri.return_value = spotify.ffi.new( 'char[]', b'spotify:image:foo') sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) self.assertEqual(lib_mock.sp_search_add_ref.call_count, 1) result = search.playlists self.assertEqual(lib_mock.sp_search_add_ref.call_count, 2) self.assertEqual(len(result), 1) lib_mock.sp_search_num_playlists.assert_called_with(sp_search) item = result[0] self.assertIsInstance(item, spotify.SearchPlaylist) self.assertEqual(item.name, 'The Party List') self.assertEqual(item.uri, 'spotify:playlist:foo') self.assertEqual(item.image_uri, 'spotify:image:foo') self.assertEqual(lib_mock.sp_search_playlist_name.call_count, 1) lib_mock.sp_search_playlist_name.assert_called_with(sp_search, 0) self.assertEqual(lib_mock.sp_search_playlist_uri.call_count, 1) lib_mock.sp_search_playlist_uri.assert_called_with(sp_search, 0) self.assertEqual(lib_mock.sp_search_playlist_image_uri.call_count, 1) lib_mock.sp_search_playlist_image_uri.assert_called_with(sp_search, 0)
def test_load(self, load_mock, lib_mock): sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) search.load(10) load_mock.assert_called_with(search, timeout=10)
def test_more(self, lib_mock): sp_search1 = spotify.ffi.cast('sp_search *', 42) sp_search2 = spotify.ffi.cast('sp_search *', 43) lib_mock.sp_search_create.side_effect = [sp_search1, sp_search2] lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_query.return_value = spotify.ffi.new( 'char[]', b'alice') result = spotify.Search(self.session, query='alice') lib_mock.sp_search_create.assert_called_with( self.session._sp_session, mock.ANY, 0, 20, 0, 20, 0, 20, 0, 20, int(spotify.SearchType.STANDARD), mock.ANY, mock.ANY) self.assertEqual( spotify.ffi.string(lib_mock.sp_search_create.call_args[0][1]), b'alice') self.assertEqual(lib_mock.sp_search_add_ref.call_count, 0) self.assertIsInstance(result, spotify.Search) self.assertEqual(result._sp_search, sp_search1) result = result.more(track_count=30, album_count=30, artist_count=30, playlist_count=30) lib_mock.sp_search_create.assert_called_with( self.session._sp_session, mock.ANY, 20, 30, 20, 30, 20, 30, 20, 30, int(spotify.SearchType.STANDARD), mock.ANY, mock.ANY) self.assertEqual( spotify.ffi.string(lib_mock.sp_search_create.call_args[0][1]), b'alice') self.assertEqual(lib_mock.sp_search_add_ref.call_count, 0) self.assertIsInstance(result, spotify.Search) self.assertEqual(result._sp_search, sp_search2)
def test_search(self, lib_mock): sp_search = spotify.ffi.cast('sp_search *', 42) lib_mock.sp_search_create.return_value = sp_search result = spotify.Search(self.session, query='alice') lib_mock.sp_search_create.assert_called_with( self.session._sp_session, mock.ANY, 0, 20, 0, 20, 0, 20, 0, 20, int(spotify.SearchType.STANDARD), mock.ANY, mock.ANY, ) self.assertEqual( spotify.ffi.string(lib_mock.sp_search_create.call_args[0][1]), b'alice', ) self.assertEqual(lib_mock.sp_search_add_ref.call_count, 0) self.assertIsInstance(result, spotify.Search) self.assertFalse(result.loaded_event.is_set()) search_complete_cb = lib_mock.sp_search_create.call_args[0][11] userdata = lib_mock.sp_search_create.call_args[0][12] search_complete_cb(sp_search, userdata) self.assertTrue(result.loaded_event.wait(3))
def test_releases_sp_search_when_search_dies(self, lib_mock): sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) search = None # noqa tests.gc_collect() lib_mock.sp_search_release.assert_called_with(sp_search)
def assert_fails_if_error(self, lib_mock, func): lib_mock.sp_search_error.return_value = ( spotify.ErrorType.BAD_API_VERSION) sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) with self.assertRaises(spotify.Error): func(search)
def test_releases_sp_search_when_search_dies(self, lib_mock): sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) search = None # noqa tests.gc_collect() lib_mock.sp_search_release.assert_called_with(sp_search)
def assert_fails_if_error(self, lib_mock, func): lib_mock.sp_search_error.return_value = ( spotify.ErrorType.BAD_API_VERSION) sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) with self.assertRaises(spotify.Error): func(search)
def test_repr(self, link_mock, lib_mock): link_instance_mock = link_mock.return_value link_instance_mock.uri = 'foo' sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = repr(search) self.assertEqual(result, 'Search(%r)' % 'foo')
def test_is_loaded(self, lib_mock): lib_mock.sp_search_is_loaded.return_value = 1 sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = search.is_loaded lib_mock.sp_search_is_loaded.assert_called_once_with(sp_search) self.assertTrue(result)
def test_repr(self, link_mock, lib_mock): link_instance_mock = link_mock.return_value link_instance_mock.uri = 'foo' sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = repr(search) self.assertEqual(result, 'Search(%r)' % 'foo')
def test_is_loaded(self, lib_mock): lib_mock.sp_search_is_loaded.return_value = 1 sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.is_loaded lib_mock.sp_search_is_loaded.assert_called_once_with(sp_search) self.assertTrue(result)
def test_playlists_if_unloaded(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.IS_LOADING lib_mock.sp_search_is_loaded.return_value = 0 sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.playlists lib_mock.sp_search_is_loaded.assert_called_with(sp_search) self.assertEqual(len(result), 0)
def test_artists_if_unloaded(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.IS_LOADING lib_mock.sp_search_is_loaded.return_value = 0 sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = search.artists lib_mock.sp_search_is_loaded.assert_called_with(sp_search) self.assertEqual(len(result), 0)
def test_playlist_total(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_total_playlists.return_value = 75 sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.playlist_total lib_mock.sp_search_total_playlists.assert_called_with(sp_search) self.assertEqual(result, 75)
def test_query_is_none_if_empty(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_query.return_value = spotify.ffi.new('char[]', b'') sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.query lib_mock.sp_search_query.assert_called_once_with(sp_search) self.assertIsNone(result)
def test_artist_total(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_total_artists.return_value = 75 sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = search.artist_total lib_mock.sp_search_total_artists.assert_called_with(sp_search) self.assertEqual(result, 75)
def test_error(self, lib_mock): lib_mock.sp_search_error.return_value = int( spotify.ErrorType.IS_LOADING) sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.error lib_mock.sp_search_error.assert_called_once_with(sp_search) self.assertIs(result, spotify.ErrorType.IS_LOADING)
def test_artists_if_no_artists(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_num_artists.return_value = 0 sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = search.artists self.assertEqual(len(result), 0) lib_mock.sp_search_num_artists.assert_called_with(sp_search) self.assertEqual(lib_mock.sp_search_artist.call_count, 0)
def test_query(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_query.return_value = spotify.ffi.new( 'char[]', b'Foo Bar Baz') sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = search.query lib_mock.sp_search_query.assert_called_once_with(sp_search) self.assertEqual(result, 'Foo Bar Baz')
def test_did_you_mean(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_did_you_mean.return_value = spotify.ffi.new( 'char[]', b'Foo Bar Baz') sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.did_you_mean lib_mock.sp_search_did_you_mean.assert_called_once_with(sp_search) self.assertEqual(result, 'Foo Bar Baz')
def test_playlists_if_no_playlists(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_num_playlists.return_value = 0 sp_search = spotify.ffi.cast('sp_search *', 42) search = spotify.Search(self.session, sp_search=sp_search) result = search.playlists self.assertEqual(len(result), 0) lib_mock.sp_search_num_playlists.assert_called_with(sp_search) self.assertEqual(lib_mock.sp_search_playlist.call_count, 0)
def test_did_you_mean_is_none_if_empty(self, lib_mock): lib_mock.sp_search_error.return_value = spotify.ErrorType.OK lib_mock.sp_search_did_you_mean.return_value = spotify.ffi.new( 'char[]', b'') sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) result = search.did_you_mean lib_mock.sp_search_did_you_mean.assert_called_once_with(sp_search) self.assertIsNone(result)
def test_link_creates_link_to_search(self, link_mock, lib_mock): sp_search = spotify.ffi.new('int *') search = spotify.Search(sp_search=sp_search) sp_link = spotify.ffi.new('int *') lib_mock.sp_link_create_from_search.return_value = sp_link link_mock.return_value = mock.sentinel.link result = search.link link_mock.assert_called_once_with(sp_link=sp_link, add_ref=False) self.assertEqual(result, mock.sentinel.link)
def search(self, query, callback=None, track_offset=0, track_count=20, album_offset=0, album_count=20, artist_offset=0, artist_count=20, playlist_offset=0, playlist_count=20, search_type=None): """ Search Spotify for tracks, albums, artists, and playlists matching ``query``. The ``query`` string can be free format, or use some prefixes like ``title:`` and ``artist:`` to limit what to match on. There is no official docs on the search query format, but there's a `Spotify blog post <https://www.spotify.com/blog/archives/2008/01/22/searching-spotify/>`_ from 2008 with some examples. If ``callback`` isn't :class:`None`, it is expected to be a callable that accepts a single argument, a :class:`Search` instance, when the search completes. The ``*_offset`` and ``*_count`` arguments can be used to retrieve more search results. libspotify will currently not respect ``*_count`` values higher than 200, though this may change at any time as the limit isn't documented in any official docs. If you want to retrieve more than 200 results, you'll have to search multiple times with different ``*_offset`` values. See the ``*_total`` attributes on the :class:`Search` to see how many results exists, and to figure out how many searches you'll need to make to retrieve everything. ``search_type`` is a :class:`SearchType` value. It defaults to :attr:`SearchType.STANDARD`. Returns a :class:`Search` instance. """ return spotify.Search(self, query=query, callback=callback, track_offset=track_offset, track_count=track_count, album_offset=album_offset, album_count=album_count, artist_offset=artist_offset, artist_count=artist_count, playlist_offset=playlist_offset, playlist_count=playlist_count, search_type=search_type)
def test_search_with_callback(self, lib_mock): sp_search = spotify.ffi.cast('sp_search *', 42) lib_mock.sp_search_create.return_value = sp_search callback = mock.Mock() result = spotify.Search(self.session, query='alice', callback=callback) search_complete_cb = lib_mock.sp_search_create.call_args[0][11] userdata = lib_mock.sp_search_create.call_args[0][12] search_complete_cb(sp_search, userdata) result.loaded_event.wait(3) callback.assert_called_with(result)