E2E Sub-C: Wahlprogramm Indexing + Content Verification #53

Closed
opened 2026-04-09 09:02:10 +02:00 by tobias · 1 comment
Owner

Sub-Issue von #50.

Zweck

Sub-Issue C des E2E-Test-Umbrellas. Drei Test-Kategorien rund um die Wahlprogramm-Indexierung — fängt vor allem die Bug-Klasse 8 (anachronistisches PDF) und 11 (fehlende Indexierung).

Datei

webapp/tests/integration/test_wahlprogramme_indexed.py

Was getestet wird

C1: Indexing-Status pro aktivem BL

Liest die embeddings.db direkt (kein Live-API nötig) via embeddings.get_indexing_status() (existiert bereits). Pro WAHLPROGRAMME[bl][partei]-Eintrag wird geprüft, ob der programm_id (aus dem Datei-Namen) in der DB ≥ 1 Chunk hat.

@pytest.mark.integration
def test_every_active_bundesland_has_all_wahlprogramme_indexed():
    from app.embeddings import get_indexing_status
    from app.bundeslaender import aktive_bundeslaender
    from app.wahlprogramme import WAHLPROGRAMME

    indexed = {p["id"] for p in get_indexing_status()["programmes"] if p["indexed"]}
    missing = []
    for bl in aktive_bundeslaender():
        for partei, info in WAHLPROGRAMME.get(bl.code, {}).items():
            pid = info["file"].rsplit(".", 1)[0]
            if pid not in indexed:
                missing.append(f"{bl.code}/{partei}: {pid}")
    assert not missing, "missing in embeddings.db:\n  " + "\n  ".join(missing)

C2: Inhalts-Plausibilität pro PDF (Bug-Klasse 8: anachronistisches PDF)

Pro registriertem Wahlprogramm-PDF wird die erste Seite per fitz (PyMuPDF echt, nicht Stub) geladen und nach erwarteten Markern durchsucht:

  • "Wahlprogramm" oder "Regierungsprogramm" oder "Programm zur Landtagswahl"
  • Das Wahljahr (info["jahr"]) muss als Token im Volltext der ersten 3 Seiten vorkommen
  • Der Partei-Name muss ≥ 1× in den ersten 3 Seiten vorkommen

Plus expliziter Anti-Marker für Bug-Klasse 8 (CDU BE 2023 vs 2026):

def test_be_cdu_pdf_is_2021_program_not_2026():
    """Regression: abgeordnetenwatch hat das CDU-BE-PDF unter dem alten
    Slug-Namen nachträglich gegen das 2026er Berlin-Plan ersetzt; ohne
    diesen Test hätten wir das anachronistische Programm indexiert."""
    text = _pdf_first_pages_text("cdu-be-2023.pdf", n=3)
    assert "2021" in text
    assert "Berlin-Plan" in text
    assert "2026 bis 2031" not in text  # explicit anti-marker

C3: Embeddings-Statistik

Pro Programm: chunk-count > 0, plus chunk-count konsistent mit Seitenzahl (grobe Heuristik: chunk-count > seiten/10, sonst Indexing wahrscheinlich abgebrochen).

Bug-Klassen

Deckt 8 (anachronistisches PDF), 11 (fehlende Indexierung), 15 (alte Programm-Slugs in der DB).

Akzeptanzkriterien

  • pytest -m integration tests/integration/test_wahlprogramme_indexed.py -v grün
  • Wenn man eine Wahlprogramm-Datei aus WAHLPROGRAMME entfernt aber die DB-Chunks behält → C1 ist trotzdem grün, C3 zeigt orphan-warning (optional, eigener Test)
  • Wenn man ein PDF gegen ein anachronistisches austauscht → C2 schlägt fehl
  • Wenn ein Programm nicht indexiert wurde → C1 schlägt fehl mit klarer Liste der fehlenden IDs
