Skip to content

Commit b92c2c3

Browse files
authored
Add method to check if audiobooks are saved (#480)
1 parent 0b2207b commit b92c2c3

File tree

4 files changed

+74
-1
lines changed

4 files changed

+74
-1
lines changed

src/spotifyaio/spotify.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,18 @@ async def remove_saved_audiobooks(self, audiobook_ids: list[str]) -> None:
333333
}
334334
await self._delete("v1/me/audiobooks", params=params)
335335

336-
# Check if one or more audiobooks is already saved
336+
async def are_audiobooks_saved(self, audiobook_ids: list[str]) -> dict[str, bool]:
337+
"""Check if audiobooks are saved."""
338+
if not audiobook_ids:
339+
return {}
340+
if len(audiobook_ids) > 50:
341+
msg = "Maximum of 50 audiobooks can be checked at once"
342+
raise ValueError(msg)
343+
identifiers = [get_identifier(i) for i in audiobook_ids]
344+
params: dict[str, Any] = {"ids": ",".join(identifiers)}
345+
response = await self._get("v1/me/audiobooks/contains", params=params)
346+
body: list[bool] = orjson.loads(response) # pylint: disable=no-member
347+
return dict(zip(identifiers, body))
337348

338349
async def get_categories(self) -> list[Category]:
339350
"""Get list of categories."""

tests/__snapshots__/test_spotify.ambr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
# serializer version: 1
2+
# name: test_check_saved_audiobooks
3+
dict({
4+
'18yVqkdbdRvS24c0Ilj2ci': False,
5+
'1HGw3J3NxZO1TP1BTtVhpZ': False,
6+
'7iHfbu1YPACw6oZPAFJtqe': False,
7+
})
8+
# ---
29
# name: test_checking_saved_albums
310
dict({
411
'1A2GTWGtFfWp7KSQTwWOyo': False,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[
2+
false,
3+
false,
4+
false
5+
]

tests/test_spotify.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,56 @@ async def test_remove_too_many_audiobooks(
15401540
responses.assert_not_called() # type: ignore[no-untyped-call]
15411541

15421542

1543+
async def test_check_saved_audiobooks(
1544+
responses: aioresponses,
1545+
snapshot: SnapshotAssertion,
1546+
authenticated_client: SpotifyClient,
1547+
) -> None:
1548+
"""Test checking saved audiobooks."""
1549+
responses.get(
1550+
f"{SPOTIFY_URL}/v1/me/audiobooks/contains?ids=18yVqkdbdRvS24c0Ilj2ci,"
1551+
f"1HGw3J3NxZO1TP1BTtVhpZ,7iHfbu1YPACw6oZPAFJtqe",
1552+
status=200,
1553+
body=load_fixture("audiobooks_saved.json"),
1554+
)
1555+
response = await authenticated_client.are_audiobooks_saved(
1556+
["18yVqkdbdRvS24c0Ilj2ci", "1HGw3J3NxZO1TP1BTtVhpZ", "7iHfbu1YPACw6oZPAFJtqe"]
1557+
)
1558+
assert response == snapshot
1559+
responses.assert_called_once_with(
1560+
f"{SPOTIFY_URL}/v1/me/audiobooks/contains",
1561+
METH_GET,
1562+
headers=HEADERS,
1563+
params={
1564+
"ids": "18yVqkdbdRvS24c0Ilj2ci,"
1565+
"1HGw3J3NxZO1TP1BTtVhpZ,"
1566+
"7iHfbu1YPACw6oZPAFJtqe"
1567+
},
1568+
json=None,
1569+
)
1570+
1571+
1572+
async def test_check_no_saved_audiobooks(
1573+
responses: aioresponses,
1574+
authenticated_client: SpotifyClient,
1575+
) -> None:
1576+
"""Test checking no saved audiobooks."""
1577+
assert await authenticated_client.are_audiobooks_saved([]) == {}
1578+
responses.assert_not_called() # type: ignore[no-untyped-call]
1579+
1580+
1581+
async def test_check_too_many_saved_audiobooks(
1582+
responses: aioresponses,
1583+
authenticated_client: SpotifyClient,
1584+
) -> None:
1585+
"""Test checking too many saved audiobooks."""
1586+
with pytest.raises(
1587+
ValueError, match="Maximum of 50 audiobooks can be checked at once"
1588+
):
1589+
await authenticated_client.are_audiobooks_saved(["abc"] * 51)
1590+
responses.assert_not_called() # type: ignore[no-untyped-call]
1591+
1592+
15431593
async def test_get_show_episodes(
15441594
responses: aioresponses,
15451595
snapshot: SnapshotAssertion,

0 commit comments

Comments
 (0)