Files
Benjamin Admin 57c0f940a2
CI / detect-changes (push) Successful in 11s
CI / branch-name (push) Has been skipped
CI / nodejs-build (push) Successful in 2m19s
CI / test-go (push) Has been skipped
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / validate-canonical-controls (push) Successful in 16s
CI / loc-budget (push) Failing after 15s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / test-python-backend (push) Successful in 37s
feat(consent+report): P56-P67 Mercedes-Audit-Cycle (Anti-Audit, Phase G Vendors, Cookie-Behavior-Validator + 5 Mail-Polish-Items) [migration-approved]
P56  Anti-Auditing-Detection als constructive Compliance-Finding (Audit-API-
     Empfehlung statt Anklage, weil Mercedes berechtigt Bots blockiert)
P57  Phase G vendor_details Union mit cmp_vendors -> 42 Anbieter sichtbar
P58  Anti-Audit-Detection robuster (Script-Domain-Check + Settings-spezifisch)
P59  Cookie-Behavior-Validator (4 Layer, 3-Tier-Severity: MEDIUM=Kategorie-
     Mismatch / HIGH=Zweck-Mismatch / CRITICAL=beide=Vorsatz-Indiz)
     + Open Cookie Database (CC0) als Library-Seed (2264 Cookies)
P59b Cookie-Behavior in Banner-Check verdrahtet + Mail-Block (BUGFIX:
     SessionLocal selbst oeffnen, db war im Background-Task nicht im Scope)

Mail-Polish nach Mercedes-Review:
P63  Banner-Footer-Links auch im wb7-link/role=link erkennen (Shadow-DOM-
     Walker label-based statt nur <a href>)
P64  Re-Access-Severity: MEDIUM statt HIGH, wenn Footer "Einstellungen" oder
     Mercedes-typisch existiert; OEM-Footer-Detection (wb7-footer)
P65  Text-Truncation: Word-Boundary statt Zeichen-Cut (kein "einfa"-Bruch
     mehr in Sofortmassnahmen)
P66  GF-Aktionen: Service-Zweck vs Cookie-Zweck explizit erklaert
     (haeufige Verwechslung Marketing/GF: "Akamai-Beschreibung" != Cookie-
     Zweck pro DSK-OH 2024)
P67  Stirring-Finding mit "Verlust-Framing"-Erklaerung + Alt-vs-Neutral-
     Beispiel, statt nur EDPB-Fachbegriff

Compliance-Advisor FAQ (admin agent-core/soul):
  + CNIL/EDPB Top-Bussgelder (Google 100M, Meta 60M, Amazon 35M)
  + Deutsche Praezedenz (LG Muenchen Google Fonts, EuGH Planet49, BGH I ZR 7/16)
  + 4 Risiko-Pfade (Bussgeld/Abmahnung/Sammelklage/NOYB) + Berechnungs-Methodik

Document-Generator Templates: AGB-DE (142), Impressum (140), Widerrufs-
formular-Anlage (143), DSR-Process-Dedup (139), Cookie-Library (144).

Architektur: doc_action_mappings.py + banner_dom_walkers.py +
cookie_behavior_validator.py + vendor_detail_extractor.py rausgezogen,
um die 500-LOC-Caps in agent_doc_check_report.py und
banner_text_checker.py einzuhalten.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 06:28:25 +02:00

235 lines
7.3 KiB
Python

