"""GT-Coverage-Integration-Test gegen den Elli-Audit (2026-06-06). Charakterisierungstest für die 5 GT-Lücken die in diesem Sprint geschlossen wurden. Konstruiert einen synthetischen `state`-dict, der Elli's reale Befunde widerspiegelt, und stellt sicher, dass jeder der neuen B13-B16 + B9-Cleanup Detektoren genau die erwarteten GT-IDs fängt. Ground-Truth-Quelle: zeroclaw/docs/ground-truth/elli_eco_2026-06-06.json """ from compliance.services.ai_legal_basis_check import check_ai_legal_basis from compliance.services.impressum_multi_entity_check import ( check_multi_entity_impressum, ) from compliance.services.retention_conflict_check import ( check_retention_conflicts, ) from compliance.services.url_slug_drift_check import check_url_slug_drift from compliance.services.widerrufsbelehrung_reachability_check import ( check_widerrufsbelehrung_reachability, ) # Elli-Fixture: minimaler State mit den Datenfeldern die jeder Check # braucht. Texte sind verdichtet, enthalten aber jedes prüf-relevante # Signal (Vertex AI / lit. f, Logfile-Widerspruch, B2C-Shop, etc.). _ELLI_IMPRESSUM = """ Impressum Volkswagen Group Charging GmbH Karl-Liebknecht-Str. 32, 10178 Berlin Amtsgericht Charlottenburg HRB 208967 B Geschäftsführer: Giovanni Palazzo, Mark Möller Telefon: 00800 3554 1111 Elli Mobility GmbH Karl-Liebknecht-Str. 32, 10178 Berlin Amtsgericht Charlottenburg HRB 274616 B USt-IdNr.: DE814424009 Geschäftsführer: Joschi Jennermann, Sebastian Steffen """ _ELLI_DSE = """ Datenschutzerklärung der Elli Mobility GmbH. Server-Logfiles: Bei jedem Zugriff werden Logfiles gespeichert. Die Logfiles werden für 7 Tage gespeichert. Bei Sicherheitsvorfällen werden Logfiles bis zu 30 Tage aufbewahrt. AI Assistant: Für unseren Chatbot setzen wir Google Vertex AI ein. Rechtsgrundlage ist Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse). Speicherdauer 6 Monate. Newsletter-Abonnement: Wir speichern Anmeldedaten 24 Monate ab Abmeldung. """ _ELLI_HOMEPAGE = ( "Elli — Charging Solutions. In den Warenkorb. Lieferzeit 2 Tage. " "Preis inkl. MwSt. Wallbox. Naturstrom. Ladetarif buchen." ) def _build_elli_state(widerruf_reachable: bool = False) -> dict: doc_entries = [ {"doc_type": "impressum", "url": "https://www.elli.eco/de/impressum", "text": _ELLI_IMPRESSUM, "auto_discovered": True, "discovery_attempted": True}, {"doc_type": "dse", "url": "https://www.elli.eco/de/datenschutz", "text": _ELLI_DSE, "auto_discovered": True, "discovery_attempted": True}, {"doc_type": "cookie", "url": "https://www.elli.eco/de/cookies", "text": "x" * 600, "auto_discovered": True, "discovery_attempted": True}, {"doc_type": "widerruf", "url": "https://www.elli.eco/de/widerruf" if widerruf_reachable else "", "text": ("x" * 600) if widerruf_reachable else "", "auto_discovered": widerruf_reachable, "discovery_attempted": True}, ] return { "doc_entries": doc_entries, "doc_texts": { "impressum": _ELLI_IMPRESSUM, "dse": _ELLI_DSE, }, "home_text": _ELLI_HOMEPAGE, } # ──────────────────────────────────────────────────────────────────────── # B9 cleanup — IMPRESSUM-001 # ──────────────────────────────────────────────────────────────────────── class TestImpressum001Coverage: def test_per_entity_ust_id_detected(self): state = _build_elli_state() findings = check_multi_entity_impressum(state) ust = [f for f in findings if f["check_id"] == "IMPRESSUM-MULTI-UST_ID"] assert len(ust) == 1 assert ust[0]["entities_missing"] == [ "Volkswagen Group Charging GmbH", ] assert ust[0]["entities_present"] == ["Elli Mobility GmbH"] # ──────────────────────────────────────────────────────────────────────── # B13 — WIDERRUFSBELEHRUNG-001 # ──────────────────────────────────────────────────────────────────────── class TestWiderrufsbelehrung001Coverage: def test_b2c_strong_high_finding(self): state = _build_elli_state(widerruf_reachable=False) findings = check_widerrufsbelehrung_reachability(state) assert len(findings) == 1 assert findings[0]["check_id"] == "WIDERRUF-REACH-001" assert findings[0]["severity"] == "HIGH" assert findings[0]["b2c_scope"] == "b2c_strong" def test_widerruf_reachable_suppresses_finding(self): state = _build_elli_state(widerruf_reachable=True) assert check_widerrufsbelehrung_reachability(state) == [] # ──────────────────────────────────────────────────────────────────────── # B14 — TH-RETENTION-001 # ──────────────────────────────────────────────────────────────────────── class TestTHRetention001Coverage: def test_logfile_7_vs_30_finding(self): state = _build_elli_state() findings = check_retention_conflicts(state) log = [f for f in findings if f["category"] == "logfile"] assert len(log) == 1 assert 7.0 in log[0]["values_days"] assert 30.0 in log[0]["values_days"] # ──────────────────────────────────────────────────────────────────────── # B15 — AI-ACT-RISK-001 # ──────────────────────────────────────────────────────────────────────── class TestAIActRisk001Coverage: def test_vertex_ai_lit_f_finding(self): state = _build_elli_state() findings = check_ai_legal_basis(state) assert len(findings) == 1 assert findings[0]["check_id"] == "AI-LEGAL-BASIS-001" assert "Vertex" in findings[0]["provider"] # ──────────────────────────────────────────────────────────────────────── # B16 — URL-STRUCTURE-001 # ──────────────────────────────────────────────────────────────────────── class TestURLStructure001Coverage: def test_cookie_richtlinie_404_emits_finding(self): # Mock _head_status: alle Standard-Slugs ausser dem discovered # liefern 404 — Elli's reale Lage. from unittest.mock import patch state = _build_elli_state() with patch( "compliance.services.url_slug_drift_check._head_status", return_value=404, ): findings = check_url_slug_drift(state) cookie_findings = [f for f in findings if f["doc_type"] == "cookie"] assert len(cookie_findings) == 1 assert cookie_findings[0]["severity"] == "LOW" assert "cookie-richtlinie" in cookie_findings[0]["alt_slugs_404"] # ──────────────────────────────────────────────────────────────────────── # All-Detector-Smoke — sicherstellen, dass die 5 Checks zusammen # gegen Elli mindestens 5 unterschiedliche Finding-IDs ergeben. # ──────────────────────────────────────────────────────────────────────── class TestElliFullCoverage: def test_all_five_detectors_fire(self): from unittest.mock import patch state = _build_elli_state(widerruf_reachable=False) all_findings: list[dict] = [] all_findings.extend(check_multi_entity_impressum(state)) all_findings.extend(check_widerrufsbelehrung_reachability(state)) all_findings.extend(check_retention_conflicts(state)) all_findings.extend(check_ai_legal_basis(state)) with patch( "compliance.services.url_slug_drift_check._head_status", return_value=404, ): all_findings.extend(check_url_slug_drift(state)) check_ids = {f["check_id"] for f in all_findings} expected = { "IMPRESSUM-MULTI-UST_ID", "WIDERRUF-REACH-001", "RETENTION-CONFLICT-001", "AI-LEGAL-BASIS-001", "URL-SLUG-DRIFT-001", } missing = expected - check_ids assert not missing, f"GT-Lücken nicht gefangen: {missing}"