import unittest from fastapi import HTTPException from fastapi.testclient import TestClient from app.api.quality_evals import get_quality_eval_service, require_current_user from app.main import app class StubQualityEvalService: def __init__(self): self.runs = [ { "id": "qualityeval-123", "tenant_id": "tenant-demo-001", "source_kind": "prompt_asset_evaluation_run", "source_run_id": "prompteval-123", "eval_domain": "prompt", "subject_type": "prompt_asset", "subject_id": "prompt-123", "subject_key": "contract_generation_default", "subject_name": "Contract generation default", "suite_key": "phase13_generation", "status": "passed", "sample_count": 2, "passed_samples": 2, "failed_samples": 0, "pass_rate": 1.0, "quality_score": 0.97, "report": {"passed": True, "sample_count": 2}, "failure_reason": None, "triggered_by": "user-admin", "started_at": "2026-05-23T00:00:00+00:00", "finished_at": "2026-05-23T00:00:01+00:00", "created_at": "2026-05-23T00:00:00+00:00", } ] def _require_admin(self, current_user): if current_user["role"] != "admin": raise HTTPException(status_code=403, detail="forbidden") def list_quality_eval_runs(self, current_user, page, page_size, *, source_kind=None, eval_domain=None, subject_type=None, status_filter=None): self._require_admin(current_user) return { "items": self.runs, "page": page, "page_size": page_size, "total": len(self.runs), } def get_quality_eval_run_detail(self, current_user, run_id): self._require_admin(current_user) return { "run": self.runs[0], "items": [ { "id": "qualityitem-123", "tenant_id": "tenant-demo-001", "quality_eval_run_id": run_id, "item_key": "GEN-001", "item_name": "GEN-001", "status": "passed", "score": 0.98, "expected": {"sample_id": "GEN-001"}, "actual": {"status": "passed"}, "evidence": {"sample_id": "GEN-001"}, "failure_reason": None, "created_at": "2026-05-23T00:00:00+00:00", } ], } class QualityEvalsApiTestCase(unittest.TestCase): def setUp(self): app.dependency_overrides[get_quality_eval_service] = lambda: StubQualityEvalService() self.client = TestClient(app) def tearDown(self): app.dependency_overrides.clear() def test_admin_can_list_and_view_quality_evals(self): app.dependency_overrides[require_current_user] = lambda: { "id": "user-admin", "tenant_id": "tenant-demo-001", "role": "admin", } list_response = self.client.get("/api/v1/quality-evals/runs") detail_response = self.client.get("/api/v1/quality-evals/runs/qualityeval-123") self.assertEqual(list_response.status_code, 200) self.assertEqual(list_response.json()["data"]["items"][0]["source_run_id"], "prompteval-123") self.assertEqual(detail_response.status_code, 200) self.assertEqual(detail_response.json()["data"]["items"][0]["item_key"], "GEN-001") def test_member_cannot_access_quality_evals(self): app.dependency_overrides[require_current_user] = lambda: { "id": "user-member", "tenant_id": "tenant-demo-001", "role": "member", } response = self.client.get("/api/v1/quality-evals/runs") self.assertEqual(response.status_code, 403) self.assertEqual(response.json()["message"], "forbidden") if __name__ == "__main__": unittest.main()