test_print_next_e2e.py
python
sha256:c07f2f34a0db9f43fe866f157d1935322008545ff8940c06c7c921eb219c55ab
NXP-b DONE: independent BV-r2 pass + ISR (SD-17)
Human
minor
⚠ breaking
17 hours ago
| 1 | """E2E — write new fence then ``ok next`` prints the new body (§ONS.12 / §NXP.8).""" |
| 2 | |
| 3 | from __future__ import annotations |
| 4 | |
| 5 | from pathlib import Path |
| 6 | |
| 7 | from cli.kit_root import kit_root |
| 8 | from tests.support import ( |
| 9 | FIXTURES, |
| 10 | git_status_runner, |
| 11 | run_cli, |
| 12 | seed_git_repo, |
| 13 | seed_governance_freshness, |
| 14 | write_config, |
| 15 | ) |
| 16 | from tools.print_next.extract import CURRENT_NEXT_HEADING, set_read_at_clock |
| 17 | from tools.workspace.board_names import expected_handover_basename |
| 18 | |
| 19 | NEW_BODY = """You are Auto — NEW FENCE BODY TOKEN abc123. |
| 20 | |
| 21 | Model: Auto |
| 22 | """ |
| 23 | |
| 24 | FIXED_READ_AT = "2026-09-04T12:00:00Z" |
| 25 | |
| 26 | |
| 27 | def test_e2e_new_fence_then_idempotent(tmp_path: Path, capsys) -> None: |
| 28 | write_config(tmp_path, "config-git-only.yaml") |
| 29 | seed_git_repo(tmp_path) |
| 30 | docs = tmp_path / "docs" |
| 31 | docs.mkdir(parents=True, exist_ok=True) |
| 32 | handover = docs / "OVERSEER-HANDOVER.md" |
| 33 | handover.write_text( |
| 34 | (FIXTURES / "print-next-handover.md").read_text(encoding="utf-8"), |
| 35 | encoding="utf-8", |
| 36 | ) |
| 37 | (docs / "ROADMAP.md").write_text("# Roadmap\n", encoding="utf-8") |
| 38 | |
| 39 | set_read_at_clock(lambda: FIXED_READ_AT) |
| 40 | try: |
| 41 | runner = git_status_runner(branch="feat/ons-operator-next-surfacing") |
| 42 | code1 = run_cli(["next"], cwd=tmp_path, runner=runner, kit=kit_root()) |
| 43 | out1 = capsys.readouterr().out |
| 44 | assert code1 == 0 |
| 45 | assert "ONS fixture" in out1 |
| 46 | assert "NEW FENCE BODY TOKEN" not in out1 |
| 47 | assert "**Source:**" in out1 |
| 48 | |
| 49 | handover.write_text( |
| 50 | "# Handover\n\n### Paste-ready prompt — new\n\n```text\n" |
| 51 | + NEW_BODY |
| 52 | + "```\n", |
| 53 | encoding="utf-8", |
| 54 | ) |
| 55 | |
| 56 | code2 = run_cli(["next"], cwd=tmp_path, runner=runner, kit=kit_root()) |
| 57 | out2 = capsys.readouterr().out |
| 58 | assert code2 == 0 |
| 59 | assert CURRENT_NEXT_HEADING in out2 |
| 60 | assert "NEW FENCE BODY TOKEN abc123" in out2 |
| 61 | assert "ONS fixture" not in out2 |
| 62 | |
| 63 | code3 = run_cli(["next"], cwd=tmp_path, runner=runner, kit=kit_root()) |
| 64 | out3 = capsys.readouterr().out |
| 65 | assert code3 == 0 |
| 66 | assert out3 == out2 |
| 67 | |
| 68 | # main tip fixture path unused; ensure we never checked out main via runner. |
| 69 | assert all("checkout" not in cmd for cmd, _ in runner.calls) |
| 70 | finally: |
| 71 | set_read_at_clock(None) |
| 72 | |
| 73 | |
| 74 | def test_e2e_two_repos_attributable(tmp_path: Path, capsys) -> None: |
| 75 | """§NXP.8 e2e: two fixture repos in one stream — each block attributable.""" |
| 76 | repo_a = tmp_path / "repo-alpha" |
| 77 | repo_b = tmp_path / "repo-beta" |
| 78 | for repo, name in ((repo_a, "alpha"), (repo_b, "beta")): |
| 79 | write_config(repo, "config-git-only.yaml") |
| 80 | cfg = (repo / ".overseer" / "config.yaml").read_text(encoding="utf-8") |
| 81 | (repo / ".overseer" / "config.yaml").write_text( |
| 82 | cfg.replace("name: test-git", f"name: {name}"), |
| 83 | encoding="utf-8", |
| 84 | ) |
| 85 | docs = repo / "docs" |
| 86 | docs.mkdir(parents=True, exist_ok=True) |
| 87 | (docs / "OVERSEER-HANDOVER.md").write_text( |
| 88 | f"# H\n\n### Paste-ready prompt\n\n```text\n" |
| 89 | f"Body for {name}\nModel: Auto\n```\n", |
| 90 | encoding="utf-8", |
| 91 | ) |
| 92 | (docs / "ROADMAP.md").write_text("# R\n", encoding="utf-8") |
| 93 | |
| 94 | set_read_at_clock(lambda: FIXED_READ_AT) |
| 95 | try: |
| 96 | code_a = run_cli(["next"], cwd=repo_a, runner=git_status_runner(), kit=kit_root()) |
| 97 | out_a = capsys.readouterr().out |
| 98 | code_b = run_cli(["next"], cwd=repo_b, runner=git_status_runner(), kit=kit_root()) |
| 99 | out_b = capsys.readouterr().out |
| 100 | assert code_a == 0 and code_b == 0 |
| 101 | stream = out_a + out_b |
| 102 | assert f"`{repo_a.resolve().as_posix()}`" in stream |
| 103 | assert f"`{repo_b.resolve().as_posix()}`" in stream |
| 104 | assert "`alpha`" in out_a and "`beta`" in out_b |
| 105 | assert "Body for alpha" in out_a |
| 106 | assert "Body for beta" in out_b |
| 107 | finally: |
| 108 | set_read_at_clock(None) |
| 109 | |
| 110 | |
| 111 | def test_e2e_status_exit_code_unchanged_by_advisory(tmp_path: Path, capsys) -> None: |
| 112 | """§NXP.8 e2e: the N4 advisory must not change ``--exit-code`` (§NXP.6). |
| 113 | |
| 114 | A fully initialized repo with bare board names exits ``0`` on every |
| 115 | pre-existing condition, so the advisory is the only thing in play. Asserting |
| 116 | the advisory fires *and* the exit stays ``0`` pins §NXP.6 directly: were the |
| 117 | advisory folded into the exit-code tiers, this could not remain ``0``. |
| 118 | """ |
| 119 | assert ( |
| 120 | run_cli( |
| 121 | ["init", "--from-config", str(FIXTURES / "config-git-only.yaml"), "--non-interactive"], |
| 122 | cwd=tmp_path, |
| 123 | runner=git_status_runner(), |
| 124 | ) |
| 125 | == 0 |
| 126 | ) |
| 127 | seed_governance_freshness(tmp_path) |
| 128 | capsys.readouterr() |
| 129 | |
| 130 | code = run_cli( |
| 131 | ["status", "--exit-code"], |
| 132 | cwd=tmp_path, |
| 133 | runner=git_status_runner(), |
| 134 | kit=kit_root(), |
| 135 | ) |
| 136 | out = capsys.readouterr().out |
| 137 | |
| 138 | # The N4 advisory is genuinely firing on this fixture (bare `OVERSEER-*` names)... |
| 139 | assert "board naming:" in out |
| 140 | assert expected_handover_basename("test-git") in out |
| 141 | # ...and contributes nothing to the exit code (§NXP.6 warn, never a gate). |
| 142 | assert code == 0 |
File History
1 commit
sha256:c07f2f34a0db9f43fe866f157d1935322008545ff8940c06c7c921eb219c55ab
NXP-b DONE: independent BV-r2 pass + ISR (SD-17)
Human
minor
⚠
17 hours ago