A kind of initial commit
This commit is contained in:
136
tests/test_spotify_client.py
Normal file
136
tests/test_spotify_client.py
Normal file
@@ -0,0 +1,136 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
|
||||
import httpx
|
||||
|
||||
from app.clients.spotify import SpotifyClient
|
||||
|
||||
|
||||
class RecordingHttpClient:
|
||||
def __init__(self, responses: list[httpx.Response]) -> None:
|
||||
self._responses = list(responses)
|
||||
self.calls: list[dict] = []
|
||||
|
||||
async def request(self, method: str, url: str, **kwargs):
|
||||
self.calls.append(
|
||||
{
|
||||
"method": method,
|
||||
"url": url,
|
||||
"headers": kwargs.get("headers"),
|
||||
"params": kwargs.get("params"),
|
||||
"json": kwargs.get("json"),
|
||||
}
|
||||
)
|
||||
if not self._responses:
|
||||
raise AssertionError("No queued response for request")
|
||||
return self._responses.pop(0)
|
||||
|
||||
|
||||
def make_response(method: str, url: str, status_code: int, *, json_body=None, text_body: str | None = None) -> httpx.Response:
|
||||
request = httpx.Request(method, url)
|
||||
if json_body is not None:
|
||||
return httpx.Response(status_code, request=request, json=json_body)
|
||||
return httpx.Response(status_code, request=request, text=text_body or "")
|
||||
|
||||
|
||||
def make_client(http_client: RecordingHttpClient) -> SpotifyClient:
|
||||
settings = SimpleNamespace(
|
||||
spotify_client_id="id",
|
||||
spotify_client_secret="secret",
|
||||
spotify_redirect_uri="https://example.test/callback",
|
||||
)
|
||||
return SpotifyClient(settings, http_client) # type: ignore[arg-type]
|
||||
|
||||
|
||||
class SpotifyClientPlaylistTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_create_playlist_uses_me_endpoint(self) -> None:
|
||||
http_client = RecordingHttpClient(
|
||||
[
|
||||
make_response(
|
||||
"POST",
|
||||
"https://api.spotify.com/v1/me/playlists",
|
||||
201,
|
||||
json_body={
|
||||
"id": "pl1",
|
||||
"name": "Test Playlist",
|
||||
"external_urls": {"spotify": "https://open.spotify.com/playlist/pl1"},
|
||||
},
|
||||
)
|
||||
]
|
||||
)
|
||||
client = make_client(http_client)
|
||||
|
||||
payload = await client.create_playlist(
|
||||
"token",
|
||||
user_id="user123",
|
||||
name="Test Playlist",
|
||||
description="desc",
|
||||
public=False,
|
||||
)
|
||||
|
||||
self.assertEqual(payload["id"], "pl1")
|
||||
self.assertEqual(len(http_client.calls), 1)
|
||||
call = http_client.calls[0]
|
||||
self.assertEqual(call["method"], "POST")
|
||||
self.assertEqual(call["url"], "https://api.spotify.com/v1/me/playlists")
|
||||
self.assertEqual(call["json"], {"name": "Test Playlist", "description": "desc", "public": False})
|
||||
self.assertEqual(call["headers"]["Authorization"], "Bearer token")
|
||||
|
||||
async def test_delete_playlist_calls_followers_delete(self) -> None:
|
||||
http_client = RecordingHttpClient(
|
||||
[
|
||||
make_response(
|
||||
"DELETE",
|
||||
"https://api.spotify.com/v1/playlists/pl123/followers",
|
||||
200,
|
||||
text_body="",
|
||||
)
|
||||
]
|
||||
)
|
||||
client = make_client(http_client)
|
||||
|
||||
await client.delete_playlist("token", "pl123")
|
||||
|
||||
self.assertEqual(len(http_client.calls), 1)
|
||||
call = http_client.calls[0]
|
||||
self.assertEqual(call["method"], "DELETE")
|
||||
self.assertEqual(call["url"], "https://api.spotify.com/v1/playlists/pl123/followers")
|
||||
self.assertEqual(call["headers"]["Authorization"], "Bearer token")
|
||||
self.assertIsNone(call["json"])
|
||||
|
||||
async def test_add_playlist_items_uses_items_endpoint_and_chunks(self) -> None:
|
||||
uris = [f"spotify:track:{i:02d}" for i in range(101)]
|
||||
http_client = RecordingHttpClient(
|
||||
[
|
||||
make_response(
|
||||
"POST",
|
||||
"https://api.spotify.com/v1/playlists/pl999/items",
|
||||
201,
|
||||
json_body={"snapshot_id": "snap1"},
|
||||
),
|
||||
make_response(
|
||||
"POST",
|
||||
"https://api.spotify.com/v1/playlists/pl999/items",
|
||||
201,
|
||||
json_body={"snapshot_id": "snap2"},
|
||||
),
|
||||
]
|
||||
)
|
||||
client = make_client(http_client)
|
||||
|
||||
await client.add_playlist_items("token", "pl999", uris)
|
||||
|
||||
self.assertEqual(len(http_client.calls), 2)
|
||||
first, second = http_client.calls
|
||||
self.assertEqual(first["method"], "POST")
|
||||
self.assertEqual(first["url"], "https://api.spotify.com/v1/playlists/pl999/items")
|
||||
self.assertEqual(second["url"], "https://api.spotify.com/v1/playlists/pl999/items")
|
||||
self.assertEqual(len(first["json"]["uris"]), 100)
|
||||
self.assertEqual(len(second["json"]["uris"]), 1)
|
||||
self.assertEqual(first["headers"]["Authorization"], "Bearer token")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user