from app.api.group_routes import _safe_analysis_progress, serialize_group def test_analysis_progress_serializer_keeps_only_bounded_public_fields(): assert _safe_analysis_progress({ "stage": "personas", "completed": 4, "total": 15, "prompt": "private prompt", "provider_error": "/private/path", }) == {"stage": "personas", "completed": 4, "total": 15} def test_analysis_progress_serializer_rejects_invalid_or_unknown_state(): assert _safe_analysis_progress({"stage": "secret", "completed": 1, "total": 1}) == {} assert _safe_analysis_progress({"stage": "personas", "completed": True, "total": 15}) == {} assert _safe_analysis_progress({"stage": "personas", "completed": 16, "total": 15}) == {} def test_group_serializer_exposes_sanitized_analysis_progress_only(): view = serialize_group({ "id": "group-1", "status": "analyzing", "analysis_progress": { "stage": "report", "completed": 0, "total": 1, "error": "private provider detail", }, "worker_input": "must not leak", }, {"role": "user"}) assert view["analysis_progress"] == {"stage": "report", "completed": 0, "total": 1} assert "worker_input" not in view assert "private provider detail" not in str(view)