def test_is_pull_request_ready_for_automerge_after_approval_approved_and_requested_changes( self, ): author_1 = builder.user().login("author_1") author_2 = builder.user().login("author_2") pull_request = build(builder.pull_request().commit( builder.commit().status(Commit.BUILD_SUCCESSFUL)).reviews([ builder.review().submitted_at("2020-01-11T14:59:58Z").state( ReviewState.CHANGES_REQUESTED).author(author_1), builder.review().submitted_at("2020-01-12T14:59:58Z").state( ReviewState.APPROVED).author(author_2), ]).mergeable(MergeableState.MERGEABLE).merged(False).label( builder.label().name(github_logic.AutomergeLabel. AFTER_TESTS_AND_APPROVAL.value))) self.assertFalse( github_logic._is_pull_request_ready_for_automerge(pull_request))
def test_non_asana_user_is_not_a_follower(self): unknown_github_user = build( builder.user("github_unknown_user_login", "GITHUB_UNKNOWN_USER_NAME")) pull_request = build( builder.pull_request().body("@github_unknown_user_login"). author(unknown_github_user).assignee(unknown_github_user).review( builder.review().body("@github_unknown_user_login").author( unknown_github_user)).comment( builder.comment().body("@github_unknown_user_login"). author(unknown_github_user)).requested_reviewer( unknown_github_user)) task_fields = src.asana.helpers.extract_task_fields_from_pull_request( pull_request) self.assertEqual(0, len(task_fields["followers"]))
def test_upsert_pull_request_when_task_id_already_found_in_dynamodb( self, create_task_mock, update_task_mock): # If the task id is found in dynamodb, then we just update (don't # attempt to create) pull_request = builder.pull_request().build() # Insert the mapping first existing_task_id = uuid4().hex dynamodb_client.insert_github_node_to_asana_id_mapping( pull_request.id(), existing_task_id) github_controller.upsert_pull_request(pull_request) create_task_mock.assert_not_called() update_task_mock.assert_called_with(pull_request, existing_task_id)
def test_html_body_status_closed_not_merged(self): pull_request = build(builder.pull_request().author( builder.user("github_test_user_login")).url( "https://foo.bar/baz").body("BODY").closed(True).merged(False)) task_fields = src.asana.helpers.extract_task_fields_from_pull_request( pull_request) actual = task_fields["html_notes"] expected_strings = [ "<body>", "closed", "the pull request was closed without merging code.", "BODY", "</body>", ] self.assertContainsStrings(actual, expected_strings)
def test_pull_request_approved_after_merging_reviews_and_comments_no_approvals( self, ): # The PR has reviews and comments, but neither have approval messages merged_at = datetime.now() reviewed_at = merged_at + timedelta(days=1) commented_at = merged_at + timedelta(days=2) pull_request = build(builder.pull_request().merged_at( datetime.now()).reviews([ builder.review("This looks OK").submitted_at(reviewed_at) ]).comments([ builder.comment("v cool use of emojis").published_at( commented_at) ])) self.assertFalse( github_logic.pull_request_approved_after_merging(pull_request))
def test_html_body_status_closed_approved_before(self, approved_before_merging): approved_before_merging.return_value = True pull_request = build(builder.pull_request().author( builder.user("github_test_user_login")).url( "https://foo.bar/baz").body("BODY").closed(True).merged(True)) task_fields = src.asana.helpers.extract_task_fields_from_pull_request( pull_request) actual = task_fields["html_notes"] expected_strings = [ "<body>", "complete", "the pull request was approved before merging.", "BODY", "</body>", ] self.assertContainsStrings(actual, expected_strings)
def test_does_not_care_about_merged_at_even_if_it_is_illegal_if_merged_is_false( self, ): def illegal_value_that_will_be_ignored(): # merged_at is supposed to be a datetime, which will be compared with other datetime values, # so the Python interpreter should be massively unhappy if merged_at is touched and turns out # to be a function (i.e. because it is illegal to compare a function to a datetime with an ordering # operator such as < > <= >=) pass pull_request = build(builder.pull_request().closed(True).merged( False).merged_at(illegal_value_that_will_be_ignored).reviews([ builder.review().submitted_at("2020-01-13T14:59:58Z").state( ReviewState.APPROVED) ])) task_fields = src.asana.helpers.extract_task_fields_from_pull_request( pull_request) self.assertEqual(True, task_fields["completed"])
def test_adds_warnings_if_label_and_no_warning_in_comments( self, add_pr_comment_mock, edit_pr_title_mock): for label in [ github_logic.AutomergeLabel.AFTER_TESTS_AND_APPROVAL.value, github_logic.AutomergeLabel.AFTER_APPROVAL.value, ]: pull_request = build(builder.pull_request().title( self.SAMPLE_PR_TITLE).label(builder.label().name(label))) github_logic.maybe_add_automerge_warning_comment(pull_request) add_pr_comment_mock.assert_called_with( pull_request.repository_owner_handle(), pull_request.repository_name(), pull_request.number(), github_logic.AUTOMERGE_COMMENT_WARNING, )
def test_handle_status_webhook_ready_for_automerge( self, is_pull_request_ready_for_automerge_mock, merge_pull_request_mock, upsert_pull_request_mock, ): # Mock that pull request can be automerged is_pull_request_ready_for_automerge_mock.return_value = True pull_request = build(builder.pull_request()) merged = github_logic.maybe_automerge_pull_request(pull_request) self.assertTrue(merged) merge_pull_request_mock.assert_called_with( pull_request.repository_owner_handle(), pull_request.repository_name(), pull_request.number(), pull_request.title(), pull_request.body(), )
def test_upsert_pull_request_when_task_id_not_found_in_dynamodb( self, create_task_mock, update_task_mock): # If the task id is not found in dynamodb, then we assume the task # doesn't exist and create a new task new_task_id = uuid4().hex create_task_mock.return_value = new_task_id pull_request = builder.pull_request().build() with patch.object(github_controller, "_add_asana_task_to_pull_request" ) as add_asana_task_to_pr_mock: github_controller.upsert_pull_request(pull_request) add_asana_task_to_pr_mock.assert_called_with( pull_request, new_task_id) create_task_mock.assert_called_with(pull_request.repository_id()) update_task_mock.assert_called_with(pull_request, new_task_id) # Assert that the new task id was inserted into the table task_id = dynamodb_client.get_asana_id_from_github_node_id( pull_request.id()) self.assertEqual(task_id, new_task_id)
def test_html_body(self): pull_request = build(builder.pull_request().author( builder.user("github_test_user_login")).url( "https://foo.bar/baz").body("BODY")) task_fields = src.asana.helpers.extract_task_fields_from_pull_request( pull_request) actual = task_fields["html_notes"] expected_strings = [ "<body>", "<em>", "This is a one-way sync from GitHub to Asana. Do not edit this task or comment on it!", "</em>", "\uD83D\uDD17", '<A href="https://foo.bar/baz">https://foo.bar/baz</A>', "✍", "TEST_USER_ASANA_DOMAIN_USER_ID", "<strong>", "Description:", "</strong>", "BODY", "</body>", ] self.assertContainsStrings(actual, expected_strings)
def test_requested_reviewers_github_users_or_teams(self): user = build(builder.user().login("user1")) pull_request = build(builder.pull_request().requested_reviewers( [user]).requested_reviewer_team("some_team", ["user1", "user2"])) self.assertEqual(["user1", "user2"], pull_request.requested_reviewers())
def test_upsert_comment_when_task_id_not_found_in_dynamodb( self, add_comment_mock, update_task_mock): pull_request = builder.pull_request().build() comment = builder.comment().build() github_controller.upsert_comment(pull_request, comment)
def test_pull_request_without_label(self): label_name = "test label" pull_request = build(builder.pull_request()) self.assertFalse( github_logic.pull_request_has_label(pull_request, label_name))
def test_returns_empty_list_if_no_linked_tasks(self): pull_request = build( builder.pull_request().body(f"Blah blah blah\nblah\nAsana tasks:")) self.assertCountEqual(asana_helpers.get_linked_task_ids(pull_request), [])
def test_returns_empty_list_for_malformed_description(self): pull_request = build(builder.pull_request().body( f"Blah blah blah\nblah\nAsana tasks:\neng jank")) self.assertCountEqual(asana_helpers.get_linked_task_ids(pull_request), [])
def test_pull_request_body_mentions(self): pull_request = builder.pull_request("@foo\n@bar").build() self.assertEqual( github_logic._pull_request_body_mentions(pull_request), ["foo", "bar"])
def test_completed_is_false_if_pr_is_closed_and_merged_but_not_reviewed( self): pull_request = build(builder.pull_request().closed(True).merged(True)) task_fields = src.asana.helpers.extract_task_fields_from_pull_request( pull_request) self.assertEqual(False, task_fields["completed"])
def test_name(self): pull_request = build( builder.pull_request().number("PR_NUMBER").title("PR_TITLE")) task_fields = src.asana.helpers.extract_task_fields_from_pull_request( pull_request) self.assertEqual("#PR_NUMBER - PR_TITLE", task_fields["name"])
def test_pull_request_approved_after_merging_no_reviews_or_comments(self): pull_request = builder.pull_request().merged_at(datetime.now()).build() self.assertFalse( github_logic.pull_request_approved_after_merging(pull_request))
def test_false_if_pull_request_does_not_have_autocomplete_label(self): pull_request = build(builder.pull_request().merged(True)) self.assertFalse(asana_logic.should_autocomplete_tasks_on_merge(pull_request))