test_pagure_flask_ui_app.py 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2018 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. from __future__ import unicode_literals
  8. __requires__ = ['SQLAlchemy >= 0.8']
  9. import pkg_resources
  10. import datetime
  11. import unittest
  12. import shutil
  13. import sys
  14. import tempfile
  15. import os
  16. import six
  17. import json
  18. import pygit2
  19. from mock import patch, MagicMock
  20. sys.path.insert(0, os.path.join(os.path.dirname(
  21. os.path.abspath(__file__)), '..'))
  22. import pagure.lib
  23. import tests
  24. class PagureFlaskApptests(tests.Modeltests):
  25. """ Tests for flask app controller of pagure """
  26. def test_watch_list(self):
  27. ''' Test for watch list of a user '''
  28. user = tests.FakeUser(username='pingou')
  29. with tests.user_set(self.app.application, user):
  30. output = self.app.get('/', follow_redirects=True)
  31. output_text = output.get_data(as_text=True)
  32. self.assertIn(
  33. '<div class="text-center">You have no projects</div>',
  34. output_text)
  35. tests.create_projects(self.session)
  36. output = self.app.get('/', follow_redirects=True)
  37. output_text = output.get_data(as_text=True)
  38. self.assertIn(
  39. '<h4 class="font-weight-bold mb-0">My Projects</h4>',
  40. output_text)
  41. def test_view_users(self):
  42. """ Test the view_users endpoint. """
  43. output = self.app.get('/users/?page=abc')
  44. self.assertEqual(output.status_code, 200)
  45. output_text = output.get_data(as_text=True)
  46. self.assertIn(
  47. '<h3 class="mb-3 font-weight-bold">\n Users '
  48. '<span class="badge badge-secondary">2</span></h3>', output_text)
  49. self.assertIn(
  50. '<a href="/user/pingou">\n '
  51. '<div class="nowrap"><strong>pingou</strong>',
  52. output_text)
  53. self.assertIn(
  54. '<a href="/user/foo">\n '
  55. '<div class="nowrap"><strong>foo</strong>',
  56. output_text)
  57. @patch.dict('pagure.config.config', {'ITEM_PER_PAGE': 2})
  58. def test_view_user_repo_cnt(self):
  59. """ Test the repo counts on the view_user endpoint. """
  60. tests.create_projects(self.session)
  61. self.gitrepos = tests.create_projects_git(
  62. pagure.config.config['GIT_FOLDER'])
  63. output = self.app.get('/user/pingou')
  64. self.assertEqual(output.status_code, 200)
  65. output_text = output.get_data(as_text=True)
  66. self.assertIn(
  67. """<span>
  68. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  69. <span class="d-none d-md-inline">Projects&nbsp;</span>
  70. </span>
  71. <div class="ml-auto">
  72. <span class="badge badge-secondary">
  73. 3
  74. </span>
  75. </div>""", output_text)
  76. self.assertIn(
  77. """<span>
  78. <i class="fa fa-fw text-muted fa-code-fork"></i>
  79. <span class="d-none d-md-inline">Forks&nbsp;</span>
  80. </span>
  81. <div class="ml-auto">
  82. <span class="badge badge-secondary">
  83. 0
  84. </span>
  85. </div>""", output_text)
  86. def test_view_user(self):
  87. """ Test the view_user endpoint. """
  88. output = self.app.get('/user/pingou?repopage=abc&forkpage=def')
  89. self.assertEqual(output.status_code, 200)
  90. output_text = output.get_data(as_text=True)
  91. self.assertIn(
  92. """<span>
  93. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  94. <span class="d-none d-md-inline">Projects&nbsp;</span>
  95. </span>
  96. <div class="ml-auto">
  97. <span class="badge badge-secondary">
  98. 0
  99. </span>
  100. </div>""", output_text)
  101. self.assertIn(
  102. """<span>
  103. <i class="fa fa-fw text-muted fa-code-fork"></i>
  104. <span class="d-none d-md-inline">Forks&nbsp;</span>
  105. </span>
  106. <div class="ml-auto">
  107. <span class="badge badge-secondary">
  108. 0
  109. </span>
  110. </div>""", output_text)
  111. tests.create_projects(self.session)
  112. self.gitrepos = tests.create_projects_git(
  113. pagure.config.config['GIT_FOLDER'])
  114. output = self.app.get('/user/pingou?repopage=abc&forkpage=def')
  115. self.assertEqual(output.status_code, 200)
  116. output_text = output.get_data(as_text=True)
  117. self.assertIn(
  118. """<span>
  119. <i class="fa fa-fw text-muted fa-calendar-o fa-rotate-270"></i>
  120. <span class="d-none d-md-inline">Projects&nbsp;</span>
  121. </span>
  122. <div class="ml-auto">
  123. <span class="badge badge-secondary">
  124. 3
  125. </span>
  126. </div>""", output_text)
  127. self.assertIn(
  128. """<span>
  129. <i class="fa fa-fw text-muted fa-code-fork"></i>
  130. <span class="d-none d-md-inline">Forks&nbsp;</span>
  131. </span>
  132. <div class="ml-auto">
  133. <span class="badge badge-secondary">
  134. 0
  135. </span>
  136. </div>""", output_text)
  137. self.assertNotIn(
  138. '<a class="page-link" href="#" tabindex="-1">page 1 of 2</a>',
  139. output_text)
  140. @patch.dict('pagure.config.config', {'ENABLE_UI_NEW_PROJECTS': False})
  141. def test_new_project_when_turned_off_in_the_ui(self):
  142. """ Test the new_project endpoint when new project creation is
  143. not allowed in the UI of this pagure instance. """
  144. user = tests.FakeUser(username='foo')
  145. with tests.user_set(self.app.application, user):
  146. output = self.app.get('/new/')
  147. self.assertEqual(output.status_code, 404)
  148. data = {
  149. 'description': 'Project #1',
  150. 'name': 'project-1',
  151. }
  152. output = self.app.post('/new/', data=data, follow_redirects=True)
  153. self.assertEqual(output.status_code, 404)
  154. @patch.dict('pagure.config.config', {'ENABLE_UI_NEW_PROJECTS': False})
  155. def test_new_project_button_when_turned_off_in_the_ui_no_project(self):
  156. """ Test the index endpoint when new project creation is
  157. not allowed in the UI of this pagure instance. """
  158. user = tests.FakeUser(username='foo')
  159. with tests.user_set(self.app.application, user):
  160. output = self.app.get('/', follow_redirects=True)
  161. self.assertEqual(output.status_code, 200)
  162. output_text = output.get_data(as_text=True)
  163. self.assertIn(
  164. '<h4 class="font-weight-bold mb-0">My Projects</h4>',
  165. output_text)
  166. # master template
  167. self.assertNotIn(
  168. '<span class="oi" data-glyph="plus" title="Create New"',
  169. output_text)
  170. # index_auth template
  171. self.assertNotIn(
  172. 'title="Create New Project" aria-hidden="true">',
  173. output_text)
  174. @patch.dict('pagure.config.config', {'ENABLE_UI_NEW_PROJECTS': False})
  175. def test_new_project_button_when_turned_off_in_the_ui_w_project(self):
  176. """ Test the index endpoint when new project creation is
  177. not allowed in the UI of this pagure instance. """
  178. tests.create_projects(self.session)
  179. user = tests.FakeUser(username='pingou')
  180. with tests.user_set(self.app.application, user):
  181. output = self.app.get('/', follow_redirects=True)
  182. self.assertEqual(output.status_code, 200)
  183. output_text = output.get_data(as_text=True)
  184. self.assertIn(
  185. '<h4 class="font-weight-bold mb-0">My Projects</h4>',
  186. output_text)
  187. # master template
  188. self.assertNotIn(
  189. '<span class="oi" data-glyph="plus" title="Create New"',
  190. output_text)
  191. # index_auth template
  192. self.assertNotIn(
  193. 'title="Create New Project" aria-hidden="true">',
  194. output_text)
  195. def test_new_project_when_turned_off(self):
  196. """ Test the new_project endpoint when new project creation is
  197. not allowed in the pagure instance. """
  198. #turn the project creation off
  199. pagure.config.config['ENABLE_NEW_PROJECTS'] = False
  200. # Before
  201. projects = pagure.lib.search_projects(self.session)
  202. self.assertEqual(len(projects), 0)
  203. self.assertFalse(os.path.exists(
  204. os.path.join(self.path, 'repos', 'project-1.git')))
  205. self.assertFalse(os.path.exists(
  206. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  207. self.assertFalse(os.path.exists(
  208. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  209. self.assertFalse(os.path.exists(
  210. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  211. user = tests.FakeUser()
  212. with tests.user_set(self.app.application, user):
  213. output = self.app.get('/new/')
  214. self.assertEqual(output.status_code, 404)
  215. #just get the csrf token
  216. pagure.config.config['ENABLE_NEW_PROJECTS'] = True
  217. output = self.app.get('/new/')
  218. pagure.config.config['ENABLE_NEW_PROJECTS'] = False
  219. csrf_token = output.get_data(as_text=True).split(
  220. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  221. data = {
  222. 'description': 'Project #1',
  223. 'name': 'project-1',
  224. }
  225. user.username = 'foo'
  226. with tests.user_set(self.app.application, user):
  227. data['csrf_token'] = csrf_token
  228. output = self.app.post('/new/', data=data, follow_redirects=True)
  229. self.assertEqual(output.status_code, 404)
  230. #After
  231. projects = pagure.lib.search_projects(self.session)
  232. self.assertEqual(len(projects), 0)
  233. self.assertFalse(os.path.exists(
  234. os.path.join(self.path, 'repos', 'project-1.git')))
  235. self.assertFalse(os.path.exists(
  236. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  237. self.assertFalse(os.path.exists(
  238. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  239. self.assertFalse(os.path.exists(
  240. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  241. pagure.config.config['ENABLE_NEW_PROJECTS'] = True
  242. def test_new_project(self):
  243. """ Test the new_project endpoint. """
  244. # Before
  245. projects = pagure.lib.search_projects(self.session)
  246. self.assertEqual(len(projects), 0)
  247. self.assertFalse(os.path.exists(
  248. os.path.join(self.path, 'repos', 'project#1.git')))
  249. self.assertFalse(os.path.exists(
  250. os.path.join(self.path, 'repos', 'tickets', 'project#1.git')))
  251. self.assertFalse(os.path.exists(
  252. os.path.join(self.path, 'repos', 'docs', 'project#1.git')))
  253. self.assertFalse(os.path.exists(
  254. os.path.join(self.path, 'repos', 'requests', 'project#1.git')))
  255. user = tests.FakeUser()
  256. with tests.user_set(self.app.application, user):
  257. output = self.app.get('/new/')
  258. self.assertEqual(output.status_code, 200)
  259. output_text = output.get_data(as_text=True)
  260. self.assertIn(
  261. '<strong>Create new Project</strong>', output_text)
  262. csrf_token = output_text.split(
  263. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  264. data = {
  265. 'description': 'Project #1',
  266. }
  267. output = self.app.post('/new/', data=data)
  268. self.assertEqual(output.status_code, 200)
  269. output_text = output.get_data(as_text=True)
  270. self.assertIn(
  271. '<strong>Create new Project</strong>', output_text)
  272. self.assertIn(
  273. '<small>\n This field is required.&nbsp;\n'
  274. ' </small>', output_text)
  275. data['name'] = 'project-1'
  276. output = self.app.post('/new/', data=data)
  277. self.assertEqual(output.status_code, 200)
  278. output_text = output.get_data(as_text=True)
  279. self.assertIn('<strong>Create new Project</strong>', output_text)
  280. self.assertNotIn(
  281. '<small>\n This field is required.&nbsp;\n'
  282. ' </small>', output_text)
  283. data['csrf_token'] = csrf_token
  284. output = self.app.post('/new/', data=data)
  285. self.assertEqual(output.status_code, 200)
  286. output_text = output.get_data(as_text=True)
  287. self.assertIn('<strong>Create new Project</strong>', output_text)
  288. self.assertIn(
  289. 'No user '
  290. '&#34;username&#34; found',
  291. output_text)
  292. user.username = 'foo'
  293. with tests.user_set(self.app.application, user):
  294. data['csrf_token'] = csrf_token
  295. output = self.app.post('/new/', data=data, follow_redirects=True)
  296. self.assertEqual(output.status_code, 200)
  297. output_text = output.get_data(as_text=True)
  298. self.assertIn(
  299. '<div class="projectinfo my-3">\nProject #1',
  300. output_text)
  301. self.assertIn('<p>This repo is brand new!</p>',
  302. output_text)
  303. self.assertIn(
  304. '<title>Overview - project-1 - Pagure</title>', output_text)
  305. # After
  306. projects = pagure.lib.search_projects(self.session)
  307. self.assertEqual(len(projects), 1)
  308. self.assertTrue(os.path.exists(
  309. os.path.join(self.path, 'repos', 'project-1.git')))
  310. self.assertTrue(os.path.exists(
  311. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  312. self.assertTrue(os.path.exists(
  313. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  314. self.assertTrue(os.path.exists(
  315. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  316. @patch.dict('pagure.config.config', {'PROJECT_NAME_REGEX': '^1[a-z]*$'})
  317. def test_new_project_diff_regex(self):
  318. """ Test the new_project endpoint with a different regex. """
  319. # Before
  320. projects = pagure.lib.search_projects(self.session)
  321. self.assertEqual(len(projects), 0)
  322. user = tests.FakeUser(username='foo')
  323. with tests.user_set(self.app.application, user):
  324. output = self.app.get('/new/')
  325. self.assertEqual(output.status_code, 200)
  326. output_text = output.get_data(as_text=True)
  327. self.assertIn(
  328. '<strong>Create new Project</strong>', output_text)
  329. csrf_token = self.get_csrf(output=output)
  330. data = {
  331. 'description': 'Project #1',
  332. 'name': 'project-1',
  333. 'csrf_token': csrf_token,
  334. }
  335. output = self.app.post('/new/', data=data, follow_redirects=True)
  336. self.assertEqual(output.status_code, 200)
  337. output_text = output.get_data(as_text=True)
  338. self.assertIn(
  339. '<title>New project - Pagure</title>', output_text)
  340. self.assertIn(
  341. '<strong>Create new Project</strong>', output_text)
  342. self.assertIn(
  343. '<small>\n Invalid input.&nbsp;\n'
  344. ' </small>', output_text)
  345. @patch.dict('pagure.config.config', {'PRIVATE_PROJECTS': True})
  346. def test_new_project_private(self):
  347. """ Test the new_project endpoint for a private project. """
  348. # Before
  349. projects = pagure.lib.search_projects(self.session)
  350. self.assertEqual(len(projects), 0)
  351. self.assertFalse(os.path.exists(
  352. os.path.join(self.path, 'repos', 'foo', 'project#1.git')))
  353. self.assertFalse(os.path.exists(
  354. os.path.join(self.path, 'repos', 'tickets', 'foo', 'project#1.git')))
  355. self.assertFalse(os.path.exists(
  356. os.path.join(self.path, 'repos', 'docs', 'foo', 'project#1.git')))
  357. self.assertFalse(os.path.exists(
  358. os.path.join(self.path, 'repos', 'requests', 'foo', 'project#1.git')))
  359. user = tests.FakeUser()
  360. with tests.user_set(self.app.application, user):
  361. output = self.app.get('/new/')
  362. self.assertEqual(output.status_code, 200)
  363. self.assertIn(
  364. '<strong>Create new Project</strong>', output.get_data(as_text=True))
  365. csrf_token = self.get_csrf(output=output)
  366. data = {
  367. 'description': 'Project #1',
  368. 'private': True,
  369. }
  370. output = self.app.post('/new/', data=data)
  371. self.assertEqual(output.status_code, 200)
  372. output_text = output.get_data(as_text=True)
  373. self.assertIn(
  374. '<strong>Create new Project</strong>', output_text)
  375. self.assertIn(
  376. '<small>\n This field is required.&nbsp;\n'
  377. ' </small>', output_text)
  378. data['name'] = 'project-1'
  379. output = self.app.post('/new/', data=data)
  380. self.assertEqual(output.status_code, 200)
  381. output_text = output.get_data(as_text=True)
  382. self.assertIn('<strong>Create new Project</strong>', output_text)
  383. self.assertNotIn(
  384. '<small>\n This field is required.&nbsp;\n'
  385. ' </small>', output_text)
  386. data['csrf_token'] = csrf_token
  387. output = self.app.post('/new/', data=data)
  388. self.assertEqual(output.status_code, 200)
  389. output_text = output.get_data(as_text=True)
  390. self.assertIn('<strong>Create new Project</strong>', output_text)
  391. self.assertIn(
  392. 'No user '
  393. '&#34;username&#34; found',
  394. output_text)
  395. user.username = 'foo'
  396. with tests.user_set(self.app.application, user):
  397. data['csrf_token'] = csrf_token
  398. output = self.app.post('/new/', data=data, follow_redirects=True)
  399. self.assertEqual(output.status_code, 200)
  400. output_text = output.get_data(as_text=True)
  401. self.assertIn(
  402. '<div class="projectinfo my-3">\nProject #1',
  403. output_text)
  404. self.assertIn('<p>This repo is brand new!</p>',
  405. output_text)
  406. self.assertIn(
  407. '<title>Overview - foo/project-1 - Pagure</title>', output_text)
  408. # After
  409. projects = pagure.lib.search_projects(self.session)
  410. self.assertEqual(len(projects), 0)
  411. projects = pagure.lib.search_projects(self.session, private=True)
  412. self.assertEqual(len(projects), 1)
  413. self.assertTrue(os.path.exists(
  414. os.path.join(self.path, 'repos', 'foo', 'project-1.git')))
  415. self.assertTrue(os.path.exists(
  416. os.path.join(self.path, 'repos', 'tickets', 'foo', 'project-1.git')))
  417. self.assertTrue(os.path.exists(
  418. os.path.join(self.path, 'repos', 'docs', 'foo', 'project-1.git')))
  419. self.assertTrue(os.path.exists(
  420. os.path.join(self.path, 'repos', 'requests', 'foo', 'project-1.git')))
  421. def test_non_ascii_new_project(self):
  422. """ Test the new_project endpoint with a non-ascii project. """
  423. # Before
  424. projects = pagure.lib.search_projects(self.session)
  425. self.assertEqual(len(projects), 0)
  426. self.assertFalse(os.path.exists(
  427. os.path.join(self.path, 'repos', 'project-1.git')))
  428. self.assertFalse(os.path.exists(
  429. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  430. self.assertFalse(os.path.exists(
  431. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  432. self.assertFalse(os.path.exists(
  433. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  434. user = tests.FakeUser()
  435. user.username = 'foo'
  436. with tests.user_set(self.app.application, user):
  437. output = self.app.get('/new/')
  438. self.assertEqual(output.status_code, 200)
  439. output_text = output.get_data(as_text=True)
  440. self.assertIn(
  441. '<strong>Create new Project</strong>', output_text)
  442. csrf_token = output_text.split(
  443. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  444. data = {
  445. 'description': 'Prõjéctö #1',
  446. 'name': 'project-1',
  447. 'csrf_token': csrf_token,
  448. 'create_readme': True,
  449. }
  450. output = self.app.post('/new/', data=data, follow_redirects=True)
  451. self.assertEqual(output.status_code, 200)
  452. output_text = output.get_data(as_text=True)
  453. self.assertIn(
  454. '<div class="projectinfo my-3">\nPrõjéctö #1',
  455. output_text)
  456. self.assertIn(
  457. '''<section class="readme">
  458. <h1>project-1</h1>
  459. <p>Prõjéctö #1</p>
  460. </section>''',
  461. output_text)
  462. data = {
  463. 'description': 'Мой первый суперский репозиторий',
  464. 'name': 'project-2',
  465. 'csrf_token': csrf_token,
  466. 'create_readme': True,
  467. }
  468. output = self.app.post('/new/', data=data, follow_redirects=True)
  469. self.assertEqual(output.status_code, 200)
  470. output_text = output.get_data(as_text=True)
  471. self.assertIn(
  472. '<div class="projectinfo my-3">\nМой первый суперский репозиторий',
  473. output_text)
  474. self.assertIn(
  475. '''<section class="readme">
  476. <h1>project-2</h1>
  477. <p>Мой первый суперский репозиторий</p>
  478. </section>''',
  479. output_text)
  480. # After
  481. projects = pagure.lib.search_projects(self.session)
  482. self.assertEqual(len(projects), 2)
  483. for project in ['project-1', 'project-2']:
  484. self.assertTrue(os.path.exists(
  485. os.path.join(self.path, 'repos', '%s.git' % project)))
  486. self.assertTrue(os.path.exists(
  487. os.path.join(self.path, 'repos', 'tickets', '%s.git' % project)))
  488. self.assertTrue(os.path.exists(
  489. os.path.join(self.path, 'repos', 'docs', '%s.git' % project)))
  490. self.assertTrue(os.path.exists(
  491. os.path.join(self.path, 'repos', 'requests', '%s.git' % project)))
  492. @patch('pygit2.init_repository', wraps=pygit2.init_repository)
  493. def test_new_project_with_template(self, pygit2init):
  494. """ Test the new_project endpoint for a new project with a template set.
  495. """
  496. # Before
  497. projects = pagure.lib.search_projects(self.session)
  498. self.assertEqual(len(projects), 0)
  499. self.assertFalse(os.path.exists(
  500. os.path.join(self.path, 'repos', 'project-1.git')))
  501. self.assertFalse(os.path.exists(
  502. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  503. self.assertFalse(os.path.exists(
  504. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  505. self.assertFalse(os.path.exists(
  506. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  507. user = tests.FakeUser()
  508. user.username = 'foo'
  509. with tests.user_set(self.app.application, user):
  510. output = self.app.get('/new/')
  511. self.assertEqual(output.status_code, 200)
  512. self.assertIn(
  513. '<strong>Create new Project</strong>', output.get_data(as_text=True))
  514. csrf_token = self.get_csrf(output=output)
  515. data = {
  516. 'description': 'test',
  517. 'name': 'project-1',
  518. 'csrf_token': csrf_token,
  519. 'create_readme': True,
  520. }
  521. output = self.app.post('/new/', data=data, follow_redirects=True)
  522. self.assertEqual(output.status_code, 200)
  523. self.assertIn(
  524. '<div class="projectinfo my-3">\ntest',
  525. output.get_data(as_text=True))
  526. self.assertEqual(pygit2init.call_count, 4)
  527. pygit2init.assert_any_call(
  528. '%s/repos/project-1.git' % self.path,
  529. bare=True, template_path=None)
  530. path = os.path.join(self.path, 'repos', 'project-1.git')
  531. with patch.dict(
  532. 'pagure.config.config',
  533. {'PROJECT_TEMPLATE_PATH': path}):
  534. data = {
  535. 'description': 'test2',
  536. 'name': 'project-2',
  537. 'csrf_token': csrf_token,
  538. 'create_readme': True,
  539. }
  540. output = self.app.post('/new/', data=data, follow_redirects=True)
  541. self.assertEqual(output.status_code, 200)
  542. self.assertIn(
  543. '<div class="projectinfo my-3">\ntest2',
  544. output.get_data(as_text=True))
  545. self.assertEqual(pygit2init.call_count, 8)
  546. pygit2init.assert_any_call(
  547. '%s/repos/project-2.git' % self.path,
  548. bare=True,
  549. template_path='%s/repos/project-1.git' % self.path)
  550. # After
  551. projects = pagure.lib.search_projects(self.session)
  552. self.assertEqual(len(projects), 2)
  553. for project in ['project-1', 'project-2']:
  554. self.assertTrue(os.path.exists(
  555. os.path.join(self.path, 'repos', '%s.git' % project)))
  556. self.assertTrue(os.path.exists(
  557. os.path.join(self.path, 'repos', 'tickets', '%s.git' % project)))
  558. self.assertTrue(os.path.exists(
  559. os.path.join(self.path, 'repos', 'docs', '%s.git' % project)))
  560. self.assertTrue(os.path.exists(
  561. os.path.join(self.path, 'repos', 'requests', '%s.git' % project)))
  562. @patch.dict('pagure.config.config', {'CASE_SENSITIVE': True})
  563. def test_new_project_case_sensitive(self):
  564. tests.create_projects(self.session)
  565. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  566. output = self.app.get('/test')
  567. self.assertEqual(output.status_code, 200)
  568. output = self.app.get('/TEST')
  569. self.assertEqual(output.status_code, 404)
  570. user = tests.FakeUser()
  571. user.username = 'foo'
  572. with tests.user_set(self.app.application, user):
  573. output = self.app.get('/new/')
  574. self.assertEqual(output.status_code, 200)
  575. csrf_token = self.get_csrf(output=output)
  576. data = {
  577. 'description': 'TEST',
  578. 'name': 'TEST',
  579. 'csrf_token': csrf_token,
  580. 'create_readme': True,
  581. }
  582. self.app.post('/new/', data=data, follow_redirects=True)
  583. output = self.app.get('/TEST')
  584. self.assertEqual(output.status_code, 200)
  585. @patch('pagure.ui.app.admin_session_timedout')
  586. def test_user_settings(self, ast):
  587. """ Test the user_settings endpoint. """
  588. ast.return_value = False
  589. self.test_new_project()
  590. user = tests.FakeUser()
  591. with tests.user_set(self.app.application, user):
  592. output = self.app.get('/settings/')
  593. self.assertEqual(output.status_code, 404)
  594. self.assertIn('<h2>Page not found (404)</h2>', output.get_data(as_text=True))
  595. user.username = 'foo'
  596. with tests.user_set(self.app.application, user):
  597. output = self.app.get('/settings/')
  598. self.assertEqual(output.status_code, 200)
  599. output_text = output.get_data(as_text=True)
  600. self.assertIn(
  601. '<title>foo\'s settings - Pagure</title>', output_text)
  602. if self.get_wtforms_version() >= (2, 2):
  603. self.assertIn(
  604. '<textarea class="form-control" '
  605. 'id="ssh_key" name="ssh_key" required></textarea>',
  606. output_text)
  607. else:
  608. self.assertIn(
  609. '<textarea class="form-control" '
  610. 'id="ssh_key" name="ssh_key"></textarea>', output_text)
  611. csrf_token = self.get_csrf(output=output)
  612. data = {
  613. 'ssh_key': 'blah'
  614. }
  615. output = self.app.post('/settings/', data=data)
  616. self.assertEqual(output.status_code, 200)
  617. output_text = output.get_data(as_text=True)
  618. self.assertIn(
  619. '<title>foo\'s settings - Pagure</title>', output_text)
  620. data['csrf_token'] = csrf_token
  621. output = self.app.post(
  622. '/settings/', data=data, follow_redirects=True)
  623. self.assertEqual(output.status_code, 200)
  624. output_text = output.get_data(as_text=True)
  625. self.assertIn('Invalid SSH keys', output_text)
  626. self.assertIn(
  627. '<title>foo\'s settings - Pagure</title>', output_text)
  628. self.assertIn('>blah</textarea>', output_text)
  629. csrf_token = output_text.split(
  630. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  631. data = {
  632. 'ssh_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDUkub32fZnNI'
  633. '1zJYs43vhhx3c6IcYo4yzhw1gQ37BLhrrNeS6x8l5PKX4J8ZP5'
  634. '1XhViPaLbeOpl94Vm5VSCbLy0xtY9KwLhMkbKj7g6vvfxLm2sT'
  635. 'Osb15j4jzIkUYYgIE7cHhZMCLWR6UA1c1HEzo6mewMDsvpQ9wk'
  636. 'cDnAuXjK3Q==',
  637. 'csrf_token': csrf_token
  638. }
  639. output = self.app.post(
  640. '/settings/', data=data, follow_redirects=True)
  641. self.assertEqual(output.status_code, 200)
  642. output_text = output.get_data(as_text=True)
  643. self.assertIn('Public ssh key updated', output_text)
  644. self.assertIn(
  645. '<title>foo\'s settings - Pagure</title>', output_text)
  646. if self.get_wtforms_version() >= (2, 2):
  647. self.assertIn(
  648. '<textarea class="form-control" '
  649. 'id="ssh_key" name="ssh_key" required>ssh-rsa AAAA',
  650. output_text)
  651. else:
  652. self.assertIn(
  653. '<textarea class="form-control" '
  654. 'id="ssh_key" name="ssh_key">ssh-rsa AAAA', output_text)
  655. ast.return_value = True
  656. output = self.app.get('/settings/')
  657. self.assertEqual(output.status_code, 302)
  658. @patch.dict('pagure.config.config', {'LOCAL_SSH_KEY': False})
  659. @patch('pagure.ui.app.admin_session_timedout')
  660. def test_user_settings_no_local_ssh_key_ui(self, ast):
  661. """ Test the ssh key field doesn't show when pagure is not managing
  662. the ssh keys. """
  663. ast.return_value = False
  664. self.test_new_project()
  665. user = tests.FakeUser(username = 'foo')
  666. with tests.user_set(self.app.application, user):
  667. output = self.app.get('/settings/')
  668. self.assertEqual(output.status_code, 200)
  669. output_text = output.get_data(as_text=True)
  670. self.assertIn(
  671. '<title>foo\'s settings - Pagure</title>', output_text)
  672. self.assertNotIn(
  673. '<textarea class="form-control" id="ssh_key" name="ssh_key"',
  674. output_text)
  675. @patch.dict('pagure.config.config', {'LOCAL_SSH_KEY': False})
  676. @patch('pagure.ui.app.admin_session_timedout')
  677. def test_user_settings_no_local_ssh_key(self, ast):
  678. """ Test the user_settings endpoint when pagure is not managing the
  679. ssh keys. """
  680. ast.return_value = False
  681. self.test_new_project()
  682. user = tests.FakeUser(username = 'foo')
  683. with tests.user_set(self.app.application, user):
  684. output = self.app.get('/settings/')
  685. self.assertEqual(output.status_code, 200)
  686. output_text = output.get_data(as_text=True)
  687. self.assertIn(
  688. '<title>foo\'s settings - Pagure</title>', output_text)
  689. self.assertNotIn(
  690. '<textarea class="form-control" id="ssh_key" name="ssh_key"',
  691. output_text)
  692. # Before
  693. user = pagure.lib.get_user(self.session, 'foo')
  694. self.assertIsNone(user.public_ssh_key)
  695. csrf_token = self.get_csrf(output=output)
  696. data = {
  697. 'ssh_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDUkub32fZnNI'
  698. '1zJYs43vhhx3c6IcYo4yzhw1gQ37BLhrrNeS6x8l5PKX4J8ZP5'
  699. '1XhViPaLbeOpl94Vm5VSCbLy0xtY9KwLhMkbKj7g6vvfxLm2sT'
  700. 'Osb15j4jzIkUYYgIE7cHhZMCLWR6UA1c1HEzo6mewMDsvpQ9wk'
  701. 'cDnAuXjK3Q==',
  702. 'csrf_token': csrf_token
  703. }
  704. output = self.app.post(
  705. '/settings/', data=data, follow_redirects=True)
  706. self.assertEqual(output.status_code, 200)
  707. output_text = output.get_data(as_text=True)
  708. self.assertNotIn('Public ssh key updated', output_text)
  709. self.assertIn(
  710. '<title>foo\'s settings - Pagure</title>', output_text)
  711. self.assertNotIn(
  712. '<textarea class="form-control" id="ssh_key" name="ssh_key"',
  713. output_text)
  714. # After
  715. user = pagure.lib.get_user(self.session, 'foo')
  716. self.assertIsNone(user.public_ssh_key)
  717. def patched_commit_exists(user, namespace, repo, githash):
  718. ''' Patched version of pagure.pfmarkdown._commit_exists to enforce
  719. returning true on some given hash without having us actually check
  720. the git repos.
  721. '''
  722. if githash in ['9364354', '9364354a', '9364354a4555ba17aa60f0dc844d70b74eb1aecd']:
  723. return True
  724. else:
  725. return False
  726. @patch(
  727. 'pagure.pfmarkdown._commit_exists',
  728. MagicMock(side_effect=patched_commit_exists))
  729. def test_patched_markdown_preview(self):
  730. """ Test the markdown_preview endpoint. """
  731. data = {
  732. 'content': 'test\n----\n\n * 1\n * item 2'
  733. }
  734. # CSRF missing
  735. output = self.app.post('/markdown/', data=data)
  736. self.assertEqual(output.status_code, 400)
  737. user = tests.FakeUser()
  738. user.username = 'foo'
  739. with tests.user_set(self.app.application, user):
  740. output = self.app.get('/settings/')
  741. self.assertEqual(output.status_code, 200)
  742. output_text = output.get_data(as_text=True)
  743. self.assertIn(
  744. '<title>foo\'s settings - Pagure</title>', output_text)
  745. if self.get_wtforms_version() >= (2, 2):
  746. self.assertIn(
  747. '<textarea class="form-control" '
  748. 'id="ssh_key" name="ssh_key" required></textarea>',
  749. output_text)
  750. else:
  751. self.assertIn(
  752. '<textarea class="form-control" '
  753. 'id="ssh_key" name="ssh_key"></textarea>', output_text)
  754. csrf_token = self.get_csrf(output=output)
  755. # With CSRF
  756. data['csrf_token'] = csrf_token
  757. output = self.app.post('/markdown/', data=data)
  758. self.assertEqual(output.status_code, 200)
  759. exp = """<h2>test</h2>
  760. <ul>
  761. <li>1</li>
  762. <li>item 2</li>
  763. </ul>"""
  764. self.assertEqual(output.get_data(as_text=True), exp)
  765. tests.create_projects(self.session)
  766. texts = [
  767. 'pingou committed on test#9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  768. 'Cf commit 936435', # 6 chars - not long enough
  769. 'Cf commit 9364354', # 7 chars - long enough
  770. 'Cf commit 9364354a', # 8 chars - still long enough
  771. 'Cf commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd', # 40 chars
  772. ]
  773. expected = [
  774. # 'pingou committed on test#9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  775. '<p>pingou committed on <a href="/test/c/9364354a4555ba17aa60f0dc844d70b74eb1aecd" '
  776. 'title="Commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd"'
  777. '>test#9364354a4555ba17aa60f0dc844d70b74eb1aecd</a></p>',
  778. # 'Cf commit 936435',
  779. '<p>Cf commit 936435</p>',
  780. # 'Cf commit 9364354',
  781. #'<p>Cf commit 9364354</p>',
  782. '<p>Cf commit <a href="/test/c/9364354" '
  783. 'title="Commit 9364354">9364354</a></p>',
  784. # 'Cf commit 9364354a',
  785. '<p>Cf commit <a href="/test/c/9364354a" '
  786. 'title="Commit 9364354a">9364354</a></p>',
  787. # 'Cf commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  788. '<p>Cf commit <a href="/test/c/9364354a4555ba17aa60f0dc844d70b74eb1aecd" '
  789. 'title="Commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd"'
  790. '>9364354</a></p>',
  791. ]
  792. with self.app.application.app_context():
  793. for idx, text in enumerate(texts):
  794. data = {
  795. 'content': text,
  796. 'csrf_token': csrf_token,
  797. }
  798. output = self.app.post('/markdown/?repo=test', data=data)
  799. self.assertEqual(output.status_code, 200)
  800. self.assertEqual(expected[idx], output.get_data(as_text=True))
  801. def test_markdown_preview(self):
  802. """ Test the markdown_preview endpoint with a non-existing commit.
  803. """
  804. user = tests.FakeUser()
  805. user.username = 'foo'
  806. with tests.user_set(self.app.application, user):
  807. output = self.app.get('/settings/')
  808. self.assertEqual(output.status_code, 200)
  809. output_text = output.get_data(as_text=True)
  810. self.assertIn(
  811. '<title>foo\'s settings - Pagure</title>', output_text)
  812. csrf_token = self.get_csrf(output=output)
  813. tests.create_projects(self.session)
  814. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  815. text = 'Cf commit 9364354a4555ba17aa60f0d'
  816. exp = '<p>Cf commit 9364354a4555ba17aa60f0d</p>'
  817. with self.app.application.app_context():
  818. data = {
  819. 'content': text,
  820. 'csrf_token': csrf_token,
  821. }
  822. output = self.app.post('/markdown/?repo=test', data=data)
  823. self.assertEqual(output.status_code, 200)
  824. self.assertEqual(exp, output.get_data(as_text=True))
  825. def test_markdown_preview_valid_commit(self):
  826. """ Test the markdown_preview endpoint with an existing commit. """
  827. user = tests.FakeUser()
  828. user.username = 'foo'
  829. with tests.user_set(self.app.application, user):
  830. output = self.app.get('/settings/')
  831. self.assertEqual(output.status_code, 200)
  832. output_text = output.get_data(as_text=True)
  833. self.assertIn(
  834. '<title>foo\'s settings - Pagure</title>', output_text)
  835. csrf_token = self.get_csrf(output=output)
  836. tests.create_projects(self.session)
  837. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  838. repopath = os.path.join(self.path, 'repos', 'test.git')
  839. tests.add_content_git_repo(repopath)
  840. repo = pygit2.Repository(repopath)
  841. first_commit = repo.revparse_single('HEAD')
  842. text = 'Cf commit %s' % first_commit.oid.hex
  843. exp = '<p>Cf commit <a href="/test/c/{0}" title="Commit {0}">{1}'\
  844. '</a></p>'.format(first_commit.oid.hex, first_commit.oid.hex[:7])
  845. with self.app.application.app_context():
  846. data = {
  847. 'content': text,
  848. 'csrf_token': csrf_token,
  849. }
  850. output = self.app.post('/markdown/?repo=test', data=data)
  851. self.assertEqual(output.status_code, 200)
  852. self.assertEqual(exp, output.get_data(as_text=True))
  853. @patch('pagure.ui.app.admin_session_timedout')
  854. def test_remove_user_email(self, ast):
  855. """ Test the remove_user_email endpoint. """
  856. ast.return_value = False
  857. self.test_new_project()
  858. user = tests.FakeUser()
  859. with tests.user_set(self.app.application, user):
  860. output = self.app.post('/settings/email/drop')
  861. self.assertEqual(output.status_code, 404)
  862. self.assertIn('<h2>Page not found (404)</h2>', output.get_data(as_text=True))
  863. user.username = 'foo'
  864. with tests.user_set(self.app.application, user):
  865. output = self.app.post('/settings/')
  866. self.assertEqual(output.status_code, 200)
  867. output_text = output.get_data(as_text=True)
  868. self.assertIn(
  869. '<title>foo\'s settings - Pagure</title>', output_text)
  870. if self.get_wtforms_version() >= (2, 2):
  871. self.assertIn(
  872. '<textarea class="form-control form-control-error" '
  873. 'id="ssh_key" name="ssh_key" required></textarea>',
  874. output_text)
  875. else:
  876. self.assertIn(
  877. '<textarea class="form-control form-control-error" '
  878. 'id="ssh_key" name="ssh_key"></textarea>', output_text)
  879. csrf_token = self.get_csrf(output=output)
  880. data = {
  881. 'email': 'foo@pingou.com',
  882. }
  883. output = self.app.post(
  884. '/settings/email/drop', data=data, follow_redirects=True)
  885. self.assertEqual(output.status_code, 200)
  886. output_text = output.get_data(as_text=True)
  887. self.assertIn(
  888. '<title>foo\'s settings - Pagure</title>', output_text)
  889. self.assertIn(
  890. 'You must always have at '
  891. 'least one email', output_text)
  892. user.username = 'pingou'
  893. with tests.user_set(self.app.application, user):
  894. output = self.app.post('/settings/')
  895. self.assertEqual(output.status_code, 200)
  896. output_text = output.get_data(as_text=True)
  897. self.assertIn(
  898. '<title>pingou\'s settings - Pagure</title>', output_text)
  899. if self.get_wtforms_version() >= (2, 2):
  900. self.assertIn(
  901. '<textarea class="form-control form-control-error" '
  902. 'id="ssh_key" name="ssh_key" required></textarea>',
  903. output_text)
  904. else:
  905. self.assertIn(
  906. '<textarea class="form-control form-control-error" '
  907. 'id="ssh_key" name="ssh_key"></textarea>', output_text)
  908. csrf_token = self.get_csrf(output=output)
  909. data = {
  910. 'email': 'foo@pingou.com',
  911. }
  912. output = self.app.post(
  913. '/settings/email/drop', data=data, follow_redirects=True)
  914. self.assertEqual(output.status_code, 200)
  915. output_text = output.get_data(as_text=True)
  916. self.assertIn(
  917. '<title>pingou\'s settings - Pagure</title>', output_text)
  918. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  919. data = {
  920. 'csrf_token': csrf_token,
  921. 'email': 'foobar@pingou.com',
  922. }
  923. output = self.app.post(
  924. '/settings/email/drop', data=data, follow_redirects=True)
  925. self.assertEqual(output.status_code, 200)
  926. output_text = output.get_data(as_text=True)
  927. self.assertIn(
  928. '<title>pingou\'s settings - Pagure</title>', output_text)
  929. self.assertIn(
  930. 'You do not have the '
  931. 'email: foobar@pingou.com, nothing to remove', output_text)
  932. data = {
  933. 'csrf_token': csrf_token,
  934. 'email': 'foo@pingou.com',
  935. }
  936. output = self.app.post(
  937. '/settings/email/drop', data=data, follow_redirects=True)
  938. self.assertEqual(output.status_code, 200)
  939. output_text = output.get_data(as_text=True)
  940. self.assertEqual(output_text.count('foo@pingou.com'), 0)
  941. self.assertEqual(output_text.count('bar@pingou.com'), 3)
  942. output = self.app.post(
  943. '/settings/email/drop', data=data, follow_redirects=True)
  944. self.assertEqual(output.status_code, 200)
  945. output_text = output.get_data(as_text=True)
  946. self.assertEqual(output_text.count('foo@pingou.com'), 0)
  947. self.assertEqual(output_text.count('bar@pingou.com'), 3)
  948. ast.return_value = True
  949. output = self.app.post('/settings/email/drop', data=data)
  950. self.assertEqual(output.status_code, 302)
  951. @patch('pagure.lib.notify.send_email')
  952. @patch('pagure.ui.app.admin_session_timedout')
  953. def test_add_api_user_email(self, ast, send_email):
  954. """ Test the add_api_user_email endpoint. """
  955. send_email.return_value = True
  956. ast.return_value = False
  957. self.test_new_project()
  958. user = tests.FakeUser()
  959. with tests.user_set(self.app.application, user):
  960. output = self.app.post('/settings/email/add')
  961. self.assertEqual(output.status_code, 404)
  962. self.assertIn('<h2>Page not found (404)</h2>', output.get_data(as_text=True))
  963. user.username = 'foo'
  964. with tests.user_set(self.app.application, user):
  965. output = self.app.post('/settings/email/add')
  966. self.assertEqual(output.status_code, 200)
  967. output_text = output.get_data(as_text=True)
  968. self.assertIn("<strong>Add new email</strong>", output_text)
  969. if self.get_wtforms_version() >= (2, 2):
  970. self.assertIn(
  971. '<input class="form-control form-control-error" id="email" '
  972. 'name="email" required type="text" value="">', output_text)
  973. else:
  974. self.assertIn(
  975. '<input class="form-control form-control-error" id="email" '
  976. 'name="email" type="text" value="">', output_text)
  977. user.username = 'pingou'
  978. with tests.user_set(self.app.application, user):
  979. output = self.app.post('/settings/email/add')
  980. self.assertEqual(output.status_code, 200)
  981. output_text = output.get_data(as_text=True)
  982. self.assertIn("<strong>Add new email</strong>", output_text)
  983. if self.get_wtforms_version() >= (2, 2):
  984. self.assertIn(
  985. '<input class="form-control form-control-error" id="email" '
  986. 'name="email" required type="text" value="">', output_text)
  987. else:
  988. self.assertIn(
  989. '<input class="form-control form-control-error" id="email" '
  990. 'name="email" type="text" value="">', output_text)
  991. csrf_token = output_text.split(
  992. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  993. data = {
  994. 'email': 'foo2@pingou.com',
  995. }
  996. output = self.app.post(
  997. '/settings/email/add', data=data, follow_redirects=True)
  998. self.assertEqual(output.status_code, 200)
  999. output_text = output.get_data(as_text=True)
  1000. self.assertIn("<strong>Add new email</strong>", output_text)
  1001. self.assertEqual(output_text.count('foo2@pingou.com'), 1)
  1002. # New email
  1003. data = {
  1004. 'csrf_token': csrf_token,
  1005. 'email': 'foðbar@pingou.com',
  1006. }
  1007. output = self.app.post(
  1008. '/settings/email/add', data=data, follow_redirects=True)
  1009. self.assertEqual(output.status_code, 200)
  1010. output_text = output.get_data(as_text=True)
  1011. self.assertIn(
  1012. '<title>pingou\'s settings - Pagure</title>', output_text)
  1013. self.assertIn(
  1014. 'Email pending validation',
  1015. output_text)
  1016. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1017. self.assertEqual(output_text.count('bar@pingou.com'), 5)
  1018. self.assertEqual(output_text.count('foðbar@pingou.com'), 2)
  1019. # Email already pending
  1020. output = self.app.post(
  1021. '/settings/email/add', data=data, follow_redirects=True)
  1022. self.assertEqual(output.status_code, 200)
  1023. output_text = output.get_data(as_text=True)
  1024. self.assertIn(
  1025. '<div class="card-header">\n '
  1026. '<strong>Add new email</strong>', output_text)
  1027. self.assertIn(
  1028. 'This email is already '
  1029. 'pending confirmation', output_text)
  1030. # User already has this email
  1031. data = {
  1032. 'csrf_token': csrf_token,
  1033. 'email': 'foo@pingou.com',
  1034. }
  1035. output = self.app.post(
  1036. '/settings/email/add', data=data, follow_redirects=True)
  1037. self.assertEqual(output.status_code, 200)
  1038. output_text = output.get_data(as_text=True)
  1039. self.assertTrue("<strong>Add new email</strong>" in output_text)
  1040. self.assertTrue(
  1041. 'Invalid value, can&#39;t be any of: bar@pingou.com, '
  1042. 'foo@pingou.com.&nbsp;' in output_text
  1043. or
  1044. 'Invalid value, can&#39;t be any of: foo@pingou.com, '
  1045. 'bar@pingou.com.&nbsp;' in output_text
  1046. )
  1047. self.assertEqual(
  1048. output_text.count('foo@pingou.com'), 6)
  1049. self.assertEqual(
  1050. output_text.count('bar@pingou.com'), 5)
  1051. self.assertEqual(
  1052. output_text.count('foðbar@pingou.com'), 0)
  1053. # Email registered by someone else
  1054. data = {
  1055. 'csrf_token': csrf_token,
  1056. 'email': 'foo@bar.com',
  1057. }
  1058. output = self.app.post(
  1059. '/settings/email/add', data=data, follow_redirects=True)
  1060. self.assertEqual(output.status_code, 200)
  1061. output_text = output.get_data(as_text=True)
  1062. self.assertTrue("<strong>Add new email</strong>" in output_text)
  1063. self.assertIn(
  1064. 'Invalid value, can&#39;t be any of: foo@bar.com.&nbsp;',
  1065. output_text)
  1066. ast.return_value = True
  1067. output = self.app.post('/settings/email/add', data=data)
  1068. self.assertEqual(output.status_code, 302)
  1069. @patch('pagure.lib.notify.send_email')
  1070. @patch('pagure.ui.app.admin_session_timedout')
  1071. def test_set_default_email(self, ast, send_email):
  1072. """ Test the set_default_email endpoint. """
  1073. send_email.return_value = True
  1074. ast.return_value = False
  1075. self.test_new_project()
  1076. user = tests.FakeUser()
  1077. with tests.user_set(self.app.application, user):
  1078. output = self.app.post('/settings/email/default')
  1079. self.assertEqual(output.status_code, 404)
  1080. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1081. user.username = 'pingou'
  1082. with tests.user_set(self.app.application, user):
  1083. output = self.app.get('/settings/')
  1084. self.assertEqual(output.status_code, 200)
  1085. output_text = output.get_data(as_text=True)
  1086. self.assertIn(
  1087. '<title>pingou\'s settings - Pagure</title>', output_text)
  1088. if self.get_wtforms_version() >= (2, 2):
  1089. self.assertIn(
  1090. '<textarea class="form-control" '
  1091. 'id="ssh_key" name="ssh_key" required></textarea>',
  1092. output_text)
  1093. else:
  1094. self.assertIn(
  1095. '<textarea class="form-control" '
  1096. 'id="ssh_key" name="ssh_key"></textarea>', output_text)
  1097. csrf_token = self.get_csrf(output=output)
  1098. data = {
  1099. 'email': 'foo@pingou.com',
  1100. }
  1101. output = self.app.post(
  1102. '/settings/email/default', data=data, follow_redirects=True)
  1103. self.assertEqual(output.status_code, 200)
  1104. output_text = output.get_data(as_text=True)
  1105. self.assertIn(
  1106. '<title>pingou\'s settings - Pagure</title>', output_text)
  1107. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1108. # Set invalid default email
  1109. data = {
  1110. 'csrf_token': csrf_token,
  1111. 'email': 'foobar@pingou.com',
  1112. }
  1113. output = self.app.post(
  1114. '/settings/email/default', data=data, follow_redirects=True)
  1115. self.assertEqual(output.status_code, 200)
  1116. output_text = output.get_data(as_text=True)
  1117. self.assertIn(
  1118. '<title>pingou\'s settings - Pagure</title>', output_text)
  1119. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1120. self.assertIn(
  1121. 'You do not have the '
  1122. 'email: foobar@pingou.com, nothing to set',
  1123. output_text)
  1124. # Set default email
  1125. data = {
  1126. 'csrf_token': csrf_token,
  1127. 'email': 'foo@pingou.com',
  1128. }
  1129. output = self.app.post(
  1130. '/settings/email/default', data=data, follow_redirects=True)
  1131. self.assertEqual(output.status_code, 200)
  1132. output_text = output.get_data(as_text=True)
  1133. self.assertIn(
  1134. '<title>pingou\'s settings - Pagure</title>', output_text)
  1135. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1136. self.assertIn(
  1137. 'Default email set to: '
  1138. 'foo@pingou.com', output_text)
  1139. ast.return_value = True
  1140. output = self.app.post('/settings/email/default', data=data)
  1141. self.assertEqual(output.status_code, 302)
  1142. @patch('pagure.lib.notify.send_email')
  1143. @patch('pagure.ui.app.admin_session_timedout')
  1144. def test_reconfirm_email(self, ast, send_email):
  1145. """ Test the reconfirm_email endpoint. """
  1146. send_email.return_value = True
  1147. ast.return_value = False
  1148. self.test_new_project()
  1149. # Add a pending email to pingou
  1150. userobj = pagure.lib.search_user(self.session, username='pingou')
  1151. self.assertEqual(len(userobj.emails), 2)
  1152. email_pend = pagure.lib.model.UserEmailPending(
  1153. user_id=userobj.id,
  1154. email='foo@fp.o',
  1155. token='abcdef',
  1156. )
  1157. self.session.add(email_pend)
  1158. self.session.commit()
  1159. user = tests.FakeUser()
  1160. with tests.user_set(self.app.application, user):
  1161. output = self.app.post('/settings/email/resend')
  1162. self.assertEqual(output.status_code, 404)
  1163. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1164. user.username = 'pingou'
  1165. with tests.user_set(self.app.application, user):
  1166. output = self.app.get('/settings/')
  1167. self.assertEqual(output.status_code, 200)
  1168. output_text = output.get_data(as_text=True)
  1169. self.assertIn(
  1170. '<title>pingou\'s settings - Pagure</title>', output_text)
  1171. if self.get_wtforms_version() >= (2, 2):
  1172. self.assertIn(
  1173. '<textarea class="form-control" '
  1174. 'id="ssh_key" name="ssh_key" required></textarea>',
  1175. output_text)
  1176. else:
  1177. self.assertIn(
  1178. '<textarea class="form-control" '
  1179. 'id="ssh_key" name="ssh_key"></textarea>', output_text)
  1180. csrf_token = self.get_csrf(output=output)
  1181. data = {
  1182. 'email': 'foo@pingou.com',
  1183. }
  1184. output = self.app.post(
  1185. '/settings/email/resend', data=data, follow_redirects=True)
  1186. self.assertEqual(output.status_code, 200)
  1187. output_text = output.get_data(as_text=True)
  1188. self.assertIn(
  1189. '<title>pingou\'s settings - Pagure</title>', output_text)
  1190. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1191. # Set invalid default email
  1192. data = {
  1193. 'csrf_token': csrf_token,
  1194. 'email': 'foobar@pingou.com',
  1195. }
  1196. output = self.app.post(
  1197. '/settings/email/resend', data=data, follow_redirects=True)
  1198. self.assertEqual(output.status_code, 200)
  1199. output_text = output.get_data(as_text=True)
  1200. self.assertIn(
  1201. '<title>pingou\'s settings - Pagure</title>', output_text)
  1202. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1203. self.assertIn(
  1204. 'This email address has '
  1205. 'already been confirmed', output_text)
  1206. # Validate a non-validated email
  1207. data = {
  1208. 'csrf_token': csrf_token,
  1209. 'email': 'foo@fp.o',
  1210. }
  1211. output = self.app.post(
  1212. '/settings/email/resend', data=data, follow_redirects=True)
  1213. self.assertEqual(output.status_code, 200)
  1214. output_text = output.get_data(as_text=True)
  1215. self.assertIn(
  1216. '<title>pingou\'s settings - Pagure</title>', output_text)
  1217. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1218. self.assertIn(
  1219. 'Confirmation email re-sent',
  1220. output_text)
  1221. ast.return_value = True
  1222. output = self.app.post('/settings/email/resend', data=data)
  1223. self.assertEqual(output.status_code, 302)
  1224. @patch('pagure.ui.app.admin_session_timedout')
  1225. def test_confirm_email(self, ast):
  1226. """ Test the confirm_email endpoint. """
  1227. output = self.app.get('/settings/email/confirm/foobar')
  1228. self.assertEqual(output.status_code, 302)
  1229. ast.return_value = False
  1230. # Add a pending email to pingou
  1231. userobj = pagure.lib.search_user(self.session, username='pingou')
  1232. self.assertEqual(len(userobj.emails), 2)
  1233. email_pend = pagure.lib.model.UserEmailPending(
  1234. user_id=userobj.id,
  1235. email='foo@fp.o',
  1236. token='abcdef',
  1237. )
  1238. self.session.add(email_pend)
  1239. self.session.commit()
  1240. user = tests.FakeUser()
  1241. user.username = 'pingou'
  1242. with tests.user_set(self.app.application, user):
  1243. # Wrong token
  1244. output = self.app.get(
  1245. '/settings/email/confirm/foobar', follow_redirects=True)
  1246. self.assertEqual(output.status_code, 200)
  1247. output_text = output.get_data(as_text=True)
  1248. self.assertIn(
  1249. '<title>pingou\'s settings - Pagure</title>', output_text)
  1250. self.assertIn(
  1251. 'No email associated with this token.',
  1252. output_text)
  1253. # Confirm email
  1254. output = self.app.get(
  1255. '/settings/email/confirm/abcdef', follow_redirects=True)
  1256. self.assertEqual(output.status_code, 200)
  1257. output_text = output.get_data(as_text=True)
  1258. self.assertIn(
  1259. '<title>pingou\'s settings - Pagure</title>', output_text)
  1260. self.assertIn(
  1261. 'Email validated',
  1262. output_text)
  1263. userobj = pagure.lib.search_user(self.session, username='pingou')
  1264. self.assertEqual(len(userobj.emails), 3)
  1265. ast.return_value = True
  1266. output = self.app.get('/settings/email/confirm/foobar')
  1267. self.assertEqual(output.status_code, 302)
  1268. def test_view_my_requests_no_user(self):
  1269. """Test the view_user_requests endpoint."""
  1270. output = self.app.get('/user/somenonexistentuser/requests')
  1271. self.assertEqual(output.status_code, 404)
  1272. @patch(
  1273. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1274. @patch(
  1275. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1276. def test_view_my_requests(self):
  1277. """Test the view_user_requests endpoint. """
  1278. # Create the PR
  1279. tests.create_projects(self.session)
  1280. repo = pagure.lib._get_project(self.session, 'test')
  1281. req = pagure.lib.new_pull_request(
  1282. session=self.session,
  1283. repo_from=repo,
  1284. branch_from='dev',
  1285. repo_to=repo,
  1286. branch_to='master',
  1287. title='test pull-request #1',
  1288. user='pingou',
  1289. )
  1290. self.session.commit()
  1291. self.assertEqual(req.id, 1)
  1292. self.assertEqual(req.title, 'test pull-request #1')
  1293. output = self.app.get('/user/pingou/requests')
  1294. self.assertEqual(output.status_code, 200)
  1295. output_text = output.get_data(as_text=True)
  1296. self.assertIn('test pull-request #1', output_text)
  1297. self.assertEqual(
  1298. output_text.count('pr-status pr-status-open"'),
  1299. 1)
  1300. # Add a PR in a fork
  1301. item = pagure.lib.model.Project(
  1302. user_id=1, # pingou
  1303. name='test_fork',
  1304. description='test project #1',
  1305. is_fork=True,
  1306. parent_id=1,
  1307. hook_token='aaabbbttt',
  1308. )
  1309. self.session.add(item)
  1310. repo = pagure.lib._get_project(
  1311. self.session, 'test_fork', user='pingou')
  1312. req = pagure.lib.new_pull_request(
  1313. session=self.session,
  1314. repo_from=repo,
  1315. branch_from='dev',
  1316. repo_to=repo,
  1317. branch_to='master',
  1318. title='tést pull-request #2',
  1319. user='pingou',
  1320. )
  1321. self.session.commit()
  1322. self.assertEqual(req.id, 1)
  1323. self.assertEqual(req.title, 'tést pull-request #2')
  1324. output = self.app.get('/user/pingou/requests')
  1325. self.assertEqual(output.status_code, 200)
  1326. output_text = output.get_data(as_text=True)
  1327. self.assertIn('test pull-request #1', output_text)
  1328. self.assertIn('tést pull-request #2', output_text)
  1329. self.assertEqual(
  1330. output_text.count('pr-status pr-status-open"'),
  1331. 2)
  1332. @patch(
  1333. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1334. @patch(
  1335. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1336. def test_view_my_requests_pr_in_another_project(self):
  1337. """Test the view_user_requests endpoint when the user opened a PR
  1338. in another project. """
  1339. # Pingou creates the PR on test
  1340. tests.create_projects(self.session)
  1341. repo = pagure.lib._get_project(self.session, 'test')
  1342. req = pagure.lib.new_pull_request(
  1343. session=self.session,
  1344. repo_from=repo,
  1345. branch_from='dev',
  1346. repo_to=repo,
  1347. branch_to='master',
  1348. title='test pull-request #1',
  1349. user='pingou',
  1350. )
  1351. self.session.commit()
  1352. self.assertEqual(req.id, 1)
  1353. self.assertEqual(req.title, 'test pull-request #1')
  1354. # foo creates the PR on test
  1355. repo = pagure.lib._get_project(self.session, 'test')
  1356. req = pagure.lib.new_pull_request(
  1357. session=self.session,
  1358. repo_from=repo,
  1359. branch_from='dev',
  1360. repo_to=repo,
  1361. branch_to='master',
  1362. title='test pull-request #2',
  1363. user='foo',
  1364. )
  1365. self.session.commit()
  1366. self.assertEqual(req.id, 2)
  1367. self.assertEqual(req.title, 'test pull-request #2')
  1368. # Check pingou's PR list
  1369. output = self.app.get('/user/pingou/requests')
  1370. self.assertEqual(output.status_code, 200)
  1371. output_text = output.get_data(as_text=True)
  1372. self.assertIn('test pull-request #1', output_text)
  1373. self.assertIn('test pull-request #2', output_text)
  1374. self.assertEqual(
  1375. output_text.count('pr-status pr-status-open"'),
  1376. 2)
  1377. # Check foo's PR list
  1378. output = self.app.get('/user/foo/requests')
  1379. self.assertEqual(output.status_code, 200)
  1380. output_text = output.get_data(as_text=True)
  1381. self.assertNotIn('test pull-request #1', output_text)
  1382. self.assertIn('test pull-request #2', output_text)
  1383. self.assertEqual(
  1384. output_text.count('pr-status pr-status-open"'),
  1385. 1)
  1386. @patch(
  1387. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1388. @patch(
  1389. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1390. def test_view_my_requests_against_another_project(self):
  1391. """Test the view_user_requests endpoint when there is a PR opened
  1392. by me against a project I do not have rights on. """
  1393. # Create the PR
  1394. tests.create_projects(self.session)
  1395. repo = pagure.lib._get_project(self.session, 'test')
  1396. req = pagure.lib.new_pull_request(
  1397. session=self.session,
  1398. repo_from=repo,
  1399. branch_from='dev',
  1400. repo_to=repo,
  1401. branch_to='master',
  1402. title='test pull-request #1',
  1403. user='foo',
  1404. )
  1405. self.session.commit()
  1406. self.assertEqual(req.id, 1)
  1407. self.assertEqual(req.title, 'test pull-request #1')
  1408. output = self.app.get('/user/foo/requests')
  1409. self.assertEqual(output.status_code, 200)
  1410. output_text = output.get_data(as_text=True)
  1411. self.assertIn('test pull-request #1', output_text)
  1412. self.assertEqual(
  1413. output_text.count('pr-status pr-status-open"'),
  1414. 1)
  1415. def test_view_my_issues_no_user(self):
  1416. """Test the view_user_issues endpoint with a missing user."""
  1417. output = self.app.get('/user/somenonexistentuser/issues')
  1418. self.assertEqual(output.status_code, 404)
  1419. @patch(
  1420. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1421. @patch(
  1422. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1423. def test_view_my_issues(self):
  1424. """Test the view_user_issues endpoint when the user exists."""
  1425. # Create the issue
  1426. tests.create_projects(self.session)
  1427. repo = pagure.lib._get_project(self.session, 'test')
  1428. msg = pagure.lib.new_issue(
  1429. session=self.session,
  1430. repo=repo,
  1431. title='Test issue #1',
  1432. content='We should work on this for the second time',
  1433. user='pingou',
  1434. status='Open',
  1435. )
  1436. self.session.commit()
  1437. self.assertEqual(msg.title, 'Test issue #1')
  1438. output = self.app.get('/user/pingou/issues')
  1439. self.assertEqual(output.status_code, 200)
  1440. output_text = output.get_data(as_text=True)
  1441. self.assertIn('Test issue #1', output_text)
  1442. self.assertEqual(
  1443. output_text.count(
  1444. 'issue-status issue-status-open'),
  1445. 1)
  1446. # Add an issue in a fork
  1447. item = pagure.lib.model.Project(
  1448. user_id=2, # foo
  1449. name='test_fork',
  1450. description='test project #1',
  1451. is_fork=True,
  1452. parent_id=1,
  1453. hook_token='aaabbbttt',
  1454. )
  1455. self.session.add(item)
  1456. repo = pagure.lib._get_project(self.session, 'test_fork', user='foo')
  1457. msg = pagure.lib.new_issue(
  1458. session=self.session,
  1459. repo=repo,
  1460. title='Test issue #2',
  1461. content='We should work on this for the second time',
  1462. user='pingou',
  1463. status='Open',
  1464. )
  1465. self.session.commit()
  1466. self.assertEqual(msg.title, 'Test issue #2')
  1467. # Test the assigned issue table. Create issue then set the assignee
  1468. msg = pagure.lib.new_issue(
  1469. session=self.session,
  1470. repo=repo,
  1471. title='Test issue #3',
  1472. content='This issue created by foo, but assigned to pingou',
  1473. user='foo',
  1474. status='Open',
  1475. )
  1476. self.session.commit()
  1477. self.assertEqual(msg.title, 'Test issue #3')
  1478. msg = pagure.lib.add_issue_assignee(
  1479. session=self.session,
  1480. issue=msg,
  1481. assignee='pingou',
  1482. user='foo',
  1483. )
  1484. self.session.commit()
  1485. self.assertEqual(msg, 'Issue assigned to pingou')
  1486. output = self.app.get('/user/pingou/issues')
  1487. self.assertEqual(output.status_code, 200)
  1488. output_text = output.get_data(as_text=True)
  1489. self.assertIn('Test issue #1', output_text)
  1490. self.assertIn('Test issue #2', output_text)
  1491. self.assertIn('Test issue #3', output_text)
  1492. self.assertEqual(
  1493. output_text.count(
  1494. 'issue-status issue-status-open'),
  1495. 3)
  1496. @patch(
  1497. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1498. @patch(
  1499. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1500. def test_view_my_issues_disabled(self):
  1501. """Test the view_user_issues endpoint when the project disabled issue
  1502. tracking."""
  1503. # Create the issue
  1504. tests.create_projects(self.session)
  1505. repo = pagure.lib._get_project(self.session, 'test')
  1506. msg = pagure.lib.new_issue(
  1507. session=self.session,
  1508. repo=repo,
  1509. title='Test issue #1',
  1510. content='We should work on this for the second time',
  1511. user='pingou',
  1512. status='Open',
  1513. )
  1514. self.session.commit()
  1515. self.assertEqual(msg.title, 'Test issue #1')
  1516. # Before
  1517. output = self.app.get('/user/pingou/issues')
  1518. self.assertEqual(output.status_code, 200)
  1519. output_text = output.get_data(as_text=True)
  1520. self.assertIn('Test issue #1', output_text)
  1521. self.assertEqual(
  1522. output_text.count('issue-status issue-status-open'),
  1523. 1)
  1524. # Disable issue tracking
  1525. repo = pagure.lib._get_project(self.session, 'test')
  1526. settings = repo.settings
  1527. settings['issue_tracker'] = False
  1528. repo.settings = settings
  1529. self.session.add(repo)
  1530. self.session.commit()
  1531. # After
  1532. output = self.app.get('/user/pingou/issues')
  1533. self.assertEqual(output.status_code, 200)
  1534. output_text = output.get_data(as_text=True)
  1535. self.assertNotIn('Test issue #1', output_text)
  1536. self.assertEqual(
  1537. output_text.count('issue-status issue-status-open'),
  1538. 0)
  1539. def test_view_my_issues_tickets_turned_off(self):
  1540. """Test the view_user_issues endpoint when the user exists and
  1541. and ENABLE_TICKETS is False """
  1542. # Turn off the tickets instance wide
  1543. pagure.config.config['ENABLE_TICKETS'] = False
  1544. output = self.app.get('/user/pingou/issues')
  1545. self.assertEqual(output.status_code, 404)
  1546. pagure.config.config['ENABLE_TICKETS'] = True
  1547. @patch('pagure.ui.app.admin_session_timedout')
  1548. def test_add_user_token(self, ast):
  1549. """ Test the add_user_token endpoint. """
  1550. ast.return_value = False
  1551. self.test_new_project()
  1552. user = tests.FakeUser()
  1553. with tests.user_set(self.app.application, user):
  1554. output = self.app.get('/settings/token/new/')
  1555. self.assertEqual(output.status_code, 404)
  1556. self.assertIn('<h2>Page not found (404)</h2>',
  1557. output.get_data(as_text=True))
  1558. user.username = 'foo'
  1559. with tests.user_set(self.app.application, user):
  1560. output = self.app.get('/settings/token/new')
  1561. self.assertEqual(output.status_code, 200)
  1562. output_text = output.get_data(as_text=True)
  1563. self.assertIn(
  1564. '<div class="card-header">\n <strong>'
  1565. 'Create a new token</strong>\n', output_text)
  1566. self.assertIn(
  1567. '<input type="checkbox" name="acls" value="create_project">',
  1568. output_text)
  1569. csrf_token = output_text.split(
  1570. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1571. data = {
  1572. 'acls': ['create_project', 'fork_project']
  1573. }
  1574. # missing CSRF
  1575. output = self.app.post('/settings/token/new', data=data)
  1576. self.assertEqual(output.status_code, 200)
  1577. output_text = output.get_data(as_text=True)
  1578. self.assertIn(
  1579. '<title>Create token - Pagure</title>', output_text)
  1580. self.assertIn(
  1581. '<div class="card-header">\n <strong>'
  1582. 'Create a new token</strong>\n', output_text)
  1583. self.assertIn(
  1584. '<input type="checkbox" name="acls" value="create_project">',
  1585. output_text)
  1586. data = {
  1587. 'acls': ['new_project'],
  1588. 'csrf_token': csrf_token
  1589. }
  1590. # Invalid ACLs
  1591. output = self.app.post('/settings/token/new', data=data)
  1592. self.assertEqual(output.status_code, 200)
  1593. output_text = output.get_data(as_text=True)
  1594. self.assertIn(
  1595. '<title>Create token - Pagure</title>', output_text)
  1596. self.assertIn(
  1597. '<div class="card-header">\n <strong>'
  1598. 'Create a new token</strong>\n', output_text)
  1599. self.assertIn(
  1600. '<input type="checkbox" name="acls" value="create_project">',
  1601. output_text)
  1602. data = {
  1603. 'acls': ['create_project', 'fork_project'],
  1604. 'csrf_token': csrf_token
  1605. }
  1606. # All good
  1607. output = self.app.post(
  1608. '/settings/token/new', data=data, follow_redirects=True)
  1609. self.assertEqual(output.status_code, 200)
  1610. output_text = output.get_data(as_text=True)
  1611. self.assertIn(
  1612. '<title>foo\'s settings - Pagure</title>', output_text)
  1613. self.assertIn(
  1614. 'Token created',
  1615. output_text)
  1616. self.assertEqual(
  1617. output_text.count(
  1618. '<small class="font-weight-bold text-success input-group-text">Active until'), 1)
  1619. ast.return_value = True
  1620. output = self.app.get('/settings/token/new')
  1621. self.assertEqual(output.status_code, 302)
  1622. @patch('pagure.ui.app.admin_session_timedout')
  1623. def test_revoke_api_user_token(self, ast):
  1624. """ Test the revoke_api_user_token endpoint. """
  1625. ast.return_value = False
  1626. self.test_new_project()
  1627. user = tests.FakeUser()
  1628. with tests.user_set(self.app.application, user):
  1629. # Token doesn't exist
  1630. output = self.app.post('/settings/token/revoke/foobar')
  1631. self.assertEqual(output.status_code, 404)
  1632. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1633. # Create the foobar API token but associated w/ the user 'foo'
  1634. item = pagure.lib.model.Token(
  1635. id='foobar',
  1636. user_id=2, # foo
  1637. expiration=datetime.datetime.utcnow() \
  1638. + datetime.timedelta(days=30)
  1639. )
  1640. self.session.add(item)
  1641. self.session.commit()
  1642. # Token not associated w/ this user
  1643. output = self.app.post('/settings/token/revoke/foobar')
  1644. self.assertEqual(output.status_code, 404)
  1645. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1646. user.username = 'foo'
  1647. with tests.user_set(self.app.application, user):
  1648. # Missing CSRF token
  1649. output = self.app.post(
  1650. '/settings/token/revoke/foobar', follow_redirects=True)
  1651. self.assertEqual(output.status_code, 200)
  1652. output_text = output.get_data(as_text=True)
  1653. self.assertIn(
  1654. "<title>foo's settings - Pagure</title>", output_text)
  1655. self.assertEqual(
  1656. output_text.count(
  1657. '<small class="font-weight-bold text-success input-group-text">Active until'), 1)
  1658. csrf_token = output_text.split(
  1659. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1660. data = {
  1661. 'csrf_token': csrf_token
  1662. }
  1663. # All good - token is deleted
  1664. output = self.app.post(
  1665. '/settings/token/revoke/foobar', data=data,
  1666. follow_redirects=True)
  1667. self.assertEqual(output.status_code, 200)
  1668. output_text = output.get_data(as_text=True)
  1669. self.assertIn(
  1670. "<title>foo's settings - Pagure</title>", output_text)
  1671. self.assertEqual(
  1672. output_text.count(
  1673. '<small class="font-weight-bold text-success input-group-text">Active until'), 0)
  1674. user = pagure.lib.get_user(self.session, key='foo')
  1675. self.assertEqual(len(user.tokens), 1)
  1676. expiration_dt = user.tokens[0].expiration
  1677. # Token was already deleted - no changes
  1678. output = self.app.post(
  1679. '/settings/token/revoke/foobar', data=data,
  1680. follow_redirects=True)
  1681. self.assertEqual(output.status_code, 200)
  1682. output_text = output.get_data(as_text=True)
  1683. self.assertIn(
  1684. "<title>foo's settings - Pagure</title>", output_text)
  1685. self.assertEqual(
  1686. output_text.count(
  1687. '<small class="font-weight-bold text-success input-group-text">Active until'), 0)
  1688. # Ensure the expiration date did not change
  1689. user = pagure.lib.get_user(self.session, key='foo')
  1690. self.assertEqual(len(user.tokens), 1)
  1691. self.assertEqual(
  1692. expiration_dt, user.tokens[0].expiration
  1693. )
  1694. ast.return_value = True
  1695. output = self.app.get('/settings/token/new')
  1696. self.assertEqual(output.status_code, 302)
  1697. class PagureFlaskAppNoDocstests(tests.Modeltests):
  1698. """ Tests for flask app controller of pagure """
  1699. config_values = {
  1700. "enable_docs": False,
  1701. "docs_folder": None,
  1702. }
  1703. def test_new_project_no_docs_folder(self):
  1704. """ Test the new_project endpoint with DOCS_FOLDER is None. """
  1705. # Before
  1706. projects = pagure.lib.search_projects(self.session)
  1707. self.assertEqual(len(projects), 0)
  1708. self.assertFalse(os.path.exists(
  1709. os.path.join(self.path, 'repos', 'project#1.git')))
  1710. self.assertFalse(os.path.exists(
  1711. os.path.join(self.path, 'repos', 'tickets', 'project#1.git')))
  1712. self.assertFalse(os.path.exists(
  1713. os.path.join(self.path, 'repos', 'docs', 'project#1.git')))
  1714. self.assertFalse(os.path.exists(
  1715. os.path.join(self.path, 'repos', 'requests', 'project#1.git')))
  1716. user = tests.FakeUser(username='foo')
  1717. with tests.user_set(self.app.application, user):
  1718. csrf_token = self.get_csrf()
  1719. data = {
  1720. 'description': 'Project #1',
  1721. 'name': 'project-1',
  1722. 'csrf_token': csrf_token,
  1723. }
  1724. output = self.app.post('/new/', data=data, follow_redirects=True)
  1725. self.assertEqual(output.status_code, 200)
  1726. output_text = output.get_data(as_text=True)
  1727. self.assertIn(
  1728. '<div class="projectinfo my-3">\nProject #1',
  1729. output_text)
  1730. self.assertIn('<p>This repo is brand new!</p>',
  1731. output_text)
  1732. self.assertIn(
  1733. '<title>Overview - project-1 - Pagure</title>', output_text)
  1734. # After
  1735. projects = pagure.lib.search_projects(self.session)
  1736. self.assertEqual(len(projects), 1)
  1737. self.assertTrue(os.path.exists(
  1738. os.path.join(self.path, 'repos', 'project-1.git')))
  1739. self.assertTrue(os.path.exists(
  1740. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  1741. self.assertFalse(os.path.exists(
  1742. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  1743. self.assertTrue(os.path.exists(
  1744. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  1745. class PagureFlaskAppNoTicketstests(tests.Modeltests):
  1746. """ Tests for flask app controller of pagure """
  1747. config_values = {
  1748. "enable_tickets": False,
  1749. "tickets_folder": None,
  1750. }
  1751. def test_new_project_no_tickets_folder(self):
  1752. """ Test the new_project endpoint with TICKETS_FOLDER is None. """
  1753. # Before
  1754. projects = pagure.lib.search_projects(self.session)
  1755. self.assertEqual(len(projects), 0)
  1756. self.assertFalse(os.path.exists(
  1757. os.path.join(self.path, 'repos', 'project#1.git')))
  1758. self.assertFalse(os.path.exists(
  1759. os.path.join(self.path, 'repos', 'tickets', 'project#1.git')))
  1760. self.assertFalse(os.path.exists(
  1761. os.path.join(self.path, 'repos', 'docs', 'project#1.git')))
  1762. self.assertFalse(os.path.exists(
  1763. os.path.join(self.path, 'repos', 'requests', 'project#1.git')))
  1764. user = tests.FakeUser(username='foo')
  1765. with tests.user_set(self.app.application, user):
  1766. csrf_token = self.get_csrf()
  1767. data = {
  1768. 'description': 'Project #1',
  1769. 'name': 'project-1',
  1770. 'csrf_token': csrf_token,
  1771. }
  1772. output = self.app.post('/new/', data=data, follow_redirects=True)
  1773. self.assertEqual(output.status_code, 200)
  1774. output_text = output.get_data(as_text=True)
  1775. self.assertIn(
  1776. '<div class="projectinfo my-3">\nProject #1',
  1777. output_text)
  1778. self.assertIn('<p>This repo is brand new!</p>',
  1779. output_text)
  1780. self.assertIn(
  1781. '<title>Overview - project-1 - Pagure</title>', output_text)
  1782. # After
  1783. projects = pagure.lib.search_projects(self.session)
  1784. self.assertEqual(len(projects), 1)
  1785. self.assertTrue(os.path.exists(
  1786. os.path.join(self.path, 'repos', 'project-1.git')))
  1787. self.assertFalse(os.path.exists(
  1788. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  1789. self.assertTrue(os.path.exists(
  1790. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  1791. self.assertTrue(os.path.exists(
  1792. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  1793. if __name__ == '__main__':
  1794. unittest.main(verbosity=2)