예제 #1
0
    def test_welcome_msg(self):
        base_msg = """Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from %s soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see [the contribution instructions](%s) for more information.
"""

        # No reviewer, no config contributing link.
        handler = HighfiveHandlerMock(Payload({})).handler
        assert handler.welcome_msg(None) == base_msg % (
            '@nrc (NB. this repo may be misconfigured)',
            'https://rustc-dev-guide.rust-lang.org/contributing.html')

        # Has reviewer, no config contributing link.
        handler = HighfiveHandlerMock(Payload({})).handler
        assert handler.welcome_msg('userA') == base_msg % (
            '@userA (or someone else)',
            'https://rustc-dev-guide.rust-lang.org/contributing.html')

        # No reviewer, has config contributing link.
        handler = HighfiveHandlerMock(Payload({}),
                                      repo_config={
                                          'contributing': 'https://something'
                                      }).handler
        assert handler.welcome_msg(None) == base_msg % (
            '@nrc (NB. this repo may be misconfigured)', 'https://something')

        # Has reviewer, has config contributing link.
        handler = HighfiveHandlerMock(Payload({}),
                                      repo_config={
                                          'contributing': 'https://something'
                                      }).handler
        assert handler.welcome_msg('userA') == base_msg % (
            '@userA (or someone else)', 'https://something')
예제 #2
0
    def make_handler(
            state='open', is_pull_request=True, commenter='userA',
            repo='repo-name', owner='repo-owner', author='userB',
            comment='comment!', issue_number=7, assignee=None
    ):
        payload = Payload({
            'issue': {
                'state': state,
                'number': issue_number,
                'assignee': None,
                'user': {
                    'login': author,
                },
            },
            'comment': {
                'user': {
                    'login': commenter,
                },
                'body': comment,
            },
            'repository': {
                'name': repo,
                'owner': {
                    'login': owner,
                },
            },
        })

        if is_pull_request:
            payload._payload['issue']['pull_request'] = {}
        if assignee is not None:
            payload._payload['issue']['assignee'] = {'login': assignee}

        return HighfiveHandlerMock(payload).handler
예제 #3
0
 def test_expected_branch_custom_expected_match(self):
     payload = Payload(
         {'pull_request': {'base': {'label': 'repo-owner:dev'}}}
     )
     config = {'expected_branch': 'dev'}
     with HighfiveHandlerMock(payload, repo_config=config) as m:
         assert not m.handler.unexpected_branch()
예제 #4
0
    def test_submodule(self):
        handler = HighfiveHandlerMock(Payload({})).handler
        submodule_diff = load_fake('submodule.diff')
        assert handler.modifies_submodule(submodule_diff)

        normal_diff = load_fake('normal.diff')
        assert not handler.modifies_submodule(normal_diff)
예제 #5
0
    def test_find_reviewer(self):
        found_cases = (
            ('r? @foo', 'foo'),
            ('R? @foo', 'foo'),
            ('....@!##$@#%r? @foo', 'foo'),
            ('r?:-:-:- @foo', 'foo'),
            ('Lorem ipsum dolor sit amet, r?@foo consectetur', 'foo'),
            ('r? @8iAke', '8iAke'),
            ('r? @D--a--s-h', 'D--a--s-h'),
            ('r? @foo$', 'foo'),
        )
        not_found_cases = (
            'rr? @foo',
            'r @foo',
            'r?! @foo',
            'r? foo',
            'r? @',
            # When there is no content in a PR description GitHub sets the body
            # as None instead of an empty string
            # https://github.com/rust-lang-nursery/highfive/issues/184
            None,
        )
        handler = HighfiveHandlerMock(Payload({})).handler

        for (msg, reviewer) in found_cases:
            assert handler.find_reviewer(msg) == reviewer, \
                "expected '%s' from '%s'" % (reviewer, msg)

        for msg in not_found_cases:
            assert handler.find_reviewer(msg) is None, \
                "expected '%s' to have no reviewer extracted" % msg
예제 #6
0
    def test_find_reviewer(self):
        found_cases = (
            ('r? @foo', 'foo'),
            ('R? @foo', 'foo'),
            ('....@!##$@#%r? @foo', 'foo'),
            ('r?:-:-:- @foo', 'foo'),
            ('Lorem ipsum dolor sit amet, r?@foo consectetur', 'foo'),
            ('r? @8iAke', '8iAke'),
            ('r? @D--a--s-h', 'D--a--s-h'),
            ('r? @foo$', 'foo'),
        )
        not_found_cases = (
            'rr? @foo',
            'r @foo',
            'r?! @foo',
            'r? foo',
            'r? @',
        )
        handler = HighfiveHandlerMock(Payload({})).handler

        for (msg, reviewer) in found_cases:
            assert handler.find_reviewer(msg) == reviewer, \
                "expected '%s' from '%s'" % (reviewer, msg)

        for msg in not_found_cases:
            assert handler.find_reviewer(msg) is None, \
                "expected '%s' to have no reviewer extracted" % msg
예제 #7
0
 def test_init(self, mock_load_repo_config):
     payload = Payload({'the': 'payload'})
     with HighfiveHandlerMock(payload, repo_config={'a': 'config!'}) as m:
         assert m.handler.payload == payload
         assert m.handler.integration_user == 'integrationUser'
         assert m.handler.integration_token == 'integrationToken'
         assert m.handler.repo_config == {'a': 'config!'}
예제 #8
0
    def test_get_irc_nick_non_200(self, mock_urllib2):
        handler = HighfiveHandlerMock(Payload({})).handler
        self.setup_get_irc_nick_mocks(mock_urllib2, 503)
        assert handler.get_irc_nick('foo') is None

        mock_urllib2.urlopen.assert_called_with(
            'http://www.ncameron.org/rustaceans/user?username=foo'
        )
예제 #9
0
 def test_newpr(self):
     payload = Payload({'action': 'opened'})
     m = self.handler_mock(payload)
     m.handler.run()
     assert m.mock_config.get.call_count == 2
     self.mocks['new_pr'].assert_called_once_with()
     self.mocks['new_comment'].assert_not_called()
     self.mocks['sys'].exit.assert_not_called()
예제 #10
0
 def test_is_collaborator_true(self, mock_api_req):
     handler = HighfiveHandlerMock(Payload({})).handler
     assert handler.is_collaborator('commentUser', 'repo-owner',
                                    'repo-name')
     mock_api_req.assert_called_with(
         'GET',
         'https://api.github.com/repos/repo-owner/repo-name/collaborators/commentUser',
         None)
예제 #11
0
 def test_unsupported_payload(self):
     payload = Payload({'action': 'something-not-supported'})
     m = self.handler_mock(payload)
     m.handler.run()
     assert m.mock_config.get.call_count == 2
     self.mocks['new_pr'].assert_not_called()
     self.mocks['new_comment'].assert_not_called()
     self.mocks['sys'].exit.assert_called_once_with(0)
예제 #12
0
 def test_post_comment_success(self, mock_api_req):
     handler = HighfiveHandlerMock(Payload({})).handler
     mock_api_req.return_value = {'body': 'response body!'}
     assert handler.post_comment('Request body!', 'repo-owner', 'repo-name',
                                 7) is None
     mock_api_req.assert_called_with(
         'POST',
         'https://api.github.com/repos/repo-owner/repo-name/issues/7/comments',
         {'body': 'Request body!'})
예제 #13
0
 def test_is_collaborator_error(self, mock_api_req):
     handler = HighfiveHandlerMock(Payload({})).handler
     mock_api_req.side_effect = HTTPError(None, 500, None, None, None)
     with pytest.raises(HTTPError):
         handler.is_collaborator('commentUser', 'repo-owner', 'repo-name')
     mock_api_req.assert_called_with(
         'GET',
         'https://api.github.com/repos/repo-owner/repo-name/collaborators/commentUser',
         None)
