"""Tests für den Cross-Placement-Agent (deplatzierter Content).""" from __future__ import annotations import asyncio import pytest from compliance.services.specialist_agents import ( REGISTRY, AgentInput, CrossPlacementAgent, Severity, ) from tests.fixtures.impressum_groundtruth import ( ETO, HECTRONIC, SAFETYKON, BMW, ) def _run(coro): return asyncio.get_event_loop().run_until_complete(coro) def test_agent_is_registered(): agent = REGISTRY.get("cross_placement") assert agent is not None assert agent.doc_type == "impressum" def test_short_text_skipped(): agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput(doc_type="impressum", text="x"))) assert all(c.status == "skipped" for c in out.mc_coverage) def test_eto_finds_nutzungsbedingungen_and_haftung(): """ETO-Impressum hat Nutzungsbedingungen + Haftungsbeschränkung — Cross-Placement-Agent muss das melden.""" agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput( doc_type="impressum", text=ETO.text, ))) field_ids = {f.field_id for f in out.findings} # ETO-Impressum hat keine Sektionen wie Copyright/Disclaimer → # nur die Pflichtangaben. Test prüft dass ETO sauber ist. # User-GT: placement_concerns = () → 0 Findings erwartet assert not out.findings, ( f"ETO sollte keine Placement-Findings haben, hat aber: " f"{field_ids}" ) def test_safetykon_finds_urheberrecht_and_haftung(): """Safetykon hat Urheberrecht + Bilder/Lizenzen + Haftungsausschluss im Impressum-Block — alle drei sollen gemeldet werden.""" agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput( doc_type="impressum", text=SAFETYKON.text, ))) field_ids = {f.field_id for f in out.findings} assert "urheberrecht" in field_ids assert "bilder_lizenzen" in field_ids assert "haftungsausschluss" in field_ids def test_hectronic_finds_weee_copyright_haftung(): """Hectronic hat WEEE-Reg + Copyright + Haftungsausschluss im Impressum-Block.""" agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput( doc_type="impressum", text=HECTRONIC.text, ))) field_ids = {f.field_id for f in out.findings} assert "weee_elektrog" in field_ids assert "urheberrecht" in field_ids # 'Copyright' heading assert "haftungsausschluss" in field_ids def test_bmw_is_clean(): """BMW-Impressum ist sauber (nur Pflichtangaben) — 0 Findings.""" agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput( doc_type="impressum", text=BMW.text, ))) assert not out.findings, ( f"BMW sollte sauber sein, hat aber: " f"{[f.field_id for f in out.findings]}" ) def test_recommendation_mentions_legal_footer(): """Best-Practice-Empfehlung muss 'Legal'-Footer-Tab vorschlagen.""" agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput( doc_type="impressum", text=HECTRONIC.text, ))) assert out.findings sample = out.findings[0] assert "Legal" in sample.action assert "Footer" in sample.action def test_weee_is_product_compliance_medium(): """ElektroG/WEEE ist eine echte Pflicht aber Ort umstritten → MEDIUM statt LOW.""" agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput( doc_type="impressum", text=HECTRONIC.text, ))) weee = next(f for f in out.findings if f.field_id == "weee_elektrog") assert weee.severity == Severity.MEDIUM.value def test_copyright_is_low(): """Copyright/Urheberrecht ist BPa nicht zwingend Impressum-Pflicht → LOW.""" agent = CrossPlacementAgent() out = _run(agent.evaluate(AgentInput( doc_type="impressum", text=SAFETYKON.text, ))) cp = next(f for f in out.findings if f.field_id == "urheberrecht") assert cp.severity == Severity.LOW.value