ba7d98be36
Ein 'X fehlt'/'zu prüfen'-Finding wird unterdrückt, wenn die Pflicht in einem ANDEREN Snapshot-Dokument erfüllt ist (z.B. § 36 VSBG / OS-Link stehen bei BMW in AGB/'Rechtlicher Hinweis', nicht im Impressum → war False Positive). Konservative Allowlist (impressum: verbraucher_streitbeilegung, odr_link) gegen False-Reconciliation. Verdrahtet in _run_doc_agent (alle Doc-Checks). Frontend: 'In anderem Dokument abgedeckt'-Sektion. Greift voll nach Scan + Legal-Capture. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
52 lines
2.4 KiB
Python
52 lines
2.4 KiB
Python
"""B — Cross-Doc-Reconciliation: cross-doc-fähige Findings unterdrücken, wenn in
|
|
einem anderen Dokument erfüllt; Nicht-Allowlist-Felder unberührt lassen."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from compliance.services.cross_doc_reconcile import reconcile_doc_findings
|
|
|
|
|
|
def test_vsbg_reconciled_from_agb():
|
|
result = {
|
|
"findings": [
|
|
{"field_id": "verbraucher_streitbeilegung",
|
|
"status": "possibly_applicable", "severity": "LOW", "title": "VSBG"},
|
|
{"field_id": "name_anbieter", "status": "fail",
|
|
"severity": "HIGH", "title": "Name fehlt"},
|
|
],
|
|
"mc_coverage": [{"label": "Verbraucher-Streitbeilegung-Hinweis",
|
|
"status": "low"}],
|
|
"mc_low": 1, "mc_ok": 0, "mc_high": 1,
|
|
}
|
|
other = [("agb", "BMW wird nicht an einem Streitbeilegungsverfahren vor "
|
|
"einer Verbraucherschlichtungsstelle im Sinne des VSBG "
|
|
"teilnehmen und ist hierzu auch nicht verpflichtet.")]
|
|
reconcile_doc_findings(result, "impressum", other)
|
|
assert not any(f["field_id"] == "verbraucher_streitbeilegung"
|
|
for f in result["findings"])
|
|
rec = result.get("reconciled") or []
|
|
assert any(f.get("reconciled_in") == "agb" for f in rec)
|
|
# nicht-reconcilable name_anbieter bleibt aktiv
|
|
assert any(f["field_id"] == "name_anbieter" for f in result["findings"])
|
|
# Coverage-Zeile auf ok, Speedometer angepasst
|
|
assert result["mc_coverage"][0]["status"] == "ok"
|
|
assert result["mc_ok"] == 1 and result["mc_low"] == 0
|
|
|
|
|
|
def test_no_reconcile_when_absent_elsewhere():
|
|
result = {"findings": [{"field_id": "verbraucher_streitbeilegung",
|
|
"status": "possibly_applicable", "severity": "LOW"}],
|
|
"mc_coverage": []}
|
|
reconcile_doc_findings(result, "impressum",
|
|
[("agb", "Text ganz ohne dieses Thema.")])
|
|
assert result["findings"] and not result.get("reconciled")
|
|
|
|
|
|
def test_non_allowlisted_field_not_reconciled():
|
|
# name_anbieter ist NICHT cross-doc-fähig → bleibt Finding, auch wenn im AGB.
|
|
result = {"findings": [{"field_id": "name_anbieter", "status": "fail",
|
|
"severity": "HIGH"}], "mc_coverage": []}
|
|
reconcile_doc_findings(result, "impressum",
|
|
[("agb", "Bayerische Motoren Werke Aktiengesellschaft")])
|
|
assert result["findings"] and not result.get("reconciled")
|