diff --git a/admin-compliance/app/sdk/agent/_components/CookieLibraryPanel.tsx b/admin-compliance/app/sdk/agent/_components/CookieLibraryPanel.tsx index ad5141a8..c939588c 100644 --- a/admin-compliance/app/sdk/agent/_components/CookieLibraryPanel.tsx +++ b/admin-compliance/app/sdk/agent/_components/CookieLibraryPanel.tsx @@ -28,6 +28,12 @@ interface CheckData { real_cookies?: number other_storage?: number } + drift?: { + declared_count?: number + browser_count?: number + high_findings?: number + low_findings?: number + } } const SEV_COLOR: Record = { @@ -55,8 +61,24 @@ export function CookieFindingList({ data }: { data: CheckData }) { const findings = data.findings || [] const s = data.summary || {} const inv = data.storage_inventory + const drift = data.drift + const driftShown = + !!drift && ((drift.declared_count ?? 0) + (drift.browser_count ?? 0)) > 0 return (
+ {driftShown && ( +
+ Richtlinie ↔ Realität:{' '} + {drift!.declared_count ?? 0} in der Cookie-Richtlinie + dokumentiert · {drift!.browser_count ?? 0} im Browser geladen + {(drift!.high_findings ?? 0) > 0 && ( + <> · {drift!.high_findings} undokumentiert geladen + )} + {(drift!.low_findings ?? 0) > 0 && ( + <> · {drift!.low_findings} dokumentiert, aber nicht geladen + )} +
+ )} {inv && (inv.total ?? 0) > 0 && (
Storage-Inventar:{' '} diff --git a/admin-compliance/app/sdk/agent/_components/__tests__/CookieLibraryPanel.test.tsx b/admin-compliance/app/sdk/agent/_components/__tests__/CookieLibraryPanel.test.tsx index c0a46559..9e05ec19 100644 --- a/admin-compliance/app/sdk/agent/_components/__tests__/CookieLibraryPanel.test.tsx +++ b/admin-compliance/app/sdk/agent/_components/__tests__/CookieLibraryPanel.test.tsx @@ -27,6 +27,16 @@ describe('CookieFindingList', () => { expect(screen.getByText(/Keine Abweichungen/)).toBeInTheDocument() }) + it('zeigt den Drift-Strip (Richtlinie vs. Browser-Realität)', () => { + render() + expect(screen.getByText(/Richtlinie ↔ Realität/)).toBeInTheDocument() + expect(screen.getByText(/31 undokumentiert geladen/)).toBeInTheDocument() + }) + it('zeigt das Storage-Inventar (echte Cookies vs. andere)', () => { render( 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