151 lines
6.0 KiB
Python
151 lines
6.0 KiB
Python
import unittest
|
|
|
|
from tests.fakes import BOT, HEAD, pr_ref
|
|
from tests.test_hints_hold_merge import hint_run
|
|
from tests.test_line_comments import app_gitea
|
|
from werkrevisor import cli, report
|
|
from werkrevisor.config import GateConfig
|
|
|
|
GATE = GateConfig(human_reviewers=("alice",), automerge=True)
|
|
|
|
|
|
def resolve_all(gitea):
|
|
for comments in gitea.line_comments.values():
|
|
for c in comments:
|
|
c["resolver"] = {"login": "claude-code"}
|
|
|
|
|
|
def release(gitea):
|
|
return cli.release_held_merge(GATE, pr_ref(), gitea, BOT)
|
|
|
|
|
|
class ReleaseHeldMergeTest(unittest.TestCase):
|
|
def test_the_last_resolved_line_comment_releases_the_merge(self):
|
|
"""Scenario#135.01"""
|
|
gitea = app_gitea()
|
|
gitea.requested = ["alice"]
|
|
hint_run(gitea)
|
|
self.assertIn(report.HELD_MARKER, gitea.comments[0]["body"])
|
|
resolve_all(gitea)
|
|
note = release(gitea)
|
|
self.assertEqual(len(gitea.scheduled_merges), 1)
|
|
self.assertEqual(gitea.withdrawn, ["alice"])
|
|
self.assertEqual(note, "merge scheduled for when the checks succeed; review request of alice withdrawn")
|
|
self.assertIn(cli.release_marker(HEAD), gitea.created_comments[-1])
|
|
self.assertIn(f"every line comment for `{HEAD}` is resolved", gitea.created_comments[-1])
|
|
|
|
def test_a_release_happens_once_per_head(self):
|
|
gitea = app_gitea()
|
|
hint_run(gitea)
|
|
resolve_all(gitea)
|
|
release(gitea)
|
|
comments = len(gitea.created_comments)
|
|
self.assertEqual(release(gitea), "")
|
|
self.assertEqual((len(gitea.scheduled_merges), len(gitea.created_comments)), (1, comments))
|
|
|
|
def test_an_open_line_comment_still_holds_the_merge(self):
|
|
"""Scenario#135.02"""
|
|
gitea = app_gitea()
|
|
gitea.requested = ["alice"]
|
|
hint_run(gitea)
|
|
self.assertEqual(release(gitea), "")
|
|
self.assertEqual((gitea.scheduled_merges, gitea.withdrawn), ([], []))
|
|
|
|
def test_no_release_without_the_approval_of_werkrevisor_for_the_head(self):
|
|
"""Scenario#135.03"""
|
|
gitea = app_gitea()
|
|
hint_run(gitea)
|
|
resolve_all(gitea)
|
|
gitea.reviews = [{**r, "dismissed": True} for r in gitea.reviews]
|
|
self.assertEqual(release(gitea), "")
|
|
self.assertEqual(gitea.scheduled_merges, [])
|
|
|
|
def test_a_hint_only_in_the_result_comment_is_not_released(self):
|
|
"""Scenario#135.03"""
|
|
gitea = app_gitea()
|
|
hint_run(gitea, start=0)
|
|
self.assertNotIn(report.HELD_MARKER, gitea.comments[0]["body"])
|
|
self.assertEqual(release(gitea), "")
|
|
self.assertEqual(gitea.scheduled_merges, [])
|
|
|
|
def test_a_merge_that_was_never_held_is_not_scheduled(self):
|
|
gitea = app_gitea()
|
|
hint_run(gitea, automerge=False)
|
|
resolve_all(gitea)
|
|
self.assertEqual(release(gitea), "")
|
|
self.assertEqual(gitea.scheduled_merges, [])
|
|
|
|
def test_a_new_head_waits_for_its_own_review(self):
|
|
gitea = app_gitea()
|
|
hint_run(gitea)
|
|
resolve_all(gitea)
|
|
gitea.heads = ["e" * 40]
|
|
self.assertEqual(release(gitea), "")
|
|
self.assertEqual(gitea.scheduled_merges, [])
|
|
|
|
def test_a_restart_with_open_line_comments_marks_its_comment_as_held(self):
|
|
gitea = app_gitea()
|
|
hint_run(gitea, start=0)
|
|
# The restart releases the hint in the result comment; a line comment of an earlier head still holds.
|
|
gitea.reviews.append({"id": 7, "state": "COMMENT", "commit_id": "c" * 40, "user": {"login": BOT}})
|
|
gitea.line_comments[7] = [{"id": 77, "user": {"login": BOT}, "path": "app.py", "position": 2,
|
|
"resolver": None, "body": "**[low] Naming** (werkrevisor)", "html_url": "x"}]
|
|
hint_run(gitea, start=0)
|
|
self.assertIn(report.HELD_MARKER, gitea.created_comments[-1])
|
|
resolve_all(gitea)
|
|
self.assertIn("merge scheduled", release(gitea))
|
|
|
|
def test_a_failed_scheduling_is_tried_again_by_the_next_run(self):
|
|
gitea = app_gitea()
|
|
hint_run(gitea)
|
|
resolve_all(gitea)
|
|
gitea.schedule_merge_refusals = [500]
|
|
comments = len(gitea.created_comments)
|
|
self.assertIn("merge not scheduled", release(gitea))
|
|
self.assertEqual(len(gitea.created_comments), comments)
|
|
self.assertIn("merge scheduled", release(gitea))
|
|
|
|
def test_a_failed_withdrawal_is_tried_again_by_the_next_run(self):
|
|
gitea = app_gitea()
|
|
gitea.requested = ["alice"]
|
|
hint_run(gitea)
|
|
resolve_all(gitea)
|
|
gitea.fail_review_request = True
|
|
comments = len(gitea.created_comments)
|
|
self.assertIn("review request of alice not withdrawn", release(gitea))
|
|
self.assertEqual(len(gitea.created_comments), comments)
|
|
gitea.fail_review_request = False
|
|
self.assertEqual(release(gitea), "merge already scheduled; review request of alice withdrawn")
|
|
self.assertIn(cli.release_marker(HEAD), gitea.created_comments[-1])
|
|
|
|
def test_a_failed_cancel_leaves_the_release_to_a_new_review(self):
|
|
from werkrevisor.gitea import GiteaError
|
|
gitea = app_gitea()
|
|
|
|
def refuse(number):
|
|
raise GiteaError("DELETE merge failed with HTTP 403", 403)
|
|
gitea.cancel_scheduled_merge = refuse
|
|
outcome, gitea = hint_run(gitea)
|
|
self.assertEqual(outcome.result.exit_code, 10)
|
|
self.assertNotIn(report.HELD_MARKER, gitea.comments[0]["body"])
|
|
resolve_all(gitea)
|
|
self.assertEqual(release(gitea), "")
|
|
|
|
def test_a_hold_after_a_release_of_the_same_head_is_released_again(self):
|
|
gitea = app_gitea()
|
|
hint_run(gitea)
|
|
resolve_all(gitea)
|
|
release(gitea)
|
|
for comments in gitea.line_comments.values():
|
|
comments[0]["resolver"] = None
|
|
hint_run(gitea)
|
|
self.assertEqual(gitea.scheduled_merges, [])
|
|
self.assertIn(report.HELD_MARKER, gitea.created_comments[-1])
|
|
resolve_all(gitea)
|
|
self.assertIn("merge scheduled", release(gitea))
|
|
self.assertEqual(len(gitea.scheduled_merges), 1)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|