"""The MusicBrainz fallback for audio dramas Audible does not carry.""" import asyncio import httpx import pytest from wordarr import metadata from wordarr.metadata import musicbrainz RELEASE = { "id": "23d80453-0d56-4064-85ec-cf3a14823897", "title": "Die drei ??? 100: Toteninsel", "date": "2001-10-15", "text-representation": {"language": "deu"}, "artist-credit": [{"name": "Die drei ???"}], "release-group": {"secondary-types": ["Audio drama"]}, } REISSUE = {**RELEASE, "id": "other", "date": "2011-08-13"} @pytest.fixture def mb_calls(monkeypatch): seen = [] def handler(request: httpx.Request) -> httpx.Response: seen.append(dict(request.url.params)) return httpx.Response(200, json={"releases": [REISSUE, RELEASE]}) real = httpx.AsyncClient monkeypatch.setattr(musicbrainz.httpx, "AsyncClient", lambda **kw: real(transport=httpx.MockTransport(handler), **kw)) monkeypatch.setattr(musicbrainz, "MIN_INTERVAL", 0) return seen def test_parses_series_number_and_original_date(mb_calls): results = asyncio.run(musicbrainz.search("Die drei ??? Toteninsel", "german")) assert len(results) == 1 # both pressings collapse into one hit = results[0] assert (hit.series, hit.volume, hit.title) == ("Die drei ???", 100, "Toteninsel") assert hit.year == 2001 # the original, not the 2011 reissue assert hit.language == "german" assert hit.source == "musicbrainz" assert hit.external_id.startswith("mb:") def test_query_drops_lucene_specials_and_filters_to_audio_drama(mb_calls): asyncio.run(musicbrainz.search("Die drei ??? Toteninsel", "german")) query = mb_calls[0]["query"] assert "???" not in query # would act as wildcards assert "release:Toteninsel" in query and " AND " in query assert 'secondarytype:"audio drama"' in query assert "lang:deu" in query def test_audiobook_search_appends_musicbrainz_hits(mb_calls, monkeypatch): from wordarr.metadata.base import MetadataResult async def fake_audible(query, language=""): return [MetadataResult(media_type="audiobook", title="Etwas anderes")] monkeypatch.setattr(metadata.audible, "search", fake_audible) results = asyncio.run(metadata.audiobook_search("Toteninsel", "german")) assert [r.source for r in results] == ["audible", "musicbrainz"] # the automatic search when the dialog opens must not hit MusicBrainz mb_calls.clear() results = asyncio.run(metadata.audiobook_search("Toteninsel", "german", fallback=False)) assert [r.source for r in results] == ["audible"] and not mb_calls def test_a_broken_fallback_never_breaks_the_search(monkeypatch): from wordarr.metadata.base import MetadataResult async def fake_audible(query, language=""): return [MetadataResult(media_type="audiobook", title="Da")] async def boom(query, language=""): raise RuntimeError("musicbrainz down") monkeypatch.setattr(metadata.audible, "search", fake_audible) monkeypatch.setattr(metadata.musicbrainz, "search", boom) results = asyncio.run(metadata.audiobook_search("Toteninsel")) assert [r.title for r in results] == ["Da"]