test_pagure_flask_ui_issues.py 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768
  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 pyclamd
  15. import tempfile
  16. import pygit2
  17. from mock import patch
  18. sys.path.insert(0, os.path.join(os.path.dirname(
  19. os.path.abspath(__file__)), '..'))
  20. import pagure.lib
  21. import tests
  22. class PagureFlaskIssuestests(tests.Modeltests):
  23. """ Tests for flask issues controller of pagure """
  24. def setUp(self):
  25. """ Set up the environnment, ran before every tests. """
  26. super(PagureFlaskIssuestests, self).setUp()
  27. pagure.APP.config['TESTING'] = True
  28. # TODO: Figure a way to enable this test on jenkins
  29. if not os.environ.get('BUILD_ID'):
  30. pagure.APP.config['VIRUS_SCAN_ATTACHMENTS'] = True
  31. pagure.SESSION = self.session
  32. pagure.ui.SESSION = self.session
  33. pagure.ui.app.SESSION = self.session
  34. pagure.ui.issues.SESSION = self.session
  35. pagure.ui.repo.SESSION = self.session
  36. pagure.ui.filters.SESSION = self.session
  37. pagure.APP.config['GIT_FOLDER'] = tests.HERE
  38. pagure.APP.config['FORK_FOLDER'] = os.path.join(
  39. tests.HERE, 'forks')
  40. pagure.APP.config['TICKETS_FOLDER'] = os.path.join(
  41. tests.HERE, 'tickets')
  42. pagure.APP.config['DOCS_FOLDER'] = os.path.join(
  43. tests.HERE, 'docs')
  44. self.app = pagure.APP.test_client()
  45. @patch('pagure.lib.git.update_git')
  46. @patch('pagure.lib.notify.send_email')
  47. def test_new_issue(self, p_send_email, p_ugt):
  48. """ Test the new_issue endpoint. """
  49. p_send_email.return_value = True
  50. p_ugt.return_value = True
  51. output = self.app.get('/foo/new_issue')
  52. self.assertEqual(output.status_code, 302)
  53. user = tests.FakeUser()
  54. with tests.user_set(pagure.APP, user):
  55. output = self.app.get('/foo/new_issue')
  56. self.assertEqual(output.status_code, 404)
  57. tests.create_projects(self.session)
  58. tests.create_projects_git(
  59. os.path.join(tests.HERE), bare=True)
  60. output = self.app.get('/test/new_issue')
  61. self.assertEqual(output.status_code, 200)
  62. self.assertTrue(
  63. '<div class="card-header">\n New issue'
  64. in output.data)
  65. csrf_token = output.data.split(
  66. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  67. data = {
  68. }
  69. # Insufficient input
  70. output = self.app.post('/test/new_issue', data=data)
  71. self.assertEqual(output.status_code, 200)
  72. self.assertTrue(
  73. '<div class="card-header">\n New issue'
  74. in output.data)
  75. self.assertEqual(output.data.count(
  76. 'This field is required.'), 2)
  77. data['title'] = 'Test issue'
  78. output = self.app.post('/test/new_issue', data=data)
  79. self.assertEqual(output.status_code, 200)
  80. self.assertTrue(
  81. '<div class="card-header">\n New issue'
  82. in output.data)
  83. self.assertEqual(output.data.count(
  84. 'This field is required.'), 1)
  85. data['issue_content'] = 'We really should improve on this issue'
  86. data['status'] = 'Open'
  87. output = self.app.post('/test/new_issue', data=data)
  88. self.assertEqual(output.status_code, 200)
  89. self.assertTrue(
  90. '<div class="card-header">\n New issue'
  91. in output.data)
  92. self.assertEqual(output.data.count(
  93. '</button>\n This field is required.'),
  94. 0)
  95. # Invalid user
  96. data['csrf_token'] = csrf_token
  97. output = self.app.post('/test/new_issue', data=data)
  98. self.assertEqual(output.status_code, 404)
  99. self.assertIn(
  100. '<p>No such user found in the database: username</p>',
  101. 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. # TODO: Figure a way to enable this test on jenkins
  963. # Try to attach a virus
  964. if not os.environ.get('BUILD_ID'):
  965. with tempfile.NamedTemporaryFile() as eicarfile:
  966. eicarfile.write(pyclamd.ClamdUnixSocket().EICAR())
  967. eicarfile.flush()
  968. stream = open(eicarfile.name, 'rb')
  969. data = {
  970. 'csrf_token': csrf_token,
  971. 'filestream': stream,
  972. 'enctype': 'multipart/form-data',
  973. }
  974. output = self.app.post(
  975. '/test/issue/1/upload', data=data, follow_redirects=True)
  976. self.assertEqual(output.status_code, 200)
  977. stream.close()
  978. json_data = json.loads(output.data)
  979. exp = {
  980. 'output': 'notok',
  981. }
  982. self.assertDictEqual(json_data, exp)
  983. # Attach a file to a ticket
  984. stream = open(os.path.join(tests.HERE, 'placebo.png'), 'rb')
  985. data = {
  986. 'csrf_token': csrf_token,
  987. 'filestream': stream,
  988. 'enctype': 'multipart/form-data',
  989. }
  990. output = self.app.post(
  991. '/test/issue/1/upload', data=data, follow_redirects=True)
  992. stream.close()
  993. self.assertEqual(output.status_code, 200)
  994. json_data = json.loads(output.data)
  995. folder = os.path.dirname(
  996. os.path.abspath(__file__))[1:].replace('/', '_')
  997. exp = {
  998. 'output': 'ok',
  999. 'filelocation': '/test/issue/raw/files/8a06845923010b27bfd8'
  1000. 'e7e75acff7badc40d1021b4994e01f5e11ca40bc3a'
  1001. 'be-%s_placebo.png' % folder,
  1002. 'filename': '%s_placebo.png' % folder,
  1003. }
  1004. self.assertDictEqual(json_data, exp)
  1005. # Project w/o issue tracker
  1006. repo = pagure.lib.get_project(self.session, 'test')
  1007. repo.settings = {'issue_tracker': False}
  1008. self.session.add(repo)
  1009. self.session.commit()
  1010. with tests.user_set(pagure.APP, user):
  1011. output = self.app.post('/test/issue/1/upload')
  1012. self.assertEqual(output.status_code, 404)
  1013. def test_view_issue_raw_file_empty(self):
  1014. """ Test the view_issue_raw_file endpoint. """
  1015. # Create the project and git repos
  1016. tests.create_projects(self.session)
  1017. tests.create_projects_git(
  1018. os.path.join(tests.HERE, 'tickets'), bare=True)
  1019. # Create issues to play with
  1020. repo = pagure.lib.get_project(self.session, 'test')
  1021. msg = pagure.lib.new_issue(
  1022. session=self.session,
  1023. repo=repo,
  1024. title='Test issue',
  1025. content='We should work on this',
  1026. user='pingou',
  1027. ticketfolder=None
  1028. )
  1029. self.session.commit()
  1030. self.assertEqual(msg.title, 'Test issue')
  1031. url = '/issue/raw/files/8a06845923010b27bfd8'\
  1032. 'e7e75acff7badc40d1021b4994e01f5e11ca40bc3a'\
  1033. 'be-home_pierrey_repos_gitrepo_pagure_tests'\
  1034. '_placebo.png'
  1035. output = self.app.get('/foo' + url)
  1036. self.assertEqual(output.status_code, 404)
  1037. output = self.app.get('/test' + url)
  1038. self.assertEqual(output.status_code, 404)
  1039. # Project w/o issue tracker
  1040. repo = pagure.lib.get_project(self.session, 'test')
  1041. repo.settings = {'issue_tracker': False}
  1042. self.session.add(repo)
  1043. self.session.commit()
  1044. output = self.app.get('/test' + url)
  1045. self.assertEqual(output.status_code, 404)
  1046. def test_view_issue_raw_file(self):
  1047. """ Test the view_issue_raw_file endpoint. """
  1048. # Create the issue and upload to it
  1049. self.test_upload_issue()
  1050. # Project w/ issue tracker
  1051. repo = pagure.lib.get_project(self.session, 'test')
  1052. repo.settings = {'issue_tracker': True}
  1053. self.session.add(repo)
  1054. self.session.commit()
  1055. url = '/issue/raw/files/8a06845923010b27bfd8'\
  1056. 'e7e75acff7badc40d1021b4994e01f5e11ca40bc3a'\
  1057. 'be-%s_placebo.png' % os.path.dirname(
  1058. os.path.abspath(__file__))[1:].replace('/', '_')
  1059. output = self.app.get('/foo' + url)
  1060. self.assertEqual(output.status_code, 404)
  1061. output = self.app.get('/test/issue/raw/files/test.png')
  1062. self.assertEqual(output.status_code, 404)
  1063. # Access file by name
  1064. output = self.app.get('/test' + url)
  1065. self.assertEqual(output.status_code, 200)
  1066. # Project w/o issue tracker
  1067. repo = pagure.lib.get_project(self.session, 'test')
  1068. repo.settings = {'issue_tracker': False}
  1069. self.session.add(repo)
  1070. self.session.commit()
  1071. output = self.app.get('/test' + url)
  1072. self.assertEqual(output.status_code, 404)
  1073. @patch('pagure.lib.git.update_git')
  1074. @patch('pagure.lib.notify.send_email')
  1075. def test_edit_issue(self, p_send_email, p_ugt):
  1076. """ Test the edit_issue endpoint. """
  1077. p_send_email.return_value = True
  1078. p_ugt.return_value = True
  1079. output = self.app.get('/foo/issue/1/edit')
  1080. self.assertEqual(output.status_code, 302)
  1081. user = tests.FakeUser()
  1082. with tests.user_set(pagure.APP, user):
  1083. output = self.app.get('/foo/issue/1/edit')
  1084. self.assertEqual(output.status_code, 404)
  1085. tests.create_projects(self.session)
  1086. tests.create_projects_git(
  1087. os.path.join(tests.HERE), bare=True)
  1088. output = self.app.get('/test/issue/1/edit')
  1089. self.assertEqual(output.status_code, 404)
  1090. user.username = 'pingou'
  1091. with tests.user_set(pagure.APP, user):
  1092. output = self.app.get('/test/issue/1/edit')
  1093. self.assertEqual(output.status_code, 404)
  1094. # Create issues to play with
  1095. repo = pagure.lib.get_project(self.session, 'test')
  1096. msg = pagure.lib.new_issue(
  1097. session=self.session,
  1098. repo=repo,
  1099. title='Test issue',
  1100. content='We should work on this',
  1101. user='pingou',
  1102. ticketfolder=None
  1103. )
  1104. self.session.commit()
  1105. self.assertEqual(msg.title, 'Test issue')
  1106. user = tests.FakeUser()
  1107. with tests.user_set(pagure.APP, user):
  1108. output = self.app.get('/test/issue/1/edit')
  1109. self.assertEqual(output.status_code, 403)
  1110. user.username = 'pingou'
  1111. with tests.user_set(pagure.APP, user):
  1112. output = self.app.get('/test/issue/1/edit')
  1113. self.assertEqual(output.status_code, 200)
  1114. self.assertTrue(
  1115. '<div class="card-header">\n Edit '
  1116. 'issue #1\n </div>' in output.data)
  1117. csrf_token = output.data.split(
  1118. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1119. data = {
  1120. 'issue_content': 'We should work on this!'
  1121. }
  1122. output = self.app.post('/test/issue/1/edit', data=data)
  1123. self.assertEqual(output.status_code, 200)
  1124. self.assertTrue(
  1125. '<div class="card-header">\n Edit '
  1126. 'issue #1\n </div>' in output.data)
  1127. self.assertEqual(output.data.count(
  1128. '<small>\n This field is required.&nbsp;\n'
  1129. ' </small>'), 1)
  1130. self.assertEqual(output.data.count(
  1131. '<small>\n Not a valid choice&nbsp;'
  1132. '\n </small>'), 1)
  1133. data['status'] = 'Open'
  1134. data['title'] = 'Test issue #1'
  1135. output = self.app.post('/test/issue/1/edit', data=data)
  1136. self.assertEqual(output.status_code, 200)
  1137. self.assertTrue(
  1138. '<div class="card-header">\n Edit '
  1139. 'issue #1\n </div>' in output.data)
  1140. self.assertEqual(output.data.count(
  1141. '<small>\n This field is required.&nbsp;\n'
  1142. ' </small>'), 0)
  1143. self.assertEqual(output.data.count(
  1144. '<small>\n Not a valid choice&nbsp;'
  1145. '\n </small>'), 0)
  1146. data['csrf_token'] = csrf_token
  1147. output = self.app.post(
  1148. '/test/issue/1/edit', data=data, follow_redirects=True)
  1149. self.assertEqual(output.status_code, 200)
  1150. self.assertIn(
  1151. '</button>\n Successfully edited issue #1',
  1152. output.data)
  1153. self.assertIn(
  1154. '<span class="issueid label label-default">#1</span>\n'
  1155. ' <span id="issuetitle">Test issue #1</span>',
  1156. output.data)
  1157. self.assertEqual(output.data.count(
  1158. '<option selected value="Open">Open</option>'), 1)
  1159. self.assertEqual(output.data.count('comment_body">'), 1)
  1160. self.assertEqual(output.data.count(
  1161. '<p>We should work on this!</p>'), 1)
  1162. # Project w/o issue tracker
  1163. repo = pagure.lib.get_project(self.session, 'test')
  1164. repo.settings = {'issue_tracker': False}
  1165. self.session.add(repo)
  1166. self.session.commit()
  1167. user.username = 'pingou'
  1168. with tests.user_set(pagure.APP, user):
  1169. output = self.app.post('/test/issue/1/edit', data=data)
  1170. self.assertEqual(output.status_code, 404)
  1171. @patch('pagure.lib.git.update_git')
  1172. @patch('pagure.lib.notify.send_email')
  1173. def test_edit_tag(self, p_send_email, p_ugt):
  1174. """ Test the edit_tag endpoint. """
  1175. p_send_email.return_value = True
  1176. p_ugt.return_value = True
  1177. output = self.app.get('/foo/tag/foo/edit')
  1178. self.assertEqual(output.status_code, 302)
  1179. user = tests.FakeUser()
  1180. with tests.user_set(pagure.APP, user):
  1181. output = self.app.get('/foo/tag/foo/edit')
  1182. self.assertEqual(output.status_code, 404)
  1183. tests.create_projects(self.session)
  1184. output = self.app.get('/test/tag/foo/edit')
  1185. self.assertEqual(output.status_code, 403)
  1186. # Create issues to play with
  1187. repo = pagure.lib.get_project(self.session, 'test')
  1188. msg = pagure.lib.new_issue(
  1189. session=self.session,
  1190. repo=repo,
  1191. title='Test issue',
  1192. content='We should work on this',
  1193. user='pingou',
  1194. ticketfolder=None
  1195. )
  1196. self.session.commit()
  1197. self.assertEqual(msg.title, 'Test issue')
  1198. # Add a tag to the issue
  1199. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1200. msg = pagure.lib.add_tag_obj(
  1201. session=self.session,
  1202. obj=issue,
  1203. tags='tag1',
  1204. user='pingou',
  1205. ticketfolder=None)
  1206. self.session.commit()
  1207. self.assertEqual(msg, 'Tag added: tag1')
  1208. # Before edit, list tags
  1209. tags = pagure.lib.get_tags_of_project(self.session, repo)
  1210. self.assertEqual([tag.tag for tag in tags], ['tag1'])
  1211. # Edit tag
  1212. user.username = 'pingou'
  1213. with tests.user_set(pagure.APP, user):
  1214. #Edit a tag that doesn't exit
  1215. output = self.app.get('/test/tag/does_not_exist/edit')
  1216. self.assertEqual(output.status_code, 404)
  1217. output = self.app.get('/test/tag/tag1/edit')
  1218. self.assertEqual(output.status_code, 200)
  1219. self.assertTrue('<h2>Edit tag: tag1</h2>' in output.data)
  1220. self.assertTrue(
  1221. '<p>Enter in the field below the new name for the tag: '
  1222. '"tag1"</p>' in output.data)
  1223. csrf_token = output.data.split(
  1224. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1225. data = {'tag': 'tag2'}
  1226. output = self.app.post('/test/tag/tag1/edit', data=data)
  1227. self.assertEqual(output.status_code, 200)
  1228. self.assertTrue('<h2>Edit tag: tag1</h2>' in output.data)
  1229. self.assertTrue(
  1230. '<p>Enter in the field below the new name for the tag: '
  1231. '"tag1"</p>' in output.data)
  1232. data['csrf_token'] = csrf_token
  1233. tests.create_projects_git(tests.HERE)
  1234. output = self.app.post(
  1235. '/test/tag/tag1/edit', data=data, follow_redirects=True)
  1236. self.assertEqual(output.status_code, 200)
  1237. self.assertIn(
  1238. '<title>Settings - test - Pagure</title>', output.data)
  1239. self.assertIn(
  1240. '</button>\n Edited tag: tag1 to tag2',
  1241. output.data)
  1242. # After edit, list tags
  1243. tags = pagure.lib.get_tags_of_project(self.session, repo)
  1244. self.assertEqual([tag.tag for tag in tags], ['tag2'])
  1245. @patch('pagure.lib.git.update_git')
  1246. @patch('pagure.lib.notify.send_email')
  1247. def test_remove_tag(self, p_send_email, p_ugt):
  1248. """ Test the remove_tag endpoint. """
  1249. p_send_email.return_value = True
  1250. p_ugt.return_value = True
  1251. output = self.app.post('/foo/droptag/')
  1252. self.assertEqual(output.status_code, 302)
  1253. user = tests.FakeUser()
  1254. with tests.user_set(pagure.APP, user):
  1255. output = self.app.post('/foo/droptag/')
  1256. self.assertEqual(output.status_code, 404)
  1257. tests.create_projects(self.session)
  1258. output = self.app.post('/test/droptag/')
  1259. self.assertEqual(output.status_code, 403)
  1260. # Create issues to play with
  1261. repo = pagure.lib.get_project(self.session, 'test')
  1262. msg = pagure.lib.new_issue(
  1263. session=self.session,
  1264. repo=repo,
  1265. title='Test issue',
  1266. content='We should work on this',
  1267. user='pingou',
  1268. ticketfolder=None
  1269. )
  1270. self.session.commit()
  1271. self.assertEqual(msg.title, 'Test issue')
  1272. # Add a tag to the issue
  1273. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1274. msg = pagure.lib.add_tag_obj(
  1275. session=self.session,
  1276. obj=issue,
  1277. tags='tag1',
  1278. user='pingou',
  1279. ticketfolder=None)
  1280. self.session.commit()
  1281. self.assertEqual(msg, 'Tag added: tag1')
  1282. # Before edit, list tags
  1283. tags = pagure.lib.get_tags_of_project(self.session, repo)
  1284. self.assertEqual([tag.tag for tag in tags], ['tag1'])
  1285. # Edit tag
  1286. user.username = 'pingou'
  1287. with tests.user_set(pagure.APP, user):
  1288. tests.create_projects_git(tests.HERE)
  1289. output = self.app.post(
  1290. '/test/droptag/', data={}, follow_redirects=True)
  1291. self.assertEqual(output.status_code, 200)
  1292. self.assertTrue(
  1293. '<title>Settings - test - Pagure</title>' in output.data)
  1294. self.assertTrue("<h3>Settings for test</h3>" in output.data)
  1295. csrf_token = output.data.split(
  1296. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1297. data = {'tag': 'tag1'}
  1298. output = self.app.post(
  1299. '/test/droptag/', data=data, follow_redirects=True)
  1300. self.assertEqual(output.status_code, 200)
  1301. self.assertTrue("<h3>Settings for test</h3>" in output.data)
  1302. data['csrf_token'] = csrf_token
  1303. output = self.app.post(
  1304. '/test/droptag/', data=data, follow_redirects=True)
  1305. self.assertEqual(output.status_code, 200)
  1306. self.assertTrue("<h3>Settings for test</h3>" in output.data)
  1307. self.assertIn(
  1308. '</button>\n Removed tag: tag1',
  1309. output.data)
  1310. @patch('pagure.lib.git.update_git')
  1311. @patch('pagure.lib.notify.send_email')
  1312. def test_delete_issue(self, p_send_email, p_ugt):
  1313. """ Test the delete_issue endpoint. """
  1314. p_send_email.return_value = True
  1315. p_ugt.return_value = True
  1316. tests.create_projects(self.session)
  1317. tests.create_projects_git(tests.HERE)
  1318. tests.create_projects_git(os.path.join(tests.HERE, 'tickets'))
  1319. # Create issues to play with
  1320. repo = pagure.lib.get_project(self.session, 'test')
  1321. msg = pagure.lib.new_issue(
  1322. session=self.session,
  1323. repo=repo,
  1324. title='Test issue',
  1325. content='We should work on this',
  1326. user='pingou',
  1327. ticketfolder=None
  1328. )
  1329. self.session.commit()
  1330. self.assertEqual(msg.title, 'Test issue')
  1331. user = tests.FakeUser()
  1332. with tests.user_set(pagure.APP, user):
  1333. output = self.app.post(
  1334. '/foo/issue/1/drop', follow_redirects=True)
  1335. self.assertEqual(output.status_code, 404)
  1336. output = self.app.post(
  1337. '/test/issue/100/drop', follow_redirects=True)
  1338. self.assertEqual(output.status_code, 404)
  1339. output = self.app.post(
  1340. '/test/issue/1/drop', follow_redirects=True)
  1341. self.assertEqual(output.status_code, 403)
  1342. user.username = 'pingou'
  1343. with tests.user_set(pagure.APP, user):
  1344. output = self.app.post(
  1345. '/test/issue/1/drop', follow_redirects=True)
  1346. self.assertEqual(output.status_code, 200)
  1347. self.assertIn(
  1348. '<title>Issue #1: Test issue - test - Pagure</title>',
  1349. output.data)
  1350. csrf_token = output.data.split(
  1351. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1352. data = {
  1353. }
  1354. # No CSRF token
  1355. output = self.app.post(
  1356. '/test/issue/1/drop', data=data, follow_redirects=True)
  1357. self.assertEqual(output.status_code, 200)
  1358. self.assertIn(
  1359. '<title>Issue #1: Test issue - test - Pagure</title>',
  1360. output.data)
  1361. data['csrf_token'] = csrf_token
  1362. output = self.app.post(
  1363. '/test/issue/1/drop', data=data, follow_redirects=True)
  1364. self.assertEqual(output.status_code, 200)
  1365. self.assertIn(
  1366. '<title>Issues - test - Pagure</title>', output.data)
  1367. self.assertIn(
  1368. '</button>\n Issue deleted',
  1369. output.data)
  1370. # Project w/o issue tracker
  1371. repo = pagure.lib.get_project(self.session, 'test')
  1372. repo.settings = {'issue_tracker': False}
  1373. self.session.add(repo)
  1374. self.session.commit()
  1375. user.username = 'pingou'
  1376. with tests.user_set(pagure.APP, user):
  1377. output = self.app.post('/test/issue/1/drop', data=data)
  1378. self.assertEqual(output.status_code, 404)
  1379. @patch('pagure.lib.git.update_git')
  1380. @patch('pagure.lib.notify.send_email')
  1381. def test_update_issue_edit_comment(self, p_send_email, p_ugt):
  1382. """ Test the issues edit comment endpoint """
  1383. p_send_email.return_value = True
  1384. p_ugt.return_value = True
  1385. tests.create_projects(self.session)
  1386. tests.create_projects_git(
  1387. os.path.join(tests.HERE), bare=True)
  1388. # Create issues to play with
  1389. repo = pagure.lib.get_project(self.session, 'test')
  1390. msg = pagure.lib.new_issue(
  1391. session=self.session,
  1392. repo=repo,
  1393. title='Test issue',
  1394. content='We should work on this',
  1395. user='pingou',
  1396. ticketfolder=None
  1397. )
  1398. self.session.commit()
  1399. self.assertEqual(msg.title, 'Test issue')
  1400. user = tests.FakeUser()
  1401. user.username = 'pingou'
  1402. with tests.user_set(pagure.APP, user):
  1403. output = self.app.get('/test/issue/1')
  1404. self.assertEqual(output.status_code, 200)
  1405. self.assertIn(
  1406. '<title>Issue #1: Test issue - test - Pagure</title>',
  1407. output.data)
  1408. self.assertIn(
  1409. '<a class="btn btn-primary btn-sm" '
  1410. 'href="/test/issue/1/edit" title="Edit this issue">',
  1411. output.data)
  1412. csrf_token = output.data.split(
  1413. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1414. # Add new comment
  1415. data = {
  1416. 'csrf_token': csrf_token,
  1417. 'comment': 'Woohoo a second comment !',
  1418. }
  1419. output = self.app.post(
  1420. '/test/issue/1/update', data=data, follow_redirects=True)
  1421. self.assertEqual(output.status_code, 200)
  1422. self.assertIn(
  1423. '<title>Issue #1: Test issue - test - Pagure</title>',
  1424. output.data)
  1425. self.assertIn(
  1426. '<a class="btn btn-primary btn-sm" '
  1427. 'href="/test/issue/1/edit" title="Edit this issue">',
  1428. output.data)
  1429. self.assertIn(
  1430. '</button>\n Comment added',
  1431. output.data)
  1432. self.assertTrue(
  1433. '<p>Woohoo a second comment !</p>' in output.data)
  1434. self.assertEqual(output.data.count('comment_body">'), 2)
  1435. repo = pagure.lib.get_project(self.session, 'test')
  1436. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1437. self.assertEqual(len(issue.comments), 1)
  1438. self.assertEqual(
  1439. issue.comments[0].comment,
  1440. 'Woohoo a second comment !')
  1441. data = {
  1442. 'csrf_token': csrf_token,
  1443. 'edit_comment': 1,
  1444. 'update_comment': 'Updated comment',
  1445. }
  1446. user = tests.FakeUser()
  1447. with tests.user_set(pagure.APP, user):
  1448. # Wrong issue id
  1449. output = self.app.post(
  1450. '/test/issue/3/update', data=data, follow_redirects=True)
  1451. self.assertEqual(output.status_code, 404)
  1452. # Wrong user
  1453. output = self.app.post(
  1454. '/test/issue/1/update', data=data, follow_redirects=True)
  1455. self.assertEqual(output.status_code, 403)
  1456. user = tests.FakeUser()
  1457. user.username = 'pingou'
  1458. with tests.user_set(pagure.APP, user):
  1459. # Edit comment
  1460. output = self.app.post(
  1461. '/test/issue/1/update', data=data, follow_redirects=True)
  1462. self.assertEqual(output.status_code, 200)
  1463. self.assertIn(
  1464. '<title>Issue #1: Test issue - test - Pagure</title>',
  1465. output.data)
  1466. self.assertIn(
  1467. '<a class="btn btn-primary btn-sm" '
  1468. 'href="/test/issue/1/edit" title="Edit this issue">',
  1469. output.data)
  1470. self.assertIn(
  1471. '</button>\n Comment updated',
  1472. output.data)
  1473. repo = pagure.lib.get_project(self.session, 'test')
  1474. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1475. self.assertEqual(len(issue.comments), 1)
  1476. self.assertEqual(issue.comments[0].comment, 'Updated comment')
  1477. with tests.user_set(pagure.APP, user):
  1478. output = self.app.get('/test/issue/1/comment/1/edit')
  1479. self.assertIn(
  1480. '<title>test - Pagure</title>', output.data)
  1481. self.assertTrue('<div id="edit">' in output.data)
  1482. self.assertTrue('<section class="edit_comment">' in output.data)
  1483. self.assertTrue(
  1484. '<textarea class="form-control" id="update_comment"'
  1485. in output.data)
  1486. csrf_token = output.data.split(
  1487. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1488. data['csrf_token'] = csrf_token
  1489. data['update_comment'] = 'Second update'
  1490. # Edit the comment with the other endpoint
  1491. output = self.app.post(
  1492. '/test/issue/1/comment/1/edit',
  1493. data=data,
  1494. follow_redirects=True)
  1495. self.assertEqual(output.status_code, 200)
  1496. self.assertIn(
  1497. '<title>Issue #1: Test issue - test - Pagure</title>',
  1498. output.data)
  1499. self.assertIn(
  1500. '<a class="btn btn-primary btn-sm" '
  1501. 'href="/test/issue/1/edit" title="Edit this issue">',
  1502. output.data)
  1503. self.assertIn(
  1504. '</button>\n Comment updated',
  1505. output.data)
  1506. repo = pagure.lib.get_project(self.session, 'test')
  1507. issue = pagure.lib.search_issues(self.session, repo, issueid=1)
  1508. self.assertEqual(len(issue.comments), 1)
  1509. self.assertEqual(issue.comments[0].comment, 'Second update')
  1510. @patch('pagure.lib.git.update_git')
  1511. @patch('pagure.lib.notify.send_email')
  1512. def test_git_urls(self, p_send_email, p_ugt):
  1513. """ Check that the url to the git repo for issues is present/absent when
  1514. it should.
  1515. """
  1516. p_send_email.return_value = True
  1517. p_ugt.return_value = True
  1518. self.test_view_issues()
  1519. user = tests.FakeUser()
  1520. user.username = 'pingou'
  1521. with tests.user_set(pagure.APP, user):
  1522. # Check that the git issue URL is present
  1523. output = self.app.get('/test')
  1524. self.assertNotIn(
  1525. '<h5><strong>Issues GIT URLs</strong></h5>', output.data)
  1526. # Project w/o issue tracker
  1527. repo = pagure.lib.get_project(self.session, 'test')
  1528. repo.settings = {'issue_tracker': True}
  1529. self.session.add(repo)
  1530. self.session.commit()
  1531. # Check that the git issue URL is gone
  1532. output = self.app.get('/test')
  1533. self.assertIn(
  1534. '<h5><strong>Issues GIT URLs</strong></h5>', output.data)
  1535. if __name__ == '__main__':
  1536. SUITE = unittest.TestLoader().loadTestsFromTestCase(PagureFlaskIssuestests)
  1537. unittest.TextTestRunner(verbosity=2).run(SUITE)