feat: extend operational investigation workflows
This commit is contained in:
@@ -40,6 +40,26 @@ def test_report_ui_round_trips_with_a_version_and_keeps_legacy_reports_readable(
|
||||
assert InvestigationReportRevision.model_validate(old).report.ui_blocks == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize("phase", [None, "final"])
|
||||
def test_report_ui_accepts_final_and_legacy_phases(phase):
|
||||
data = rich_report()
|
||||
if phase is not None:
|
||||
data["ui_blocks"][0]["block"]["phase"] = phase
|
||||
report = InvestigationReportInput.model_validate(data)
|
||||
assert report.ui_blocks[0].block.phase == phase
|
||||
serialized = report.model_dump()["ui_blocks"][0]["block"]
|
||||
assert ("phase" in serialized) == (phase is not None)
|
||||
assert InvestigationReportInput.model_validate(report.model_dump()).ui_blocks[0].block.phase == phase
|
||||
|
||||
|
||||
@pytest.mark.parametrize("phase", ["process", "unknown", None])
|
||||
def test_report_ui_rejects_process_and_unknown_phases(phase):
|
||||
data = rich_report()
|
||||
data["ui_blocks"][0]["block"]["phase"] = phase
|
||||
with pytest.raises(ValidationError):
|
||||
InvestigationReportInput.model_validate(data)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("defect", ["unknown", "script", "unaligned", "nan", "cycle", "unreachable", "duplicate", "foreign", "many", "oversized"])
|
||||
def test_report_ui_rejects_invalid_or_unbound_content(defect):
|
||||
data = rich_report()
|
||||
@@ -72,3 +92,26 @@ def test_report_ui_rejects_invalid_or_unbound_content(defect):
|
||||
data["ui_blocks"] = [entry, {**deepcopy(entry), "block": {**deepcopy(entry["block"]), "block_id": "second"}}]
|
||||
with pytest.raises(ValidationError):
|
||||
InvestigationReportInput.model_validate(data)
|
||||
|
||||
|
||||
def test_report_ui_accepts_semantic_results_without_allowing_raw_presentation_code():
|
||||
data = rich_report()
|
||||
spec = data["ui_blocks"][0]["block"]["spec"]
|
||||
spec["root"] = "layout"
|
||||
spec["elements"] = {
|
||||
"layout": {"type": "Stack", "props": {"columns": "one", "gap": "normal", "intent": "report", "density": "compact"}, "children": ["section"]},
|
||||
"section": {"type": "Section", "props": {"title": "演练结果", "description": None, "role": "result"}, "children": ["result", "note"]},
|
||||
"result": {"type": "Result", "props": {"title": "演练记录已保存", "summary": "现场处置仍待核验。", "status": "partial", "source": "演练回执"}, "children": []},
|
||||
"note": {"type": "Text", "props": {"title": "核验说明", "text": "结果仅限演练。", "tone": "neutral"}, "children": []},
|
||||
}
|
||||
restored = InvestigationReportInput.model_validate(data)
|
||||
assert restored.ui_blocks[0].block.spec.elements["result"].props["status"] == "partial"
|
||||
for extra in ({"style": {"color": "red"}}, {"className": "text-red-500"}, {"css": "display:none"}, {"action": "dispatch"}):
|
||||
invalid = deepcopy(data)
|
||||
invalid["ui_blocks"][0]["block"]["spec"]["elements"]["result"]["props"].update(extra)
|
||||
with pytest.raises(ValidationError):
|
||||
InvestigationReportInput.model_validate(invalid)
|
||||
invalid = deepcopy(data)
|
||||
invalid["ui_blocks"][0]["block"]["spec"]["elements"]["result"]["children"] = ["note"]
|
||||
with pytest.raises(ValidationError):
|
||||
InvestigationReportInput.model_validate(invalid)
|
||||
|
||||
Reference in New Issue
Block a user