fix: align test mocks with #399 lease gates and head SHA requirements
PR #416 introduced pr_work_lease reviewer blocks and mandatory full 40-hex expected_head_sha on mark/merge paths. Update audit, review, permission-report, terminal hard-stop, inventory, and schema tests to patch lease comment fetches, seed ready review decisions, and use consistent HEAD_SHA constants so the full suite passes again.
This commit is contained in:
+73
-12
@@ -47,6 +47,7 @@ import gitea_config # noqa: E402
|
||||
import mcp_server
|
||||
|
||||
FAKE_AUTH = "Basic dGVzdDp0ZXN0"
|
||||
FULL_HEAD_SHA = "a" * 40
|
||||
|
||||
_NO_BLOCKER_FEEDBACK = {
|
||||
"success": True,
|
||||
@@ -139,6 +140,45 @@ def _install_owned_reviewer_lease(
|
||||
)
|
||||
|
||||
|
||||
def _seed_ready_review_decision(
|
||||
pr_number,
|
||||
action,
|
||||
*,
|
||||
sha=FULL_HEAD_SHA,
|
||||
remote="prgs",
|
||||
org=None,
|
||||
repo=None,
|
||||
):
|
||||
"""Mark the review-decision lock ready without mark_final API calls (#399)."""
|
||||
import mcp_server as _m
|
||||
|
||||
resolved_org, resolved_repo = org, repo
|
||||
if remote in _m.REMOTES:
|
||||
_, resolved_org, resolved_repo = _m._resolve(remote, None, org, repo)
|
||||
profile_name = (_m.get_profile().get("profile_name") or "").strip()
|
||||
session_lock = (
|
||||
(os.environ.get(_m.SESSION_PROFILE_LOCK_ENV) or "").strip()
|
||||
or profile_name
|
||||
)
|
||||
_m._save_review_decision_lock({
|
||||
"task": "review_pr",
|
||||
"remote": remote,
|
||||
"session_pid": os.getpid(),
|
||||
"session_profile": profile_name,
|
||||
"session_profile_lock": session_lock,
|
||||
"final_review_decision_ready": True,
|
||||
"ready_pr_number": pr_number,
|
||||
"ready_action": action,
|
||||
"ready_expected_head_sha": sha,
|
||||
"ready_remote": remote,
|
||||
"ready_org": resolved_org,
|
||||
"ready_repo": resolved_repo,
|
||||
"live_mutations": [],
|
||||
"correction_authorized": False,
|
||||
"correction_reason": None,
|
||||
})
|
||||
|
||||
|
||||
# Issue-write tools are profile-gated (#69).
|
||||
ISSUE_WRITE_ENV = {
|
||||
"GITEA_ALLOWED_OPERATIONS": (
|
||||
@@ -1104,16 +1144,18 @@ class TestReviewPR(unittest.TestCase):
|
||||
"forbidden_operations": [],
|
||||
"base_url": None,
|
||||
}
|
||||
mock_get_all.return_value = [{"number": 1, "title": "PR 1", "state": "open", "head": {"ref": "branch1", "sha": "abc1234"}, "base": {"ref": "master"}, "mergeable": True, "user": {"login": "jcwalker3"}}]
|
||||
head_sha = FULL_HEAD_SHA
|
||||
mock_get_all.return_value = [{"number": 1, "title": "PR 1", "state": "open", "head": {"ref": "branch1", "sha": head_sha}, "base": {"ref": "master"}, "mergeable": True, "user": {"login": "jcwalker3"}}]
|
||||
# mock_api responses: 1) /user (inventory), 2) /user (eligibility), 3) /pulls/1 (eligibility)
|
||||
mock_api.side_effect = [
|
||||
{"login": "jcwalker3"}, # /api/v1/user (inventory)
|
||||
{"login": "jcwalker3"}, # /api/v1/user (submit eligibility)
|
||||
{"user": {"login": "jcwalker3"}, "state": "open", "head": {"sha": "abc1234"}, "mergeable": True}, # /pulls/1
|
||||
{"user": {"login": "jcwalker3"}, "state": "open", "head": {"sha": head_sha}, "mergeable": True}, # /pulls/1
|
||||
]
|
||||
from mcp_server import init_review_decision_lock
|
||||
init_review_decision_lock("prgs", "review_pr")
|
||||
gitea_mark_final_review_decision(1, "approve", remote="prgs", expected_head_sha="abc123")
|
||||
with patch("mcp_server._list_pr_lease_comments", return_value=[]):
|
||||
_seed_ready_review_decision(1, "approve", sha=head_sha, remote="prgs")
|
||||
result = gitea_review_pr(
|
||||
pr_number=1,
|
||||
event="APPROVE",
|
||||
@@ -1769,7 +1811,7 @@ class TestReviewDecisionValidationGate(unittest.TestCase):
|
||||
"""Block incidental live review mutations during validation."""
|
||||
|
||||
PR = 203
|
||||
SHA = "abc123"
|
||||
SHA = FULL_HEAD_SHA
|
||||
|
||||
def _pr(self, author, sha=SHA):
|
||||
return {
|
||||
@@ -1798,7 +1840,13 @@ class TestReviewDecisionValidationGate(unittest.TestCase):
|
||||
"mcp_server._list_pr_lease_comments", return_value=[]
|
||||
)
|
||||
self._pr_lease_comments_patch.start()
|
||||
self._pr_work_lease_patch = patch(
|
||||
"mcp_server._pr_work_lease_reviewer_block",
|
||||
return_value=dict(_NO_PR_WORK_LEASE_BLOCK),
|
||||
)
|
||||
self._pr_work_lease_patch.start()
|
||||
self.addCleanup(self._pr_lease_comments_patch.stop)
|
||||
self.addCleanup(self._pr_work_lease_patch.stop)
|
||||
|
||||
|
||||
def _env(self):
|
||||
@@ -2406,6 +2454,11 @@ class TestTrackerHygieneCleanup(unittest.TestCase):
|
||||
self.mock_audit = patch("gitea_audit.write_event").start()
|
||||
# gitea.pr.close: closing a PR via gitea_edit_pr is capability-gated (#216).
|
||||
patch("mcp_server.get_profile", return_value={"profile_name": "test", "allowed_operations": ["read", "merge", "edit", "close", "gitea.pr.close", "gitea.issue.close"], "audit_label": "test", "forbidden_operations": []}).start()
|
||||
patch("mcp_server._list_pr_lease_comments", return_value=[]).start()
|
||||
patch(
|
||||
"mcp_server._pr_work_lease_reviewer_block",
|
||||
return_value=dict(_NO_PR_WORK_LEASE_BLOCK),
|
||||
).start()
|
||||
|
||||
def tearDown(self):
|
||||
patch.stopall()
|
||||
@@ -2452,7 +2505,8 @@ class TestTrackerHygieneCleanup(unittest.TestCase):
|
||||
def test_merge_pr_with_closes_removes_label(self):
|
||||
import reviewer_pr_lease
|
||||
|
||||
lease_patch = _install_owned_reviewer_lease(1, head_sha="sha123")
|
||||
head_sha = FULL_HEAD_SHA
|
||||
lease_patch = _install_owned_reviewer_lease(1, head_sha=head_sha)
|
||||
lease_patch.start()
|
||||
self.addCleanup(lease_patch.stop)
|
||||
self.addCleanup(reviewer_pr_lease.clear_session_lease)
|
||||
@@ -2461,12 +2515,12 @@ class TestTrackerHygieneCleanup(unittest.TestCase):
|
||||
if method == "GET" and "/user" in url:
|
||||
return {"login": "merger"}
|
||||
if method == "GET" and url.endswith("/reviews"):
|
||||
return [_formal_review("reviewer", "APPROVED", sha="sha123")]
|
||||
return [_formal_review("reviewer", "APPROVED", sha=head_sha)]
|
||||
if method == "GET" and "pulls/1" in url and "/files" not in url:
|
||||
return {
|
||||
"user": {"login": "author"},
|
||||
"state": "open",
|
||||
"head": {"sha": "sha123", "ref": "feat/my-branch"},
|
||||
"head": {"sha": head_sha, "ref": "feat/my-branch"},
|
||||
"base": {"ref": "main"},
|
||||
"mergeable": True,
|
||||
"merged_commit_sha": "merge123",
|
||||
@@ -2486,14 +2540,18 @@ class TestTrackerHygieneCleanup(unittest.TestCase):
|
||||
return {}
|
||||
self.mock_api.side_effect = api_side_effect
|
||||
|
||||
res = gitea_merge_pr(pr_number=1, confirmation="MERGE PR 1", do="merge")
|
||||
res = gitea_merge_pr(
|
||||
pr_number=1, confirmation="MERGE PR 1", do="merge",
|
||||
expected_head_sha=head_sha,
|
||||
)
|
||||
self.assertTrue(res["performed"])
|
||||
self.assertEqual(res["cleanup_status"].get(123), "released")
|
||||
|
||||
def test_merge_pr_with_branch_name_removes_label(self):
|
||||
import reviewer_pr_lease
|
||||
|
||||
lease_patch = _install_owned_reviewer_lease(1, head_sha="sha123")
|
||||
head_sha = FULL_HEAD_SHA
|
||||
lease_patch = _install_owned_reviewer_lease(1, head_sha=head_sha)
|
||||
lease_patch.start()
|
||||
self.addCleanup(lease_patch.stop)
|
||||
self.addCleanup(reviewer_pr_lease.clear_session_lease)
|
||||
@@ -2502,12 +2560,12 @@ class TestTrackerHygieneCleanup(unittest.TestCase):
|
||||
if method == "GET" and "/user" in url:
|
||||
return {"login": "merger"}
|
||||
if method == "GET" and url.endswith("/reviews"):
|
||||
return [_formal_review("reviewer", "APPROVED", sha="sha123")]
|
||||
return [_formal_review("reviewer", "APPROVED", sha=head_sha)]
|
||||
if method == "GET" and "pulls/1" in url and "/files" not in url:
|
||||
return {
|
||||
"user": {"login": "author"},
|
||||
"state": "open",
|
||||
"head": {"sha": "sha123", "ref": "fix/issue-123-slug"},
|
||||
"head": {"sha": head_sha, "ref": "fix/issue-123-slug"},
|
||||
"base": {"ref": "main"},
|
||||
"mergeable": True,
|
||||
"merged_commit_sha": "merge123",
|
||||
@@ -2527,7 +2585,10 @@ class TestTrackerHygieneCleanup(unittest.TestCase):
|
||||
return {}
|
||||
self.mock_api.side_effect = api_side_effect
|
||||
|
||||
res = gitea_merge_pr(pr_number=1, confirmation="MERGE PR 1", do="merge")
|
||||
res = gitea_merge_pr(
|
||||
pr_number=1, confirmation="MERGE PR 1", do="merge",
|
||||
expected_head_sha=head_sha,
|
||||
)
|
||||
self.assertTrue(res["performed"])
|
||||
self.assertEqual(res["cleanup_status"].get(123), "released")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user