403e3c66d2
Für die Library-getroffene Teilmesse (~32%) pro Cookie die Feld- Abweichungen deklariert→Library (Kategorie/Laufzeit/Zweck) als Diff-Karte, plus ehrlicher Funnel (gesamt → geprüft → abweichend) — nicht-getroffene Cookies sind nicht prüfbar (kein Pass/Fail), passend zur Tonalität. - analyze_cookies: 'expected'-Soll-Wert an tracker_as_necessary/ excessive_lifetime/missing_purpose (+ _CAT_LABEL_DE). - neues cookie_declaration_diff.build_declaration_diff: reine Regroup- Aggregation der Findings pro Cookie (single source = analyze_cookies), Hinweis-Typen (third_country/eu_alternative) bewusst ausgeschlossen. - cookie-check exponiert out['declaration_diff']. - CookieDeclarationDiff.tsx oben im Cookie-Tab (vor Panel/ResultView). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
40 lines
1.9 KiB
Python
40 lines
1.9 KiB
Python
"""Deklaration-vs-Bibliothek-Diff: Regroup pro Cookie + Funnel."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from compliance.services.cookie_declaration_diff import build_declaration_diff
|
|
|
|
|
|
def test_groups_diffs_per_cookie_with_funnel():
|
|
analysis = {
|
|
"summary": {"checked": 100, "in_library": 32, "findings": 4},
|
|
"findings": [
|
|
{"vendor": "Google", "cookie": "_ga", "type": "tracker_as_necessary",
|
|
"severity": "HIGH", "declared": "notwendig", "expected": "Marketing",
|
|
"remediation": "Als § 25 einstufen."},
|
|
{"vendor": "Google", "cookie": "_ga", "type": "excessive_lifetime",
|
|
"severity": "LOW", "declared": "Session", "expected": "730 Tage",
|
|
"remediation": "Laufzeit prüfen."},
|
|
{"vendor": "Meta", "cookie": "_fbp", "type": "missing_purpose",
|
|
"severity": "MEDIUM", "declared": "(kein Zweck)", "expected": "Tracking",
|
|
"remediation": "Zweck ergänzen."},
|
|
# Hinweis-Typ ohne Library-Soll → NICHT im Diff.
|
|
{"vendor": "Google", "cookie": "_ga", "type": "third_country",
|
|
"severity": "MEDIUM", "declared": "US"},
|
|
],
|
|
}
|
|
out = build_declaration_diff(analysis)
|
|
assert out["coverage"] == {"total": 100, "checked": 32, "discrepant": 2}
|
|
ga = next(r for r in out["rows"] if r["cookie"] == "_ga")
|
|
assert {d["field"] for d in ga["diffs"]} == {"Kategorie", "Laufzeit"}
|
|
assert ga["severity"] == "HIGH" # höchste der beiden
|
|
assert ga["diffs"][0]["severe"] is True
|
|
assert out["rows"][0]["cookie"] == "_ga" # HIGH zuerst sortiert
|
|
|
|
|
|
def test_no_discrepancies_yields_empty_rows():
|
|
out = build_declaration_diff(
|
|
{"summary": {"checked": 10, "in_library": 4}, "findings": []})
|
|
assert out["coverage"] == {"total": 10, "checked": 4, "discrepant": 0}
|
|
assert out["rows"] == []
|