test(#134): build_pdf_href Coverage 50% → 100%

6 neue Tests in TestBuildPdfHref:
- explizite url wird unveraendert durchgereicht
- ohne url: WAHLPROGRAMME-Lookup ueber quelle-Feld
- ohne Seitenzahl in quelle → leerer href
- Quelle ohne WAHLPROGRAMME-Match → leerer href
- Query nutzt nur die ersten 5 Worte des Zitats
- Komma-Separator 'Titel, S. 17' parst genauso wie ' · S. 17'

app/redline_utils.py jetzt bei 100% Branch-Coverage.
This commit is contained in:
Dotty Dotter 2026-04-28 08:39:05 +02:00
parent 7de4df1fef
commit 50442f203a

View File

@ -143,3 +143,83 @@ class TestEdgeCases:
assert "muss" in ins_texts
assert "31.12.2026" in del_texts
assert "30.06.2025" in ins_texts
# ─── build_pdf_href Tests (#134 Coverage-Backfill) ───────────────────────────
class TestBuildPdfHref:
"""Tests fuer build_pdf_href: rekonstruiert PDF-URLs aus Zitat-Metadaten,
bevorzugt die explizite url, faellt auf WAHLPROGRAMME-Lookup zurueck."""
def test_explicit_url_passed_through(self):
from app.redline_utils import build_pdf_href
zitat = {"url": "/api/wahlprogramm-cite?pid=cdu-nrw-2022&seite=15"}
assert build_pdf_href(zitat) == "/api/wahlprogramm-cite?pid=cdu-nrw-2022&seite=15"
def test_empty_url_falls_back_to_quelle_lookup(self):
"""Ohne url muss die quelle reconstruiert werden via WAHLPROGRAMME."""
from app.redline_utils import build_pdf_href
# Ein in WAHLPROGRAMME hinterlegter Titel
from app.wahlprogramme import WAHLPROGRAMME
# Pick the first programme from the registry
bl, parteien = next(iter(WAHLPROGRAMME.items()))
partei, info = next(iter(parteien.items()))
titel = info.get("titel", "")
if not titel:
pytest.skip("Kein WAHLPROGRAMME-Eintrag mit titel verfuegbar")
zitat = {
"quelle": f"{titel} · S. 42",
"text": "Wir wollen die Energiewende",
"url": "",
}
href = build_pdf_href(zitat)
assert "/api/wahlprogramm-cite" in href
assert "seite=42" in href
assert "#page=42" in href # URL-Hash fuer Browser-PDF-Viewer
def test_no_seitenzahl_returns_empty(self):
from app.redline_utils import build_pdf_href
zitat = {"quelle": "Irgendein Programm ohne Seite", "text": "x", "url": ""}
assert build_pdf_href(zitat) == ""
def test_unmatched_quelle_returns_empty(self):
from app.redline_utils import build_pdf_href
zitat = {
"quelle": "Erfundenes Programm 1995, S. 1",
"text": "x",
"url": "",
}
assert build_pdf_href(zitat) == ""
def test_query_uses_first_5_words_of_text(self):
from app.redline_utils import build_pdf_href
from app.wahlprogramme import WAHLPROGRAMME
bl, parteien = next(iter(WAHLPROGRAMME.items()))
partei, info = next(iter(parteien.items()))
titel = info.get("titel", "")
if not titel:
pytest.skip("Kein WAHLPROGRAMME-Eintrag mit titel verfuegbar")
zitat = {
"quelle": f"{titel} · S. 5",
"text": "Eins zwei drei vier fünf sechs sieben",
"url": "",
}
href = build_pdf_href(zitat)
# max. 5 Worte → "sechs sieben" muessen im Query fehlen
assert "sechs" not in href
assert "sieben" not in href
# erste fuenf Wortteile sollten kodiert in q= auftauchen
assert "Eins" in href or "Eins" in href.replace("+", " ")
def test_handles_seite_with_comma_separator(self):
"""Quelle 'Titel, S. 42' (Komma) muss genauso parsen wie '· S. 42'."""
from app.redline_utils import build_pdf_href
from app.wahlprogramme import WAHLPROGRAMME
bl, parteien = next(iter(WAHLPROGRAMME.items()))
partei, info = next(iter(parteien.items()))
titel = info.get("titel", "")
if not titel:
pytest.skip("Kein WAHLPROGRAMME-Eintrag mit titel verfuegbar")
zitat = {"quelle": f"{titel}, S. 17", "text": "x", "url": ""}
href = build_pdf_href(zitat)
assert "seite=17" in href