From 03948aeab93df47b9441ec6ff98bcb8f961ed612 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Mon, 11 Nov 2024 16:58:11 +0100 Subject: [PATCH] Remove local file support (#394) --- src/spotifyaio/models.py | 13 ++ tests/__snapshots__/test_spotify.ambr | 116 +++++++++- tests/fixtures/playback_4.json | 67 ++++++ .../{playlist.json => playlist_1.json} | 0 tests/fixtures/playlist_2.json | 200 ++++++++++++++++++ tests/test_spotify.py | 13 +- 6 files changed, 405 insertions(+), 4 deletions(-) create mode 100644 tests/fixtures/playback_4.json rename tests/fixtures/{playlist.json => playlist_1.json} (100%) create mode 100644 tests/fixtures/playlist_2.json diff --git a/src/spotifyaio/models.py b/src/spotifyaio/models.py index a783e87..8fce915 100644 --- a/src/spotifyaio/models.py +++ b/src/spotifyaio/models.py @@ -322,6 +322,13 @@ class CurrentPlaying(DataClassORJSONMixin): item: Annotated[Item, Discriminator(field="type", include_subtypes=True)] | None currently_playing_type: str | None + @classmethod + def __pre_deserialize__(cls, d: dict[str, Any]) -> dict[str, Any]: + """Pre deserialize hook.""" + if (item := d.get("item")) is not None and item.get("is_local"): + return {**d, "item": None} + return d + @dataclass class PlaybackState(CurrentPlaying): @@ -386,6 +393,12 @@ class PlaylistTracks(DataClassORJSONMixin): items: list[PlaylistTrack] + @classmethod + def __pre_deserialize__(cls, d: dict[str, Any]) -> dict[str, Any]: + """Pre deserialize hook.""" + items = [item for item in d["items"] if not item["is_local"]] + return {"items": items} + @dataclass class PlaylistTrack(DataClassORJSONMixin): diff --git a/tests/__snapshots__/test_spotify.ambr b/tests/__snapshots__/test_spotify.ambr index cd438a9..95c1c1e 100644 --- a/tests/__snapshots__/test_spotify.ambr +++ b/tests/__snapshots__/test_spotify.ambr @@ -4117,7 +4117,6 @@ 'description': ''' Author(s): Frank Herbert Narrator(s): Scott Brick, Orlagh Cassidy, Euan Morton, Ilyana Kadushin, Simon Vance -

NOW A MAJOR MOTION PICTURE directed by Denis Villeneuve, starring Timothée Chalamet, Zendaya, Rebecca Ferguson, Javier Bardem, Josh Brolin, Austin Butler, Florence Pugh, Dave Bautista, Christopher Walken, Léa Seydoux, Stellan Skarsgård, and Charlotte Rampling

Set on the desert planet Arrakis, Dune is the story of the boy Paul Atreides, who would become the mysterious man known as Muad'dib. He would avenge the traitorous plot against his noble family—and would bring to fruition humankind's most ancient and unattainable dream.

A stunning blend of adventure and mysticism, environmentalism and politics, Dune won the first Nebula Award, shared the Hugo Award, and formed the basis of what is undoubtedly the grandest epic in science fiction. Frank Herbert's death in 1986 was a tragic loss, yet the astounding legacy of his visionary fiction will live forever.

''', 'edition': 'Unabridged', @@ -9383,6 +9382,27 @@ 'shuffle': False, }) # --- +# name: test_get_playback_state[playback_4.json] + dict({ + 'context': None, + 'currently_playing_type': 'track', + 'device': dict({ + 'device_id': 'aee274e4bbe6b44cf3b22ad3b68eca3a6954a701', + 'device_type': , + 'is_active': True, + 'is_private_session': False, + 'is_restricted': False, + 'name': 'Joost’s MacBook Pro', + 'supports_volume': True, + 'volume_percent': 67, + }), + 'is_playing': True, + 'item': None, + 'progress_ms': 22215, + 'repeat_mode': , + 'shuffle': False, + }) +# --- # name: test_get_playback_state[playback_audiobook_1.json] dict({ 'context': dict({ @@ -9571,7 +9591,7 @@ 'shuffle': False, }) # --- -# name: test_get_playlist +# name: test_get_playlist[playlist_1.json] dict({ 'collaborative': False, 'description': 'A playlist for testing pourposes', @@ -9891,6 +9911,98 @@ 'uri': 'spotify:playlist:3cEYpjA9oz9GiPac4AsH4n', }) # --- +# name: test_get_playlist[playlist_2.json] + dict({ + 'collaborative': False, + 'description': '', + 'external_urls': dict({ + 'spotify': 'https://open.spotify.com/playlist/3toMXYM91T55pKzuysH5Ph', + }), + 'images': list([ + dict({ + 'height': None, + 'url': 'https://i.scdn.co/image/ab67616d00001e022f9b47bdc2b1c7cae7b014af', + 'width': None, + }), + ]), + 'name': 'Starred', + 'object_type': 'playlist', + 'owner': dict({ + 'display_name': 'chadandcaren', + 'external_urls': dict({ + 'spotify': 'https://open.spotify.com/user/chadandcaren', + }), + 'href': 'https://api.spotify.com/v1/users/chadandcaren', + 'object_type': 'user', + 'owner_id': 'chadandcaren', + 'uri': 'spotify:user:chadandcaren', + }), + 'playlist_id': '3toMXYM91T55pKzuysH5Ph', + 'public': True, + 'tracks': dict({ + 'items': list([ + dict({ + 'track': dict({ + 'album': dict({ + 'album_id': '3KVfMVtOmoVCgihLE4HoBr', + 'album_type': , + 'artists': list([ + dict({ + 'artist_id': '2vm8GdHyrJh2O2MfbQFYG0', + 'name': 'Ingrid Michaelson', + 'uri': 'spotify:artist:2vm8GdHyrJh2O2MfbQFYG0', + }), + ]), + 'images': list([ + dict({ + 'height': 640, + 'url': 'https://i.scdn.co/image/ab67616d0000b273866dc0fd5fbfd51fd4c50919', + 'width': 640, + }), + dict({ + 'height': 300, + 'url': 'https://i.scdn.co/image/ab67616d00001e02866dc0fd5fbfd51fd4c50919', + 'width': 300, + }), + dict({ + 'height': 64, + 'url': 'https://i.scdn.co/image/ab67616d00004851866dc0fd5fbfd51fd4c50919', + 'width': 64, + }), + ]), + 'name': 'Be OK', + 'release_date': '2008-01-01', + 'release_date_precision': , + 'total_tracks': 11, + 'uri': 'spotify:album:3KVfMVtOmoVCgihLE4HoBr', + }), + 'artists': list([ + dict({ + 'artist_id': '2vm8GdHyrJh2O2MfbQFYG0', + 'name': 'Ingrid Michaelson', + 'uri': 'spotify:artist:2vm8GdHyrJh2O2MfbQFYG0', + }), + ]), + 'disc_number': 1, + 'duration_ms': 148706, + 'explicit': False, + 'external_urls': dict({ + 'spotify': 'https://open.spotify.com/track/4oeRfmp9XpKWym6YD1WvBP', + }), + 'href': 'https://api.spotify.com/v1/tracks/4oeRfmp9XpKWym6YD1WvBP', + 'is_local': False, + 'name': 'You and I', + 'track_id': '4oeRfmp9XpKWym6YD1WvBP', + 'track_number': 10, + 'type': , + 'uri': 'spotify:track:4oeRfmp9XpKWym6YD1WvBP', + }), + }), + ]), + }), + 'uri': 'spotify:playlist:3toMXYM91T55pKzuysH5Ph', + }) +# --- # name: test_get_recently_played_tracks list([ dict({ diff --git a/tests/fixtures/playback_4.json b/tests/fixtures/playback_4.json new file mode 100644 index 0000000..59f0c49 --- /dev/null +++ b/tests/fixtures/playback_4.json @@ -0,0 +1,67 @@ +{ + "device": { + "id": "aee274e4bbe6b44cf3b22ad3b68eca3a6954a701", + "is_active": true, + "is_private_session": false, + "is_restricted": false, + "name": "Joost’s MacBook Pro", + "supports_volume": true, + "type": "Computer", + "volume_percent": 67 + }, + "shuffle_state": false, + "smart_shuffle": false, + "repeat_state": "off", + "timestamp": 1731336494187, + "context": null, + "progress_ms": 22215, + "item": { + "album": { + "album_type": null, + "artists": [], + "available_markets": [], + "external_urls": {}, + "href": null, + "id": null, + "images": [], + "name": "", + "release_date": null, + "release_date_precision": null, + "type": "album", + "uri": null + }, + "artists": [ + { + "external_urls": {}, + "href": null, + "id": null, + "name": "Four Tet x Fred again.. x Skrillex", + "type": "artist", + "uri": null + } + ], + "available_markets": [], + "disc_number": 0, + "duration_ms": 5432000, + "explicit": false, + "external_ids": {}, + "external_urls": {}, + "href": null, + "id": null, + "is_local": true, + "name": "Coachella 2023", + "popularity": 0, + "preview_url": null, + "track_number": 0, + "type": "track", + "uri": "spotify:local:Four+Tet+x+Fred+again..+x+Skrillex::Coachella+2023:5432" + }, + "currently_playing_type": "track", + "actions": { + "disallows": { + "resuming": true, + "skipping_prev": true + } + }, + "is_playing": true +} diff --git a/tests/fixtures/playlist.json b/tests/fixtures/playlist_1.json similarity index 100% rename from tests/fixtures/playlist.json rename to tests/fixtures/playlist_1.json diff --git a/tests/fixtures/playlist_2.json b/tests/fixtures/playlist_2.json new file mode 100644 index 0000000..4cea3fb --- /dev/null +++ b/tests/fixtures/playlist_2.json @@ -0,0 +1,200 @@ +{ + "collaborative": false, + "description": "", + "external_urls": { + "spotify": "https://open.spotify.com/playlist/3toMXYM91T55pKzuysH5Ph" + }, + "followers": { + "href": null, + "total": 0 + }, + "href": "https://api.spotify.com/v1/playlists/3toMXYM91T55pKzuysH5Ph?locale=en-US%2Cen%3Bq%3D0.5", + "id": "3toMXYM91T55pKzuysH5Ph", + "images": [ + { + "height": null, + "url": "https://i.scdn.co/image/ab67616d00001e022f9b47bdc2b1c7cae7b014af", + "width": null + } + ], + "name": "Starred", + "owner": { + "display_name": "chadandcaren", + "external_urls": { + "spotify": "https://open.spotify.com/user/chadandcaren" + }, + "href": "https://api.spotify.com/v1/users/chadandcaren", + "id": "chadandcaren", + "type": "user", + "uri": "spotify:user:chadandcaren" + }, + "primary_color": null, + "public": true, + "snapshot_id": "AAAAAoRTkoeSGwZYJQxBuBVJ4+cWjJZf", + "tracks": { + "href": "https://api.spotify.com/v1/playlists/3toMXYM91T55pKzuysH5Ph/tracks?offset=0&limit=100&locale=en-US,en;q%3D0.5", + "items": [ + { + "added_at": "2013-01-19T21:31:09Z", + "added_by": { + "external_urls": { + "spotify": "https://open.spotify.com/user/chadandcaren" + }, + "href": "https://api.spotify.com/v1/users/chadandcaren", + "id": "chadandcaren", + "type": "user", + "uri": "spotify:user:chadandcaren" + }, + "is_local": true, + "primary_color": null, + "track": { + "album": { + "album_type": null, + "available_markets": [], + "external_urls": {}, + "href": null, + "id": null, + "images": [], + "name": "The Score", + "release_date": null, + "release_date_precision": null, + "type": "album", + "uri": null, + "artists": [] + }, + "artists": [ + { + "external_urls": {}, + "href": null, + "id": null, + "name": "Fugees (Refugee Camp)", + "type": "artist", + "uri": null + } + ], + "available_markets": [], + "explicit": false, + "preview_url": null, + "type": "track", + "disc_number": 0, + "external_ids": {}, + "external_urls": {}, + "href": null, + "id": null, + "duration_ms": 273000, + "name": "No Woman, No Cry", + "uri": "spotify:local:Fugees+%28Refugee+Camp%29:The+Score:No+Woman%2C+No+Cry:273", + "popularity": 0, + "track_number": 0, + "is_local": true + }, + "video_thumbnail": { + "url": null + } + }, + { + "added_at": "2013-01-19T22:16:08Z", + "added_by": { + "external_urls": { + "spotify": "https://open.spotify.com/user/chadandcaren" + }, + "href": "https://api.spotify.com/v1/users/chadandcaren", + "id": "chadandcaren", + "type": "user", + "uri": "spotify:user:chadandcaren" + }, + "is_local": false, + "primary_color": null, + "track": { + "preview_url": "https://p.scdn.co/mp3-preview/5327d47d3f8c601cc8e783aaed138669c6331e31?cid=cfe923b2d660439caf2b557b21f31221", + "available_markets": [], + "explicit": false, + "type": "track", + "episode": false, + "track": true, + "album": { + "available_markets": [], + "type": "album", + "album_type": "album", + "href": "https://api.spotify.com/v1/albums/3KVfMVtOmoVCgihLE4HoBr", + "id": "3KVfMVtOmoVCgihLE4HoBr", + "images": [ + { + "url": "https://i.scdn.co/image/ab67616d0000b273866dc0fd5fbfd51fd4c50919", + "width": 640, + "height": 640 + }, + { + "url": "https://i.scdn.co/image/ab67616d00001e02866dc0fd5fbfd51fd4c50919", + "width": 300, + "height": 300 + }, + { + "url": "https://i.scdn.co/image/ab67616d00004851866dc0fd5fbfd51fd4c50919", + "width": 64, + "height": 64 + } + ], + "name": "Be OK", + "release_date": "2008-01-01", + "release_date_precision": "day", + "uri": "spotify:album:3KVfMVtOmoVCgihLE4HoBr", + "artists": [ + { + "external_urls": { + "spotify": "https://open.spotify.com/artist/2vm8GdHyrJh2O2MfbQFYG0" + }, + "href": "https://api.spotify.com/v1/artists/2vm8GdHyrJh2O2MfbQFYG0", + "id": "2vm8GdHyrJh2O2MfbQFYG0", + "name": "Ingrid Michaelson", + "type": "artist", + "uri": "spotify:artist:2vm8GdHyrJh2O2MfbQFYG0" + } + ], + "external_urls": { + "spotify": "https://open.spotify.com/album/3KVfMVtOmoVCgihLE4HoBr" + }, + "total_tracks": 11 + }, + "artists": [ + { + "external_urls": { + "spotify": "https://open.spotify.com/artist/2vm8GdHyrJh2O2MfbQFYG0" + }, + "href": "https://api.spotify.com/v1/artists/2vm8GdHyrJh2O2MfbQFYG0", + "id": "2vm8GdHyrJh2O2MfbQFYG0", + "name": "Ingrid Michaelson", + "type": "artist", + "uri": "spotify:artist:2vm8GdHyrJh2O2MfbQFYG0" + } + ], + "disc_number": 1, + "track_number": 10, + "duration_ms": 148706, + "external_ids": { + "isrc": "ushm80865849" + }, + "external_urls": { + "spotify": "https://open.spotify.com/track/4oeRfmp9XpKWym6YD1WvBP" + }, + "href": "https://api.spotify.com/v1/tracks/4oeRfmp9XpKWym6YD1WvBP", + "id": "4oeRfmp9XpKWym6YD1WvBP", + "name": "You and I", + "popularity": 0, + "uri": "spotify:track:4oeRfmp9XpKWym6YD1WvBP", + "is_local": false + }, + "video_thumbnail": { + "url": null + } + } + ], + "limit": 100, + "next": null, + "offset": 0, + "previous": null, + "total": 2 + }, + "type": "playlist", + "uri": "spotify:playlist:3toMXYM91T55pKzuysH5Ph" +} diff --git a/tests/test_spotify.py b/tests/test_spotify.py index b34e29c..e0451f4 100644 --- a/tests/test_spotify.py +++ b/tests/test_spotify.py @@ -345,6 +345,7 @@ async def test_get_audiobooks( "playback_1.json", "playback_2.json", "playback_3.json", + "playback_4.json", "playback_episode_1.json", "playback_audiobook_1.json", ], @@ -830,16 +831,24 @@ async def test_get_album( ) +@pytest.mark.parametrize( + "fixture", + [ + "playlist_1.json", + "playlist_2.json", + ], +) async def test_get_playlist( responses: aioresponses, snapshot: SnapshotAssertion, authenticated_client: SpotifyClient, + fixture: str, ) -> None: """Test retrieving playlist.""" responses.get( f"{SPOTIFY_URL}/v1/playlists/37i9dQZF1DXcBWIGoYBM5M", status=200, - body=load_fixture("playlist.json"), + body=load_fixture(fixture), ) response = await authenticated_client.get_playlist("37i9dQZF1DXcBWIGoYBM5M") assert response == snapshot @@ -899,7 +908,7 @@ async def test_get_playlist_variation( responses.get( f"{SPOTIFY_URL}/v1/playlists/37i9dQZF1DXcBWIGoYBM5M", status=200, - body=load_fixture("playlist.json"), + body=load_fixture("playlist_1.json"), ) await authenticated_client.get_playlist(playlist_id) responses.assert_called_once_with(