test_pagure_flask_api.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals, absolute_import
  8. import unittest
  9. import shutil
  10. import sys
  11. import os
  12. import json
  13. from mock import patch, MagicMock
  14. sys.path.insert(
  15. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  16. )
  17. import pagure.api
  18. import pagure.flask_app
  19. import pagure.lib.query
  20. import tests
  21. class PagureFlaskApitests(tests.SimplePagureTest):
  22. """ Tests for flask API controller of pagure """
  23. maxDiff = None
  24. def test_api_doc(self):
  25. """ Test the API documentation page. """
  26. print(dir(self.app))
  27. output = self.app.get("/api/0/")
  28. output_text = output.get_data(as_text=True)
  29. self.assertIn("<title> API | pagure - Pagure</title>\n", output_text)
  30. self.assertIn(
  31. "&nbsp; Pagure API Reference\n </h2>\n", output_text
  32. )
  33. def test_api_doc_authenticated(self):
  34. """ Test the API documentation page. """
  35. user = tests.FakeUser(username="foo")
  36. with tests.user_set(self.app.application, user):
  37. output = self.app.get("/api/0/")
  38. output_text = output.get_data(as_text=True)
  39. self.assertIn(
  40. "<title> API | pagure - Pagure</title>\n", output_text
  41. )
  42. self.assertIn(
  43. "&nbsp; Pagure API Reference\n </h2>\n", output_text
  44. )
  45. def test_api_get_request_data(self):
  46. data = {"foo": "bar"}
  47. # test_request_context doesn't set flask.g, but some teardown
  48. # functions try to use that, so let's exclude them
  49. self._app.teardown_request_funcs = {}
  50. with self._app.test_request_context(
  51. "/api/0/version", method="POST", data=data
  52. ):
  53. self.assertEqual(pagure.api.get_request_data()["foo"], "bar")
  54. data = json.dumps(data)
  55. with self._app.test_request_context(
  56. "/api/0/version", data=data, content_type="application/json"
  57. ):
  58. self.assertEqual(pagure.api.get_request_data()["foo"], "bar")
  59. def test_api_version_old_url(self):
  60. """ Test the api_version function. """
  61. output = self.app.get("/api/0/version")
  62. self.assertEqual(output.status_code, 200)
  63. data = json.loads(output.get_data(as_text=True))
  64. self.assertEqual(data["version"], pagure.__api_version__)
  65. self.assertEqual(sorted(data.keys()), ["version"])
  66. def test_api_version_new_url(self):
  67. """ Test the api_version function at its new url. """
  68. output = self.app.get("/api/0/-/version")
  69. self.assertEqual(output.status_code, 200)
  70. data = json.loads(output.get_data(as_text=True))
  71. self.assertEqual(data["version"], pagure.__api_version__)
  72. self.assertEqual(sorted(data.keys()), ["version"])
  73. def test_api_project_tags(self):
  74. """ Test the api_project_tags function. """
  75. tests.create_projects(self.session)
  76. output = self.app.get("/api/0/foo/tags/")
  77. self.assertEqual(output.status_code, 404)
  78. data = json.loads(output.get_data(as_text=True))
  79. self.assertEqual(set(data.keys()), set(["output", "error"]))
  80. self.assertEqual(data["output"], "notok")
  81. self.assertEqual(data["error"], "Project not found")
  82. output = self.app.get("/api/0/test/tags/")
  83. self.assertEqual(output.status_code, 200)
  84. data = json.loads(output.get_data(as_text=True))
  85. self.assertEqual(sorted(data.keys()), ["tags", "total_tags"])
  86. self.assertEqual(data["tags"], [])
  87. self.assertEqual(data["total_tags"], 0)
  88. # Add an issue and tag it so that we can list them
  89. item = pagure.lib.model.Issue(
  90. id=1,
  91. uid="foobar",
  92. project_id=1,
  93. title="issue",
  94. content="a bug report",
  95. user_id=1, # pingou
  96. )
  97. self.session.add(item)
  98. self.session.commit()
  99. item = pagure.lib.model.TagColored(
  100. tag="tag1", tag_color="DeepBlueSky", project_id=1
  101. )
  102. self.session.add(item)
  103. self.session.commit()
  104. item = pagure.lib.model.TagIssueColored(
  105. issue_uid="foobar", tag_id=item.id
  106. )
  107. self.session.add(item)
  108. self.session.commit()
  109. output = self.app.get("/api/0/test/tags/")
  110. self.assertEqual(output.status_code, 200)
  111. data = json.loads(output.get_data(as_text=True))
  112. self.assertEqual(sorted(data.keys()), ["tags", "total_tags"])
  113. self.assertEqual(data["tags"], ["tag1"])
  114. self.assertEqual(data["total_tags"], 1)
  115. output = self.app.get("/api/0/test/tags/?pattern=t")
  116. self.assertEqual(output.status_code, 200)
  117. data = json.loads(output.get_data(as_text=True))
  118. self.assertEqual(sorted(data.keys()), ["tags", "total_tags"])
  119. self.assertEqual(data["tags"], ["tag1"])
  120. self.assertEqual(data["total_tags"], 1)
  121. output = self.app.get("/api/0/test/tags/?pattern=p")
  122. self.assertEqual(output.status_code, 200)
  123. data = json.loads(output.get_data(as_text=True))
  124. self.assertEqual(sorted(data.keys()), ["tags", "total_tags"])
  125. self.assertEqual(data["tags"], [])
  126. self.assertEqual(data["total_tags"], 0)
  127. def test_api_groups(self):
  128. """ Test the api_groups function. """
  129. # Add a couple of groups so that we can list them
  130. item = pagure.lib.model.PagureGroup(
  131. group_name="group1",
  132. group_type="user",
  133. display_name="User group",
  134. user_id=1, # pingou
  135. )
  136. self.session.add(item)
  137. item = pagure.lib.model.PagureGroup(
  138. group_name="rel-eng",
  139. group_type="user",
  140. display_name="Release engineering group",
  141. user_id=1, # pingou
  142. )
  143. self.session.add(item)
  144. self.session.commit()
  145. output = self.app.get("/api/0/groups")
  146. self.assertEqual(output.status_code, 200)
  147. data = json.loads(output.get_data(as_text=True))
  148. self.assertEqual(data["groups"], ["group1", "rel-eng"])
  149. self.assertEqual(
  150. sorted(data.keys()), ["groups", "pagination", "total_groups"]
  151. )
  152. self.assertEqual(data["total_groups"], 2)
  153. output = self.app.get("/api/0/groups?pattern=re")
  154. self.assertEqual(output.status_code, 200)
  155. data = json.loads(output.get_data(as_text=True))
  156. self.assertEqual(data["groups"], ["rel-eng"])
  157. self.assertEqual(
  158. sorted(data.keys()), ["groups", "pagination", "total_groups"]
  159. )
  160. self.assertEqual(data["total_groups"], 1)
  161. def test_api_whoami_unauth(self):
  162. """ Test the api_whoami function. """
  163. output = self.app.post("/api/0/-/whoami")
  164. self.assertEqual(output.status_code, 401)
  165. data = json.loads(output.get_data(as_text=True))
  166. self.assertEqual(
  167. data,
  168. {
  169. "error": "Invalid or expired token. Please visit "
  170. "http://localhost.localdomain/settings#api-keys to get or "
  171. "renew your API token.",
  172. "error_code": "EINVALIDTOK",
  173. },
  174. )
  175. def test_api_whoami_invalid_auth(self):
  176. """ Test the api_whoami function with an invalid token. """
  177. tests.create_projects(self.session)
  178. tests.create_tokens(self.session)
  179. headers = {"Authorization": "token invalid"}
  180. output = self.app.post("/api/0/-/whoami", headers=headers)
  181. self.assertEqual(output.status_code, 401)
  182. data = json.loads(output.get_data(as_text=True))
  183. self.assertEqual(
  184. data,
  185. {
  186. "error": "Invalid or expired token. Please visit "
  187. "http://localhost.localdomain/settings#api-keys to get or "
  188. "renew your API token.",
  189. "error_code": "EINVALIDTOK",
  190. "errors": "Invalid token",
  191. },
  192. )
  193. def test_api_whoami_auth(self):
  194. """ Test the api_whoami function with a valid token. """
  195. tests.create_projects(self.session)
  196. tests.create_tokens(self.session)
  197. headers = {"Authorization": "token aaabbbcccddd"}
  198. output = self.app.post("/api/0/-/whoami", headers=headers)
  199. self.assertEqual(output.status_code, 200)
  200. data = json.loads(output.get_data(as_text=True))
  201. self.assertEqual(data, {"username": "pingou"})
  202. def test_api_error_codes(self):
  203. """ Test the api_error_codes endpoint. """
  204. output = self.app.get("/api/0/-/error_codes")
  205. self.assertEqual(output.status_code, 200)
  206. data = json.loads(output.get_data(as_text=True))
  207. self.assertEqual(len(data), 36)
  208. self.assertEqual(
  209. sorted(data.keys()),
  210. sorted(
  211. [
  212. "EDATETIME",
  213. "EDBERROR",
  214. "EGITERROR",
  215. "EINVALIDISSUEFIELD",
  216. "EINVALIDISSUEFIELD_LINK",
  217. "EINVALIDPERPAGEVALUE",
  218. "EINVALIDPRIORITY",
  219. "EINVALIDREQ",
  220. "EINVALIDTOK",
  221. "EISSUENOTALLOWED",
  222. "EMODIFYPROJECTNOTALLOWED",
  223. "ENEWPROJECTDISABLED",
  224. "ENOCODE",
  225. "ENOCOMMENT",
  226. "ENOCOMMIT",
  227. "ENOGROUP",
  228. "ENOISSUE",
  229. "ENOPRCLOSE",
  230. "ENOPROJECT",
  231. "ENOPROJECTS",
  232. "ENOPRSTATS",
  233. "ENOREQ",
  234. "ENOSIGNEDOFF",
  235. "ENOTASSIGNED",
  236. "ENOTASSIGNEE",
  237. "ENOTHIGHENOUGH",
  238. "ENOTMAINADMIN",
  239. "ENOUSER",
  240. "EPRCONFLICTS",
  241. "EPRNOTALLOWED",
  242. "EPRSCORE",
  243. "EPULLREQUESTSDISABLED",
  244. "ETIMESTAMP",
  245. "ETRACKERDISABLED",
  246. "ETRACKERREADONLY",
  247. "EUBLOCKED",
  248. ]
  249. ),
  250. )
  251. @patch("pagure.lib.tasks.get_result")
  252. def test_api_task_status(self, get_result):
  253. async_result = MagicMock()
  254. async_result.status = "running"
  255. async_result.ready.return_value = False
  256. get_result.return_value = async_result
  257. output = self.app.get("/api/0/task/123abc/status/")
  258. self.assertEqual(output.status_code, 200)
  259. data = json.loads(output.get_data(as_text=True))
  260. self.assertEqual(data, {"ready": False, "status": "running"})
  261. async_result = MagicMock()
  262. async_result.status = "finished"
  263. async_result.ready.return_value = True
  264. async_result.successful.return_value = True
  265. get_result.return_value = async_result
  266. output = self.app.get("/api/0/task/123abc/status/")
  267. self.assertEqual(output.status_code, 200)
  268. data = json.loads(output.get_data(as_text=True))
  269. self.assertEqual(
  270. data, {"ready": True, "status": "finished", "successful": True}
  271. )
  272. if __name__ == "__main__":
  273. unittest.main(verbosity=2)