Files
next-tjwater-server/tests/unit/test_investigation_report_authoring.py
T
jiang b45c5c6f46
Generic Container CI/CD / test-build-publish (push) Successful in 4m31s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 4m31s
feat(investigations): refine report authoring and replay flushing
2026-11-14 23:00:15 +08:00

97 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""New publications are readable; historical reports keep their original evidence."""
from copy import deepcopy
import pytest
from app.domain.schemas.operational_task import (
InvestigationProgress,
InvestigationProgressInput,
InvestigationReport,
InvestigationReportInput,
)
def report():
return {
"title": "压力异常恢复复核报告",
"current_conclusion": "恢复复核通过。7 月 16 日 13:15,13 台复核设备均处于历史正常范围。",
"conclusion_boundary": "依据完工后的一个采样时刻判断恢复,长期稳定性继续由日常监测跟踪。",
"stage": "final", "outcome": "concluded", "data_gaps": [],
"evidence_refs": ["recovery:sha256:stored-evidence"],
"recommendations": ["继续监测压力与流量。"], "pending_items": [],
}
@pytest.mark.parametrize("text", [
"恢复复核 status=passed,13 台设备 normal。",
"第 3 轮 execution_generation=3,handling_context.phase=verification_ready。",
"完工后 required_samples=1,interval_seconds=900,verified_through=13:15。",
"已读取 recovery:sha256:01234567,复核通过。",
"Skill scada-anomaly v1.0.16 已按 Server 分发执行。",
"query_scada_readings 已执行,query_complete=true。",
"关联工单 60000000-0000-4000-8000-000000000002 已完工。",
"恢复采样时间为 2026-07-16T05:15:00Z。",
"恢复采样时间为 2026-07-16 13:15(UTC+8)。",
"恢复采样时间为 2026-07-16 13:15+08:00。",
"**恢复复核通过**,其余设备正常。",
"<strong>恢复复核通过</strong>。",
])
def test_new_report_and_progress_reject_execution_details_and_raw_display_markup(text):
legacy = {**report(), "current_conclusion": text}
assert InvestigationReport.model_validate(legacy).current_conclusion == text
assert InvestigationProgress.model_validate({"summary": text}).summary == text
with pytest.raises(ValueError):
InvestigationReportInput.model_validate(legacy)
with pytest.raises(ValueError):
InvestigationProgressInput.model_validate({"summary": text})
@pytest.mark.parametrize(("field", "limit"), [
("title", 80), ("current_conclusion", 300), ("conclusion_boundary", 240),
])
def test_new_report_bounds_summary_fields_without_truncating_history(field, limit):
valid = {**report(), field: "测" * limit}
assert getattr(InvestigationReportInput.model_validate(valid), field) == valid[field]
too_long = {**valid, field: "测" * (limit + 1)}
assert getattr(InvestigationReport.model_validate(too_long), field) == too_long[field]
with pytest.raises(ValueError):
InvestigationReportInput.model_validate(too_long)
def test_progress_summary_is_short_and_keeps_technical_references_structured():
progress = {"summary": "测" * 300, "graph_update": {"nodes": [{
"node_id": "recovery", "label": "恢复监测复核通过", "status": "recorded",
"evidence_refs": ["recovery:sha256:stored-evidence"],
}]}}
assert InvestigationProgressInput.model_validate(progress).summary == progress["summary"]
with pytest.raises(ValueError):
InvestigationProgressInput.model_validate({**progress, "summary": "测" * 301})
def test_asset_ids_measurements_and_evidence_linked_tables_remain_publishable():
value = report()
value["current_conclusion"] = "05:00-08:00 的候选管段 515870(DN600)相似度 97.08%,尚待现场核验。压力测点 170486 回升至 26.12 m。"
value["ui_blocks"] = [{"evidence_refs": value["evidence_refs"], "block": {
"version": "answer-ui@1", "block_id": "recovery-table", "phase": "final",
"fallback_text": "压力测点 170486 恢复至 26.12 m。",
"spec": {"root": "table", "elements": {"table": {
"type": "Table", "children": [], "props": {
"title": "恢复监测明细", "columns": ["测点", "修复后", "正常范围"],
"rows": [["170486", "26.12 m", "26.02 至 26.30 m"]],
},
}}},
}}]
assert InvestigationReportInput.model_validate(value).ui_blocks
leaked = deepcopy(value)
leaked["ui_blocks"][0]["block"]["spec"]["elements"]["table"]["props"]["rows"][0][2] = "status=passed"
assert InvestigationReport.model_validate(leaked).ui_blocks
with pytest.raises(ValueError):
InvestigationReportInput.model_validate(leaked)
@pytest.mark.parametrize("field", ["recommendations", "pending_items"])
def test_follow_up_is_business_prose(field):
value = {**report(), field: ["等待 handling_context.phase=waiting_scada。"]}
with pytest.raises(ValueError):
InvestigationReportInput.model_validate(value)