예제 #14
0
 def test_expected_branch_default_expected_match(self):
     payload = Payload(
         {'pull_request': {
             'base': {
                 'label': 'repo-owner:master'
             }
         }})
     with HighfiveHandlerMock(payload, repo_config={}) as m:
         assert not m.handler.unexpected_branch()
예제 #15
0
 def test_circular_groups(self):
     """Test choosing a reviewer from groups that have circular references.
     """
     handler = HighfiveHandlerMock(
         Payload({}),
         repo_config=self.fakes['config']['circular_groups']).handler
     with pytest.raises(AssertionError):
         handler.choose_reviewer('rust', 'rust-lang',
                                 self.fakes['diff']['normal'], 'fooauthor')
예제 #16
0
    def make_defaults(cls, patcherize):
        cls.mocks = patcherize(
            (('api_req', 'highfive.newpr.HighfiveHandler.api_req'), ))
        cls.payload = Payload({'repository': {'fork': False}})

        cls.username = '******'
        cls.owner = 'repo-owner'
        cls.repo = 'repo-name'
        cls.token = 'integrationToken'
예제 #17
0
 def test_load_json_file(self, mock_dirname):
     handler = HighfiveHandlerMock(Payload({})).handler
     mock_dirname.return_value = '/the/path'
     contents = ['some json']
     with mock.patch(
             'builtins.open',
             mock.mock_open(read_data=json.dumps(contents))) as mock_file:
         assert handler._load_json_file('a-config.json') == contents
         mock_file.assert_called_with('/the/path/configs/a-config.json')
예제 #18
0
    def test_review_msg(self):
        # No reviewer.
        handler = HighfiveHandlerMock(Payload({})).handler
        assert handler.review_msg(None, 'userB') == \
               '@userB: no appropriate reviewer found, use r? to override'

        # Has reviewer.
        assert handler.review_msg('userA', 'userB') == \
               'r? @userA\n\n(rust_highfive has picked a reviewer for you, use r? to override)'
예제 #19
0
 def test_with_files(self):
     """Test choosing a reviewer when a file os changed."""
     self.handler = HighfiveHandlerMock(
         Payload({}),
         repo_config=self.fakes['config']['individual_files']).handler
     (chosen_reviewers,
      mentions) = self.choose_reviewers(self.fakes['diff']['travis-yml'],
                                        "nikomatsakis")
     assert set(["pnkfelix", "nrc", "aturon"]) == chosen_reviewers
     assert set([()]) == mentions
예제 #20
0
 def test_no_potential_reviewers(self):
     """Test choosing a reviewer when nobody qualifies.
     """
     self.handler = HighfiveHandlerMock(
         Payload({}), repo_config=self.fakes['config']['empty']).handler
     chosen_reviewers, mentions = self.choose_reviewers(
         self.fakes['diff']['normal'], 'alexcrichton',
         self.fakes['global_']['base'])
     assert set([None]) == chosen_reviewers
     assert set([()]) == mentions
예제 #21
0
    def test_get_irc_nick_no_data(self, mock_urllib2):
        handler = HighfiveHandlerMock(Payload({})).handler
        mock_data = self.setup_get_irc_nick_mocks(mock_urllib2, 200, '[]')
        assert handler.get_irc_nick('foo') is None

        mock_urllib2.urlopen.assert_called_with(
            'http://www.ncameron.org/rustaceans/user?username=foo'
        )
        mock_data.getcode.assert_called()
        mock_data.read.assert_called()
예제 #22
0
 def test_post_comment_error(self, mock_api_req):
     handler = HighfiveHandlerMock(Payload({})).handler
     mock_api_req.return_value = {}
     mock_api_req.side_effect = HTTPError(None, 422, None, None, None)
     with pytest.raises(HTTPError):
         handler.post_comment('Request body!', 'repo-owner', 'repo-name', 7)
     mock_api_req.assert_called_with(
         'POST',
         'https://api.github.com/repos/repo-owner/repo-name/issues/7/comments',
         {'body': 'Request body!'})
