test_pagure_flask_ui_issues.py 65 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2016 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. __requires__ = ['SQLAlchemy >= 0.8']
  8. import pkg_resources
  9. import json
  10. import unittest
  11. import shutil
  12. import sys
  13. import os
  14. import pygit2
  15. from mock import patch
  16. sys.path.insert(0, os.path.join(os.path.dirname(
  17. os.path.abspath(__file__)), '..'))
  18. import pagure.lib
  19. import tests
  20. class PagureFlaskIssuestests(tests.Modeltests):
  21. """ Tests for flask issues controller of pagure """
  22. def setUp(self):
  23. """ Set up the environnment, ran before every tests. """
  24. super(PagureFlaskIssuestests, self).setUp()
  25. pagure.APP.config['TESTING'] = True
  26. pagure.SESSION = self.session
  27. pagure.ui.SESSION = self.session
  28. pagure.ui.app.SESSION = self.session
  29. pagure.ui.issues.SESSION = self.session
  30. pagure.ui.repo.SESSION = self.session
  31. pagure.ui.filters.SESSION = self.session
  32. pagure.APP.config['GIT_FOLDER'] = tests.HERE
  33. pagure.APP.config['FORK_FOLDER'] = os.path.join(
  34. tests.HERE, 'forks')
  35. pagure.APP.config['TICKETS_FOLDER'] = os.path.join(
  36. tests.HERE, 'tickets')
  37. pagure.APP.config['DOCS_FOLDER'] = os.path.join(
  38. tests.HERE, 'docs')
  39. self.app = pagure.APP.test_client()
  40. @patch('pagure.lib.git.update_git')
  41. @patch('pagure.lib.notify.send_email')
  42. def test_new_issue(self, p_send_email, p_ugt):
  43. """ Test the new_issue endpoint. """
  44. p_send_email.return_value = True
  45. p_ugt.return_value = True
  46. output = self.app.get('/foo/new_issue')
  47. self.assertEqual(output.status_code, 302)
  48. user = tests.FakeUser()
  49. with tests.user_set(pagure.APP, user):
  50. output = self.app.get('/foo/new_issue')
  51. self.assertEqual(output.status_code, 404)
  52. tests.create_projects(self.session)
  53. tests.create_projects_git(
  54. os.path.join(tests.HERE), bare=True)
  55. output = self.app.get('/test/new_issue')
  56. self.assertEqual(output.status_code, 200)
  57. self.assertTrue(
  58. '<div class="card-header">\n New issue'
  59. in output.data)
  60. csrf_token = output.data.split(
  61. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  62. data = {
  63. }
  64. # Insufficient input
  65. output = self.app.post('/test/new_issue', data=data)
  66. self.assertEqual(output.status_code, 200)
  67. self.assertTrue(
  68. '<div class="card-header">\n New issue'
  69. in output.data)
  70. self.assertEqual(output.data.count(
  71. 'This field is required.'), 2)
  72. data['title'] = 'Test issue'
  73. output = self.app.post('/test/new_issue', data=data)
  74. self.assertEqual(output.status_code, 200)
  75. self.assertTrue(
  76. '<div class="card-header">\n New issue'
  77. in output.data)
  78. self.assertEqual(output.data.count(
  79. 'This field is required.'), 1)
  80. data['issue_content'] = 'We really should improve on this issue'
  81. data['status'] = 'Open'
  82. output = self.app.post('/test/new_issue', data=data)
  83. self.assertEqual(output.status_code, 200)
  84. self.assertTrue(
  85. '<div class="card-header">\n New issue'
  86. in output.data)
  87. self.assertEqual(output.data.count(
  88. '</button>\n This field is required.'),
  89. 0)
  90. # Invalid user
  91. data['csrf_token'] = csrf_token
  92. output = self.app.post('/test/new_issue', data=data)
  93. self.assertEqual(output.status_code, 200)
  94. self.assertTrue(
  95. '<div class="card-header">\n New issue'
  96. in output.data)
  97. self.assertEqual(output.data.count(
  98. '<td class="errors">This field is required.</td>'), 0)
  99. self.assertTrue(
  100. '</button>\n No user &#34;username&#34; found'
  101. in output.data)
  102. user.username = 'pingou'
  103. with tests.user_set(pagure.APP, user):
  104. output = self.app.post(
  105. '/test/new_issue', data=data, follow_redirects=True)
  106. self.assertEqual(output.status_code, 200)
  107. self.assertIn(
  108. '<title>Issue #1: Test issue - test - Pagure</title>',
  109. output.data)
  110. self.assertIn(
  111. '<a class="btn btn-primary btn-sm" '
  112. 'href="/test/issue/1/edit" title="Edit this issue">',
  113. output.data)
  114. # Project w/o issue tracker
  115. repo = pagure.lib.get_project(self.session, 'test')
  116. repo.settings = {'issue_tracker': False}
  117. self.session.add(repo)
  118. self.session.commit()
  119. user.username = 'pingou'
  120. with tests.user_set(pagure.APP, user):
  121. output = self.app.post(
  122. '/test/new_issue', data=data, follow_redirects=True)
  123. self.assertEqual(output.status_code, 404)
  124. @patch('pagure.lib.git.update_git')
  125. @patch('pagure.lib.notify.send_email')
  126. def test_new_issue_w_file(self, p_send_email, p_ugt):
  127. """ Test the new_issue endpoint with a file. """
  128. p_send_email.return_value = True
  129. p_ugt.return_value = True
  130. tests.create_projects(self.session)
  131. tests.create_projects_git(
  132. os.path.join(tests.HERE), bare=True)
  133. tests.create_projects_git(
  134. os.path.join(tests.HERE, 'tickets'), bare=True)
  135. user = tests.FakeUser()
  136. user.username = 'pingou'
  137. with tests.user_set(pagure.APP, user):
  138. output = self.app.get('/test/new_issue')
  139. self.assertEqual(output.status_code, 200)
  140. self.assertTrue(
  141. '<div class="card-header">\n New issue'
  142. in output.data)
  143. csrf_token = output.data.split(
  144. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  145. stream = open(os.path.join(tests.HERE, 'placebo.png'), 'r')
  146. data = {
  147. 'title': 'Test issue',
  148. 'issue_content': 'We really should improve on this issue\n'
  149. '<!!image>',
  150. 'status': 'Open',
  151. 'filestream': stream,
  152. 'enctype': 'multipart/form-data',
  153. 'csrf_token': csrf_token,
  154. }
  155. output = self.app.post(
  156. '/test/new_issue', data=data, follow_redirects=True)
  157. stream.close()
  158. self.assertEqual(output.status_code, 200)
  159. self.assertIn(
  160. '<title>Issue #1: Test issue - test - Pagure</title>',
  161. output.data)
  162. self.assertIn(
  163. '<a class="btn btn-primary btn-sm" '
  164. 'href="/test/issue/1/edit" title="Edit this issue">',
  165. output.data)
  166. # Project w/o issue tracker
  167. repo = pagure.lib.get_project(self.session, 'test')
  168. repo.settings = {'issue_tracker': False}
  169. self.session.add(repo)
  170. self.session.commit()
  171. user.username = 'pingou'
  172. with tests.user_set(pagure.APP, user):
  173. stream = open(os.path.join(tests.HERE, 'placebo.png'), 'r')
  174. data = {
  175. 'title': 'Test issue',
  176. 'issue_content': 'We really should improve on this issue',
  177. 'status': 'Open',
  178. 'filestream': stream,
  179. 'enctype': 'multipart/form-data',
  180. 'csrf_token': csrf_token,
  181. }
  182. output = self.app.post(
  183. '/test/new_issue', data=data, follow_redirects=True)
  184. self.assertEqual(output.status_code, 404)
  185. @patch('pagure.lib.git.update_git')
  186. @patch('pagure.lib.notify.send_email')
  187. def test_view_issues(self, p_send_email, p_ugt):
  188. """ Test the view_issues endpoint. """
  189. p_send_email.return_value = True
  190. p_ugt.return_value = True
  191. output = self.app.get('/foo/issues')
  192. self.assertEqual(output.status_code, 404)
  193. tests.create_projects(self.session)
  194. tests.create_projects_git(
  195. os.path.join(tests.HERE), bare=True)
  196. output = self.app.get('/test/issues')
  197. self.assertEqual(output.status_code, 200)
  198. self.assertIn(
  199. 'div class="projectinfo m-t-1 m-b-1">\ntest project #1 '
  200. '</div>', output.data)
  201. self.assertTrue(
  202. '<h2>\n 0 Open Issues' in output.data)
  203. # Create issues to play with
  204. repo = pagure.lib.get_project(self.session, 'test')
  205. msg = pagure.lib.new_issue(
  206. session=self.session,
  207. repo=repo,
  208. title='Test issue',
  209. content='We should work on this',
  210. user='pingou',
  211. ticketfolder=None
  212. )
  213. self.session.commit()
  214. self.assertEqual(msg.title, 'Test issue')
  215. # Whole list
  216. output = self.app.get('/test/issues')
  217. self.assertEqual(output.status_code, 200)
  218. self.assertIn('<title>Issues - test - Pagure</title>', output.data)
  219. self.assertTrue(
  220. '<h2>\n 1 Open Issues' in output.data)
  221. # Status = closed
  222. output = self.app.get('/test/issues?status=cloSED')
  223. self.assertEqual(output.status_code, 200)
  224. self.assertIn('<title>Issues - test - Pagure</title>', output.data)
  225. self.assertTrue(
  226. '<h2>\n 0 Closed Issues' in output.data)
  227. # Status = fixed
  228. output = self.app.get('/test/issues?status=fixed')
  229. self.assertEqual(output.status_code, 200)
  230. self.assertIn('<title>Issues - test - Pagure</title>', output.data)
  231. self.assertTrue(
  232. '<h2>\n 0 Closed Issues' in output.data)
  233. # New issue button is shown
  234. user = tests.FakeUser()
  235. with tests.user_set(pagure.APP, user):
  236. output = self.app.get('/test')
  237. self.assertEqual(output.status_code, 200)
  238. self.assertIn(
  239. 'class="btn btn-success btn-sm">New Issue</a>',
  240. output.data)
  241. # Project w/o issue tracker
  242. repo = pagure.lib.get_project(self.session, 'test')
  243. repo.settings = {'issue_tracker': False}
  244. self.session.add(repo)
  245. self.session.commit()
  246. output = self.app.get('/test/issues')
  247. self.assertEqual(output.status_code, 404)
  248. # New issue button is hidden
  249. user = tests.FakeUser()
  250. with tests.user_set(pagure.APP, user):
  251. output = self.app.get('/test')
  252. self.assertEqual(output.status_code, 200)
  253. self.assertNotIn(
  254. 'class="btn btn-success btn-sm">New Issue</a>',
  255. output.data)
  256. @patch('pagure.lib.git.update_git')
  257. @patch('pagure.lib.notify.send_email')
  258. def test_view_issue(self, p_send_email, p_ugt):
  259. """ Test the view_issue endpoint. """
  260. p_send_email.return_value = True
  261. p_ugt.return_value = True
  262. output = self.app.get('/foo/issue/1')
  263. self.assertEqual(output.status_code, 404)
  264. tests.create_projects(self.session)
  265. tests.create_projects_git(
  266. os.path.join(tests.HERE), bare=True)
  267. output = self.app.get('/test/issue/1')
  268. self.assertEqual(output.status_code, 404)
  269. # Create issues to play with
  270. repo = pagure.lib.get_project(self.session, 'test')
  271. msg = pagure.lib.new_issue(
  272. session=self.session,
  273. repo=repo,
  274. title='Test issue',
  275. content='We should work on this',
  276. user='pingou',
  277. ticketfolder=None
  278. )
  279. self.session.commit()
  280. self.assertEqual(msg.title, 'Test issue')
  281. output = self.app.get('/test/issue/1')
  282. self.assertEqual(output.status_code, 200)
  283. # Not authentified = No edit
  284. self.assertNotIn(
  285. '<a class="btn btn-primary btn-sm" href="/test/issue/1/edit" '
  286. 'title="Edit this issue">',
  287. output.data)
  288. self.assertTrue(
  289. '<a href="/login/?next=http%3A%2F%2Flocalhost%2Ftest%2Fissue%2F1">'
  290. 'Login</a>\n to comment on this ticket.'
  291. in output.data)
  292. user = tests.FakeUser()
  293. with tests.user_set(pagure.APP, user):
  294. output = self.app.get('/test/issue/1')
  295. self.assertEqual(output.status_code, 200)
  296. # Not author nor admin = No edit
  297. self.assertNotIn(
  298. '<a class="btn btn-primary btn-sm" '
  299. 'href="/test/issue/1/edit" title="Edit this issue">',
  300. output.data)
  301. self.assertNotIn(
  302. '<button class="btn btn-danger btn-sm" type="submit"',
  303. output.data)
  304. self.assertNotIn('title="Delete this ticket">', output.data)
  305. self.assertFalse(
  306. '<a href="/login/">Login</a> to comment on this ticket.'
  307. in output.data)
  308. user.username = 'pingou'
  309. with tests.user_set(pagure.APP, user):
  310. output = self.app.get('/test/issue/1')
  311. self.assertEqual(output.status_code, 200)
  312. self.assertIn(
  313. '<a class="btn btn-primary btn-sm" '
  314. 'href="/test/issue/1/edit" title="Edit this issue">',
  315. output.data)
  316. self.assertIn(
  317. '<button class="btn btn-danger btn-sm" type="submit"',
  318. output.data)
  319. self.assertIn('title="Delete this ticket">', output.data)
  320. csrf_token = output.data.split(
  321. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  322. # Create private issue
  323. repo = pagure.lib.get_project(self.session, 'test')
  324. msg = pagure.lib.new_issue(
  325. session=self.session,
  326. repo=repo,
  327. title='Test issue',
  328. content='We should work on this',
  329. user='pingou',
  330. ticketfolder=None,
  331. private=True,
  332. )
  333. self.session.commit()
  334. self.assertEqual(msg.title, 'Test issue')
  335. # Not logged in
  336. output = self.app.get('/test/issue/2')
  337. self.assertEqual(output.status_code, 403)
  338. # Wrong user
  339. user = tests.FakeUser()
  340. with tests.user_set(pagure.APP, user):
  341. output = self.app.get('/test/issue/2')
  342. self.assertEqual(output.status_code, 403)
  343. # reporter
  344. user.username = 'pingou'
  345. with tests.user_set(pagure.APP, user):
  346. output = self.app.get('/test/issue/2')
  347. self.assertEqual(output.status_code, 200)
  348. self.assertIn(
  349. '<title>Issue #2: Test issue - test - Pagure</title>',
  350. output.data)
  351. self.assertIn(
  352. '<span class="oi red-icon" data-glyph="lock-locked" '
  353. 'title="Private issue"></span>', output.data)
  354. self.assertIn(
  355. '<a class="btn btn-primary btn-sm" '
  356. 'href="/test/issue/2/edit" title="Edit this issue">',
  357. output.data)
  358. # Project w/o issue tracker
  359. repo = pagure.lib.get_project(self.session, 'test')
  360. repo.settings = {'issue_tracker': False}
  361. self.session.add(repo)
  362. self.session.commit()
  363. output = self.app.get('/test/issue/1')
  364. self.assertEqual(output.status_code, 404)
  365. @patch('pagure.lib.git.update_git')
  366. @patch('pagure.lib.notify.send_email')
  367. def test_update_issue(self, p_send_email, p_ugt):
  368. """ Test the update_issue endpoint. """
  369. p_send_email.return_value = True
  370. p_ugt.return_value = True
  371. output = self.app.get('/foo/issue/1/update')
  372. self.assertEqual(output.status_code, 302)
  373. tests.create_projects(self.session)
  374. tests.create_projects_git(
  375. os.path.join(tests.HERE), bare=True)
  376. output = self.app.get('/test/issue/1/update')
  377. self.assertEqual(output.status_code, 302)
  378. # Create issues to play with
  379. repo = pagure.lib.get_project(self.session, 'test')
  380. msg = pagure.lib.new_issue(
  381. session=self.session,
  382. repo=repo,
  383. title='Test issue',
  384. content='We should work on this',
  385. user='pingou',
  386. ticketfolder=None
  387. )
  388. self.session.commit()
  389. self.assertEqual(msg.title, 'Test issue')
  390. user = tests.FakeUser()
  391. user.username = 'pingou'
  392. with tests.user_set(pagure.APP, user):
  393. output = self.app.get('/test/issue/1')
  394. self.assertEqual(output.status_code, 200)
  395. self.assertIn(
  396. '<title>Issue #1: Test issue - test - Pagure</title>',
  397. output.data)
  398. self.assertIn(
  399. '<a class="btn btn-primary btn-sm" '
  400. 'href="/test/issue/1/edit" title="Edit this issue">',
  401. output.data)
  402. csrf_token = output.data.split(
  403. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  404. data = {
  405. 'status': 'fixed'
  406. }
  407. # Invalid repo
  408. output = self.app.post('/bar/issue/1/update', data=data)
  409. self.assertEqual(output.status_code, 404)
  410. # Non-existing issue
  411. output = self.app.post('/test/issue/100/update', data=data)
  412. self.assertEqual(output.status_code, 404)
  413. output = self.app.post(
  414. '/test/issue/1/update', data=data, follow_redirects=True)
  415. self.assertEqual(output.status_code, 200)
  416. self.assertIn(
  417. '<title>Issue #1: Test issue - test - Pagure</title>',
  418. output.data)
  419. self.assertIn(
  420. '<a class="btn btn-primary btn-sm" '
  421. 'href="/test/issue/1/edit" title="Edit this issue">',
  422. output.data)
  423. self.assertFalse(
  424. '<option selected value="Fixed">Fixed</option>'
  425. in output.data)
  426. # Right status, wrong csrf
  427. data['status'] = 'Fixed'
  428. output = self.app.post(
  429. '/test/issue/1/update', data=data, follow_redirects=True)
  430. self.assertEqual(output.status_code, 200)
  431. self.assertIn(
  432. '<title>Issue #1: Test issue - test - Pagure</title>',
  433. output.data)
  434. self.assertIn(
  435. '<a class="btn btn-primary btn-sm" '
  436. 'href="/test/issue/1/edit" title="Edit this issue">',
  437. output.data)
  438. self.assertFalse(
  439. '<option selected value="Fixed">Fixed</option>'
  440. in output.data)
  441. # working status update
  442. data['csrf_token'] = csrf_token
  443. output = self.app.post(
  444. '/test/issue/1/update', data=data, follow_redirects=True)
  445. self.assertEqual(output.status_code, 200)
  446. self.assertIn(
  447. '<title>Issue #1: Test issue - test - Pagure</title>',
  448. output.data)
  449. self.assertIn(
  450. '<a class="btn btn-primary btn-sm" '
  451. 'href="/test/issue/1/edit" title="Edit this issue">',
  452. output.data)
  453. self.assertIn(
  454. '</button>\n Successfully edited issue #1',
  455. output.data)
  456. self.assertTrue(
  457. '<option selected value="Fixed">Fixed</option>'
  458. in output.data)
  459. self.assertIn(
  460. '<small><p><a href="/user/pingou"> @pingou</a> '
  461. 'changed the status to <code>Fixed</code></p></small>',
  462. output.data)
  463. # Add new comment
  464. data = {
  465. 'csrf_token': csrf_token,
  466. 'status': 'Fixed',
  467. 'comment': 'Woohoo a second comment !',
  468. }
  469. output = self.app.post(
  470. '/test/issue/1/update', data=data, follow_redirects=True)
  471. self.assertEqual(output.status_code, 200)
  472. self.assertIn(
  473. '<title>Issue #1: Test issue - test - Pagure</title>',
  474. output.data)
  475. self.assertIn(
  476. '<a class="btn btn-primary btn-sm" '
  477. 'href="/test/issue/1/edit" title="Edit this issue">',
  478. output.data)
  479. self.assertIn(
  480. '</button>\n Comment added',
  481. output.data)
  482. self.assertNotIn(
  483. '</button>\n No changes to edit',
  484. output.data)
  485. self.assertTrue(
  486. '<p>Woohoo a second comment !</p>' in output.data)
  487. self.assertEqual(output.data.count('comment_body">'), 2)
  488. self.assertTrue(
  489. '<option selected value="Fixed">Fixed</option>'
  490. in output.data)
  491. # Add new tag
  492. data = {
  493. 'csrf_token': csrf_token,
  494. 'status': 'Fixed',
  495. 'tag': 'tag2',
  496. }
  497. output = self.app.post(
  498. '/test/issue/1/update', data=data, follow_redirects=True)
  499. self.assertEqual(output.status_code, 200)
  500. self.assertIn(
  501. '<title>Issue #1: Test issue - test - Pagure</title>',
  502. output.data)
  503. self.assertIn(
  504. '<a class="btn btn-primary btn-sm" '
  505. 'href="/test/issue/1/edit" title="Edit this issue">',
  506. output.data)
  507. self.assertIn(
  508. '</button>\n Tag added: tag2',
  509. output.data)
  510. self.assertNotIn(
  511. '</button>\n No changes to edit',
  512. output.data)
  513. self.assertTrue(
  514. '<p>Woohoo a second comment !</p>' in output.data)
  515. self.assertEqual(output.data.count('comment_body">'), 2)
  516. self.assertTrue(
  517. '<option selected value="Fixed">Fixed</option>'
  518. in output.data)
  519. # Assign issue to an non-existent user
  520. data = {
  521. 'csrf_token': csrf_token,
  522. 'status': 'Fixed',
  523. 'assignee': 'ralph',
  524. }
  525. output = self.app.post(
  526. '/test/issue/1/update', data=data, follow_redirects=True)
  527. self.assertEqual(output.status_code, 200)
  528. self.assertIn(
  529. '<title>Issue #1: Test issue - test - Pagure</title>',
  530. output.data)
  531. self.assertIn(
  532. '<a class="btn btn-primary btn-sm" '
  533. 'href="/test/issue/1/edit" title="Edit this issue">',
  534. output.data)
  535. self.assertIn(
  536. '</button>\n No user &#34;ralph&#34; found',
  537. output.data)
  538. self.assertTrue(
  539. '<p>Woohoo a second comment !</p>' in output.data)
  540. self.assertEqual(output.data.count('comment_body">'), 2)
  541. self.assertTrue(
  542. '<option selected value="Fixed">Fixed</option>'
  543. in output.data)
  544. # Assign issue properly
  545. data = {
  546. 'csrf_token': csrf_token,
  547. 'status': 'Fixed',
  548. 'assignee': 'pingou',
  549. }
  550. output = self.app.post(
  551. '/test/issue/1/update', data=data, follow_redirects=True)
  552. self.assertEqual(output.status_code, 200)
  553. self.assertIn(
  554. '<title>Issue #1: Test issue - test - Pagure</title>',
  555. output.data)
  556. self.assertIn(
  557. '<a class="btn btn-primary btn-sm" '
  558. 'href="/test/issue/1/edit" title="Edit this issue">',
  559. output.data)
  560. self.assertIn(
  561. '</button>\n Issue assigned',
  562. output.data)
  563. self.assertTrue(
  564. '<a href="/test/issues?assignee=pingou">' in output.data)
  565. self.assertTrue(
  566. '<p>Woohoo a second comment !</p>' in output.data)
  567. self.assertEqual(output.data.count('comment_body">'), 2)
  568. self.assertTrue(
  569. '<option selected value="Fixed">Fixed</option>'
  570. in output.data)
  571. # Create another issue with a dependency
  572. repo = pagure.lib.get_project(self.session, 'test')
  573. msg = pagure.lib.new_issue(
  574. session=self.session,
  575. repo=repo,
  576. title='Test issue',
  577. content='We should work on this',
  578. user='pingou',
  579. ticketfolder=None
  580. )
  581. self.session.commit()
  582. self.assertEqual(msg.title, 'Test issue')
  583. # Reset the status of the first issue
  584. parent_issue = pagure.lib.search_issues(
  585. self.session, repo, issueid=2)
  586. parent_issue.status = 'Open'
  587. # Add the dependency relationship
  588. self.session.add(parent_issue)
  589. issue = pagure.lib.search_issues(self.session, repo, issueid=2)
  590. issue.parents.append(parent_issue)
  591. self.session.add(issue)
  592. self.session.commit()
  593. with tests.user_set(pagure.APP, user):
  594. data['csrf_token'] = csrf_token
  595. output = self.app.post(
  596. '/test/issue/2/update', data=data, follow_redirects=True)
  597. self.assertEqual(output.status_code, 200)
  598. self.assertIn(
  599. '<title>Issue #2: Test issue - test - Pagure</title>',
  600. output.data)
  601. self.assertIn(
  602. '<a class="btn btn-primary btn-sm" '
  603. 'href="/test/issue/2/edit" title="Edit this issue">',
  604. output.data)
  605. self.assertIn(
  606. '</button>\n You cannot close a ticket '
  607. 'that has ticket depending that are still open.',
  608. output.data)
  609. self.assertTrue(
  610. '<option selected value="Open">Open</option>'
  611. in output.data)
  612. # Create private issue
  613. repo = pagure.lib.get_project(self.session, 'test')
  614. msg = pagure.lib.new_issue(
  615. session=self.session,
  616. repo=repo,
  617. title='Test issue',
  618. content='We should work on this',
  619. user='pingou',
  620. ticketfolder=None,
  621. private=True,
  622. )
  623. self.session.commit()
  624. self.assertEqual(msg.title, 'Test issue')
  625. # Wrong user
  626. user = tests.FakeUser()
  627. with tests.user_set(pagure.APP, user):
  628. output = self.app.post(
  629. '/test/issue/3/update', data=data, follow_redirects=True)
  630. self.assertEqual(output.status_code, 403)
  631. # Project w/o issue tracker
  632. repo = pagure.lib.get_project(self.session, 'test')
  633. repo.settings = {'issue_tracker': False}
  634. self.session.add(repo)
  635. self.session.commit()
  636. with tests.user_set(pagure.APP, user):
  637. output = self.app.get('/test/issue/1/update')
  638. self.assertEqual(output.status_code, 302)
  639. # Repo not set-up for issue tracker
  640. output = self.app.post('/test/issue/1/update', data=data)
  641. self.assertEqual(output.status_code, 404)
  642. @patch('pagure.lib.git.update_git')
  643. @patch('pagure.lib.notify.send_email')
  644. def test_update_issue_drop_comment(self, p_send_email, p_ugt):
  645. """ Test droping comment via the update_issue endpoint. """
  646. p_send_email.return_value = True
  647. p_ugt.return_value = True
  648. tests.create_projects(self.session)
  649. tests.create_projects_git(
  650. os.path.join(tests.HERE), bare=True)
  651. # Create issues to play with
  652. repo = pagure.lib.get_project(self.session, 'test')
  653. msg = pagure.lib.new_issue(
  654. session=self.session,
  655. repo=repo,
  656. title='Test issue',
  657. content='We should work on this',
  658. user='pingou',
  659. ticketfolder=None
  660. )
  661. self.session.commit()
  662. self.assertEqual(msg.title, 'Test issue')
  663. user = tests.FakeUser()
  664. user.username = 'pingou'
  665. with tests.user_set(pagure.APP, user):
  666. output = self.app.get('/test/issue/1')
  667. self.assertEqual(output.status_code, 200)
  668. self.assertIn(
  669. '<title>Issue #1: Test issue - test - Pagure</title>',
  670. output.data)
  671. self.assertIn(
  672. '<a class="btn btn-primary btn-sm" '
  673. 'href="/test/issue/1/edit" title="Edit this issue">',
  674. output.data)
  675. csrf_token = output.data.split(
  676. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  677. # Add new comment
  678. data = {
  679. 'csrf_token': csrf_token,
  680. 'comment': 'Woohoo a second comment !',
  681. }
  682. output = self.app.post(
  683. '/test/issue/1/update', data=data, follow_redirects=True)
  684. self.assertEqual(output.status_code, 200)
  685. self.assertIn(
  686. '<title>Issue #1: Test issue - test - Pagure</title>',
  687. output.data)
  688. self.assertIn(
  689. '<a class="btn btn-primary btn-sm" '
  690. 'href="/test/issue/1/edit" title="Edit this issue">',
  691. output.data)
  692. self.assertIn(
  693. '</button>\n Comment added',
  694. output.data)
  695. self.assertTrue(
  696. '<p>Woohoo a second comment !</p>' in output.data)
  697. self.assertEqual(output.data.count('comment_body">'), 2)
  698. repo = pagure.lib.get_project(self.session, 'test')
  699. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  700. self.assertEqual(len(issue.comments), 1)
  701. data = {
  702. 'csrf_token': csrf_token,
  703. 'drop_comment': 1,
  704. }
  705. user = tests.FakeUser()
  706. with tests.user_set(pagure.APP, user):
  707. # Wrong issue id
  708. output = self.app.post(
  709. '/test/issue/3/update', data=data, follow_redirects=True)
  710. self.assertEqual(output.status_code, 404)
  711. # Wrong user
  712. output = self.app.post(
  713. '/test/issue/1/update', data=data, follow_redirects=True)
  714. self.assertEqual(output.status_code, 403)
  715. user = tests.FakeUser()
  716. user.username = 'pingou'
  717. with tests.user_set(pagure.APP, user):
  718. # Drop the new comment
  719. output = self.app.post(
  720. '/test/issue/1/update', data=data, follow_redirects=True)
  721. self.assertEqual(output.status_code, 200)
  722. self.assertIn(
  723. '<title>Issue #1: Test issue - test - Pagure</title>',
  724. output.data)
  725. self.assertIn(
  726. '<a class="btn btn-primary btn-sm" '
  727. 'href="/test/issue/1/edit" title="Edit this issue">',
  728. output.data)
  729. self.assertIn(
  730. '</button>\n Comment removed',
  731. output.data)
  732. # Drop non-existant comment
  733. output = self.app.post(
  734. '/test/issue/1/update', data=data, follow_redirects=True)
  735. self.assertEqual(output.status_code, 404)
  736. repo = pagure.lib.get_project(self.session, 'test')
  737. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  738. self.assertEqual(len(issue.comments), 0)
  739. @patch('pagure.lib.git.update_git')
  740. @patch('pagure.lib.notify.send_email')
  741. def test_update_issue_depend(self, p_send_email, p_ugt):
  742. """ Test adding dependency via the update_issue endpoint. """
  743. p_send_email.return_value = True
  744. p_ugt.return_value = True
  745. tests.create_projects(self.session)
  746. tests.create_projects_git(
  747. os.path.join(tests.HERE), bare=True)
  748. # Create issues to play with
  749. repo = pagure.lib.get_project(self.session, 'test')
  750. msg = pagure.lib.new_issue(
  751. session=self.session,
  752. repo=repo,
  753. title='Test issue',
  754. content='We should work on this',
  755. user='pingou',
  756. ticketfolder=None
  757. )
  758. self.session.commit()
  759. self.assertEqual(msg.title, 'Test issue')
  760. repo = pagure.lib.get_project(self.session, 'test')
  761. msg = pagure.lib.new_issue(
  762. session=self.session,
  763. repo=repo,
  764. title='Test issue #2',
  765. content='We should work on this again',
  766. user='foo',
  767. ticketfolder=None
  768. )
  769. self.session.commit()
  770. self.assertEqual(msg.title, 'Test issue #2')
  771. user = tests.FakeUser()
  772. user.username = 'pingou'
  773. with tests.user_set(pagure.APP, user):
  774. output = self.app.get('/test/issue/1')
  775. self.assertEqual(output.status_code, 200)
  776. self.assertIn(
  777. '<title>Issue #1: Test issue - test - Pagure</title>',
  778. output.data)
  779. self.assertIn(
  780. '<a class="btn btn-primary btn-sm" '
  781. 'href="/test/issue/1/edit" title="Edit this issue">',
  782. output.data)
  783. csrf_token = output.data.split(
  784. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  785. # Add a dependent ticket
  786. data = {
  787. 'csrf_token': csrf_token,
  788. 'depends': '2',
  789. }
  790. output = self.app.post(
  791. '/test/issue/1/update', data=data, follow_redirects=True)
  792. self.assertEqual(output.status_code, 200)
  793. self.assertIn(
  794. '<title>Issue #1: Test issue - test - Pagure</title>',
  795. output.data)
  796. self.assertIn(
  797. '<a class="btn btn-primary btn-sm" '
  798. 'href="/test/issue/1/edit" title="Edit this issue">',
  799. output.data)
  800. self.assertIn(
  801. '</button>\n Dependency added',
  802. output.data)
  803. # Add an invalid dependent ticket
  804. data = {
  805. 'csrf_token': csrf_token,
  806. 'depends': '2,abc',
  807. }
  808. output = self.app.post(
  809. '/test/issue/1/update', data=data, follow_redirects=True)
  810. self.assertEqual(output.status_code, 200)
  811. self.assertIn(
  812. '<title>Issue #1: Test issue - test - Pagure</title>',
  813. output.data)
  814. self.assertIn(
  815. '<a class="btn btn-primary btn-sm" '
  816. 'href="/test/issue/1/edit" title="Edit this issue">',
  817. output.data)
  818. self.assertNotIn(
  819. '</button>\n Dependency added',
  820. output.data)
  821. repo = pagure.lib.get_project(self.session, 'test')
  822. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  823. self.assertEqual(issue.depends_text, [2])
  824. self.assertEqual(issue.blocks_text, [])
  825. @patch('pagure.lib.git.update_git')
  826. @patch('pagure.lib.notify.send_email')
  827. def test_update_issue_block(self, p_send_email, p_ugt):
  828. """ Test adding blocked issue via the update_issue endpoint. """
  829. p_send_email.return_value = True
  830. p_ugt.return_value = True
  831. tests.create_projects(self.session)
  832. tests.create_projects_git(
  833. os.path.join(tests.HERE), bare=True)
  834. # Create issues to play with
  835. repo = pagure.lib.get_project(self.session, 'test')
  836. msg = pagure.lib.new_issue(
  837. session=self.session,
  838. repo=repo,
  839. title='Test issue',
  840. content='We should work on this',
  841. user='pingou',
  842. ticketfolder=None
  843. )
  844. self.session.commit()
  845. self.assertEqual(msg.title, 'Test issue')
  846. repo = pagure.lib.get_project(self.session, 'test')
  847. msg = pagure.lib.new_issue(
  848. session=self.session,
  849. repo=repo,
  850. title='Test issue #2',
  851. content='We should work on this again',
  852. user='foo',
  853. ticketfolder=None
  854. )
  855. self.session.commit()
  856. self.assertEqual(msg.title, 'Test issue #2')
  857. user = tests.FakeUser()
  858. user.username = 'pingou'
  859. with tests.user_set(pagure.APP, user):
  860. output = self.app.get('/test/issue/1')
  861. self.assertEqual(output.status_code, 200)
  862. self.assertIn(
  863. '<title>Issue #1: Test issue - test - Pagure</title>',
  864. output.data)
  865. self.assertIn(
  866. '<a class="btn btn-primary btn-sm" '
  867. 'href="/test/issue/1/edit" title="Edit this issue">',
  868. output.data)
  869. csrf_token = output.data.split(
  870. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  871. # Add a dependent ticket
  872. data = {
  873. 'csrf_token': csrf_token,
  874. 'blocks': '2',
  875. }
  876. output = self.app.post(
  877. '/test/issue/1/update', data=data, follow_redirects=True)
  878. self.assertEqual(output.status_code, 200)
  879. self.assertIn(
  880. '<title>Issue #1: Test issue - test - Pagure</title>',
  881. output.data)
  882. self.assertIn(
  883. '<a class="btn btn-primary btn-sm" '
  884. 'href="/test/issue/1/edit" title="Edit this issue">',
  885. output.data)
  886. self.assertIn(
  887. '</button>\n Dependency added',
  888. output.data)
  889. # Add an invalid dependent ticket
  890. data = {
  891. 'csrf_token': csrf_token,
  892. 'blocks': '2,abc',
  893. }
  894. output = self.app.post(
  895. '/test/issue/1/update', data=data, follow_redirects=True)
  896. self.assertEqual(output.status_code, 200)
  897. self.assertIn(
  898. '<title>Issue #1: Test issue - test - Pagure</title>',
  899. output.data)
  900. self.assertIn(
  901. '<a class="btn btn-primary btn-sm" '
  902. 'href="/test/issue/1/edit" title="Edit this issue">',
  903. output.data)
  904. self.assertNotIn(
  905. '</button>\n Dependency added',
  906. output.data)
  907. repo = pagure.lib.get_project(self.session, 'test')
  908. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  909. self.assertEqual(issue.depends_text, [])
  910. self.assertEqual(issue.blocks_text, [2])
  911. @patch('pagure.lib.git.update_git')
  912. @patch('pagure.lib.notify.send_email')
  913. def test_upload_issue(self, p_send_email, p_ugt):
  914. """ Test the upload_issue endpoint. """
  915. p_send_email.return_value = True
  916. p_ugt.return_value = True
  917. tests.create_projects(self.session)
  918. tests.create_projects_git(
  919. os.path.join(tests.HERE), bare=True)
  920. tests.create_projects_git(
  921. os.path.join(tests.HERE, 'tickets'), bare=True)
  922. # Create issues to play with
  923. repo = pagure.lib.get_project(self.session, 'test')
  924. msg = pagure.lib.new_issue(
  925. session=self.session,
  926. repo=repo,
  927. title='Test issue',
  928. content='We should work on this',
  929. user='pingou',
  930. ticketfolder=None
  931. )
  932. self.session.commit()
  933. self.assertEqual(msg.title, 'Test issue')
  934. user = tests.FakeUser()
  935. user.username = 'pingou'
  936. with tests.user_set(pagure.APP, user):
  937. output = self.app.get('/test/issue/1')
  938. self.assertEqual(output.status_code, 200)
  939. self.assertIn(
  940. '<title>Issue #1: Test issue - test - Pagure</title>',
  941. output.data)
  942. self.assertIn(
  943. '<a class="btn btn-primary btn-sm" '
  944. 'href="/test/issue/1/edit" title="Edit this issue">',
  945. output.data)
  946. csrf_token = output.data.split(
  947. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  948. output = self.app.post('/foo/issue/1/upload')
  949. self.assertEqual(output.status_code, 404)
  950. output = self.app.post('/test/issue/100/upload')
  951. self.assertEqual(output.status_code, 404)
  952. # Invalid upload
  953. data = {
  954. 'enctype': 'multipart/form-data',
  955. }
  956. output = self.app.post(
  957. '/test/issue/1/upload', data=data, follow_redirects=True)
  958. self.assertEqual(output.status_code, 200)
  959. json_data = json.loads(output.data)
  960. exp = {'output': 'notok'}
  961. self.assertDictEqual(json_data, exp)
  962. # Attach a file to a ticket
  963. stream = open(os.path.join(tests.HERE, 'placebo.png'), 'rb')
  964. data = {
  965. 'csrf_token': csrf_token,
  966. 'filestream': stream,
  967. 'enctype': 'multipart/form-data',
  968. }
  969. output = self.app.post(
  970. '/test/issue/1/upload', data=data, follow_redirects=True)
  971. stream.close()
  972. self.assertEqual(output.status_code, 200)
  973. json_data = json.loads(output.data)
  974. folder = os.path.dirname(
  975. os.path.abspath(__file__))[1:].replace('/', '_')
  976. exp = {
  977. 'output': 'ok',
  978. 'filelocation': '/test/issue/raw/files/8a06845923010b27bfd8'
  979. 'e7e75acff7badc40d1021b4994e01f5e11ca40bc3a'
  980. 'be-%s_placebo.png' % folder,
  981. 'filename': '%s_placebo.png' % folder,
  982. }
  983. self.assertDictEqual(json_data, exp)
  984. # Project w/o issue tracker
  985. repo = pagure.lib.get_project(self.session, 'test')
  986. repo.settings = {'issue_tracker': False}
  987. self.session.add(repo)
  988. self.session.commit()
  989. with tests.user_set(pagure.APP, user):
  990. output = self.app.post('/test/issue/1/upload')
  991. self.assertEqual(output.status_code, 404)
  992. def test_view_issue_raw_file_empty(self):
  993. """ Test the view_issue_raw_file endpoint. """
  994. # Create the project and git repos
  995. tests.create_projects(self.session)
  996. tests.create_projects_git(
  997. os.path.join(tests.HERE, 'tickets'), bare=True)
  998. # Create issues to play with
  999. repo = pagure.lib.get_project(self.session, 'test')
  1000. msg = pagure.lib.new_issue(
  1001. session=self.session,
  1002. repo=repo,
  1003. title='Test issue',
  1004. content='We should work on this',
  1005. user='pingou',
  1006. ticketfolder=None
  1007. )
  1008. self.session.commit()
  1009. self.assertEqual(msg.title, 'Test issue')
  1010. url = '/issue/raw/files/8a06845923010b27bfd8'\
  1011. 'e7e75acff7badc40d1021b4994e01f5e11ca40bc3a'\
  1012. 'be-home_pierrey_repos_gitrepo_pagure_tests'\
  1013. '_placebo.png'
  1014. output = self.app.get('/foo' + url)
  1015. self.assertEqual(output.status_code, 404)
  1016. output = self.app.get('/test' + url)
  1017. self.assertEqual(output.status_code, 404)
  1018. # Project w/o issue tracker
  1019. repo = pagure.lib.get_project(self.session, 'test')
  1020. repo.settings = {'issue_tracker': False}
  1021. self.session.add(repo)
  1022. self.session.commit()
  1023. output = self.app.get('/test' + url)
  1024. self.assertEqual(output.status_code, 404)
  1025. def test_view_issue_raw_file(self):
  1026. """ Test the view_issue_raw_file endpoint. """
  1027. # Create the issue and upload to it
  1028. self.test_upload_issue()
  1029. # Project w/ issue tracker
  1030. repo = pagure.lib.get_project(self.session, 'test')
  1031. repo.settings = {'issue_tracker': True}
  1032. self.session.add(repo)
  1033. self.session.commit()
  1034. url = '/issue/raw/files/8a06845923010b27bfd8'\
  1035. 'e7e75acff7badc40d1021b4994e01f5e11ca40bc3a'\
  1036. 'be-%s_placebo.png' % os.path.dirname(
  1037. os.path.abspath(__file__))[1:].replace('/', '_')
  1038. output = self.app.get('/foo' + url)
  1039. self.assertEqual(output.status_code, 404)
  1040. output = self.app.get('/test/issue/raw/files/test.png')
  1041. self.assertEqual(output.status_code, 404)
  1042. # Access file by name
  1043. output = self.app.get('/test' + url)
  1044. self.assertEqual(output.status_code, 200)
  1045. # Project w/o issue tracker
  1046. repo = pagure.lib.get_project(self.session, 'test')
  1047. repo.settings = {'issue_tracker': False}
  1048. self.session.add(repo)
  1049. self.session.commit()
  1050. output = self.app.get('/test' + url)
  1051. self.assertEqual(output.status_code, 404)
  1052. @patch('pagure.lib.git.update_git')
  1053. @patch('pagure.lib.notify.send_email')
  1054. def test_edit_issue(self, p_send_email, p_ugt):
  1055. """ Test the edit_issue endpoint. """
  1056. p_send_email.return_value = True
  1057. p_ugt.return_value = True
  1058. output = self.app.get('/foo/issue/1/edit')
  1059. self.assertEqual(output.status_code, 302)
  1060. user = tests.FakeUser()
  1061. with tests.user_set(pagure.APP, user):
  1062. output = self.app.get('/foo/issue/1/edit')
  1063. self.assertEqual(output.status_code, 404)
  1064. tests.create_projects(self.session)
  1065. tests.create_projects_git(
  1066. os.path.join(tests.HERE), bare=True)
  1067. output = self.app.get('/test/issue/1/edit')
  1068. self.assertEqual(output.status_code, 404)
  1069. user.username = 'pingou'
  1070. with tests.user_set(pagure.APP, user):
  1071. output = self.app.get('/test/issue/1/edit')
  1072. self.assertEqual(output.status_code, 404)
  1073. # Create issues to play with
  1074. repo = pagure.lib.get_project(self.session, 'test')
  1075. msg = pagure.lib.new_issue(
  1076. session=self.session,
  1077. repo=repo,
  1078. title='Test issue',
  1079. content='We should work on this',
  1080. user='pingou',
  1081. ticketfolder=None
  1082. )
  1083. self.session.commit()
  1084. self.assertEqual(msg.title, 'Test issue')
  1085. user = tests.FakeUser()
  1086. with tests.user_set(pagure.APP, user):
  1087. output = self.app.get('/test/issue/1/edit')
  1088. self.assertEqual(output.status_code, 403)
  1089. user.username = 'pingou'
  1090. with tests.user_set(pagure.APP, user):
  1091. output = self.app.get('/test/issue/1/edit')
  1092. self.assertEqual(output.status_code, 200)
  1093. self.assertTrue(
  1094. '<div class="card-header">\n Edit '
  1095. 'issue #1\n </div>' in output.data)
  1096. csrf_token = output.data.split(
  1097. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1098. data = {
  1099. 'issue_content': 'We should work on this!'
  1100. }
  1101. output = self.app.post('/test/issue/1/edit', data=data)
  1102. self.assertEqual(output.status_code, 200)
  1103. self.assertTrue(
  1104. '<div class="card-header">\n Edit '
  1105. 'issue #1\n </div>' in output.data)
  1106. self.assertEqual(output.data.count(
  1107. '<small>\n This field is required.&nbsp;\n'
  1108. ' </small>'), 1)
  1109. self.assertEqual(output.data.count(
  1110. '<small>\n Not a valid choice&nbsp;'
  1111. '\n </small>'), 1)
  1112. data['status'] = 'Open'
  1113. data['title'] = 'Test issue #1'
  1114. output = self.app.post('/test/issue/1/edit', data=data)
  1115. self.assertEqual(output.status_code, 200)
  1116. self.assertTrue(
  1117. '<div class="card-header">\n Edit '
  1118. 'issue #1\n </div>' in output.data)
  1119. self.assertEqual(output.data.count(
  1120. '<small>\n This field is required.&nbsp;\n'
  1121. ' </small>'), 0)
  1122. self.assertEqual(output.data.count(
  1123. '<small>\n Not a valid choice&nbsp;'
  1124. '\n </small>'), 0)
  1125. data['csrf_token'] = csrf_token
  1126. output = self.app.post(
  1127. '/test/issue/1/edit', data=data, follow_redirects=True)
  1128. self.assertEqual(output.status_code, 200)
  1129. self.assertIn(
  1130. '</button>\n Successfully edited issue #1',
  1131. output.data)
  1132. self.assertIn(
  1133. '<span class="issueid label label-default">#1</span>\n'
  1134. ' <span id="issuetitle">Test issue #1</span>',
  1135. output.data)
  1136. self.assertEqual(output.data.count(
  1137. '<option selected value="Open">Open</option>'), 1)
  1138. self.assertEqual(output.data.count('comment_body">'), 1)
  1139. self.assertEqual(output.data.count(
  1140. '<p>We should work on this!</p>'), 1)
  1141. # Project w/o issue tracker
  1142. repo = pagure.lib.get_project(self.session, 'test')
  1143. repo.settings = {'issue_tracker': False}
  1144. self.session.add(repo)
  1145. self.session.commit()
  1146. user.username = 'pingou'
  1147. with tests.user_set(pagure.APP, user):
  1148. output = self.app.post('/test/issue/1/edit', data=data)
  1149. self.assertEqual(output.status_code, 404)
  1150. @patch('pagure.lib.git.update_git')
  1151. @patch('pagure.lib.notify.send_email')
  1152. def test_edit_tag(self, p_send_email, p_ugt):
  1153. """ Test the edit_tag endpoint. """
  1154. p_send_email.return_value = True
  1155. p_ugt.return_value = True
  1156. output = self.app.get('/foo/tag/foo/edit')
  1157. self.assertEqual(output.status_code, 302)
  1158. user = tests.FakeUser()
  1159. with tests.user_set(pagure.APP, user):
  1160. output = self.app.get('/foo/tag/foo/edit')
  1161. self.assertEqual(output.status_code, 404)
  1162. tests.create_projects(self.session)
  1163. output = self.app.get('/test/tag/foo/edit')
  1164. self.assertEqual(output.status_code, 403)
  1165. # Create issues to play with
  1166. repo = pagure.lib.get_project(self.session, 'test')
  1167. msg = pagure.lib.new_issue(
  1168. session=self.session,
  1169. repo=repo,
  1170. title='Test issue',
  1171. content='We should work on this',
  1172. user='pingou',
  1173. ticketfolder=None
  1174. )
  1175. self.session.commit()
  1176. self.assertEqual(msg.title, 'Test issue')
  1177. # Add a tag to the issue
  1178. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1179. msg = pagure.lib.add_tag_obj(
  1180. session=self.session,
  1181. obj=issue,
  1182. tags='tag1',
  1183. user='pingou',
  1184. ticketfolder=None)
  1185. self.session.commit()
  1186. self.assertEqual(msg, 'Tag added: tag1')
  1187. # Before edit, list tags
  1188. tags = pagure.lib.get_tags_of_project(self.session, repo)
  1189. self.assertEqual([tag.tag for tag in tags], ['tag1'])
  1190. # Edit tag
  1191. user.username = 'pingou'
  1192. with tests.user_set(pagure.APP, user):
  1193. #Edit a tag that doesn't exit
  1194. output = self.app.get('/test/tag/does_not_exist/edit')
  1195. self.assertEqual(output.status_code, 404)
  1196. output = self.app.get('/test/tag/tag1/edit')
  1197. self.assertEqual(output.status_code, 200)
  1198. self.assertTrue('<h2>Edit tag: tag1</h2>' in output.data)
  1199. self.assertTrue(
  1200. '<p>Enter in the field below the new name for the tag: '
  1201. '"tag1"</p>' in output.data)
  1202. csrf_token = output.data.split(
  1203. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1204. data = {'tag': 'tag2'}
  1205. output = self.app.post('/test/tag/tag1/edit', data=data)
  1206. self.assertEqual(output.status_code, 200)
  1207. self.assertTrue('<h2>Edit tag: tag1</h2>' in output.data)
  1208. self.assertTrue(
  1209. '<p>Enter in the field below the new name for the tag: '
  1210. '"tag1"</p>' in output.data)
  1211. data['csrf_token'] = csrf_token
  1212. tests.create_projects_git(tests.HERE)
  1213. output = self.app.post(
  1214. '/test/tag/tag1/edit', data=data, follow_redirects=True)
  1215. self.assertEqual(output.status_code, 200)
  1216. self.assertIn(
  1217. '<title>Settings - test - Pagure</title>', output.data)
  1218. self.assertIn(
  1219. '</button>\n Edited tag: tag1 to tag2',
  1220. output.data)
  1221. # After edit, list tags
  1222. tags = pagure.lib.get_tags_of_project(self.session, repo)
  1223. self.assertEqual([tag.tag for tag in tags], ['tag2'])
  1224. @patch('pagure.lib.git.update_git')
  1225. @patch('pagure.lib.notify.send_email')
  1226. def test_remove_tag(self, p_send_email, p_ugt):
  1227. """ Test the remove_tag endpoint. """
  1228. p_send_email.return_value = True
  1229. p_ugt.return_value = True
  1230. output = self.app.post('/foo/droptag/')
  1231. self.assertEqual(output.status_code, 302)
  1232. user = tests.FakeUser()
  1233. with tests.user_set(pagure.APP, user):
  1234. output = self.app.post('/foo/droptag/')
  1235. self.assertEqual(output.status_code, 404)
  1236. tests.create_projects(self.session)
  1237. output = self.app.post('/test/droptag/')
  1238. self.assertEqual(output.status_code, 403)
  1239. # Create issues to play with
  1240. repo = pagure.lib.get_project(self.session, 'test')
  1241. msg = pagure.lib.new_issue(
  1242. session=self.session,
  1243. repo=repo,
  1244. title='Test issue',
  1245. content='We should work on this',
  1246. user='pingou',
  1247. ticketfolder=None
  1248. )
  1249. self.session.commit()
  1250. self.assertEqual(msg.title, 'Test issue')
  1251. # Add a tag to the issue
  1252. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1253. msg = pagure.lib.add_tag_obj(
  1254. session=self.session,
  1255. obj=issue,
  1256. tags='tag1',
  1257. user='pingou',
  1258. ticketfolder=None)
  1259. self.session.commit()
  1260. self.assertEqual(msg, 'Tag added: tag1')
  1261. # Before edit, list tags
  1262. tags = pagure.lib.get_tags_of_project(self.session, repo)
  1263. self.assertEqual([tag.tag for tag in tags], ['tag1'])
  1264. # Edit tag
  1265. user.username = 'pingou'
  1266. with tests.user_set(pagure.APP, user):
  1267. tests.create_projects_git(tests.HERE)
  1268. output = self.app.post(
  1269. '/test/droptag/', data={}, follow_redirects=True)
  1270. self.assertEqual(output.status_code, 200)
  1271. self.assertTrue(
  1272. '<title>Settings - test - Pagure</title>' in output.data)
  1273. self.assertTrue("<h3>Settings for test</h3>" in output.data)
  1274. csrf_token = output.data.split(
  1275. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1276. data = {'tag': 'tag1'}
  1277. output = self.app.post(
  1278. '/test/droptag/', data=data, follow_redirects=True)
  1279. self.assertEqual(output.status_code, 200)
  1280. self.assertTrue("<h3>Settings for test</h3>" in output.data)
  1281. data['csrf_token'] = csrf_token
  1282. output = self.app.post(
  1283. '/test/droptag/', data=data, follow_redirects=True)
  1284. self.assertEqual(output.status_code, 200)
  1285. self.assertTrue("<h3>Settings for test</h3>" in output.data)
  1286. self.assertIn(
  1287. '</button>\n Removed tag: tag1',
  1288. output.data)
  1289. @patch('pagure.lib.git.update_git')
  1290. @patch('pagure.lib.notify.send_email')
  1291. def test_delete_issue(self, p_send_email, p_ugt):
  1292. """ Test the delete_issue endpoint. """
  1293. p_send_email.return_value = True
  1294. p_ugt.return_value = True
  1295. tests.create_projects(self.session)
  1296. tests.create_projects_git(tests.HERE)
  1297. tests.create_projects_git(os.path.join(tests.HERE, 'tickets'))
  1298. # Create issues to play with
  1299. repo = pagure.lib.get_project(self.session, 'test')
  1300. msg = pagure.lib.new_issue(
  1301. session=self.session,
  1302. repo=repo,
  1303. title='Test issue',
  1304. content='We should work on this',
  1305. user='pingou',
  1306. ticketfolder=None
  1307. )
  1308. self.session.commit()
  1309. self.assertEqual(msg.title, 'Test issue')
  1310. user = tests.FakeUser()
  1311. with tests.user_set(pagure.APP, user):
  1312. output = self.app.post(
  1313. '/foo/issue/1/drop', follow_redirects=True)
  1314. self.assertEqual(output.status_code, 404)
  1315. output = self.app.post(
  1316. '/test/issue/100/drop', follow_redirects=True)
  1317. self.assertEqual(output.status_code, 404)
  1318. output = self.app.post(
  1319. '/test/issue/1/drop', follow_redirects=True)
  1320. self.assertEqual(output.status_code, 403)
  1321. user.username = 'pingou'
  1322. with tests.user_set(pagure.APP, user):
  1323. output = self.app.post(
  1324. '/test/issue/1/drop', follow_redirects=True)
  1325. self.assertEqual(output.status_code, 200)
  1326. self.assertIn(
  1327. '<title>Issue #1: Test issue - test - Pagure</title>',
  1328. output.data)
  1329. csrf_token = output.data.split(
  1330. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1331. data = {
  1332. }
  1333. # No CSRF token
  1334. output = self.app.post(
  1335. '/test/issue/1/drop', data=data, follow_redirects=True)
  1336. self.assertEqual(output.status_code, 200)
  1337. self.assertIn(
  1338. '<title>Issue #1: Test issue - test - Pagure</title>',
  1339. output.data)
  1340. data['csrf_token'] = csrf_token
  1341. output = self.app.post(
  1342. '/test/issue/1/drop', data=data, follow_redirects=True)
  1343. self.assertEqual(output.status_code, 200)
  1344. self.assertIn(
  1345. '<title>Issues - test - Pagure</title>', output.data)
  1346. self.assertIn(
  1347. '</button>\n Issue deleted',
  1348. output.data)
  1349. # Project w/o issue tracker
  1350. repo = pagure.lib.get_project(self.session, 'test')
  1351. repo.settings = {'issue_tracker': False}
  1352. self.session.add(repo)
  1353. self.session.commit()
  1354. user.username = 'pingou'
  1355. with tests.user_set(pagure.APP, user):
  1356. output = self.app.post('/test/issue/1/drop', data=data)
  1357. self.assertEqual(output.status_code, 404)
  1358. @patch('pagure.lib.git.update_git')
  1359. @patch('pagure.lib.notify.send_email')
  1360. def test_update_issue_edit_comment(self, p_send_email, p_ugt):
  1361. """ Test the issues edit comment endpoint """
  1362. p_send_email.return_value = True
  1363. p_ugt.return_value = True
  1364. tests.create_projects(self.session)
  1365. tests.create_projects_git(
  1366. os.path.join(tests.HERE), bare=True)
  1367. # Create issues to play with
  1368. repo = pagure.lib.get_project(self.session, 'test')
  1369. msg = pagure.lib.new_issue(
  1370. session=self.session,
  1371. repo=repo,
  1372. title='Test issue',
  1373. content='We should work on this',
  1374. user='pingou',
  1375. ticketfolder=None
  1376. )
  1377. self.session.commit()
  1378. self.assertEqual(msg.title, 'Test issue')
  1379. user = tests.FakeUser()
  1380. user.username = 'pingou'
  1381. with tests.user_set(pagure.APP, user):
  1382. output = self.app.get('/test/issue/1')
  1383. self.assertEqual(output.status_code, 200)
  1384. self.assertIn(
  1385. '<title>Issue #1: Test issue - test - Pagure</title>',
  1386. output.data)
  1387. self.assertIn(
  1388. '<a class="btn btn-primary btn-sm" '
  1389. 'href="/test/issue/1/edit" title="Edit this issue">',
  1390. output.data)
  1391. csrf_token = output.data.split(
  1392. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1393. # Add new comment
  1394. data = {
  1395. 'csrf_token': csrf_token,
  1396. 'comment': 'Woohoo a second comment !',
  1397. }
  1398. output = self.app.post(
  1399. '/test/issue/1/update', data=data, follow_redirects=True)
  1400. self.assertEqual(output.status_code, 200)
  1401. self.assertIn(
  1402. '<title>Issue #1: Test issue - test - Pagure</title>',
  1403. output.data)
  1404. self.assertIn(
  1405. '<a class="btn btn-primary btn-sm" '
  1406. 'href="/test/issue/1/edit" title="Edit this issue">',
  1407. output.data)
  1408. self.assertIn(
  1409. '</button>\n Comment added',
  1410. output.data)
  1411. self.assertTrue(
  1412. '<p>Woohoo a second comment !</p>' in output.data)
  1413. self.assertEqual(output.data.count('comment_body">'), 2)
  1414. repo = pagure.lib.get_project(self.session, 'test')
  1415. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1416. self.assertEqual(len(issue.comments), 1)
  1417. self.assertEqual(
  1418. issue.comments[0].comment,
  1419. 'Woohoo a second comment !')
  1420. data = {
  1421. 'csrf_token': csrf_token,
  1422. 'edit_comment': 1,
  1423. 'update_comment': 'Updated comment',
  1424. }
  1425. user = tests.FakeUser()
  1426. with tests.user_set(pagure.APP, user):
  1427. # Wrong issue id
  1428. output = self.app.post(
  1429. '/test/issue/3/update', data=data, follow_redirects=True)
  1430. self.assertEqual(output.status_code, 404)
  1431. # Wrong user
  1432. output = self.app.post(
  1433. '/test/issue/1/update', data=data, follow_redirects=True)
  1434. self.assertEqual(output.status_code, 403)
  1435. user = tests.FakeUser()
  1436. user.username = 'pingou'
  1437. with tests.user_set(pagure.APP, user):
  1438. # Edit comment
  1439. output = self.app.post(
  1440. '/test/issue/1/update', data=data, follow_redirects=True)
  1441. self.assertEqual(output.status_code, 200)
  1442. self.assertIn(
  1443. '<title>Issue #1: Test issue - test - Pagure</title>',
  1444. output.data)
  1445. self.assertIn(
  1446. '<a class="btn btn-primary btn-sm" '
  1447. 'href="/test/issue/1/edit" title="Edit this issue">',
  1448. output.data)
  1449. self.assertIn(
  1450. '</button>\n Comment updated',
  1451. output.data)
  1452. repo = pagure.lib.get_project(self.session, 'test')
  1453. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1454. self.assertEqual(len(issue.comments), 1)
  1455. self.assertEqual(issue.comments[0].comment, 'Updated comment')
  1456. with tests.user_set(pagure.APP, user):
  1457. output = self.app.get('/test/issue/1/comment/1/edit')
  1458. self.assertIn(
  1459. '<title>test - Pagure</title>', output.data)
  1460. self.assertTrue('<div id="edit">' in output.data)
  1461. self.assertTrue('<section class="edit_comment">' in output.data)
  1462. self.assertTrue(
  1463. '<textarea class="form-control" id="update_comment"'
  1464. in output.data)
  1465. csrf_token = output.data.split(
  1466. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1467. data['csrf_token'] = csrf_token
  1468. data['update_comment'] = 'Second update'
  1469. # Edit the comment with the other endpoint
  1470. output = self.app.post(
  1471. '/test/issue/1/comment/1/edit',
  1472. data=data,
  1473. follow_redirects=True)
  1474. self.assertEqual(output.status_code, 200)
  1475. self.assertIn(
  1476. '<title>Issue #1: Test issue - test - Pagure</title>',
  1477. output.data)
  1478. self.assertIn(
  1479. '<a class="btn btn-primary btn-sm" '
  1480. 'href="/test/issue/1/edit" title="Edit this issue">',
  1481. output.data)
  1482. self.assertIn(
  1483. '</button>\n Comment updated',
  1484. output.data)
  1485. repo = pagure.lib.get_project(self.session, 'test')
  1486. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1487. self.assertEqual(len(issue.comments), 1)
  1488. self.assertEqual(issue.comments[0].comment, 'Second update')
  1489. @patch('pagure.lib.git.update_git')
  1490. @patch('pagure.lib.notify.send_email')
  1491. def test_git_urls(self, p_send_email, p_ugt):
  1492. """ Check that the url to the git repo for issues is present/absent when
  1493. it should.
  1494. """
  1495. p_send_email.return_value = True
  1496. p_ugt.return_value = True
  1497. self.test_view_issues()
  1498. user = tests.FakeUser()
  1499. user.username = 'pingou'
  1500. with tests.user_set(pagure.APP, user):
  1501. # Check that the git issue URL is present
  1502. output = self.app.get('/test')
  1503. self.assertNotIn(
  1504. '<h5><strong>Issues GIT URLs</strong></h5>', output.data)
  1505. # Project w/o issue tracker
  1506. repo = pagure.lib.get_project(self.session, 'test')
  1507. repo.settings = {'issue_tracker': True}
  1508. self.session.add(repo)
  1509. self.session.commit()
  1510. # Check that the git issue URL is gone
  1511. output = self.app.get('/test')
  1512. self.assertIn(
  1513. '<h5><strong>Issues GIT URLs</strong></h5>', output.data)
  1514. if __name__ == '__main__':
  1515. SUITE = unittest.TestLoader().loadTestsFromTestCase(PagureFlaskIssuestests)
  1516. unittest.TextTestRunner(verbosity=2).run(SUITE)