Files
hermes 31b1a62cb2 feat: Phase 3 Tasks 23-25 + Quality-Gate-Fixes
Task 23: Worker-Intake-Pipeline verbinden
- ergebnis-Feld in Submission/Payload
- worker.py extrahiert + worker_loop refactor
- test_worker.py mit VerarbeiteSubmission/WorkerLoop tests

Task 24: Admin-Stats mit echten Daten
- processed_total, uptime, error_rate, VERSION
- admin_health mit Redis-Live-Daten

Task 25: E2E-Integrationstest + worker_refaktorisiert

Quality-Gate-Fixes:
- consumername Collision: 'worker-1' -> f'worker-{id(self)}'
- fakeredis block=0 Timeout fix
- WhatsApp/Telegram webhook payload fixes
- test_telegram/integration/e2e/refaktorisiert
- handler.py recovery nach corrupted Patch
2026-06-23 21:38:50 +00:00

89 lines
2.9 KiB
Python

"""Tests für Queue-Worker."""
from datetime import datetime
from unittest.mock import MagicMock, patch
from src.queue.worker import verarbeite_submission, worker_loop
class TestVerarbeiteSubmission:
"""Tests für verarbeite_submission."""
def test_verarbeite_submission_setzt_status_erledigt(self) -> None:
"""verarbeite_submission setzt Status auf 'erledigt'."""
submission = MagicMock()
submission.message_id = "msg_id"
submission.zeitstempel = datetime.now()
submission.absender = "+491****7890"
submission.text = "Test Message"
submission.ergebnis = None
assert submission.status != "erledigt"
result = verarbeite_submission(submission)
assert result is True
assert submission.status == "erledigt"
assert submission.ergebnis is not None
class TestWorkerLoop:
"""Tests für worker_loop."""
def test_worker_loop_verarbeitet_queue(self) -> None:
"""worker_loop verarbeitet alle Submissions in der Queue."""
mock_qh = MagicMock()
mock_sub = MagicMock()
mock_sub.zeitstempel = datetime.now()
mock_sub.absender = "+491****7890"
mock_sub.text = "Test"
mock_sub.message_id = "msg1"
mock_sub.ergebnis = MagicMock()
calls = [False]
def dequeue_side_effect(count: int = 5) -> list:
if not calls[0]:
calls[0] = True
return [mock_sub]
return []
mock_qh.dequeue.side_effect = dequeue_side_effect
with (
patch("src.queue.worker.verarbeite_submission", return_value=True) as mock_verarb,
patch("src.queue.worker.time.sleep", return_value=None),
):
worker_loop(mock_qh, poll_interval=0, batch_size=5, max_iterations=2)
assert mock_verarb.call_count >= 1
assert mock_qh.mark_done.call_count >= 1
def test_worker_loop_stopt_nicht_bei_fehler(self) -> None:
"""worker_loop crasht nicht bei Fehler in einer Submission."""
mock_qh = MagicMock()
def dequeue_side_effect(count: int = 5) -> list:
if not hasattr(dequeue_side_effect, "called"):
dequeue_side_effect.called = True # type: ignore[attr-defined]
m = MagicMock()
m.zeitstempel = datetime.now()
m.absender = "+491****7890"
m.text = "Test"
m.message_id = "msg_err"
return [m]
return []
mock_qh.dequeue.side_effect = dequeue_side_effect
with (
patch(
"src.queue.worker.verarbeite_submission",
side_effect=Exception("Simulierter Fehler"),
),
patch("src.queue.worker.time.sleep", return_value=None),
):
worker_loop(mock_qh, poll_interval=0, batch_size=5, max_iterations=2)
assert True