import argparse import json import pytest from pydantic import ValidationError from scripts.import_agent_investigation import convert_plan, run @pytest.fixture def anyio_backend(): return "asyncio" def snapshot(): return {"session_id": "ses_test", "revision": 1, "updated_at": "2026-09-23T00:00:00Z", "title": "合成调查", "nodes": [ {"id": "STAGE_JUDGMENT", "title": "阶段判断", "owner": "agent", "status": "completed", "detail": "合成证据不足以确定原因", "evidence": ["合成输入"]}, {"id": "SAMPLE", "title": "采样", "owner": "human", "status": "waiting", "detail": "等待现场采样反馈", "evidence": []}, ], "edges": [{"from": "STAGE_JUDGMENT", "to": "SAMPLE"}]} def test_legacy_conversion_preserves_waiting_and_explicit_synthetic_boundary(): plan, evidence, report = convert_plan(snapshot()) assert plan["nodes"][1]["status"] == "waiting" assert all(item["kind"] == "synthetic" for item in evidence) assert report["pending_items"] == ["等待现场采样反馈"] assert report["current_conclusion"] == "合成证据不足以确定原因" assert "未重新查询当前数据" in report["conclusion_boundary"] assert report["evidence_refs"] == [evidence[0]["evidence_id"]] @pytest.mark.anyio async def test_dry_run_validates_historical_schema_before_any_network_access(tmp_path, monkeypatch, capsys): metadata_dir = tmp_path / "session-metadata" states_dir = tmp_path / "session-ui-states" metadata_dir.mkdir() states_dir.mkdir() (metadata_dir / "ses_test.json").write_text(json.dumps({ "triggerWorkflow": "water_quality_complaint", "triggerSource": "peripheral_sample", "projectId": "10000000-0000-4000-8000-000000000001", })) state = snapshot() state_path = states_dir / "ses_test.json" state_path.write_text(json.dumps({"executionPlans": [state]})) def no_network(*args, **kwargs): raise AssertionError("dry run must not open a network client") monkeypatch.setattr("scripts.import_agent_investigation.httpx.AsyncClient", no_network) args = argparse.Namespace(session_id="ses_test", agent_data=tmp_path, dry_run=True) await run(args) assert "2 nodes and 1 synthetic evidence records; no writes" in capsys.readouterr().out state["nodes"][1]["status"] = "invented_status" state_path.write_text(json.dumps({"executionPlans": [state]})) with pytest.raises(ValidationError): await run(args) assert "Ready" not in capsys.readouterr().out