test_q1_app_integration.py python
133 lines 4.6 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
1 """Integration tests for Track Q / Q1 overseer app (§Q0.12)."""
2
3 from __future__ import annotations
4
5 from pathlib import Path
6
7 import pytest
8
9 from cli.kit_root import kit_root
10 from tests.fixtures.app import seed_app_repo, start_test_app
11 from tests.support import FIXTURES, git_status_runner, make_runner, ok, pass_provider_factory, run_cli, seed_freeze_repo
12
13
14 def _governance_runner(tmp_path: Path):
15 return make_runner(
16 {
17 "git rev-parse --abbrev-ref HEAD": ok("main"),
18 "git status --porcelain": ok(""),
19 "git rev-parse origin/main": ok("cafebabe"),
20 "gh pr list --state merged --limit 5 --json number,title,mergeCommit,mergedAt": ok("[]"),
21 "git remote get-url origin": ok("[email protected]:owner/repo.git"),
22 "git merge-base --is-ancestor": ok(""),
23 }
24 )
25
26
27 def test_static_ui_served(tmp_path: Path) -> None:
28 seed_app_repo(tmp_path)
29 handle, client = start_test_app(tmp_path)
30 try:
31 status, _payload = client.get("/api/health")
32 assert status == 200
33 request = __import__("urllib.request").request.Request(
34 f"{client.base_url}/",
35 headers={"Authorization": f"Bearer {client.session}"},
36 )
37 with __import__("urllib.request").request.urlopen(request, timeout=5) as response:
38 html = response.read().decode("utf-8")
39 assert "Overseer Kit" in html
40 assert "/assets/app.js" in html
41 finally:
42 handle.shutdown()
43
44
45 def test_status_exit_code_matches_cli(tmp_path: Path) -> None:
46 seed_app_repo(tmp_path)
47 handle, client = start_test_app(tmp_path, runner=git_status_runner())
48 try:
49 cli_code = run_cli(
50 ["status", "--json", "--exit-code"],
51 cwd=tmp_path,
52 runner=git_status_runner(),
53 kit=kit_root(),
54 json_mode=True,
55 )
56 _status, payload = client.get("/api/status")
57 assert payload["exit_code"] == cli_code
58 assert payload["result"]["initialized"] is True
59 finally:
60 handle.shutdown()
61
62
63 def test_docs_endpoints_return_text(tmp_path: Path) -> None:
64 seed_app_repo(tmp_path)
65 handle, client = start_test_app(tmp_path)
66 try:
67 _status, roadmap = client.get("/api/docs/roadmap")
68 assert roadmap["ok"] is True
69 assert roadmap["result"]["path"].endswith("ROADMAP.md")
70 assert "Roadmap fixture" in roadmap["result"]["text"]
71 assert len(roadmap["result"]["sha256"]) == 64
72
73 _status, handover = client.get("/api/docs/handover")
74 assert handover["ok"] is True
75 assert "Handover fixture" in handover["result"]["text"]
76 finally:
77 handle.shutdown()
78
79
80 def test_gates_slice_matches_status(tmp_path: Path) -> None:
81 seed_app_repo(tmp_path)
82 handle, client = start_test_app(tmp_path)
83 try:
84 _s1, status = client.get("/api/status")
85 _s2, gates = client.get("/api/gates")
86 assert gates["result"] == status["result"]["governance_gates"]
87 finally:
88 handle.shutdown()
89
90
91 def test_review_freeze_dry_run(tmp_path: Path) -> None:
92 artifact = seed_freeze_repo(tmp_path)
93 rel = artifact.relative_to(tmp_path).as_posix()
94 handle, client = start_test_app(tmp_path, review_provider_factory=pass_provider_factory())
95 try:
96 _status, payload = client.post("/api/review/freeze", {"path": rel, "dry_run": True})
97 assert payload["exit_code"] == 0
98 assert payload["result"]["verdict"] == "pass"
99 finally:
100 handle.shutdown()
101
102
103 def test_governance_sync_dry_run(tmp_path: Path) -> None:
104 seed_app_repo(tmp_path)
105 docs = tmp_path / "docs"
106 (docs / "OVERSEER-HANDOVER.md").write_text(
107 (FIXTURES / "governance-handover-drift.md").read_text(encoding="utf-8"),
108 encoding="utf-8",
109 )
110 (docs / "ROADMAP.md").write_text(
111 (FIXTURES / "governance-roadmap-drift.md").read_text(encoding="utf-8"),
112 encoding="utf-8",
113 )
114 handle, client = start_test_app(tmp_path, runner=_governance_runner(tmp_path))
115 try:
116 before = (docs / "ROADMAP.md").read_text(encoding="utf-8")
117 _status, payload = client.post("/api/governance-sync", {"write": False})
118 assert payload["exit_code"] == 0
119 assert payload["result"]["dry_run"] is True
120 assert (docs / "ROADMAP.md").read_text(encoding="utf-8") == before
121 finally:
122 handle.shutdown()
123
124
125 def test_bind_refused_exit_two(tmp_path: Path) -> None:
126 seed_app_repo(tmp_path)
127 code = run_cli(["app", "--bind", "0.0.0.0", "--repo", str(tmp_path)], cwd=tmp_path)
128 assert code == 2
129
130
131 def test_uninitialized_repo_exit_two(tmp_path: Path) -> None:
132 code = run_cli(["app", "--repo", str(tmp_path)], cwd=tmp_path)
133 assert code == 2
File History 1 commit
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago