test_pagure_flask_ui_repo_delete_project.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2017 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals, absolute_import
  8. import sys
  9. import os
  10. import pagure_messages
  11. from mock import ANY, patch, MagicMock
  12. from fedora_messaging import testing
  13. sys.path.insert(
  14. 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
  15. )
  16. import pagure.lib.query
  17. import tests
  18. class PagureFlaskDeleteRepotests(tests.Modeltests):
  19. """ Tests for deleting a project in pagure """
  20. def setUp(self):
  21. """ Set up the environnment, ran before every tests. """
  22. super(PagureFlaskDeleteRepotests, self).setUp()
  23. # Create some projects
  24. tests.create_projects(self.session)
  25. tests.create_projects_git(os.path.join(self.path, "repos"))
  26. self.session.commit()
  27. # Create all the git repos
  28. tests.create_projects_git(os.path.join(self.path, "repos"))
  29. tests.create_projects_git(os.path.join(self.path, "repos", "docs"))
  30. tests.create_projects_git(
  31. os.path.join(self.path, "repos", "tickets"), bare=True
  32. )
  33. tests.create_projects_git(
  34. os.path.join(self.path, "repos", "requests"), bare=True
  35. )
  36. project = pagure.lib.query.get_authorized_project(
  37. self.session, project_name="test"
  38. )
  39. self.assertIsNotNone(project)
  40. # Ensure the project isn't read-only
  41. project.read_only = False
  42. self.session.add(project)
  43. self.session.commit()
  44. # Create a fork
  45. task = pagure.lib.query.fork_project(
  46. session=self.session, user="pingou", repo=project
  47. )
  48. task.get()
  49. # Ensure everything was correctly created
  50. projects = pagure.lib.query.search_projects(self.session)
  51. self.assertEqual(len(projects), 4)
  52. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  53. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  54. @patch(
  55. "pagure.decorators.admin_session_timedout",
  56. MagicMock(return_value=False),
  57. )
  58. def test_delete_repo_when_turned_off(self):
  59. """Test the delete_repo endpoint for a fork when only deleting main
  60. project is forbidden.
  61. """
  62. user = tests.FakeUser(username="pingou")
  63. with tests.user_set(self.app.application, user):
  64. output = self.app.post("/test/delete", follow_redirects=True)
  65. self.assertEqual(output.status_code, 404)
  66. projects = pagure.lib.query.search_projects(self.session)
  67. self.assertEqual(len(projects), 4)
  68. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  69. @patch(
  70. "pagure.decorators.admin_session_timedout",
  71. MagicMock(return_value=False),
  72. )
  73. def test_delete_button_present(self):
  74. """Test that the delete button is present when deletions are
  75. allowed.
  76. """
  77. user = tests.FakeUser(username="pingou")
  78. with tests.user_set(self.app.application, user):
  79. output = self.app.get("/test/settings")
  80. self.assertEqual(output.status_code, 200)
  81. self.assertIn(
  82. '<form action="/test/delete"', output.get_data(as_text=True)
  83. )
  84. self.assertIn(
  85. "&nbsp; Delete the test project", output.get_data(as_text=True)
  86. )
  87. projects = pagure.lib.query.search_projects(self.session)
  88. self.assertEqual(len(projects), 4)
  89. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  90. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  91. @patch(
  92. "pagure.decorators.admin_session_timedout",
  93. MagicMock(return_value=False),
  94. )
  95. def test_delete_button_absent(self):
  96. """Test that the delete button is absent when deletions are not
  97. allowed.
  98. """
  99. user = tests.FakeUser(username="pingou")
  100. with tests.user_set(self.app.application, user):
  101. output = self.app.get("/test/settings")
  102. self.assertEqual(output.status_code, 200)
  103. self.assertNotIn(
  104. '<form action="/test/delete"', output.get_data(as_text=True)
  105. )
  106. self.assertNotIn(
  107. "&nbsp; Delete the test project", output.get_data(as_text=True)
  108. )
  109. projects = pagure.lib.query.search_projects(self.session)
  110. self.assertEqual(len(projects), 4)
  111. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  112. @patch.dict("pagure.config.config", {"ENABLE_DEL_FORKS": True})
  113. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  114. @patch(
  115. "pagure.decorators.admin_session_timedout",
  116. MagicMock(return_value=False),
  117. )
  118. def test_delete_fork_when_project_off_refreshing(self):
  119. """Test the delete_repo endpoint for a fork when only deleting main
  120. project is forbidden but the fork is being refreshed in the backend
  121. """
  122. project = pagure.lib.query.get_authorized_project(
  123. self.session, project_name="test", user="pingou"
  124. )
  125. self.assertIsNotNone(project)
  126. # Ensure the project isn't read-only
  127. project.read_only = True
  128. self.session.add(project)
  129. self.session.commit()
  130. user = tests.FakeUser(username="pingou")
  131. with tests.user_set(self.app.application, user):
  132. output = self.app.post(
  133. "/fork/pingou/test/delete", follow_redirects=True
  134. )
  135. self.assertEqual(output.status_code, 200)
  136. self.assertIn(
  137. "The ACLs of this project "
  138. "are being refreshed in the backend this prevents the "
  139. "project from being deleted. Please wait for this task to "
  140. "finish before trying again. Thanks!",
  141. output.get_data(as_text=True),
  142. )
  143. projects = pagure.lib.query.search_projects(self.session)
  144. self.assertEqual(len(projects), 4)
  145. @patch.dict(
  146. "pagure.config.config", {"FEDORA_MESSAGING_NOTIFICATIONS": True}
  147. )
  148. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  149. @patch.dict("pagure.config.config", {"ENABLE_DEL_FORKS": True})
  150. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  151. @patch(
  152. "pagure.decorators.admin_session_timedout",
  153. MagicMock(return_value=False),
  154. )
  155. def test_delete_fork_when_project_off(self):
  156. """Test the delete_repo endpoint for a fork when only deleting main
  157. project is forbidden.
  158. """
  159. project = pagure.lib.query.get_authorized_project(
  160. self.session, project_name="test", user="pingou"
  161. )
  162. self.assertIsNotNone(project)
  163. # Ensure the project isn't read-only
  164. project.read_only = False
  165. self.session.add(project)
  166. self.session.commit()
  167. user = tests.FakeUser(username="pingou")
  168. with tests.user_set(self.app.application, user):
  169. with testing.mock_sends(
  170. pagure_messages.ProjectDeletedV1(
  171. topic="pagure.project.deleted",
  172. body={
  173. "project": {
  174. "id": 4,
  175. "name": "test",
  176. "fullname": "forks/pingou/test",
  177. "url_path": "fork/pingou/test",
  178. "full_url": "http://localhost.localdomain/fork/pingou/test",
  179. "description": "test project #1",
  180. "namespace": None,
  181. "parent": {
  182. "id": 1,
  183. "name": "test",
  184. "fullname": "test",
  185. "url_path": "test",
  186. "full_url": "http://localhost.localdomain/test",
  187. "description": "test project #1",
  188. "namespace": None,
  189. "parent": None,
  190. "date_created": ANY,
  191. "date_modified": ANY,
  192. "user": {
  193. "name": "pingou",
  194. "fullname": "PY C",
  195. "url_path": "user/pingou",
  196. "full_url": "http://localhost.localdomain/user/pingou",
  197. },
  198. "access_users": {
  199. "owner": ["pingou"],
  200. "admin": [],
  201. "commit": [],
  202. "collaborator": [],
  203. "ticket": [],
  204. },
  205. "access_groups": {
  206. "admin": [],
  207. "commit": [],
  208. "collaborator": [],
  209. "ticket": [],
  210. },
  211. "tags": [],
  212. "priorities": {},
  213. "custom_keys": [],
  214. "close_status": [
  215. "Invalid",
  216. "Insufficient data",
  217. "Fixed",
  218. "Duplicate",
  219. ],
  220. "milestones": {},
  221. },
  222. "date_created": ANY,
  223. "date_modified": ANY,
  224. "user": {
  225. "name": "pingou",
  226. "fullname": "PY C",
  227. "url_path": "user/pingou",
  228. "full_url": "http://localhost.localdomain/user/pingou",
  229. },
  230. "access_users": {
  231. "owner": ["pingou"],
  232. "admin": [],
  233. "commit": [],
  234. "collaborator": [],
  235. "ticket": [],
  236. },
  237. "access_groups": {
  238. "admin": [],
  239. "commit": [],
  240. "collaborator": [],
  241. "ticket": [],
  242. },
  243. "tags": [],
  244. "priorities": {},
  245. "custom_keys": [],
  246. "close_status": [],
  247. "milestones": {},
  248. },
  249. "agent": "pingou",
  250. },
  251. )
  252. ):
  253. output = self.app.post(
  254. "/fork/pingou/test/delete", follow_redirects=True
  255. )
  256. self.assertEqual(output.status_code, 200)
  257. projects = pagure.lib.query.search_projects(self.session)
  258. self.assertEqual(len(projects), 3)
  259. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  260. @patch.dict("pagure.config.config", {"ENABLE_DEL_FORKS": False})
  261. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  262. @patch(
  263. "pagure.decorators.admin_session_timedout",
  264. MagicMock(return_value=False),
  265. )
  266. def test_delete_fork_when_fork_and_project_off(self):
  267. """Test the delete_repo endpoint for a fork when deleting fork and
  268. project is forbidden.
  269. """
  270. user = tests.FakeUser(username="pingou")
  271. with tests.user_set(self.app.application, user):
  272. output = self.app.post(
  273. "/fork/pingou/test/delete", follow_redirects=True
  274. )
  275. self.assertEqual(output.status_code, 404)
  276. projects = pagure.lib.query.search_projects(self.session)
  277. self.assertEqual(len(projects), 4)
  278. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  279. @patch.dict("pagure.config.config", {"ENABLE_DEL_FORKS": False})
  280. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  281. @patch(
  282. "pagure.decorators.admin_session_timedout",
  283. MagicMock(return_value=False),
  284. )
  285. def test_delete_fork_button_absent(self):
  286. """Test that the delete button is absent when deletions are not
  287. allowed.
  288. """
  289. user = tests.FakeUser(username="pingou")
  290. with tests.user_set(self.app.application, user):
  291. output = self.app.get("/fork/pingou/test/settings")
  292. self.assertEqual(output.status_code, 200)
  293. self.assertNotIn(
  294. '<form action="/fork/pingou/test/delete"',
  295. output.get_data(as_text=True),
  296. )
  297. self.assertNotIn(
  298. "&nbsp; Delete the forks/pingou/test project",
  299. output.get_data(as_text=True),
  300. )
  301. projects = pagure.lib.query.search_projects(self.session)
  302. self.assertEqual(len(projects), 4)
  303. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  304. @patch.dict("pagure.config.config", {"ENABLE_DEL_FORKS": True})
  305. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  306. @patch(
  307. "pagure.decorators.admin_session_timedout",
  308. MagicMock(return_value=False),
  309. )
  310. def test_delete_fork_button_fork_del_allowed(self):
  311. """Test that the delete button is present when deletions of projects
  312. is not allowed but deletions of forks is.
  313. """
  314. project = pagure.lib.query.get_authorized_project(
  315. self.session, project_name="test", user="pingou"
  316. )
  317. self.assertIsNotNone(project)
  318. # Ensure the project isn't read-only
  319. project.read_only = False
  320. self.session.add(project)
  321. self.session.commit()
  322. user = tests.FakeUser(username="pingou")
  323. with tests.user_set(self.app.application, user):
  324. output = self.app.get("/fork/pingou/test/settings")
  325. self.assertEqual(output.status_code, 200)
  326. self.assertIn(
  327. '<form action="/fork/pingou/test/delete"',
  328. output.get_data(as_text=True),
  329. )
  330. self.assertIn(
  331. "&nbsp; Delete the forks/pingou/test project",
  332. output.get_data(as_text=True),
  333. )
  334. projects = pagure.lib.query.search_projects(self.session)
  335. self.assertEqual(len(projects), 4)
  336. @patch.dict("pagure.config.config", {"ENABLE_DEL_PROJECTS": False})
  337. @patch.dict("pagure.config.config", {"ENABLE_DEL_FORKS": True})
  338. @patch("pagure.lib.notify.send_email", MagicMock(return_value=True))
  339. @patch(
  340. "pagure.decorators.admin_session_timedout",
  341. MagicMock(return_value=False),
  342. )
  343. def test_delete_fork_button_fork_del_allowed_read_only(self):
  344. """Test that the delete button is absent when deletions of projects
  345. is not allowed but deletions of forks is but fork is still being
  346. processed.
  347. """
  348. project = pagure.lib.query.get_authorized_project(
  349. self.session, project_name="test", user="pingou"
  350. )
  351. self.assertIsNotNone(project)
  352. # Ensure the project is read-only
  353. project.read_only = True
  354. self.session.add(project)
  355. self.session.commit()
  356. user = tests.FakeUser(username="pingou")
  357. with tests.user_set(self.app.application, user):
  358. output = self.app.get("/fork/pingou/test/settings")
  359. self.assertEqual(output.status_code, 200)
  360. self.assertNotIn(
  361. '<form action="/fork/pingou/test/delete"',
  362. output.get_data(as_text=True),
  363. )
  364. self.assertIn(
  365. "title=\"Action disabled while project's ACLs are being "
  366. 'refreshed">',
  367. output.get_data(as_text=True),
  368. )
  369. self.assertIn(
  370. "&nbsp; Delete the forks/pingou/test project",
  371. output.get_data(as_text=True),
  372. )