diff --git a/pagure/api/__init__.py b/pagure/api/__init__.py index 45eabcc..8a0eccd 100644 --- a/pagure/api/__init__.py +++ b/pagure/api/__init__.py @@ -90,6 +90,7 @@ class APIERROR(enum.Enum): "This request does not have the minimum review score " "necessary to be merged" ) + EPRCONFLICTS = "This pull-request conflicts and thus cannot be merged" ENOTASSIGNEE = "Only the assignee can merge this review" ENOTASSIGNED = "This request must be assigned to be merged" ENOUSER = "No such user found" diff --git a/pagure/api/fork.py b/pagure/api/fork.py index 0f563d9..e0b09c3 100644 --- a/pagure/api/fork.py +++ b/pagure/api/fork.py @@ -498,8 +498,13 @@ def api_pull_request_merge(repo, requestid, username=None, namespace=None): output = {"message": "Merging queued", "taskid": task.id} if get_request_data().get("wait", True): - task.get() - output = {"message": "Changes merged!"} + try: + task.get() + output = {"message": "Changes merged!"} + except pagure.exceptions.PagureException: + raise pagure.exceptions.APIError( + 409, error_code=APIERROR.EPRCONFLICTS + ) jsonout = flask.jsonify(output) return jsonout diff --git a/tests/test_pagure_flask_api.py b/tests/test_pagure_flask_api.py index 1467746..2a3e81e 100644 --- a/tests/test_pagure_flask_api.py +++ b/tests/test_pagure_flask_api.py @@ -235,7 +235,7 @@ class PagureFlaskApitests(tests.SimplePagureTest): output = self.app.get('/api/0/-/error_codes') self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) - self.assertEqual(len(data), 33) + self.assertEqual(len(data), 34) self.assertEqual( sorted(data.keys()), [ @@ -248,8 +248,9 @@ class PagureFlaskApitests(tests.SimplePagureTest): u'ENOISSUE', u'ENOPRCLOSE', u'ENOPROJECT', u'ENOPROJECTS', u'ENOPRSTATS', u'ENOREQ', u'ENOSIGNEDOFF', u'ENOTASSIGNED', u'ENOTASSIGNEE', u'ENOTHIGHENOUGH', u'ENOTMAINADMIN', - u'ENOUSER', u'EPRSCORE', u'EPULLREQUESTSDISABLED', - u'ETIMESTAMP', u'ETRACKERDISABLED', u'ETRACKERREADONLY' + u'ENOUSER', u'EPRCONFLICTS', u'EPRSCORE', + u'EPULLREQUESTSDISABLED', u'ETIMESTAMP', u'ETRACKERDISABLED', + u'ETRACKERREADONLY' ] ) diff --git a/tests/test_pagure_flask_api_fork.py b/tests/test_pagure_flask_api_fork.py index 90a68bb..4aceb60 100644 --- a/tests/test_pagure_flask_api_fork.py +++ b/tests/test_pagure_flask_api_fork.py @@ -1370,6 +1370,81 @@ class PagureFlaskApiForktests(tests.Modeltests): ) @patch('pagure.lib.notify.send_email') + def test_api_pull_request_merge_conflicting(self, send_email): + """ Test the api_pull_request_merge method of the flask api. """ + send_email.return_value = True + + tests.create_projects(self.session) + tests.add_content_git_repo( + os.path.join(self.path, "repos", "test.git")) + + # Fork + project = pagure.lib.query.get_authorized_project( + self.session, 'test') + task = pagure.lib.query.fork_project( + session=self.session, + user='pingou', + repo=project, + ) + self.session.commit() + self.assertEqual( + task.get(), + {'endpoint': 'ui_ns.view_repo', + 'repo': 'test', + 'namespace': None, + 'username': 'pingou'}) + + # Add content to the fork + tests.add_content_to_git( + os.path.join(self.path, "repos", "forks", "pingou", "test.git"), + filename="foobar", content="content from the fork") + + # Add content to the main repo, so they conflict + tests.add_content_to_git( + os.path.join(self.path, "repos", "test.git"), + filename="foobar", content="content from the main repo") + + project = pagure.lib.query.get_authorized_project( + self.session, 'test') + fork = pagure.lib.query.get_authorized_project( + self.session, + 'test', + user='pingou', + ) + + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Create the pull-request to close + req = pagure.lib.query.new_pull_request( + session=self.session, + repo_from=fork, + branch_from='master', + repo_to=project, + branch_to='master', + title='test pull-request', + user='pingou', + ) + self.session.commit() + self.assertEqual(req.id, 1) + self.assertEqual(req.title, 'test pull-request') + + headers = {'Authorization': 'token aaabbbcccddd'} + + # Merge PR + output = self.app.post( + '/api/0/test/pull-request/1/merge', headers=headers) + self.assertEqual(output.status_code, 409) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + 'error': 'This pull-request conflicts and thus cannot be merged', + 'error_code': 'EPRCONFLICTS' + } + ) + + @patch('pagure.lib.notify.send_email') def test_api_pull_request_merge_user_token(self, send_email): """ Test the api_pull_request_merge method of the flask api. """ send_email.return_value = True