"""End-to-end test for ``scripts/demo_walkthrough.py``. The walkthrough is the canonical scripted demo of the milestone: 1. seed a node with the sample dataset, 2. ask "what do you know about me and why?" (browse claims + explanations), 3. drill into provenance down to raw evidence, 4. correct/refute a claim, 5. show the cascade of downstream invalidations, 6. export and audit the resulting graph. This test runs the script exactly as a user would — as a subprocess against a throwaway node directory selected via ``FABLEPOOL_NODE_DIR`` — and then verifies that the node it leaves behind is real and auditable. """ from __future__ import annotations import json import os import subprocess import sys from pathlib import Path import pytest REPO_ROOT = Path(__file__).resolve().parents[1] SCRIPT = REPO_ROOT / "scripts" / "demo_walkthrough.py" SUBPROCESS_TIMEOUT = 300 @pytest.fixture() def walkthrough_run(tmp_path: Path) -> tuple[Path, subprocess.CompletedProcess]: """Run the walkthrough once against a fresh node dir; share the result.""" env = dict(os.environ) env["FABLEPOOL_NODE_DIR"] = str(tmp_path) proc = subprocess.run( [sys.executable, str(SCRIPT)], capture_output=True, text=True, cwd=str(REPO_ROOT), env=env, timeout=SUBPROCESS_TIMEOUT, ) return tmp_path, proc def test_walkthrough_script_exists() -> None: assert SCRIPT.exists(), "scripts/demo_walkthrough.py is part of the milestone deliverable" def test_walkthrough_runs_to_completion(walkthrough_run) -> None: node_dir, proc = walkthrough_run assert proc.returncode == 0, ( f"demo walkthrough exited with {proc.returncode}\n" f"--- stdout ---\n{proc.stdout}\n--- stderr ---\n{proc.stderr}" ) assert proc.stdout.strip(), "walkthrough must narrate what it is doing on stdout" def test_walkthrough_covers_the_canonical_flow(walkthrough_run) -> None: _, proc = walkthrough_run out = proc.stdout.lower() # The canonical question. assert "what do you know about me" in out, ( "walkthrough must pose the canonical question " "'what do you know about me and why?'" ) # Provenance / explanation step. assert any(word in out for word in ("evidence", "provenance", "derived")), ( "walkthrough must drill into provenance/evidence" ) # Correction or refutation step. assert any(word in out for word in ("refut", "correct")), ( "walkthrough must correct or refute a claim" ) # Cascade step. assert any(word in out for word in ("cascade", "invalidated", "downstream")), ( "walkthrough must demonstrate downstream cascade of the correction" ) def test_walkthrough_populates_the_node_directory(walkthrough_run) -> None: node_dir, proc = walkthrough_run assert proc.returncode == 0 assert any(node_dir.iterdir()), ( "walkthrough must operate on the node directory given via FABLEPOOL_NODE_DIR" ) def test_walkthrough_leaves_an_auditable_node(walkthrough_run) -> None: """After the walkthrough — including its mutations — the operation log it produced must still fully verify, via the same CLI a user would run.""" node_dir, proc = walkthrough_run assert proc.returncode == 0 env = dict(os.environ) env.pop("FABLEPOOL_NODE_DIR", None) audit = subprocess.run( [sys.executable, "-m", "fablepool", "--node-dir", str(node_dir), "audit", "--json"], capture_output=True, text=True, cwd=str(REPO_ROOT), env=env, timeout=SUBPROCESS_TIMEOUT, ) assert audit.returncode == 0, ( f"audit of the walkthrough node failed\n" f"--- stdout ---\n{audit.stdout}\n--- stderr ---\n{audit.stderr}" ) doc = json.loads(audit.stdout) assert doc.get("ok") is True assert doc.get("verified") == doc.get("ops") and doc.get("ops", 0) > 0