Files
breakpilot-compliance/consent-tester/tests/test_scan_matrix_summary.py
T
Benjamin Admin 881e9c28de feat(consent-tester): /scan-matrix echt — Profil je Engine + Per-Engine-Summary (Phase 1.2)
- _scanner_run reicht browser_profile an run_consent_test durch (statt Single-Chromium-Shim)
- neue scan_matrix_summary.matrix_scan_dict: ConsentTestResult -> schlanke
  Matrix-dict-Form (phases fuer _extract_dimensions + kompakter `summary`:
  cookies_before_consent/after_reject, reject_respected-Heuristik [keine
  Verstoesse UND kein neuer Tracker], surface, screenshot)
- multi_browser_scanner._run_one hebt summary + engine + is_mobile an die
  Zeile, verwirft die vollen Cookie-Listen (JSONB-Persistenz schlank)
- consent_scanner: _ctx_base mit Mobile-Device-Emulation (iPhone-Profil ->
  echtes Mobile-Viewport/Touch), alle 5 new_context auf **_ctx_base
- Tests: test_scan_matrix_summary (6) inkl. _extract_dimensions-Vertrag

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-12 22:46:42 +02:00

74 lines
2.9 KiB
Python

"""Per-Engine-Projektion der Browser-Matrix (`scan_matrix_summary`).
Sichert: ConsentTestResult → schlanke Matrix-dict-Form mit (a) phases, die
`multi_browser_scanner._extract_dimensions` lesen kann, und (b) kompaktem
`summary` (cookies_before/after_reject, reject_respected-Heuristik, Surface).
"""
from types import SimpleNamespace
from services.scan_matrix_summary import matrix_scan_dict
from services.multi_browser_scanner import _extract_dimensions
def _result(**kw):
base = dict(
banner_detected=True, banner_provider="Usercentrics",
before_cookies=[], reject_cookies=[],
before_violations=[], reject_violations=[], reject_new_tracking=[],
banner_text_violations=[],
banner_has_impressum_link=True, banner_has_dse_link=True,
banner_screenshot_b64="iVBOR_fake",
)
base.update(kw)
return SimpleNamespace(**base)
def test_cookie_counts_and_names_capped():
r = _result(before_cookies=[f"c{i}" for i in range(50)],
reject_cookies=["a", "b"])
out = matrix_scan_dict(r)
s = out["summary"]
assert s["cookies_before_consent"] == 50
assert s["cookies_after_reject"] == 2
assert len(s["cookies_before_names"]) == 40 # gedeckelt
assert s["cookies_after_reject_names"] == ["a", "b"]
def test_reject_respected_true_when_no_violation_no_tracking():
r = _result(reject_cookies=["consent_choice"]) # essentielles Cookie bleibt
out = matrix_scan_dict(r)
# Verbleibendes essentielles Cookie allein darf NICHT als Verstoß zählen.
assert out["summary"]["reject_respected"] is True
def test_reject_respected_false_on_reject_violation():
r = _result(reject_violations=[SimpleNamespace(severity="HIGH", text="x")])
assert matrix_scan_dict(r)["summary"]["reject_respected"] is False
def test_reject_respected_false_on_new_tracking():
r = _result(reject_new_tracking=["google-analytics"])
assert matrix_scan_dict(r)["summary"]["reject_respected"] is False
def test_surface_and_screenshot_passthrough():
r = _result(banner_has_impressum_link=False,
banner_text_violations=[SimpleNamespace(severity="LOW", text="y")])
out = matrix_scan_dict(r)
assert out["summary"]["surface"]["has_impressum_link"] is False
assert out["summary"]["surface"]["has_dse_link"] is True
assert out["summary"]["surface"]["banner_text_issues"] == 1
assert out["summary"]["banner_screenshot_b64"] == "iVBOR_fake"
def test_phases_shape_readable_by_extract_dimensions():
# Vertrag: die Projektion MUSS von _extract_dimensions konsumierbar sein.
r = _result(before_cookies=["a", "b", "c"], reject_cookies=["d"])
out = matrix_scan_dict(r)
dims = _extract_dimensions(out)
assert set(dims) == {"pre_consent", "reject_respect", "banner_design"}
# 3 Pre-Cookies → pre_consent < 1.0; weniger Reject-Cookies → höher.
assert 0.0 <= dims["pre_consent"] <= 1.0
assert dims["reject_respect"] <= 1.0