cgcardona / muse public
test_annotate_command.py python
110 lines 4.2 KB
8d5137ed fix(security): full surface hardening — validation, path containment, p… Gabriel Cardona <cgcardona@gmail.com> 10h ago
1 """Tests for muse annotate — CRDT-backed commit annotations."""
2
3 import datetime
4 import pathlib
5
6 import pytest
7 from typer.testing import CliRunner
8
9 from muse.cli.app import cli
10 from muse.core.store import CommitRecord, write_commit
11
12 runner = CliRunner()
13
14
15 # ---------------------------------------------------------------------------
16 # Fixtures
17 # ---------------------------------------------------------------------------
18
19
20 @pytest.fixture
21 def repo(tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch) -> pathlib.Path:
22 """Set up a minimal Muse repo and chdir into it."""
23 monkeypatch.chdir(tmp_path)
24 muse = tmp_path / ".muse"
25 muse.mkdir()
26 (muse / "repo.json").write_text('{"repo_id":"test-repo"}')
27 (muse / "HEAD").write_text("refs/heads/main")
28 (muse / "commits").mkdir()
29 (muse / "snapshots").mkdir()
30 (muse / "refs" / "heads").mkdir(parents=True)
31 return tmp_path
32
33
34 def _write_commit(root: pathlib.Path, commit_id: str = "a" * 64) -> CommitRecord:
35 record = CommitRecord(
36 commit_id=commit_id,
37 repo_id="test-repo",
38 branch="main",
39 snapshot_id="s" * 64,
40 message="test commit",
41 committed_at=datetime.datetime.now(datetime.timezone.utc),
42 author="test-author",
43 )
44 write_commit(root, record)
45 (root / ".muse" / "refs" / "heads" / "main").write_text(commit_id)
46 return record
47
48
49 # ---------------------------------------------------------------------------
50 # Tests
51 # ---------------------------------------------------------------------------
52
53
54 class TestAnnotateCommand:
55 def test_show_annotations_when_no_flags(self, repo: pathlib.Path) -> None:
56 _write_commit(repo, "a" * 64)
57 result = runner.invoke(cli, ["annotate", "a" * 64], catch_exceptions=False)
58 assert result.exit_code == 0
59 assert "reviewed-by" in result.output
60
61 def test_add_reviewer(self, repo: pathlib.Path) -> None:
62 _write_commit(repo, "a" * 64)
63 result = runner.invoke(cli, ["annotate", "--reviewed-by", "agent-x", "a" * 64], catch_exceptions=False)
64 assert result.exit_code == 0, result.output
65 assert "agent-x" in result.output
66
67 # Verify it's persisted.
68 from muse.core.store import read_commit
69 record = read_commit(repo, "a" * 64)
70 assert record is not None
71 assert "agent-x" in record.reviewed_by
72
73 def test_add_multiple_reviewers(self, repo: pathlib.Path) -> None:
74 _write_commit(repo, "a" * 64)
75 # Pass comma-separated reviewers in one call.
76 r = runner.invoke(cli, ["annotate", "--reviewed-by", "alice,bob", "a" * 64], catch_exceptions=False)
77 assert r.exit_code == 0, r.output
78
79 from muse.core.store import read_commit
80 record = read_commit(repo, "a" * 64)
81 assert record is not None
82 # ORSet semantics: both reviewers should be present.
83 assert "alice" in record.reviewed_by
84 assert "bob" in record.reviewed_by
85
86 def test_add_reviewer_idempotent(self, repo: pathlib.Path) -> None:
87 _write_commit(repo, "a" * 64)
88 runner.invoke(cli, ["annotate", "--reviewed-by", "alice", "a" * 64], catch_exceptions=False)
89 runner.invoke(cli, ["annotate", "--reviewed-by", "alice", "a" * 64], catch_exceptions=False)
90
91 from muse.core.store import read_commit
92 record = read_commit(repo, "a" * 64)
93 assert record is not None
94 # ORSet: adding the same element twice should appear once.
95 assert record.reviewed_by.count("alice") == 1
96
97 def test_increment_test_run_counter(self, repo: pathlib.Path) -> None:
98 _write_commit(repo, "a" * 64)
99 runner.invoke(cli, ["annotate", "--test-run", "a" * 64], catch_exceptions=False)
100 runner.invoke(cli, ["annotate", "--test-run", "a" * 64], catch_exceptions=False)
101
102 from muse.core.store import read_commit
103 record = read_commit(repo, "a" * 64)
104 assert record is not None
105 assert record.test_runs == 2 # GCounter: monotone increment
106
107 def test_unknown_commit_exits_error(self, repo: pathlib.Path) -> None:
108 (repo / ".muse" / "refs" / "heads" / "main").write_text("nosuchcommit")
109 result = runner.invoke(cli, ["annotate", "nosuchcommit"])
110 assert result.exit_code != 0