test_pagure_flask_ui_fork.py 117 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2017 - 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 json
  11. import unittest
  12. import shutil
  13. import sys
  14. import tempfile
  15. import time
  16. import os
  17. import re
  18. import pygit2
  19. import six
  20. from mock import patch, MagicMock
  21. from bs4 import BeautifulSoup
  22. from datetime import datetime, timedelta
  23. sys.path.insert(0, os.path.join(os.path.dirname(
  24. os.path.abspath(__file__)), '..'))
  25. import pagure
  26. import pagure.lib
  27. import tests
  28. from pagure.lib.repo import PagureRepo
  29. def _get_commits(output):
  30. ''' Returns the commits message in the output. All commits must have
  31. been made by `Alice Author` or `PY C` to be found.
  32. '''
  33. commits = []
  34. save = False
  35. cnt = 0
  36. for row in output.split('\n'):
  37. if row.strip() in ['Alice Author', 'Alice Äuthòr', 'PY C']:
  38. save = True
  39. if save:
  40. cnt += 1
  41. if cnt == 7:
  42. commits.append(row.strip())
  43. save = False
  44. cnt = 0
  45. return commits
  46. class PagureFlaskForktests(tests.Modeltests):
  47. """ Tests for flask fork controller of pagure """
  48. def set_up_git_repo(
  49. self, new_project=None, branch_from='feature', mtype='FF',
  50. prid=1, name_from='test'):
  51. """ Set up the git repo and create the corresponding PullRequest
  52. object.
  53. """
  54. # Create a git repo to play with
  55. gitrepo = os.path.join(self.path, 'repos', '%s.git' % name_from)
  56. repo = pygit2.init_repository(gitrepo, bare=True)
  57. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  58. repopath = os.path.join(newpath, 'test')
  59. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  60. # Create a file in that git repo
  61. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  62. stream.write('foo\n bar')
  63. clone_repo.index.add('sources')
  64. clone_repo.index.write()
  65. try:
  66. com = repo.revparse_single('HEAD')
  67. prev_commit = [com.oid.hex]
  68. except:
  69. prev_commit = []
  70. # Commits the files added
  71. tree = clone_repo.index.write_tree()
  72. author = pygit2.Signature(
  73. 'Alice Author', 'alice@authors.tld')
  74. committer = pygit2.Signature(
  75. 'Cecil Committer', 'cecil@committers.tld')
  76. clone_repo.create_commit(
  77. 'refs/heads/master', # the name of the reference to update
  78. author,
  79. committer,
  80. 'Add sources file for testing',
  81. # binary string representing the tree object ID
  82. tree,
  83. # list of binary strings representing parents of the new commit
  84. prev_commit
  85. )
  86. time.sleep(1)
  87. refname = 'refs/heads/master:refs/heads/master'
  88. ori_remote = clone_repo.remotes[0]
  89. PagureRepo.push(ori_remote, refname)
  90. first_commit = repo.revparse_single('HEAD')
  91. def compatible_signature(name, email):
  92. if six.PY2:
  93. name = name.encode("utf-8")
  94. email = email.encode("utf-8")
  95. return pygit2.Signature(name, email)
  96. if mtype == 'merge':
  97. with open(os.path.join(repopath, '.gitignore'), 'w') as stream:
  98. stream.write('*~')
  99. clone_repo.index.add('.gitignore')
  100. clone_repo.index.write()
  101. # Commits the files added
  102. tree = clone_repo.index.write_tree()
  103. author = compatible_signature(
  104. 'Alice Äuthòr', 'alice@äuthòrs.tld')
  105. comitter = compatible_signature(
  106. 'Cecil Cõmmîttër', 'cecil@cõmmîttërs.tld')
  107. clone_repo.create_commit(
  108. 'refs/heads/master',
  109. author,
  110. committer,
  111. 'Add .gitignore file for testing',
  112. # binary string representing the tree object ID
  113. tree,
  114. # list of binary strings representing parents of the new commit
  115. [first_commit.oid.hex]
  116. )
  117. refname = 'refs/heads/master:refs/heads/master'
  118. ori_remote = clone_repo.remotes[0]
  119. PagureRepo.push(ori_remote, refname)
  120. if mtype == 'conflicts':
  121. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  122. stream.write('foo\n bar\nbaz')
  123. clone_repo.index.add('sources')
  124. clone_repo.index.write()
  125. # Commits the files added
  126. tree = clone_repo.index.write_tree()
  127. author = pygit2.Signature(
  128. 'Alice Author', 'alice@authors.tld')
  129. committer = pygit2.Signature(
  130. 'Cecil Committer', 'cecil@committers.tld')
  131. clone_repo.create_commit(
  132. 'refs/heads/master',
  133. author,
  134. committer,
  135. 'Add sources conflicting',
  136. # binary string representing the tree object ID
  137. tree,
  138. # list of binary strings representing parents of the new commit
  139. [first_commit.oid.hex]
  140. )
  141. refname = 'refs/heads/master:refs/heads/master'
  142. ori_remote = clone_repo.remotes[0]
  143. PagureRepo.push(ori_remote, refname)
  144. # Set the second repo
  145. new_gitrepo = repopath
  146. if new_project:
  147. # Create a new git repo to play with
  148. new_gitrepo = os.path.join(newpath, new_project.fullname)
  149. if not os.path.exists(new_gitrepo):
  150. os.makedirs(new_gitrepo)
  151. new_repo = pygit2.clone_repository(gitrepo, new_gitrepo)
  152. repo = pygit2.Repository(new_gitrepo)
  153. if mtype != 'nochanges':
  154. # Edit the sources file again
  155. with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream:
  156. stream.write('foo\n bar\nbaz\n boose')
  157. repo.index.add('sources')
  158. repo.index.write()
  159. # Commits the files added
  160. tree = repo.index.write_tree()
  161. author = pygit2.Signature(
  162. 'Alice Author', 'alice@authors.tld')
  163. committer = pygit2.Signature(
  164. 'Cecil Committer', 'cecil@committers.tld')
  165. repo.create_commit(
  166. 'refs/heads/%s' % branch_from,
  167. author,
  168. committer,
  169. 'A commit on branch %s' % branch_from,
  170. tree,
  171. [first_commit.oid.hex]
  172. )
  173. refname = 'refs/heads/%s' % (branch_from)
  174. ori_remote = repo.remotes[0]
  175. PagureRepo.push(ori_remote, refname)
  176. # Create a PR for these changes
  177. project = pagure.lib.get_authorized_project(self.session, 'test')
  178. req = pagure.lib.new_pull_request(
  179. session=self.session,
  180. repo_from=project,
  181. branch_from=branch_from,
  182. repo_to=project,
  183. branch_to='master',
  184. title='PR from the %s branch' % branch_from,
  185. user='pingou',
  186. requestfolder=None,
  187. )
  188. self.session.commit()
  189. self.assertEqual(req.id, prid)
  190. self.assertEqual(req.title, 'PR from the %s branch' % branch_from)
  191. shutil.rmtree(newpath)
  192. def test_request_pull_reference(self):
  193. """ Test if there is a reference created for a new PR. """
  194. tests.create_projects(self.session)
  195. tests.create_projects_git(
  196. os.path.join(self.path, 'requests'), bare=True)
  197. self.set_up_git_repo(new_project=None, branch_from='feature')
  198. project = pagure.lib.get_authorized_project(self.session, 'test')
  199. self.assertEqual(len(project.requests), 1)
  200. # View the pull-request
  201. output = self.app.get('/test/pull-request/1')
  202. self.assertEqual(output.status_code, 200)
  203. # Give time to the worker to process the task
  204. time.sleep(1)
  205. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  206. repo = pygit2.Repository(gitrepo)
  207. self.assertEqual(
  208. list(repo.listall_references()),
  209. ['refs/heads/feature', 'refs/heads/master', 'refs/pull/1/head']
  210. )
  211. @patch('pagure.lib.notify.send_email')
  212. def test_request_pull(self, send_email):
  213. """ Test the request_pull endpoint. """
  214. send_email.return_value = True
  215. tests.create_projects(self.session)
  216. tests.create_projects_git(
  217. os.path.join(self.path, 'requests'), bare=True)
  218. # Non-existant project
  219. output = self.app.get('/foobar/pull-request/1')
  220. self.assertEqual(output.status_code, 404)
  221. # Project has no PR
  222. output = self.app.get('/test/pull-request/1')
  223. self.assertEqual(output.status_code, 404)
  224. self.set_up_git_repo(new_project=None, branch_from='feature')
  225. project = pagure.lib.get_authorized_project(self.session, 'test')
  226. self.assertEqual(len(project.requests), 1)
  227. # View the pull-request
  228. output = self.app.get('/test/pull-request/1')
  229. self.assertEqual(output.status_code, 200)
  230. output_text = output.get_data(as_text=True)
  231. #self.assertIn(
  232. #'<h3><span class="label label-default">PR#1</span>\n'
  233. #' PR from the feature branch\n</h3>',
  234. #output_text)
  235. self.assertIn(
  236. 'title="View file as of 2a552b">sources</a>', output_text)
  237. # Test if the `open changed file icon` is displayed.
  238. self.assertIn(
  239. 'class="open_changed_file_icon_wrap"><span '
  240. 'class="oi open_changed_file_icon" data-glyph="eye" '
  241. 'alt="Open changed file" title="Open changed file"></span>'
  242. '</a>', output_text)
  243. self.assertIn(
  244. '<span class="label label-success '
  245. 'pull-xs-right text-mono">+3</span>', output_text)
  246. self.assertIn(
  247. '<span class="label label-danger pull-xs-right">-1</span>',
  248. output_text)
  249. @patch('pagure.lib.notify.send_email')
  250. def test_merge_request_pull_FF(self, send_email):
  251. """ Test the merge_request_pull endpoint with a FF PR. """
  252. send_email.return_value = True
  253. self.test_request_pull()
  254. user = tests.FakeUser()
  255. with tests.user_set(self.app.application, user):
  256. output = self.app.get('/test/pull-request/1')
  257. self.assertEqual(output.status_code, 200)
  258. csrf_token = self.get_csrf(output=output)
  259. # No CSRF
  260. output = self.app.post(
  261. '/test/pull-request/1/merge', data={}, follow_redirects=True)
  262. self.assertEqual(output.status_code, 200)
  263. output_text = output.get_data(as_text=True)
  264. self.assertIn(
  265. '<title>PR#1: PR from the feature branch - test\n - '
  266. 'Pagure</title>', output_text)
  267. #self.assertIn(
  268. #'<h3><span class="label label-default">PR#1</span>\n'
  269. #' PR from the feature branch\n</h3>',
  270. #output_text)
  271. self.assertIn(
  272. 'title="View file as of 2a552b">sources</a>', output_text)
  273. # Wrong project
  274. data = {
  275. 'csrf_token': csrf_token,
  276. }
  277. output = self.app.post(
  278. '/foobar/pull-request/100/merge', data=data, follow_redirects=True)
  279. self.assertEqual(output.status_code, 404)
  280. # Wrong project
  281. data = {
  282. 'csrf_token': csrf_token,
  283. }
  284. output = self.app.post(
  285. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  286. self.assertEqual(output.status_code, 403)
  287. user.username = 'pingou'
  288. with tests.user_set(self.app.application, user):
  289. # Wrong request id
  290. data = {
  291. 'csrf_token': csrf_token,
  292. }
  293. output = self.app.post(
  294. '/test/pull-request/100/merge', data=data, follow_redirects=True)
  295. self.assertEqual(output.status_code, 404)
  296. # Project w/o pull-request
  297. self.session.commit()
  298. repo = pagure.lib.get_authorized_project(self.session, 'test')
  299. settings = repo.settings
  300. settings['pull_requests'] = False
  301. repo.settings = settings
  302. self.session.add(repo)
  303. self.session.commit()
  304. # Pull-request disabled
  305. output = self.app.post(
  306. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  307. self.assertEqual(output.status_code, 404)
  308. # Project w pull-request but only assignee can merge
  309. self.session.commit()
  310. repo = pagure.lib.get_authorized_project(self.session, 'test')
  311. settings['pull_requests'] = True
  312. settings['Only_assignee_can_merge_pull-request'] = True
  313. repo.settings = settings
  314. self.session.add(repo)
  315. self.session.commit()
  316. output = self.app.post(
  317. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  318. self.assertEqual(output.status_code, 200)
  319. output_text = output.get_data(as_text=True)
  320. self.assertIn(
  321. '<title>PR#1: PR from the feature branch - test\n - '
  322. 'Pagure</title>', output_text)
  323. self.assertIn(
  324. '<h3><span class="label label-default">PR#1</span>\n'
  325. ' PR from the feature branch\n <span class="pull-xs-right">',
  326. output_text)
  327. self.assertIn(
  328. '</button>\n This request must be '
  329. 'assigned to be merged', output_text)
  330. # PR assigned but not to this user
  331. self.session.commit()
  332. repo = pagure.lib.get_authorized_project(self.session, 'test')
  333. req = repo.requests[0]
  334. req.assignee_id = 2
  335. self.session.add(req)
  336. self.session.commit()
  337. output = self.app.post(
  338. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  339. self.assertEqual(output.status_code, 200)
  340. output_text = output.get_data(as_text=True)
  341. self.assertIn(
  342. '<h3><span class="label label-default">PR#1</span>\n'
  343. ' PR from the feature branch\n <span class="pull-xs-right">',
  344. output_text)
  345. self.assertIn(
  346. '</button>\n Only the assignee can '
  347. 'merge this review', output_text)
  348. # Project w/ minimal PR score
  349. self.session.commit()
  350. repo = pagure.lib.get_authorized_project(self.session, 'test')
  351. settings['Only_assignee_can_merge_pull-request'] = False
  352. settings['Minimum_score_to_merge_pull-request'] = 2
  353. repo.settings = settings
  354. self.session.add(repo)
  355. self.session.commit()
  356. output = self.app.post(
  357. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  358. self.assertEqual(output.status_code, 200)
  359. output_text = output.get_data(as_text=True)
  360. self.assertIn(
  361. '<h3><span class="label label-default">PR#1</span>\n'
  362. ' PR from the feature branch\n <span class="pull-xs-right">',
  363. output_text)
  364. self.assertIn(
  365. '</button>\n This request does not '
  366. 'have the minimum review score necessary to be merged',
  367. output_text)
  368. # Merge
  369. self.session.commit()
  370. repo = pagure.lib.get_authorized_project(self.session, 'test')
  371. settings['Minimum_score_to_merge_pull-request'] = -1
  372. repo.settings = settings
  373. self.session.add(repo)
  374. self.session.commit()
  375. output = self.app.post(
  376. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  377. self.assertEqual(output.status_code, 200)
  378. output = self.app.get('/test/commits')
  379. output_text = output.get_data(as_text=True)
  380. self.assertIn(
  381. '<title>Commits - test - Pagure</title>', output_text)
  382. self.assertIn(
  383. 'A commit on branch feature', output_text)
  384. self.assertNotIn(
  385. 'Merge #1 `PR from the feature branch`', output_text)
  386. # Check if the closing notification was added
  387. output = self.app.get('/test/pull-request/1')
  388. self.assertIn(
  389. '<small><p>Pull-Request has been merged by pingou</p></small>',
  390. output.get_data(as_text=True))
  391. @patch('pagure.lib.notify.send_email')
  392. def test_merge_request_pull_merge(self, send_email):
  393. """ Test the merge_request_pull endpoint with a merge PR. """
  394. send_email.return_value = True
  395. tests.create_projects(self.session)
  396. tests.create_projects_git(
  397. os.path.join(self.path, 'requests'), bare=True)
  398. self.set_up_git_repo(
  399. new_project=None, branch_from='feature', mtype='merge')
  400. user = tests.FakeUser()
  401. user.username = 'pingou'
  402. with tests.user_set(self.app.application, user):
  403. output = self.app.get('/test/pull-request/1')
  404. self.assertEqual(output.status_code, 200)
  405. csrf_token = self.get_csrf(output=output)
  406. data = {
  407. 'csrf_token': csrf_token,
  408. }
  409. # Merge
  410. output = self.app.post(
  411. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  412. self.assertEqual(output.status_code, 200)
  413. self.assertIn(
  414. '<title>Overview - test - Pagure</title>', output.get_data(as_text=True))
  415. # Check if the closing notification was added
  416. output = self.app.get('/test/pull-request/1')
  417. self.assertIn(
  418. '<small><p>Pull-Request has been merged by pingou</p></small>',
  419. output.get_data(as_text=True))
  420. @patch('pagure.lib.notify.send_email')
  421. def test_merge_request_pull_merge_with_delete_branch(self, send_email):
  422. """ Test the merge_request_pull endpoint with a merge PR and delete source branch. """
  423. send_email.return_value = True
  424. tests.create_projects(self.session)
  425. tests.create_projects_git(
  426. os.path.join(self.path, 'requests'), bare=True)
  427. self.set_up_git_repo(
  428. new_project=None, branch_from='feature-branch', mtype='merge')
  429. user = tests.FakeUser()
  430. user.username = 'pingou'
  431. with tests.user_set(self.app.application, user):
  432. output = self.app.get('/test/pull-request/1')
  433. self.assertEqual(output.status_code, 200)
  434. data = {
  435. 'csrf_token': self.get_csrf(output=output),
  436. 'delete_branch': True,
  437. }
  438. # Merge
  439. output = self.app.post(
  440. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  441. self.assertEqual(output.status_code, 200)
  442. output_text = output.get_data(as_text=True)
  443. self.assertIn(
  444. '<title>Overview - test - Pagure</title>', output_text)
  445. # Check the branch is not mentioned
  446. self.assertNotIn(
  447. '<a class="" href="/test/branch/feature-branch"', output_text)
  448. @patch('pagure.lib.notify.send_email')
  449. def test_merge_request_pull_conflicts(self, send_email):
  450. """ Test the merge_request_pull endpoint with a conflicting PR. """
  451. send_email.return_value = True
  452. tests.create_projects(self.session)
  453. tests.create_projects_git(
  454. os.path.join(self.path, 'requests'), bare=True)
  455. self.set_up_git_repo(
  456. new_project=None, branch_from='feature', mtype='conflicts')
  457. user = tests.FakeUser()
  458. user.username = 'pingou'
  459. with tests.user_set(self.app.application, user):
  460. output = self.app.get('/test/pull-request/1')
  461. self.assertEqual(output.status_code, 200)
  462. csrf_token = self.get_csrf(output=output)
  463. data = {
  464. 'csrf_token': csrf_token,
  465. }
  466. # Merge conflicts
  467. output = self.app.post(
  468. '/test/pull-request/1/merge', 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. '<h3><span class="label label-default">PR#1</span>\n'
  473. ' PR from the feature branch\n <span class="pull-xs-right">',
  474. output_text)
  475. self.assertIn('Merge conflicts!', output_text)
  476. @patch('pagure.lib.notify.send_email')
  477. def test_merge_request_pull_conflicts_with_delete_branch(self, send_email):
  478. """ Test the merge_request_pull endpoint with a conflicting PR and request deletion of branch. """
  479. send_email.return_value = True
  480. tests.create_projects(self.session)
  481. tests.create_projects_git(
  482. os.path.join(self.path, 'requests'), bare=True)
  483. self.set_up_git_repo(
  484. new_project=None, branch_from='feature-branch', mtype='conflicts')
  485. user = tests.FakeUser()
  486. user.username = 'pingou'
  487. with tests.user_set(self.app.application, user):
  488. output = self.app.get('/test/pull-request/1')
  489. self.assertEqual(output.status_code, 200)
  490. data = {
  491. 'csrf_token': self.get_csrf(output=output),
  492. 'delete_branch': True,
  493. }
  494. # Merge conflicts
  495. output = self.app.post(
  496. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  497. self.assertEqual(output.status_code, 200)
  498. output_text = output.get_data(as_text=True)
  499. self.assertIn(
  500. '<h3><span class="label label-default">PR#1</span>\n'
  501. ' PR from the feature-branch branch\n <span class="pull-xs-right">',
  502. output_text)
  503. self.assertIn('Merge conflicts!', output_text)
  504. # Check the branch still exists
  505. output = self.app.get('/test/branches')
  506. self.assertIn('feature-branch', output.get_data(as_text=True))
  507. @patch('pagure.lib.notify.send_email')
  508. def test_merge_request_pull_nochange(self, send_email):
  509. """ Test the merge_request_pull endpoint. """
  510. send_email.return_value = True
  511. tests.create_projects(self.session)
  512. tests.create_projects_git(
  513. os.path.join(self.path, 'requests'), bare=True)
  514. self.set_up_git_repo(
  515. new_project=None, branch_from='master', mtype='nochanges')
  516. user = tests.FakeUser()
  517. user.username = 'pingou'
  518. with tests.user_set(self.app.application, user):
  519. output = self.app.get('/test/pull-request/1')
  520. self.assertEqual(output.status_code, 200)
  521. csrf_token = self.get_csrf(output=output)
  522. data = {
  523. 'csrf_token': csrf_token,
  524. }
  525. # Nothing to merge
  526. output = self.app.post(
  527. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  528. self.assertEqual(output.status_code, 200)
  529. output_text = output.get_data(as_text=True)
  530. self.assertIn(
  531. '<h3><span class="label label-default">PR#1</span>\n'
  532. ' <span class="label label-success">Merged</span>',
  533. output_text)
  534. self.assertIn('Nothing to do, changes were already merged',
  535. output_text)
  536. # Check if the closing notification was added
  537. output = self.app.get('/test/pull-request/1')
  538. self.assertIn(
  539. '<small><p>Pull-Request has been merged by pingou</p></small>',
  540. output.get_data(as_text=True))
  541. @patch('pagure.lib.notify.send_email')
  542. def test_request_pull_close(self, send_email):
  543. """ Test the request_pull endpoint with a closed PR. """
  544. send_email.return_value = True
  545. self.test_merge_request_pull_FF()
  546. output = self.app.get('/test/pull-request/1')
  547. self.assertEqual(output.status_code, 200)
  548. output_text = output.get_data(as_text=True)
  549. self.assertIn(
  550. '<h3><span class="label label-default">PR#1</span>\n'
  551. ' <span class="label label-success">', output_text)
  552. self.assertIn('<div>Merged by\n', output_text)
  553. self.assertIn(
  554. 'title="View file as of 2a552b">sources</a>', output_text)
  555. @patch('pagure.lib.notify.send_email')
  556. def test_request_pull_disabled(self, send_email):
  557. """ Test the request_pull endpoint with PR disabled. """
  558. send_email.return_value = True
  559. tests.create_projects(self.session)
  560. tests.create_projects_git(
  561. os.path.join(self.path, 'requests'), bare=True)
  562. self.set_up_git_repo(new_project=None, branch_from='feature')
  563. # Project w/o pull-request
  564. repo = pagure.lib.get_authorized_project(self.session, 'test')
  565. settings = repo.settings
  566. settings['pull_requests'] = False
  567. repo.settings = settings
  568. self.session.add(repo)
  569. self.session.commit()
  570. output = self.app.get('/test/pull-request/1')
  571. self.assertEqual(output.status_code, 404)
  572. @patch('pagure.lib.notify.send_email')
  573. @patch('pagure.lib.git.update_pull_ref')
  574. def test_request_pull_empty_repo(self, send_email, update_pull_ref):
  575. """ Test the request_pull endpoint against an empty repo. """
  576. # Mock update_pull_ref or the repo won't be empty anymore
  577. # (the PR will have been pushed to refs/pull)
  578. send_email.return_value = True
  579. tests.create_projects(self.session)
  580. item = pagure.lib.model.Project(
  581. user_id=2, # foo
  582. name='test',
  583. description='test project #1',
  584. hook_token='aaabbb',
  585. is_fork=True,
  586. parent_id=1,
  587. )
  588. self.session.add(item)
  589. self.session.commit()
  590. tests.create_projects_git(
  591. os.path.join(self.path, 'requests'), bare=True)
  592. tests.create_projects_git(
  593. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  594. # Create a git repo to play with
  595. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  596. self.assertFalse(os.path.exists(gitrepo))
  597. os.makedirs(gitrepo)
  598. repo = pygit2.init_repository(gitrepo, bare=True)
  599. # Create a fork of this repo
  600. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  601. gitrepo = os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git')
  602. new_repo = pygit2.clone_repository(gitrepo, newpath)
  603. # Edit the sources file again
  604. with open(os.path.join(newpath, 'sources'), 'w') as stream:
  605. stream.write('foo\n bar\nbaz\n boose')
  606. new_repo.index.add('sources')
  607. new_repo.index.write()
  608. # Commits the files added
  609. tree = new_repo.index.write_tree()
  610. author = pygit2.Signature(
  611. 'Alice Author', 'alice@authors.tld')
  612. committer = pygit2.Signature(
  613. 'Cecil Committer', 'cecil@committers.tld')
  614. new_repo.create_commit(
  615. 'refs/heads/feature',
  616. author,
  617. committer,
  618. 'A commit on branch feature',
  619. tree,
  620. []
  621. )
  622. refname = 'refs/heads/feature:refs/heads/feature'
  623. ori_remote = new_repo.remotes[0]
  624. PagureRepo.push(ori_remote, refname)
  625. # Create a PR for these changes
  626. project = pagure.lib.get_authorized_project(self.session, 'test')
  627. req = pagure.lib.new_pull_request(
  628. session=self.session,
  629. repo_from=item,
  630. branch_from='feature',
  631. repo_to=project,
  632. branch_to='master',
  633. title='PR from the feature branch',
  634. user='pingou',
  635. requestfolder=None,
  636. )
  637. self.session.commit()
  638. self.assertEqual(req.id, 1)
  639. self.assertEqual(req.title, 'PR from the feature branch')
  640. output = self.app.get('/test/pull-request/1')
  641. self.assertEqual(output.status_code, 200)
  642. output_text = output.get_data(as_text=True)
  643. self.assertIn(
  644. '<h3><span class="label label-default">PR#1</span>\n'
  645. ' PR from the feature branch\n</h3>', output_text)
  646. self.assertTrue(
  647. output_text.count(
  648. '<span class="commitdate" title='), 1)
  649. self.assertTrue(update_pull_ref.called)
  650. shutil.rmtree(newpath)
  651. @patch('pagure.lib.notify.send_email')
  652. def test_request_pull_empty_fork(self, send_email):
  653. """ Test the request_pull endpoint from an empty fork. """
  654. send_email.return_value = True
  655. tests.create_projects(self.session)
  656. item = pagure.lib.model.Project(
  657. user_id=2, # foo
  658. name='test',
  659. description='test project #1',
  660. hook_token='aaabbb',
  661. is_fork=True,
  662. parent_id=1,
  663. )
  664. self.session.add(item)
  665. self.session.commit()
  666. tests.create_projects_git(
  667. os.path.join(self.path, 'requests'), bare=True)
  668. tests.create_projects_git(
  669. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  670. # Create a git repo to play with
  671. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  672. self.assertFalse(os.path.exists(gitrepo))
  673. os.makedirs(gitrepo)
  674. repo = pygit2.init_repository(gitrepo, bare=True)
  675. # Create a fork of this repo
  676. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  677. gitrepo = os.path.join(
  678. self.path, 'repos', 'forks', 'foo', 'test.git')
  679. new_repo = pygit2.clone_repository(gitrepo, newpath)
  680. # Create a PR for these "changes" (there are none, both repos are
  681. # empty)
  682. project = pagure.lib.get_authorized_project(self.session, 'test')
  683. req = pagure.lib.new_pull_request(
  684. session=self.session,
  685. repo_from=item,
  686. branch_from='feature',
  687. repo_to=project,
  688. branch_to='master',
  689. title='PR from the feature branch',
  690. user='pingou',
  691. requestfolder=None,
  692. )
  693. self.session.commit()
  694. self.assertEqual(req.id, 1)
  695. self.assertEqual(req.title, 'PR from the feature branch')
  696. output = self.app.get('/test/pull-request/1', follow_redirects=True)
  697. self.assertEqual(output.status_code, 200)
  698. output_text = output.get_data(as_text=True)
  699. self.assertIn(
  700. '<title>PR#1: PR from the feature branch - test\n - Pagure</title>',
  701. output_text)
  702. self.assertIn(
  703. '</button>\n Fork is empty, there are no '
  704. 'commits to create a pull request with',
  705. output_text)
  706. shutil.rmtree(newpath)
  707. @patch('pagure.lib.notify.send_email')
  708. def test_request_pulls_order(self, send_email):
  709. """Test the request_pulls
  710. i.e Make sure that the results are displayed
  711. in the order required by the user"""
  712. send_email.return_value = True
  713. #Initially no project
  714. output = self.app.get('/test/pull-requests')
  715. self.assertEqual(output.status_code, 404)
  716. tests.create_projects(self.session)
  717. tests.create_projects_git(
  718. os.path.join(self.path, 'repos'), bare=True)
  719. repo = pagure.lib.get_authorized_project(self.session, 'test')
  720. item = pagure.lib.model.Project(
  721. user_id=2,
  722. name='test',
  723. description='test project #1',
  724. hook_token='aaabbb',
  725. is_fork=True,
  726. parent_id=1,
  727. )
  728. self.session.add(item)
  729. self.session.commit()
  730. # create PR's to play with
  731. # PR-1
  732. req = pagure.lib.new_pull_request(
  733. session=self.session,
  734. repo_to=repo,
  735. repo_from=item,
  736. branch_from='feature',
  737. branch_to='master',
  738. title='PR from the feature branch',
  739. user='pingou',
  740. status='Open',
  741. requestfolder=None,
  742. )
  743. self.session.commit()
  744. self.assertEqual(req.id, 1)
  745. self.assertEqual(req.title, 'PR from the feature branch')
  746. # PR-2
  747. req = pagure.lib.new_pull_request(
  748. session=self.session,
  749. repo_to=repo,
  750. branch_to='master',
  751. branch_from='feature',
  752. repo_from=item,
  753. title='test PR',
  754. user='pingou',
  755. status='Open',
  756. requestfolder=None,
  757. )
  758. self.session.commit()
  759. self.assertEqual(req.title, 'test PR')
  760. # PR-3
  761. req = pagure.lib.new_pull_request(
  762. session=self.session,
  763. repo_to=repo,
  764. branch_from='feature',
  765. branch_to='master',
  766. repo_from=item,
  767. title='test Invalid PR',
  768. user='pingou',
  769. status='Closed',
  770. requestfolder=None,
  771. )
  772. self.session.commit()
  773. self.assertEqual(req.title, 'test Invalid PR')
  774. # PR-4
  775. req = pagure.lib.new_pull_request(
  776. session=self.session,
  777. repo_to=repo,
  778. branch_from='feature',
  779. title='test PR for sort',
  780. repo_from=item,
  781. user='pingou',
  782. branch_to='master',
  783. status='Open',
  784. requestfolder=None,
  785. )
  786. self.session.commit()
  787. self.assertEqual(req.title, 'test PR for sort')
  788. # sort by last_updated
  789. output = self.app.get('/test/pull-requests?order_key=last_updated')
  790. output_text = output.get_data(as_text=True)
  791. tr_elements = re.findall('<tr>(.*?)</tr>', output_text, re.M | re.S)
  792. self.assertEqual(output.status_code, 200)
  793. arrowed_th = ('Modified</a>\n <span class="oi" data-glyph='
  794. '"arrow-thick-bottom"></span>')
  795. # First table row is the header
  796. self.assertIn(arrowed_th, tr_elements[0])
  797. # Make sure that issue four is first since it was modified last
  798. self.assertIn('href="/test/pull-request/4"', tr_elements[1])
  799. self.assertIn('href="/test/pull-request/2"', tr_elements[2])
  800. self.assertIn('href="/test/pull-request/1"', tr_elements[3])
  801. pr_one = pagure.lib.search_pull_requests(
  802. self.session, project_id=1, requestid=1)
  803. pr_one.last_updated = datetime.utcnow() + timedelta(seconds=2)
  804. self.session.add(pr_one)
  805. self.session.commit()
  806. # sort by last_updated
  807. output = self.app.get('/test/pull-requests?order_key=last_updated')
  808. output_text = output.get_data(as_text=True)
  809. tr_elements = re.findall(r'<tr>(.*?)</tr>', output_text, re.M | re.S)
  810. self.assertEqual(output.status_code, 200)
  811. # Make sure that PR four is first since it was modified last
  812. self.assertIn('href="/test/pull-request/1"', tr_elements[1])
  813. # Make sure that PR two is second since it was modified second
  814. self.assertIn('href="/test/pull-request/4"', tr_elements[2])
  815. # Make sure that PR one is last since it was modified first
  816. self.assertIn('href="/test/pull-request/2"', tr_elements[3])
  817. # Now query so that the results are ascending
  818. output = self.app.get('/test/pull-requests?'
  819. 'order_key=last_updated&order=asc')
  820. output_text = output.get_data(as_text=True)
  821. tr_elements = re.findall(r'<tr>(.*?)</tr>', output_text, re.M | re.S)
  822. arrowed_th = ('Modified</a>\n <span class="oi" data-glyph='
  823. '"arrow-thick-top"></span>')
  824. self.assertIn(arrowed_th, tr_elements[0])
  825. self.assertIn('href="/test/pull-request/2"', tr_elements[1])
  826. self.assertIn('href="/test/pull-request/4"', tr_elements[2])
  827. self.assertIn('href="/test/pull-request/1"', tr_elements[3])
  828. @patch('pagure.lib.notify.send_email')
  829. def test_request_pulls(self, send_email):
  830. """ Test the request_pulls endpoint. """
  831. send_email.return_value = True
  832. # No such project
  833. output = self.app.get('/test/pull-requests')
  834. self.assertEqual(output.status_code, 404)
  835. tests.create_projects(self.session)
  836. tests.create_projects_git(
  837. os.path.join(self.path, 'repos'), bare=True)
  838. output = self.app.get('/test/pull-requests')
  839. self.assertEqual(output.status_code, 200)
  840. output_text = output.get_data(as_text=True)
  841. self.assertIn(
  842. '<h2 class="p-b-1">\n 0 Pull Requests (of 0)\n </h2>',
  843. output_text)
  844. # Open is primary
  845. self.assertIn(
  846. '<a class="btn btn-primary btn-sm" '
  847. 'href="/test/pull-requests">Open</a>', output_text)
  848. self.assertIn(
  849. '<a class="btn btn-outline-dark btn-sm" '
  850. 'href="/test/pull-requests?status=0">Closed</a>', output_text)
  851. self.set_up_git_repo(new_project=None, branch_from='feature')
  852. output = self.app.get('/test/pull-requests')
  853. self.assertEqual(output.status_code, 200)
  854. output_text = output.get_data(as_text=True)
  855. self.assertIn(
  856. '<h2 class="p-b-1">\n 1 Pull Requests (of 1)\n </h2>',
  857. output_text)
  858. # Open is primary
  859. self.assertIn(
  860. '<a class="btn btn-primary btn-sm" '
  861. 'href="/test/pull-requests">Open</a>', output_text)
  862. self.assertIn(
  863. '<a class="btn btn-outline-dark btn-sm" '
  864. 'href="/test/pull-requests?status=0">Closed</a>', output_text)
  865. output = self.app.get('/test/pull-requests?status=Closed')
  866. self.assertEqual(output.status_code, 200)
  867. output_text = output.get_data(as_text=True)
  868. self.assertIn(
  869. '<h2 class="p-b-1">\n 0 Closed Pull Requests (of 0)\n </h2>',
  870. output_text)
  871. # Close is primary
  872. self.assertIn(
  873. '<a class="btn btn-secondary btn-sm" '
  874. 'href="/test/pull-requests">Open</a>', output_text)
  875. self.assertIn(
  876. '<a class="btn btn-primary btn-sm" '
  877. 'href="/test/pull-requests?status=0">Closed</a>', output_text)
  878. output = self.app.get('/test/pull-requests?status=0')
  879. self.assertEqual(output.status_code, 200)
  880. output_text = output.get_data(as_text=True)
  881. self.assertIn(
  882. '<h2 class="p-b-1">\n 0 Closed/Merged Pull Requests (of 0)\n </h2>',
  883. output_text)
  884. # Close is primary
  885. self.assertIn(
  886. '<a class="btn btn-secondary btn-sm" '
  887. 'href="/test/pull-requests">Open</a>', output_text)
  888. self.assertIn(
  889. '<a class="btn btn-primary btn-sm" '
  890. 'href="/test/pull-requests?status=0">Closed</a>', output_text)
  891. # Project w/o pull-request
  892. repo = pagure.lib.get_authorized_project(self.session, 'test')
  893. settings = repo.settings
  894. settings['pull_requests'] = False
  895. repo.settings = settings
  896. self.session.add(repo)
  897. self.session.commit()
  898. output = self.app.get('/test/pull-requests')
  899. self.assertEqual(output.status_code, 404)
  900. @patch('pagure.lib.notify.send_email')
  901. def test_request_pull_patch(self, send_email):
  902. """ Test the request_pull_patch endpoint. """
  903. send_email.return_value = True
  904. output = self.app.get('/test/pull-request/1.patch')
  905. self.assertEqual(output.status_code, 404)
  906. tests.create_projects(self.session)
  907. tests.create_projects_git(
  908. os.path.join(self.path, 'requests'), bare=True)
  909. self.set_up_git_repo(
  910. new_project=None, branch_from='feature', mtype='merge')
  911. output = self.app.get('/test/pull-request/100.patch')
  912. self.assertEqual(output.status_code, 404)
  913. output = self.app.get('/test/pull-request/1.patch')
  914. self.assertEqual(output.status_code, 200)
  915. npatch = []
  916. for row in output.get_data(as_text=True).split('\n'):
  917. if row.startswith('Date:'):
  918. continue
  919. if row.startswith('From '):
  920. row = row.split(' ', 2)[2]
  921. npatch.append(row)
  922. exp = """Mon Sep 17 00:00:00 2001
  923. From: Alice Author <alice@authors.tld>
  924. Subject: A commit on branch feature
  925. ---
  926. diff --git a/.gitignore b/.gitignore
  927. new file mode 100644
  928. index 0000000..e4e5f6c
  929. --- /dev/null
  930. +++ b/.gitignore
  931. @@ -0,0 +1 @@
  932. +*~
  933. \ No newline at end of file
  934. diff --git a/sources b/sources
  935. index 9f44358..2a552bb 100644
  936. --- a/sources
  937. +++ b/sources
  938. @@ -1,2 +1,4 @@
  939. foo
  940. - bar
  941. \ No newline at end of file
  942. + bar
  943. +baz
  944. + boose
  945. \ No newline at end of file
  946. """
  947. patch = '\n'.join(npatch)
  948. #print patch
  949. self.assertEqual(patch, exp)
  950. # Project w/o pull-request
  951. repo = pagure.lib.get_authorized_project(self.session, 'test')
  952. settings = repo.settings
  953. settings['pull_requests'] = False
  954. repo.settings = settings
  955. self.session.add(repo)
  956. self.session.commit()
  957. output = self.app.get('/test/pull-request/1.patch')
  958. self.assertEqual(output.status_code, 404)
  959. @patch('pagure.lib.notify.send_email')
  960. def test_request_pull_diff(self, send_email):
  961. """ Test the request_pull_patch endpoint. """
  962. send_email.return_value = True
  963. output = self.app.get('/test/pull-request/1.diff')
  964. self.assertEqual(output.status_code, 404)
  965. tests.create_projects(self.session)
  966. tests.create_projects_git(
  967. os.path.join(self.path, 'requests'), bare=True)
  968. self.set_up_git_repo(
  969. new_project=None, branch_from='feature', mtype='merge')
  970. output = self.app.get('/test/pull-request/100.diff')
  971. self.assertEqual(output.status_code, 404)
  972. output = self.app.get('/test/pull-request/1.diff')
  973. self.assertEqual(output.status_code, 200)
  974. exp = """diff --git a/.gitignore b/.gitignore
  975. new file mode 100644
  976. index 0000000..e4e5f6c
  977. --- /dev/null
  978. +++ b/.gitignore
  979. @@ -0,0 +1 @@
  980. +*~
  981. \ No newline at end of file
  982. diff --git a/sources b/sources
  983. index 9f44358..2a552bb 100644
  984. --- a/sources
  985. +++ b/sources
  986. @@ -1,2 +1,4 @@
  987. foo
  988. - bar
  989. \ No newline at end of file
  990. + bar
  991. +baz
  992. + boose
  993. \ No newline at end of file
  994. """
  995. self.assertEqual(output.get_data(as_text=True), exp)
  996. # Project w/o pull-request
  997. repo = pagure.lib.get_authorized_project(self.session, 'test')
  998. settings = repo.settings
  999. settings['pull_requests'] = False
  1000. repo.settings = settings
  1001. self.session.add(repo)
  1002. self.session.commit()
  1003. output = self.app.get('/test/pull-request/1.diff')
  1004. self.assertEqual(output.status_code, 404)
  1005. @patch('pagure.lib.notify.send_email')
  1006. def test_request_pull_patch_close(self, send_email):
  1007. """ Test the request_pull_patch endpoint with a closed PR. """
  1008. send_email.return_value = True
  1009. self.test_merge_request_pull_FF()
  1010. output = self.app.get('/test/pull-request/1.patch')
  1011. self.assertEqual(output.status_code, 200)
  1012. npatch = []
  1013. for row in output.get_data(as_text=True).split('\n'):
  1014. if row.startswith('Date:'):
  1015. continue
  1016. if row.startswith('From '):
  1017. row = row.split(' ', 2)[2]
  1018. npatch.append(row)
  1019. exp = """Mon Sep 17 00:00:00 2001
  1020. From: Alice Author <alice@authors.tld>
  1021. Subject: A commit on branch feature
  1022. ---
  1023. diff --git a/sources b/sources
  1024. index 9f44358..2a552bb 100644
  1025. --- a/sources
  1026. +++ b/sources
  1027. @@ -1,2 +1,4 @@
  1028. foo
  1029. - bar
  1030. \ No newline at end of file
  1031. + bar
  1032. +baz
  1033. + boose
  1034. \ No newline at end of file
  1035. """
  1036. patch = '\n'.join(npatch)
  1037. #print patch
  1038. self.assertEqual(patch, exp)
  1039. @patch('pagure.lib.notify.send_email')
  1040. @patch('pagure.lib.git.update_pull_ref')
  1041. def test_request_pull_patch_empty_repo(self, send_email, update_pull_ref):
  1042. """ Test the request_pull_patch endpoint against an empty repo. """
  1043. # Mock update_pull_ref or the repo won't be empty anymore
  1044. # (the PR will have been pushed to refs/pull)
  1045. send_email.return_value = True
  1046. tests.create_projects(self.session)
  1047. item = pagure.lib.model.Project(
  1048. user_id=2, # foo
  1049. name='test',
  1050. description='test project #1',
  1051. hook_token='aaabbb',
  1052. is_fork=True,
  1053. parent_id=1,
  1054. )
  1055. self.session.add(item)
  1056. self.session.commit()
  1057. tests.create_projects_git(
  1058. os.path.join(self.path, 'requests'), bare=True)
  1059. tests.create_projects_git(
  1060. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  1061. # Create a git repo to play with
  1062. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1063. self.assertFalse(os.path.exists(gitrepo))
  1064. os.makedirs(gitrepo)
  1065. repo = pygit2.init_repository(gitrepo, bare=True)
  1066. # Create a fork of this repo
  1067. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  1068. gitrepo = os.path.join(
  1069. self.path, 'repos', 'forks', 'foo', 'test.git')
  1070. new_repo = pygit2.clone_repository(gitrepo, newpath)
  1071. # Edit the sources file again
  1072. with open(os.path.join(newpath, 'sources'), 'w') as stream:
  1073. stream.write('foo\n bar\nbaz\n boose')
  1074. new_repo.index.add('sources')
  1075. new_repo.index.write()
  1076. # Commits the files added
  1077. tree = new_repo.index.write_tree()
  1078. author = pygit2.Signature(
  1079. 'Alice Author', 'alice@authors.tld')
  1080. committer = pygit2.Signature(
  1081. 'Cecil Committer', 'cecil@committers.tld')
  1082. new_repo.create_commit(
  1083. 'refs/heads/feature',
  1084. author,
  1085. committer,
  1086. 'A commit on branch feature',
  1087. tree,
  1088. []
  1089. )
  1090. refname = 'refs/heads/feature:refs/heads/feature'
  1091. ori_remote = new_repo.remotes[0]
  1092. PagureRepo.push(ori_remote, refname)
  1093. # Create a PR for these "changes" (there are none, both repos are
  1094. # empty)
  1095. project = pagure.lib.get_authorized_project(self.session, 'test')
  1096. req = pagure.lib.new_pull_request(
  1097. session=self.session,
  1098. repo_from=item,
  1099. branch_from='feature',
  1100. repo_to=project,
  1101. branch_to='master',
  1102. title='PR from the feature branch',
  1103. user='pingou',
  1104. requestfolder=None,
  1105. )
  1106. self.session.commit()
  1107. self.assertEqual(req.id, 1)
  1108. self.assertEqual(req.title, 'PR from the feature branch')
  1109. output = self.app.get(
  1110. '/test/pull-request/1.patch', follow_redirects=True)
  1111. self.assertEqual(output.status_code, 200)
  1112. npatch = []
  1113. for row in output.get_data(as_text=True).split('\n'):
  1114. if row.startswith('Date:'):
  1115. continue
  1116. if row.startswith('From '):
  1117. row = row.split(' ', 2)[2]
  1118. npatch.append(row)
  1119. exp = """Mon Sep 17 00:00:00 2001
  1120. From: Alice Author <alice@authors.tld>
  1121. Subject: A commit on branch feature
  1122. ---
  1123. diff --git a/sources b/sources
  1124. new file mode 100644
  1125. index 0000000..2a552bb
  1126. --- /dev/null
  1127. +++ b/sources
  1128. @@ -0,0 +1,4 @@
  1129. +foo
  1130. + bar
  1131. +baz
  1132. + boose
  1133. \ No newline at end of file
  1134. """
  1135. patch = '\n'.join(npatch)
  1136. #print patch
  1137. self.assertEqual(patch, exp)
  1138. shutil.rmtree(newpath)
  1139. @patch('pagure.lib.notify.send_email')
  1140. def test_request_pull_patch_empty_fork(self, send_email):
  1141. """ Test the request_pull_patch endpoint from an empty fork. """
  1142. send_email.return_value = True
  1143. tests.create_projects(self.session)
  1144. item = pagure.lib.model.Project(
  1145. user_id=2, # foo
  1146. name='test',
  1147. description='test project #1',
  1148. hook_token='aaabbb',
  1149. is_fork=True,
  1150. parent_id=1,
  1151. )
  1152. self.session.add(item)
  1153. self.session.commit()
  1154. tests.create_projects_git(
  1155. os.path.join(self.path, 'requests'), bare=True)
  1156. tests.create_projects_git(
  1157. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  1158. # Create a git repo to play with
  1159. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1160. self.assertFalse(os.path.exists(gitrepo))
  1161. os.makedirs(gitrepo)
  1162. repo = pygit2.init_repository(gitrepo, bare=True)
  1163. # Create a fork of this repo
  1164. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  1165. gitrepo = os.path.join(
  1166. self.path, 'repos', 'forks', 'foo', 'test.git')
  1167. new_repo = pygit2.clone_repository(gitrepo, newpath)
  1168. # Create a PR for these "changes" (there are none, both repos are
  1169. # empty)
  1170. project = pagure.lib.get_authorized_project(self.session, 'test')
  1171. req = pagure.lib.new_pull_request(
  1172. session=self.session,
  1173. repo_from=item,
  1174. branch_from='feature',
  1175. repo_to=project,
  1176. branch_to='master',
  1177. title='PR from the feature branch',
  1178. user='pingou',
  1179. requestfolder=None,
  1180. )
  1181. self.session.commit()
  1182. self.assertEqual(req.id, 1)
  1183. self.assertEqual(req.title, 'PR from the feature branch')
  1184. output = self.app.get('/test/pull-request/1.patch',
  1185. follow_redirects=True)
  1186. self.assertEqual(output.status_code, 200)
  1187. output_text = output.get_data(as_text=True)
  1188. self.assertIn(
  1189. '<title>Overview - test - Pagure</title>',
  1190. output_text)
  1191. self.assertIn(
  1192. '</button>\n Fork is empty, there are no '
  1193. 'commits to create a pull request with',
  1194. output_text)
  1195. shutil.rmtree(newpath)
  1196. @patch('pagure.lib.notify.send_email')
  1197. def test_cancel_request_pull(self, send_email):
  1198. """ Test the cancel_request_pull endpoint. """
  1199. send_email.return_value = True
  1200. tests.create_projects(self.session)
  1201. tests.create_projects_git(
  1202. os.path.join(self.path, 'requests'), bare=True)
  1203. self.set_up_git_repo(
  1204. new_project=None, branch_from='feature', mtype='merge')
  1205. user = tests.FakeUser()
  1206. with tests.user_set(self.app.application, user):
  1207. output = self.app.post('/test/pull-request/cancel/1')
  1208. self.assertEqual(output.status_code, 302)
  1209. output = self.app.post(
  1210. '/test/pull-request/cancel/1', follow_redirects=True)
  1211. self.assertEqual(output.status_code, 200)
  1212. output_text = output.get_data(as_text=True)
  1213. self.assertIn(
  1214. '<title>Overview - test - Pagure</title>', output_text)
  1215. self.assertIn(
  1216. '</button>\n Invalid input submitted',
  1217. output_text)
  1218. output = self.app.get('/test/pull-request/1')
  1219. self.assertEqual(output.status_code, 200)
  1220. csrf_token = self.get_csrf(output=output)
  1221. data = {
  1222. 'csrf_token': csrf_token,
  1223. }
  1224. # Invalid project
  1225. output = self.app.post(
  1226. '/foo/pull-request/cancel/1', data=data,
  1227. follow_redirects=True)
  1228. self.assertEqual(output.status_code, 404)
  1229. # Invalid PR id
  1230. output = self.app.post(
  1231. '/test/pull-request/cancel/100', data=data,
  1232. follow_redirects=True)
  1233. self.assertEqual(output.status_code, 404)
  1234. # Invalid user for this project
  1235. output = self.app.post(
  1236. '/test/pull-request/cancel/1', data=data,
  1237. follow_redirects=True)
  1238. self.assertEqual(output.status_code, 403)
  1239. user.username = 'pingou'
  1240. with tests.user_set(self.app.application, user):
  1241. # Project w/o pull-request
  1242. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1243. settings = repo.settings
  1244. settings['pull_requests'] = False
  1245. repo.settings = settings
  1246. self.session.add(repo)
  1247. self.session.commit()
  1248. output = self.app.post(
  1249. '/test/pull-request/cancel/1', data=data,
  1250. follow_redirects=True)
  1251. self.assertEqual(output.status_code, 404)
  1252. # Project w/ pull-request
  1253. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1254. settings = repo.settings
  1255. settings['pull_requests'] = True
  1256. repo.settings = settings
  1257. self.session.add(repo)
  1258. self.session.commit()
  1259. output = self.app.post(
  1260. '/test/pull-request/cancel/1', data=data,
  1261. follow_redirects=True)
  1262. self.assertEqual(output.status_code, 200)
  1263. output_text = output.get_data(as_text=True)
  1264. self.assertIn(
  1265. '<title>Overview - test - Pagure</title>', output_text)
  1266. self.assertIn(
  1267. '</button>\n Pull request canceled!',
  1268. output_text)
  1269. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  1270. def test_update_pull_requests_assign(self):
  1271. """ Test the update_pull_requests endpoint when assigning a PR.
  1272. """
  1273. tests.create_projects(self.session)
  1274. tests.create_projects_git(
  1275. os.path.join(self.path, 'requests'), bare=True)
  1276. self.set_up_git_repo(new_project=None, branch_from='feature')
  1277. user = tests.FakeUser()
  1278. user.username = 'pingou'
  1279. with tests.user_set(self.app.application, user):
  1280. # No such project
  1281. output = self.app.post('/foo/pull-request/1/update')
  1282. self.assertEqual(output.status_code, 404)
  1283. output = self.app.post('/test/pull-request/100/update')
  1284. self.assertEqual(output.status_code, 404)
  1285. # Invalid input
  1286. output = self.app.post(
  1287. '/test/pull-request/1/update', follow_redirects=True)
  1288. self.assertEqual(output.status_code, 200)
  1289. output_text = output.get_data(as_text=True)
  1290. self.assertIn(
  1291. '<title>PR#1: PR from the feature branch - test\n - '
  1292. 'Pagure</title>', output_text)
  1293. self.assertIn(
  1294. '<h3><span class="label label-default">PR#1</span>\n'
  1295. ' PR from the feature branch\n', output_text)
  1296. self.assertNotIn(
  1297. '</button>\n Request assigned',
  1298. output_text)
  1299. output = self.app.get('/test/pull-request/1')
  1300. self.assertEqual(output.status_code, 200)
  1301. csrf_token = self.get_csrf(output=output)
  1302. data = {
  1303. 'user': 'pingou',
  1304. }
  1305. # No CSRF
  1306. output = self.app.post(
  1307. '/test/pull-request/1/update', data=data,
  1308. follow_redirects=True)
  1309. self.assertEqual(output.status_code, 200)
  1310. output_text = output.get_data(as_text=True)
  1311. self.assertIn(
  1312. '<title>PR#1: PR from the feature branch - test\n - '
  1313. 'Pagure</title>', output_text)
  1314. self.assertIn(
  1315. '<h3><span class="label label-default">PR#1</span>\n'
  1316. ' PR from the feature branch\n', output_text)
  1317. self.assertNotIn(
  1318. '</button>\n Request assigned',
  1319. output_text)
  1320. # Invalid assignee
  1321. data = {
  1322. 'csrf_token': csrf_token,
  1323. 'user': 'bar',
  1324. }
  1325. output = self.app.post(
  1326. '/test/pull-request/1/update', data=data,
  1327. follow_redirects=True)
  1328. self.assertEqual(output.status_code, 200)
  1329. output_text = output.get_data(as_text=True)
  1330. self.assertIn(
  1331. '<title>PR#1: PR from the feature branch - test\n - '
  1332. 'Pagure</title>', output_text)
  1333. self.assertIn(
  1334. '<h3><span class="label label-default">PR#1</span>\n'
  1335. ' PR from the feature branch\n', output_text)
  1336. self.assertIn(
  1337. '</button>\n No user &#34;bar&#34; found',
  1338. output_text)
  1339. # Assign the PR
  1340. data = {
  1341. 'csrf_token': csrf_token,
  1342. 'user': 'pingou',
  1343. }
  1344. user.username = 'foo'
  1345. with tests.user_set(self.app.application, user):
  1346. output = self.app.post(
  1347. '/test/pull-request/1/update', data=data,
  1348. follow_redirects=True)
  1349. self.assertEqual(output.status_code, 403)
  1350. user.username = 'pingou'
  1351. with tests.user_set(self.app.application, user):
  1352. output = self.app.post(
  1353. '/test/pull-request/1/update', data=data,
  1354. follow_redirects=True)
  1355. self.assertEqual(output.status_code, 200)
  1356. output_text = output.get_data(as_text=True)
  1357. self.assertIn(
  1358. '<title>PR#1: PR from the feature branch - test\n - '
  1359. 'Pagure</title>', output_text)
  1360. self.assertIn(
  1361. '<h3><span class="label label-default">PR#1</span>\n'
  1362. ' PR from the feature branch\n', output_text)
  1363. self.assertIn(
  1364. '</button>\n Request assigned',
  1365. output_text)
  1366. # Pull-Request closed
  1367. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1368. req = repo.requests[0]
  1369. req.status = 'Closed'
  1370. req.closed_by_in = 1
  1371. self.session.add(req)
  1372. self.session.commit()
  1373. output = self.app.post(
  1374. '/test/pull-request/1/update', data=data,
  1375. follow_redirects=True)
  1376. self.assertEqual(output.status_code, 403)
  1377. # Project w/o pull-request
  1378. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1379. settings = repo.settings
  1380. settings['pull_requests'] = False
  1381. repo.settings = settings
  1382. self.session.add(repo)
  1383. self.session.commit()
  1384. output = self.app.post(
  1385. '/test/pull-request/1/update', data=data,
  1386. follow_redirects=True)
  1387. self.assertEqual(output.status_code, 404)
  1388. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  1389. def test_update_pull_requests_tag(self):
  1390. """ Test the update_pull_requests endpoint when tagging a PR.
  1391. """
  1392. tests.create_projects(self.session)
  1393. tests.create_projects_git(
  1394. os.path.join(self.path, 'requests'), bare=True)
  1395. self.set_up_git_repo(new_project=None, branch_from='feature')
  1396. user = tests.FakeUser()
  1397. user.username = 'pingou'
  1398. with tests.user_set(self.app.application, user):
  1399. output = self.app.get('/test/pull-request/1')
  1400. self.assertEqual(output.status_code, 200)
  1401. csrf_token = self.get_csrf(output=output)
  1402. data = {
  1403. 'tag': 'black',
  1404. }
  1405. # No CSRF
  1406. output = self.app.post(
  1407. '/test/pull-request/1/update', data=data,
  1408. follow_redirects=True)
  1409. self.assertEqual(output.status_code, 200)
  1410. output_text = output.get_data(as_text=True)
  1411. self.assertIn(
  1412. '<title>PR#1: PR from the feature branch - test\n - '
  1413. 'Pagure</title>', output_text)
  1414. self.assertIn(
  1415. '<h3><span class="label label-default">PR#1</span>\n'
  1416. ' PR from the feature branch\n', output_text)
  1417. self.assertNotIn(
  1418. '</button>\n Request assigned',
  1419. output_text)
  1420. # Tag the PR
  1421. data = {
  1422. 'csrf_token': csrf_token,
  1423. 'tag': 'black',
  1424. }
  1425. output = self.app.post(
  1426. '/test/pull-request/1/update', data=data,
  1427. follow_redirects=True)
  1428. self.assertEqual(output.status_code, 200)
  1429. output_text = output.get_data(as_text=True)
  1430. self.assertIn(
  1431. '<title>PR#1: PR from the feature branch - test\n - '
  1432. 'Pagure</title>', output_text)
  1433. self.assertIn(
  1434. '<h3><span class="label label-default">PR#1</span>\n'
  1435. ' PR from the feature branch\n', output_text)
  1436. self.assertIn(
  1437. '</button>\n Pull-request tagged with: black',
  1438. output_text)
  1439. self.assertIn(
  1440. 'title="comma separated list of tags"\n '
  1441. 'value="black" />', output_text)
  1442. # Try as another user
  1443. user.username = 'foo'
  1444. with tests.user_set(self.app.application, user):
  1445. # Tag the PR
  1446. data = {
  1447. 'csrf_token': csrf_token,
  1448. 'tag': 'blue, yellow',
  1449. }
  1450. output = self.app.post(
  1451. '/test/pull-request/1/update', data=data,
  1452. follow_redirects=True)
  1453. self.assertEqual(output.status_code, 403)
  1454. # Make the PR be from foo
  1455. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1456. req = repo.requests[0]
  1457. req.user_id = 2
  1458. self.session.add(req)
  1459. self.session.commit()
  1460. # Re-try to tag the PR
  1461. data = {
  1462. 'csrf_token': csrf_token,
  1463. 'tag': 'blue, yellow',
  1464. }
  1465. output = self.app.post(
  1466. '/test/pull-request/1/update', data=data,
  1467. follow_redirects=True)
  1468. self.assertEqual(output.status_code, 200)
  1469. soup = BeautifulSoup(output.get_data(as_text=True), "html.parser")
  1470. self.assertEqual(
  1471. soup.find("title").string,
  1472. 'PR#1: PR from the feature branch - test\n - Pagure'
  1473. )
  1474. h3 = soup.find_all("h3")
  1475. self.assertIsNotNone(h3)
  1476. self.assertEqual(len(h3), 3)
  1477. # keep the last one only
  1478. h3 = h3[2]
  1479. self.assertListEqual(
  1480. h3.find("span")["class"], ["label", "label-default"])
  1481. self.assertEqual(h3.find("span").string, "PR#1")
  1482. self.assertEqual(
  1483. list(h3.stripped_strings)[1], 'PR from the feature branch')
  1484. alerts = [
  1485. list(a.stripped_strings)[2] for a in
  1486. soup.find_all("div", class_="alert")
  1487. if list(a.stripped_strings)
  1488. ]
  1489. self.assertIn('Pull-request **un**tagged with: black', alerts)
  1490. self.assertIn('Pull-request tagged with: blue, yellow', alerts)
  1491. input_tag = soup.find("input", id="tag")
  1492. self.assertEqual(
  1493. input_tag["title"], "comma separated list of tags")
  1494. # The order is not guaranteed, compare sets.
  1495. self.assertEqual(
  1496. set(input_tag["value"].split(",")),
  1497. set(["blue", "yellow"])
  1498. )
  1499. user.username = 'pingou'
  1500. with tests.user_set(self.app.application, user):
  1501. # Pull-Request closed
  1502. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1503. req = repo.requests[0]
  1504. req.status = 'Closed'
  1505. req.closed_by_in = 1
  1506. self.session.add(req)
  1507. self.session.commit()
  1508. output = self.app.post(
  1509. '/test/pull-request/1/update', data=data,
  1510. follow_redirects=True)
  1511. self.assertEqual(output.status_code, 403)
  1512. # Project w/o pull-request
  1513. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1514. settings = repo.settings
  1515. settings['pull_requests'] = False
  1516. repo.settings = settings
  1517. self.session.add(repo)
  1518. self.session.commit()
  1519. output = self.app.post(
  1520. '/test/pull-request/1/update', data=data,
  1521. follow_redirects=True)
  1522. self.assertEqual(output.status_code, 404)
  1523. @patch('pagure.lib.notify.send_email')
  1524. def test_fork_project(self, send_email):
  1525. """ Test the fork_project endpoint. """
  1526. send_email.return_value = True
  1527. tests.create_projects(self.session)
  1528. for folder in ['docs', 'tickets', 'requests', 'repos']:
  1529. tests.create_projects_git(
  1530. os.path.join(self.path, folder), bare=True)
  1531. user = tests.FakeUser()
  1532. user.username = 'pingou'
  1533. with tests.user_set(self.app.application, user):
  1534. output = self.app.post('/do_fork/test')
  1535. self.assertEqual(output.status_code, 400)
  1536. output = self.app.get('/new/')
  1537. self.assertEqual(output.status_code, 200)
  1538. self.assertIn('<strong>Create new Project</strong>', output.get_data(as_text=True))
  1539. csrf_token = self.get_csrf(output=output)
  1540. data = {
  1541. 'csrf_token': csrf_token,
  1542. }
  1543. output = self.app.post(
  1544. '/do_fork/foo', data=data, follow_redirects=True)
  1545. self.assertEqual(output.status_code, 404)
  1546. user.username = 'foo'
  1547. with tests.user_set(self.app.application, user):
  1548. output = self.app.post('/do_fork/test')
  1549. self.assertEqual(output.status_code, 400)
  1550. data = {
  1551. 'csrf_token': csrf_token,
  1552. }
  1553. output = self.app.post(
  1554. '/do_fork/test', data=data, follow_redirects=True)
  1555. self.assertEqual(output.status_code, 200)
  1556. @patch('pagure.lib.notify.send_email')
  1557. def test_new_request_pull_branch_space(self, send_email):
  1558. """ Test the new_request_pull endpoint. """
  1559. send_email.return_value = True
  1560. self.test_fork_project()
  1561. tests.create_projects_git(
  1562. os.path.join(self.path, 'requests'), bare=True)
  1563. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1564. fork = pagure.lib.get_authorized_project(self.session, 'test', user='foo')
  1565. self.set_up_git_repo(
  1566. new_project=fork, branch_from='feature', mtype='FF')
  1567. user = tests.FakeUser(username = 'pingou')
  1568. with tests.user_set(self.app.application, user):
  1569. output = self.app.get('/test/diff/master..foo bar')
  1570. self.assertEqual(output.status_code, 400)
  1571. output_text = output.get_data(as_text=True)
  1572. self.assertIn(
  1573. '<p>Branch foo bar does not exist</p>', output_text)
  1574. @patch('pagure.lib.notify.send_email')
  1575. def test_new_request_pull(self, send_email):
  1576. """ Test the new_request_pull endpoint. """
  1577. send_email.return_value = True
  1578. self.test_fork_project()
  1579. tests.create_projects_git(
  1580. os.path.join(self.path, 'requests'), bare=True)
  1581. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1582. fork = pagure.lib.get_authorized_project(self.session, 'test', user='foo')
  1583. self.set_up_git_repo(
  1584. new_project=fork, branch_from='feature', mtype='FF')
  1585. user = tests.FakeUser()
  1586. user.username = 'foo'
  1587. with tests.user_set(self.app.application, user):
  1588. output = self.app.get('/foo/diff/master..feature')
  1589. self.assertEqual(output.status_code, 404)
  1590. output = self.app.get('/test/diff/master..foo')
  1591. self.assertEqual(output.status_code, 400)
  1592. output = self.app.get('/test/diff/foo..master')
  1593. self.assertEqual(output.status_code, 400)
  1594. output = self.app.get('/test/diff/feature..master')
  1595. self.assertEqual(output.status_code, 200)
  1596. output_text = output.get_data(as_text=True)
  1597. self.assertIn(
  1598. '<title>Diff from master to feature - test\n - '
  1599. 'Pagure</title>', output_text)
  1600. self.assertIn(
  1601. '<p class="error"> No commits found </p>', output_text)
  1602. output = self.app.get('/test/diff/master..feature')
  1603. self.assertEqual(output.status_code, 200)
  1604. output_text = output.get_data(as_text=True)
  1605. self.assertIn(
  1606. '<title>Diff from feature to master - test\n - '
  1607. 'Pagure</title>', output_text)
  1608. self.assertNotIn(
  1609. '<input type="submit" class="submit positive button" '
  1610. 'value="Create">', output_text)
  1611. user.username = 'pingou'
  1612. with tests.user_set(self.app.application, user):
  1613. output = self.app.get('/test/diff/master..feature')
  1614. self.assertEqual(output.status_code, 200)
  1615. output_text = output.get_data(as_text=True)
  1616. self.assertIn(
  1617. '<title>Create new Pull Request for master - test\n - '
  1618. 'Pagure</title>', output_text)
  1619. self.assertIn(
  1620. '<input type="submit" class="btn btn-primary" value="Create">',
  1621. output_text)
  1622. csrf_token = self.get_csrf(output=output)
  1623. # Case 1 - Add an initial comment
  1624. data = {
  1625. 'csrf_token': csrf_token,
  1626. 'title': 'foo bar PR',
  1627. 'initial_comment': 'Test Initial Comment',
  1628. }
  1629. output = self.app.post(
  1630. '/test/diff/master..feature', data=data, follow_redirects=True)
  1631. self.assertEqual(output.status_code, 200)
  1632. output_text = output.get_data(as_text=True)
  1633. self.assertIn(
  1634. '<title>PR#2: foo bar PR - test\n - Pagure</title>',
  1635. output_text)
  1636. self.assertIn('<p>Test Initial Comment</p>',
  1637. output_text)
  1638. self.assertEqual(
  1639. output_text.count('title="PY C (pingou)"'),
  1640. 1)
  1641. # Test if the `open changed file icon` is displayed.
  1642. self.assertIn(
  1643. 'class="open_changed_file_icon_wrap"><span '
  1644. 'class="oi open_changed_file_icon" data-glyph="eye" '
  1645. 'alt="Open changed file" title="Open changed file"></span>'
  1646. '</a>', output_text)
  1647. # Case 2 - Add an empty initial comment
  1648. data = {
  1649. 'csrf_token': csrf_token,
  1650. 'title': 'foo bar PR',
  1651. 'initial_comment': '',
  1652. }
  1653. output = self.app.post(
  1654. '/test/diff/master..feature', data=data, follow_redirects=True)
  1655. self.assertEqual(output.status_code, 200)
  1656. output_text = output.get_data(as_text=True)
  1657. self.assertIn(
  1658. '<title>PR#3: foo bar PR - test\n - Pagure</title>',
  1659. output_text)
  1660. self.assertNotIn('<div id="comment-', output_text)
  1661. @patch('pagure.lib.notify.send_email')
  1662. def test_new_request_pull_req_sign_off_view(self, send_email):
  1663. """ Test the new_request_pull endpoint. """
  1664. send_email.return_value = True
  1665. self.test_fork_project()
  1666. tests.create_projects_git(
  1667. os.path.join(self.path, 'requests'), bare=True)
  1668. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1669. fork = pagure.lib.get_authorized_project(self.session, 'test', user='foo')
  1670. # Enforce Signed-of-by in the repo
  1671. settings = repo.settings
  1672. settings['Enforce_signed-off_commits_in_pull-request'] = True
  1673. repo.settings = settings
  1674. self.session.add(repo)
  1675. self.session.commit()
  1676. self.set_up_git_repo(
  1677. new_project=fork, branch_from='feature', mtype='FF')
  1678. user = tests.FakeUser()
  1679. user.username = 'foo'
  1680. with tests.user_set(self.app.application, user):
  1681. output = self.app.get('/test/diff/master..feature')
  1682. self.assertEqual(output.status_code, 200)
  1683. output_text = output.get_data(as_text=True)
  1684. self.assertIn(
  1685. '<title>Diff from feature to master - test\n - '
  1686. 'Pagure</title>', output_text)
  1687. self.assertIn(
  1688. '</button>\n This project enforces the '
  1689. 'Signed-off-by statement on all commits', output_text)
  1690. self.assertNotIn(
  1691. '<input type="submit" class="btn btn-primary" value="Create">',
  1692. output_text)
  1693. self.assertNotIn(
  1694. '</button>\n This repo enforces that '
  1695. 'all commits are signed off by their author.', output_text)
  1696. @patch('pagure.lib.notify.send_email')
  1697. def test_new_request_pull_req_sign_off_submit(self, send_email):
  1698. """ Test the new_request_pull endpoint. """
  1699. send_email.return_value = True
  1700. self.test_fork_project()
  1701. tests.create_projects_git(
  1702. os.path.join(self.path, 'requests'), bare=True)
  1703. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1704. fork = pagure.lib.get_authorized_project(self.session, 'test', user='foo')
  1705. # Enforce Signed-of-by in the repo
  1706. settings = repo.settings
  1707. settings['Enforce_signed-off_commits_in_pull-request'] = True
  1708. repo.settings = settings
  1709. self.session.add(repo)
  1710. self.session.commit()
  1711. self.set_up_git_repo(
  1712. new_project=fork, branch_from='feature', mtype='FF')
  1713. user = tests.FakeUser()
  1714. user.username = 'pingou'
  1715. with tests.user_set(self.app.application, user):
  1716. output = self.app.get('/test/diff/master..feature')
  1717. self.assertEqual(output.status_code, 200)
  1718. output_text = output.get_data(as_text=True)
  1719. self.assertIn(
  1720. '<title>Create new Pull Request for master - test\n - '
  1721. 'Pagure</title>', output_text)
  1722. self.assertIn(
  1723. '</button>\n This project enforces the '
  1724. 'Signed-off-by statement on all commits', output_text)
  1725. self.assertIn(
  1726. '<input type="submit" class="btn btn-primary" value="Create">',
  1727. output_text)
  1728. csrf_token = self.get_csrf(output=output)
  1729. # Try to create the PR
  1730. data = {
  1731. 'csrf_token': csrf_token,
  1732. 'title': 'foo bar PR',
  1733. 'initial_comment': 'Test Initial Comment',
  1734. }
  1735. output = self.app.post(
  1736. '/test/diff/master..feature', data=data, follow_redirects=True)
  1737. self.assertEqual(output.status_code, 200)
  1738. output_text = output.get_data(as_text=True)
  1739. self.assertIn(
  1740. '<title>Create new Pull Request for master - test\n - '
  1741. 'Pagure</title>', output_text)
  1742. # Flashed information message
  1743. self.assertIn(
  1744. '</button>\n This project enforces the '
  1745. 'Signed-off-by statement on all commits', output_text)
  1746. # Flashed error message
  1747. self.assertIn(
  1748. '</button>\n This repo enforces that '
  1749. 'all commits are signed off by their author.', output_text)
  1750. self.assertIn(
  1751. '<input type="submit" class="btn btn-primary" value="Create">',
  1752. output_text)
  1753. @patch('pagure.lib.notify.send_email')
  1754. def test_request_pull_commit_start_stop(self, send_email):
  1755. """ Test the the commit start and stop of brand new PR. """
  1756. send_email.return_value = True
  1757. self.test_fork_project()
  1758. tests.create_projects_git(
  1759. os.path.join(self.path, 'requests'), bare=True)
  1760. repo = pagure.lib.get_authorized_project(self.session, 'test')
  1761. fork = pagure.lib.get_authorized_project(self.session, 'test', user='foo')
  1762. self.set_up_git_repo(
  1763. new_project=fork, branch_from='feature', mtype='FF')
  1764. user = tests.FakeUser()
  1765. user.username = 'pingou'
  1766. with tests.user_set(self.app.application, user):
  1767. output = self.app.get('/test/diff/master..feature')
  1768. self.assertEqual(output.status_code, 200)
  1769. output_text = output.get_data(as_text=True)
  1770. self.assertIn(
  1771. '<title>Create new Pull Request for master - test\n - '
  1772. 'Pagure</title>', output_text)
  1773. self.assertIn(
  1774. '<input type="submit" class="btn btn-primary" value="Create">',
  1775. output_text)
  1776. csrf_token = self.get_csrf(output=output)
  1777. # Case 1 - Add an initial comment
  1778. data = {
  1779. 'csrf_token': csrf_token,
  1780. 'title': 'foo bar PR',
  1781. 'initial_comment': 'Test Initial Comment',
  1782. }
  1783. output = self.app.post(
  1784. '/test/diff/master..feature', data=data, follow_redirects=True)
  1785. self.assertEqual(output.status_code, 200)
  1786. output_text = output.get_data(as_text=True)
  1787. self.assertIn(
  1788. '<title>PR#2: foo bar PR - test\n - Pagure</title>',
  1789. output_text)
  1790. self.assertIn('<p>Test Initial Comment</p>', output_text)
  1791. # Check if commit start and stop have been set for PR#2
  1792. request = pagure.lib.search_pull_requests(
  1793. self.session, project_id=1, requestid=2)
  1794. self.assertIsNotNone(request.commit_start)
  1795. self.assertIsNotNone(request.commit_stop)
  1796. @patch('pagure.lib.notify.send_email')
  1797. def test_new_request_pull_fork_to_fork_pr_disabled(self, send_email):
  1798. """ Test creating a fork to fork PR. """
  1799. send_email.return_value = True
  1800. self.test_fork_project()
  1801. # Create a 3rd user
  1802. item = pagure.lib.model.User(
  1803. user='ralph',
  1804. fullname='Ralph bar',
  1805. password='ralph_foo',
  1806. default_email='ralph@bar.com',
  1807. )
  1808. self.session.add(item)
  1809. item = pagure.lib.model.UserEmail(
  1810. user_id=3,
  1811. email='ralph@bar.com')
  1812. self.session.add(item)
  1813. self.session.commit()
  1814. user = tests.FakeUser()
  1815. user.username = 'ralph'
  1816. with tests.user_set(self.app.application, user):
  1817. # Have Ralph fork, foo's fork of test
  1818. output = self.app.get('/fork/foo/test')
  1819. self.assertEqual(output.status_code, 200)
  1820. output = self.app.post('/do_fork/fork/foo/test')
  1821. self.assertEqual(output.status_code, 400)
  1822. csrf_token = self.get_csrf()
  1823. data = {
  1824. 'csrf_token': csrf_token,
  1825. }
  1826. output = self.app.post(
  1827. '/do_fork/fork/foo/test', data=data,
  1828. follow_redirects=True)
  1829. self.assertEqual(output.status_code, 200)
  1830. # Check that Ralph's fork do exist
  1831. output = self.app.get('/fork/ralph/test')
  1832. self.assertEqual(output.status_code, 200)
  1833. tests.create_projects_git(
  1834. os.path.join(self.path, 'requests'), bare=True)
  1835. fork = pagure.lib.get_authorized_project(
  1836. self.session, 'test', user='ralph')
  1837. self.set_up_git_repo(
  1838. new_project=fork, branch_from='feature', mtype='FF')
  1839. # Try opening a pull-request
  1840. output = self.app.get(
  1841. '/fork/ralph/test/diff/master..feature')
  1842. self.assertEqual(output.status_code, 404)
  1843. self.assertIn(
  1844. '<p>No pull-request allowed on this project</p>',
  1845. output.get_data(as_text=True))
  1846. @patch('pagure.lib.notify.send_email')
  1847. def test_new_request_pull_fork_to_fork(self, send_email):
  1848. """ Test creating a fork to fork PR. """
  1849. send_email.return_value = True
  1850. self.test_fork_project()
  1851. # Create a 3rd user
  1852. item = pagure.lib.model.User(
  1853. user='ralph',
  1854. fullname='Ralph bar',
  1855. password='ralph_foo',
  1856. default_email='ralph@bar.com',
  1857. )
  1858. self.session.add(item)
  1859. item = pagure.lib.model.UserEmail(
  1860. user_id=3,
  1861. email='ralph@bar.com')
  1862. self.session.add(item)
  1863. self.session.commit()
  1864. user = tests.FakeUser()
  1865. user.username = 'ralph'
  1866. with tests.user_set(self.app.application, user):
  1867. # Have Ralph fork, foo's fork of test
  1868. output = self.app.get('/fork/foo/test')
  1869. self.assertEqual(output.status_code, 200)
  1870. output = self.app.post('/do_fork/fork/foo/test')
  1871. self.assertEqual(output.status_code, 400)
  1872. csrf_token = self.get_csrf()
  1873. data = {
  1874. 'csrf_token': csrf_token,
  1875. }
  1876. output = self.app.post(
  1877. '/do_fork/fork/foo/test', data=data,
  1878. follow_redirects=True)
  1879. self.assertEqual(output.status_code, 200)
  1880. # Check that Ralph's fork do exist
  1881. output = self.app.get('/fork/ralph/test')
  1882. self.assertEqual(output.status_code, 200)
  1883. tests.create_projects_git(
  1884. os.path.join(self.path, 'requests'), bare=True)
  1885. # Turn on pull-request on the fork
  1886. repo = pagure.lib.get_authorized_project(
  1887. self.session, 'test', user='foo')
  1888. settings = repo.settings
  1889. settings['pull_requests'] = True
  1890. repo.settings = settings
  1891. self.session.add(repo)
  1892. self.session.commit()
  1893. # Add some content to the parent
  1894. self.set_up_git_repo(
  1895. new_project=repo, branch_from='master', mtype='FF',
  1896. name_from=repo.fullname)
  1897. fork = pagure.lib.get_authorized_project(
  1898. self.session, 'test', user='ralph')
  1899. self.set_up_git_repo(
  1900. new_project=fork, branch_from='feature', mtype='FF',
  1901. prid=2, name_from=fork.fullname)
  1902. # Try opening a pull-request
  1903. output = self.app.get(
  1904. '/fork/ralph/test/diff/master..feature')
  1905. self.assertEqual(output.status_code, 200)
  1906. output_text = output.get_data(as_text=True)
  1907. self.assertIn(
  1908. '<title>Create new Pull Request for master - fork/ralph/test\n - '
  1909. 'Pagure</title>', output_text)
  1910. self.assertIn(
  1911. '<input type="submit" class="btn btn-primary" value="Create">',
  1912. output_text)
  1913. csrf_token = self.get_csrf(output=output)
  1914. # Case 1 - Add an initial comment
  1915. data = {
  1916. 'csrf_token': csrf_token,
  1917. 'title': 'foo bar PR',
  1918. 'initial_comment': 'Test Initial Comment',
  1919. }
  1920. output = self.app.post(
  1921. '/fork/ralph/test/diff/master..feature',
  1922. data=data, follow_redirects=True)
  1923. self.assertEqual(output.status_code, 200)
  1924. output_text = output.get_data(as_text=True)
  1925. self.assertIn(
  1926. '<title>PR#1: foo bar PR - fork/foo/test\n - Pagure</title>',
  1927. output_text)
  1928. self.assertIn('<p>Test Initial Comment</p>', output_text)
  1929. @patch('pagure.lib.notify.send_email')
  1930. def test_new_request_pull_fork_to_other_fork(self, send_email):
  1931. """ Test creating a PR from fork to a fork of the same family. """
  1932. send_email.return_value = True
  1933. self.test_fork_project()
  1934. # Create a 3rd user
  1935. item = pagure.lib.model.User(
  1936. user='ralph',
  1937. fullname='Ralph bar',
  1938. password='ralph_foo',
  1939. default_email='ralph@bar.com',
  1940. )
  1941. self.session.add(item)
  1942. item = pagure.lib.model.UserEmail(
  1943. user_id=3,
  1944. email='ralph@bar.com')
  1945. self.session.add(item)
  1946. self.session.commit()
  1947. user = tests.FakeUser()
  1948. user.username = 'ralph'
  1949. with tests.user_set(self.app.application, user):
  1950. csrf_token = self.get_csrf()
  1951. data = {
  1952. 'csrf_token': csrf_token,
  1953. }
  1954. output = self.app.post(
  1955. '/do_fork/test', data=data,
  1956. follow_redirects=True)
  1957. self.assertEqual(output.status_code, 200)
  1958. # Check that Ralph's fork do exist
  1959. output = self.app.get('/fork/ralph/test')
  1960. self.assertEqual(output.status_code, 200)
  1961. tests.create_projects_git(
  1962. os.path.join(self.path, 'requests'), bare=True)
  1963. # Turn on pull-request on the fork
  1964. repo = pagure.lib.get_authorized_project(
  1965. self.session, 'test', user='foo')
  1966. settings = repo.settings
  1967. settings['pull_requests'] = True
  1968. repo.settings = settings
  1969. self.session.add(repo)
  1970. self.session.commit()
  1971. # Add some content to the parents
  1972. self.set_up_git_repo(
  1973. new_project=repo, branch_from='master', mtype='FF')
  1974. self.set_up_git_repo(
  1975. new_project=repo, branch_from='master', mtype='FF',
  1976. name_from=repo.fullname, prid=2)
  1977. fork = pagure.lib.get_authorized_project(
  1978. self.session, 'test', user='ralph')
  1979. self.set_up_git_repo(
  1980. new_project=fork, branch_from='feature', mtype='FF',
  1981. prid=3, name_from=fork.fullname)
  1982. # Try opening a pull-request
  1983. output = self.app.get(
  1984. '/fork/ralph/test/diff/master..feature?project_to=fork/foo/test')
  1985. self.assertEqual(output.status_code, 200)
  1986. output_text = output.get_data(as_text=True)
  1987. self.assertIn(
  1988. '<title>Create new Pull Request for master - fork/ralph/test\n - '
  1989. 'Pagure</title>', output_text)
  1990. self.assertIn(
  1991. '<input type="submit" class="btn btn-primary" value="Create">',
  1992. output_text)
  1993. csrf_token = self.get_csrf(output=output)
  1994. # Case 1 - Opening PR to fork/foo/test
  1995. data = {
  1996. 'csrf_token': csrf_token,
  1997. 'title': 'foo bar PR',
  1998. 'initial_comment': 'Test Initial Comment',
  1999. }
  2000. output = self.app.post(
  2001. '/fork/ralph/test/diff/master..feature?project_to=fork/foo/test',
  2002. data=data, follow_redirects=True)
  2003. self.assertEqual(output.status_code, 200)
  2004. output_text = output.get_data(as_text=True)
  2005. self.assertIn(
  2006. '<title>PR#1: foo bar PR - fork/foo/test\n - Pagure</title>',
  2007. output_text)
  2008. self.assertIn('<p>Test Initial Comment</p>', output_text)
  2009. # Case 1 - Opening PR to parent repo, shows project_to works
  2010. output = self.app.post(
  2011. '/fork/ralph/test/diff/master..feature',
  2012. data=data, follow_redirects=True)
  2013. self.assertEqual(output.status_code, 200)
  2014. output_text = output.get_data(as_text=True)
  2015. self.assertIn(
  2016. '<title>PR#4: foo bar PR - test\n - Pagure</title>',
  2017. output_text)
  2018. self.assertIn('<p>Test Initial Comment</p>', output_text)
  2019. @patch('pagure.lib.notify.send_email')
  2020. def test_new_request_pull_fork_to_other_unrelated_fork(self, send_email):
  2021. """ Test creating a PR from fork to fork that isn't from the same
  2022. family.
  2023. """
  2024. send_email.return_value = True
  2025. self.test_fork_project()
  2026. # Create a 3rd user
  2027. item = pagure.lib.model.User(
  2028. user='ralph',
  2029. fullname='Ralph bar',
  2030. password='ralph_foo',
  2031. default_email='ralph@bar.com',
  2032. )
  2033. self.session.add(item)
  2034. item = pagure.lib.model.UserEmail(
  2035. user_id=3,
  2036. email='ralph@bar.com')
  2037. self.session.add(item)
  2038. self.session.commit()
  2039. user = tests.FakeUser()
  2040. user.username = 'ralph'
  2041. with tests.user_set(self.app.application, user):
  2042. csrf_token = self.get_csrf()
  2043. data = {
  2044. 'csrf_token': csrf_token,
  2045. }
  2046. output = self.app.post(
  2047. '/do_fork/test2', data=data,
  2048. follow_redirects=True)
  2049. self.assertEqual(output.status_code, 200)
  2050. # Check that Ralph's fork do exist
  2051. output = self.app.get('/fork/ralph/test2')
  2052. self.assertEqual(output.status_code, 200)
  2053. tests.create_projects_git(
  2054. os.path.join(self.path, 'requests'), bare=True)
  2055. # Turn on pull-request on the fork
  2056. repo = pagure.lib.get_authorized_project(
  2057. self.session, 'test', user='foo')
  2058. settings = repo.settings
  2059. settings['pull_requests'] = True
  2060. repo.settings = settings
  2061. self.session.add(repo)
  2062. self.session.commit()
  2063. # Add some content to the parent
  2064. self.set_up_git_repo(
  2065. new_project=repo, branch_from='master', mtype='FF',
  2066. name_from=repo.fullname)
  2067. fork = pagure.lib.get_authorized_project(
  2068. self.session, 'test2', user='ralph')
  2069. self.set_up_git_repo(
  2070. new_project=fork, branch_from='feature', mtype='FF',
  2071. prid=2, name_from=fork.fullname)
  2072. # Case 1 - Opening PR to fork/foo/test
  2073. data = {
  2074. 'csrf_token': csrf_token,
  2075. 'title': 'foo bar PR',
  2076. 'initial_comment': 'Test Initial Comment',
  2077. }
  2078. output = self.app.post(
  2079. '/fork/ralph/test2/diff/master..feature?project_to=fork/foo/test',
  2080. data=data, follow_redirects=True)
  2081. self.assertEqual(output.status_code, 400)
  2082. self.assertIn(
  2083. "<p>fork/foo/test is not part of fork/ralph/test2's "
  2084. "family</p>", output.get_data(as_text=True))
  2085. @patch('pagure.lib.notify.send_email')
  2086. def test_new_request_pull_empty_repo(self, send_email):
  2087. """ Test the new_request_pull endpoint against an empty repo. """
  2088. send_email.return_value = True
  2089. self.test_fork_project()
  2090. tests.create_projects_git(
  2091. os.path.join(self.path, 'requests'), bare=True)
  2092. repo = pagure.lib.get_authorized_project(self.session, 'test')
  2093. fork = pagure.lib.get_authorized_project(self.session, 'test', user='foo')
  2094. # Create a git repo to play with
  2095. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  2096. repo = pygit2.init_repository(gitrepo, bare=True)
  2097. # Create a fork of this repo
  2098. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  2099. gitrepo = os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git')
  2100. new_repo = pygit2.clone_repository(gitrepo, newpath)
  2101. user = tests.FakeUser()
  2102. user.username = 'foo'
  2103. with tests.user_set(self.app.application, user):
  2104. output = self.app.get(
  2105. '/fork/foo/test/diff/master..feature',
  2106. follow_redirects=True)
  2107. self.assertEqual(output.status_code, 400)
  2108. self.assertIn(
  2109. '<p>Fork is empty, there are no commits to create a pull '
  2110. 'request with</p>', output.get_data(as_text=True))
  2111. output = self.app.get('/test/new_issue')
  2112. csrf_token = self.get_csrf(output=output)
  2113. data = {
  2114. 'csrf_token': csrf_token,
  2115. 'title': 'foo bar PR',
  2116. }
  2117. output = self.app.post(
  2118. '/test/diff/master..feature', data=data, follow_redirects=True)
  2119. self.assertEqual(output.status_code, 400)
  2120. self.assertIn(
  2121. '<p>Fork is empty, there are no commits to create a pull '
  2122. 'request with</p>', output.get_data(as_text=True))
  2123. shutil.rmtree(newpath)
  2124. @patch('pagure.lib.notify.send_email')
  2125. def test_new_request_pull_empty_fork(self, send_email):
  2126. """ Test the new_request_pull endpoint against an empty repo. """
  2127. send_email.return_value = True
  2128. self.test_fork_project()
  2129. tests.create_projects_git(
  2130. os.path.join(self.path, 'requests'), bare=True)
  2131. repo = pagure.lib.get_authorized_project(self.session, 'test')
  2132. fork = pagure.lib.get_authorized_project(self.session, 'test', user='foo')
  2133. # Create a git repo to play with
  2134. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  2135. repo = pygit2.init_repository(gitrepo, bare=True)
  2136. # Create a fork of this repo
  2137. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  2138. gitrepo = os.path.join(
  2139. self.path, 'repos', 'forks', 'foo', 'test.git')
  2140. new_repo = pygit2.clone_repository(gitrepo, newpath)
  2141. user = tests.FakeUser()
  2142. user.username = 'foo'
  2143. with tests.user_set(self.app.application, user):
  2144. output = self.app.get(
  2145. '/fork/foo/test/diff/master..master', follow_redirects=True)
  2146. self.assertEqual(output.status_code, 400)
  2147. self.assertIn(
  2148. '<p>Fork is empty, there are no commits to create a pull '
  2149. 'request with</p>', output.get_data(as_text=True))
  2150. shutil.rmtree(newpath)
  2151. @patch('pagure.lib.notify.send_email')
  2152. def test_pull_request_add_comment(self, send_email):
  2153. """ Test the pull_request_add_comment endpoint. """
  2154. send_email.return_value = True
  2155. self.test_request_pull()
  2156. user = tests.FakeUser()
  2157. user.username = 'pingou'
  2158. with tests.user_set(self.app.application, user):
  2159. output = self.app.post('/foo/pull-request/1/comment')
  2160. self.assertEqual(output.status_code, 404)
  2161. output = self.app.post('/test/pull-request/100/comment')
  2162. self.assertEqual(output.status_code, 404)
  2163. output = self.app.post('/test/pull-request/1/comment')
  2164. self.assertEqual(output.status_code, 200)
  2165. self.assertTrue(
  2166. output.get_data(as_text=True).startswith('\n<section class="add_comment">'))
  2167. csrf_token = self.get_csrf(output=output)
  2168. data = {
  2169. 'csrf_token': csrf_token,
  2170. 'comment': 'This look alright but we can do better',
  2171. }
  2172. output = self.app.post(
  2173. '/test/pull-request/1/comment', data=data,
  2174. follow_redirects=True)
  2175. self.assertEqual(output.status_code, 200)
  2176. output_text = output.get_data(as_text=True)
  2177. self.assertIn(
  2178. '<title>PR#1: PR from the feature branch - test\n - '
  2179. 'Pagure</title>', output_text)
  2180. self.assertIn(
  2181. '</button>\n Comment added',
  2182. output_text)
  2183. self.assertEqual(output_text.count('title="PY C (pingou)"'), 2)
  2184. # Project w/o pull-request
  2185. repo = pagure.lib.get_authorized_project(self.session, 'test')
  2186. settings = repo.settings
  2187. settings['pull_requests'] = False
  2188. repo.settings = settings
  2189. self.session.add(repo)
  2190. self.session.commit()
  2191. output = self.app.post(
  2192. '/test/pull-request/1/comment', data=data,
  2193. follow_redirects=True)
  2194. self.assertEqual(output.status_code, 404)
  2195. @patch('pagure.lib.notify.send_email')
  2196. def test_pull_request_drop_comment(self, send_email):
  2197. """ Test the pull_request_drop_comment endpoint. """
  2198. send_email.return_value = True
  2199. self.test_pull_request_add_comment()
  2200. # Project w/ pull-request
  2201. repo = pagure.lib.get_authorized_project(self.session, 'test')
  2202. settings = repo.settings
  2203. settings['pull_requests'] = True
  2204. repo.settings = settings
  2205. self.session.add(repo)
  2206. self.session.commit()
  2207. user = tests.FakeUser()
  2208. user.username = 'foo'
  2209. with tests.user_set(self.app.application, user):
  2210. output = self.app.post('/foo/pull-request/1/comment/drop')
  2211. self.assertEqual(output.status_code, 404)
  2212. output = self.app.post('/test/pull-request/100/comment/drop')
  2213. self.assertEqual(output.status_code, 404)
  2214. output = self.app.post(
  2215. '/test/pull-request/1/comment/drop', follow_redirects=True)
  2216. self.assertEqual(output.status_code, 200)
  2217. output_text = output.get_data(as_text=True)
  2218. self.assertIn(
  2219. '<h3><span class="label label-default">PR#1</span>\n'
  2220. ' PR from the feature branch\n</h3>', output_text)
  2221. #self.assertIn('href="#comment-1">¶</a>', output_text)
  2222. self.assertIn(
  2223. '<p>This look alright but we can do better</p>',
  2224. output_text)
  2225. csrf_token = self.get_csrf(output=output)
  2226. # Invalid comment id
  2227. data = {
  2228. 'csrf_token': csrf_token,
  2229. 'drop_comment': '10',
  2230. }
  2231. output = self.app.post(
  2232. '/test/pull-request/1/comment/drop', data=data,
  2233. follow_redirects=True)
  2234. self.assertEqual(output.status_code, 404)
  2235. data['drop_comment'] = '1'
  2236. output = self.app.post(
  2237. '/test/pull-request/1/comment/drop', data=data,
  2238. follow_redirects=True)
  2239. self.assertEqual(output.status_code, 403)
  2240. user.username = 'pingou'
  2241. with tests.user_set(self.app.application, user):
  2242. # Drop comment
  2243. output = self.app.post(
  2244. '/test/pull-request/1/comment/drop', data=data,
  2245. follow_redirects=True)
  2246. self.assertEqual(output.status_code, 200)
  2247. output_text = output.get_data(as_text=True)
  2248. self.assertIn(
  2249. '<h3><span class="label label-default">PR#1</span>\n'
  2250. ' PR from the feature branch\n <span class="pull-xs-right">',
  2251. output_text)
  2252. self.assertIn(
  2253. '</button>\n Comment removed',
  2254. output_text)
  2255. # Project w/o pull-request
  2256. repo = pagure.lib.get_authorized_project(self.session, 'test')
  2257. settings = repo.settings
  2258. settings['pull_requests'] = False
  2259. repo.settings = settings
  2260. self.session.add(repo)
  2261. self.session.commit()
  2262. output = self.app.post(
  2263. '/test/pull-request/1/comment/drop', data=data,
  2264. follow_redirects=True)
  2265. self.assertEqual(output.status_code, 404)
  2266. @patch('pagure.lib.notify.send_email')
  2267. def test_pull_request_edit_comment(self, send_email):
  2268. """ Test the pull request edit comment endpoint """
  2269. send_email.return_value = True
  2270. self.test_request_pull()
  2271. user = tests.FakeUser()
  2272. user.username = 'pingou'
  2273. with tests.user_set(self.app.application, user):
  2274. # Repo 'foo' does not exist so it is verifying that condition
  2275. output = self.app.post('/foo/pull-request/1/comment/1/edit')
  2276. self.assertEqual(output.status_code, 404)
  2277. # Here no comment is present in the PR so its verifying that condition
  2278. output = self.app.post('/test/pull-request/100/comment/100/edit')
  2279. self.assertEqual(output.status_code, 404)
  2280. output = self.app.post('/test/pull-request/1/comment')
  2281. self.assertEqual(output.status_code, 200)
  2282. # Creating comment to play with
  2283. self.assertTrue(
  2284. output.get_data(as_text=True).startswith('\n<section class="add_comment">'))
  2285. csrf_token = self.get_csrf(output=output)
  2286. data = {
  2287. 'csrf_token': csrf_token,
  2288. 'comment': 'This look alright but we can do better',
  2289. }
  2290. output = self.app.post(
  2291. '/test/pull-request/1/comment', data=data,
  2292. follow_redirects=True)
  2293. self.assertEqual(output.status_code, 200)
  2294. output_text = output.get_data(as_text=True)
  2295. self.assertIn(
  2296. '<h3><span class="label label-default">PR#1</span>\n'
  2297. ' PR from the feature branch\n <span class="pull-xs-right">',
  2298. output_text)
  2299. self.assertIn(
  2300. '</button>\n Comment added',
  2301. output_text)
  2302. # Check if the comment is there
  2303. self.assertIn(
  2304. '<p>This look alright but we can do better</p>', output_text)
  2305. output = self.app.get('/test/pull-request/1/comment/1/edit')
  2306. self.assertEqual(output.status_code, 200)
  2307. output_text = output.get_data(as_text=True)
  2308. self.assertIn('<section class="edit_comment">', output_text)
  2309. # Checking if the comment is there in the update page
  2310. self.assertIn(
  2311. 'This look alright but we can do better</textarea>', output_text)
  2312. csrf_token = self.get_csrf(output=output)
  2313. data = {
  2314. 'csrf_token': csrf_token,
  2315. 'update_comment': 'This look alright but we can do better than this.',
  2316. }
  2317. output = self.app.post(
  2318. '/test/pull-request/1/comment/1/edit', data=data,
  2319. follow_redirects=True)
  2320. output_text = output.get_data(as_text=True)
  2321. # Checking if the comment is updated in the main page
  2322. self.assertIn(
  2323. '<p>This look alright but we can do better than this.</p>', output_text)
  2324. self.assertIn(
  2325. '<h3><span class="label label-default">PR#1</span>\n'
  2326. ' PR from the feature branch\n <span class="pull-xs-right">',
  2327. output_text)
  2328. # Checking if Edited by User is there or not
  2329. self.assertTrue(
  2330. '<small class="text-muted">Edited just now by pingou </small>'
  2331. in output_text
  2332. or
  2333. '<small class="text-muted">Edited seconds ago by pingou </small>'
  2334. in output_text)
  2335. self.assertIn(
  2336. '</button>\n Comment updated', output_text)
  2337. # Project w/o pull-request
  2338. repo = pagure.lib.get_authorized_project(self.session, 'test')
  2339. settings = repo.settings
  2340. settings['pull_requests'] = False
  2341. repo.settings = settings
  2342. self.session.add(repo)
  2343. self.session.commit()
  2344. output = self.app.post(
  2345. '/test/pull-request/1/comment/edit/1', data=data,
  2346. follow_redirects=True)
  2347. self.assertEqual(output.status_code, 404)
  2348. @patch('pagure.lib.notify.send_email')
  2349. def test_merge_request_pull_FF_w_merge_commit(self, send_email):
  2350. """ Test the merge_request_pull endpoint with a FF PR but with a
  2351. merge commit.
  2352. """
  2353. send_email.return_value = True
  2354. self.test_request_pull()
  2355. user = tests.FakeUser()
  2356. with tests.user_set(self.app.application, user):
  2357. output = self.app.get('/test/pull-request/1')
  2358. self.assertEqual(output.status_code, 200)
  2359. csrf_token = self.get_csrf(output=output)
  2360. # No CSRF
  2361. output = self.app.post(
  2362. '/test/pull-request/1/merge', data={}, follow_redirects=True)
  2363. self.assertEqual(output.status_code, 200)
  2364. output_text = output.get_data(as_text=True)
  2365. self.assertIn(
  2366. '<title>PR#1: PR from the feature branch - test\n - '
  2367. 'Pagure</title>', output_text)
  2368. self.assertIn(
  2369. '<h3><span class="label label-default">PR#1</span>\n'
  2370. ' PR from the feature branch\n</h3>', output_text)
  2371. self.assertIn(
  2372. 'title="View file as of 2a552b">sources</a>', output_text)
  2373. # Wrong project
  2374. data = {
  2375. 'csrf_token': csrf_token,
  2376. }
  2377. output = self.app.post(
  2378. '/foobar/pull-request/100/merge', data=data, follow_redirects=True)
  2379. self.assertEqual(output.status_code, 404)
  2380. # Wrong project
  2381. data = {
  2382. 'csrf_token': csrf_token,
  2383. }
  2384. output = self.app.post(
  2385. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  2386. self.assertEqual(output.status_code, 403)
  2387. user.username = 'pingou'
  2388. with tests.user_set(self.app.application, user):
  2389. # Wrong request id
  2390. data = {
  2391. 'csrf_token': csrf_token,
  2392. }
  2393. output = self.app.post(
  2394. '/test/pull-request/100/merge', data=data, follow_redirects=True)
  2395. self.assertEqual(output.status_code, 404)
  2396. # Project requiring a merge commit
  2397. repo = pagure.lib.get_authorized_project(self.session, 'test')
  2398. settings = repo.settings
  2399. settings['always_merge'] = True
  2400. repo.settings = settings
  2401. self.session.add(repo)
  2402. self.session.commit()
  2403. # Merge
  2404. output = self.app.post(
  2405. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  2406. self.assertEqual(output.status_code, 200)
  2407. output = self.app.get('/test/commits')
  2408. output_text = output.get_data(as_text=True)
  2409. self.assertIn(
  2410. '<title>Commits - test - Pagure</title>', output_text)
  2411. self.assertIn(
  2412. 'Merge #1 `PR from the feature branch`', output_text)
  2413. self.assertIn(
  2414. 'A commit on branch feature', output_text)
  2415. # Check if the closing notification was added
  2416. output = self.app.get('/test/pull-request/1')
  2417. self.assertIn(
  2418. '<small><p>Pull-Request has been merged by pingou</p></small>',
  2419. output.get_data(as_text=True))
  2420. @patch('pagure.lib.notify.send_email')
  2421. def test_internal_endpoint_main_ahead(self, send_email):
  2422. """ Test the new_request_pull endpoint when the main repo is ahead
  2423. of the fork.
  2424. """
  2425. send_email.return_value = True
  2426. tests.create_projects(self.session)
  2427. tests.create_projects_git(
  2428. os.path.join(self.path, 'requests'), bare=True)
  2429. self.set_up_git_repo(
  2430. new_project=None,
  2431. branch_from='feature')
  2432. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  2433. repo = pygit2.init_repository(gitrepo, bare=True)
  2434. # Make the main repo be ahead of the fork
  2435. # First commit
  2436. newpath = tempfile.mkdtemp(prefix='pagure-test')
  2437. repopath = os.path.join(newpath, 'test')
  2438. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  2439. # Create a file in that git repo
  2440. with open(os.path.join(repopath, 'testfile'), 'w') as stream:
  2441. stream.write('foo\n bar')
  2442. clone_repo.index.add('testfile')
  2443. clone_repo.index.write()
  2444. # Commits the files added
  2445. last_commit = clone_repo.revparse_single('HEAD')
  2446. tree = clone_repo.index.write_tree()
  2447. author = pygit2.Signature(
  2448. 'Alice Author', 'alice@authors.tld')
  2449. committer = pygit2.Signature(
  2450. 'Cecil Committer', 'cecil@committers.tld')
  2451. clone_repo.create_commit(
  2452. 'refs/heads/master', # the name of the reference to update
  2453. author,
  2454. committer,
  2455. 'Add testfile file for testing',
  2456. # binary string representing the tree object ID
  2457. tree,
  2458. # list of binary strings representing parents of the new commit
  2459. [last_commit.oid.hex]
  2460. )
  2461. # Second commit
  2462. with open(os.path.join(repopath, 'testfile'), 'a') as stream:
  2463. stream.write('\nfoo2\n bar2')
  2464. clone_repo.index.add('testfile')
  2465. clone_repo.index.write()
  2466. # Commits the files added
  2467. last_commit = clone_repo.revparse_single('HEAD')
  2468. tree = clone_repo.index.write_tree()
  2469. author = pygit2.Signature(
  2470. 'Alice Author', 'alice@authors.tld')
  2471. committer = pygit2.Signature(
  2472. 'Cecil Committer', 'cecil@committers.tld')
  2473. clone_repo.create_commit(
  2474. 'refs/heads/master', # the name of the reference to update
  2475. author,
  2476. committer,
  2477. 'Add a second commit to testfile for testing',
  2478. # binary string representing the tree object ID
  2479. tree,
  2480. # list of binary strings representing parents of the new commit
  2481. [last_commit.oid.hex]
  2482. )
  2483. # Third commit
  2484. with open(os.path.join(repopath, 'testfile'), 'a') as stream:
  2485. stream.write('\nfoo3\n bar3')
  2486. clone_repo.index.add('testfile')
  2487. clone_repo.index.write()
  2488. # Commits the files added
  2489. last_commit = clone_repo.revparse_single('HEAD')
  2490. tree = clone_repo.index.write_tree()
  2491. author = pygit2.Signature(
  2492. 'Alice Author', 'alice@authors.tld')
  2493. committer = pygit2.Signature(
  2494. 'Cecil Committer', 'cecil@committers.tld')
  2495. clone_repo.create_commit(
  2496. 'refs/heads/master', # the name of the reference to update
  2497. author,
  2498. committer,
  2499. 'Add a third commit to testfile for testing',
  2500. # binary string representing the tree object ID
  2501. tree,
  2502. # list of binary strings representing parents of the new commit
  2503. [last_commit.oid.hex]
  2504. )
  2505. refname = 'refs/heads/master:refs/heads/master'
  2506. ori_remote = clone_repo.remotes[0]
  2507. PagureRepo.push(ori_remote, refname)
  2508. shutil.rmtree(newpath)
  2509. user = tests.FakeUser()
  2510. user.username = 'foo'
  2511. with tests.user_set(self.app.application, user):
  2512. csrf_token = self.get_csrf()
  2513. output = self.app.post(
  2514. '/pv/pull-request/ready',
  2515. data={'repo': 'test', 'csrf_token': csrf_token}
  2516. )
  2517. self.assertEqual(output.status_code, 200)
  2518. data = json.loads(output.get_data(as_text=True))
  2519. self.assertEqual(
  2520. data,
  2521. {
  2522. "code": "OK",
  2523. "message": {
  2524. "branch_w_pr": {
  2525. "feature": "test/pull-request/1"
  2526. },
  2527. "new_branch": {}
  2528. }
  2529. }
  2530. )
  2531. @patch('pagure.lib.notify.send_email')
  2532. def test_fork_edit_file(self, send_email):
  2533. """ Test the fork_edit file endpoint. """
  2534. send_email.return_value = True
  2535. # Git repo not found
  2536. output = self.app.post('fork_edit/test/edit/master/f/sources')
  2537. self.assertEqual(output.status_code, 404)
  2538. tests.create_projects(self.session)
  2539. for folder in ['docs', 'tickets', 'requests', 'repos']:
  2540. tests.create_projects_git(
  2541. os.path.join(self.path, folder), bare=True)
  2542. # User not logged in
  2543. output = self.app.post('fork_edit/test/edit/master/f/sources')
  2544. self.assertEqual(output.status_code, 302)
  2545. user = tests.FakeUser()
  2546. user.username = 'pingou'
  2547. with tests.user_set(self.app.application, user):
  2548. # Invalid request
  2549. output = self.app.post('fork_edit/test/edit/master/f/source')
  2550. self.assertEqual(output.status_code, 400)
  2551. output = self.app.get('/new/')
  2552. self.assertEqual(output.status_code, 200)
  2553. self.assertIn('<strong>Create new Project</strong>', output.get_data(as_text=True))
  2554. csrf_token = self.get_csrf(output=output)
  2555. data = {
  2556. 'csrf_token': csrf_token,
  2557. }
  2558. # No files can be found since they are not added
  2559. output = self.app.post('fork_edit/test/edit/master/f/sources',
  2560. data=data, follow_redirects=True)
  2561. self.assertEqual(output.status_code, 404)
  2562. user = tests.FakeUser()
  2563. user.username = 'foo'
  2564. with tests.user_set(self.app.application, user):
  2565. data = {
  2566. 'csrf_token': csrf_token,
  2567. }
  2568. # Invalid request
  2569. output = self.app.post('fork_edit/test/edit/master/f/sources',
  2570. follow_redirects=True)
  2571. self.assertEqual(output.status_code, 400)
  2572. # Add content to the repo
  2573. tests.add_content_git_repo(os.path.join(
  2574. pagure.config.config['GIT_FOLDER'], 'test.git'))
  2575. tests.add_readme_git_repo(os.path.join(
  2576. pagure.config.config['GIT_FOLDER'], 'test.git'))
  2577. tests.add_binary_git_repo(
  2578. os.path.join(
  2579. pagure.config.config['GIT_FOLDER'], 'test.git'), 'test.jpg')
  2580. # Check if button exists
  2581. output = self.app.get('/test/blob/master/f/sources')
  2582. self.assertEqual(output.status_code, 200)
  2583. self.assertIn(
  2584. 'Fork and Edit\n </button>\n',
  2585. output.get_data(as_text=True))
  2586. # Check fork-edit doesn't show for binary files
  2587. output = self.app.get('/test/blob/master/f/test.jpg')
  2588. self.assertEqual(output.status_code, 200)
  2589. self.assertNotIn(
  2590. 'Fork and Edit\n </button>\n',
  2591. output.get_data(as_text=True))
  2592. # Check for edit panel
  2593. output = self.app.post('fork_edit/test/edit/master/f/sources',
  2594. data=data, follow_redirects=True)
  2595. self.assertEqual(output.status_code, 200)
  2596. output_text = output.get_data(as_text=True)
  2597. self.assertIn(
  2598. '<li><a href="/fork/foo/test/tree/master">'
  2599. '<span class="fa fa-random"></span>&nbsp; master</a>'
  2600. '</li><li class="active"><span class="fa fa-file">'
  2601. '</span>&nbsp; sources</li>',
  2602. output_text)
  2603. self.assertIn(
  2604. '<textarea id="textareaCode" name="content">foo\n bar</textarea>',
  2605. output_text)
  2606. # View what's supposed to be an image
  2607. output = self.app.post('fork_edit/test/edit/master/f/test.jpg',
  2608. data=data, follow_redirects=True)
  2609. self.assertEqual(output.status_code, 400)
  2610. self.assertIn('<p>Cannot edit binary files</p>', output.get_data(as_text=True))
  2611. # Check fork-edit shows when user is not logged in
  2612. output = self.app.get('/test/blob/master/f/sources')
  2613. self.assertEqual(output.status_code, 200)
  2614. self.assertIn(
  2615. 'Fork and Edit\n </button>\n',
  2616. output.get_data(as_text=True))
  2617. # Check if fork-edit shows for different user
  2618. user.username = 'pingou'
  2619. with tests.user_set(self.app.application, user):
  2620. # Check if button exists
  2621. output = self.app.get('/test/blob/master/f/sources')
  2622. self.assertEqual(output.status_code, 200)
  2623. self.assertIn(
  2624. 'Edit in your fork\n </button>\n',
  2625. output.get_data(as_text=True))
  2626. # Check fork-edit doesn't show for binary
  2627. output = self.app.get('/test/blob/master/f/test.jpg')
  2628. self.assertEqual(output.status_code, 200)
  2629. self.assertNotIn(
  2630. 'Edit in your fork\n </button>\n',
  2631. output.get_data(as_text=True))
  2632. @patch('pagure.lib.notify.send_email')
  2633. def test_fork_without_main_repo(self, send_email):
  2634. """ Test the fork without the main repo. """
  2635. send_email.return_value = True
  2636. tests.create_projects(self.session)
  2637. # Create a fork with no parent i.e parent_id = None
  2638. item = pagure.lib.model.Project(
  2639. user_id=2, # foo
  2640. name='test',
  2641. description='test project #1',
  2642. hook_token='aaabbb',
  2643. is_fork=True,
  2644. parent_id=None,
  2645. )
  2646. self.session.add(item)
  2647. self.session.commit()
  2648. # Get fork project
  2649. project = pagure.lib._get_project(self.session, 'test', 'foo')
  2650. # Pull-requests and issue-trackers are off for forks
  2651. # lib function is not used here so mannually turning them off
  2652. project_settings = project.settings
  2653. project_settings['pull_requests'] = False
  2654. project_settings['issue_tracker'] = False
  2655. project.settings = project_settings
  2656. self.session.add(project)
  2657. self.session.commit()
  2658. tests.create_projects_git(
  2659. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  2660. # Create a git repo to play with
  2661. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  2662. self.assertFalse(os.path.exists(gitrepo))
  2663. os.makedirs(gitrepo)
  2664. repo = pygit2.init_repository(gitrepo, bare=True)
  2665. # Create a fork of this repo
  2666. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  2667. gitrepo = os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git')
  2668. new_repo = pygit2.clone_repository(gitrepo, newpath)
  2669. tests.add_content_git_repo(gitrepo)
  2670. # UI test for deleted main
  2671. output = self.app.get('/fork/foo/test')
  2672. self.assertEqual(output.status_code, 200)
  2673. self.assertIn('Forked from a deleted repository', output.get_data(as_text=True))
  2674. # Testing commit endpoint
  2675. output = self.app.get('/fork/foo/test/commits/master')
  2676. self.assertEqual(output.status_code, 200)
  2677. self.assertIn(
  2678. 'Commits <span class="badge badge-secondary"> 2</span>\n',
  2679. output.get_data(as_text=True))
  2680. # Test pull-request endpoint
  2681. output = self.app.get('/fork/foo/test/pull-requests')
  2682. self.assertEqual(output.status_code, 404)
  2683. # Test issue-tracker endpoint
  2684. output = self.app.get('/fork/foo/test/issues')
  2685. self.assertEqual(output.status_code, 404)
  2686. shutil.rmtree(newpath)
  2687. if __name__ == '__main__':
  2688. unittest.main(verbosity=2)