test_pagure_flask_api_issue_change_status.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2017 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. __requires__ = ['SQLAlchemy >= 0.8']
  8. import pkg_resources
  9. import copy
  10. import datetime
  11. import unittest
  12. import shutil
  13. import sys
  14. import time
  15. import os
  16. import json
  17. from mock import patch, MagicMock
  18. sys.path.insert(0, os.path.join(os.path.dirname(
  19. os.path.abspath(__file__)), '..'))
  20. import pagure
  21. import pagure.lib
  22. import tests
  23. class PagureFlaskApiIssueChangeStatustests(tests.Modeltests):
  24. """ Tests for the flask API of pagure for changing the status of an
  25. issue
  26. """
  27. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  28. def setUp(self):
  29. """ Set up the environnment, ran before every tests. """
  30. super(PagureFlaskApiIssueChangeStatustests, self).setUp()
  31. pagure.config.config['TICKETS_FOLDER'] = None
  32. tests.create_projects(self.session)
  33. tests.create_projects_git(os.path.join(self.path, 'tickets'))
  34. tests.create_tokens(self.session)
  35. tests.create_tokens_acl(self.session)
  36. # Create normal issue
  37. repo = pagure.lib.get_authorized_project(self.session, 'test')
  38. msg = pagure.lib.new_issue(
  39. session=self.session,
  40. repo=repo,
  41. title='Test issue #1',
  42. content='We should work on this',
  43. user='pingou',
  44. ticketfolder=None,
  45. private=False,
  46. )
  47. self.session.commit()
  48. self.assertEqual(msg.title, 'Test issue #1')
  49. # Create private issue
  50. msg = pagure.lib.new_issue(
  51. session=self.session,
  52. repo=repo,
  53. title='Test issue #2',
  54. content='We should work on this',
  55. user='foo',
  56. ticketfolder=None,
  57. private=True,
  58. )
  59. self.session.commit()
  60. self.assertEqual(msg.title, 'Test issue #2')
  61. # Create project-less token for user foo
  62. item = pagure.lib.model.Token(
  63. id='project-less-foo',
  64. user_id=2,
  65. project_id=None,
  66. expiration=datetime.datetime.utcnow()
  67. + datetime.timedelta(days=30)
  68. )
  69. self.session.add(item)
  70. self.session.commit()
  71. tests.create_tokens_acl(self.session, token_id='project-less-foo')
  72. # Create project-less token for user pingou
  73. item = pagure.lib.model.Token(
  74. id='project-less-pingou',
  75. user_id=1,
  76. project_id=None,
  77. expiration=datetime.datetime.utcnow()
  78. + datetime.timedelta(days=30)
  79. )
  80. self.session.add(item)
  81. self.session.commit()
  82. tests.create_tokens_acl(self.session, token_id='project-less-pingou')
  83. def test_api_change_status_issue_invalid_project(self):
  84. """ Test the api_change_status_issue method of the flask api. """
  85. headers = {'Authorization': 'token aaabbbcccddd'}
  86. # Invalid project
  87. output = self.app.post(
  88. '/api/0/foobar/issue/1/status', headers=headers)
  89. self.assertEqual(output.status_code, 404)
  90. data = json.loads(output.data)
  91. self.assertDictEqual(
  92. data,
  93. {
  94. "error": "Project not found",
  95. "error_code": "ENOPROJECT",
  96. }
  97. )
  98. def test_api_change_status_issue_token_not_for_project(self):
  99. """ Test the api_change_status_issue method of the flask api. """
  100. headers = {'Authorization': 'token aaabbbcccddd'}
  101. # Valid token, wrong project
  102. output = self.app.post('/api/0/test2/issue/1/status', headers=headers)
  103. self.assertEqual(output.status_code, 401)
  104. data = json.loads(output.data)
  105. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.name,
  106. data['error_code'])
  107. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
  108. def test_api_change_status_issue_invalid_issue(self):
  109. """ Test the api_change_status_issue method of the flask api. """
  110. headers = {'Authorization': 'token aaabbbcccddd'}
  111. # No issue
  112. output = self.app.post('/api/0/test/issue/42/status', headers=headers)
  113. self.assertEqual(output.status_code, 404)
  114. data = json.loads(output.data)
  115. self.assertDictEqual(
  116. data,
  117. {
  118. "error": "Issue not found",
  119. "error_code": "ENOISSUE",
  120. }
  121. )
  122. def test_api_change_status_issue_incomplete(self):
  123. """ Test the api_change_status_issue method of the flask api. """
  124. headers = {'Authorization': 'token aaabbbcccddd'}
  125. # Check status before
  126. repo = pagure.lib.get_authorized_project(self.session, 'test')
  127. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  128. self.assertEqual(issue.status, 'Open')
  129. data = {
  130. 'title': 'test issue',
  131. }
  132. # Incomplete request
  133. output = self.app.post(
  134. '/api/0/test/issue/1/status', data=data, headers=headers)
  135. self.assertEqual(output.status_code, 400)
  136. data = json.loads(output.data)
  137. self.assertDictEqual(
  138. data,
  139. {
  140. "error": "Invalid or incomplete input submitted",
  141. "error_code": "EINVALIDREQ",
  142. "errors": {"status": ["Not a valid choice"]}
  143. }
  144. )
  145. # No change
  146. repo = pagure.lib.get_authorized_project(self.session, 'test')
  147. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  148. self.assertEqual(issue.status, 'Open')
  149. def test_api_change_status_issue_no_change(self):
  150. """ Test the api_change_status_issue method of the flask api. """
  151. headers = {'Authorization': 'token aaabbbcccddd'}
  152. data = {
  153. 'status': 'Open',
  154. }
  155. # Valid request but no change
  156. output = self.app.post(
  157. '/api/0/test/issue/1/status', data=data, headers=headers)
  158. self.assertEqual(output.status_code, 200)
  159. data = json.loads(output.data)
  160. self.assertDictEqual(
  161. data,
  162. {'message': 'No changes'}
  163. )
  164. # No change
  165. repo = pagure.lib.get_authorized_project(self.session, 'test')
  166. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  167. self.assertEqual(issue.status, 'Open')
  168. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  169. def test_api_change_status_issue(self):
  170. """ Test the api_change_status_issue method of the flask api. """
  171. headers = {'Authorization': 'token aaabbbcccddd'}
  172. data = {
  173. 'status': 'Fixed',
  174. }
  175. # Valid request
  176. output = self.app.post(
  177. '/api/0/test/issue/1/status', data=data, headers=headers)
  178. self.assertEqual(output.status_code, 200)
  179. data = json.loads(output.data)
  180. self.assertDictEqual(
  181. data,
  182. {'message':[
  183. 'Issue status updated to: Closed (was: Open)',
  184. 'Issue close_status updated to: Fixed'
  185. ]}
  186. )
  187. headers = {'Authorization': 'token pingou_foo'}
  188. # Un-authorized issue
  189. output = self.app.post(
  190. '/api/0/foo/issue/1/status', data=data, headers=headers)
  191. self.assertEqual(output.status_code, 401)
  192. data = json.loads(output.data)
  193. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.name,
  194. data['error_code'])
  195. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
  196. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  197. def test_api_change_status_issue_no_ticket_project_less(self):
  198. """ Test the api_change_status_issue method of the flask api. """
  199. headers = {'Authorization': 'token project-less-foo'}
  200. data = {
  201. 'status': 'Fixed',
  202. }
  203. # Valid request
  204. output = self.app.post(
  205. '/api/0/test/issue/1/status', data=data, headers=headers)
  206. self.assertEqual(output.status_code, 403)
  207. data = json.loads(output.data)
  208. self.assertDictEqual(
  209. data,
  210. {
  211. "error": "You are not allowed to view this issue",
  212. "error_code": "EISSUENOTALLOWED"
  213. }
  214. )
  215. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  216. def test_api_change_status_issue_project_less(self):
  217. """ Test the api_change_status_issue method of the flask api. """
  218. headers = {'Authorization': 'token project-less-pingou'}
  219. data = {
  220. 'status': 'Fixed',
  221. }
  222. # Valid request
  223. output = self.app.post(
  224. '/api/0/test/issue/1/status', data=data, headers=headers)
  225. self.assertEqual(output.status_code, 200)
  226. data = json.loads(output.data)
  227. self.assertDictEqual(
  228. data,
  229. {
  230. "message": [
  231. "Issue status updated to: Closed (was: Open)",
  232. "Issue close_status updated to: Fixed"
  233. ]
  234. }
  235. )
  236. if __name__ == '__main__':
  237. unittest.main(verbosity=2)