"""DSEAgent — kuratierte Art-13/14-Checkliste (kein Library-Firehose).""" from __future__ import annotations import asyncio from compliance.services.specialist_agents import REGISTRY, AgentInput def _run(text: str): return asyncio.run( REGISTRY.get("dse").evaluate(AgentInput(doc_type="dse", text=text))) def test_dse_agent_registered(): assert REGISTRY.get("dse") is not None def test_dse_detects_core_obligations(): text = ( "Datenschutzerklaerung. Verantwortlich im Sinne der DSGVO ist die " "Muster GmbH, Musterstrasse 1, 12345 Berlin. E-Mail: info@muster.de. " "Datenschutzbeauftragter: dsb@muster.de. Zwecke der Verarbeitung und " "Rechtsgrundlage Art. 6 Abs. 1. Empfaenger Ihrer Daten. Speicherdauer " "der Daten. Ihre Rechte: Auskunft, Loeschung, Widerspruch, Beschwerde " "bei der Aufsichtsbehoerde. ") * 3 out = _run(text) assert out.agent == "dse" # 10 L1-Pflichtangaben immer + L2-Details deren Parent vorhanden ist # (fehlende Parents → L2 übersprungen, kein 'na'-Rauschen). assert 10 <= out.mc_total <= 33 ok = [c.label for c in out.mc_coverage if c.status == "ok"] assert any("Verantwortlich" in lbl for lbl in ok) assert any("Rechtsgrundlage" in lbl for lbl in ok) def test_dse_missing_obligations_are_findings(): out = _run("Lorem ipsum dolor sit amet consectetur adipiscing elit. " * 6) assert out.findings assert any(f.severity == "HIGH" for f in out.findings) def test_dse_short_text_skips(): out = _run("zu kurz") assert out.confidence == 0.0 assert all(c.status == "skipped" for c in out.mc_coverage) def test_third_country_high_when_applicable_no_na_detail_short_action(): # Text ohne Drittland-Abschnitt + Scan-Kontext drittland=ja: # - third_country (L1) fehlt → HIGH (nicht weiches MEDIUM) # - Transfermechanismus (L2) → KEIN 'na' (übersprungen, Parent deckt ab) # - Titel/Maßnahme kurz (kein 280-Zeichen-Hint als Recommendation-Titel) text = ("Datenschutz. Verantwortlich ist die Muster GmbH, info@muster.de. " "Zwecke und Rechtsgrundlage Art. 6. Speicherdauer. Ihre Rechte. ") * 4 out = asyncio.run(REGISTRY.get("dse").evaluate(AgentInput( doc_type="dse", text=text, context={"scan_context": {"third_country_transfer": "yes"}}))) tc = [f for f in out.findings if "Drittland" in f.title] assert tc and tc[0].severity == "HIGH" assert not any(c.status == "na" and "Transfermechanismus" in c.label for c in out.mc_coverage) assert all(len(f.action) < 110 for f in out.findings) # Detail-Begründung bleibt als evidence erhalten assert any(f.evidence for f in out.findings)