"""Tests for B13 Widerrufsbelehrung-Reachability-Check.""" from compliance.services.widerrufsbelehrung_reachability_check import ( _detect_b2c_scope, check_widerrufsbelehrung_reachability, ) def _state(widerruf_entry=None, home_text="", doc_entries=None, footer_text=""): entries = list(doc_entries or []) if widerruf_entry is not None: entries.append({"doc_type": "widerruf", **widerruf_entry}) return { "doc_entries": entries, "home_text": home_text, "footer_text": footer_text, } class TestDetectB2CScope: def test_strong_b2c_warenkorb(self): s = _state(home_text="Legen Sie das Produkt in den Warenkorb.") scope, hits = _detect_b2c_scope(s) assert scope == "b2c_strong" assert any("warenkorb" in h for h in hits) def test_b2b_only_overrides_b2c(self): s = _state(home_text="Wir verkaufen ausschließlich an Unternehmer. " "Warenkorb für Großkunden.") scope, _ = _detect_b2c_scope(s) assert scope == "b2b_only" def test_weak_signals_two_promote_to_likely(self): s = _state(home_text="Unser Shop bietet Wallbox-Produkte mit " "Rechnung zur Bestellung.") scope, _ = _detect_b2c_scope(s) assert scope == "b2c_likely" def test_single_weak_signal_stays_unknown(self): s = _state(home_text="Wir bieten einen Shop.") scope, _ = _detect_b2c_scope(s) assert scope == "unknown" def test_empty_state(self): s = _state() scope, _ = _detect_b2c_scope(s) assert scope == "unknown" class TestCheck: def test_no_widerruf_entry_no_finding(self): out = check_widerrufsbelehrung_reachability(_state()) assert out == [] def test_widerruf_reachable_no_finding(self): out = check_widerrufsbelehrung_reachability(_state( widerruf_entry={ "url": "https://shop.de/widerruf", "text": "Belehrung " * 100, "discovery_attempted": True, }, home_text="Warenkorb / zur Kasse.", )) assert out == [] def test_unreachable_plus_b2c_strong_high_finding(self): out = check_widerrufsbelehrung_reachability(_state( widerruf_entry={ "url": "", "text": "", "discovery_attempted": True, "rejected_url": "https://shop.de/widerruf", }, home_text="In den Warenkorb. Lieferzeit 2 Tage. Preis inkl. MwSt.", )) assert len(out) == 1 f = out[0] assert f["check_id"] == "WIDERRUF-REACH-001" assert f["severity"] == "HIGH" assert f["b2c_scope"] == "b2c_strong" assert "Art. 246a" in f["norm"] assert "shop.de/widerruf" in f["evidence"] def test_unreachable_plus_b2c_likely_medium(self): out = check_widerrufsbelehrung_reachability(_state( widerruf_entry={ "url": "", "text": "", "discovery_attempted": True, }, home_text="Shop bietet Wallbox und Tarif buchen.", )) assert len(out) == 1 assert out[0]["severity"] == "MEDIUM" assert out[0]["b2c_scope"] == "b2c_likely" def test_unreachable_plus_b2b_only_no_finding(self): out = check_widerrufsbelehrung_reachability(_state( widerruf_entry={ "url": "", "text": "", "discovery_attempted": True, }, home_text="B2B only — kein Verkauf an Verbraucher.", )) assert out == [] def test_unreachable_plus_unknown_scope_no_finding(self): # Pure agency / B2B-services without clear shop signals — silent. out = check_widerrufsbelehrung_reachability(_state( widerruf_entry={ "url": "", "text": "", "discovery_attempted": True, }, home_text="Wir sind eine Beratungsagentur für Mittelstand.", )) assert out == [] def test_discovery_not_attempted_no_finding(self): # Avoid false positives when discovery had no homepage to crawl. out = check_widerrufsbelehrung_reachability(_state( widerruf_entry={ "url": "", "text": "", "discovery_attempted": False, }, home_text="In den Warenkorb. Preis inkl. MwSt.", )) assert out == [] def test_footer_widerruf_link_suppresses_finding(self): out = check_widerrufsbelehrung_reachability(_state( widerruf_entry={ "url": "", "text": "", "discovery_attempted": True, }, home_text="Warenkorb. Lieferzeit. Preis inkl. MwSt.", footer_text='Widerruf', )) assert out == []