Files
ai-contract-platform/backend/tests/test_legal_document_drafts_api.py
T
yuqei 3df85fdb04 feat: land phase15 legal docs and commercial ops
Includes legal document generation workflows, prompt governance runtime wiring, legal change impact scans, operation KPI dashboards, invoice files, sales follow-up events, mobile review polish, deployment automation, and updated project docs.
2026-05-21 14:42:44 +08:00

164 lines
6.2 KiB
Python

import unittest
from fastapi.testclient import TestClient
from app.api.legal_document_drafts import (
get_audit_log_service,
get_legal_document_draft_service,
require_current_user,
)
from app.main import app
class StubAuditLogService:
def __init__(self):
self.events = []
def record_event(self, **kwargs):
self.events.append(kwargs)
return kwargs
class StubLegalDocumentDraftService:
def __init__(self):
self.draft = {
"id": "ldd-001",
"tenant_id": "tenant-demo-001",
"user_id": "user-member",
"document_type_code": "procurement_goods",
"title": "采购合同草稿",
"status": "draft",
"element_values": {"party_a": {"name": "甲方公司"}},
"validation_result": {"valid": False, "errors": [{"field_key": "party_b.name", "message": "required"}]},
"element_schema_id": "ldes-procurement-v1",
"element_schema_version_label": "v1.0",
"template_id": "tpl-procurement",
"generated_contract_id": None,
"submitted_at": None,
"deleted_at": None,
"created_at": "2026-05-20T00:00:00+00:00",
"updated_at": "2026-05-20T00:00:00+00:00",
}
def list_drafts(self, current_user, document_type_code=None, status_value="draft", limit=20):
return {"items": [self.draft], "total": 1}
def create_draft(self, current_user, **kwargs):
created = dict(self.draft)
created.update(
{
"document_type_code": kwargs["document_type_code"],
"element_values": kwargs["element_values"],
"title": kwargs.get("title"),
"template_id": kwargs.get("template_id"),
}
)
return created
def get_draft(self, current_user, draft_id):
return dict(self.draft, id=draft_id)
def update_draft(self, current_user, draft_id, **kwargs):
updated = dict(self.draft, id=draft_id)
updated.update({key: value for key, value in kwargs.items() if value is not None})
return updated
def delete_draft(self, current_user, draft_id):
return dict(self.draft, id=draft_id, status="deleted", deleted_at="2026-05-20T00:01:00+00:00")
def generate_from_draft(self, current_user, draft_id, **kwargs):
generated_draft = dict(self.draft, id=draft_id, status="generated", generated_contract_id="contract-001")
return {
"draft": generated_draft,
"generated_contract": {
"id": "contract-001",
"document_type_code": "procurement_goods",
"elements_snapshot": self.draft["element_values"],
"metadata": {
"element_schema_id": "ldes-procurement-v1",
"element_schema_version_label": "v1.0",
},
},
}
class LegalDocumentDraftsApiTestCase(unittest.TestCase):
def setUp(self):
self.audit_log_service = StubAuditLogService()
self.draft_service = StubLegalDocumentDraftService()
app.dependency_overrides[get_legal_document_draft_service] = lambda: self.draft_service
app.dependency_overrides[get_audit_log_service] = lambda: self.audit_log_service
app.dependency_overrides[require_current_user] = lambda: {
"id": "user-member",
"tenant_id": "tenant-demo-001",
"role": "member",
}
self.client = TestClient(app)
def tearDown(self):
app.dependency_overrides.clear()
def test_user_can_list_recent_drafts(self):
response = self.client.get("/api/v1/legal-document-drafts")
self.assertEqual(response.status_code, 200)
body = response.json()
self.assertEqual(body["data"]["total"], 1)
self.assertEqual(body["data"]["items"][0]["id"], "ldd-001")
def test_user_can_save_draft_and_write_audit_log(self):
response = self.client.post(
"/api/v1/legal-document-drafts",
json={
"document_type_code": "procurement_goods",
"title": "采购合同草稿",
"template_id": "tpl-procurement",
"element_values": {"party_a": {"name": "甲方公司"}},
},
)
self.assertEqual(response.status_code, 200)
body = response.json()
self.assertEqual(body["data"]["document_type_code"], "procurement_goods")
self.assertEqual(body["data"]["element_values"]["party_a"]["name"], "甲方公司")
self.assertEqual(self.audit_log_service.events[0]["action"], "save_legal_document_draft")
def test_user_can_restore_update_delete_and_generate_from_draft(self):
detail = self.client.get("/api/v1/legal-document-drafts/ldd-001")
self.assertEqual(detail.status_code, 200)
self.assertEqual(detail.json()["data"]["id"], "ldd-001")
updated = self.client.put(
"/api/v1/legal-document-drafts/ldd-001",
json={"title": "已恢复草稿", "element_values": {"party_a": {"name": "甲方公司"}}},
)
self.assertEqual(updated.status_code, 200)
self.assertEqual(updated.json()["data"]["title"], "已恢复草稿")
generated = self.client.post(
"/api/v1/legal-document-drafts/ldd-001/generate",
json={"export_format": "pdf", "options": {"watermark": True}},
)
self.assertEqual(generated.status_code, 200)
self.assertEqual(generated.json()["data"]["draft"]["generated_contract_id"], "contract-001")
self.assertEqual(
generated.json()["data"]["generated_contract"]["elements_snapshot"]["party_a"]["name"],
"甲方公司",
)
deleted = self.client.delete("/api/v1/legal-document-drafts/ldd-001")
self.assertEqual(deleted.status_code, 200)
self.assertEqual(deleted.json()["data"]["status"], "deleted")
self.assertEqual(
[event["action"] for event in self.audit_log_service.events],
[
"update_legal_document_draft",
"generate_contract_from_legal_document_draft",
"delete_legal_document_draft",
],
)
if __name__ == "__main__":
unittest.main()