def test_initialization(self): playlist = PlaylistFixture.one() actual = playlist.asdict() expected = { "type": "type_a", "provider": "provider_a", "arguments": { "a": 0 }, "id": "id_a", "title": "title_a", "youtube_id": None, "tracks": [], "synced": None, "uploaded": None, } self.assertDictEqual(expected, actual) expected = ( "eyJhcmd1bWVudHMiOiB7ImEiOiAwfSwgInByb3ZpZGVyIjogInByb3ZpZG" "VyX2EiLCAidHlwZSI6ICJ0eXBlX2EiLCAidGl0bGUiOiAidGl0bGVfYSJ9") self.assertEqual(expected, playlist.mime) expected = { "arguments": { "a": 0 }, "provider": "provider_a", "type": "type_a", "title": "title_a", } self.assertEqual(expected, json.loads(base64.b64decode(playlist.mime.encode())))
def test_artist_playlist(self, create_playlist, artist_param, fetch_tracks): artist_param.return_value = "Queen" create_playlist.return_value = PlaylistFixture.one() result = self.runner.invoke( cli, ["add", "lastfm", "artist-playlist"], input="Queen\n50\nQueen....", catch_exceptions=False, ) expected_output = ( "Artist: Queen", "Maximum tracks [50]: 50", "Title: Queen....", "Added playlist: id_a!", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) create_playlist.assert_called_once_with( dict( type=PlaylistType.ARTIST, provider=Provider.lastfm, arguments=dict(limit=50, artist="Queen"), title="Queen....", )) fetch_tracks.assert_called_once_with("id_a")
def test_get_playlists(self, get_client): playlist = PlaylistFixture.one() list = get_client.return_value.playlists.return_value.list list.return_value.execute.side_effect = [ { "nextPageToken": 2, "items": [ { "id": "a", "snippet": { "description": playlist.mime, "title": "One", }, }, {"snippet": {"description": "", "title": ""}}, ], }, {"items": [{"snippet": {"description": "", "title": ""}}]}, ] actual = YouService.get_playlists() self.assertEqual(1, len(actual)) self.assertEqual("One", actual[0].title) list.assert_has_calls( [ mock.call(part="snippet", mine=True, maxResults=2), mock.call().execute(), mock.call( part="snippet", mine=True, maxResults=2, pageToken=2 ), mock.call().execute(), ] ) self.assertEqual(6, YouService.get_quota_usage())
def test_show_playlist(self, get_playlist, get_track): playlist = PlaylistFixture.one(tracks=[1, 2, 3]) get_playlist.return_value = playlist get_track.side_effect = TrackFixture.get(3, youtube_id=[None, "a", ""]) result = self.runner.invoke(cli, ["show", playlist.id]) expected_output = ( "ID: id_a", " Provider: provider_a", " Title: title_a", " Type: type_a", "Arguments: a: 0", " Synced: -", " Uploaded: -", " Youtube: -", " Tracks:", "", "No Artist Track Name Youtube", "---- -------- ------------ ---------", "0 artist_a name_a -", "1 artist_b name_b ✔", "2 artist_c name_c -", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) get_playlist.assert_called_once_with(playlist.id) get_track.assert_has_calls([mock.call(id) for id in playlist.tracks])
def test_show_playlist_mime(self, get_playlist): playlist = PlaylistFixture.one(tracks=[1, 2, 3]) get_playlist.return_value = playlist result = self.runner.invoke(cli, ["show", playlist.id, "--mime"]) expected_output = ( "ID: id_a", " Provider: provider_a", " Title: title_a", " Type: type_a", "Arguments: a: 0", " Synced: -", " Uploaded: -", " Youtube: -", " Mime: eyJhcmd1bWVudHMiOiB7ImEiOiAwfSwgInByb3ZpZGVyIjogInByb3ZpZGVyX2EiLCAidHlwZSI6ICJ0eXBlX2EiLCAidGl0bGUiOiAidGl0bGVfYSJ9", "", "You reached the 10 playlists limit per day on youtube?", "Create a playlist manually and add in the bottom the above mime string", "The mime is base64 signature that pytuber uses to link with youtube playlists", 'Use "pytuber fetch youtube --playlists" to sync, before you try to push any tracks', ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) get_playlist.assert_called_once_with(playlist.id)
def test_user_playlist(self, create_playlist, convert, fetch_tracks): convert.return_value = "bbb" create_playlist.return_value = PlaylistFixture.one() result = self.runner.invoke( cli, ["add", "lastfm", "user-playlist"], input="\n".join(("aaa", "2", "50", "My Favorite ")), catch_exceptions=False, ) expected_output = ( "Last.fm username: aaa", "Playlist Types", "[1] User Loved Tracks", "[2] User Top Tracks", "[3] User Recent Tracks", "[4] User Friends Recent Tracks", "Select a playlist type 1-4: 2", "Maximum tracks [50]: 50", "Title: My Favorite ", "Added playlist: id_a!", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) create_playlist.assert_called_once_with( dict( type=UserPlaylistType.USER_TOP_TRACKS, provider=Provider.lastfm, arguments=dict(limit=50, username="******"), title="My Favorite", )) fetch_tracks.assert_called_once_with("id_a")
def test_get_playlist_items(self, get_client): playlist = PlaylistFixture.one() list = get_client.return_value.playlistItems.return_value.list list.return_value.execute.side_effect = [ { "nextPageToken": 3, "items": [ { "id": "a", "contentDetails": {"videoId": "va"}, "snippet": {"title": "foo - bar"}, }, { "id": "b", "contentDetails": {"videoId": "vb"}, "snippet": {"title": "thug life"}, }, ], }, { "items": [ { "id": "c", "contentDetails": {"videoId": "vc"}, "snippet": {"title": "a-b-c"}, } ] }, ] actual = YouService.get_playlist_items(playlist) expected = [ {"artist": "foo", "id": "a", "name": "bar", "video_id": "va"}, {"artist": "", "id": "b", "name": "thug life", "video_id": "vb"}, {"artist": "a", "id": "c", "name": "b-c", "video_id": "vc"}, ] self.assertEqual(expected, [a.asdict() for a in actual]) list.assert_has_calls( [ mock.call( part="contentDetails,snippet", maxResults=2, playlistId=playlist.youtube_id, ), mock.call().execute(), mock.call( part="contentDetails,snippet", maxResults=2, playlistId=playlist.youtube_id, pageToken=3, ), mock.call().execute(), ] ) self.assertEqual(10, YouService.get_quota_usage())
def test_with_tracks( self, find_playlists, update_playlist, find_tracks, get_playlist_items, create_playlist_item, remove_playlist_item, timestamp, ): timestamp.return_value = 101 items = PlaylistItemFixture.get(4, video_id=["$a", "$d", "$e", "$f"]) tracks = TrackFixture.get( 6, youtube_id=["$a", "$b", "$c", "$d", "$e", "$f"]) p_one, p_two = PlaylistFixture.get(2, tracks=[["id_a", "id_b", "id_c"], ["id_d", "id_e", "id_f"]]) find_playlists.return_value = [p_one, p_two] find_tracks.side_effect = [tracks[:3], tracks[3:]] get_playlist_items.side_effect = [ [items[0], items[2]], [items[1], items[2], items[3]], ] result = self.runner.invoke(cli, ["push", "youtube", "--tracks"], catch_exceptions=False) expected_output = ( "Syncing playlists", "Fetching playlist items: title_a", "Adding new playlist items: 2", "Removing playlist items: 1", "Fetching playlist items: title_b", "Adding new playlist items", "Removing playlist items", ) self.assertEqual(0, result.exit_code) self.assertOutputContains(expected_output, result.output) get_playlist_items.assert_has_calls( [mock.call(p_one), mock.call(p_two)]) create_playlist_item.assert_has_calls([ mock.call(p_one, tracks[1].youtube_id), mock.call(p_one, tracks[2].youtube_id), ]) remove_playlist_item.assert_called_once_with(items[2]) update_playlist.assert_called_once_with(p_one, dict(uploaded=101))
def test_removes_orphan_tracks_and_empty_playlists(self): [TrackManager.set(t.asdict()) for t in TrackFixture.get(2)] [PlaylistManager.set(p.asdict()) for p in PlaylistFixture.get(3)] playlist = PlaylistFixture.one(num=50) track = TrackFixture.one(num=5) playlist.tracks = [track.id] PlaylistManager.set(playlist.asdict()) TrackManager.set(track.asdict()) result = self.runner.invoke(cli, ["clean"]) expected_output = ( "Cleanup removed:", " Tracks: 2", "Playlists: 3", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) self.assertEqual(track.id, TrackManager.find()[0].id) self.assertEqual(playlist.id, PlaylistManager.find()[0].id)
def test_create_playlist(self, get_client): playlist = PlaylistFixture.one() insert = get_client.return_value.playlists.return_value.insert insert.return_value.execute.return_value = {"id": "101"} self.assertEqual("101", YouService.create_playlist(playlist)) insert.assert_called_once_with( body=dict( snippet=dict(title=playlist.title, description=playlist.mime), status=dict(privacyStatus="private"), ), part="snippet,status", ) self.assertEqual(55, YouService.get_quota_usage())
def test_with_playlists(self, find, update, create_playlist): p_one, p_two = PlaylistFixture.get(2) find.return_value = [p_one, p_two] create_playlist.side_effect = ["y1", "y2"] result = self.runner.invoke(cli, ["push", "youtube", "--playlists"], catch_exceptions=False) expected_messages = ("Creating playlists: 2/2", ) self.assertEqual(0, result.exit_code) self.assertOutputContains(expected_messages, result.output) create_playlist.assert_has_calls([mock.call(p_one), mock.call(p_two)]) update.assert_has_calls([ mock.call(p_one, dict(youtube_id="y1")), mock.call(p_two, dict(youtube_id="y2")), ])
def test_create_playlist_item(self, get_client): playlist = PlaylistFixture.one(youtube_id="b") insert = get_client.return_value.playlistItems.return_value.insert insert.return_value.execute.return_value = "foo" self.assertEqual( "foo", YouService.create_playlist_item(playlist, "aa") ) insert.assert_called_once_with( body=dict( snippet=dict( playlistId=playlist.youtube_id, resourceId=dict(kind="youtube#video", videoId="aa"), ) ), part="snippet", ) self.assertEqual(53, YouService.get_quota_usage())
def test_list_playlists(self, find): find.return_value = PlaylistFixture.get( 2, youtube_id=["456ybnm", None], synced=[None, 1546727285], uploaded=[None, 1546727385], tracks=[[], list(range(0, 99))], ) result = self.runner.invoke(cli, ["list"]) expected_output = ( "ID Title Provider Youtube Tracks", "---- ------- ---------- --------- --------", "id_a title_a provider_a ✔ 0", "id_b title_b provider_b - 99", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) find.assert_called_once_with()
def test_with_tracks(self, find, update, get_tracks, get_tags, set): tracks = TrackFixture.get(6) playlists = PlaylistFixture.get(2) last_tracks = [ pydrag.Track.from_dict(dict(name=track.name, artist=track.artist)) for track in tracks ] set.side_effect = tracks find.return_value = playlists get_tracks.side_effect = [ [last_tracks[0], last_tracks[1], last_tracks[2]], [last_tracks[3], last_tracks[4], last_tracks[5]], ] result = self.runner.invoke(cli, ["fetch", "lastfm", "--tracks"]) self.assertEqual(0, result.exit_code) get_tags.assert_called_once_with() find.assert_called_once_with(provider=Provider.lastfm) get_tracks.assert_has_calls( [mock.call(a=0, type="type_a"), mock.call(b=1, type="type_b")] ) set.assert_has_calls( [ mock.call({"artist": "artist_a", "name": "name_a"}), mock.call({"artist": "artist_b", "name": "name_b"}), mock.call({"artist": "artist_c", "name": "name_c"}), mock.call({"artist": "artist_d", "name": "name_d"}), mock.call({"artist": "artist_e", "name": "name_e"}), mock.call({"artist": "artist_f", "name": "name_f"}), ] ) update.assert_has_calls( [ mock.call(playlists[0], dict(tracks=["id_a", "id_b", "id_c"])), mock.call(playlists[1], dict(tracks=["id_d", "id_e", "id_f"])), ] )
def test_chart_playlist(self, create_playlist, fetch_tracks): create_playlist.return_value = PlaylistFixture.one() result = self.runner.invoke(cli, ["add", "lastfm", "chart-playlist"], input="50\n ") expected_output = ( "Maximum tracks [50]: 50", "Title: ", "Added playlist: id_a!", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) create_playlist.assert_called_once_with( dict( type=PlaylistType.CHART, provider=Provider.lastfm, arguments=dict(limit=50), title="", )) fetch_tracks.assert_called_once_with("id_a")
def test_fetch_playlists( self, get_playlists, get_playlist_items, set_playlist, exists, set_tracks, ): exists.side_effect = [True, False] p_one, p_two = PlaylistFixture.get(2) v_one, v_two = PlaylistItemFixture.get(2) get_playlists.return_value = [p_one, p_two] get_playlist_items.return_value = [v_one, v_two] set_tracks.side_effect = TrackFixture.get(2) result = self.runner.invoke(cli, ["fetch", "youtube", "--playlists"], catch_exceptions=False) expected_messages = ("Fetching playlists info", ) self.assertEqual(0, result.exit_code) self.assertOutputContains(expected_messages, result.output) p_two.tracks = ["id_a", "id_b"] get_playlists.assert_called_once_with() set_playlist.assert_has_calls( [mock.call(p_one.asdict()), mock.call(p_two.asdict())]) set_tracks.assert_has_calls([ mock.call({ "artist": "artist_a", "name": "name_a", "youtube_id": "video_id_a", }), mock.call({ "artist": "artist_b", "name": "name_b", "youtube_id": "video_id_b", }), ])
def test_create_playlist(self, clear, secho, confirm, set, magenta): magenta.side_effect = lambda x: x set.return_value = PlaylistFixture.one() tracks = [ ("Queen", "Bohemian Rhapsody"), ("Queen", "I want to break free"), ] create_playlist( title="My Cool Playlist", tracks=tracks, type="foo", arguments=dict(foo="bar"), ) expected_ouput = ( "Title: My Cool Playlist", "Tracks: 2", "", " No Artist Track Name", "---- -------- --------------------", " 1 Queen Bohemian Rhapsody", " 2 Queen I want to break free", ) self.assertOutput(expected_ouput, secho.call_args_list[0][0][0]) self.assertEqual("Added playlist: id_a!", secho.call_args_list[1][0][0]) clear.assert_called_once_with() confirm.assert_called_once_with( "Are you sure you want to save this playlist?", abort=True) set.assert_called_once_with( dict( type="foo", arguments=dict(foo="bar"), provider=Provider.user, title="My Cool Playlist", tracks=["55a4d2b", "b045fee"], ))
def test_tag_playlist(self, create_playlist, convert, fetch_tracks): convert.return_value = "rock" create_playlist.return_value = PlaylistFixture.one(synced=111) result = self.runner.invoke(cli, ["add", "lastfm", "tag-playlist"], input="rock\n50\n ") expected_output = ( "Tag: rock", "Maximum tracks [50]: 50", "Title: ", "Updated playlist: id_a!", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) create_playlist.assert_called_once_with( dict( type=PlaylistType.TAG, provider=Provider.lastfm, arguments=dict(limit=50, tag="rock"), title="", )) fetch_tracks.assert_called_once_with("id_a")
def test_country_playlist(self, create_playlist, country_param_type, fetch_tracks): country_param_type.return_value = "greece" create_playlist.return_value = PlaylistFixture.one() result = self.runner.invoke(cli, ["add", "lastfm", "country-playlist"], input=b"gr\n50\n ") expected_output = ( "Country Code: gr", "Maximum tracks [50]: 50", "Title: ", "Added playlist: id_a!", ) self.assertEqual(0, result.exit_code) self.assertOutput(expected_output, result.output) create_playlist.assert_called_once_with( dict( type=PlaylistType.COUNTRY, provider=Provider.lastfm, arguments=dict(limit=50, country="greece"), title="", )) fetch_tracks.assert_called_once_with("id_a")
def test_complete(self): [PlaylistManager.set(p.asdict()) for p in PlaylistFixture.get(2)] self.assertEqual(["id_a", "id_b"], self.param.complete(None, "")) self.assertEqual(["id_a"], self.param.complete(None, "id_a"))