From 3ffb2e70c9696b8c5ce473e6a8257e009c25cfc8 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Feb 05 2018 15:04:31 +0000 Subject: Move the unit-tests for flagging PR to their own file and expand them This commit in addition to moving the old tests to their own file also restructures them so they do less and are better documented. It also add some tests for the notifications being sent when a project opts in to notification on PR flags. Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_api_fork.py b/tests/test_pagure_flask_api_fork.py index 5a4eb8c..b793a61 100644 --- a/tests/test_pagure_flask_api_fork.py +++ b/tests/test_pagure_flask_api_fork.py @@ -961,425 +961,6 @@ class PagureFlaskApiForktests(tests.Modeltests): self.session, project_id=1, requestid=1) self.assertEqual(len(request.comments), 1) - @patch('pagure.lib.notify.send_email') - def test_api_pull_request_add_flag(self, mockemail): - """ Test the api_pull_request_add_flag method of the flask api. """ - mockemail.return_value = True - - tests.create_projects(self.session) - tests.create_tokens(self.session) - tests.create_tokens_acl(self.session) - - headers = {'Authorization': 'token aaabbbcccddd'} - - # Invalid project - output = self.app.post( - '/api/0/foo/pull-request/1/flag', headers=headers) - self.assertEqual(output.status_code, 404) - data = json.loads(output.data) - self.assertDictEqual( - data, - { - "error": "Project not found", - "error_code": "ENOPROJECT", - } - ) - - # Valid token, wrong project - output = self.app.post( - '/api/0/test2/pull-request/1/flag', headers=headers) - self.assertEqual(output.status_code, 401) - data = json.loads(output.data) - self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.name, - data['error_code']) - self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error']) - - # No input - output = self.app.post( - '/api/0/test/pull-request/1/flag', headers=headers) - self.assertEqual(output.status_code, 404) - data = json.loads(output.data) - self.assertDictEqual( - data, - { - "error": "Pull-Request not found", - "error_code": "ENOREQ", - } - ) - - # Create a pull-request - repo = pagure.lib.get_authorized_project(self.session, 'test') - forked_repo = pagure.lib.get_authorized_project(self.session, 'test') - req = pagure.lib.new_pull_request( - session=self.session, - repo_from=forked_repo, - branch_from='master', - repo_to=repo, - branch_to='master', - title='test pull-request', - user='pingou', - requestfolder=None, - ) - self.session.commit() - self.assertEqual(req.id, 1) - self.assertEqual(req.title, 'test pull-request') - - # Check comments before - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 0) - - data = { - 'username': 'Jenkins', - 'percent': 100, - 'url': 'http://jenkins.cloud.fedoraproject.org/', - 'uid': 'jenkins_build_pagure_100+seed', - } - - # Incomplete request - output = self.app.post( - '/api/0/test/pull-request/1/flag', data=data, headers=headers) - self.assertEqual(output.status_code, 400) - data = json.loads(output.data) - self.assertDictEqual( - data, - { - "error": "Invalid or incomplete input submitted", - "error_code": "EINVALIDREQ", - "errors": {"comment": ["This field is required."]} - } - ) - - # No change - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 0) - - data = { - 'username': 'Jenkins', - 'comment': 'Tests running', - 'url': 'http://jenkins.cloud.fedoraproject.org/', - 'uid': 'jenkins_build_pagure_100+seed', - } - - # Valid request - output = self.app.post( - '/api/0/test/pull-request/1/flag', data=data, headers=headers) - self.assertEqual(output.status_code, 200) - data = json.loads(output.data) - data['flag']['date_created'] = u'1510742565' - data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' - self.assertDictEqual( - data, - { - u'flag': { - u'comment': u'Tests running', - u'date_created': u'1510742565', - u'percent': None, - u'pull_request_uid': u'62b49f00d489452994de5010565fab81', - u'status': u'pending', - u'url': u'http://jenkins.cloud.fedoraproject.org/', - u'user': { - u'default_email': u'bar@pingou.com', - u'emails': [u'bar@pingou.com', u'foo@pingou.com'], - u'fullname': u'PY C', - u'name': u'pingou'}, - u'username': u'Jenkins'}, - u'message': u'Flag added', - u'uid': u'jenkins_build_pagure_100+seed' - } - ) - - # One flag added - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 1) - self.assertEqual(request.flags[0].comment, 'Tests running') - self.assertEqual(request.flags[0].percent, None) - - # Update flag - w/o providing the status - data = { - 'username': 'Jenkins', - 'percent': 100, - 'comment': 'Tests passed', - 'url': 'http://jenkins.cloud.fedoraproject.org/', - 'uid': 'jenkins_build_pagure_100+seed', - } - - output = self.app.post( - '/api/0/test/pull-request/1/flag', data=data, headers=headers) - self.assertEqual(output.status_code, 200) - data = json.loads(output.data) - data['flag']['date_created'] = u'1510742565' - data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' - self.assertDictEqual( - data, - { - u'flag': { - u'comment': u'Tests passed', - u'date_created': u'1510742565', - u'percent': 100, - u'pull_request_uid': u'62b49f00d489452994de5010565fab81', - u'status': u'success', - u'url': u'http://jenkins.cloud.fedoraproject.org/', - u'user': { - u'default_email': u'bar@pingou.com', - u'emails': [u'bar@pingou.com', u'foo@pingou.com'], - u'fullname': u'PY C', - u'name': u'pingou'}, - u'username': u'Jenkins'}, - u'message': u'Flag updated', - u'uid': u'jenkins_build_pagure_100+seed' - } - ) - - # One flag added - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 1) - self.assertEqual(request.flags[0].comment, 'Tests passed') - self.assertEqual(request.flags[0].percent, 100) - - data = { - 'username': 'Jenkins', - 'comment': 'Tests running again', - 'url': 'http://jenkins.cloud.fedoraproject.org/', - } - - # Valid request - output = self.app.post( - '/api/0/test/pull-request/1/flag', data=data, headers=headers) - self.assertEqual(output.status_code, 200) - data = json.loads(output.data) - data['flag']['date_created'] = u'1510742565' - data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' - self.assertNotEqual( - data['uid'], 'jenkins_build_pagure_100+seed') - data['uid'] = 'jenkins_build_pagure_100+seed' - self.assertDictEqual( - data, - { - u'flag': { - u'comment': u'Tests running again', - u'date_created': u'1510742565', - u'percent': None, - u'pull_request_uid': u'62b49f00d489452994de5010565fab81', - u'status': u'pending', - u'url': u'http://jenkins.cloud.fedoraproject.org/', - u'user': { - u'default_email': u'bar@pingou.com', - u'emails': [u'bar@pingou.com', u'foo@pingou.com'], - u'fullname': u'PY C', - u'name': u'pingou'}, - u'username': u'Jenkins'}, - u'message': u'Flag added', - u'uid': u'jenkins_build_pagure_100+seed' - } - ) - - # Two flag added - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 2) - self.assertEqual(request.flags[0].comment, 'Tests passed') - self.assertEqual(request.flags[0].percent, 100) - self.assertEqual(request.flags[1].comment, 'Tests running again') - self.assertEqual(request.flags[1].percent, None) - - @patch('pagure.lib.notify.send_email') - def test_api_pull_request_add_flag_user_token(self, mockemail): - """ Test the api_pull_request_add_flag method of the flask api. """ - mockemail.return_value = True - - tests.create_projects(self.session) - tests.create_tokens(self.session, project_id=None) - tests.create_tokens_acl(self.session) - - headers = {'Authorization': 'token aaabbbcccddd'} - - # Invalid project - output = self.app.post( - '/api/0/foo/pull-request/1/flag', headers=headers) - self.assertEqual(output.status_code, 404) - data = json.loads(output.data) - self.assertDictEqual( - data, - { - "error": "Project not found", - "error_code": "ENOPROJECT", - } - ) - - # Valid token, wrong project - output = self.app.post( - '/api/0/test2/pull-request/1/flag', headers=headers) - self.assertEqual(output.status_code, 404) - data = json.loads(output.data) - self.assertDictEqual( - data, - { - "error": "Pull-Request not found", - "error_code": "ENOREQ", - } - ) - - # No input - output = self.app.post( - '/api/0/test/pull-request/1/flag', headers=headers) - self.assertEqual(output.status_code, 404) - data = json.loads(output.data) - self.assertDictEqual( - data, - { - "error": "Pull-Request not found", - "error_code": "ENOREQ", - } - ) - - # Create a pull-request - repo = pagure.lib.get_authorized_project(self.session, 'test') - forked_repo = pagure.lib.get_authorized_project(self.session, 'test') - req = pagure.lib.new_pull_request( - session=self.session, - repo_from=forked_repo, - branch_from='master', - repo_to=repo, - branch_to='master', - title='test pull-request', - user='pingou', - requestfolder=None, - ) - self.session.commit() - self.assertEqual(req.id, 1) - self.assertEqual(req.title, 'test pull-request') - - # Check comments before - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 0) - - data = { - 'username': 'Jenkins', - 'percent': 100, - 'url': 'http://jenkins.cloud.fedoraproject.org/', - 'uid': 'jenkins_build_pagure_100+seed', - } - - # Incomplete request - output = self.app.post( - '/api/0/test/pull-request/1/flag', data=data, headers=headers) - self.assertEqual(output.status_code, 400) - data = json.loads(output.data) - self.assertDictEqual( - data, - { - "error": "Invalid or incomplete input submitted", - "error_code": "EINVALIDREQ", - "errors": {"comment": ["This field is required."]} - } - ) - - # No change - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 0) - - data = { - 'username': 'Jenkins', - 'percent': 0, - 'comment': 'Tests failed', - 'url': 'http://jenkins.cloud.fedoraproject.org/', - 'uid': 'jenkins_build_pagure_100+seed', - } - - # Valid request - w/o providing the status - output = self.app.post( - '/api/0/test/pull-request/1/flag', data=data, headers=headers) - self.assertEqual(output.status_code, 200) - data = json.loads(output.data) - data['flag']['date_created'] = u'1510742565' - data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' - self.assertDictEqual( - data, - { - u'flag': { - u'comment': u'Tests failed', - u'date_created': u'1510742565', - u'percent': 0, - u'pull_request_uid': u'62b49f00d489452994de5010565fab81', - u'status': u'failure', - u'url': u'http://jenkins.cloud.fedoraproject.org/', - u'user': { - u'default_email': u'bar@pingou.com', - u'emails': [u'bar@pingou.com', u'foo@pingou.com'], - u'fullname': u'PY C', - u'name': u'pingou'}, - u'username': u'Jenkins'}, - u'message': u'Flag added', - u'uid': u'jenkins_build_pagure_100+seed' - } - ) - - # One flag added - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 1) - self.assertEqual(request.flags[0].comment, 'Tests failed') - self.assertEqual(request.flags[0].percent, 0) - - # Update flag - data = { - 'username': 'Jenkins', - 'percent': 100, - 'comment': 'Tests passed', - 'url': 'http://jenkins.cloud.fedoraproject.org/', - 'uid': 'jenkins_build_pagure_100+seed', - 'status': 'success', - } - - output = self.app.post( - '/api/0/test/pull-request/1/flag', data=data, headers=headers) - self.assertEqual(output.status_code, 200) - data = json.loads(output.data) - data['flag']['date_created'] = u'1510742565' - data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' - self.assertDictEqual( - data, - { - u'flag': { - u'comment': u'Tests passed', - u'date_created': u'1510742565', - u'percent': 100, - u'pull_request_uid': u'62b49f00d489452994de5010565fab81', - u'status': u'success', - u'url': u'http://jenkins.cloud.fedoraproject.org/', - u'user': { - u'default_email': u'bar@pingou.com', - u'emails': [u'bar@pingou.com', u'foo@pingou.com'], - u'fullname': u'PY C', - u'name': u'pingou'}, - u'username': u'Jenkins'}, - u'message': u'Flag updated', - u'uid': u'jenkins_build_pagure_100+seed' - } - ) - - # One flag added - self.session = pagure.lib.create_session(self.dbpath) - request = pagure.lib.search_pull_requests( - self.session, project_id=1, requestid=1) - self.assertEqual(len(request.flags), 1) - self.assertEqual(request.flags[0].comment, 'Tests passed') - self.assertEqual(request.flags[0].percent, 100) - @patch('pagure.lib.git.update_git') @patch('pagure.lib.notify.send_email') def test_api_subscribe_pull_request(self, p_send_email, p_ugt): diff --git a/tests/test_pagure_flask_api_pr_flag.py b/tests/test_pagure_flask_api_pr_flag.py new file mode 100644 index 0000000..d711e8e --- /dev/null +++ b/tests/test_pagure_flask_api_pr_flag.py @@ -0,0 +1,744 @@ +# -*- coding: utf-8 -*- + +""" + (c) 2018 - Copyright Red Hat Inc + + Authors: + Pierre-Yves Chibon + +""" + +import unittest +import sys +import os + +import json +from mock import patch, MagicMock + +sys.path.insert(0, os.path.join(os.path.dirname( + os.path.abspath(__file__)), '..')) + +import pagure # noqa +import pagure.lib # noqa +import tests # noqa + + +class PagureFlaskApiPRFlagtests(tests.Modeltests): + """ Tests for the flask API of pagure for flagging pull-requests """ + + maxDiff = None + + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) + def setUp(self): + """ Set up the environnment, ran before every tests. """ + super(PagureFlaskApiPRFlagtests, self).setUp() + + pagure.config.config['REQUESTS_FOLDER'] = None + + tests.create_projects(self.session) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Create a pull-request + repo = pagure.lib.get_authorized_project(self.session, 'test') + forked_repo = pagure.lib.get_authorized_project(self.session, 'test') + req = pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='test pull-request', + user='pingou', + requestfolder=None, + ) + self.session.commit() + self.assertEqual(req.id, 1) + self.assertEqual(req.title, 'test pull-request') + + # Check flags before + # self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 0) + + def test_invalid_project(self): + """ Test the flagging a PR on an invalid project. """ + + headers = {'Authorization': 'token aaabbbcccddd'} + + # Invalid project + output = self.app.post( + '/api/0/foo/pull-request/1/flag', headers=headers) + self.assertEqual(output.status_code, 404) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + "error": "Project not found", + "error_code": "ENOPROJECT", + } + ) + + def test_incorrect_project(self): + """ Test the flagging a PR on the wrong project. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + # Valid token, wrong project + output = self.app.post( + '/api/0/test2/pull-request/1/flag', headers=headers) + self.assertEqual(output.status_code, 401) + data = json.loads(output.data) + self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.name, + data['error_code']) + self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error']) + + def test_no_pr(self): + """ Test the flagging a PR when the PR doesn't exist. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + # No PR + output = self.app.post( + '/api/0/test/pull-request/10/flag', headers=headers) + self.assertEqual(output.status_code, 404) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + "error": "Pull-Request not found", + "error_code": "ENOREQ", + } + ) + + def test_no_input(self): + """ Test the flagging an existing PR but with no data. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + # No input + output = self.app.post( + '/api/0/test/pull-request/1/flag', headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + u'error': u'Invalid or incomplete input submitted', + u'error_code': u'EINVALIDREQ', + u'errors': { + u'comment': [u'This field is required.'], + u'url': [u'This field is required.'], + u'username': [u'This field is required.'] + } + } + ) + + def test_no_comment(self): + """ Test the flagging an existing PR but with incomplete data. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'username': 'Jenkins', + 'percent': 100, + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Incomplete request + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + "error": "Invalid or incomplete input submitted", + "error_code": "EINVALIDREQ", + "errors": {"comment": ["This field is required."]} + } + ) + + # No change + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 0) + + @patch('pagure.lib.notify.send_email') + def test_flagging_a_pul_request_with_notification(self, mock_email): + """ Test the flagging a PR. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + # Enable PR notifications + repo = pagure.lib.get_authorized_project(self.session, 'test') + settings = repo.settings + settings['notify_on_pull-request_flag'] = True + repo.settings = settings + self.session.add(repo) + self.session.commit() + + data = { + 'username': 'Jenkins', + 'comment': 'Tests running', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Valid request + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + pr_uid = data['flag']['pull_request_uid'] + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests running', + u'date_created': u'1510742565', + u'percent': None, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'pending', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag added', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # One flag added + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 1) + self.assertEqual(request.flags[0].comment, 'Tests running') + self.assertEqual(request.flags[0].percent, None) + + # Check the notification sent + mock_email.assert_called_once_with( + u'\nJenkins flagged the pull-request `test pull-request` ' + u'as pending: Tests running\n\n' + u'https://pagure.org/test/pull-request/1\n', + u'PR #1 - Jenkins: pending', + u'bar@pingou.com', + in_reply_to=u'test-pull-request-' + pr_uid, + mail_id=u'test-pull-request-' + pr_uid + '-1', + project_name=u'test', + user_from=u'Jenkins' + ) + + def test_updating_flag(self): + """ Test the updating the flag of a PR. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'username': 'Jenkins', + 'comment': 'Tests running', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Valid request + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests running', + u'date_created': u'1510742565', + u'percent': None, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'pending', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag added', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # One flag added + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 1) + self.assertEqual(request.flags[0].comment, 'Tests running') + self.assertEqual(request.flags[0].percent, None) + + # Update flag - w/o providing the status + data = { + 'username': 'Jenkins', + 'percent': 100, + 'comment': 'Tests passed', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests passed', + u'date_created': u'1510742565', + u'percent': 100, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'success', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag updated', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # One flag added + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 1) + self.assertEqual(request.flags[0].comment, 'Tests passed') + self.assertEqual(request.flags[0].percent, 100) + + def test_adding_two_flags(self): + """ Test the adding two flags to a PR. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'username': 'Jenkins', + 'comment': 'Tests passed', + 'status': 'success', + 'percent': '100', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Valid request + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests passed', + u'date_created': u'1510742565', + u'percent': 100, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'success', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag added', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # One flag added + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 1) + self.assertEqual(request.flags[0].comment, 'Tests passed') + self.assertEqual(request.flags[0].percent, 100) + + data = { + 'username': 'Jenkins', + 'comment': 'Tests running again', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + } + + # Valid request + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertNotEqual( + data['uid'], 'jenkins_build_pagure_100+seed') + data['uid'] = 'jenkins_build_pagure_100+seed' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests running again', + u'date_created': u'1510742565', + u'percent': None, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'pending', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag added', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # Two flag added + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 2) + self.assertEqual(request.flags[0].comment, 'Tests passed') + self.assertEqual(request.flags[0].percent, 100) + self.assertEqual(request.flags[1].comment, 'Tests running again') + self.assertEqual(request.flags[1].percent, None) + + +class PagureFlaskApiPRFlagUserTokentests(tests.Modeltests): + """ Tests for the flask API of pagure for flagging pull-requests using + an user token (ie: not restricted to a specific project). + """ + + maxDiff = None + + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) + def setUp(self): + """ Set up the environnment, ran before every tests. """ + super(PagureFlaskApiPRFlagUserTokentests, self).setUp() + + pagure.config.config['REQUESTS_FOLDER'] = None + + tests.create_projects(self.session) + tests.create_tokens(self.session, project_id=None) + tests.create_tokens_acl(self.session) + + # Create a pull-request + repo = pagure.lib.get_authorized_project(self.session, 'test') + forked_repo = pagure.lib.get_authorized_project(self.session, 'test') + req = pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='test pull-request', + user='pingou', + requestfolder=None, + ) + self.session.commit() + self.assertEqual(req.id, 1) + self.assertEqual(req.title, 'test pull-request') + + # Check flags before + # self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 0) + + def test_no_pr(self): + """ Test flagging a non-existing PR. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + # Invalid project + output = self.app.post( + '/api/0/foo/pull-request/1/flag', headers=headers) + self.assertEqual(output.status_code, 404) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + "error": "Project not found", + "error_code": "ENOPROJECT", + } + ) + + def test_no_pr_other_project(self): + """ Test flagging a non-existing PR on a different project. """ + headers = {'Authorization': 'token aaabbbcccddd'} + # Valid token, wrong project + output = self.app.post( + '/api/0/test2/pull-request/1/flag', headers=headers) + self.assertEqual(output.status_code, 404) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + "error": "Pull-Request not found", + "error_code": "ENOREQ", + } + ) + + def test_no_input(self): + """ Test flagging an existing PR but without submitting any data. """ + headers = {'Authorization': 'token aaabbbcccddd'} + + # No input + output = self.app.post( + '/api/0/test/pull-request/1/flag', headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + u'error': u'Invalid or incomplete input submitted', + u'error_code': u'EINVALIDREQ', + u'errors': { + u'comment': [u'This field is required.'], + u'url': [u'This field is required.'], + u'username': [u'This field is required.'] + } + } + ) + + def test_no_comment(self): + """ Test flagging an existing PR but without all the required info. + """ + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'username': 'Jenkins', + 'percent': 100, + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Incomplete request + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + "error": "Invalid or incomplete input submitted", + "error_code": "EINVALIDREQ", + "errors": {"comment": ["This field is required."]} + } + ) + + # No change + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 0) + + def test_invalid_status(self): + """ Test flagging an existing PR but with an invalid status. + """ + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'username': 'Jenkins', + 'status': 'failed', + 'comment': 'Failed to run the tests', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Invalid status submitted + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.data) + self.assertDictEqual( + data, + { + "error": "Invalid or incomplete input submitted", + "error_code": "EINVALIDREQ", + "errors": {"status": ["Not a valid choice"]} + } + ) + + # No change + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 0) + + @patch('pagure.lib.notify.send_email') + def test_flag_pr_no_status(self, mock_email): + """ Test flagging an existing PR without providing a status. + + Also check that no notifications have been sent. + """ + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'username': 'Jenkins', + 'percent': 0, + 'comment': 'Tests failed', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Valid request - w/o providing the status + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests failed', + u'date_created': u'1510742565', + u'percent': 0, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'failure', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag added', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # One flag added + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 1) + self.assertEqual(request.flags[0].comment, 'Tests failed') + self.assertEqual(request.flags[0].percent, 0) + + # no notifications sent + mock_email.assert_not_called() + + def test_editing_flag(self): + """ Test flagging an existing PR without providing a status. + """ + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'username': 'Jenkins', + 'status': 'failure', + 'comment': 'Tests failed', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + } + + # Valid request - w/o providing the status + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests failed', + u'date_created': u'1510742565', + u'percent': None, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'failure', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag added', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # One flag added + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 1) + self.assertEqual(request.flags[0].comment, 'Tests failed') + self.assertEqual(request.flags[0].percent, None) + + # Update flag + data = { + 'username': 'Jenkins', + 'percent': 100, + 'comment': 'Tests passed', + 'url': 'http://jenkins.cloud.fedoraproject.org/', + 'uid': 'jenkins_build_pagure_100+seed', + 'status': 'success', + } + + output = self.app.post( + '/api/0/test/pull-request/1/flag', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + data['flag']['date_created'] = u'1510742565' + data['flag']['pull_request_uid'] = u'62b49f00d489452994de5010565fab81' + self.assertDictEqual( + data, + { + u'flag': { + u'comment': u'Tests passed', + u'date_created': u'1510742565', + u'percent': 100, + u'pull_request_uid': u'62b49f00d489452994de5010565fab81', + u'status': u'success', + u'url': u'http://jenkins.cloud.fedoraproject.org/', + u'user': { + u'default_email': u'bar@pingou.com', + u'emails': [u'bar@pingou.com', u'foo@pingou.com'], + u'fullname': u'PY C', + u'name': u'pingou' + }, + u'username': u'Jenkins'}, + u'message': u'Flag updated', + u'uid': u'jenkins_build_pagure_100+seed' + } + ) + + # Still only one flag + self.session = pagure.lib.create_session(self.dbpath) + request = pagure.lib.search_pull_requests( + self.session, project_id=1, requestid=1) + self.assertEqual(len(request.flags), 1) + self.assertEqual(request.flags[0].comment, 'Tests passed') + self.assertEqual(request.flags[0].percent, 100) + + +if __name__ == '__main__': + unittest.main(verbosity=2)