def test_get_merge_body_include_pull_request_author_mannequin() -> None: """ Test case where actor is not a User and Bot to see how we handle weird cases. """ pull_request = create_pull_request() pull_request.body = "hello world" pull_request.author.name = None pull_request.author.type = "Mannequin" actual = get_merge_body( config=V1( version=1, merge=Merge(message=MergeMessage( body=MergeBodyStyle.pull_request_body, include_pull_request_author=True, )), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody( merge_method="squash", commit_message= "hello world\n\nCo-authored-by: barry <*****@*****.**>", ) assert actual == expected
def test_get_merge_body_includes_pull_request_url_with_coauthor() -> None: """ Coauthor should appear after the pull request url """ pull_request = create_pull_request() actual = get_merge_body( config=V1( version=1, merge=Merge(message=MergeMessage( body=MergeBodyStyle.pull_request_body, include_pull_request_url=True, include_pull_request_author=True, )), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody( merge_method="squash", commit_message="""\ # some description PR-URL: https://github.com/example_org/example_repo/pull/65 Co-authored-by: Barry Berkman <*****@*****.**>""", ) assert actual == expected
def test_config_parsing_opposite() -> None: """ parse config with all opposite settings so we can ensure the config is correctly formatted. """ file_path = load_config_fixture("v1-opposite.toml") loaded = toml.load(file_path) actual = V1.parse_obj(cast(Dict[Any, Any], loaded)) expected = V1( version=1, app_id="12345", merge=Merge( automerge_label="mergeit!", require_automerge_label=False, blacklist_title_regex="", blacklist_labels=["wip", "block-merge"], method=MergeMethod.squash, delete_branch_on_merge=True, block_on_reviews_requested=True, notify_on_conflict=False, optimistic_updates=False, message=MergeMessage( title=MergeTitleStyle.pull_request_title, body=MergeBodyStyle.pull_request_body, include_pr_number=False, body_type=BodyText.plain_text, strip_html_comments=True, ), ), ) assert actual == expected
def test_get_merge_body_includes_pull_request_url() -> None: """ Ensure that when the appropriate config option is set, we include the pull request url in the commit message. """ pull_request = create_pull_request() actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage(body=MergeBodyStyle.pull_request_body, include_pull_request_url=True)), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody( merge_method="squash", commit_message="""\ # some description PR-URL: https://github.com/example_org/example_repo/pull/65""", ) assert actual == expected
def test_get_merge_body_empty() -> None: pull_request = create_pull_request() pull_request.body = "hello world" actual = get_merge_body( config=V1( version=1, merge=Merge(message=MergeMessage(body=MergeBodyStyle.empty))), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message="") assert actual == expected
def test_get_merge_body_empty(pull_request: queries.PullRequest) -> None: pull_request.body = "hello world" actual = get_merge_body( V1( version=1, merge=Merge( method=MergeMethod.squash, message=MergeMessage(body=MergeBodyStyle.empty), ), ), pull_request, ) expected = dict(merge_method="squash", commit_message="") assert actual == expected
def test_get_merge_body_strip_html_comments() -> None: pull_request = create_pull_request() pull_request.body = "hello <!-- testing -->world" actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage(body=MergeBodyStyle.pull_request_body, strip_html_comments=True)), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message="hello world") assert actual == expected
def test_get_merge_body_strip_html_comments(pull_request: queries.PullRequest, original: str, stripped: str) -> None: pull_request.body = "hello <!-- testing -->world" actual = get_merge_body( V1( version=1, merge=Merge( method=MergeMethod.squash, message=MergeMessage(body=MergeBodyStyle.pull_request_body, strip_html_comments=True), ), ), pull_request, ) expected = dict(merge_method="squash", commit_message="hello world") assert actual == expected
def test_get_merge_body_includes_pull_request_url_github_default() -> None: """ We should not set a commit message when merge.body = "github_default". """ pull_request = create_pull_request() actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage(body=MergeBodyStyle.github_default, include_pull_request_url=True)), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message=None) assert actual == expected
def test_pr_get_merge_body_full(pull_request: queries.PullRequest) -> None: actual = get_merge_body( V1( version=1, merge=Merge( method=MergeMethod.squash, message=MergeMessage( title=MergeTitleStyle.pull_request_title, body=MergeBodyStyle.pull_request_body, include_pr_number=True, ), ), ), pull_request, ) expected = dict( merge_method="squash", commit_title=pull_request.title + f" (#{pull_request.number})", commit_message=pull_request.body, ) assert actual == expected
def test_pr_get_merge_body_full() -> None: pull_request = create_pull_request() actual = get_merge_body( config=V1( version=1, merge=Merge(message=MergeMessage( title=MergeTitleStyle.pull_request_title, body=MergeBodyStyle.pull_request_body, include_pr_number=True, )), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody( merge_method="squash", commit_title=pull_request.title + f" (#{pull_request.number})", commit_message=pull_request.body, ) assert expected == actual
def test_get_merge_body_include_pull_request_author_user() -> None: pull_request = create_pull_request() pull_request.body = "hello world" actual = get_merge_body( config=V1( version=1, merge=Merge(message=MergeMessage( body=MergeBodyStyle.pull_request_body, include_pull_request_author=True, )), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody( merge_method="squash", commit_message= "hello world\n\nCo-authored-by: Barry Berkman <*****@*****.**>", ) assert actual == expected
def test_get_merge_body_cut_body_after() -> None: """ Basic check of cut_body_after removing content. """ pull_request = create_pull_request() pull_request.body = "hello <!-- testing -->world" actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage( body=MergeBodyStyle.pull_request_body, cut_body_after="<!-- testing -->", ) ), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message="hello <!-- testing -->") assert actual == expected
def test_get_merge_body_cut_body_before_multiple_markers() -> None: """ We should choose the first substring matching cut_body_before. """ pull_request = create_pull_request() pull_request.body = "hello <!-- testing -->world<!-- testing --> 123" actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage( body=MergeBodyStyle.pull_request_body, cut_body_before="<!-- testing -->", strip_html_comments=True, ) ), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message="world 123") assert actual == expected
def test_get_merge_body_cut_body_after_strip_html() -> None: """ We should be able to use strip_html_comments with cut_body_after. """ pull_request = create_pull_request() pull_request.body = "hello <!-- testing -->world" actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage( body=MergeBodyStyle.pull_request_body, cut_body_after="<!-- testing -->", strip_html_comments=True, ) ), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message="hello ") assert actual == expected
def test_get_merge_body_cut_body_and_text_before() -> None: """ Verify that the separator is also gone after removing content. """ pull_request = create_pull_request() pull_request.body = "hello <!-- testing -->world" actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage( body=MergeBodyStyle.pull_request_body, cut_body_before="<!-- testing -->", cut_body_and_text=True, ) ), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message="world") assert actual == expected
def test_get_merge_body_cut_body_before_no_match_found() -> None: """ Ensure we don't edit the message if there isn't any match found with cut_body_before. """ pull_request = create_pull_request() pr_body = "hello <!-- foo -->world<!-- bar --> 123" pull_request.body = pr_body actual = get_merge_body( config=V1( version=1, merge=Merge( message=MergeMessage( body=MergeBodyStyle.pull_request_body, cut_body_before="<!-- buzz -->", ) ), ), pull_request=pull_request, merge_method=MergeMethod.squash, commits=[], ) expected = MergeBody(merge_method="squash", commit_message=pr_body) assert actual == expected
def create_event() -> EventInfoResponse: config = V1(version=1, merge=Merge(automerge_label="automerge", method=MergeMethod.squash)) pr = PullRequest( id="e14ff7599399478fb9dbc2dacb87da72", number=100, author=PullRequestAuthor(login="******", databaseId=49118, type="Bot"), mergeStateStatus=MergeStateStatus.BEHIND, state=PullRequestState.OPEN, isDraft=False, mergeable=MergeableState.MERGEABLE, isCrossRepository=False, labels=["automerge"], latest_sha="8d728d017cac4f5ba37533debe65730abe65730a", baseRefName="master", headRefName="df825f90-9825-424c-a97e-733522027e4c", title="Update README.md", body="", bodyText="", bodyHTML="", url="https://github.com/delos-corp/hive-mind/pull/324", ) rep_info = RepoInfo( merge_commit_allowed=False, rebase_merge_allowed=False, squash_merge_allowed=True, is_private=True, delete_branch_on_merge=False, ) branch_protection = BranchProtectionRule( requiresApprovingReviews=True, requiredApprovingReviewCount=2, requiresStatusChecks=True, requiredStatusCheckContexts=[ "ci/circleci: frontend_lint", "ci/circleci: frontend_test", ], requiresStrictStatusChecks=True, requiresCodeOwnerReviews=False, requiresCommitSignatures=False, restrictsPushes=False, pushAllowances=NodeListPushAllowance(nodes=[]), ) return EventInfoResponse( config=config, config_str="""\ version = 1 [merge] method = "squash" """, config_file_expression="master:.kodiak.toml", head_exists=True, pull_request=pr, repository=rep_info, branch_protection=branch_protection, review_requests=[], reviews=[], status_contexts=[], check_runs=[], valid_signature=True, valid_merge_methods=[MergeMethod.squash], subscription=None, )
( "v1-opposite.1.toml", V1( version=1, app_id="12345", merge=Merge( automerge_label="mergeit!", require_automerge_label=False, blacklist_title_regex="", blacklist_labels=["wip", "block-merge"], method=MergeMethod.squash, delete_branch_on_merge=True, block_on_reviews_requested=True, notify_on_conflict=False, optimistic_updates=False, dont_wait_on_status_checks=["ci/circleci: deploy"], update_branch_immediately=True, prioritize_ready_to_merge=True, message=MergeMessage( title=MergeTitleStyle.pull_request_title, body=MergeBodyStyle.pull_request_body, include_pr_number=False, body_type=BodyText.plain_text, strip_html_comments=True, ), ), ), ), ( "v1-opposite.2.toml", V1(
def test_pr_get_merge_body_empty(pull_request: queries.PullRequest) -> None: actual = get_merge_body( V1(version=1, merge=Merge(method=MergeMethod.squash)), pull_request ) expected = dict(merge_method="squash") assert actual == expected
def block_event(config_file_expression: str, config_str: str) -> EventInfoResponse: config = V1(version=1, merge=Merge(automerge_label="automerge", method=MergeMethod.squash)) pr = PullRequest( id="e14ff7599399478fb9dbc2dacb87da72", number=100, mergeStateStatus=MergeStateStatus.BEHIND, state=PullRequestState.OPEN, mergeable=MergeableState.MERGEABLE, isCrossRepository=False, labels=["automerge"], latest_sha="8d728d017cac4f5ba37533debe65730abe65730a", baseRefName="master", headRefName="df825f90-9825-424c-a97e-733522027e4c", title="Update README.md", body="", bodyText="", bodyHTML="", ) rep_info = RepoInfo( merge_commit_allowed=False, rebase_merge_allowed=False, squash_merge_allowed=True, ) branch_protection = BranchProtectionRule( requiresApprovingReviews=True, requiredApprovingReviewCount=2, requiresStatusChecks=True, requiredStatusCheckContexts=[ "ci/circleci: backend_lint", "ci/circleci: backend_test", "ci/circleci: frontend_lint", "ci/circleci: frontend_test", "WIP (beta)", ], requiresStrictStatusChecks=True, requiresCommitSignatures=False, ) return EventInfoResponse( config=config, config_str=config_str, config_file_expression=config_file_expression, head_exists=True, pull_request=pr, repo=rep_info, branch_protection=branch_protection, review_requests=[ PRReviewRequest(name="ghost"), PRReviewRequest(name="ghost-team"), PRReviewRequest(name="ghost-mannequin"), ], reviews=[ PRReview( createdAt=arrow.get("2019-05-22T15:29:34Z").datetime, state=PRReviewState.COMMENTED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), PRReview( createdAt=arrow.get("2019-05-22T15:29:52Z").datetime, state=PRReviewState.CHANGES_REQUESTED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), PRReview( createdAt=arrow.get("2019-05-22T15:30:52Z").datetime, state=PRReviewState.COMMENTED, author=PRReviewAuthor(login="******", permission=Permission.ADMIN), ), PRReview( createdAt=arrow.get("2019-05-22T15:43:17Z").datetime, state=PRReviewState.APPROVED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), PRReview( createdAt=arrow.get("2019-05-23T15:13:29Z").datetime, state=PRReviewState.APPROVED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), ], status_contexts=[ StatusContext(context="ci/circleci: backend_lint", state=StatusState.SUCCESS), StatusContext(context="ci/circleci: backend_test", state=StatusState.SUCCESS), StatusContext(context="ci/circleci: frontend_lint", state=StatusState.SUCCESS), StatusContext(context="ci/circleci: frontend_test", state=StatusState.SUCCESS), ], check_runs=[ CheckRun(name="WIP (beta)", conclusion=CheckConclusionState.SUCCESS) ], valid_signature=True, valid_merge_methods=[MergeMethod.squash], )
def block_event() -> EventInfoResponse: config = V1(version=1, merge=Merge(automerge_label="automerge", method=MergeMethod.squash)) pr = PullRequest( id="e14ff7599399478fb9dbc2dacb87da72", number=100, author=PullRequestAuthor(login="******", databaseId=49118, type="Bot"), mergeStateStatus=MergeStateStatus.BEHIND, state=PullRequestState.OPEN, mergeable=MergeableState.MERGEABLE, isCrossRepository=False, labels=["automerge"], latest_sha="8d728d017cac4f5ba37533debe65730abe65730a", baseRefName="master", headRefName="df825f90-9825-424c-a97e-733522027e4c", title="Update README.md", body="", bodyText="", bodyHTML="", url="https://github.com/delos-corp/hive-mind/pull/324", ) rep_info = RepoInfo( merge_commit_allowed=False, rebase_merge_allowed=False, squash_merge_allowed=True, delete_branch_on_merge=True, is_private=True, ) branch_protection = BranchProtectionRule( requiresApprovingReviews=True, requiredApprovingReviewCount=2, requiresStatusChecks=True, requiredStatusCheckContexts=[ "ci/circleci: backend_lint", "ci/circleci: backend_test", "ci/circleci: frontend_lint", "ci/circleci: frontend_test", "WIP (beta)", ], requiresStrictStatusChecks=True, requiresCommitSignatures=False, restrictsPushes=True, pushAllowances=NodeListPushAllowance(nodes=[ PushAllowance(actor=PushAllowanceActor(databaseId=None)), PushAllowance(actor=PushAllowanceActor(databaseId=53453)), ]), ) return EventInfoResponse( config=config, config_str="""\ version = 1 [merge] method = "squash" """, config_file_expression="master:.kodiak.toml", head_exists=True, pull_request=pr, repository=rep_info, subscription=Subscription( account_id="D1606A79-A1A1-4550-BA7B-C9ED0D792B1E", subscription_blocker=None), branch_protection=branch_protection, review_requests=[ PRReviewRequest(name="ghost"), PRReviewRequest(name="ghost-team"), PRReviewRequest(name="ghost-mannequin"), ], reviews=[ PRReview( createdAt=arrow.get("2019-05-22T15:29:34Z").datetime, state=PRReviewState.COMMENTED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), PRReview( createdAt=arrow.get("2019-05-22T15:29:52Z").datetime, state=PRReviewState.CHANGES_REQUESTED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), PRReview( createdAt=arrow.get("2019-05-22T15:30:52Z").datetime, state=PRReviewState.COMMENTED, author=PRReviewAuthor(login="******", permission=Permission.ADMIN), ), PRReview( createdAt=arrow.get("2019-05-22T15:43:17Z").datetime, state=PRReviewState.APPROVED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), PRReview( createdAt=arrow.get("2019-05-23T15:13:29Z").datetime, state=PRReviewState.APPROVED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), PRReview( createdAt=arrow.get("2019-05-24T10:21:32Z").datetime, state=PRReviewState.APPROVED, author=PRReviewAuthor(login="******", permission=Permission.WRITE), ), ], status_contexts=[ StatusContext(context="ci/circleci: backend_lint", state=StatusState.SUCCESS), StatusContext(context="ci/circleci: backend_test", state=StatusState.SUCCESS), StatusContext(context="ci/circleci: frontend_lint", state=StatusState.SUCCESS), StatusContext(context="ci/circleci: frontend_test", state=StatusState.SUCCESS), ], check_runs=[ CheckRun(name="WIP (beta)", conclusion=CheckConclusionState.SUCCESS) ], valid_signature=True, valid_merge_methods=[MergeMethod.squash], )