From 6c49a7fc525599fc2a4f5cdb2c7b4c8905751b2b Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Wed, 31 Oct 2012 16:52:34 +0100 Subject: [PATCH] Make core.stored_playlists.save() support multibackend (#217) --- mopidy/core/stored_playlists.py | 32 ++++++++++++++++++------- tests/core/stored_playlists_test.py | 37 +++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 10 deletions(-) diff --git a/mopidy/core/stored_playlists.py b/mopidy/core/stored_playlists.py index 16dffdb0..c404a408 100644 --- a/mopidy/core/stored_playlists.py +++ b/mopidy/core/stored_playlists.py @@ -31,6 +31,9 @@ class StoredPlaylistsController(object): :class:`None` or doesn't match a current backend, the first backend is asked to create the playlist. + All new playlists should be created by calling this method, and **not** + by creating new instances of :class:`mopidy.models.Playlist`. + :param name: name of the new playlist :type name: string :param uri_scheme: use the backend matching the URI scheme @@ -128,15 +131,28 @@ class StoredPlaylistsController(object): """ Save the playlist to the set of stored playlists. - Returns the saved playlist. The return playlist may differ from the - saved playlist. E.g. if the playlist name was changed, the returned - playlist may have a different URI. The caller of this method should - throw away the playlist sent to this method, and use the returned - playlist instead. + For a playlist to be saveable, it must have the ``uri`` attribute set. + You should not set the ``uri`` atribute yourself, but use playlist + objects returned by :meth:`create` or retrieved from :attr:`playlists`, + which will always give you saveable playlists. + + The method returns the saved playlist. The return playlist may differ + from the saved playlist. E.g. if the playlist name was changed, the + returned playlist may have a different URI. The caller of this method + should throw away the playlist sent to this method, and use the + returned playlist instead. + + If the playlist's URI isn't set or doesn't match the URI scheme of a + current backend, nothing is done and :class:`None` is returned. :param playlist: the playlist :type playlist: :class:`mopidy.models.Playlist` - :rtype: :class:`mopidy.models.Playlist` + :rtype: :class:`mopidy.models.Playlist` or :class:`None` """ - # TODO Support multiple backends - return self.backends[0].stored_playlists.save(playlist).get() + if playlist.uri is None: + return + uri_scheme = urlparse.urlparse(playlist.uri).scheme + if uri_scheme not in self.backends.by_uri_scheme: + return + backend = self.backends.by_uri_scheme[uri_scheme] + return backend.stored_playlists.save(playlist).get() diff --git a/tests/core/stored_playlists_test.py b/tests/core/stored_playlists_test.py index 39914766..b0d48512 100644 --- a/tests/core/stored_playlists_test.py +++ b/tests/core/stored_playlists_test.py @@ -107,5 +107,38 @@ class StoredPlaylistsTest(unittest.TestCase): self.assertFalse(self.sp1.refresh.called) self.assertFalse(self.sp2.refresh.called) - # TODO The rest of the stored playlists API is pending redesign before - # we'll update it to support multiple backends. + def test_save_selects_the_dummy1_backend(self): + playlist = Playlist(uri='dummy1:a') + self.sp1.save().get.return_value = playlist + self.sp1.reset_mock() + + result = self.core.stored_playlists.save(playlist) + + self.assertEqual(playlist, result) + self.sp1.save.assert_called_once_with(playlist) + self.assertFalse(self.sp2.save.called) + + def test_save_selects_the_dummy2_backend(self): + playlist = Playlist(uri='dummy2:a') + self.sp2.save().get.return_value = playlist + self.sp2.reset_mock() + + result = self.core.stored_playlists.save(playlist) + + self.assertEqual(playlist, result) + self.assertFalse(self.sp1.save.called) + self.sp2.save.assert_called_once_with(playlist) + + def test_save_does_nothing_if_playlist_uri_is_unset(self): + result = self.core.stored_playlists.save(Playlist()) + + self.assertIsNone(result) + self.assertFalse(self.sp1.save.called) + self.assertFalse(self.sp2.save.called) + + def test_save_does_nothing_if_playlist_uri_has_unknown_scheme(self): + result = self.core.stored_playlists.save(Playlist(uri='foobar:a')) + + self.assertIsNone(result) + self.assertFalse(self.sp1.save.called) + self.assertFalse(self.sp2.save.called)