test_pagure_flask_api_issue_comment.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2017 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. import datetime
  8. import unittest
  9. import sys
  10. import os
  11. import json
  12. from mock import patch, MagicMock
  13. sys.path.insert(0, os.path.join(os.path.dirname(
  14. os.path.abspath(__file__)), '..'))
  15. import pagure # noqa: E402
  16. import pagure.lib # noqa: E402
  17. import tests # noqa: E402
  18. class PagureFlaskApiIssueCommenttests(tests.Modeltests):
  19. """ Tests for the flask API of pagure for changing the status of an
  20. issue
  21. """
  22. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  23. def setUp(self):
  24. """ Set up the environnment, ran before every tests. """
  25. super(PagureFlaskApiIssueCommenttests, self).setUp()
  26. pagure.config.config['TICKETS_FOLDER'] = None
  27. tests.create_projects(self.session)
  28. tests.create_projects_git(os.path.join(self.path, 'tickets'))
  29. tests.create_tokens(self.session)
  30. tests.create_tokens_acl(self.session)
  31. # Create normal issue
  32. repo = pagure.lib.get_authorized_project(self.session, 'test')
  33. msg = pagure.lib.new_issue(
  34. session=self.session,
  35. repo=repo,
  36. title='Test issue #1',
  37. content='We should work on this',
  38. user='pingou',
  39. ticketfolder=None,
  40. private=False,
  41. )
  42. self.session.commit()
  43. self.assertEqual(msg.title, 'Test issue #1')
  44. # Create private issue
  45. msg = pagure.lib.new_issue(
  46. session=self.session,
  47. repo=repo,
  48. title='Test issue #2',
  49. content='We should work on this',
  50. user='foo',
  51. ticketfolder=None,
  52. private=True,
  53. )
  54. self.session.commit()
  55. self.assertEqual(msg.title, 'Test issue #2')
  56. # Create project-less token for user foo
  57. item = pagure.lib.model.Token(
  58. id='project-less-foo',
  59. user_id=2,
  60. project_id=None,
  61. expiration=datetime.datetime.utcnow()
  62. + datetime.timedelta(days=30)
  63. )
  64. self.session.add(item)
  65. self.session.commit()
  66. tests.create_tokens_acl(self.session, token_id='project-less-foo')
  67. def test_api_comment_issue_invalid_project(self):
  68. """ Test the api_comment_issue method of the flask api. """
  69. headers = {'Authorization': 'token aaabbbcccddd'}
  70. # Invalid project
  71. output = self.app.post('/api/0/foo/issue/1/comment', headers=headers)
  72. self.assertEqual(output.status_code, 404)
  73. data = json.loads(output.data)
  74. self.assertDictEqual(
  75. data,
  76. {
  77. "error": "Project not found",
  78. "error_code": "ENOPROJECT",
  79. }
  80. )
  81. def test_api_comment_issue_invalid_project_token(self):
  82. """ Test the api_comment_issue method of the flask api. """
  83. headers = {'Authorization': 'token aaabbbcccddd'}
  84. # Valid token, wrong project
  85. output = self.app.post('/api/0/test2/issue/1/comment', headers=headers)
  86. self.assertEqual(output.status_code, 401)
  87. data = json.loads(output.data)
  88. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.name,
  89. data['error_code'])
  90. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
  91. def test_api_comment_issue_invalid_issue(self):
  92. """ Test the api_comment_issue method of the flask api. """
  93. headers = {'Authorization': 'token aaabbbcccddd'}
  94. # Invalid issue
  95. output = self.app.post('/api/0/test/issue/10/comment', headers=headers)
  96. self.assertEqual(output.status_code, 404)
  97. data = json.loads(output.data)
  98. self.assertDictEqual(
  99. data,
  100. {
  101. "error": "Issue not found",
  102. "error_code": "ENOISSUE",
  103. }
  104. )
  105. def test_api_comment_issue_incomplete_request(self):
  106. """ Test the api_comment_issue method of the flask api. """
  107. headers = {'Authorization': 'token aaabbbcccddd'}
  108. # Check comments before
  109. repo = pagure.lib.get_authorized_project(self.session, 'test')
  110. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  111. self.assertEqual(len(issue.comments), 0)
  112. data = {
  113. 'title': 'test issue',
  114. }
  115. # Incomplete request
  116. output = self.app.post(
  117. '/api/0/test/issue/1/comment', data=data, headers=headers)
  118. self.assertEqual(output.status_code, 400)
  119. data = json.loads(output.data)
  120. self.assertDictEqual(
  121. data,
  122. {
  123. "error": "Invalid or incomplete input submitted",
  124. "error_code": "EINVALIDREQ",
  125. "errors": {"comment": ["This field is required."]}
  126. }
  127. )
  128. # No change
  129. repo = pagure.lib.get_authorized_project(self.session, 'test')
  130. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  131. self.assertEqual(issue.status, 'Open')
  132. def test_api_comment_issue(self):
  133. """ Test the api_comment_issue method of the flask api. """
  134. headers = {'Authorization': 'token aaabbbcccddd'}
  135. data = {
  136. 'comment': 'This is a very interesting question',
  137. }
  138. # Valid request
  139. output = self.app.post(
  140. '/api/0/test/issue/1/comment', data=data, headers=headers)
  141. self.assertEqual(output.status_code, 200)
  142. data = json.loads(output.data)
  143. self.assertDictEqual(
  144. data,
  145. {'message': 'Comment added'}
  146. )
  147. # One comment added
  148. repo = pagure.lib.get_authorized_project(self.session, 'test')
  149. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  150. self.assertEqual(len(issue.comments), 1)
  151. def test_api_comment_issue_private_un_authorized(self):
  152. """ Test the api_comment_issue method of the flask api. """
  153. # Check before
  154. repo = pagure.lib.get_authorized_project(self.session, 'test')
  155. issue = pagure.lib.search_issues(self.session, repo, issueid=2)
  156. self.assertEqual(len(issue.comments), 0)
  157. data = {
  158. 'comment': 'This is a very interesting question',
  159. }
  160. headers = {'Authorization': 'token pingou_foo'}
  161. # Valid request but un-authorized
  162. output = self.app.post(
  163. '/api/0/test/issue/2/comment', data=data, headers=headers)
  164. self.assertEqual(output.status_code, 401)
  165. data = json.loads(output.data)
  166. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.name,
  167. data['error_code'])
  168. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
  169. # No comment added
  170. repo = pagure.lib.get_authorized_project(self.session, 'test')
  171. issue = pagure.lib.search_issues(self.session, repo, issueid=2)
  172. self.assertEqual(len(issue.comments), 0)
  173. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  174. def test_api_comment_issue_private(self):
  175. """ Test the api_comment_issue method of the flask api. """
  176. # Create token for user foo
  177. item = pagure.lib.model.Token(
  178. id='foo_token2',
  179. user_id=2,
  180. project_id=1,
  181. expiration=datetime.datetime.utcnow() + datetime.timedelta(days=30)
  182. )
  183. self.session.add(item)
  184. self.session.commit()
  185. tests.create_tokens_acl(self.session, token_id='foo_token2')
  186. data = {
  187. 'comment': 'This is a very interesting question',
  188. }
  189. headers = {'Authorization': 'token foo_token2'}
  190. # Valid request and authorized
  191. output = self.app.post(
  192. '/api/0/test/issue/2/comment', data=data, headers=headers)
  193. self.assertEqual(output.status_code, 200)
  194. data = json.loads(output.data)
  195. self.assertDictEqual(
  196. data,
  197. {'message': 'Comment added'}
  198. )
  199. def test_api_comment_issue_invalid_project_project_less(self):
  200. """ Test the api_comment_issue method of the flask api. """
  201. headers = {'Authorization': 'token project-less-foo'}
  202. # Invalid project
  203. output = self.app.post('/api/0/foo/issue/1/comment', headers=headers)
  204. self.assertEqual(output.status_code, 404)
  205. data = json.loads(output.data)
  206. self.assertDictEqual(
  207. data,
  208. {
  209. "error": "Project not found",
  210. "error_code": "ENOPROJECT",
  211. }
  212. )
  213. def test_api_comment_issue_invalid_project_token_project_less(self):
  214. """ Test the api_comment_issue method of the flask api. """
  215. headers = {'Authorization': 'token project-less-foo'}
  216. # Valid token, no such issue, project-less token so different failure
  217. output = self.app.post('/api/0/test2/issue/1/comment', headers=headers)
  218. self.assertEqual(output.status_code, 404)
  219. data = json.loads(output.data)
  220. self.assertDictEqual(
  221. data,
  222. {
  223. "error": "Issue not found",
  224. "error_code": "ENOISSUE",
  225. }
  226. )
  227. def test_api_comment_issue_invalid_issue_project_less(self):
  228. """ Test the api_comment_issue method of the flask api. """
  229. headers = {'Authorization': 'token project-less-foo'}
  230. # Invalid issue
  231. output = self.app.post('/api/0/test/issue/10/comment', headers=headers)
  232. self.assertEqual(output.status_code, 404)
  233. data = json.loads(output.data)
  234. self.assertDictEqual(
  235. data,
  236. {
  237. "error": "Issue not found",
  238. "error_code": "ENOISSUE",
  239. }
  240. )
  241. def test_api_comment_issue_incomplete_request_project_less(self):
  242. """ Test the api_comment_issue method of the flask api. """
  243. headers = {'Authorization': 'token project-less-foo'}
  244. # Check comments before
  245. repo = pagure.lib.get_authorized_project(self.session, 'test')
  246. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  247. self.assertEqual(len(issue.comments), 0)
  248. data = {
  249. 'title': 'test issue',
  250. }
  251. # Incomplete request
  252. output = self.app.post(
  253. '/api/0/test/issue/1/comment', data=data, headers=headers)
  254. self.assertEqual(output.status_code, 400)
  255. data = json.loads(output.data)
  256. self.assertDictEqual(
  257. data,
  258. {
  259. "error": "Invalid or incomplete input submitted",
  260. "error_code": "EINVALIDREQ",
  261. "errors": {"comment": ["This field is required."]}
  262. }
  263. )
  264. # No change
  265. repo = pagure.lib.get_authorized_project(self.session, 'test')
  266. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  267. self.assertEqual(issue.status, 'Open')
  268. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  269. def test_api_comment_issue_project_less(self):
  270. """ Test the api_comment_issue method of the flask api. """
  271. headers = {'Authorization': 'token project-less-foo'}
  272. data = {
  273. 'comment': 'This is a very interesting question',
  274. }
  275. # Valid request
  276. output = self.app.post(
  277. '/api/0/test/issue/1/comment', data=data, headers=headers)
  278. self.assertEqual(output.status_code, 200)
  279. data = json.loads(output.data)
  280. self.assertDictEqual(
  281. data,
  282. {'message': 'Comment added'}
  283. )
  284. # One comment added
  285. repo = pagure.lib.get_authorized_project(self.session, 'test')
  286. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  287. self.assertEqual(len(issue.comments), 1)
  288. def test_api_comment_issue_private_un_authorized_project_less(self):
  289. """ Test the api_comment_issue method of the flask api. """
  290. # Check before
  291. repo = pagure.lib.get_authorized_project(self.session, 'test')
  292. issue = pagure.lib.search_issues(self.session, repo, issueid=2)
  293. self.assertEqual(len(issue.comments), 0)
  294. data = {
  295. 'comment': 'This is a very interesting question',
  296. }
  297. headers = {'Authorization': 'token pingou_foo'}
  298. # Valid request but un-authorized
  299. output = self.app.post(
  300. '/api/0/test/issue/2/comment', data=data, headers=headers)
  301. self.assertEqual(output.status_code, 401)
  302. data = json.loads(output.data)
  303. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.name,
  304. data['error_code'])
  305. self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data['error'])
  306. # No comment added
  307. repo = pagure.lib.get_authorized_project(self.session, 'test')
  308. issue = pagure.lib.search_issues(self.session, repo, issueid=2)
  309. self.assertEqual(len(issue.comments), 0)
  310. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  311. def test_api_comment_issue_private_project_less(self):
  312. """ Test the api_comment_issue method of the flask api. """
  313. # Create token for user foo
  314. item = pagure.lib.model.Token(
  315. id='foo_token2',
  316. user_id=2,
  317. project_id=None,
  318. expiration=datetime.datetime.utcnow() + datetime.timedelta(days=30)
  319. )
  320. self.session.add(item)
  321. self.session.commit()
  322. tests.create_tokens_acl(self.session, token_id='foo_token2')
  323. data = {
  324. 'comment': 'This is a very interesting question',
  325. }
  326. headers = {'Authorization': 'token foo_token2'}
  327. # Valid request and authorized
  328. output = self.app.post(
  329. '/api/0/test/issue/2/comment', data=data, headers=headers)
  330. self.assertEqual(output.status_code, 200)
  331. data = json.loads(output.data)
  332. self.assertDictEqual(
  333. data,
  334. {'message': 'Comment added'}
  335. )
  336. if __name__ == '__main__':
  337. unittest.main(verbosity=2)