"""Sub-Issue B — Adapter ↔ Frontend Cross-Validation. Pro aktivem BL ist im ``ground_truth.py``-Modul ein einzelnes Drucksachen- Tupel kuratiert, das aus der echten Frontend-Suche des jeweiligen Landtags stammt. Dieser Test ruft ``adapter.get_document(...)`` mit der bekannten ID auf und prüft, dass: - die Drucksache überhaupt gefunden wird - der Title (substring) passt - die erwarteten Fraktionen drin sind - das Datum (wenn gesetzt im Sample) übereinstimmt - der PDF-Link das erwartete URL-Fragment enthält Bug-Klassen aus den letzten Sessions, die diese Datei abdeckt: - 14 (get_document() liefert Match aus falschem Bundesland) - Allgemeine Schema-Drift in URL-Strukturen, Hit-Format-Änderungen, Encoding-Bugs, Pagination-Cut-Offs, Adapter-Reuse-Konfigurations-Fehler Issue: #52 (Sub-Issue B des Umbrella #50) Wartung: siehe Doku im ``ground_truth.py``-Header. """ import pytest from app.bundeslaender import aktive_bundeslaender from app.parlamente import ADAPTERS from .ground_truth import GROUND_TRUTH pytestmark = pytest.mark.integration _ACTIVE_CODES = {bl.code for bl in aktive_bundeslaender()} # Skip Samples für BL die nicht (mehr) aktiv sind _GT_PARAMS = [pytest.param(gt, id=gt.bundesland) for gt in GROUND_TRUTH if gt.bundesland in _ACTIVE_CODES] @pytest.mark.parametrize("gt", _GT_PARAMS) async def test_adapter_finds_known_drucksache(gt): """Cross-Validation gegen die Frontend-Suche des jeweiligen Landtags. Wenn dieser Test fehlschlägt: erst den Frontend-URL aus ``gt.frontend_search_url`` öffnen und prüfen, ob die Drucksache überhaupt noch existiert. Wenn ja → Adapter-Bug. Wenn nein → ein neues Sample im ``ground_truth.py`` aufnehmen. """ if gt.bundesland not in ADAPTERS: pytest.skip(f"{gt.bundesland} hat keinen registrierten Adapter") if not gt.title_substring: pytest.skip( f"{gt.bundesland}: Sample noch nicht kuratiert " "(title_substring leer in ground_truth.py)" ) adapter = ADAPTERS[gt.bundesland] doc = await adapter.get_document(gt.drucksache) assert doc is not None, ( f"{gt.bundesland} adapter ({type(adapter).__name__}) hat die " f"bekannte Drucksache {gt.drucksache!r} nicht gefunden. Frontend-" f"Probe: {gt.frontend_search_url}" ) # 1. Drucksachen-Nummer roundtrip assert doc.drucksache == gt.drucksache, ( f"{gt.bundesland}: get_document({gt.drucksache!r}) lieferte " f"abweichende drucksache={doc.drucksache!r}" ) # 2. Title-Substring assert gt.title_substring.lower() in doc.title.lower(), ( f"{gt.bundesland}: title_substring {gt.title_substring!r} nicht " f"in adapter-title {doc.title!r}" ) # 3. Erwartete Fraktionen sind alle da (Subset-Match — Adapter darf # mehr Fraktionen erkennen als das Sample erwartet) if gt.expected_fraktionen: adapter_fraktionen = set(doc.fraktionen) missing = gt.expected_fraktionen - adapter_fraktionen assert not missing, ( f"{gt.bundesland}: erwartete Fraktionen {gt.expected_fraktionen} " f"nicht alle im Adapter-Output {adapter_fraktionen}; fehlt: {missing}" ) # 4. Datum (nur wenn das Sample eines hat) if gt.datum: assert doc.datum == gt.datum, ( f"{gt.bundesland}: erwartetes datum={gt.datum!r}, adapter lieferte " f"{doc.datum!r}" ) # 5. PDF-Link enthält erwartetes URL-Fragment if gt.pdf_url_substring: assert gt.pdf_url_substring.lower() in doc.link.lower(), ( f"{gt.bundesland}: pdf_url_substring {gt.pdf_url_substring!r} " f"nicht in adapter-link {doc.link!r}" ) # 6. Bundesland-Konsistenz — fängt Bug-Klasse 14 (Cross-Bundesland-Match) assert doc.bundesland == gt.bundesland, ( f"adapter[{gt.bundesland}].get_document() lieferte ein Doc mit " f"bundesland={doc.bundesland!r}" )