Files
breakpilot-compliance/backend-compliance/compliance/tests/test_sse_compliance_check.py
T
Benjamin Admin 65de90114a feat(agent): SSE — progressive Themen-Tabs (Phase 2)
Der Compliance-Check streamt jetzt progressive Events; der Impressum-Tab
erscheint, sobald das Thema fertig ist, statt am Ende alles auf einmal.
Additiv — das Polling fürs finale Ergebnis bleibt.

- backend: _sse.py (Queue/emit/event_generator) + Endpoint
  /compliance-check/{id}/stream; _update emittiert progress,
  run_agent_outputs emittiert topic (laeuft jetzt frueh nach Phase B),
  Orchestrator emittiert complete/error.
- frontend: SSE-Proxy-Route + EventSource in ComplianceCheckTab merged
  topic-Events in agent_outputs -> Tab erscheint progressiv.
- Tests: backend 5 passed (SSE + agent_outputs); tsc 0 neue Fehler,
  vitest 2 passed, check-loc 0.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 19:07:26 +02:00

51 lines
1.5 KiB
Python

"""Phase 2: SSE-Plumbing für den Compliance-Check.
Deckt emit (Queue-Push), _format_sse (SSE-Zeilenformat) und den
event_generator (hello → Events → stream_close bei 'complete') ab.
"""
from __future__ import annotations
import asyncio
from compliance.api.agent_check import _sse
def test_emit_pushes_and_format():
cid = "sse-test-1"
_sse.new_queue(cid)
_sse.emit(cid, {"type": "topic", "topic": "impressum", "output": {"x": 1}})
q = _sse._check_queues[cid]
assert q.qsize() == 1
ev = q.get_nowait()
assert ev["type"] == "topic" and ev["topic"] == "impressum"
line = _sse._format_sse(ev)
assert line.startswith("data: ") and line.endswith("\n\n")
assert '"impressum"' in line
def test_emit_is_noop_without_queue():
# Kein new_queue → emit darf nicht crashen (best-effort).
_sse.emit("does-not-exist-xyz", {"type": "topic"})
def test_event_generator_streams_topic_then_closes_on_complete():
cid = "sse-test-gen"
_sse.new_queue(cid)
_sse.emit(cid, {"type": "topic", "topic": "impressum", "output": {}})
_sse.emit(cid, {"type": "complete", "status": "completed"})
async def collect():
out = []
async for line in _sse.event_generator(cid):
out.append(line)
if len(out) > 12: # safety
break
return out
blob = "".join(asyncio.run(collect()))
assert '"type": "hello"' in blob
assert '"topic": "impressum"' in blob
assert '"type": "complete"' in blob
assert '"type": "stream_close"' in blob