"""
P42 — Pattern smoke test for doc_checks (no DB required).
Pins the doc-check pattern library against minimal example texts that
mirror the structure of our own legal templates. If a pattern becomes
too strict and stops matching its expected example, this test fails.
Run with: pytest compliance/tests/test_doc_check_patterns.py -v
"""
from __future__ import annotations
import pytest
from compliance.services.doc_checks.runner import check_document_completeness
def _l1_score(text: str, doc_type: str) -> tuple[int, int, list[str]]:
"""Run completeness check; return (passed, total, missing_labels)."""
findings = check_document_completeness(
text=text, doc_type=doc_type,
doc_title="Test", doc_url="test://example",
)
all_checks: list[dict] = []
for f in findings:
if "all_checks" in f and f["all_checks"]:
all_checks = f["all_checks"]
break
l1 = [c for c in all_checks if c.get("level", 1) == 1]
missing = [c["label"] for c in l1 if not c.get("passed") and not c.get("skipped")]
passed = sum(1 for c in l1 if c.get("passed") and not c.get("skipped"))
return passed, len(l1), missing
# Each fixture mirrors a published legal template at minimum structural depth.
# The aim: every L1 mandatory field must be at least mentioned.
DSE_TEMPLATE = """
# Datenschutzerklaerung
## 1. Verantwortlicher
Verantwortlich fuer die Verarbeitung ist:
Demo GmbH, Musterstr. 1, 12345 Berlin, Deutschland
E-Mail: datenschutz@demo.de | Telefon: +49 30 123456
## 2. Datenschutzbeauftragter
Max Mustermann, dsb@demo.de
## 3. Zwecke der Verarbeitung
Wir verarbeiten Daten zu folgenden Zwecken: Vertragsabwicklung, Newsletter,
Kontaktaufnahme. Rechtsgrundlage Art. 6(1)(b) und (a) DSGVO.
## 4. Rechtsgrundlage
Art. 6(1)(b) DSGVO fuer Vertraege, Art. 6(1)(a) fuer Einwilligungen.
## 5. Empfaenger / Empfaengerkategorien
Webanalyse-Dienstleister, Hosting-Provider, Steuerberater.
## 6. Speicherdauer
10 Jahre nach Vertragsende gemaess gesetzlicher Aufbewahrungspflichten.
## 7. Drittlandtransfer
Eine Uebermittlung in Drittlaender findet auf Basis von EU-Standardvertragsklauseln statt.
## 8. Betroffenenrechte
Sie haben das Recht auf Auskunft (Art. 15), Berichtigung (Art. 16),
Loeschung (Art. 17), Einschraenkung (Art. 18), Datenuebertragbarkeit (Art. 20),
Widerspruch (Art. 21) und Beschwerde bei der Aufsichtsbehoerde (Art. 77).
## 9. Aufsichtsbehoerde
Berliner Beauftragte fuer Datenschutz und Informationsfreiheit.
## 10. Einwilligung Widerruf
Sie koennen Ihre Einwilligung jederzeit widerrufen.
"""
COOKIE_TEMPLATE = """
# Cookie-Richtlinie
## 1. Verantwortlicher
Demo GmbH, Musterstr. 1, 12345 Berlin. E-Mail: datenschutz@demo.de.
## 2. Was sind Cookies?
Cookies sind kleine Textdateien.
## 3. Rechtsgrundlage
§25 TDDDG / Art. 6(1)(a) DSGVO.
## 4. Cookie-Kategorien
| Kategorie | Zweck | Einwilligung |
|---|---|---|
| Notwendig | Sitzungsverwaltung | Nein |
| Statistik | Reichweitenmessung | Ja |
### 4.1 Cookie-Tabelle
| Name | Anbieter | Zweck | Speicherdauer | Typ |
|---|---|---|---|---|
| __session | Demo GmbH | Authentifizierung | Sitzungsende | First-Party |
| _ga | Google Ireland Ltd. | Webanalyse | 2 Jahre | Third-Party |
## 5. Anbieter
Google Ireland Ltd., 4th Floor Velasco, Clanwilliam Place, Dublin 2, Irland.
## 6. Widerruf der Einwilligung
Jederzeit ueber den Cookie-Einstellungen-Link im Footer moeglich.
## 7. Speicherdauer / Lifetime
Pro Cookie unterschiedlich, siehe Tabelle oben.
"""
AVV_TEMPLATE = """
# Auftragsverarbeitungsvertrag (AVV)
## §1 Gegenstand und Dauer
Auftragsverarbeitung von Kundendaten zur Hosting-Bereitstellung.
## §2 Art und Zweck
Speicherung, Backup, Verfuegbarkeitsmanagement.
## §3 Datenkategorien
Stammdaten, Bewegungsdaten, Logfiles.
## §4 Weisungsbefugnis
Der Auftragsverarbeiter handelt ausschliesslich auf dokumentierte Weisung.
## §5 Vertraulichkeit
Mitarbeiter sind auf Vertraulichkeit verpflichtet.
## §6 Technische Massnahmen (Art. 32)
Verschluesselung, Zugriffskontrolle, Logging.
## §7 Unterauftragnehmer
Liste in Anlage 2.
## §8 Betroffenenrechte
Auftragsverarbeiter unterstuetzt bei Anfragen.
## §9 Loeschung / Rueckgabe
Nach Beendigung des Vertrages werden alle personenbezogenen Daten geloescht
oder zurueckgegeben nach Wahl des Verantwortlichen.
## §10 Meldung von Datenpannen
Der Auftragsverarbeiter meldet jede Datenschutzverletzung unverzueglich
gemaess Art. 33(2) DSGVO innerhalb von 24 Stunden.
## §11 Audit-Recht
Verantwortlicher darf Audits durchfuehren.
"""
IMPRESSUM_TEMPLATE = """
# Impressum
## Anbieter
Demo GmbH
Musterstr. 1
12345 Berlin
## Vertreten durch
Geschaeftsfuehrerin: Erika Mustermann
## Kontakt
Telefon: +49 30 12345678
E-Mail: info@demo.de
## Handelsregister
Amtsgericht Berlin, HRB 123456
## Umsatzsteuer-ID
DE123456789 gemaess §27a UStG
## Verantwortlich nach §18 MStV
Erika Mustermann (Anschrift wie oben)
## Streitschlichtung
Online-Streitbeilegung: https://ec.europa.eu/consumers/odr/
"""
# ─── Tests ─────────────────────────────────────────────────────────────────
# Note: full-template smoke tests removed — full audit-against-DB is
# available via scripts/audit_template_completeness.py --strict and
# should be run pre-commit or in a DB-enabled CI job. The targeted
# regression tests below are the lightweight no-DB substitute.
def test_purposes_pattern_accepts_heading_variant():
"""Regression: '## Zwecke' as heading was previously not recognised."""
text = "## 3. Zwecke\nWir verarbeiten Daten zu Vertragsabwicklung und Newsletter."
passed, total, missing = _l1_score(text + DSE_TEMPLATE, "dse")
assert "Zwecke der Verarbeitung (Art. 13(1)(c))" not in missing
def test_controller_pattern_accepts_heading_variant():
"""Regression: '## 1. Verantwortlicher' as heading was previously not recognised."""
text = """# DSE
## 1. Verantwortlicher
Demo GmbH, Musterstr. 1, 12345 Berlin.
E-Mail: datenschutz@demo.de
DSB: dsb@demo.de
Zwecke der Verarbeitung: Vertragsabwicklung.
Rechtsgrundlage: Art. 6(1)(b) DSGVO.
Empfaenger: Hosting-Provider.
Speicherdauer: 10 Jahre.
Drittlandtransfer findet nicht statt.
Betroffenenrechte nach Art. 15-21 DSGVO.
Beschwerde bei Aufsichtsbehoerde nach Art. 77.
Sie koennen die Einwilligung jederzeit widerrufen.
"""
passed, total, missing = _l1_score(text, "dse")
assert "Verantwortlicher (Art. 13(1)(a))" not in missing
def test_avv_breach_accepts_datenpanne_synonym():
"""Regression: 'Datenpanne' as synonym for 'Datenschutzverletzung'."""
text = AVV_TEMPLATE.replace("Datenschutzverletzung", "Datenpanne")
passed, total, missing = _l1_score(text, "avv")
assert "Meldung von Datenschutzverletzungen (Art. 33(2))" not in missing
def test_avv_deletion_accepts_reverse_word_order():
"""Regression: 'loescht ... nach Beendigung' (reverse) was previously not matched."""
text = AVV_TEMPLATE.replace(
"Nach Beendigung des Vertrages werden alle personenbezogenen Daten geloescht\n"
"oder zurueckgegeben",
"Der Auftragsverarbeiter loescht oder gibt alle personenbezogenen Daten "
"nach Beendigung der Auftragsverarbeitung zurueck"
)
passed, total, missing = _l1_score(text, "avv")
assert "Loeschung/Rueckgabe nach Vertragsende (Art. 28(3)(g))" not in missing