feat: add final-report audit paste tool to web UI (Closes #431)
Expose /audit and /api/audit for local validator previews using final_report_validator and review schema checks. Operators can paste reports, auto-detect task kind, and get structured findings with suggested next prompts and issue-comment drafts. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""Tests for web UI report audit paste (#431)."""
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
from starlette.testclient import TestClient
|
||||
|
||||
from webui.app import create_app
|
||||
from webui.audit_validator import audit_report, infer_task_kind
|
||||
|
||||
|
||||
_MINIMAL_REVIEW_REPORT = """## Controller Handoff
|
||||
|
||||
- Task: review PR #1
|
||||
- Repo: Scaled-Tech-Consulting/Gitea-Tools
|
||||
- Role: reviewer
|
||||
- Identity: sysadmin / prgs-reviewer
|
||||
- Review decision: approve
|
||||
"""
|
||||
|
||||
|
||||
class TestAuditValidator(unittest.TestCase):
|
||||
def test_infer_task_kind_from_review_report(self):
|
||||
self.assertEqual(infer_task_kind(_MINIMAL_REVIEW_REPORT), "review_pr")
|
||||
|
||||
def test_infer_task_kind_explicit_override(self):
|
||||
self.assertEqual(
|
||||
infer_task_kind(_MINIMAL_REVIEW_REPORT, explicit="work_issue"),
|
||||
"work_issue",
|
||||
)
|
||||
|
||||
def test_empty_report_blocked(self):
|
||||
result = audit_report("")
|
||||
self.assertTrue(result["blocked"])
|
||||
self.assertIn("empty", result["reasons"][0].lower())
|
||||
|
||||
def test_minimal_report_produces_findings(self):
|
||||
result = audit_report(_MINIMAL_REVIEW_REPORT)
|
||||
self.assertIn(result["grade"], {"blocked", "downgraded", "warning", "A"})
|
||||
self.assertTrue(result["findings"] or result["blocked"] or result["downgraded"])
|
||||
|
||||
|
||||
class TestAuditRoutes(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.client = TestClient(create_app())
|
||||
|
||||
def test_audit_page_renders_form(self):
|
||||
response = self.client.get("/audit")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn("Report audit", response.text)
|
||||
self.assertIn('name="report_text"', response.text)
|
||||
self.assertIn("Run validator preview", response.text)
|
||||
self.assertNotIn("child issue", response.text.lower())
|
||||
|
||||
def test_audit_post_runs_validator(self):
|
||||
response = self.client.post(
|
||||
"/audit",
|
||||
data={"report_text": _MINIMAL_REVIEW_REPORT, "task_kind": "review_pr"},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn("Validator preview", response.text)
|
||||
self.assertIn("Safe next action", response.text)
|
||||
|
||||
def test_api_audit_post_json(self):
|
||||
response = self.client.post(
|
||||
"/api/audit",
|
||||
json={"report_text": _MINIMAL_REVIEW_REPORT, "task_kind": "review_pr"},
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
data = response.json()
|
||||
self.assertEqual(data["task_kind"], "review_pr")
|
||||
self.assertIn("grade", data)
|
||||
self.assertIn("findings", data)
|
||||
self.assertIn("suggested_next_prompt", data)
|
||||
|
||||
def test_api_audit_rejects_empty_body(self):
|
||||
response = self.client.post("/api/audit", json={"report_text": ""})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_audit_post_allowed_other_post_still_blocked(self):
|
||||
self.assertEqual(self.client.post("/health").status_code, 405)
|
||||
self.assertEqual(
|
||||
self.client.post(
|
||||
"/audit",
|
||||
data={"report_text": _MINIMAL_REVIEW_REPORT},
|
||||
).status_code,
|
||||
200,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user