feat: add recommendation service adapters

This commit is contained in:
Justin Visser 2026-08-10 12:05:59 +02:00
parent e970bdf542
commit 751391e6a2
9 changed files with 676 additions and 26 deletions

View file

@ -228,6 +228,31 @@ def test_search_maps_valid_fields_and_drops_malformed_item() -> None:
asyncio.run(run())
def test_taste_endpoints_map_supported_response_shapes() -> None:
async def run() -> None:
async def handler(request: httpx2.Request) -> httpx2.Response:
if request.url.path == "/v1/me/top/artists":
assert request.url.params["time_range"] == "short_term"
return httpx2.Response(200, json={"items": [{"name": "Top Artist"}]})
if request.url.path == "/v1/me/top/tracks":
return httpx2.Response(200, json={"items": [_track_payload()]})
assert request.url.path == "/v1/me/tracks"
assert request.url.params["offset"] == "0"
return httpx2.Response(200, json={"items": [{"track": _track_payload()}]})
async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as http:
client = _client(http)
artists = await client.fetch_top_artists("short_term", 50)
top_tracks = await client.fetch_top_tracks("long_term", 50)
saved_tracks = await client.fetch_saved_tracks(100)
assert artists == ["Top Artist"]
assert [track.id for track in top_tracks] == ["track-1"]
assert [track.id for track in saved_tracks] == ["track-1"]
asyncio.run(run())
async def _search_with_handler(handler: TransportHandler) -> list[Track]:
async with httpx2.AsyncClient(transport=httpx2.MockTransport(handler)) as http:
return list(await _client(http).search_tracks("mapped"))
@ -251,18 +276,22 @@ def _search_payload() -> dict[str, object]:
"tracks": {
"total": 0,
"items": [
{
"id": "track-1",
"uri": "spotify:track:1",
"name": "Mapped song",
"artists": [{"name": "First artist"}, {"name": "Second artist"}],
"album": {
"name": "Mapped album",
"images": [{"url": "https://images.example/cover.jpg"}],
},
"external_urls": {"spotify": "https://open.spotify.com/track/track-1"},
},
_track_payload(),
{"id": "missing-required-fields"},
],
}
}
def _track_payload() -> dict[str, object]:
return {
"id": "track-1",
"uri": "spotify:track:1",
"name": "Mapped song",
"artists": [{"name": "First artist"}, {"name": "Second artist"}],
"album": {
"name": "Mapped album",
"images": [{"url": "https://images.example/cover.jpg"}],
},
"external_urls": {"spotify": "https://open.spotify.com/track/track-1"},
}