test_pagure_flask_ui_app.py 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224
  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.query
  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>', 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.query.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.query.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_mirrored_invalid_url(self):
  243. """ Test the new_project with a mirrored repo but an invalid URL. """
  244. user = tests.FakeUser(username='foo')
  245. with tests.user_set(self.app.application, user):
  246. output = self.app.get('/new/')
  247. self.assertEqual(output.status_code, 200)
  248. csrf_token = self.get_csrf(output=output)
  249. data = {
  250. 'description': 'Project #1',
  251. 'name': 'project-1',
  252. 'mirrored_from': 'abcd',
  253. 'csrf_token': csrf_token,
  254. }
  255. output = self.app.post('/new/', data=data, follow_redirects=True)
  256. self.assertEqual(output.status_code, 200)
  257. output_text = output.get_data(as_text=True)
  258. self.assertIn(
  259. '<title>New project - Pagure</title>', output_text)
  260. self.assertIn(
  261. 'Invalid input.&nbsp;', output_text)
  262. def test_new_project_mirrored_invalid_sshurl(self):
  263. """ Test the new_project with a mirrored repo but an invalid
  264. SSH-like url.
  265. """
  266. user = tests.FakeUser(username='foo')
  267. with tests.user_set(self.app.application, user):
  268. output = self.app.get('/new/')
  269. self.assertEqual(output.status_code, 200)
  270. csrf_token = self.get_csrf(output=output)
  271. data = {
  272. 'description': 'Project #1',
  273. 'name': 'project-1',
  274. 'mirrored_from': 'ssh://git@server.org/foo/bar.git',
  275. 'csrf_token': csrf_token,
  276. }
  277. output = self.app.post('/new/', data=data, follow_redirects=True)
  278. self.assertEqual(output.status_code, 200)
  279. output_text = output.get_data(as_text=True)
  280. self.assertIn(
  281. '<title>New project - Pagure</title>', output_text)
  282. self.assertIn(
  283. 'Invalid input.&nbsp;', output_text)
  284. def test_new_project_mirrored_valid_url(self):
  285. """ Test the new_project with a mirrored repo with a valid url. """
  286. user = tests.FakeUser(username='foo')
  287. with tests.user_set(self.app.application, user):
  288. output = self.app.get('/new/')
  289. self.assertEqual(output.status_code, 200)
  290. csrf_token = self.get_csrf(output=output)
  291. data = {
  292. 'description': 'Project #1',
  293. 'name': 'project-1',
  294. 'mirrored_from': 'https://example.com/foo/bar.git',
  295. 'csrf_token': csrf_token,
  296. }
  297. output = self.app.post('/new/', data=data, follow_redirects=True)
  298. self.assertEqual(output.status_code, 200)
  299. output_text = output.get_data(as_text=True)
  300. self.assertIn(
  301. '<title>Overview - project-1 - Pagure</title>',
  302. output_text)
  303. self.assertIn(
  304. '<p>This repo is brand new and meant to be mirrored from '
  305. 'https://example.com/foo/bar.git !</p>', output_text)
  306. def test_new_project(self):
  307. """ Test the new_project endpoint. """
  308. # Before
  309. projects = pagure.lib.query.search_projects(self.session)
  310. self.assertEqual(len(projects), 0)
  311. self.assertFalse(os.path.exists(
  312. os.path.join(self.path, 'repos', 'project#1.git')))
  313. self.assertFalse(os.path.exists(
  314. os.path.join(self.path, 'repos', 'tickets', 'project#1.git')))
  315. self.assertFalse(os.path.exists(
  316. os.path.join(self.path, 'repos', 'docs', 'project#1.git')))
  317. self.assertFalse(os.path.exists(
  318. os.path.join(self.path, 'repos', 'requests', 'project#1.git')))
  319. user = tests.FakeUser()
  320. with tests.user_set(self.app.application, user):
  321. output = self.app.get('/new/')
  322. self.assertEqual(output.status_code, 200)
  323. output_text = output.get_data(as_text=True)
  324. self.assertIn(
  325. '<strong>Create new Project</strong>', output_text)
  326. csrf_token = output_text.split(
  327. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  328. data = {
  329. 'description': 'Project #1',
  330. }
  331. output = self.app.post('/new/', data=data)
  332. self.assertEqual(output.status_code, 200)
  333. output_text = output.get_data(as_text=True)
  334. self.assertIn(
  335. '<strong>Create new Project</strong>', output_text)
  336. self.assertIn(
  337. '<small>\n This field is required.&nbsp;\n'
  338. ' </small>', output_text)
  339. data['name'] = 'project-1'
  340. output = self.app.post('/new/', data=data)
  341. self.assertEqual(output.status_code, 200)
  342. output_text = output.get_data(as_text=True)
  343. self.assertIn('<strong>Create new Project</strong>', output_text)
  344. self.assertNotIn(
  345. '<small>\n This field is required.&nbsp;\n'
  346. ' </small>', output_text)
  347. data['csrf_token'] = csrf_token
  348. output = self.app.post('/new/', data=data)
  349. self.assertEqual(output.status_code, 200)
  350. output_text = output.get_data(as_text=True)
  351. self.assertIn('<strong>Create new Project</strong>', output_text)
  352. self.assertIn(
  353. 'No user '
  354. '&#34;username&#34; found',
  355. output_text)
  356. user.username = 'foo'
  357. with tests.user_set(self.app.application, user):
  358. data['csrf_token'] = csrf_token
  359. output = self.app.post('/new/', data=data, follow_redirects=True)
  360. self.assertEqual(output.status_code, 200)
  361. output_text = output.get_data(as_text=True)
  362. self.assertIn(
  363. '<div class="projectinfo my-3">\nProject #1',
  364. output_text)
  365. self.assertIn('<p>This repo is brand new!</p>',
  366. output_text)
  367. self.assertIn(
  368. '<title>Overview - project-1 - Pagure</title>', output_text)
  369. # After
  370. projects = pagure.lib.query.search_projects(self.session)
  371. self.assertEqual(len(projects), 1)
  372. self.assertTrue(os.path.exists(
  373. os.path.join(self.path, 'repos', 'project-1.git')))
  374. self.assertTrue(os.path.exists(
  375. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  376. self.assertTrue(os.path.exists(
  377. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  378. self.assertTrue(os.path.exists(
  379. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  380. @patch.dict('pagure.config.config', {'PAGURE_ADMIN_USERS': ['pingou'],
  381. 'ALLOW_ADMIN_IGNORE_EXISTING_REPOS': True})
  382. def test_adopt_repos(self):
  383. """ Test the new_project endpoint with existing git repo. """
  384. # Before
  385. projects = pagure.lib.query.search_projects(self.session)
  386. self.assertEqual(len(projects), 0)
  387. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  388. tests.add_content_git_repo(os.path.join(self.path, 'repos', 'test.git'))
  389. user = tests.FakeUser(username='pingou')
  390. with tests.user_set(self.app.application, user):
  391. data = {
  392. 'csrf_token': self.get_csrf(),
  393. 'name': 'test',
  394. 'description': 'Project #1',
  395. }
  396. output = self.app.post('/new/', data=data, follow_redirects=True)
  397. self.assertEqual(output.status_code, 200)
  398. output_text = output.get_data(as_text=True)
  399. self.assertIn('The main repo test.git already exists', output_text)
  400. data['ignore_existing_repos'] = 'y'
  401. output = self.app.post('/new/', data=data, follow_redirects=True)
  402. self.assertEqual(output.status_code, 200)
  403. output_text = output.get_data(as_text=True)
  404. self.assertIn("Alice Author", output_text)
  405. @patch.dict('pagure.config.config', {'PAGURE_ADMIN_USERS': [],
  406. 'USERS_IGNORE_EXISTING_REPOS': ['pingou']})
  407. def test_adopt_repos_non_admin(self):
  408. """ Test the new_project endpoint with existing git repo for non-admins. """
  409. # Before
  410. projects = pagure.lib.query.search_projects(self.session)
  411. self.assertEqual(len(projects), 0)
  412. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  413. tests.add_content_git_repo(os.path.join(self.path, 'repos', 'test.git'))
  414. user = tests.FakeUser(username='pingou')
  415. with tests.user_set(self.app.application, user):
  416. data = {
  417. 'csrf_token': self.get_csrf(),
  418. 'name': 'test',
  419. 'description': 'Project #1',
  420. }
  421. output = self.app.post('/new/', data=data, follow_redirects=True)
  422. self.assertEqual(output.status_code, 200)
  423. output_text = output.get_data(as_text=True)
  424. self.assertIn('The main repo test.git already exists', output_text)
  425. data['ignore_existing_repos'] = 'y'
  426. output = self.app.post('/new/', data=data, follow_redirects=True)
  427. self.assertEqual(output.status_code, 200)
  428. output_text = output.get_data(as_text=True)
  429. self.assertIn("Alice Author", output_text)
  430. @patch.dict('pagure.config.config', {'PAGURE_ADMIN_USERS': [],
  431. 'USERS_IGNORE_EXISTING_REPOS': []})
  432. def test_adopt_repos_not_allowed(self):
  433. """ Test the new_project endpoint with existing git repo for no access. """
  434. # Before
  435. projects = pagure.lib.query.search_projects(self.session)
  436. self.assertEqual(len(projects), 0)
  437. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  438. tests.add_content_git_repo(os.path.join(self.path, 'repos', 'test.git'))
  439. user = tests.FakeUser(username='pingou')
  440. with tests.user_set(self.app.application, user):
  441. data = {
  442. 'csrf_token': self.get_csrf(),
  443. 'name': 'test',
  444. 'description': 'Project #1',
  445. }
  446. output = self.app.post('/new/', data=data, follow_redirects=True)
  447. self.assertEqual(output.status_code, 200)
  448. output_text = output.get_data(as_text=True)
  449. self.assertIn('The main repo test.git already exists', output_text)
  450. data['ignore_existing_repos'] = 'y'
  451. output = self.app.post('/new/', data=data, follow_redirects=True)
  452. self.assertEqual(output.status_code, 200)
  453. output_text = output.get_data(as_text=True)
  454. self.assertIn('The main repo test.git already exists', output_text)
  455. @patch.dict('pagure.config.config', {'PROJECT_NAME_REGEX': '^1[a-z]*$'})
  456. def test_new_project_diff_regex(self):
  457. """ Test the new_project endpoint with a different regex. """
  458. # Before
  459. projects = pagure.lib.query.search_projects(self.session)
  460. self.assertEqual(len(projects), 0)
  461. user = tests.FakeUser(username='foo')
  462. with tests.user_set(self.app.application, user):
  463. output = self.app.get('/new/')
  464. self.assertEqual(output.status_code, 200)
  465. output_text = output.get_data(as_text=True)
  466. self.assertIn(
  467. '<strong>Create new Project</strong>', output_text)
  468. csrf_token = self.get_csrf(output=output)
  469. data = {
  470. 'description': 'Project #1',
  471. 'name': 'project-1',
  472. 'csrf_token': csrf_token,
  473. }
  474. output = self.app.post('/new/', data=data, follow_redirects=True)
  475. self.assertEqual(output.status_code, 200)
  476. output_text = output.get_data(as_text=True)
  477. self.assertIn(
  478. '<title>New project - Pagure</title>', output_text)
  479. self.assertIn(
  480. '<strong>Create new Project</strong>', output_text)
  481. self.assertIn(
  482. '<small>\n Invalid input.&nbsp;\n'
  483. ' </small>', output_text)
  484. @patch.dict('pagure.config.config', {'PRIVATE_PROJECTS': True})
  485. def test_new_project_private(self):
  486. """ Test the new_project endpoint for a private project. """
  487. # Before
  488. projects = pagure.lib.query.search_projects(self.session)
  489. self.assertEqual(len(projects), 0)
  490. self.assertFalse(os.path.exists(
  491. os.path.join(self.path, 'repos', 'foo', 'project#1.git')))
  492. self.assertFalse(os.path.exists(
  493. os.path.join(self.path, 'repos', 'tickets', 'foo', 'project#1.git')))
  494. self.assertFalse(os.path.exists(
  495. os.path.join(self.path, 'repos', 'docs', 'foo', 'project#1.git')))
  496. self.assertFalse(os.path.exists(
  497. os.path.join(self.path, 'repos', 'requests', 'foo', 'project#1.git')))
  498. user = tests.FakeUser()
  499. with tests.user_set(self.app.application, user):
  500. output = self.app.get('/new/')
  501. self.assertEqual(output.status_code, 200)
  502. self.assertIn(
  503. '<strong>Create new Project</strong>', output.get_data(as_text=True))
  504. csrf_token = self.get_csrf(output=output)
  505. data = {
  506. 'description': 'Project #1',
  507. 'private': True,
  508. }
  509. output = self.app.post('/new/', data=data)
  510. self.assertEqual(output.status_code, 200)
  511. output_text = output.get_data(as_text=True)
  512. self.assertIn(
  513. '<strong>Create new Project</strong>', output_text)
  514. self.assertIn(
  515. '<small>\n This field is required.&nbsp;\n'
  516. ' </small>', output_text)
  517. data['name'] = 'project-1'
  518. output = self.app.post('/new/', data=data)
  519. self.assertEqual(output.status_code, 200)
  520. output_text = output.get_data(as_text=True)
  521. self.assertIn('<strong>Create new Project</strong>', output_text)
  522. self.assertNotIn(
  523. '<small>\n This field is required.&nbsp;\n'
  524. ' </small>', output_text)
  525. data['csrf_token'] = csrf_token
  526. output = self.app.post('/new/', data=data)
  527. self.assertEqual(output.status_code, 200)
  528. output_text = output.get_data(as_text=True)
  529. self.assertIn('<strong>Create new Project</strong>', output_text)
  530. self.assertIn(
  531. 'No user '
  532. '&#34;username&#34; found',
  533. output_text)
  534. user.username = 'foo'
  535. with tests.user_set(self.app.application, user):
  536. data['csrf_token'] = csrf_token
  537. output = self.app.post('/new/', data=data, follow_redirects=True)
  538. self.assertEqual(output.status_code, 200)
  539. output_text = output.get_data(as_text=True)
  540. self.assertIn(
  541. '<div class="projectinfo my-3">\nProject #1',
  542. output_text)
  543. self.assertIn('<p>This repo is brand new!</p>',
  544. output_text)
  545. self.assertIn(
  546. '<title>Overview - foo/project-1 - Pagure</title>', output_text)
  547. # After
  548. projects = pagure.lib.query.search_projects(self.session)
  549. self.assertEqual(len(projects), 0)
  550. projects = pagure.lib.query.search_projects(self.session, private=True)
  551. self.assertEqual(len(projects), 1)
  552. self.assertTrue(os.path.exists(
  553. os.path.join(self.path, 'repos', 'foo', 'project-1.git')))
  554. self.assertTrue(os.path.exists(
  555. os.path.join(self.path, 'repos', 'tickets', 'foo', 'project-1.git')))
  556. self.assertTrue(os.path.exists(
  557. os.path.join(self.path, 'repos', 'docs', 'foo', 'project-1.git')))
  558. self.assertTrue(os.path.exists(
  559. os.path.join(self.path, 'repos', 'requests', 'foo', 'project-1.git')))
  560. def test_non_ascii_new_project(self):
  561. """ Test the new_project endpoint with a non-ascii project. """
  562. # Before
  563. projects = pagure.lib.query.search_projects(self.session)
  564. self.assertEqual(len(projects), 0)
  565. self.assertFalse(os.path.exists(
  566. os.path.join(self.path, 'repos', 'project-1.git')))
  567. self.assertFalse(os.path.exists(
  568. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  569. self.assertFalse(os.path.exists(
  570. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  571. self.assertFalse(os.path.exists(
  572. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  573. user = tests.FakeUser()
  574. user.username = 'foo'
  575. with tests.user_set(self.app.application, user):
  576. output = self.app.get('/new/')
  577. self.assertEqual(output.status_code, 200)
  578. output_text = output.get_data(as_text=True)
  579. self.assertIn(
  580. '<strong>Create new Project</strong>', output_text)
  581. csrf_token = output_text.split(
  582. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  583. data = {
  584. 'description': 'Prõjéctö #1',
  585. 'name': 'project-1',
  586. 'csrf_token': csrf_token,
  587. 'create_readme': True,
  588. }
  589. output = self.app.post('/new/', data=data, follow_redirects=True)
  590. self.assertEqual(output.status_code, 200)
  591. output_text = output.get_data(as_text=True)
  592. self.assertIn(
  593. '<div class="projectinfo my-3">\nPrõjéctö #1',
  594. output_text)
  595. self.assertIn(
  596. '''<section class="readme">
  597. <h1>project-1</h1>
  598. <p>Prõjéctö #1</p>
  599. </section>''',
  600. output_text)
  601. data = {
  602. 'description': 'Мой первый суперский репозиторий',
  603. 'name': 'project-2',
  604. 'csrf_token': csrf_token,
  605. 'create_readme': True,
  606. }
  607. output = self.app.post('/new/', data=data, follow_redirects=True)
  608. self.assertEqual(output.status_code, 200)
  609. output_text = output.get_data(as_text=True)
  610. self.assertIn(
  611. '<div class="projectinfo my-3">\nМой первый суперский репозиторий',
  612. output_text)
  613. self.assertIn(
  614. '''<section class="readme">
  615. <h1>project-2</h1>
  616. <p>Мой первый суперский репозиторий</p>
  617. </section>''',
  618. output_text)
  619. # After
  620. projects = pagure.lib.query.search_projects(self.session)
  621. self.assertEqual(len(projects), 2)
  622. for project in ['project-1', 'project-2']:
  623. self.assertTrue(os.path.exists(
  624. os.path.join(self.path, 'repos', '%s.git' % project)))
  625. self.assertTrue(os.path.exists(
  626. os.path.join(self.path, 'repos', 'tickets', '%s.git' % project)))
  627. self.assertTrue(os.path.exists(
  628. os.path.join(self.path, 'repos', 'docs', '%s.git' % project)))
  629. self.assertTrue(os.path.exists(
  630. os.path.join(self.path, 'repos', 'requests', '%s.git' % project)))
  631. @patch('pygit2.init_repository', wraps=pygit2.init_repository)
  632. def test_new_project_with_template(self, pygit2init):
  633. """ Test the new_project endpoint for a new project with a template set.
  634. """
  635. # Before
  636. projects = pagure.lib.query.search_projects(self.session)
  637. self.assertEqual(len(projects), 0)
  638. self.assertFalse(os.path.exists(
  639. os.path.join(self.path, 'repos', 'project-1.git')))
  640. self.assertFalse(os.path.exists(
  641. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  642. self.assertFalse(os.path.exists(
  643. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  644. self.assertFalse(os.path.exists(
  645. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  646. user = tests.FakeUser()
  647. user.username = 'foo'
  648. with tests.user_set(self.app.application, user):
  649. output = self.app.get('/new/')
  650. self.assertEqual(output.status_code, 200)
  651. self.assertIn(
  652. '<strong>Create new Project</strong>', output.get_data(as_text=True))
  653. csrf_token = self.get_csrf(output=output)
  654. data = {
  655. 'description': 'test',
  656. 'name': 'project-1',
  657. 'csrf_token': csrf_token,
  658. 'create_readme': True,
  659. }
  660. output = self.app.post('/new/', data=data, follow_redirects=True)
  661. self.assertEqual(output.status_code, 200)
  662. self.assertIn(
  663. '<div class="projectinfo my-3">\ntest',
  664. output.get_data(as_text=True))
  665. self.assertEqual(pygit2init.call_count, 4)
  666. pygit2init.assert_any_call(
  667. '%s/repos/project-1.git' % self.path,
  668. bare=True, template_path=None)
  669. path = os.path.join(self.path, 'repos', 'project-1.git')
  670. with patch.dict(
  671. 'pagure.config.config',
  672. {'PROJECT_TEMPLATE_PATH': path}):
  673. data = {
  674. 'description': 'test2',
  675. 'name': 'project-2',
  676. 'csrf_token': csrf_token,
  677. 'create_readme': True,
  678. }
  679. output = self.app.post('/new/', data=data, follow_redirects=True)
  680. self.assertEqual(output.status_code, 200)
  681. self.assertIn(
  682. '<div class="projectinfo my-3">\ntest2',
  683. output.get_data(as_text=True))
  684. self.assertEqual(pygit2init.call_count, 8)
  685. pygit2init.assert_any_call(
  686. '%s/repos/project-2.git' % self.path,
  687. bare=True,
  688. template_path='%s/repos/project-1.git' % self.path)
  689. # After
  690. projects = pagure.lib.query.search_projects(self.session)
  691. self.assertEqual(len(projects), 2)
  692. for project in ['project-1', 'project-2']:
  693. self.assertTrue(os.path.exists(
  694. os.path.join(self.path, 'repos', '%s.git' % project)))
  695. self.assertTrue(os.path.exists(
  696. os.path.join(self.path, 'repos', 'tickets', '%s.git' % project)))
  697. self.assertTrue(os.path.exists(
  698. os.path.join(self.path, 'repos', 'docs', '%s.git' % project)))
  699. self.assertTrue(os.path.exists(
  700. os.path.join(self.path, 'repos', 'requests', '%s.git' % project)))
  701. @patch.dict('pagure.config.config', {'CASE_SENSITIVE': True})
  702. def test_new_project_case_sensitive(self):
  703. tests.create_projects(self.session)
  704. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  705. output = self.app.get('/test')
  706. self.assertEqual(output.status_code, 200)
  707. output = self.app.get('/TEST')
  708. self.assertEqual(output.status_code, 404)
  709. user = tests.FakeUser()
  710. user.username = 'foo'
  711. with tests.user_set(self.app.application, user):
  712. output = self.app.get('/new/')
  713. self.assertEqual(output.status_code, 200)
  714. csrf_token = self.get_csrf(output=output)
  715. data = {
  716. 'description': 'TEST',
  717. 'name': 'TEST',
  718. 'csrf_token': csrf_token,
  719. 'create_readme': True,
  720. }
  721. self.app.post('/new/', data=data, follow_redirects=True)
  722. output = self.app.get('/TEST')
  723. self.assertEqual(output.status_code, 200)
  724. @patch('pagure.ui.app.admin_session_timedout')
  725. def test_user_settings(self, ast):
  726. """ Test the user_settings endpoint. """
  727. ast.return_value = False
  728. self.test_new_project()
  729. user = tests.FakeUser()
  730. with tests.user_set(self.app.application, user):
  731. output = self.app.get('/settings/')
  732. self.assertEqual(output.status_code, 404)
  733. self.assertIn('<h2>Page not found (404)</h2>', output.get_data(as_text=True))
  734. user.username = 'foo'
  735. with tests.user_set(self.app.application, user):
  736. output = self.app.get('/settings/')
  737. self.assertEqual(output.status_code, 200)
  738. output_text = output.get_data(as_text=True)
  739. self.assertIn(
  740. '<title>foo\'s settings - Pagure</title>', output_text)
  741. ast.return_value = True
  742. output = self.app.get('/settings/')
  743. self.assertEqual(output.status_code, 302)
  744. @patch('pagure.decorators.admin_session_timedout')
  745. def test_add_user_sshkey(self, ast):
  746. """ Test the add_user_sshkey endpoint. """
  747. ast.return_value = False
  748. # User not logged in
  749. output = self.app.get('/settings/')
  750. self.assertEqual(output.status_code, 302)
  751. ast.return_value = False
  752. user = tests.FakeUser(username='pingou')
  753. with tests.user_set(self.app.application, user):
  754. output = self.app.get('/settings', follow_redirects=True)
  755. self.assertEqual(output.status_code, 200)
  756. output_text = output.get_data(as_text=True)
  757. self.assertIn('<strong>Add SSH key', output_text)
  758. csrf_token = self.get_csrf(output=output)
  759. data = {
  760. 'ssh_key': 'asdf',
  761. }
  762. # No CSRF token
  763. output = self.app.post(
  764. '/settings/usersettings/addkey', data=data , follow_redirects=True)
  765. self.assertEqual(output.status_code, 200)
  766. output_text = output.get_data(as_text=True)
  767. self.assertIn('<strong>Add SSH key', output_text)
  768. data['csrf_token'] = csrf_token
  769. # First, invalid SSH key
  770. output = self.app.post(
  771. '/settings/usersettings/addkey', data=data, follow_redirects=True)
  772. self.assertEqual(output.status_code, 200)
  773. output_text = output.get_data(as_text=True)
  774. self.assertIn('<strong>Add SSH key', output_text)
  775. self.assertIn('SSH key invalid', output_text)
  776. # Next up, multiple SSH keys
  777. data['ssh_key'] = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q=='
  778. output = self.app.post(
  779. '/settings/usersettings/addkey', data=data, follow_redirects=True)
  780. self.assertEqual(output.status_code, 200)
  781. output_text = output.get_data(as_text=True)
  782. self.assertIn('Please add single SSH keys.', output_text)
  783. # Now, a valid SSH key
  784. data['ssh_key'] = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q=='
  785. output = self.app.post(
  786. '/settings/usersettings/addkey', data=data, follow_redirects=True)
  787. self.assertEqual(output.status_code, 200)
  788. output_text = output.get_data(as_text=True)
  789. self.assertIn(
  790. "<title>pingou's settings - Pagure</title>", output_text)
  791. self.assertIn('SSH key added', output_text)
  792. self.assertNotIn('Push Access', output_text)
  793. # And now, adding the same key
  794. output = self.app.post(
  795. '/settings/usersettings/addkey', data=data, follow_redirects=True)
  796. self.assertEqual(output.status_code, 200)
  797. output_text = output.get_data(as_text=True)
  798. self.assertIn('SSH key already exists', output_text)
  799. # And next, a key with push access
  800. data['ssh_key'] = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9Xwc2RDzPBhlEDARfHldGjudIVoa04tqT1JVKGQmyllTFz7Rb8CngQL3e7zyNzotnhwYKHdoiLlPkVEiDee4dWMUe48ilqId+FJZQGhyv8fu4BoFdE1AJUVylzmltbLg14VqG5gjTpXgtlrEva9arKwBMHJjRYc8ScaSn3OgyQw=='
  801. output = self.app.post(
  802. '/settings/usersettings/addkey', data=data, follow_redirects=True)
  803. self.assertEqual(output.status_code, 200)
  804. output_text = output.get_data(as_text=True)
  805. self.assertIn(
  806. "<title>pingou's settings - Pagure</title>", output_text)
  807. self.assertIn('SSH key added', output_text)
  808. @patch('pagure.decorators.admin_session_timedout')
  809. def test_remove_user_sshkey(self, ast):
  810. """ Test the remove_sshkey endpoint. """
  811. ast.return_value = False
  812. user = tests.FakeUser()
  813. # User not logged in
  814. output = self.app.post('/settings/usersettings/removekey/1')
  815. self.assertEqual(output.status_code, 302)
  816. user.username = 'pingou'
  817. with tests.user_set(self.app.application, user):
  818. data = {'csrf_token': self.get_csrf()}
  819. output = self.app.post(
  820. '/settings/usersettings/removekey/1', data=data, follow_redirects=True)
  821. self.assertEqual(output.status_code, 200)
  822. output_text = output.get_data(as_text=True)
  823. self.assertIn(
  824. "<title>pingou's settings - Pagure</title>", output_text)
  825. self.assertIn('SSH key does not exist', output_text)
  826. # Add a deploy key to a project
  827. pingou = pagure.lib.query.get_user(self.session, 'pingou')
  828. msg = pagure.lib.query.add_sshkey_to_project_or_user(
  829. session=self.session,
  830. ssh_key='ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAzBMSIlvPRaEiLOTVInErkRIw9CzQQcnslDekAn1jFnGf+SNa1acvbTiATbCX71AA03giKrPxPH79dxcC7aDXerc6zRcKjJs6MAL9PrCjnbyxCKXRNNZU5U9X/DLaaL1b3caB+WD6OoorhS3LTEtKPX8xyjOzhf3OQSzNjhJp5Q==',
  831. user=pingou,
  832. pushaccess=True,
  833. creator=pingou,
  834. )
  835. self.session.commit()
  836. self.assertEqual(msg, 'SSH key added')
  837. with tests.user_set(self.app.application, user):
  838. output = self.app.post('/settings/usersettings/removekey/1', follow_redirects=True)
  839. self.assertEqual(output.status_code, 200)
  840. output_text = output.get_data(as_text=True)
  841. self.assertIn(
  842. "<title>pingou's settings - Pagure</title>", output_text)
  843. self.assertNotIn('SSH key removed', output_text)
  844. data = {'csrf_token': self.get_csrf()}
  845. output = self.app.post(
  846. '/settings/usersettings/removekey/1', data=data, follow_redirects=True)
  847. self.assertEqual(output.status_code, 200)
  848. output_text = output.get_data(as_text=True)
  849. self.assertIn(
  850. "<title>pingou's settings - Pagure</title>", output_text)
  851. self.assertIn('SSH key removed', output_text)
  852. def patched_commit_exists(user, namespace, repo, githash):
  853. ''' Patched version of pagure.pfmarkdown._commit_exists to enforce
  854. returning true on some given hash without having us actually check
  855. the git repos.
  856. '''
  857. if githash in ['9364354', '9364354a', '9364354a4555ba17aa60f0dc844d70b74eb1aecd']:
  858. return True
  859. else:
  860. return False
  861. @patch(
  862. 'pagure.pfmarkdown._commit_exists',
  863. MagicMock(side_effect=patched_commit_exists))
  864. def test_patched_markdown_preview(self):
  865. """ Test the markdown_preview endpoint. """
  866. data = {
  867. 'content': 'test\n----\n\n * 1\n * item 2'
  868. }
  869. # CSRF missing
  870. output = self.app.post('/markdown/', data=data)
  871. self.assertEqual(output.status_code, 400)
  872. user = tests.FakeUser()
  873. user.username = 'foo'
  874. with tests.user_set(self.app.application, user):
  875. output = self.app.get('/settings/')
  876. self.assertEqual(output.status_code, 200)
  877. output_text = output.get_data(as_text=True)
  878. self.assertIn(
  879. '<title>foo\'s settings - Pagure</title>', output_text)
  880. csrf_token = self.get_csrf(output=output)
  881. # With CSRF
  882. data['csrf_token'] = csrf_token
  883. output = self.app.post('/markdown/', data=data)
  884. self.assertEqual(output.status_code, 200)
  885. exp = """<h2>test</h2>
  886. <ul>
  887. <li>1</li>
  888. <li>item 2</li>
  889. </ul>"""
  890. self.assertEqual(output.get_data(as_text=True), exp)
  891. tests.create_projects(self.session)
  892. texts = [
  893. 'pingou committed on test#9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  894. 'Cf commit 936435', # 6 chars - not long enough
  895. 'Cf commit 9364354', # 7 chars - long enough
  896. 'Cf commit 9364354a', # 8 chars - still long enough
  897. 'Cf commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd', # 40 chars
  898. ]
  899. expected = [
  900. # 'pingou committed on test#9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  901. '<p>pingou committed on <a href="/test/c/9364354a4555ba17aa60f0dc844d70b74eb1aecd" '
  902. 'title="Commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd"'
  903. '>test#9364354a4555ba17aa60f0dc844d70b74eb1aecd</a></p>',
  904. # 'Cf commit 936435',
  905. '<p>Cf commit 936435</p>',
  906. # 'Cf commit 9364354',
  907. #'<p>Cf commit 9364354</p>',
  908. '<p>Cf commit <a href="/test/c/9364354" '
  909. 'title="Commit 9364354">9364354</a></p>',
  910. # 'Cf commit 9364354a',
  911. '<p>Cf commit <a href="/test/c/9364354a" '
  912. 'title="Commit 9364354a">9364354</a></p>',
  913. # 'Cf commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd',
  914. '<p>Cf commit <a href="/test/c/9364354a4555ba17aa60f0dc844d70b74eb1aecd" '
  915. 'title="Commit 9364354a4555ba17aa60f0dc844d70b74eb1aecd"'
  916. '>9364354</a></p>',
  917. ]
  918. with self.app.application.app_context():
  919. for idx, text in enumerate(texts):
  920. data = {
  921. 'content': text,
  922. 'csrf_token': csrf_token,
  923. }
  924. output = self.app.post('/markdown/?repo=test', data=data)
  925. self.assertEqual(output.status_code, 200)
  926. self.assertEqual(expected[idx], output.get_data(as_text=True))
  927. def test_markdown_preview(self):
  928. """ Test the markdown_preview endpoint with a non-existing commit.
  929. """
  930. user = tests.FakeUser()
  931. user.username = 'foo'
  932. with tests.user_set(self.app.application, user):
  933. output = self.app.get('/settings/')
  934. self.assertEqual(output.status_code, 200)
  935. output_text = output.get_data(as_text=True)
  936. self.assertIn(
  937. '<title>foo\'s settings - Pagure</title>', output_text)
  938. csrf_token = self.get_csrf(output=output)
  939. tests.create_projects(self.session)
  940. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  941. text = 'Cf commit 9364354a4555ba17aa60f0d'
  942. exp = '<p>Cf commit 9364354a4555ba17aa60f0d</p>'
  943. with self.app.application.app_context():
  944. data = {
  945. 'content': text,
  946. 'csrf_token': csrf_token,
  947. }
  948. output = self.app.post('/markdown/?repo=test', data=data)
  949. self.assertEqual(output.status_code, 200)
  950. self.assertEqual(exp, output.get_data(as_text=True))
  951. def test_markdown_preview_valid_commit(self):
  952. """ Test the markdown_preview endpoint with an existing commit. """
  953. user = tests.FakeUser()
  954. user.username = 'foo'
  955. with tests.user_set(self.app.application, user):
  956. output = self.app.get('/settings/')
  957. self.assertEqual(output.status_code, 200)
  958. output_text = output.get_data(as_text=True)
  959. self.assertIn(
  960. '<title>foo\'s settings - Pagure</title>', output_text)
  961. csrf_token = self.get_csrf(output=output)
  962. tests.create_projects(self.session)
  963. tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True)
  964. repopath = os.path.join(self.path, 'repos', 'test.git')
  965. tests.add_content_git_repo(repopath)
  966. repo = pygit2.Repository(repopath)
  967. first_commit = repo.revparse_single('HEAD')
  968. text = 'Cf commit %s' % first_commit.oid.hex
  969. exp = '<p>Cf commit <a href="/test/c/{0}" title="Commit {0}">{1}'\
  970. '</a></p>'.format(first_commit.oid.hex, first_commit.oid.hex[:7])
  971. with self.app.application.app_context():
  972. data = {
  973. 'content': text,
  974. 'csrf_token': csrf_token,
  975. }
  976. output = self.app.post('/markdown/?repo=test', data=data)
  977. self.assertEqual(output.status_code, 200)
  978. self.assertEqual(exp, output.get_data(as_text=True))
  979. @patch('pagure.ui.app.admin_session_timedout')
  980. def test_remove_user_email(self, ast):
  981. """ Test the remove_user_email endpoint. """
  982. ast.return_value = False
  983. self.test_new_project()
  984. user = tests.FakeUser()
  985. with tests.user_set(self.app.application, user):
  986. output = self.app.post('/settings/email/drop')
  987. self.assertEqual(output.status_code, 404)
  988. self.assertIn('<h2>Page not found (404)</h2>', output.get_data(as_text=True))
  989. user.username = 'foo'
  990. with tests.user_set(self.app.application, user):
  991. output = self.app.get('/settings/')
  992. self.assertEqual(output.status_code, 200)
  993. output_text = output.get_data(as_text=True)
  994. self.assertIn(
  995. '<title>foo\'s settings - Pagure</title>', output_text)
  996. csrf_token = self.get_csrf(output=output)
  997. data = {
  998. 'email': 'foo@pingou.com',
  999. }
  1000. output = self.app.post(
  1001. '/settings/email/drop', data=data, follow_redirects=True)
  1002. self.assertEqual(output.status_code, 200)
  1003. output_text = output.get_data(as_text=True)
  1004. self.assertIn(
  1005. '<title>foo\'s settings - Pagure</title>', output_text)
  1006. self.assertIn(
  1007. 'You must always have at '
  1008. 'least one email', output_text)
  1009. user.username = 'pingou'
  1010. with tests.user_set(self.app.application, user):
  1011. output = self.app.get('/settings/')
  1012. self.assertEqual(output.status_code, 200)
  1013. output_text = output.get_data(as_text=True)
  1014. self.assertIn(
  1015. '<title>pingou\'s settings - Pagure</title>', output_text)
  1016. csrf_token = self.get_csrf(output=output)
  1017. data = {
  1018. 'email': 'foo@pingou.com',
  1019. }
  1020. output = self.app.post(
  1021. '/settings/email/drop', 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. '<title>pingou\'s settings - Pagure</title>', output_text)
  1026. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1027. data = {
  1028. 'csrf_token': csrf_token,
  1029. 'email': 'foobar@pingou.com',
  1030. }
  1031. output = self.app.post(
  1032. '/settings/email/drop', data=data, follow_redirects=True)
  1033. self.assertEqual(output.status_code, 200)
  1034. output_text = output.get_data(as_text=True)
  1035. self.assertIn(
  1036. '<title>pingou\'s settings - Pagure</title>', output_text)
  1037. self.assertIn(
  1038. 'You do not have the '
  1039. 'email: foobar@pingou.com, nothing to remove', output_text)
  1040. data = {
  1041. 'csrf_token': csrf_token,
  1042. 'email': 'foo@pingou.com',
  1043. }
  1044. output = self.app.post(
  1045. '/settings/email/drop', data=data, follow_redirects=True)
  1046. self.assertEqual(output.status_code, 200)
  1047. output_text = output.get_data(as_text=True)
  1048. self.assertEqual(output_text.count('foo@pingou.com'), 0)
  1049. self.assertEqual(output_text.count('bar@pingou.com'), 3)
  1050. output = self.app.post(
  1051. '/settings/email/drop', data=data, follow_redirects=True)
  1052. self.assertEqual(output.status_code, 200)
  1053. output_text = output.get_data(as_text=True)
  1054. self.assertEqual(output_text.count('foo@pingou.com'), 0)
  1055. self.assertEqual(output_text.count('bar@pingou.com'), 3)
  1056. ast.return_value = True
  1057. output = self.app.post('/settings/email/drop', data=data)
  1058. self.assertEqual(output.status_code, 302)
  1059. @patch('pagure.lib.notify.send_email')
  1060. @patch('pagure.ui.app.admin_session_timedout')
  1061. def test_add_api_user_email(self, ast, send_email):
  1062. """ Test the add_api_user_email endpoint. """
  1063. send_email.return_value = True
  1064. ast.return_value = False
  1065. self.test_new_project()
  1066. user = tests.FakeUser()
  1067. with tests.user_set(self.app.application, user):
  1068. output = self.app.post('/settings/email/add')
  1069. self.assertEqual(output.status_code, 404)
  1070. self.assertIn('<h2>Page not found (404)</h2>', output.get_data(as_text=True))
  1071. user.username = 'foo'
  1072. with tests.user_set(self.app.application, user):
  1073. output = self.app.post('/settings/email/add')
  1074. self.assertEqual(output.status_code, 200)
  1075. output_text = output.get_data(as_text=True)
  1076. self.assertIn("<strong>Add new email</strong>", output_text)
  1077. if self.get_wtforms_version() >= (2, 2):
  1078. self.assertIn(
  1079. '<input class="form-control form-control-error" id="email" '
  1080. 'name="email" required type="text" value="">', output_text)
  1081. else:
  1082. self.assertIn(
  1083. '<input class="form-control form-control-error" id="email" '
  1084. 'name="email" type="text" value="">', output_text)
  1085. user.username = 'pingou'
  1086. with tests.user_set(self.app.application, user):
  1087. output = self.app.post('/settings/email/add')
  1088. self.assertEqual(output.status_code, 200)
  1089. output_text = output.get_data(as_text=True)
  1090. self.assertIn("<strong>Add new email</strong>", output_text)
  1091. if self.get_wtforms_version() >= (2, 2):
  1092. self.assertIn(
  1093. '<input class="form-control form-control-error" id="email" '
  1094. 'name="email" required type="text" value="">', output_text)
  1095. else:
  1096. self.assertIn(
  1097. '<input class="form-control form-control-error" id="email" '
  1098. 'name="email" type="text" value="">', output_text)
  1099. csrf_token = output_text.split(
  1100. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1101. data = {
  1102. 'email': 'foo2@pingou.com',
  1103. }
  1104. output = self.app.post(
  1105. '/settings/email/add', data=data, follow_redirects=True)
  1106. self.assertEqual(output.status_code, 200)
  1107. output_text = output.get_data(as_text=True)
  1108. self.assertIn("<strong>Add new email</strong>", output_text)
  1109. self.assertEqual(output_text.count('foo2@pingou.com'), 1)
  1110. # New email
  1111. data = {
  1112. 'csrf_token': csrf_token,
  1113. 'email': 'foðbar@pingou.com',
  1114. }
  1115. output = self.app.post(
  1116. '/settings/email/add', data=data, follow_redirects=True)
  1117. self.assertEqual(output.status_code, 200)
  1118. output_text = output.get_data(as_text=True)
  1119. self.assertIn(
  1120. '<title>pingou\'s settings - Pagure</title>', output_text)
  1121. self.assertIn(
  1122. 'Email pending validation',
  1123. output_text)
  1124. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1125. self.assertEqual(output_text.count('bar@pingou.com'), 5)
  1126. self.assertEqual(output_text.count('foðbar@pingou.com'), 2)
  1127. # Email already pending
  1128. output = self.app.post(
  1129. '/settings/email/add', data=data, follow_redirects=True)
  1130. self.assertEqual(output.status_code, 200)
  1131. output_text = output.get_data(as_text=True)
  1132. self.assertIn(
  1133. '<div class="card-header">\n '
  1134. '<strong>Add new email</strong>', output_text)
  1135. self.assertIn(
  1136. 'This email is already '
  1137. 'pending confirmation', output_text)
  1138. # User already has this email
  1139. data = {
  1140. 'csrf_token': csrf_token,
  1141. 'email': 'foo@pingou.com',
  1142. }
  1143. output = self.app.post(
  1144. '/settings/email/add', data=data, follow_redirects=True)
  1145. self.assertEqual(output.status_code, 200)
  1146. output_text = output.get_data(as_text=True)
  1147. self.assertTrue("<strong>Add new email</strong>" in output_text)
  1148. self.assertTrue(
  1149. 'Invalid value, can&#39;t be any of: bar@pingou.com, '
  1150. 'foo@pingou.com.&nbsp;' in output_text
  1151. or
  1152. 'Invalid value, can&#39;t be any of: foo@pingou.com, '
  1153. 'bar@pingou.com.&nbsp;' in output_text
  1154. )
  1155. self.assertEqual(
  1156. output_text.count('foo@pingou.com'), 6)
  1157. self.assertEqual(
  1158. output_text.count('bar@pingou.com'), 5)
  1159. self.assertEqual(
  1160. output_text.count('foðbar@pingou.com'), 0)
  1161. # Email registered by someone else
  1162. data = {
  1163. 'csrf_token': csrf_token,
  1164. 'email': 'foo@bar.com',
  1165. }
  1166. output = self.app.post(
  1167. '/settings/email/add', data=data, follow_redirects=True)
  1168. self.assertEqual(output.status_code, 200)
  1169. output_text = output.get_data(as_text=True)
  1170. self.assertTrue("<strong>Add new email</strong>" in output_text)
  1171. self.assertIn(
  1172. 'Invalid value, can&#39;t be any of: foo@bar.com.&nbsp;',
  1173. output_text)
  1174. ast.return_value = True
  1175. output = self.app.post('/settings/email/add', data=data)
  1176. self.assertEqual(output.status_code, 302)
  1177. @patch('pagure.lib.notify.send_email')
  1178. @patch('pagure.ui.app.admin_session_timedout')
  1179. def test_set_default_email(self, ast, send_email):
  1180. """ Test the set_default_email endpoint. """
  1181. send_email.return_value = True
  1182. ast.return_value = False
  1183. self.test_new_project()
  1184. user = tests.FakeUser()
  1185. with tests.user_set(self.app.application, user):
  1186. output = self.app.post('/settings/email/default')
  1187. self.assertEqual(output.status_code, 404)
  1188. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1189. user.username = 'pingou'
  1190. with tests.user_set(self.app.application, user):
  1191. output = self.app.get('/settings/')
  1192. self.assertEqual(output.status_code, 200)
  1193. output_text = output.get_data(as_text=True)
  1194. self.assertIn(
  1195. '<title>pingou\'s settings - Pagure</title>', output_text)
  1196. csrf_token = self.get_csrf(output=output)
  1197. data = {
  1198. 'email': 'foo@pingou.com',
  1199. }
  1200. output = self.app.post(
  1201. '/settings/email/default', data=data, follow_redirects=True)
  1202. self.assertEqual(output.status_code, 200)
  1203. output_text = output.get_data(as_text=True)
  1204. self.assertIn(
  1205. '<title>pingou\'s settings - Pagure</title>', output_text)
  1206. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1207. # Set invalid default email
  1208. data = {
  1209. 'csrf_token': csrf_token,
  1210. 'email': 'foobar@pingou.com',
  1211. }
  1212. output = self.app.post(
  1213. '/settings/email/default', data=data, follow_redirects=True)
  1214. self.assertEqual(output.status_code, 200)
  1215. output_text = output.get_data(as_text=True)
  1216. self.assertIn(
  1217. '<title>pingou\'s settings - Pagure</title>', output_text)
  1218. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1219. self.assertIn(
  1220. 'You do not have the '
  1221. 'email: foobar@pingou.com, nothing to set',
  1222. output_text)
  1223. # Set default email
  1224. data = {
  1225. 'csrf_token': csrf_token,
  1226. 'email': 'foo@pingou.com',
  1227. }
  1228. output = self.app.post(
  1229. '/settings/email/default', data=data, follow_redirects=True)
  1230. self.assertEqual(output.status_code, 200)
  1231. output_text = output.get_data(as_text=True)
  1232. self.assertIn(
  1233. '<title>pingou\'s settings - Pagure</title>', output_text)
  1234. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1235. self.assertIn(
  1236. 'Default email set to: '
  1237. 'foo@pingou.com', output_text)
  1238. ast.return_value = True
  1239. output = self.app.post('/settings/email/default', data=data)
  1240. self.assertEqual(output.status_code, 302)
  1241. @patch('pagure.lib.notify.send_email')
  1242. @patch('pagure.ui.app.admin_session_timedout')
  1243. def test_reconfirm_email(self, ast, send_email):
  1244. """ Test the reconfirm_email endpoint. """
  1245. send_email.return_value = True
  1246. ast.return_value = False
  1247. self.test_new_project()
  1248. # Add a pending email to pingou
  1249. userobj = pagure.lib.query.search_user(self.session, username='pingou')
  1250. self.assertEqual(len(userobj.emails), 2)
  1251. email_pend = pagure.lib.model.UserEmailPending(
  1252. user_id=userobj.id,
  1253. email='foo@fp.o',
  1254. token='abcdef',
  1255. )
  1256. self.session.add(email_pend)
  1257. self.session.commit()
  1258. user = tests.FakeUser()
  1259. with tests.user_set(self.app.application, user):
  1260. output = self.app.post('/settings/email/resend')
  1261. self.assertEqual(output.status_code, 404)
  1262. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1263. user.username = 'pingou'
  1264. with tests.user_set(self.app.application, user):
  1265. output = self.app.get('/settings/')
  1266. self.assertEqual(output.status_code, 200)
  1267. output_text = output.get_data(as_text=True)
  1268. self.assertIn(
  1269. '<title>pingou\'s settings - Pagure</title>', output_text)
  1270. csrf_token = self.get_csrf(output=output)
  1271. data = {
  1272. 'email': 'foo@pingou.com',
  1273. }
  1274. output = self.app.post(
  1275. '/settings/email/resend', data=data, follow_redirects=True)
  1276. self.assertEqual(output.status_code, 200)
  1277. output_text = output.get_data(as_text=True)
  1278. self.assertIn(
  1279. '<title>pingou\'s settings - Pagure</title>', output_text)
  1280. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1281. # Set invalid default email
  1282. data = {
  1283. 'csrf_token': csrf_token,
  1284. 'email': 'foobar@pingou.com',
  1285. }
  1286. output = self.app.post(
  1287. '/settings/email/resend', data=data, follow_redirects=True)
  1288. self.assertEqual(output.status_code, 200)
  1289. output_text = output.get_data(as_text=True)
  1290. self.assertIn(
  1291. '<title>pingou\'s settings - Pagure</title>', output_text)
  1292. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1293. self.assertIn(
  1294. 'This email address has '
  1295. 'already been confirmed', output_text)
  1296. # Validate a non-validated email
  1297. data = {
  1298. 'csrf_token': csrf_token,
  1299. 'email': 'foo@fp.o',
  1300. }
  1301. output = self.app.post(
  1302. '/settings/email/resend', data=data, follow_redirects=True)
  1303. self.assertEqual(output.status_code, 200)
  1304. output_text = output.get_data(as_text=True)
  1305. self.assertIn(
  1306. '<title>pingou\'s settings - Pagure</title>', output_text)
  1307. self.assertEqual(output_text.count('foo@pingou.com'), 4)
  1308. self.assertIn(
  1309. 'Confirmation email re-sent',
  1310. output_text)
  1311. ast.return_value = True
  1312. output = self.app.post('/settings/email/resend', data=data)
  1313. self.assertEqual(output.status_code, 302)
  1314. @patch('pagure.ui.app.admin_session_timedout')
  1315. def test_confirm_email(self, ast):
  1316. """ Test the confirm_email endpoint. """
  1317. output = self.app.get('/settings/email/confirm/foobar')
  1318. self.assertEqual(output.status_code, 302)
  1319. ast.return_value = False
  1320. # Add a pending email to pingou
  1321. userobj = pagure.lib.query.search_user(self.session, username='pingou')
  1322. self.assertEqual(len(userobj.emails), 2)
  1323. email_pend = pagure.lib.model.UserEmailPending(
  1324. user_id=userobj.id,
  1325. email='foo@fp.o',
  1326. token='abcdef',
  1327. )
  1328. self.session.add(email_pend)
  1329. self.session.commit()
  1330. user = tests.FakeUser()
  1331. user.username = 'pingou'
  1332. with tests.user_set(self.app.application, user):
  1333. # Wrong token
  1334. output = self.app.get(
  1335. '/settings/email/confirm/foobar', follow_redirects=True)
  1336. self.assertEqual(output.status_code, 200)
  1337. output_text = output.get_data(as_text=True)
  1338. self.assertIn(
  1339. '<title>pingou\'s settings - Pagure</title>', output_text)
  1340. self.assertIn(
  1341. 'No email associated with this token.',
  1342. output_text)
  1343. # Confirm email
  1344. output = self.app.get(
  1345. '/settings/email/confirm/abcdef', follow_redirects=True)
  1346. self.assertEqual(output.status_code, 200)
  1347. output_text = output.get_data(as_text=True)
  1348. self.assertIn(
  1349. '<title>pingou\'s settings - Pagure</title>', output_text)
  1350. self.assertIn(
  1351. 'Email validated',
  1352. output_text)
  1353. userobj = pagure.lib.query.search_user(self.session, username='pingou')
  1354. self.assertEqual(len(userobj.emails), 3)
  1355. ast.return_value = True
  1356. output = self.app.get('/settings/email/confirm/foobar')
  1357. self.assertEqual(output.status_code, 302)
  1358. def test_view_my_requests_no_user(self):
  1359. """Test the view_user_requests endpoint."""
  1360. output = self.app.get('/user/somenonexistentuser/requests')
  1361. self.assertEqual(output.status_code, 404)
  1362. @patch(
  1363. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1364. @patch(
  1365. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1366. def test_view_my_requests(self):
  1367. """Test the view_user_requests endpoint. """
  1368. # Create the PR
  1369. tests.create_projects(self.session)
  1370. repo = pagure.lib.query._get_project(self.session, 'test')
  1371. req = pagure.lib.query.new_pull_request(
  1372. session=self.session,
  1373. repo_from=repo,
  1374. branch_from='dev',
  1375. repo_to=repo,
  1376. branch_to='master',
  1377. title='test pull-request #1',
  1378. user='pingou',
  1379. )
  1380. self.session.commit()
  1381. self.assertEqual(req.id, 1)
  1382. self.assertEqual(req.title, 'test pull-request #1')
  1383. output = self.app.get('/user/pingou/requests')
  1384. self.assertEqual(output.status_code, 200)
  1385. output_text = output.get_data(as_text=True)
  1386. self.assertIn('test pull-request #1', output_text)
  1387. self.assertEqual(
  1388. output_text.count('pr-status pr-status-open"'),
  1389. 1)
  1390. # Add a PR in a fork
  1391. item = pagure.lib.model.Project(
  1392. user_id=1, # pingou
  1393. name='test_fork',
  1394. description='test project #1',
  1395. is_fork=True,
  1396. parent_id=1,
  1397. hook_token='aaabbbttt',
  1398. )
  1399. self.session.add(item)
  1400. repo = pagure.lib.query._get_project(
  1401. self.session, 'test_fork', user='pingou')
  1402. req = pagure.lib.query.new_pull_request(
  1403. session=self.session,
  1404. repo_from=repo,
  1405. branch_from='dev',
  1406. repo_to=repo,
  1407. branch_to='master',
  1408. title='tést pull-request #2',
  1409. user='pingou',
  1410. )
  1411. self.session.commit()
  1412. self.assertEqual(req.id, 1)
  1413. self.assertEqual(req.title, 'tést pull-request #2')
  1414. output = self.app.get('/user/pingou/requests')
  1415. self.assertEqual(output.status_code, 200)
  1416. output_text = output.get_data(as_text=True)
  1417. self.assertIn('test pull-request #1', output_text)
  1418. self.assertIn('tést pull-request #2', output_text)
  1419. self.assertEqual(
  1420. output_text.count('pr-status pr-status-open"'),
  1421. 2)
  1422. @patch(
  1423. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1424. @patch(
  1425. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1426. def test_view_my_requests_pr_in_another_project(self):
  1427. """Test the view_user_requests endpoint when the user opened a PR
  1428. in another project. """
  1429. # Pingou creates the PR on test
  1430. tests.create_projects(self.session)
  1431. repo = pagure.lib.query._get_project(self.session, 'test')
  1432. req = pagure.lib.query.new_pull_request(
  1433. session=self.session,
  1434. repo_from=repo,
  1435. branch_from='dev',
  1436. repo_to=repo,
  1437. branch_to='master',
  1438. title='test pull-request #1',
  1439. user='pingou',
  1440. )
  1441. self.session.commit()
  1442. self.assertEqual(req.id, 1)
  1443. self.assertEqual(req.title, 'test pull-request #1')
  1444. # foo creates the PR on test
  1445. repo = pagure.lib.query._get_project(self.session, 'test')
  1446. req = pagure.lib.query.new_pull_request(
  1447. session=self.session,
  1448. repo_from=repo,
  1449. branch_from='dev',
  1450. repo_to=repo,
  1451. branch_to='master',
  1452. title='test pull-request #2',
  1453. user='foo',
  1454. )
  1455. self.session.commit()
  1456. self.assertEqual(req.id, 2)
  1457. self.assertEqual(req.title, 'test pull-request #2')
  1458. # Check pingou's PR list
  1459. output = self.app.get('/user/pingou/requests')
  1460. self.assertEqual(output.status_code, 200)
  1461. output_text = output.get_data(as_text=True)
  1462. self.assertIn('test pull-request #1', output_text)
  1463. self.assertIn('test pull-request #2', output_text)
  1464. self.assertEqual(
  1465. output_text.count('pr-status pr-status-open"'),
  1466. 2)
  1467. # Check foo's PR list
  1468. output = self.app.get('/user/foo/requests')
  1469. self.assertEqual(output.status_code, 200)
  1470. output_text = output.get_data(as_text=True)
  1471. self.assertNotIn('test pull-request #1', output_text)
  1472. self.assertIn('test pull-request #2', output_text)
  1473. self.assertEqual(
  1474. output_text.count('pr-status pr-status-open"'),
  1475. 1)
  1476. @patch(
  1477. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1478. @patch(
  1479. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1480. def test_view_my_requests_against_another_project(self):
  1481. """Test the view_user_requests endpoint when there is a PR opened
  1482. by me against a project I do not have rights on. """
  1483. # Create the PR
  1484. tests.create_projects(self.session)
  1485. repo = pagure.lib.query._get_project(self.session, 'test')
  1486. req = pagure.lib.query.new_pull_request(
  1487. session=self.session,
  1488. repo_from=repo,
  1489. branch_from='dev',
  1490. repo_to=repo,
  1491. branch_to='master',
  1492. title='test pull-request #1',
  1493. user='foo',
  1494. )
  1495. self.session.commit()
  1496. self.assertEqual(req.id, 1)
  1497. self.assertEqual(req.title, 'test pull-request #1')
  1498. output = self.app.get('/user/foo/requests')
  1499. self.assertEqual(output.status_code, 200)
  1500. output_text = output.get_data(as_text=True)
  1501. self.assertIn('test pull-request #1', output_text)
  1502. self.assertEqual(
  1503. output_text.count('pr-status pr-status-open"'),
  1504. 1)
  1505. def test_view_my_issues_no_user(self):
  1506. """Test the view_user_issues endpoint with a missing user."""
  1507. output = self.app.get('/user/somenonexistentuser/issues')
  1508. self.assertEqual(output.status_code, 404)
  1509. @patch(
  1510. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1511. @patch(
  1512. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1513. def test_view_my_issues(self):
  1514. """Test the view_user_issues endpoint when the user exists."""
  1515. # Create the issue
  1516. tests.create_projects(self.session)
  1517. repo = pagure.lib.query._get_project(self.session, 'test')
  1518. msg = pagure.lib.query.new_issue(
  1519. session=self.session,
  1520. repo=repo,
  1521. title='Test issue #1',
  1522. content='We should work on this for the second time',
  1523. user='pingou',
  1524. status='Open',
  1525. )
  1526. self.session.commit()
  1527. self.assertEqual(msg.title, 'Test issue #1')
  1528. output = self.app.get('/user/pingou/issues')
  1529. self.assertEqual(output.status_code, 200)
  1530. output_text = output.get_data(as_text=True)
  1531. self.assertIn('Test issue #1', output_text)
  1532. self.assertEqual(
  1533. output_text.count(
  1534. 'issue-status issue-status-open'),
  1535. 1)
  1536. # Add an issue in a fork
  1537. item = pagure.lib.model.Project(
  1538. user_id=2, # foo
  1539. name='test_fork',
  1540. description='test project #1',
  1541. is_fork=True,
  1542. parent_id=1,
  1543. hook_token='aaabbbttt',
  1544. )
  1545. self.session.add(item)
  1546. repo = pagure.lib.query._get_project(self.session, 'test_fork', user='foo')
  1547. msg = pagure.lib.query.new_issue(
  1548. session=self.session,
  1549. repo=repo,
  1550. title='Test issue #2',
  1551. content='We should work on this for the second time',
  1552. user='pingou',
  1553. status='Open',
  1554. )
  1555. self.session.commit()
  1556. self.assertEqual(msg.title, 'Test issue #2')
  1557. # Test the assigned issue table. Create issue then set the assignee
  1558. msg = pagure.lib.query.new_issue(
  1559. session=self.session,
  1560. repo=repo,
  1561. title='Test issue #3',
  1562. content='This issue created by foo, but assigned to pingou',
  1563. user='foo',
  1564. status='Open',
  1565. )
  1566. self.session.commit()
  1567. self.assertEqual(msg.title, 'Test issue #3')
  1568. msg = pagure.lib.query.add_issue_assignee(
  1569. session=self.session,
  1570. issue=msg,
  1571. assignee='pingou',
  1572. user='foo',
  1573. )
  1574. self.session.commit()
  1575. self.assertEqual(msg, 'Issue assigned to pingou')
  1576. output = self.app.get('/user/pingou/issues')
  1577. self.assertEqual(output.status_code, 200)
  1578. output_text = output.get_data(as_text=True)
  1579. self.assertIn('Test issue #1', output_text)
  1580. self.assertIn('Test issue #2', output_text)
  1581. self.assertIn('Test issue #3', output_text)
  1582. self.assertEqual(
  1583. output_text.count(
  1584. 'issue-status issue-status-open'),
  1585. 3)
  1586. @patch(
  1587. 'pagure.lib.git.update_git', MagicMock(return_value=True))
  1588. @patch(
  1589. 'pagure.lib.notify.send_email', MagicMock(return_value=True))
  1590. def test_view_my_issues_disabled(self):
  1591. """Test the view_user_issues endpoint when the project disabled issue
  1592. tracking."""
  1593. # Create the issue
  1594. tests.create_projects(self.session)
  1595. repo = pagure.lib.query._get_project(self.session, 'test')
  1596. msg = pagure.lib.query.new_issue(
  1597. session=self.session,
  1598. repo=repo,
  1599. title='Test issue #1',
  1600. content='We should work on this for the second time',
  1601. user='pingou',
  1602. status='Open',
  1603. )
  1604. self.session.commit()
  1605. self.assertEqual(msg.title, 'Test issue #1')
  1606. # Before
  1607. output = self.app.get('/user/pingou/issues')
  1608. self.assertEqual(output.status_code, 200)
  1609. output_text = output.get_data(as_text=True)
  1610. self.assertIn('Test issue #1', output_text)
  1611. self.assertEqual(
  1612. output_text.count('issue-status issue-status-open'),
  1613. 1)
  1614. # Disable issue tracking
  1615. repo = pagure.lib.query._get_project(self.session, 'test')
  1616. settings = repo.settings
  1617. settings['issue_tracker'] = False
  1618. repo.settings = settings
  1619. self.session.add(repo)
  1620. self.session.commit()
  1621. # After
  1622. output = self.app.get('/user/pingou/issues')
  1623. self.assertEqual(output.status_code, 200)
  1624. output_text = output.get_data(as_text=True)
  1625. self.assertNotIn('Test issue #1', output_text)
  1626. self.assertEqual(
  1627. output_text.count('issue-status issue-status-open'),
  1628. 0)
  1629. def test_view_my_issues_tickets_turned_off(self):
  1630. """Test the view_user_issues endpoint when the user exists and
  1631. and ENABLE_TICKETS is False """
  1632. # Turn off the tickets instance wide
  1633. pagure.config.config['ENABLE_TICKETS'] = False
  1634. output = self.app.get('/user/pingou/issues')
  1635. self.assertEqual(output.status_code, 404)
  1636. pagure.config.config['ENABLE_TICKETS'] = True
  1637. @patch('pagure.ui.app.admin_session_timedout')
  1638. def test_add_user_token(self, ast):
  1639. """ Test the add_user_token endpoint. """
  1640. ast.return_value = False
  1641. self.test_new_project()
  1642. user = tests.FakeUser()
  1643. with tests.user_set(self.app.application, user):
  1644. output = self.app.get('/settings/token/new/')
  1645. self.assertEqual(output.status_code, 404)
  1646. self.assertIn('<h2>Page not found (404)</h2>',
  1647. output.get_data(as_text=True))
  1648. user.username = 'foo'
  1649. with tests.user_set(self.app.application, user):
  1650. output = self.app.get('/settings/token/new')
  1651. self.assertEqual(output.status_code, 200)
  1652. output_text = output.get_data(as_text=True)
  1653. self.assertIn(
  1654. '<div class="card-header">\n <strong>'
  1655. 'Create a new token</strong>\n', output_text)
  1656. self.assertIn(
  1657. '<input type="checkbox" name="acls" value="create_project">',
  1658. output_text)
  1659. csrf_token = output_text.split(
  1660. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1661. data = {
  1662. 'acls': ['create_project', 'fork_project']
  1663. }
  1664. # missing CSRF
  1665. output = self.app.post('/settings/token/new', data=data)
  1666. self.assertEqual(output.status_code, 200)
  1667. output_text = output.get_data(as_text=True)
  1668. self.assertIn(
  1669. '<title>Create token - Pagure</title>', output_text)
  1670. self.assertIn(
  1671. '<div class="card-header">\n <strong>'
  1672. 'Create a new token</strong>\n', output_text)
  1673. self.assertIn(
  1674. '<input type="checkbox" name="acls" value="create_project">',
  1675. output_text)
  1676. data = {
  1677. 'acls': ['new_project'],
  1678. 'csrf_token': csrf_token
  1679. }
  1680. # Invalid ACLs
  1681. output = self.app.post('/settings/token/new', data=data)
  1682. self.assertEqual(output.status_code, 200)
  1683. output_text = output.get_data(as_text=True)
  1684. self.assertIn(
  1685. '<title>Create token - Pagure</title>', output_text)
  1686. self.assertIn(
  1687. '<div class="card-header">\n <strong>'
  1688. 'Create a new token</strong>\n', output_text)
  1689. self.assertIn(
  1690. '<input type="checkbox" name="acls" value="create_project">',
  1691. output_text)
  1692. data = {
  1693. 'acls': ['create_project', 'fork_project'],
  1694. 'csrf_token': csrf_token
  1695. }
  1696. # All good
  1697. output = self.app.post(
  1698. '/settings/token/new', data=data, follow_redirects=True)
  1699. self.assertEqual(output.status_code, 200)
  1700. output_text = output.get_data(as_text=True)
  1701. self.assertIn(
  1702. '<title>foo\'s settings - Pagure</title>', output_text)
  1703. self.assertIn(
  1704. 'Token created',
  1705. output_text)
  1706. self.assertEqual(
  1707. output_text.count(
  1708. '<small class="font-weight-bold text-success input-group-text">Active until'), 1)
  1709. ast.return_value = True
  1710. output = self.app.get('/settings/token/new')
  1711. self.assertEqual(output.status_code, 302)
  1712. @patch('pagure.ui.app.admin_session_timedout')
  1713. def test_revoke_api_user_token(self, ast):
  1714. """ Test the revoke_api_user_token endpoint. """
  1715. ast.return_value = False
  1716. self.test_new_project()
  1717. user = tests.FakeUser()
  1718. with tests.user_set(self.app.application, user):
  1719. # Token doesn't exist
  1720. output = self.app.post('/settings/token/revoke/foobar')
  1721. self.assertEqual(output.status_code, 404)
  1722. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1723. # Create the foobar API token but associated w/ the user 'foo'
  1724. item = pagure.lib.model.Token(
  1725. id='foobar',
  1726. user_id=2, # foo
  1727. expiration=datetime.datetime.utcnow() \
  1728. + datetime.timedelta(days=30)
  1729. )
  1730. self.session.add(item)
  1731. self.session.commit()
  1732. # Token not associated w/ this user
  1733. output = self.app.post('/settings/token/revoke/foobar')
  1734. self.assertEqual(output.status_code, 404)
  1735. self.assertTrue('<h2>Page not found (404)</h2>' in output.get_data(as_text=True))
  1736. user.username = 'foo'
  1737. with tests.user_set(self.app.application, user):
  1738. # Missing CSRF token
  1739. output = self.app.post(
  1740. '/settings/token/revoke/foobar', follow_redirects=True)
  1741. self.assertEqual(output.status_code, 200)
  1742. output_text = output.get_data(as_text=True)
  1743. self.assertIn(
  1744. "<title>foo's settings - Pagure</title>", output_text)
  1745. self.assertEqual(
  1746. output_text.count(
  1747. '<small class="font-weight-bold text-success input-group-text">Active until'), 1)
  1748. csrf_token = output_text.split(
  1749. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1750. data = {
  1751. 'csrf_token': csrf_token
  1752. }
  1753. # All good - token is deleted
  1754. output = self.app.post(
  1755. '/settings/token/revoke/foobar', data=data,
  1756. follow_redirects=True)
  1757. self.assertEqual(output.status_code, 200)
  1758. output_text = output.get_data(as_text=True)
  1759. self.assertIn(
  1760. "<title>foo's settings - Pagure</title>", output_text)
  1761. self.assertEqual(
  1762. output_text.count(
  1763. '<small class="font-weight-bold text-success input-group-text">Active until'), 0)
  1764. user = pagure.lib.query.get_user(self.session, key='foo')
  1765. self.assertEqual(len(user.tokens), 1)
  1766. expiration_dt = user.tokens[0].expiration
  1767. # Token was already deleted - no changes
  1768. output = self.app.post(
  1769. '/settings/token/revoke/foobar', data=data,
  1770. follow_redirects=True)
  1771. self.assertEqual(output.status_code, 200)
  1772. output_text = output.get_data(as_text=True)
  1773. self.assertIn(
  1774. "<title>foo's settings - Pagure</title>", output_text)
  1775. self.assertEqual(
  1776. output_text.count(
  1777. '<small class="font-weight-bold text-success input-group-text">Active until'), 0)
  1778. # Ensure the expiration date did not change
  1779. user = pagure.lib.query.get_user(self.session, key='foo')
  1780. self.assertEqual(len(user.tokens), 1)
  1781. self.assertEqual(
  1782. expiration_dt, user.tokens[0].expiration
  1783. )
  1784. ast.return_value = True
  1785. output = self.app.get('/settings/token/new')
  1786. self.assertEqual(output.status_code, 302)
  1787. @patch.dict('pagure.config.config', {'PAGURE_AUTH': 'fas'})
  1788. @patch.dict('pagure.utils.pagure_config', {'PAGURE_AUTH': 'fas'})
  1789. def test_create_project_auth_FAS_no_FPCA(self):
  1790. """ Test creating a project when auth is FAS and the user did not
  1791. sign the FPCA. """
  1792. user = tests.FakeUser(username='foo', cla_done=False)
  1793. with tests.user_set(self.app.application, user):
  1794. output = self.app.get('/new/', follow_redirects=True)
  1795. self.assertEqual(output.status_code, 200)
  1796. output_text = output.get_data(as_text=True)
  1797. self.assertIn('<title>Home - Pagure</title>', output_text)
  1798. self.assertIn(
  1799. '</i> You must <a href="https://admin.fedoraproject.org/accounts/'
  1800. '">sign the FPCA</a> (Fedora Project Contributor Agreement) '
  1801. 'to use pagure</div>', output_text)
  1802. class PagureFlaskAppAboutPagetests(tests.Modeltests):
  1803. """ Unit-tests for the about page. """
  1804. def test_about_page(self):
  1805. """ Test the about page when an admin_email is set. """
  1806. output = self.app.get('/about/')
  1807. self.assertEqual(output.status_code, 200)
  1808. output_text = output.get_data(as_text=True)
  1809. self.assertIn('<title>About - Pagure</title>', output_text)
  1810. self.assertIn(
  1811. 'by emailing:\n '
  1812. '<a href="mailto:root@localhost.localdomain">', output_text)
  1813. self.assertIn(
  1814. 'href="https://pagure.io/pagure/issues">open a ticket</a>',
  1815. output_text)
  1816. @patch.dict('pagure.config.config', {'ADMIN_EMAIL': 'admin@fp.o'})
  1817. def test_about_page_admin_email(self):
  1818. """ Test the about page when an admin_email is set. """
  1819. output = self.app.get('/about/')
  1820. self.assertEqual(output.status_code, 200)
  1821. output_text = output.get_data(as_text=True)
  1822. self.assertIn('<title>About - Pagure</title>', output_text)
  1823. self.assertIn(
  1824. 'by emailing:\n <a href="mailto:admin@fp.o">',
  1825. output_text)
  1826. self.assertIn(
  1827. 'href="https://pagure.io/pagure/issues">open a ticket</a>',
  1828. output_text)
  1829. class PagureFlaskAppNoDocstests(tests.Modeltests):
  1830. """ Tests for flask app controller of pagure """
  1831. config_values = {
  1832. "enable_docs": False,
  1833. "docs_folder": None,
  1834. }
  1835. def test_new_project_no_docs_folder(self):
  1836. """ Test the new_project endpoint with DOCS_FOLDER is None. """
  1837. # Before
  1838. projects = pagure.lib.query.search_projects(self.session)
  1839. self.assertEqual(len(projects), 0)
  1840. self.assertFalse(os.path.exists(
  1841. os.path.join(self.path, 'repos', 'project#1.git')))
  1842. self.assertFalse(os.path.exists(
  1843. os.path.join(self.path, 'repos', 'tickets', 'project#1.git')))
  1844. self.assertFalse(os.path.exists(
  1845. os.path.join(self.path, 'repos', 'docs', 'project#1.git')))
  1846. self.assertFalse(os.path.exists(
  1847. os.path.join(self.path, 'repos', 'requests', 'project#1.git')))
  1848. user = tests.FakeUser(username='foo')
  1849. with tests.user_set(self.app.application, user):
  1850. csrf_token = self.get_csrf()
  1851. data = {
  1852. 'description': 'Project #1',
  1853. 'name': 'project-1',
  1854. 'csrf_token': csrf_token,
  1855. }
  1856. output = self.app.post('/new/', data=data, follow_redirects=True)
  1857. self.assertEqual(output.status_code, 200)
  1858. output_text = output.get_data(as_text=True)
  1859. self.assertIn(
  1860. '<div class="projectinfo my-3">\nProject #1',
  1861. output_text)
  1862. self.assertIn('<p>This repo is brand new!</p>',
  1863. output_text)
  1864. self.assertIn(
  1865. '<title>Overview - project-1 - Pagure</title>', output_text)
  1866. # After
  1867. projects = pagure.lib.query.search_projects(self.session)
  1868. self.assertEqual(len(projects), 1)
  1869. self.assertTrue(os.path.exists(
  1870. os.path.join(self.path, 'repos', 'project-1.git')))
  1871. self.assertTrue(os.path.exists(
  1872. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  1873. self.assertFalse(os.path.exists(
  1874. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  1875. self.assertTrue(os.path.exists(
  1876. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  1877. class PagureFlaskAppNoTicketstests(tests.Modeltests):
  1878. """ Tests for flask app controller of pagure """
  1879. config_values = {
  1880. "enable_tickets": False,
  1881. "tickets_folder": None,
  1882. }
  1883. def test_new_project_no_tickets_folder(self):
  1884. """ Test the new_project endpoint with TICKETS_FOLDER is None. """
  1885. # Before
  1886. projects = pagure.lib.query.search_projects(self.session)
  1887. self.assertEqual(len(projects), 0)
  1888. self.assertFalse(os.path.exists(
  1889. os.path.join(self.path, 'repos', 'project#1.git')))
  1890. self.assertFalse(os.path.exists(
  1891. os.path.join(self.path, 'repos', 'tickets', 'project#1.git')))
  1892. self.assertFalse(os.path.exists(
  1893. os.path.join(self.path, 'repos', 'docs', 'project#1.git')))
  1894. self.assertFalse(os.path.exists(
  1895. os.path.join(self.path, 'repos', 'requests', 'project#1.git')))
  1896. user = tests.FakeUser(username='foo')
  1897. with tests.user_set(self.app.application, user):
  1898. csrf_token = self.get_csrf()
  1899. data = {
  1900. 'description': 'Project #1',
  1901. 'name': 'project-1',
  1902. 'csrf_token': csrf_token,
  1903. }
  1904. output = self.app.post('/new/', data=data, follow_redirects=True)
  1905. self.assertEqual(output.status_code, 200)
  1906. output_text = output.get_data(as_text=True)
  1907. self.assertIn(
  1908. '<div class="projectinfo my-3">\nProject #1',
  1909. output_text)
  1910. self.assertIn('<p>This repo is brand new!</p>',
  1911. output_text)
  1912. self.assertIn(
  1913. '<title>Overview - project-1 - Pagure</title>', output_text)
  1914. # After
  1915. projects = pagure.lib.query.search_projects(self.session)
  1916. self.assertEqual(len(projects), 1)
  1917. self.assertTrue(os.path.exists(
  1918. os.path.join(self.path, 'repos', 'project-1.git')))
  1919. self.assertFalse(os.path.exists(
  1920. os.path.join(self.path, 'repos', 'tickets', 'project-1.git')))
  1921. self.assertTrue(os.path.exists(
  1922. os.path.join(self.path, 'repos', 'docs', 'project-1.git')))
  1923. self.assertTrue(os.path.exists(
  1924. os.path.join(self.path, 'repos', 'requests', 'project-1.git')))
  1925. if __name__ == '__main__':
  1926. unittest.main(verbosity=2)