97 lines
4.6 KiB
Python
97 lines
4.6 KiB
Python
"""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)
|