import json import httpx import pytest from tag_albums.library import Album, MusicLibrary def test_search_albums_parses_music_assistant_response(): calls = [] def handler(request: httpx.Request) -> httpx.Response: calls.append(request) if request.url.path == "/api/config/config_entries/entry": return httpx.Response(200, json=[{"entry_id": "ma-entry"}]) body = json.loads(request.content) assert body == {"config_entry_id": "ma-entry", "name": "lateralus", "media_type": ["album"], "limit": 12} return httpx.Response(200, json={"service_response": {"albums": [ {"name": "Lateralus", "artists": [{"name": "Tool"}, {"name": "Guest"}], "image": "http://img/1"}, {"name": "No Artist", "artists": []}, ]}}) client = httpx.Client(base_url="http://ha", transport=httpx.MockTransport(handler)) library = MusicLibrary("http://ha", "token", client=client) albums = library.search_albums("lateralus") assert [(a.artist, a.album, a.image) for a in albums] == [ ("Tool", "Lateralus", "http://img/1"), ("", "No Artist", None), ] library.search_albums("lateralus") # The Music Assistant config entry is looked up once, then cached. assert sum(c.url.path == "/api/config/config_entries/entry" for c in calls) == 1 def _library_with_images(responses): seen = [] def handler(request: httpx.Request) -> httpx.Response: seen.append(request) return responses[str(request.url)] images = httpx.Client(transport=httpx.MockTransport(handler)) return MusicLibrary("http://ha", "ha-token", client=httpx.Client(), image_client=images), seen def test_fetch_image_checks_type_and_never_sends_ha_token(): library, seen = _library_with_images({ "http://ma/cover": httpx.Response(200, content=b"jpg", headers={"content-type": "image/jpeg"}), "http://ma/page": httpx.Response(200, content=b"", headers={"content-type": "text/html"}), }) assert library.fetch_image("http://ma/cover") == (b"jpg", "image/jpeg") assert "authorization" not in seen[0].headers with pytest.raises(ValueError): library.fetch_image("http://ma/page") def test_find_album_needs_exact_names(): library = MusicLibrary("http://ha", "t", client=httpx.Client()) library.search_albums = lambda query, limit=12: [ Album("Tool", "Lateralus (Live)", "http://img/live"), Album("TOOL", "lateralus", "http://img/1"), ] assert library.find_album("Tool", "Lateralus").image == "http://img/1" assert library.find_album("Mogwai", "Lateralus") is None def test_ma_url_replaces_music_assistant_host_for_downloads(): library, seen = _library_with_images({ "https://ma.example/imageproxy/abc?size=0": httpx.Response(200, content=b"jpg", headers={"content-type": "image/jpeg"}), }) library._ma_url = httpx.URL("https://ma.example") assert library.fetch_image("http://172.16.40.250:8095/imageproxy/abc?size=0") == (b"jpg", "image/jpeg") assert str(seen[0].url) == "https://ma.example/imageproxy/abc?size=0" # Without MA_URL the address is used as Music Assistant reports it. assert MusicLibrary("http://ha", "t", client=httpx.Client()).image_download_url("http://x:8095/a") == "http://x:8095/a"