From d86db98e887e7526706dd55cf26096540254f268 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 1/15] Improve tests to include a close_status Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_api_issue_change_status.py b/tests/test_pagure_flask_api_issue_change_status.py index 20712c5..e6bd732 100644 --- a/tests/test_pagure_flask_api_issue_change_status.py +++ b/tests/test_pagure_flask_api_issue_change_status.py @@ -29,6 +29,7 @@ sys.path.insert(0, os.path.join(os.path.dirname( import pagure import pagure.lib +import pagure.lib.model import tests @@ -205,6 +206,7 @@ class PagureFlaskApiIssueChangeStatustests(tests.Modeltests): issue = pagure.lib.search_issues(self.session, repo, issueid=1) self.assertEqual(issue.status, 'Open') + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) def test_api_change_status_issue(self): """ Test the api_change_status_issue method of the flask api. """ @@ -241,6 +243,38 @@ class PagureFlaskApiIssueChangeStatustests(tests.Modeltests): self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error']) @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) + def test_api_change_status_issue_closed_status(self): + """ Test the api_change_status_issue method of the flask api. """ + repo = pagure.lib.get_authorized_project(self.session, 'test') + close_status = repo.close_status + close_status = ['Fixed', 'Upstream', 'Invalid'] + repo.close_status = close_status + self.session.add(repo) + self.session.commit() + + + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'status': 'Closed', + 'close_status': 'Fixed' + } + + # Valid request + output = self.app.post( + '/api/0/test/issue/1/status', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.get_data(as_text=True)) + + self.assertDictEqual( + data, + {'message':[ + 'Issue status updated to: Closed (was: Open)', + 'Issue close_status updated to: Fixed' + ]} + ) + + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) def test_api_change_status_issue_no_ticket_project_less(self): """ Test the api_change_status_issue method of the flask api. """ From 9a16eb6fe553a9a98632999eef9cf073aa581160 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 2/15] Add test when api_change_status raises an exception Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_api_issue_change_status.py b/tests/test_pagure_flask_api_issue_change_status.py index e6bd732..1a4542a 100644 --- a/tests/test_pagure_flask_api_issue_change_status.py +++ b/tests/test_pagure_flask_api_issue_change_status.py @@ -206,6 +206,37 @@ class PagureFlaskApiIssueChangeStatustests(tests.Modeltests): issue = pagure.lib.search_issues(self.session, repo, issueid=1) self.assertEqual(issue.status, 'Open') + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) + @patch( + 'pagure.lib.edit_issue', + MagicMock(side_effect=pagure.exceptions.PagureException('error'))) + def test_api_change_status_issue_raise_error(self): + """ Test the api_change_status_issue method of the flask api. """ + repo = pagure.lib.get_authorized_project(self.session, 'test') + close_status = repo.close_status + close_status = ['Fixed', 'Upstream', 'Invalid'] + repo.close_status = close_status + self.session.add(repo) + self.session.commit() + + + headers = {'Authorization': 'token aaabbbcccddd'} + + data = { + 'status': 'Closed', + 'close_status': 'Fixed' + } + + # Valid request + output = self.app.post( + '/api/0/test/issue/1/status', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.get_data(as_text=True)) + + self.assertDictEqual( + data, + {u'error': u'error', u'error_code': u'ENOCODE'} + ) @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) def test_api_change_status_issue(self): From d00a9e8f5112cc892acf9796ffd818e1112aaae7 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 3/15] Simplify code checking for a milestone Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/api/issue.py b/pagure/api/issue.py index 49a239b..7a11a89 100644 --- a/pagure/api/issue.py +++ b/pagure/api/issue.py @@ -878,9 +878,7 @@ def api_change_milestone_issue(repo, issueid, username=None, namespace=None): csrf_enabled=False) if form.validate_on_submit(): - new_milestone = form.milestone.data - if new_milestone == '': - new_milestone = None # unset milestone + new_milestone = form.milestone.data or None try: # Update status message = pagure.lib.edit_issue( From 0bc20d93f3610dcb06d575b8b59e78227f050f20 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 4/15] Restructure the tests for the api_change_milestone endpoint Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_api_issue.py b/tests/test_pagure_flask_api_issue.py index 4efc4f2..a32a8b7 100644 --- a/tests/test_pagure_flask_api_issue.py +++ b/tests/test_pagure_flask_api_issue.py @@ -2265,7 +2265,7 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): } ) - def test_api_change_milestone_issue(self): + def test_api_change_milestone_issue_invalid_project(self): """ Test the api_change_milestone_issue method of the flask api. """ tests.create_projects(self.session) tests.create_projects_git(os.path.join(self.path, 'tickets')) @@ -2292,6 +2292,21 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): } ) + def test_api_change_milestone_issue_wrong_token(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # Valid token, wrong project output = self.app.post('/api/0/test2/issue/1/milestone', headers=headers) self.assertEqual(output.status_code, 401) @@ -2302,6 +2317,21 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): self.assertEqual( pagure.api.APIERROR.EINVALIDTOK.name, data['error_code']) + def test_api_change_milestone_issue_no_issue(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # No issue output = self.app.post('/api/0/test/issue/1/milestone', headers=headers) self.assertEqual(output.status_code, 404) @@ -2314,6 +2344,20 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): } ) + def test_api_change_milestone_issue_no_milestone(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} # Create normal issue repo = pagure.lib.get_authorized_project(self.session, 'test') msg = pagure.lib.new_issue( @@ -2352,6 +2396,39 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): issue = pagure.lib.search_issues(self.session, repo, issueid=1) self.assertEqual(issue.milestone, None) + def test_api_change_milestone_issue_invalid_milestone(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # Create normal issue + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.new_issue( + session=self.session, + repo=repo, + title='Test issue #1', + content='We should work on this', + user='pingou', + ticketfolder=None, + private=False, + ) + self.session.commit() + self.assertEqual(msg.title, 'Test issue #1') + + # Check milestone before + repo = pagure.lib.get_authorized_project(self.session, 'test') + issue = pagure.lib.search_issues(self.session, repo, issueid=1) + self.assertEqual(issue.milestone, None) + data = { 'milestone': 'milestone-1-0', } @@ -2374,6 +2451,90 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): } ) + def test_api_change_milestone_issue(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # Create normal issue + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.new_issue( + session=self.session, + repo=repo, + title='Test issue #1', + content='We should work on this', + user='pingou', + ticketfolder=None, + private=False, + ) + self.session.commit() + self.assertEqual(msg.title, 'Test issue #1') + + # Check milestone before + repo = pagure.lib.get_authorized_project(self.session, 'test') + issue = pagure.lib.search_issues(self.session, repo, issueid=1) + self.assertEqual(issue.milestone, None) + + data = { + 'milestone': 'v1.0', + } + + # Valid requests + output = self.app.post( + '/api/0/test/issue/1/milestone', data=data, headers=headers) + self.assertEqual(output.status_code, 200) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "message": [ + "Issue set to the milestone: v1.0" + ] + } + ) + + def test_api_change_milestone_issue_remove_milestone(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # Create normal issue + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.new_issue( + session=self.session, + repo=repo, + title='Test issue #1', + content='We should work on this', + user='pingou', + ticketfolder=None, + private=False, + ) + self.session.commit() + self.assertEqual(msg.title, 'Test issue #1') + + # Check milestone before + repo = pagure.lib.get_authorized_project(self.session, 'test') + issue = pagure.lib.search_issues(self.session, repo, issueid=1) + self.assertEqual(issue.milestone, None) + data = { 'milestone': 'v1.0', } @@ -2416,6 +2577,39 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): issue = pagure.lib.search_issues(self.session, repo, issueid=1) self.assertEqual(issue.milestone, None) + def test_api_change_milestone_issue_remove_milestone2(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # Create normal issue + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.new_issue( + session=self.session, + repo=repo, + title='Test issue #1', + content='We should work on this', + user='pingou', + ticketfolder=None, + private=False, + ) + self.session.commit() + self.assertEqual(msg.title, 'Test issue #1') + + # Check milestone before + repo = pagure.lib.get_authorized_project(self.session, 'test') + issue = pagure.lib.search_issues(self.session, repo, issueid=1) + self.assertEqual(issue.milestone, None) + data = { 'milestone': 'v1.0', } @@ -2456,11 +2650,40 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): issue = pagure.lib.search_issues(self.session, repo, issueid=1) self.assertEqual(issue.milestone, None) + def test_api_change_milestone_issue_unauthorized(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # Create normal issue + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.new_issue( + session=self.session, + repo=repo, + title='Test issue #1', + content='We should work on this', + user='pingou', + ticketfolder=None, + private=False, + ) + self.session.commit() + self.assertEqual(msg.title, 'Test issue #1') + headers = {'Authorization': 'token pingou_foo'} + data = {'milestone': 'v1.0',} # Un-authorized issue output = self.app.post( - '/api/0/foo/issue/1/milestone', data=data, headers=headers) + '/api/0/foo/issue/1/milestone', data={}, headers=headers) self.assertEqual(output.status_code, 401) data = json.loads(output.get_data(as_text=True)) self.assertEqual(sorted(data.keys()), ['error', 'error_code']) From 51514cf5f64ce0d7a8b5c83b72aec98bb69bcc7d Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 5/15] Add more tests for the api_change_milestone_issue API method Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_api_issue.py b/tests/test_pagure_flask_api_issue.py index a32a8b7..f5ee7d0 100644 --- a/tests/test_pagure_flask_api_issue.py +++ b/tests/test_pagure_flask_api_issue.py @@ -2692,6 +2692,52 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): self.assertEqual( pagure.api.APIERROR.EINVALIDTOK.name, data['error_code']) + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) + @patch( + 'pagure.lib.add_metadata_update_notif', + MagicMock(side_effect=pagure.exceptions.PagureException('error'))) + def test_api_change_milestone_issue_raises_exception(self): + """ Test the api_change_milestone_issue method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + # Set some milestones to the project + repo = pagure.lib.get_authorized_project(self.session, 'test') + repo.milestones = {'v1.0': None, 'v2.0': 'Soon'} + self.session.add(repo) + self.session.commit() + + headers = {'Authorization': 'token aaabbbcccddd'} + # Create normal issue + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.new_issue( + session=self.session, + repo=repo, + title='Test issue #1', + content='We should work on this', + user='pingou', + ticketfolder=None, + private=False, + ) + self.session.commit() + self.assertEqual(msg.title, 'Test issue #1') + + data = { + 'milestone': 'v1.0', + } + + # Valid requests + output = self.app.post( + '/api/0/test/issue/1/milestone', data=data, headers=headers) + self.assertEqual(output.status_code, 400) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + {u'error': u'error', u'error_code': u'ENOCODE'} + ) + @patch('pagure.lib.git.update_git') @patch('pagure.lib.notify.send_email') def test_api_view_issue_comment(self, p_send_email, p_ugt): From ce02c2b3c3c354d9f972166f6eddcadba6089134 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 6/15] Add tests for the no new branch hook Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_ui_plugins_pagure_no_new_branch.py b/tests/test_pagure_flask_ui_plugins_pagure_no_new_branch.py new file mode 100644 index 0000000..9c594bb --- /dev/null +++ b/tests/test_pagure_flask_ui_plugins_pagure_no_new_branch.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- + +""" + (c) 2015-2018 - Copyright Red Hat Inc + + Authors: + Pierre-Yves Chibon + +""" + +from __future__ import unicode_literals + +__requires__ = ['SQLAlchemy >= 0.8'] + +import unittest +import shutil +import sys +import os + + +sys.path.insert(0, os.path.join(os.path.dirname( + os.path.abspath(__file__)), '..')) + +import pagure.lib +import tests + + +class PagureFlaskPluginPagureNoNewBranchHooktests(tests.SimplePagureTest): + """ Tests for pagure_no_new_branches plugin of pagure """ + + def setUp(self): + """ Set up the environnment, ran before every tests. """ + super(PagureFlaskPluginPagureNoNewBranchHooktests, self).setUp() + + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'repos')) + + pagure.config.config['GIT_FOLDER'] = os.path.join( + self.path, 'repos') + + with tests.user_set(self.app.application, tests.FakeUser()): + self.csrf_token = self.get_csrf() + + def test_plugin_pagure_ticket_no_data(self): + """ Test the pagure_ticket plugin on/off endpoint. """ + + user = tests.FakeUser(username='pingou') + with tests.user_set(self.app.application, user): + output = self.app.get( + '/test/settings/Prevent creating new branches by git push') + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Settings Prevent creating new branches by git ' + 'push - test - Pagure', output_text) + self.assertIn( + '', output_text) + + data = {} + + output = self.app.post( + '/test/settings/Prevent creating new branches by git push', + data=data) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Settings Prevent creating new branches by git push ' + '- test - Pagure', output_text) + self.assertIn( + '', output_text) + + def test_plugin_pagure_ticket_deactivate(self): + """ Test the pagure_ticket plugin on/off endpoint. """ + user = tests.FakeUser(username='pingou') + with tests.user_set(self.app.application, user): + data = {'csrf_token': self.csrf_token} + + output = self.app.post( + '/test/settings/Prevent creating new branches by git push', + data=data, follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
' + 'Project Settings
\n', output_text) + self.assertIn( + 'Hook Prevent creating new branches by git push deactivated', + output_text) + + output = self.app.get( + '/test/settings/Prevent creating new branches by git push') + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Settings Prevent creating new branches by git push ' + '- test - Pagure', output_text) + self.assertIn( + '', output_text) + + self.assertFalse(os.path.exists(os.path.join( + self.path, 'repos', 'test.git', 'hooks', 'post-receive.pagure'))) + + def test_plugin_pagure_ticket_activate(self): + """ Test the pagure_ticket plugin on/off endpoint. """ + + user = tests.FakeUser(username='pingou') + with tests.user_set(self.app.application, user): + # Activate hook + data = { + 'csrf_token': self.csrf_token, + 'active': 'y', + } + + output = self.app.post( + '/test/settings/Prevent creating new branches by git push', + data=data, follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
' + 'Project Settings
\n', output_text) + self.assertIn( + 'Hook Prevent creating new branches by git push activated', + output_text) + + output = self.app.get( + '/test/settings/Prevent creating new branches by git push') + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Settings Prevent creating new branches by git push ' + '- test - Pagure', output_text) + self.assertIn( + '', output_text) + + self.assertTrue(os.path.exists(os.path.join( + self.path, 'repos', 'test.git', 'hooks', + 'pre-receive.pagure_no_new_branches'))) + + # De-Activate hook + data = {'csrf_token': self.csrf_token} + output = self.app.post( + '/test/settings/Prevent creating new branches by git push', + data=data, follow_redirects=True) + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + '
' + 'Project Settings
\n', output_text) + self.assertIn( + 'Hook Prevent creating new branches by git push deactivated', + output_text) + + output = self.app.get( + '/test/settings/Prevent creating new branches by git push') + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Settings Prevent creating new branches by git push ' + '- test - Pagure', output_text) + self.assertIn( + '', output_text) + + self.assertFalse(os.path.exists(os.path.join( + self.path, 'repos', 'test.git', 'hooks', + 'pre-receive.pagure_no_new_branches'))) + + def test_plugin_pagure_ticket_activate_w_no_repo(self): + """ Test the pagure_ticket plugin on/off endpoint. """ + shutil.rmtree(os.path.join(self.path, 'repos', 'test.git')) + + user = tests.FakeUser(username='pingou') + with tests.user_set(self.app.application, user): + # Try re-activate hook w/o the git repo + data = { + 'csrf_token': self.csrf_token, + 'active': 'y', + } + + output = self.app.post( + '/test/settings/Prevent creating new branches by git push', + data=data) + self.assertEqual(output.status_code, 404) + + +if __name__ == '__main__': + unittest.main(verbosity=2) From 1d97e085d56882365c36e7f1205c2ae8aa4cff66 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 7/15] Expand the tests for the default hook Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_ui_plugins_default_hook.py b/tests/test_pagure_flask_ui_plugins_default_hook.py index 32c2b93..5993265 100644 --- a/tests/test_pagure_flask_ui_plugins_default_hook.py +++ b/tests/test_pagure_flask_ui_plugins_default_hook.py @@ -19,8 +19,9 @@ import shutil import sys import os +import flask import pygit2 -from mock import patch +from mock import patch, MagicMock sys.path.insert(0, os.path.join(os.path.dirname( os.path.abspath(__file__)), '..')) @@ -76,6 +77,84 @@ class PagureFlaskPluginDefaultHooktests(tests.Modeltests): self.assertTrue(os.path.exists(os.path.join( self.path, 'repos', 'test.git', 'hooks', 'post-receive'))) + def test_plugin_default_remove(self): + """ Check that the default plugin can be correctly removed if + somehow managed. + """ + + task = pagure.lib.new_project( + self.session, + user='pingou', + name='test', + blacklist=[], + allowed_prefix=[], + gitfolder=os.path.join(self.path, 'repos'), + docfolder=os.path.join(self.path, 'docs'), + ticketfolder=os.path.join(self.path, 'tickets'), + requestfolder=os.path.join(self.path, 'requests'), + description=None, + url=None, avatar_email=None, + parent_id=None, + add_readme=False, + userobj=None, + prevent_40_chars=False, + namespace=None + ) + self.assertEqual(task.get(), + {'endpoint': 'ui_ns.view_repo', + 'repo': 'test', + 'namespace': None}) + + repo = pagure.lib.get_authorized_project(self.session, 'test') + plugin = pagure.lib.plugins.get_plugin('default') + dbobj = plugin.db_object() + + plugin.remove(repo) + + self.assertFalse(os.path.exists(os.path.join( + self.path, 'repos', 'test.git', 'hooks', 'post-receive.default'))) + self.assertTrue(os.path.exists(os.path.join( + self.path, 'repos', 'test.git', 'hooks', 'post-receive'))) + + def test_plugin_default_form(self): + """ Check that the default plugin's form. + """ + with self._app.test_request_context('/') as ctx: + flask.g.session = self.session + flask.g.fas_user = tests.FakeUser(username='foo') + + task = pagure.lib.new_project( + self.session, + user='pingou', + name='test', + blacklist=[], + allowed_prefix=[], + gitfolder=os.path.join(self.path, 'repos'), + docfolder=os.path.join(self.path, 'docs'), + ticketfolder=os.path.join(self.path, 'tickets'), + requestfolder=os.path.join(self.path, 'requests'), + description=None, + url=None, avatar_email=None, + parent_id=None, + add_readme=False, + userobj=None, + prevent_40_chars=False, + namespace=None + ) + self.assertEqual(task.get(), + {'endpoint': 'ui_ns.view_repo', + 'repo': 'test', + 'namespace': None}) + + repo = pagure.lib.get_authorized_project(self.session, 'test') + plugin = pagure.lib.plugins.get_plugin('default') + dbobj = plugin.db_object() + form = plugin.form(obj=dbobj) + self.assertEqual( + str(form.active), + '' + ) + if __name__ == '__main__': unittest.main(verbosity=2) From 7056450fdeded9cfcec846190bc3bb7b88b21e4c Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 8/15] Add more tests on the internal API checking if a PR can be merged Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_internal.py b/tests/test_pagure_flask_internal.py index b17712f..11463c1 100644 --- a/tests/test_pagure_flask_internal.py +++ b/tests/test_pagure_flask_internal.py @@ -22,7 +22,7 @@ import time import os import pygit2 -from mock import patch +from mock import patch, MagicMock sys.path.insert(0, os.path.join(os.path.dirname( os.path.abspath(__file__)), '..')) @@ -825,6 +825,23 @@ class PagureFlaskInternaltests(tests.Modeltests): data = { 'csrf_token': csrf_token, 'requestid': project.requests[0].uid, + 'force': True, + } + output = self.app.post('/pv/pull-request/merge', data=data) + self.assertEqual(output.status_code, 200) + exp = { + "code": "MERGE", + "message": "The pull-request can be merged with a merge commit", + "short_code": "With merge" + } + + js_data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual(js_data, exp) + + # Asking a second time will trigger the cache + data = { + 'csrf_token': csrf_token, + 'requestid': project.requests[0].uid, } output = self.app.post('/pv/pull-request/merge', data=data) self.assertEqual(output.status_code, 200) @@ -989,6 +1006,284 @@ class PagureFlaskInternaltests(tests.Modeltests): js_data = json.loads(output.get_data(as_text=True)) self.assertDictEqual(js_data, exp) + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) + @patch( + 'pagure.lib.git.merge_pull_request', + MagicMock(side_effect=pagure.exceptions.PagureException('error'))) + def test_mergeable_request_pull_merge_pagureerror(self): + """ Test the mergeable_request_pull endpoint when the backend + raises an GitError exception. + """ + # Create a git repo to play with + + origgitrepo = os.path.join(self.path, 'repos', 'test.git') + self.assertFalse(os.path.exists(origgitrepo)) + os.makedirs(origgitrepo) + orig_repo = pygit2.init_repository(origgitrepo, bare=True) + os.makedirs(os.path.join(self.path, 'repos_tmp')) + gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git') + repo = pygit2.clone_repository(origgitrepo, gitrepo) + + # Create a file in that git repo + with open(os.path.join(gitrepo, 'sources'), 'w') as stream: + stream.write('foo\n bar') + repo.index.add('sources') + repo.index.write() + + # Commits the files added + tree = repo.index.write_tree() + author = pygit2.Signature( + 'Alice Author', 'alice@authors.tld') + committer = pygit2.Signature( + 'Cecil Committer', 'cecil@committers.tld') + repo.create_commit( + 'refs/heads/master', # the name of the reference to update + author, + committer, + 'Add sources file for testing', + # binary string representing the tree object ID + tree, + # list of binary strings representing parents of the new commit + [] + ) + + first_commit = repo.revparse_single('HEAD') + refname = 'refs/heads/master:refs/heads/master' + ori_remote = repo.remotes[0] + PagureRepo.push(ori_remote, refname) + + # Edit the sources file again + with open(os.path.join(gitrepo, 'sources'), 'w') as stream: + stream.write('foo\n bar\nbaz\n boose') + repo.index.add('sources') + repo.index.write() + + # Commits the files added + tree = repo.index.write_tree() + author = pygit2.Signature( + 'Alice Author', 'alice@authors.tld') + committer = pygit2.Signature( + 'Cecil Committer', 'cecil@committers.tld') + repo.create_commit( + 'refs/heads/feature', # the name of the reference to update + author, + committer, + 'Add baz and boose to the sources\n\n There are more objects to ' + 'consider', + # binary string representing the tree object ID + tree, + # list of binary strings representing parents of the new commit + [first_commit.oid.hex] + ) + refname = 'refs/heads/feature:refs/heads/feature' + ori_remote = repo.remotes[0] + PagureRepo.push(ori_remote, refname) + + # Create another file in the master branch + with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream: + stream.write('*~') + repo.index.add('.gitignore') + repo.index.write() + + # Commits the files added + tree = repo.index.write_tree() + author = pygit2.Signature( + 'Alice Author', 'alice@authors.tld') + committer = pygit2.Signature( + 'Cecil Committer', 'cecil@committers.tld') + repo.create_commit( + 'refs/heads/master', # the name of the reference to update + author, + committer, + 'Add .gitignore file for testing', + # binary string representing the tree object ID + tree, + # list of binary strings representing parents of the new commit + [first_commit.oid.hex] + ) + refname = 'refs/heads/master:refs/heads/master' + ori_remote = repo.remotes[0] + PagureRepo.push(ori_remote, refname) + + # Create a PR for these changes + tests.create_projects(self.session) + project = pagure.lib.get_authorized_project(self.session, 'test') + req = pagure.lib.new_pull_request( + session=self.session, + repo_from=project, + branch_from='feature', + repo_to=project, + branch_to='master', + title='PR from the feature branch', + user='pingou', + requestfolder=None, + ) + self.session.commit() + self.assertEqual(req.id, 1) + self.assertEqual(req.title, 'PR from the feature branch') + + # Check if the PR can be merged + data = {} + + user = tests.FakeUser() + user.username = 'pingou' + with tests.user_set(self.app.application, user): + output = self.app.get('/test/adduser') + csrf_token = self.get_csrf(output=output) + + # With all the desired information + project = pagure.lib.get_authorized_project(self.session, 'test') + data = { + 'csrf_token': csrf_token, + 'requestid': project.requests[0].uid, + 'force': True, + } + output = self.app.post('/pv/pull-request/merge', data=data) + self.assertEqual(output.status_code, 500) + exp = {u'code': u'CONFLICTS', u'message': u'error'} + + js_data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual(js_data, exp) + + @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) + @patch( + 'pagure.lib.git.merge_pull_request', + MagicMock(side_effect=pygit2.GitError('git error'))) + def test_mergeable_request_pull_merge_giterror(self): + """ Test the mergeable_request_pull endpoint when the backend + raises an GitError exception. + """ + # Create a git repo to play with + + origgitrepo = os.path.join(self.path, 'repos', 'test.git') + self.assertFalse(os.path.exists(origgitrepo)) + os.makedirs(origgitrepo) + orig_repo = pygit2.init_repository(origgitrepo, bare=True) + os.makedirs(os.path.join(self.path, 'repos_tmp')) + gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git') + repo = pygit2.clone_repository(origgitrepo, gitrepo) + + # Create a file in that git repo + with open(os.path.join(gitrepo, 'sources'), 'w') as stream: + stream.write('foo\n bar') + repo.index.add('sources') + repo.index.write() + + # Commits the files added + tree = repo.index.write_tree() + author = pygit2.Signature( + 'Alice Author', 'alice@authors.tld') + committer = pygit2.Signature( + 'Cecil Committer', 'cecil@committers.tld') + repo.create_commit( + 'refs/heads/master', # the name of the reference to update + author, + committer, + 'Add sources file for testing', + # binary string representing the tree object ID + tree, + # list of binary strings representing parents of the new commit + [] + ) + + first_commit = repo.revparse_single('HEAD') + refname = 'refs/heads/master:refs/heads/master' + ori_remote = repo.remotes[0] + PagureRepo.push(ori_remote, refname) + + # Edit the sources file again + with open(os.path.join(gitrepo, 'sources'), 'w') as stream: + stream.write('foo\n bar\nbaz\n boose') + repo.index.add('sources') + repo.index.write() + + # Commits the files added + tree = repo.index.write_tree() + author = pygit2.Signature( + 'Alice Author', 'alice@authors.tld') + committer = pygit2.Signature( + 'Cecil Committer', 'cecil@committers.tld') + repo.create_commit( + 'refs/heads/feature', # the name of the reference to update + author, + committer, + 'Add baz and boose to the sources\n\n There are more objects to ' + 'consider', + # binary string representing the tree object ID + tree, + # list of binary strings representing parents of the new commit + [first_commit.oid.hex] + ) + refname = 'refs/heads/feature:refs/heads/feature' + ori_remote = repo.remotes[0] + PagureRepo.push(ori_remote, refname) + + # Create another file in the master branch + with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream: + stream.write('*~') + repo.index.add('.gitignore') + repo.index.write() + + # Commits the files added + tree = repo.index.write_tree() + author = pygit2.Signature( + 'Alice Author', 'alice@authors.tld') + committer = pygit2.Signature( + 'Cecil Committer', 'cecil@committers.tld') + repo.create_commit( + 'refs/heads/master', # the name of the reference to update + author, + committer, + 'Add .gitignore file for testing', + # binary string representing the tree object ID + tree, + # list of binary strings representing parents of the new commit + [first_commit.oid.hex] + ) + refname = 'refs/heads/master:refs/heads/master' + ori_remote = repo.remotes[0] + PagureRepo.push(ori_remote, refname) + + # Create a PR for these changes + tests.create_projects(self.session) + project = pagure.lib.get_authorized_project(self.session, 'test') + req = pagure.lib.new_pull_request( + session=self.session, + repo_from=project, + branch_from='feature', + repo_to=project, + branch_to='master', + title='PR from the feature branch', + user='pingou', + requestfolder=None, + ) + self.session.commit() + self.assertEqual(req.id, 1) + self.assertEqual(req.title, 'PR from the feature branch') + + # Check if the PR can be merged + data = {} + + user = tests.FakeUser() + user.username = 'pingou' + with tests.user_set(self.app.application, user): + output = self.app.get('/test/adduser') + csrf_token = self.get_csrf(output=output) + + # With all the desired information + project = pagure.lib.get_authorized_project(self.session, 'test') + data = { + 'csrf_token': csrf_token, + 'requestid': project.requests[0].uid, + 'force': True, + } + output = self.app.post('/pv/pull-request/merge', data=data) + self.assertEqual(output.status_code, 409) + exp = {u'code': u'CONFLICTS', u'message': u'git error'} + + js_data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual(js_data, exp) + def test_get_branches_of_commit(self): ''' Test the get_branches_of_commit from the internal API. ''' tests.create_projects(self.session) From ea47176a882d53043776be7f4e40b65270f7351c Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 9/15] Add tests for the get_pull_request_ready_branch Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_internal.py b/tests/test_pagure_flask_internal.py index 11463c1..57d48f9 100644 --- a/tests/test_pagure_flask_internal.py +++ b/tests/test_pagure_flask_internal.py @@ -2157,6 +2157,57 @@ class PagureFlaskInternaltests(tests.Modeltests): js_data['family'], ['test', 'fork/ralph/test']) + def test_get_pull_request_ready_branch_no_csrf(self): + '''Test the get_pull_request_ready_branch from the internal API + on the main repository + ''' + tests.create_projects(self.session) + tests.create_projects_git( + os.path.join(self.path, 'repos'), bare=True) + + # Query branches on the main repo + data = { + 'repo': 'test', + } + output = self.app.post('/pv/pull-request/ready', data=data) + self.assertEqual(output.status_code, 400) + js_data = json.loads(output.get_data(as_text=True)) + self.assertEqual( + sorted(js_data.keys()), + ['code', 'message'] + ) + self.assertEqual(js_data['code'], 'ERROR') + self.assertEqual( + js_data['message'], + 'Invalid input submitted' + ) + + def test_get_pull_request_ready_branch_no_repo(self): + '''Test the get_pull_request_ready_branch from the internal API + on the main repository + ''' + with tests.user_set(self.app.application, tests.FakeUser()): + csrf_token = self.get_csrf() + + # Query branches on an invalid repo + data = { + 'repo': 'test', + 'namespace': 'fake', + 'csrf_token': csrf_token, + } + output = self.app.post('/pv/pull-request/ready', data=data) + self.assertEqual(output.status_code, 404) + js_data = json.loads(output.get_data(as_text=True)) + self.assertEqual( + sorted(js_data.keys()), + ['code', 'message'] + ) + self.assertEqual(js_data['code'], 'ERROR') + self.assertEqual( + js_data['message'], + 'No repo found with the information provided' + ) + def test_get_pull_request_ready_branch_main_repo_no_branch(self): '''Test the get_pull_request_ready_branch from the internal API on the main repository From 9262b7af6d06654484304d4cb2fa501695da8b60 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 10/15] Drop unused section of code We check the existence of the project earlier in the code Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index 0853793..79f56f9 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -393,14 +393,6 @@ def get_ticket_template(repo, namespace=None, username=None): repo = pagure.lib.get_authorized_project( flask.g.session, repo, user=username, namespace=namespace) - if repo is None: - response = flask.jsonify({ - 'code': 'ERROR', - 'message': 'Project not found', - }) - response.status_code = 404 - return response - if not repo.settings.get('issue_tracker', True): response = flask.jsonify({ 'code': 'ERROR', From a3de6440e8a1e485a89f8c61719e085cbd682e0b Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 11/15] Add unit-tests for the task_info internal API endpoint Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_internal.py b/tests/test_pagure_flask_internal.py index 57d48f9..706a3a1 100644 --- a/tests/test_pagure_flask_internal.py +++ b/tests/test_pagure_flask_internal.py @@ -22,7 +22,7 @@ import time import os import pygit2 -from mock import patch, MagicMock +from mock import patch, MagicMock, Mock sys.path.insert(0, os.path.join(os.path.dirname( os.path.abspath(__file__)), '..')) @@ -2553,6 +2553,39 @@ class PagureFlaskInternaltests(tests.Modeltests): self.assertEqual( js_data['message']['new_branch']['feature']['target_branch'], 'feature') + def test_task_info_task_running(self): + """ Test the task_info internal API endpoint when the task isn't + ready. + """ + task = MagicMock() + task.get = MagicMock(return_value='FAILED') + task.ready = MagicMock(return_value=False) + with patch('pagure.lib.tasks.get_result', MagicMock(return_value=task)): + output = self.app.get('/pv/task/2') + self.assertEqual(output.status_code, 418) + + def test_task_info_task_passed(self): + """ Test the task_info internal API endpoint when the task failed. + """ + task = MagicMock() + task.get = MagicMock(return_value='PASSED') + with patch('pagure.lib.tasks.get_result', MagicMock(return_value=task)): + output = self.app.get('/pv/task/2') + self.assertEqual(output.status_code, 200) + js_data = json.loads(output.get_data(as_text=True)) + self.assertEqual(js_data, {u'results': u'PASSED'}) + + def test_task_info_task_failed(self): + """ Test the task_info internal API endpoint when the task failed. + """ + task = MagicMock() + task.get = MagicMock(return_value=Exception('Random error')) + with patch('pagure.lib.tasks.get_result', MagicMock(return_value=task)): + output = self.app.get('/pv/task/2') + self.assertEqual(output.status_code, 200) + js_data = json.loads(output.get_data(as_text=True)) + self.assertEqual(js_data, {u'results': u'Random error'}) + if __name__ == '__main__': unittest.main(verbosity=2) From 689da110cde3c39f1d768c75c39708cbe7479d19 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 12/15] Expand the unit-tests about the internal endpoint for a project's templates Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_ui_issues_templates.py b/tests/test_pagure_flask_ui_issues_templates.py index b3e6e3e..ae57ad4 100644 --- a/tests/test_pagure_flask_ui_issues_templates.py +++ b/tests/test_pagure_flask_ui_issues_templates.py @@ -108,14 +108,14 @@ def create_templates(repopath): ) -class PagureFlaskIssuestests(tests.Modeltests): +class PagureFlaskIssuesTemplatetests(tests.Modeltests): """ Tests for flask issues controller of pagure """ @patch('pagure.lib.git.update_git', MagicMock(return_value=True)) @patch('pagure.lib.notify.send_email', MagicMock(return_value=True)) def setUp(self): """ Set up the environnment, run before every tests. """ - super(PagureFlaskIssuestests, self).setUp() + super(PagureFlaskIssuesTemplatetests, self).setUp() pagure.config.config['TICKETS_FOLDER'] = os.path.join( self.path, 'tickets') @@ -206,8 +206,8 @@ class PagureFlaskIssuestests(tests.Modeltests): {"code": "ERROR", "message": "No template provided"}) def test_get_ticket_template_no_project(self): - """ Test the get_ticket_template endpoint when not specifying which - template to get. + """ Test the get_ticket_template endpoint when the project does not + exist. """ user = tests.FakeUser() @@ -215,7 +215,7 @@ class PagureFlaskIssuestests(tests.Modeltests): csrf = self.get_csrf() data = {'csrf_token': csrf} output = self.app.post( - '/pv/test/issue/template?template=RFE', data=data) + '/pv/foobar/issue/template', data=data) self.assertEqual(output.status_code, 404) def test_get_ticket_template_no_template(self): @@ -235,6 +235,33 @@ class PagureFlaskIssuestests(tests.Modeltests): data, {"code": "ERROR", "message": "No such template found"}) + def test_get_ticket_template_issue_tracker_disabled(self): + """ Test the get_ticket_template endpoint when the project has + disabled its issue tracker. + """ + repo = pagure.lib.get_authorized_project(self.session, 'test') + settings = repo.settings + settings['issue_tracker'] = False + repo.settings = settings + self.session.add(repo) + self.session.commit() + + user = tests.FakeUser() + with tests.user_set(self.app.application, user): + csrf = self.get_csrf() + data = {'csrf_token': csrf} + output = self.app.post( + '/pv/test/issue/template?template=RFE', data=data) + self.assertEqual(output.status_code, 404) + data = json.loads(output.get_data(as_text=True)) + self.assertEqual( + data, + { + u'code': u'ERROR', + u'message': u'No issue tracker found for this project' + } + ) + def test_get_ticket_template_w_template(self): """ Test the get_ticket_template endpoint when the project has templates. From 3a70728e429702a6fa2c3cfa6853a655fc87859a Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 13/15] Remove never used code Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/api/issue.py b/pagure/api/issue.py index 7a11a89..c699ab4 100644 --- a/pagure/api/issue.py +++ b/pagure/api/issue.py @@ -1083,10 +1083,6 @@ def api_assign_issue(repo, issueid, username=None, namespace=None): _log.exception(err) raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR) - else: - raise pagure.exceptions.APIError( - 400, error_code=APIERROR.EINVALIDREQ, errors=form.errors) - jsonout = flask.jsonify(output) return jsonout @@ -1166,10 +1162,6 @@ def api_subscribe_issue(repo, issueid, username=None, namespace=None): _log.exception(err) raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR) - else: - raise pagure.exceptions.APIError( - 400, error_code=APIERROR.EINVALIDREQ, errors=form.errors) - jsonout = flask.jsonify(output) return jsonout From aa57b32d4921d281f53c0ded0ea94da37b626bc5 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 09:36:52 +0000 Subject: [PATCH 14/15] Add tests when updating custom fields via the API raises an exception Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_api_issue.py b/tests/test_pagure_flask_api_issue.py index f5ee7d0..910ce64 100644 --- a/tests/test_pagure_flask_api_issue.py +++ b/tests/test_pagure_flask_api_issue.py @@ -3632,6 +3632,65 @@ class PagureFlaskApiIssuetests(tests.SimplePagureTest): issue = pagure.lib.search_issues(self.session, repo, issueid=1) self.assertEqual(len(issue.other_fields), 0) + @patch( + 'pagure.lib.set_custom_key_value', + MagicMock(side_effect=pagure.exceptions.PagureException('error'))) + def test_api_update_custom_field_raises_error(self): + """ Test the api_update_custom_field method of the flask api. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'tickets')) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + + headers = {'Authorization': 'token aaabbbcccddd'} + + # Create normal issue + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.new_issue( + session=self.session, + repo=repo, + title='Test issue #1', + content='We should work on this', + user='pingou', + ticketfolder=None, + private=False, + ) + self.session.commit() + self.assertEqual(msg.title, 'Test issue #1') + + # Set some custom fields + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.set_custom_key_fields( + self.session, repo, + ['bugzilla', 'upstream', 'reviewstatus'], + ['link', 'boolean', 'list'], + ['unused data for non-list type', '', 'ack, nack , needs review'], + [None, None, None]) + self.session.commit() + self.assertEqual(msg, 'List of custom fields updated') + + # Check the project custom fields were correctly set + for key in repo.issue_keys: + # Check that the bugzilla field correctly had its data removed + if key.name == "bugzilla": + self.assertIsNone(key.data) + + # Check that the reviewstatus list field still has its list + elif key.name == "reviewstatus": + self.assertEqual( + sorted(key.data), ['ack', 'nack', 'needs review']) + + # Should work but raises an exception + output = self.app.post( + '/api/0/test/issue/1/custom/bugzilla', headers=headers, + data={'value': 'https://bugzilla.redhat.com/1234'}) + self.assertEqual(output.status_code, 400) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + {u'error': u'error', u'error_code': u'ENOCODE'} + ) + def test_api_view_issues_history_stats(self): """ Test the api_view_issues_history_stats method of the flask api. """ self.test_api_new_issue() diff --git a/tests/test_pagure_flask_api_issue_custom_fields.py b/tests/test_pagure_flask_api_issue_custom_fields.py index c1a2500..ccb831d 100644 --- a/tests/test_pagure_flask_api_issue_custom_fields.py +++ b/tests/test_pagure_flask_api_issue_custom_fields.py @@ -13,6 +13,7 @@ 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__)), '..')) @@ -24,6 +25,7 @@ import tests # noqa: E402 class PagureFlaskApiCustomFieldIssuetests(tests.Modeltests): """ Tests for the flask API of pagure for issue's custom fields """ + def setUp(self): """ Set up the environnment, ran before every tests. """ self.maxDiff = None @@ -90,6 +92,35 @@ class PagureFlaskApiCustomFieldIssuetests(tests.Modeltests): } ) + @patch( + 'pagure.lib.set_custom_key_value', + MagicMock(side_effect=pagure.exceptions.PagureException('error'))) + def test_api_update_custom_field_raise_error(self): + """ Test the api_update_custom_field method of the flask api. + This test the successful requests scenarii. + """ + + headers = {'Authorization': 'token aaabbbcccddd'} + + # Set some custom fields + repo = pagure.lib.get_authorized_project(self.session, 'test') + msg = pagure.lib.set_custom_key_fields( + self.session, repo, + ['bugzilla', 'upstream', 'reviewstatus'], + ['link', 'boolean', 'list'], + ['unused data for non-list type', '', 'ack', 'nack', 'needs review'], + [None, None, None]) + self.session.commit() + self.assertEqual(msg, 'List of custom fields updated') + + payload = {'bugzilla': '', 'upstream': True} + output = self.app.post( + '/api/0/test/issue/1/custom', headers=headers, data=payload) + self.assertEqual(output.status_code, 400) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, {u'error': u'error', u'error_code': u'ENOCODE'}) + def test_api_update_custom_field(self): """ Test the api_update_custom_field method of the flask api. This test the successful requests scenarii. From 2cca8378b834f1a22369b3ff596e31a1bfc56563 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Aug 02 2018 13:57:56 +0000 Subject: [PATCH 15/15] Fix invalid py3 code Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index 79f56f9..c62cee8 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -227,12 +227,12 @@ def mergeable_request_pull(): domerge=False) except pygit2.GitError as err: response = flask.jsonify({ - 'code': 'CONFLICTS', 'message': err.message}) + 'code': 'CONFLICTS', 'message': '%s' % err}) response.status_code = 409 return response except pagure.exceptions.PagureException as err: response = flask.jsonify({ - 'code': 'CONFLICTS', 'message': err.message}) + 'code': 'CONFLICTS', 'message': '%s' % err}) response.status_code = 500 return response