gwoe-antragspruefer/tests
Dotty Dotter 4ec6190416 #47 PDF Zitat-Highlighting via PyMuPDF Single-Page-Render
Klick auf eine Zitat-Quelle im Report öffnet jetzt eine 1-Seiten-PDF-
Variante des Wahlprogramms mit gelb markiertem Snippet, statt nur zum
Page-Anchor zu springen und den Leser selbst suchen zu lassen.

Implementation:

embeddings.render_highlighted_page(programm_id, seite, query)
- Validiert programm_id gegen PROGRAMME (Path-Traversal-Schutz)
- Lädt das volle Wahlprogramm-PDF, extrahiert via insert_pdf nur die
  angeforderte Seite in einen neuen Document → kleinere Response
- search_for(query[:200]) → Bounding-Boxes aller Treffer
- Fallback: 5-Wort-Anker wenn Volltext-Match leer (LLM-Truncation,
  identisch zu find_chunk_for_text/Sub-D-Logik)
- add_highlight_annot mit gelber stroke-Color (1.0, 0.93, 0.0)
- Returns serialisierte PDF-Bytes oder None

embeddings._chunk_pdf_url
- Wenn chunk["text"] vorhanden: emittiert /api/wahlprogramm-cite-URL
  mit pid=, seite=, q=urlencoded(text[:200])
- Sonst: alter statischer /static/referenzen/X.pdf#page=N (Pre-#47
  rückwärts-kompatibel)
- text wird auf 200 Zeichen abgeschnitten, sonst blasen
  500-Zeichen-Snippets jedes Assessment-JSON auf

main.py /api/wahlprogramm-cite Endpoint
- Validiert pid gegen PROGRAMME registry
- seite: 1 ≤ n ≤ 2000
- Response: application/pdf, Cache-Control max-age=86400
- 404 bei unknown pid oder fehlendem PDF, 400 bei seite out of range

Reconstruct-Pipeline (Issue #60 Option B) zieht das automatisch durch:
reconstruct_zitate ruft _chunk_pdf_url(matched_chunk) auf, der jetzt
bevorzugt die Cite-URL emittiert. Keine Änderung an reconstruct_zitate
selbst nötig.

Tests: 194/194 grün (185 + 9 neue):

- TestChunkPdfUrl: 4 Cases (cite vs static, unknown prog, 200-char-truncate)
- TestRenderHighlightedPage: 5 Cases (unknown pid, invalid seite, valid
  render, empty query, query-not-found-falls-back-zu-leerem-Highlight)
- Plus Bridge im Test-Stub: pymupdf-as-fitz Shim falls eine
  third-party "fitz" das Pkg shadowt (kommt auf älteren Dev-Setups vor)

Refs: #47
2026-04-10 01:09:45 +02:00
..
integration Sub-B: NRW Sample 10/5376 — F.D.P.+CDU CO2-Minderungsprogramm 1990 2026-04-09 13:43:17 +02:00
__init__.py Add pytest suite + fix two regex bugs uncovered by it (#46) 2026-04-08 23:26:06 +02:00
conftest.py Add pytest suite + fix two regex bugs uncovered by it (#46) 2026-04-08 23:26:06 +02:00
test_analyzer.py Add pytest suite + fix two regex bugs uncovered by it (#46) 2026-04-08 23:26:06 +02:00
test_auswertungen.py Phase G: BundestagAdapter via DIP-API (#56) 2026-04-09 14:04:11 +02:00
test_bundeslaender.py Phase J: SN EDAS-XML-Adapter (#26/#38) — Sachsen aktiv via XML-Export 2026-04-09 14:39:03 +02:00
test_embeddings.py #47 PDF Zitat-Highlighting via PyMuPDF Single-Page-Render 2026-04-10 01:09:45 +02:00
test_main_validators.py Phase A: Audit-Restbefunde #57.3/4/7 (Roadmap #59) 2026-04-09 11:15:16 +02:00
test_parlamente.py Phase B: Parteinamen-Mapper #55 (Roadmap #59) 2026-04-09 11:22:13 +02:00
test_parteien.py Phase B: Parteinamen-Mapper #55 (Roadmap #59) 2026-04-09 11:22:13 +02:00
test_report.py Security hotfixes #1, #2, #6 from audit (#57) 2026-04-09 10:45:43 +02:00
test_wahlprogramme.py Add pytest suite + fix two regex bugs uncovered by it (#46) 2026-04-08 23:26:06 +02:00