| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- from fastapi.testclient import TestClient
- from app.contracts import SCHEMA_CATALOG
- from app.fake_data import (
- ARTIFACT_DIGESTS,
- GRAPH,
- RUN_ID,
- canonical_digest,
- canonical_wire_digest,
- )
- from app.main import app
- client = TestClient(app)
- def test_health_declares_fake_mode() -> None:
- response = client.get("/api/health")
- assert response.status_code == 200
- assert response.json()["data_mode"] == "fake"
- def test_graph_is_fine_grained_and_connected() -> None:
- response = client.get(f"/api/runs/{RUN_ID}/graph")
- assert response.status_code == 200
- body = response.json()
- assert body["data_mode"] == "fake"
- assert len(body["nodes"]) >= 55
- assert len(body["edges"]) >= 50
- assert {item["phase"] for item in body["nodes"]} == {
- "phase-1",
- "phase-2",
- "phase-3",
- "delivery",
- }
- assert {item["node_type"] for item in body["nodes"]} >= {
- "contract",
- "operation",
- "attempt",
- "artifact",
- "validation",
- "decision",
- "publication",
- "transaction",
- "readback",
- }
- def test_every_fake_record_uses_exact_contract_fields() -> None:
- used_models: set[str] = set()
- for node in GRAPH.nodes:
- model = node.record.model_name
- used_models.add(model)
- assert set(node.record.payload) == set(SCHEMA_CATALOG[model]), node.id
- required = {
- "ScriptBuildRecord",
- "ScriptBuildInputSnapshotV1",
- "MissionBinding",
- "MissionOwnerToken",
- "ScriptTaskContractV1",
- "OperationView",
- "AttemptView",
- "ValidationView",
- "PlannerDecisionView",
- "EvidenceRecordV1",
- "ScriptDirectionArtifactV1",
- "StructureArtifactV1",
- "ParagraphArtifactV1",
- "ElementSetArtifactV1",
- "ComparisonArtifactV1",
- "StructuredScriptArtifactV1",
- "CandidatePortfolioArtifactV1",
- "RootDeliveryManifestV1",
- "LegacyProjectionCanonicalV1",
- "Publication",
- "PublicationResult",
- "HttpCommandRecord",
- "InputSnapshotRow",
- "ArtifactVersionRow",
- "ParagraphRow",
- "ElementRow",
- "ParagraphElementLinkRow",
- }
- assert required <= used_models
- def test_manifest_and_legacy_projection_use_real_logical_closure() -> None:
- records = {node.record.model_name: node.record.payload for node in GRAPH.nodes}
- canonical = records["LegacyProjectionCanonicalV1"]
- manifest = records["RootDeliveryManifestV1"]
- assert manifest["legacy_projection_digest"] == canonical_wire_digest(canonical)
- assert manifest["input_closure_digest"] != manifest["legacy_projection_digest"]
- for paragraph in canonical["paragraphs"]:
- assert "logical_key" in paragraph
- assert "parent_logical_key" in paragraph
- assert not {"paragraph_id", "parent_id", "is_active"} & set(paragraph)
- for element in canonical["elements"]:
- assert "logical_key" in element
- assert not {"element_id", "is_active"} & set(element)
- for link in canonical["paragraph_element_links"]:
- assert set(link) == {"paragraph_logical_key", "element_logical_key"}
- def test_artifact_refs_pin_specific_kind_and_canonical_digest() -> None:
- attempts = [
- node.record.payload
- for node in GRAPH.nodes
- if node.record.model_name == "AttemptView"
- ]
- for attempt in attempts:
- for ref in attempt["submission"]["artifact_refs"]:
- version = int(ref["version"])
- assert ref["kind"] != "business-artifact"
- assert ref["digest"] == ARTIFACT_DIGESTS[version]
- node_ids = {node.id for node in GRAPH.nodes}
- assert "compose:alternate:artifact" in node_ids
- assert "compose:alternate:decision" in node_ids
- def test_root_task_has_no_self_parent_and_declares_children() -> None:
- root = next(
- node.record.payload
- for node in GRAPH.nodes
- if node.record.model_name == "TaskView"
- and node.record.payload["task_id"] == "task-root"
- )
- assert root["parent_task_id"] is None
- assert root["child_task_ids"] == ["direction", "portfolio"]
- contract = next(
- node.record.payload
- for node in GRAPH.nodes
- if node.id == "root-delivery:contract"
- )
- assert contract["scope_ref"] == "script-build://scope/root"
- assert contract["write_scope"] == []
- assert [item["expected_task_kind"] for item in contract["input_decision_refs"]] == [
- "direction",
- "candidate-portfolio",
- ]
- attempt = next(
- node.record.payload
- for node in GRAPH.nodes
- if node.id == "root-delivery:attempt"
- )
- assert attempt["accepted_child_decision_ids"] == [
- "decision-direction",
- "decision-portfolio",
- ]
- def test_input_snapshot_row_and_logical_view_share_one_canonical_payload() -> None:
- row = next(
- node.record.payload
- for node in GRAPH.nodes
- if node.record.model_name == "InputSnapshotRow"
- )
- logical = next(
- node.record.payload
- for node in GRAPH.nodes
- if node.record.model_name == "ScriptBuildInputSnapshotV1"
- )
- assert logical["snapshot_id"] == str(row["id"]) == "301"
- assert row["canonical_sha256"] == canonical_digest(row["canonical_json"])
- assert logical["canonical_sha256"] == f"sha256:{row['canonical_sha256']}"
- for key in (
- "script_build_id",
- "execution_id",
- "topic_build_id",
- "topic_id",
- "topic",
- "account",
- "persona_points",
- "section_patterns",
- "strategies",
- "prompt_manifest",
- "datasource_manifest",
- "model_manifest",
- ):
- assert logical[key] == row["canonical_json"][key]
- def test_final_physical_row_counts_match_canonical_counts() -> None:
- canonical = next(
- node.record.payload
- for node in GRAPH.nodes
- if node.record.model_name == "LegacyProjectionCanonicalV1"
- )
- counts = {
- model: sum(1 for node in GRAPH.nodes if node.record.model_name == model)
- for model in ("ParagraphRow", "ElementRow", "ParagraphElementLinkRow")
- }
- assert counts == {
- "ParagraphRow": canonical["paragraph_count"],
- "ElementRow": canonical["element_count"],
- "ParagraphElementLinkRow": canonical["link_count"],
- }
- def test_node_detail_and_not_found() -> None:
- node_id = GRAPH.nodes[10].id
- response = client.get(f"/api/runs/{RUN_ID}/nodes/{node_id}")
- assert response.status_code == 200
- assert response.json()["node"]["id"] == node_id
- assert client.get(f"/api/runs/999/nodes/{node_id}").status_code == 404
- assert client.get(f"/api/runs/{RUN_ID}/nodes/missing").status_code == 404
|