test_pagure_flask_api_issue_change_status.py 9.3 KB

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