test_pagure_flask_api_issue_comment.py 15 KB

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