138 lines
5.8 KiB
Python
138 lines
5.8 KiB
Python
import unittest
|
|
|
|
from fastapi import HTTPException
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.api.operation_kpis import get_operation_kpi_service, require_current_user
|
|
from app.main import app
|
|
|
|
|
|
class StubOperationKpiService:
|
|
def get_dashboard(self, current_user):
|
|
if current_user["role"] != "admin":
|
|
raise HTTPException(status_code=403, detail="forbidden")
|
|
return {
|
|
"scope": {
|
|
"tenant_id": current_user["tenant_id"],
|
|
"usage_scope": "current_tenant",
|
|
"plan_distribution_scope": "platform_counts",
|
|
"timezone": "UTC",
|
|
},
|
|
"generated_at": "2026-05-21T00:00:00+00:00",
|
|
"periods": [
|
|
{
|
|
"key": "monthly",
|
|
"label": "本月",
|
|
"start_at": "2026-05-01T00:00:00+00:00",
|
|
"end_at": "2026-05-21T00:00:00+00:00",
|
|
"metrics": {
|
|
"ai_usage_count": 7,
|
|
"review_count": 2,
|
|
"generation_count": 2,
|
|
"chat_message_count": 1,
|
|
"report_download_count": 1,
|
|
"clause_recommendation_count": 2,
|
|
"clause_action_total": 3,
|
|
"clause_action_applied": 2,
|
|
"clause_action_ignored": 1,
|
|
"clause_action_adoption_rate_percent": 66.67,
|
|
"clause_recommendation_shown_count": 4,
|
|
"clause_recommendation_applied_count": 1,
|
|
"clause_recommendation_modified_count": 1,
|
|
"clause_recommendation_ignored_count": 1,
|
|
"clause_recommendation_adoption_rate_percent": 50.0,
|
|
"clause_recommendation_action_rate_percent": 75.0,
|
|
"quality_eval_run_count": 3,
|
|
"quality_eval_passed_count": 2,
|
|
"quality_eval_failed_count": 1,
|
|
"quality_eval_running_count": 0,
|
|
"quality_eval_pass_rate_percent": 66.67,
|
|
"quality_eval_average_score_percent": 91.5,
|
|
"legal_reference_count": 3,
|
|
"legal_reference_verified_rate_percent": 100,
|
|
},
|
|
}
|
|
],
|
|
"top_templates": [{"template_id": "tpl-1", "template_name": "采购合同模板", "usage_count": 2, "last_used_at": None}],
|
|
"clause_action_summary": {"total": 3, "applied_count": 2, "ignored_count": 1, "adoption_rate_percent": 66.67},
|
|
"risk_action_top_items": [],
|
|
"clause_recommendation_funnel": {
|
|
"total": 4,
|
|
"shown_only_count": 1,
|
|
"applied_count": 1,
|
|
"modified_count": 1,
|
|
"ignored_count": 1,
|
|
"adopted_count": 2,
|
|
"acted_count": 3,
|
|
"adoption_rate_percent": 50.0,
|
|
"action_rate_percent": 75.0,
|
|
},
|
|
"clause_recommendation_top_items": [
|
|
{
|
|
"clause_title": "验收标准与流程",
|
|
"clause_key": "acceptance",
|
|
"recommendation_kind": "missing_clause",
|
|
"action_status": "shown",
|
|
"action_count": 1,
|
|
}
|
|
],
|
|
"quality_eval_summary": {
|
|
"total_runs": 3,
|
|
"passed_runs": 2,
|
|
"failed_runs": 1,
|
|
"running_runs": 0,
|
|
"pass_rate_percent": 66.67,
|
|
"average_score_percent": 91.5,
|
|
"total_samples": 24,
|
|
"passed_samples": 21,
|
|
"sample_pass_rate_percent": 87.5,
|
|
"latest_run_id": "qualityeval-123",
|
|
"latest_subject_name": "合同文书生成默认 Prompt",
|
|
"latest_eval_domain": "prompt",
|
|
"latest_status": "passed",
|
|
"latest_finished_at": "2026-05-21T00:00:01+00:00",
|
|
},
|
|
"legal_citation_summary": {"total_reference_count": 3, "verified_reference_rate_percent": 100},
|
|
"conversion_funnel": {"trial_or_free_tenants": 1, "active_paid_tenants": 1, "plan_distribution": []},
|
|
"overage_conversion": {"current_exceeded_count": 2, "pending_overage_order_count": 1},
|
|
}
|
|
|
|
|
|
class OperationKpisApiTestCase(unittest.TestCase):
|
|
def setUp(self):
|
|
app.dependency_overrides[get_operation_kpi_service] = lambda: StubOperationKpiService()
|
|
self.client = TestClient(app)
|
|
|
|
def tearDown(self):
|
|
app.dependency_overrides.clear()
|
|
|
|
def test_admin_can_get_operation_kpi_dashboard(self):
|
|
app.dependency_overrides[require_current_user] = lambda: {
|
|
"id": "user-admin",
|
|
"tenant_id": "tenant-demo-001",
|
|
"role": "admin",
|
|
}
|
|
|
|
response = self.client.get("/api/v1/operation-kpis/dashboard")
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.json()["data"]["periods"][0]["metrics"]["ai_usage_count"], 7)
|
|
self.assertEqual(response.json()["data"]["quality_eval_summary"]["total_runs"], 3)
|
|
self.assertEqual(response.json()["data"]["top_templates"][0]["template_id"], "tpl-1")
|
|
|
|
def test_member_cannot_get_operation_kpi_dashboard(self):
|
|
app.dependency_overrides[require_current_user] = lambda: {
|
|
"id": "user-member",
|
|
"tenant_id": "tenant-demo-001",
|
|
"role": "member",
|
|
}
|
|
|
|
response = self.client.get("/api/v1/operation-kpis/dashboard")
|
|
|
|
self.assertEqual(response.status_code, 403)
|
|
self.assertEqual(response.json()["message"], "forbidden")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|