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')
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)
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()
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
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
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
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!'}
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' )
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()
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)
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)
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!'})
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)
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()
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')
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'
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')
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)'
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
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
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()
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!'})
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
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 )
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')
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
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
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
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'), )
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'), )