test_git_only.py python
82 lines 2.9 KB
Raw
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
1 """Unit tests for git-only adapter fail-closed branches."""
2
3 from __future__ import annotations
4
5 from adapters.errors import ReadError, WriteError
6 from tests.support import adapter_for, fail, make_runner, ok
7
8
9 def test_status_success(git_only_config, repo_root) -> None:
10 runner = make_runner(
11 {
12 "git rev-parse": ok("feat/test"),
13 "git status": ok(""),
14 }
15 )
16 adapter = adapter_for(git_only_config, repo_root, runner)
17 result = adapter.status()
18 assert result.regime == "git-only"
19 assert result.branch == "feat/test"
20 assert result.dirty is False
21
22
23 def test_status_fails_closed_on_git_error(git_only_config, repo_root) -> None:
24 runner = make_runner({"git rev-parse": fail("fatal: not a git repo")})
25 adapter = adapter_for(git_only_config, repo_root, runner)
26 result = adapter.status()
27 assert isinstance(result, ReadError)
28 assert "git rev-parse" in result.command
29
30
31 def test_read_head_missing_ref(git_only_config, repo_root) -> None:
32 runner = make_runner({"git rev-parse": fail("bad ref", 128)})
33 adapter = adapter_for(git_only_config, repo_root, runner)
34 result = adapter.read_head("origin/main")
35 assert isinstance(result, ReadError)
36
37
38 def test_read_head_rejects_muse_ref(git_only_config, repo_root) -> None:
39 adapter = adapter_for(git_only_config, repo_root, make_runner({}))
40 result = adapter.read_head("muse:main")
41 assert isinstance(result, ReadError)
42 assert "forbidden" in result.message
43
44
45 def test_read_canonical_anchor(git_only_config, repo_root) -> None:
46 runner = make_runner({"git rev-parse": ok("abc123def456")})
47 adapter = adapter_for(git_only_config, repo_root, runner)
48 result = adapter.read_canonical_anchor()
49 assert result.anchor_sha == "abc123def456"
50 assert result.source == "origin/main"
51
52
53 def test_realign_noop(git_only_config, repo_root) -> None:
54 adapter = adapter_for(git_only_config, repo_root, make_runner({}))
55 result = adapter.realign(dry_run=True, max_commits=50)
56 assert result.applied is False
57 assert result.reason == "single-history"
58
59
60 def test_commit_feature_refuses_main(git_only_config, repo_root) -> None:
61 adapter = adapter_for(git_only_config, repo_root, make_runner({}))
62 result = adapter.commit_feature(branch="main", message="x", paths=["docs/a.md"])
63 assert isinstance(result, WriteError)
64 assert "protected" in result.message
65
66
67 def test_commit_feature_unsafe_path(git_only_config, repo_root) -> None:
68 adapter = adapter_for(git_only_config, repo_root, make_runner({}))
69 result = adapter.commit_feature(
70 branch="feat/x",
71 message="x",
72 paths=["../escape"],
73 )
74 assert isinstance(result, ReadError)
75 assert "unsafe path" in result.message
76
77
78 def test_mirror_noop(git_only_config, repo_root) -> None:
79 adapter = adapter_for(git_only_config, repo_root, make_runner({}))
80 result = adapter.mirror(dry_run=True)
81 assert result.pushed is False
82 assert result.reason == "single-history"
File History 2 commits
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1 docs: MuseHub-first before ISR #74 — staging solidify NEXT Human 1 day ago
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 53 days ago