예제 #23
0
 def test_individuals_no_dirs_2(self):
     """Test choosing a reviewer from a list of individual reviewers, no
     directories, and an author who is a potential reviewer.
     """
     self.handler = HighfiveHandlerMock(
         Payload({}),
         repo_config=self.fakes['config']['individuals_no_dirs']).handler
     (chosen_reviewers,
      mentions) = self.choose_reviewers(self.fakes['diff']['normal'], "nrc")
     assert set(["pnkfelix"]) == chosen_reviewers
     assert set([()]) == mentions
예제 #24
0
 def test_add_labels_success(self, mock_api_req):
     mock_api_req.return_value = {'body': 'response body!'}
     labels = ['label1', 'label2']
     handler = HighfiveHandlerMock(
         Payload({}), repo_config={'new_pr_labels': labels}
     ).handler
     assert handler.add_labels('repo-owner', 'repo-name', 7) is None
     mock_api_req.assert_called_with(
         'POST', 'https://api.github.com/repos/repo-owner/repo-name/issues/7/labels',
         labels
     )
예제 #25
0
 def test_global_group_overlap(self, mock_load_json):
     """Test for an AssertionError when the global config contains a group
     already defined in the config.
     """
     handler = HighfiveHandlerMock(
         Payload({}),
         repo_config=self.fakes['config']['individuals_no_dirs']).handler
     mock_load_json.return_value = self.fakes['global_']['has_all']
     with pytest.raises(AssertionError):
         handler.choose_reviewer('rust', 'rust-lang',
                                 self.fakes['diff']['normal'], 'fooauthor')
예제 #26
0
 def test_with_dirs(self):
     """Test choosing a reviewer when directory reviewers are defined that
     intersect with the diff.
     """
     self.handler = HighfiveHandlerMock(
         Payload({}),
         repo_config=self.fakes['config']['individuals_dirs']).handler
     chosen_reviewers, mentions = self.choose_reviewers(
         self.fakes['diff']['normal'], "nikomatsakis")
     assert set(["pnkfelix", "nrc", "aturon"]) == chosen_reviewers
     assert set([()]) == mentions
예제 #27
0
 def test_mentions(self):
     """Test tagging people listed in the mentions list."""
     self.handler = HighfiveHandlerMock(
         Payload({}), repo_config=self.fakes['config']['mentions']).handler
     (chosen_reviewers, mentions) = self.choose_reviewers(
         self.fakes['diff']['mentions'],
         "nikomatsakis",
     )
     assert set(["pnkfelix"]) == chosen_reviewers
     # @ehuss should not be listed here
     assert set(["@pnkfelix", "@GuillaumeGomez"]) == mentions
예제 #28
0
 def test_global_core(self):
     """Test choosing a reviewer from the core group in the global
     configuration.
     """
     self.handler = HighfiveHandlerMock(
         Payload({}), repo_config=self.fakes['config']['empty']).handler
     (chosen_reviewers,
      mentions) = self.choose_reviewers(self.fakes['diff']['normal'],
                                        'fooauthor',
                                        self.fakes['global_']['base'])
     assert set(['alexcrichton']) == chosen_reviewers
     assert set([()]) == mentions
예제 #29
0
 def test_load_repo_config_supported(self, mock_load_json_file):
     mock_load_json_file.return_value = {'a': 'config!'}
     payload = Payload({
         'action': 'opened',
         'repository': {'full_name': 'foo/blah'}
     })
     m = HighfiveHandlerMock(payload)
     m.stop_patchers()
     assert m.handler.load_repo_config() == {'a': 'config!'}
     mock_load_json_file.assert_called_once_with(
         os.path.join('foo', 'blah.json'),
     )
예제 #30
0
 def test_load_repo_config_unsupported(self, mock_load_json_file):
     mock_load_json_file.side_effect = IOError
     payload = Payload({
         'action': 'created',
         'repository': {'full_name': 'foo/blah'}
     })
     m = HighfiveHandlerMock(payload)
     m.stop_patchers()
     with pytest.raises(newpr.UnsupportedRepoError):
         m.handler.load_repo_config()
     mock_load_json_file.assert_called_once_with(
         os.path.join('foo', 'blah.json'),
     )