test_pagure_flask_api_issue_comment.py 15 KB

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