Sub-Issue von #50. ## Zweck Sub-Issue C des E2E-Test-Umbrellas. Drei Test-Kategorien rund um die Wahlprogramm-Indexierung — fängt vor allem die Bug-Klasse 8 (anachronistisches PDF) und 11 (fehlende Indexierung). ## Datei `webapp/tests/integration/test_wahlprogramme_indexed.py` ## Was getestet wird ### C1: Indexing-Status pro aktivem BL Liest die `embeddings.db` direkt (kein Live-API nötig) via `embeddings.get_indexing_status()` (existiert bereits). Pro `WAHLPROGRAMME[bl][partei]`-Eintrag wird geprüft, ob der `programm_id` (aus dem Datei-Namen) in der DB ≥ 1 Chunk hat. ```python @pytest.mark.integration def test_every_active_bundesland_has_all_wahlprogramme_indexed(): from app.embeddings import get_indexing_status from app.bundeslaender import aktive_bundeslaender from app.wahlprogramme import WAHLPROGRAMME indexed = {p["id"] for p in get_indexing_status()["programmes"] if p["indexed"]} missing = [] for bl in aktive_bundeslaender(): for partei, info in WAHLPROGRAMME.get(bl.code, {}).items(): pid = info["file"].rsplit(".", 1)[0] if pid not in indexed: missing.append(f"{bl.code}/{partei}: {pid}") assert not missing, "missing in embeddings.db:\n " + "\n ".join(missing) ``` ### C2: Inhalts-Plausibilität pro PDF (Bug-Klasse 8: anachronistisches PDF) Pro registriertem Wahlprogramm-PDF wird die erste Seite per `fitz` (PyMuPDF echt, nicht Stub) geladen und nach erwarteten Markern durchsucht: - "Wahlprogramm" oder "Regierungsprogramm" oder "Programm zur Landtagswahl" - Das **Wahljahr** (`info["jahr"]`) muss als Token im Volltext der ersten 3 Seiten vorkommen - Der **Partei-Name** muss ≥ 1× in den ersten 3 Seiten vorkommen Plus expliziter Anti-Marker für Bug-Klasse 8 (CDU BE 2023 vs 2026): ```python def test_be_cdu_pdf_is_2021_program_not_2026(): """Regression: abgeordnetenwatch hat das CDU-BE-PDF unter dem alten Slug-Namen nachträglich gegen das 2026er Berlin-Plan ersetzt; ohne diesen Test hätten wir das anachronistische Programm indexiert.""" text = _pdf_first_pages_text("cdu-be-2023.pdf", n=3) assert "2021" in text assert "Berlin-Plan" in text assert "2026 bis 2031" not in text # explicit anti-marker ``` ### C3: Embeddings-Statistik Pro Programm: chunk-count > 0, plus chunk-count konsistent mit Seitenzahl (grobe Heuristik: chunk-count > seiten/10, sonst Indexing wahrscheinlich abgebrochen). ## Bug-Klassen Deckt 8 (anachronistisches PDF), 11 (fehlende Indexierung), 15 (alte Programm-Slugs in der DB). ## Akzeptanzkriterien - [ ] `pytest -m integration tests/integration/test_wahlprogramme_indexed.py -v` grün - [ ] Wenn man eine Wahlprogramm-Datei aus `WAHLPROGRAMME` entfernt aber die DB-Chunks behält → C1 ist trotzdem grün, C3 zeigt orphan-warning (optional, eigener Test) - [ ] Wenn man ein PDF gegen ein anachronistisches austauscht → C2 schlägt fehl - [ ] Wenn ein Programm nicht indexiert wurde → C1 schlägt fehl mit klarer Liste der fehlenden IDs
Author
Owner

Sub-C erledigt — tests/integration/test_wahlprogramme_indexed.py mit Indexing-Status-Check + PDF-Plausibilitäts-Tests + expliziter Anti-Marker für CDU-BE-PDF-Tausch (Bug-Klasse 8). Commit 73a7f76.

Sub-C erledigt — tests/integration/test_wahlprogramme_indexed.py mit Indexing-Status-Check + PDF-Plausibilitäts-Tests + expliziter Anti-Marker für CDU-BE-PDF-Tausch (Bug-Klasse 8). Commit 73a7f76.
Sign in to join this conversation.
No description provided.