"""② Documentation Drift — Cookie-Richtlinie (deklariert) vs. Browser-Realität. Pinnt den Vertrag, den der Endpoint (snapshot_cookie_check → out["drift"]) und das Frontend (CookieFindingList Drift-Strip) konsumieren: declared_count / browser_count / high_findings / low_findings + die undokumentiert-geladen-Liste. db=None → Library-Lookup übersprungen, Drift bleibt rein mengenbasiert. """ from __future__ import annotations from compliance.services.cookie_compliance_audit import audit_cookie_compliance def _banner(*cookie_names: str) -> dict: return {"phases": {"after_accept": { "cookies": [{"name": n} for n in cookie_names]}}} def test_undeclared_browser_cookies_are_high_drift(): # BMW-Fall: Richtlinie nennt nichts, Browser lädt Tracker → undokumentiert. audit = audit_cookie_compliance(None, None, _banner("_ga", "_fbp")) assert audit["declared_count"] == 0 assert audit["browser_count"] == 2 assert audit["high_findings"] == 2 assert set(audit["undeclared_in_browser"]) == {"_ga", "_fbp"} assert audit["low_findings"] == 0 def test_empty_inputs_yield_zero_drift(): audit = audit_cookie_compliance(None, None, None) for k in ("declared_count", "browser_count", "high_findings", "low_findings"): assert audit[k] == 0 def test_drift_both_directions(): # Richtlinie deklariert 3 Cookies (Tab-Tabelle), Browser lädt 2 davon + 1 neuen. doc = ( "Name\tKategorie\tZweck\tSpeicherdauer\n" "_ga\tAnalytics\tBesucher unterscheiden\t2 Jahre\n" "_gid\tAnalytics\tBesucher unterscheiden\t1 Tag\n" "consent\tNotwendig\tEinwilligung speichern\t1 Jahr\n" ) audit = audit_cookie_compliance(None, doc, _banner("_ga", "_gid", "_fbp")) # _fbp ist geladen aber nicht deklariert → HIGH-Drift. assert "_fbp" in audit["undeclared_in_browser"] assert audit["high_findings"] >= 1 # consent ist deklariert aber nicht geladen → LOW-Drift. assert "consent" in audit["declared_not_loaded"] assert audit["low_findings"] >= 1