def test_update_target_revision(self, backend, csrf_token): commits = [ {'message': 'ancestor'}, {'message': 'change'}, {'message': 'ancestor-new', 'parents': ['ancestor']}, {'message': 'change-rebased'}, ] commit_ids = backend.create_master_repo(commits) target = backend.create_repo(heads=['ancestor']) source = backend.create_repo(heads=['change']) # create pr from a in source to A in target pull_request = PullRequest() pull_request.source_repo = source # TODO: johbo: Make sure that we write the source ref this way! pull_request.source_ref = 'branch:{branch}:{commit_id}'.format( branch=backend.default_branch_name, commit_id=commit_ids['change']) pull_request.target_repo = target # TODO: johbo: Target ref should be branch based, since tip can jump # from branch to branch pull_request.target_ref = 'branch:{branch}:{commit_id}'.format( branch=backend.default_branch_name, commit_id=commit_ids['ancestor']) pull_request.revisions = [commit_ids['change']] pull_request.title = u"Test" pull_request.description = u"Description" pull_request.author = UserModel().get_by_username( TEST_USER_ADMIN_LOGIN) Session().add(pull_request) Session().commit() pull_request_id = pull_request.pull_request_id # target has ancestor - ancestor-new # source has ancestor - ancestor-new - change-rebased backend.pull_heads(target, heads=['ancestor-new']) backend.pull_heads(source, heads=['change-rebased']) # update PR self.app.post( url(controller='pullrequests', action='update', repo_name=target.repo_name, pull_request_id=str(pull_request_id)), params={'update_commits': 'true', '_method': 'put', 'csrf_token': csrf_token}, status=200) # check that we have now both revisions pull_request = PullRequest.get(pull_request_id) assert pull_request.revisions == [commit_ids['change-rebased']] assert pull_request.target_ref == 'branch:{branch}:{commit_id}'.format( branch=backend.default_branch_name, commit_id=commit_ids['ancestor-new']) # TODO: johbo: This should be a test on its own response = self.app.get(url( controller='pullrequests', action='index', repo_name=target.repo_name)) assert response.status_int == 200 assert 'Pull request updated to' in response.body assert 'with 1 added, 1 removed commits.' in response.body
def test_merge_failed(self, pull_request, merge_extras): user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) self.merge_mock.return_value = MergeResponse( False, False, '6126b7bfcc82ad2d3deaee22af926b082ce54cc6', MergeFailureReason.MERGE_FAILED) PullRequestModel().merge(pull_request, pull_request.author, extras=merge_extras) message = ( u'Merge pull request #{pr_id} from {source_repo} {source_ref_name}' u'\n\n {pr_title}'.format( pr_id=pull_request.pull_request_id, source_repo=safe_unicode( pull_request.source_repo.scm_instance().name), source_ref_name=pull_request.source_ref_parts.name, pr_title=safe_unicode(pull_request.title))) self.merge_mock.assert_called_once_with( pull_request.target_ref_parts, pull_request.source_repo.scm_instance(), pull_request.source_ref_parts, self.workspace_id, user_name=user.username, user_email=user.email, message=message) pull_request = PullRequest.get(pull_request.pull_request_id) assert self.invalidation_mock.called is False assert pull_request.merge_rev is None
def test_comment_force_close_pull_request(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id reviewers_ids = [1, 2] PullRequestModel().update_reviewers(pull_request_id, reviewers_ids) author = pull_request.user_id repo = pull_request.target_repo.repo_id self.app.post( url(controller='pullrequests', action='comment', repo_name=pull_request.target_repo.scm_instance().name, pull_request_id=str(pull_request_id)), params={ 'changeset_status': 'forced_closed', 'csrf_token': csrf_token}, status=302) pull_request = PullRequest.get(pull_request_id) action = 'user_closed_pull_request:%d' % pull_request_id journal = UserLog.query().filter( UserLog.user_id == author, UserLog.repository_id == repo, UserLog.action == action).all() assert len(journal) == 1 # check only the latest status, not the review status status = ChangesetStatusModel().get_status( pull_request.source_repo, pull_request=pull_request) assert status == ChangesetStatus.STATUS_REJECTED
def test_reviewer_notifications(self, backend, csrf_token): # We have to use the app.post for this test so it will create the # notifications properly with the new PR commits = [ {'message': 'ancestor', 'added': [FileNode('file_A', content='content_of_ancestor')]}, {'message': 'change', 'added': [FileNode('file_a', content='content_of_change')]}, {'message': 'change-child'}, {'message': 'ancestor-child', 'parents': ['ancestor'], 'added': [ FileNode('file_B', content='content_of_ancestor_child')]}, {'message': 'ancestor-child-2'}, ] commit_ids = backend.create_master_repo(commits) target = backend.create_repo(heads=['ancestor-child']) source = backend.create_repo(heads=['change']) response = self.app.post( url( controller='pullrequests', action='create', repo_name=source.repo_name), params={ 'source_repo': source.repo_name, 'source_ref': 'branch:default:' + commit_ids['change'], 'target_repo': target.repo_name, 'target_ref': 'branch:default:' + commit_ids['ancestor-child'], 'pullrequest_desc': 'Description', 'pullrequest_title': 'Title', 'review_members': '2', 'revisions': commit_ids['change'], 'user': '', 'csrf_token': csrf_token, }, status=302) location = response.headers['Location'] pull_request_id = int(location.rsplit('/', 1)[1]) pull_request = PullRequest.get(pull_request_id) # Check that a notification was made notifications = Notification.query()\ .filter(Notification.created_by == pull_request.author.user_id, Notification.type_ == Notification.TYPE_PULL_REQUEST, Notification.subject.contains("wants you to review " "pull request #%d" % pull_request_id)) assert len(notifications.all()) == 1 # Change reviewers and check that a notification was made PullRequestModel().update_reviewers(pull_request.pull_request_id, [1]) assert len(notifications.all()) == 2
def test_merge_pull_request_disabled(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request(mergeable=False) pull_request_id = pull_request.pull_request_id pull_request = PullRequest.get(pull_request_id) response = self.app.post( url(controller='pullrequests', action='merge', repo_name=pull_request.target_repo.scm_instance().name, pull_request_id=str(pull_request.pull_request_id)), params={'csrf_token': csrf_token}).follow() assert response.status_int == 200 assert 'Server-side pull request merging is disabled.' in response.body
def test_create_pull_request_stores_ancestor_commit_id(self, backend, csrf_token): commits = [ {'message': 'ancestor', 'added': [FileNode('file_A', content='content_of_ancestor')]}, {'message': 'change', 'added': [FileNode('file_a', content='content_of_change')]}, {'message': 'change-child'}, {'message': 'ancestor-child', 'parents': ['ancestor'], 'added': [ FileNode('file_B', content='content_of_ancestor_child')]}, {'message': 'ancestor-child-2'}, ] commit_ids = backend.create_master_repo(commits) target = backend.create_repo(heads=['ancestor-child']) source = backend.create_repo(heads=['change']) response = self.app.post( url( controller='pullrequests', action='create', repo_name=source.repo_name), params={ 'source_repo': source.repo_name, 'source_ref': 'branch:default:' + commit_ids['change'], 'target_repo': target.repo_name, 'target_ref': 'branch:default:' + commit_ids['ancestor-child'], 'pullrequest_desc': 'Description', 'pullrequest_title': 'Title', 'review_members': '1', 'revisions': commit_ids['change'], 'user': '', 'csrf_token': csrf_token, }, status=302) location = response.headers['Location'] pull_request_id = int(location.rsplit('/', 1)[1]) pull_request = PullRequest.get(pull_request_id) # target_ref has to point to the ancestor's commit_id in order to # show the correct diff expected_target_ref = 'branch:default:' + commit_ids['ancestor'] assert pull_request.target_ref == expected_target_ref # Check generated diff contents response = response.follow() assert 'content_of_ancestor' not in response.body assert 'content_of_ancestor-child' not in response.body assert 'content_of_change' in response.body
def test_merge_pull_request_not_approved(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request(mergeable=True) pull_request_id = pull_request.pull_request_id repo_name = pull_request.target_repo.scm_instance().name, response = self.app.post( url(controller='pullrequests', action='merge', repo_name=str(repo_name[0]), pull_request_id=str(pull_request_id)), params={'csrf_token': csrf_token}).follow() pull_request = PullRequest.get(pull_request_id) assert response.status_int == 200 assert ' Reviewer approval is pending.' in response.body
def test_merge_pull_request_enabled(self, pr_util, csrf_token): # Clear any previous calls to rcextensions rhodecode.EXTENSIONS.calls.clear() pull_request = pr_util.create_pull_request( approved=True, mergeable=True) pull_request_id = pull_request.pull_request_id repo_name = pull_request.target_repo.scm_instance().name, response = self.app.post( url(controller='pullrequests', action='merge', repo_name=str(repo_name[0]), pull_request_id=str(pull_request_id)), params={'csrf_token': csrf_token}).follow() pull_request = PullRequest.get(pull_request_id) assert response.status_int == 200 assert pull_request.is_closed() assert_pull_request_status( pull_request, ChangesetStatus.STATUS_APPROVED) # Check the relevant log entries were added user_logs = UserLog.query().order_by('-user_log_id').limit(4) actions = [log.action for log in user_logs] pr_commit_ids = PullRequestModel()._get_commit_ids(pull_request) expected_actions = [ u'user_closed_pull_request:%d' % pull_request_id, u'user_merged_pull_request:%d' % pull_request_id, # The action below reflect that the post push actions were executed u'user_commented_pull_request:%d' % pull_request_id, u'push:%s' % ','.join(pr_commit_ids), ] assert actions == expected_actions # Check post_push rcextension was really executed push_calls = rhodecode.EXTENSIONS.calls['post_push'] assert len(push_calls) == 1 unused_last_call_args, last_call_kwargs = push_calls[0] assert last_call_kwargs['action'] == 'push' assert last_call_kwargs['pushed_revs'] == pr_commit_ids
def test_reject_and_close_pull_request(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id response = self.app.post( url(controller='pullrequests', action='update', repo_name=pull_request.target_repo.scm_instance().name, pull_request_id=str(pull_request.pull_request_id)), params={'close_pull_request': 'true', '_method': 'put', 'csrf_token': csrf_token}) pull_request = PullRequest.get(pull_request_id) assert response.json is True assert pull_request.is_closed() # check only the latest status, not the review status status = ChangesetStatusModel().get_status( pull_request.source_repo, pull_request=pull_request) assert status == ChangesetStatus.STATUS_REJECTED
def test_edit_title_description(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id response = self.app.post( url(controller='pullrequests', action='update', repo_name=pull_request.target_repo.repo_name, pull_request_id=str(pull_request_id)), params={ 'edit_pull_request': 'true', '_method': 'put', 'title': 'New title', 'description': 'New description', 'csrf_token': csrf_token}) assert_session_flash( response, u'Pull request title & description updated.', category='success') pull_request = PullRequest.get(pull_request_id) assert pull_request.title == 'New title' assert pull_request.description == 'New description'
def test_create_pull_request(self, backend, csrf_token): commits = [ {'message': 'ancestor'}, {'message': 'change'}, ] commit_ids = backend.create_master_repo(commits) target = backend.create_repo(heads=['ancestor']) source = backend.create_repo(heads=['change']) response = self.app.post( url( controller='pullrequests', action='create', repo_name=source.repo_name), params={ 'source_repo': source.repo_name, 'source_ref': 'branch:default:' + commit_ids['change'], 'target_repo': target.repo_name, 'target_ref': 'branch:default:' + commit_ids['ancestor'], 'pullrequest_desc': 'Description', 'pullrequest_title': 'Title', 'review_members': '1', 'revisions': commit_ids['change'], 'user': '', 'csrf_token': csrf_token, }, status=302) location = response.headers['Location'] pull_request_id = int(location.rsplit('/', 1)[1]) pull_request = PullRequest.get(pull_request_id) # check that we have now both revisions assert pull_request.revisions == [commit_ids['change']] assert pull_request.source_ref == 'branch:default:' + commit_ids['change'] expected_target_ref = 'branch:default:' + commit_ids['ancestor'] assert pull_request.target_ref == expected_target_ref