"""Tests für SSE-Endpoints des Specialist-Agent-Test-Harness.""" from __future__ import annotations import asyncio import json from unittest.mock import AsyncMock, patch import pytest from fastapi.testclient import TestClient @pytest.fixture def app(tmp_path, monkeypatch): monkeypatch.setenv("EVIDENCE_VAULT_ROOT", str(tmp_path / "vault")) from fastapi import FastAPI from compliance.api.specialist_agent_routes import router app = FastAPI() app.include_router(router, prefix="/api/v1") return app @pytest.fixture def client(app): return TestClient(app) def test_list_agents(client): r = client.get("/api/v1/specialist-agent/agents") assert r.status_code == 200 data = r.json() agent_ids = {a["agent_id"] for a in data["agents"]} assert "impressum" in agent_ids assert "cookie_policy" in agent_ids def test_start_test_invalid_agent(client): r = client.post("/api/v1/specialist-agent/test/start", json={"agent_id": "ghost", "raw_texts": ["test"]}) assert r.status_code == 404 def test_start_test_no_input(client): r = client.post("/api/v1/specialist-agent/test/start", json={"agent_id": "impressum"}) assert r.status_code == 400 def test_start_test_with_raw_text(client): r = client.post("/api/v1/specialist-agent/test/start", json={"agent_id": "impressum", "raw_texts": ["Tesla Germany GmbH " "Berlin Email: x@y.com " "HRB 123 Charlottenburg"]}) assert r.status_code == 200 data = r.json() assert data["agent_id"] == "impressum" assert data["slot_count"] == 1 assert data["run_id"] def test_stream_unknown_run(client): r = client.get("/api/v1/specialist-agent/test/stream/ghost") assert r.status_code == 404 def test_run_result_after_text_input(client, monkeypatch): # Skip LLM async def _no_cascade(*a, **kw): return None, [] monkeypatch.setattr( "compliance.services.specialist_agents.impressum.agent.cascade", _no_cascade, ) r = client.post("/api/v1/specialist-agent/test/start", json={"agent_id": "impressum", "raw_texts": [ "Tesla Germany GmbH\nLudwig-Prandtl-Strasse 25\n" "12526 Berlin\nDeutschland\nEmail: x@y.com\n" "Tel: +49 89 1250 16 800\n" "Management: Elon Musk\n" "HRB 218904 B Charlottenburg", ]}) run_id = r.json()["run_id"] # Give async task time to finish (small text → fast) for _ in range(40): rr = client.get( f"/api/v1/specialist-agent/run/{run_id}/result", ) if rr.json().get("finished"): break import time; time.sleep(0.05) res = client.get(f"/api/v1/specialist-agent/run/{run_id}/result") body = res.json() assert body["finished"] assert "text1" in body["results"] out = body["results"]["text1"] field_ids = {f["field_id"] for f in out["findings"]} # Tesla pattern: German-label fehlt + USt fehlt assert "vertretungsberechtigte_label_korrekt" in field_ids def test_artifacts_listing(client, monkeypatch): async def _no_cascade(*a, **kw): return None, [] monkeypatch.setattr( "compliance.services.specialist_agents.impressum.agent.cascade", _no_cascade, ) r = client.post("/api/v1/specialist-agent/test/start", json={"agent_id": "impressum", "raw_texts": ["Tesla Germany GmbH " "Berlin Email: x@y.com " "HRB 123 Charlottenburg"]}) run_id = r.json()["run_id"] for _ in range(40): rr = client.get( f"/api/v1/specialist-agent/run/{run_id}/result", ) if rr.json().get("finished"): break import time; time.sleep(0.05) arts = client.get( f"/api/v1/specialist-agent/run/{run_id}/artifacts", ) assert arts.status_code == 200 manifest = arts.json()["manifest"] kinds = {a["kind"] for a in manifest["assets"]} assert "finding" in kinds assert "raw" in kinds