test_pagure_flask_ui_fork.py 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. __requires__ = ['SQLAlchemy >= 0.8']
  8. import pkg_resources
  9. import json
  10. import unittest
  11. import shutil
  12. import sys
  13. import tempfile
  14. import os
  15. import pygit2
  16. from mock import patch
  17. sys.path.insert(0, os.path.join(os.path.dirname(
  18. os.path.abspath(__file__)), '..'))
  19. import pagure
  20. import pagure.lib
  21. import tests
  22. from pagure.lib.repo import PagureRepo
  23. def _get_commits(output):
  24. ''' Returns the commits message in the output. All commits must have
  25. been made by `Alice Author` or `PY C` to be found.
  26. '''
  27. commits = []
  28. save = False
  29. cnt = 0
  30. for row in output.split('\n'):
  31. if row.strip() in ['Alice Author', 'Alice Äuthòr', 'PY C']:
  32. save = True
  33. if save:
  34. cnt += 1
  35. if cnt == 7:
  36. commits.append(row.strip())
  37. save = False
  38. cnt = 0
  39. return commits
  40. class PagureFlaskForktests(tests.Modeltests):
  41. """ Tests for flask fork controller of pagure """
  42. def setUp(self):
  43. """ Set up the environnment, ran before every tests. """
  44. super(PagureFlaskForktests, self).setUp()
  45. pagure.APP.config['TESTING'] = True
  46. pagure.SESSION = self.session
  47. pagure.lib.SESSION = self.session
  48. pagure.ui.SESSION = self.session
  49. pagure.ui.app.SESSION = self.session
  50. pagure.ui.filters.SESSION = self.session
  51. pagure.ui.fork.SESSION = self.session
  52. pagure.ui.repo.SESSION = self.session
  53. pagure.ui.issues.SESSION = self.session
  54. self.app = pagure.APP.test_client()
  55. def set_up_git_repo(
  56. self, new_project=None, branch_from='feature', mtype='FF'):
  57. """ Set up the git repo and create the corresponding PullRequest
  58. object.
  59. """
  60. # Create a git repo to play with
  61. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  62. repo = pygit2.init_repository(gitrepo, bare=True)
  63. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  64. repopath = os.path.join(newpath, 'test')
  65. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  66. # Create a file in that git repo
  67. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  68. stream.write('foo\n bar')
  69. clone_repo.index.add('sources')
  70. clone_repo.index.write()
  71. # Commits the files added
  72. tree = clone_repo.index.write_tree()
  73. author = pygit2.Signature(
  74. 'Alice Author', 'alice@authors.tld')
  75. committer = pygit2.Signature(
  76. 'Cecil Committer', 'cecil@committers.tld')
  77. clone_repo.create_commit(
  78. 'refs/heads/master', # the name of the reference to update
  79. author,
  80. committer,
  81. 'Add sources file for testing',
  82. # binary string representing the tree object ID
  83. tree,
  84. # list of binary strings representing parents of the new commit
  85. []
  86. )
  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. if mtype == 'merge':
  92. with open(os.path.join(repopath, '.gitignore'), 'w') as stream:
  93. stream.write('*~')
  94. clone_repo.index.add('.gitignore')
  95. clone_repo.index.write()
  96. # Commits the files added
  97. tree = clone_repo.index.write_tree()
  98. author = pygit2.Signature(
  99. 'Alice Äuthòr', 'alice@äuthòrs.tld')
  100. committer = pygit2.Signature(
  101. 'Cecil Cõmmîttër', 'cecil@cõmmîttërs.tld')
  102. clone_repo.create_commit(
  103. 'refs/heads/master',
  104. author,
  105. committer,
  106. 'Add .gitignore file for testing',
  107. # binary string representing the tree object ID
  108. tree,
  109. # list of binary strings representing parents of the new commit
  110. [first_commit.oid.hex]
  111. )
  112. refname = 'refs/heads/master:refs/heads/master'
  113. ori_remote = clone_repo.remotes[0]
  114. PagureRepo.push(ori_remote, refname)
  115. if mtype == 'conflicts':
  116. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  117. stream.write('foo\n bar\nbaz')
  118. clone_repo.index.add('sources')
  119. clone_repo.index.write()
  120. # Commits the files added
  121. tree = clone_repo.index.write_tree()
  122. author = pygit2.Signature(
  123. 'Alice Author', 'alice@authors.tld')
  124. committer = pygit2.Signature(
  125. 'Cecil Committer', 'cecil@committers.tld')
  126. clone_repo.create_commit(
  127. 'refs/heads/master',
  128. author,
  129. committer,
  130. 'Add sources conflicting',
  131. # binary string representing the tree object ID
  132. tree,
  133. # list of binary strings representing parents of the new commit
  134. [first_commit.oid.hex]
  135. )
  136. refname = 'refs/heads/master:refs/heads/master'
  137. ori_remote = clone_repo.remotes[0]
  138. PagureRepo.push(ori_remote, refname)
  139. # Set the second repo
  140. new_gitrepo = repopath
  141. if new_project:
  142. # Create a new git repo to play with
  143. new_gitrepo = os.path.join(newpath, new_project.fullname)
  144. if not os.path.exists(new_gitrepo):
  145. os.makedirs(new_gitrepo)
  146. new_repo = pygit2.clone_repository(gitrepo, new_gitrepo)
  147. repo = pygit2.Repository(new_gitrepo)
  148. if mtype != 'nochanges':
  149. # Edit the sources file again
  150. with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream:
  151. stream.write('foo\n bar\nbaz\n boose')
  152. repo.index.add('sources')
  153. repo.index.write()
  154. # Commits the files added
  155. tree = repo.index.write_tree()
  156. author = pygit2.Signature(
  157. 'Alice Author', 'alice@authors.tld')
  158. committer = pygit2.Signature(
  159. 'Cecil Committer', 'cecil@committers.tld')
  160. repo.create_commit(
  161. 'refs/heads/%s' % branch_from,
  162. author,
  163. committer,
  164. 'A commit on branch %s' % branch_from,
  165. tree,
  166. [first_commit.oid.hex]
  167. )
  168. refname = 'refs/heads/%s' % (branch_from)
  169. ori_remote = repo.remotes[0]
  170. PagureRepo.push(ori_remote, refname)
  171. # Create a PR for these changes
  172. project = pagure.get_authorized_project(self.session, 'test')
  173. req = pagure.lib.new_pull_request(
  174. session=self.session,
  175. repo_from=project,
  176. branch_from=branch_from,
  177. repo_to=project,
  178. branch_to='master',
  179. title='PR from the %s branch' % branch_from,
  180. user='pingou',
  181. requestfolder=None,
  182. )
  183. self.session.commit()
  184. self.assertEqual(req.id, 1)
  185. self.assertEqual(req.title, 'PR from the %s branch' % branch_from)
  186. shutil.rmtree(newpath)
  187. @patch('pagure.lib.notify.send_email')
  188. def test_request_pull(self, send_email):
  189. """ Test the request_pull endpoint. """
  190. send_email.return_value = True
  191. tests.create_projects(self.session)
  192. tests.create_projects_git(
  193. os.path.join(self.path, 'requests'), bare=True)
  194. # Non-existant project
  195. output = self.app.get('/foobar/pull-request/1')
  196. self.assertEqual(output.status_code, 404)
  197. # Project has no PR
  198. output = self.app.get('/test/pull-request/1')
  199. self.assertEqual(output.status_code, 404)
  200. self.set_up_git_repo(new_project=None, branch_from='feature')
  201. project = pagure.get_authorized_project(self.session, 'test')
  202. self.assertEqual(len(project.requests), 1)
  203. # View the pull-request
  204. output = self.app.get('/test/pull-request/1')
  205. self.assertEqual(output.status_code, 200)
  206. self.assertIn(
  207. '<h3><span class="label label-default">PR#1</span>\n'
  208. ' PR from the feature branch\n</h3>', output.data)
  209. self.assertIn(
  210. 'title="View file as of 2a552b">sources</a>', output.data)
  211. # Test if the `open changed file icon` is displayed.
  212. self.assertIn(
  213. 'class="open_changed_file_icon_wrap"><span '
  214. 'class="oi open_changed_file_icon" data-glyph="eye" '
  215. 'alt="Open changed file" title="Open changed file"></span>'
  216. '</a>', output.data)
  217. @patch('pagure.lib.notify.send_email')
  218. def test_merge_request_pull_FF(self, send_email):
  219. """ Test the merge_request_pull endpoint with a FF PR. """
  220. send_email.return_value = True
  221. self.test_request_pull()
  222. user = tests.FakeUser()
  223. with tests.user_set(pagure.APP, user):
  224. output = self.app.get('/test/pull-request/1')
  225. self.assertEqual(output.status_code, 200)
  226. csrf_token = output.data.split(
  227. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  228. # No CSRF
  229. output = self.app.post(
  230. '/test/pull-request/1/merge', data={}, follow_redirects=True)
  231. self.assertEqual(output.status_code, 200)
  232. self.assertIn(
  233. '<title>PR#1: PR from the feature branch - test\n - '
  234. 'Pagure</title>', output.data)
  235. self.assertIn(
  236. '<h3><span class="label label-default">PR#1</span>\n'
  237. ' PR from the feature branch\n</h3>', output.data)
  238. self.assertIn(
  239. 'title="View file as of 2a552b">sources</a>', output.data)
  240. # Wrong project
  241. data = {
  242. 'csrf_token': csrf_token,
  243. }
  244. output = self.app.post(
  245. '/foobar/pull-request/100/merge', data=data, follow_redirects=True)
  246. self.assertEqual(output.status_code, 404)
  247. # Wrong project
  248. data = {
  249. 'csrf_token': csrf_token,
  250. }
  251. output = self.app.post(
  252. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  253. self.assertEqual(output.status_code, 403)
  254. user.username = 'pingou'
  255. with tests.user_set(pagure.APP, user):
  256. # Wrong request id
  257. data = {
  258. 'csrf_token': csrf_token,
  259. }
  260. output = self.app.post(
  261. '/test/pull-request/100/merge', data=data, follow_redirects=True)
  262. self.assertEqual(output.status_code, 404)
  263. # Project w/o pull-request
  264. repo = pagure.get_authorized_project(self.session, 'test')
  265. settings = repo.settings
  266. settings['pull_requests'] = False
  267. repo.settings = settings
  268. self.session.add(repo)
  269. self.session.commit()
  270. # Pull-request disabled
  271. output = self.app.post(
  272. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  273. self.assertEqual(output.status_code, 404)
  274. # Project w pull-request but only assignee can merge
  275. settings['pull_requests'] = True
  276. settings['Only_assignee_can_merge_pull-request'] = True
  277. repo.settings = settings
  278. self.session.add(repo)
  279. self.session.commit()
  280. output = self.app.post(
  281. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  282. self.assertEqual(output.status_code, 200)
  283. self.assertIn(
  284. '<title>PR#1: PR from the feature branch - test\n - '
  285. 'Pagure</title>', output.data)
  286. self.assertIn(
  287. '<h3><span class="label label-default">PR#1</span>\n'
  288. ' PR from the feature branch\n <span class="pull-xs-right">',
  289. output.data)
  290. self.assertIn(
  291. '</button>\n This request must be '
  292. 'assigned to be merged', output.data)
  293. # PR assigned but not to this user
  294. repo = pagure.get_authorized_project(self.session, 'test')
  295. req = repo.requests[0]
  296. req.assignee_id = 2
  297. self.session.add(req)
  298. self.session.commit()
  299. output = self.app.post(
  300. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  301. self.assertEqual(output.status_code, 200)
  302. self.assertIn(
  303. '<h3><span class="label label-default">PR#1</span>\n'
  304. ' PR from the feature branch\n <span class="pull-xs-right">',
  305. output.data)
  306. self.assertIn(
  307. '</button>\n Only the assignee can '
  308. 'merge this review', output.data)
  309. # Project w/ minimal PR score
  310. settings['Only_assignee_can_merge_pull-request'] = False
  311. settings['Minimum_score_to_merge_pull-request'] = 2
  312. repo.settings = settings
  313. self.session.add(repo)
  314. self.session.commit()
  315. output = self.app.post(
  316. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  317. self.assertEqual(output.status_code, 200)
  318. self.assertIn(
  319. '<h3><span class="label label-default">PR#1</span>\n'
  320. ' PR from the feature branch\n <span class="pull-xs-right">',
  321. output.data)
  322. self.assertIn(
  323. '</button>\n This request does not '
  324. 'have the minimum review score necessary to be merged',
  325. output.data)
  326. # Merge
  327. settings['Minimum_score_to_merge_pull-request'] = -1
  328. repo.settings = settings
  329. self.session.add(repo)
  330. self.session.commit()
  331. output = self.app.post(
  332. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  333. self.assertEqual(output.status_code, 200)
  334. self.assertIn(
  335. '<title>Overview - test - Pagure</title>', output.data)
  336. self.assertIn(
  337. 'A commit on branch feature', output.data)
  338. self.assertNotIn(
  339. 'Merge #1 `PR from the feature branch`', output.data)
  340. # Ensure we have the new commit
  341. commits = _get_commits(output.data)
  342. self.assertEqual(
  343. commits,
  344. [
  345. 'A commit on branch feature',
  346. 'Add sources file for testing'
  347. ]
  348. )
  349. # Check if the closing notification was added
  350. output = self.app.get('/test/pull-request/1')
  351. self.assertIn(
  352. '<small><p>Pull-Request has been merged by pingou</p></small>',
  353. output.data)
  354. @patch('pagure.lib.notify.send_email')
  355. def test_merge_request_pull_merge(self, send_email):
  356. """ Test the merge_request_pull endpoint with a merge PR. """
  357. send_email.return_value = True
  358. tests.create_projects(self.session)
  359. tests.create_projects_git(
  360. os.path.join(self.path, 'requests'), bare=True)
  361. self.set_up_git_repo(
  362. new_project=None, branch_from='feature', mtype='merge')
  363. user = tests.FakeUser()
  364. user.username = 'pingou'
  365. with tests.user_set(pagure.APP, user):
  366. output = self.app.get('/test/pull-request/1')
  367. self.assertEqual(output.status_code, 200)
  368. csrf_token = output.data.split(
  369. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  370. data = {
  371. 'csrf_token': csrf_token,
  372. }
  373. # Merge
  374. output = self.app.post(
  375. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  376. self.assertEqual(output.status_code, 200)
  377. self.assertIn(
  378. '<title>Overview - test - Pagure</title>', output.data)
  379. # Check if the closing notification was added
  380. output = self.app.get('/test/pull-request/1')
  381. self.assertIn(
  382. '<small><p>Pull-Request has been merged by pingou</p></small>',
  383. output.data)
  384. @patch('pagure.lib.notify.send_email')
  385. def test_merge_request_pull_conflicts(self, send_email):
  386. """ Test the merge_request_pull endpoint with a conflicting PR. """
  387. send_email.return_value = True
  388. tests.create_projects(self.session)
  389. tests.create_projects_git(
  390. os.path.join(self.path, 'requests'), bare=True)
  391. self.set_up_git_repo(
  392. new_project=None, branch_from='feature', mtype='conflicts')
  393. user = tests.FakeUser()
  394. user.username = 'pingou'
  395. with tests.user_set(pagure.APP, user):
  396. output = self.app.get('/test/pull-request/1')
  397. self.assertEqual(output.status_code, 200)
  398. csrf_token = output.data.split(
  399. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  400. data = {
  401. 'csrf_token': csrf_token,
  402. }
  403. # Merge conflicts
  404. output = self.app.post(
  405. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  406. self.assertEqual(output.status_code, 200)
  407. self.assertIn(
  408. '<h3><span class="label label-default">PR#1</span>\n'
  409. ' PR from the feature branch\n <span class="pull-xs-right">',
  410. output.data)
  411. self.assertIn('Merge conflicts!', output.data)
  412. @patch('pagure.lib.notify.send_email')
  413. def test_merge_request_pull_nochange(self, send_email):
  414. """ Test the merge_request_pull endpoint. """
  415. send_email.return_value = True
  416. tests.create_projects(self.session)
  417. tests.create_projects_git(
  418. os.path.join(self.path, 'requests'), bare=True)
  419. self.set_up_git_repo(
  420. new_project=None, branch_from='master', mtype='nochanges')
  421. user = tests.FakeUser()
  422. user.username = 'pingou'
  423. with tests.user_set(pagure.APP, user):
  424. output = self.app.get('/test/pull-request/1')
  425. self.assertEqual(output.status_code, 200)
  426. csrf_token = output.data.split(
  427. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  428. data = {
  429. 'csrf_token': csrf_token,
  430. }
  431. # Nothing to merge
  432. output = self.app.post(
  433. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  434. self.assertEqual(output.status_code, 200)
  435. self.assertIn(
  436. '<h3><span class="label label-default">PR#1</span>\n'
  437. ' <span class="label label-success">Merged</span>',
  438. output.data)
  439. self.assertIn('Nothing to do, changes were already merged',
  440. output.data)
  441. # Check if the closing notification was added
  442. output = self.app.get('/test/pull-request/1')
  443. self.assertIn(
  444. '<small><p>Pull-Request has been merged by pingou</p></small>',
  445. output.data)
  446. @patch('pagure.lib.notify.send_email')
  447. def test_request_pull_close(self, send_email):
  448. """ Test the request_pull endpoint with a closed PR. """
  449. send_email.return_value = True
  450. self.test_merge_request_pull_FF()
  451. output = self.app.get('/test/pull-request/1')
  452. self.assertEqual(output.status_code, 200)
  453. self.assertIn(
  454. '<h3><span class="label label-default">PR#1</span>\n'
  455. ' <span class="label label-success">', output.data)
  456. self.assertIn('<div>Merged by\n', output.data)
  457. self.assertIn(
  458. 'title="View file as of 2a552b">sources</a>', output.data)
  459. @patch('pagure.lib.notify.send_email')
  460. def test_request_pull_disabled(self, send_email):
  461. """ Test the request_pull endpoint with PR disabled. """
  462. send_email.return_value = True
  463. tests.create_projects(self.session)
  464. tests.create_projects_git(
  465. os.path.join(self.path, 'requests'), bare=True)
  466. self.set_up_git_repo(new_project=None, branch_from='feature')
  467. # Project w/o pull-request
  468. repo = pagure.get_authorized_project(self.session, 'test')
  469. settings = repo.settings
  470. settings['pull_requests'] = False
  471. repo.settings = settings
  472. self.session.add(repo)
  473. self.session.commit()
  474. output = self.app.get('/test/pull-request/1')
  475. self.assertEqual(output.status_code, 404)
  476. @patch('pagure.lib.notify.send_email')
  477. def test_request_pull_empty_repo(self, send_email):
  478. """ Test the request_pull endpoint against an empty repo. """
  479. send_email.return_value = True
  480. tests.create_projects(self.session)
  481. item = pagure.lib.model.Project(
  482. user_id=2, # foo
  483. name='test',
  484. description='test project #1',
  485. hook_token='aaabbb',
  486. is_fork=True,
  487. parent_id=1,
  488. )
  489. self.session.add(item)
  490. self.session.commit()
  491. tests.create_projects_git(
  492. os.path.join(self.path, 'requests'), bare=True)
  493. tests.create_projects_git(
  494. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  495. # Create a git repo to play with
  496. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  497. self.assertFalse(os.path.exists(gitrepo))
  498. os.makedirs(gitrepo)
  499. repo = pygit2.init_repository(gitrepo, bare=True)
  500. # Create a fork of this repo
  501. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  502. gitrepo = os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git')
  503. new_repo = pygit2.clone_repository(gitrepo, newpath)
  504. # Edit the sources file again
  505. with open(os.path.join(newpath, 'sources'), 'w') as stream:
  506. stream.write('foo\n bar\nbaz\n boose')
  507. new_repo.index.add('sources')
  508. new_repo.index.write()
  509. # Commits the files added
  510. tree = new_repo.index.write_tree()
  511. author = pygit2.Signature(
  512. 'Alice Author', 'alice@authors.tld')
  513. committer = pygit2.Signature(
  514. 'Cecil Committer', 'cecil@committers.tld')
  515. new_repo.create_commit(
  516. 'refs/heads/feature',
  517. author,
  518. committer,
  519. 'A commit on branch feature',
  520. tree,
  521. []
  522. )
  523. refname = 'refs/heads/feature:refs/heads/feature'
  524. ori_remote = new_repo.remotes[0]
  525. PagureRepo.push(ori_remote, refname)
  526. # Create a PR for these changes
  527. project = pagure.get_authorized_project(self.session, 'test')
  528. req = pagure.lib.new_pull_request(
  529. session=self.session,
  530. repo_from=item,
  531. branch_from='feature',
  532. repo_to=project,
  533. branch_to='master',
  534. title='PR from the feature branch',
  535. user='pingou',
  536. requestfolder=None,
  537. )
  538. self.session.commit()
  539. self.assertEqual(req.id, 1)
  540. self.assertEqual(req.title, 'PR from the feature branch')
  541. output = self.app.get('/test/pull-request/1')
  542. self.assertEqual(output.status_code, 200)
  543. self.assertIn(
  544. '<h3><span class="label label-default">PR#1</span>\n'
  545. ' PR from the feature branch\n</h3>', output.data)
  546. self.assertTrue(
  547. output.data.count('<span class="commitdate" title='), 1)
  548. shutil.rmtree(newpath)
  549. @patch('pagure.lib.notify.send_email')
  550. def test_request_pull_empty_fork(self, send_email):
  551. """ Test the request_pull endpoint from an empty fork. """
  552. send_email.return_value = True
  553. tests.create_projects(self.session)
  554. item = pagure.lib.model.Project(
  555. user_id=2, # foo
  556. name='test',
  557. description='test project #1',
  558. hook_token='aaabbb',
  559. is_fork=True,
  560. parent_id=1,
  561. )
  562. self.session.add(item)
  563. self.session.commit()
  564. tests.create_projects_git(
  565. os.path.join(self.path, 'requests'), bare=True)
  566. tests.create_projects_git(
  567. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  568. # Create a git repo to play with
  569. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  570. self.assertFalse(os.path.exists(gitrepo))
  571. os.makedirs(gitrepo)
  572. repo = pygit2.init_repository(gitrepo, bare=True)
  573. # Create a fork of this repo
  574. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  575. gitrepo = os.path.join(
  576. self.path, 'repos', 'forks', 'foo', 'test.git')
  577. new_repo = pygit2.clone_repository(gitrepo, newpath)
  578. # Create a PR for these "changes" (there are none, both repos are
  579. # empty)
  580. project = pagure.get_authorized_project(self.session, 'test')
  581. req = pagure.lib.new_pull_request(
  582. session=self.session,
  583. repo_from=item,
  584. branch_from='feature',
  585. repo_to=project,
  586. branch_to='master',
  587. title='PR from the feature branch',
  588. user='pingou',
  589. requestfolder=None,
  590. )
  591. self.session.commit()
  592. self.assertEqual(req.id, 1)
  593. self.assertEqual(req.title, 'PR from the feature branch')
  594. output = self.app.get('/test/pull-request/1', follow_redirects=True)
  595. self.assertEqual(output.status_code, 200)
  596. self.assertIn(
  597. '<title>Overview - test - Pagure</title>', output.data)
  598. self.assertIn(
  599. '</button>\n Fork is empty, there are no '
  600. 'commits to create a pull request with', output.data)
  601. shutil.rmtree(newpath)
  602. @patch('pagure.lib.notify.send_email')
  603. def test_request_pulls(self, send_email):
  604. """ Test the request_pulls endpoint. """
  605. send_email.return_value = True
  606. # No such project
  607. output = self.app.get('/test/pull-requests')
  608. self.assertEqual(output.status_code, 404)
  609. tests.create_projects(self.session)
  610. tests.create_projects_git(
  611. os.path.join(self.path, 'repos'), bare=True)
  612. output = self.app.get('/test/pull-requests')
  613. self.assertEqual(output.status_code, 200)
  614. self.assertIn(
  615. '<h2 class="p-b-1">\n 0 Pull Requests (of 0)\n </h2>',
  616. output.data)
  617. # Open is primary
  618. self.assertIn(
  619. '<a class="btn btn-primary btn-sm" '
  620. 'href="/test/pull-requests">Open</a>', output.data)
  621. self.assertIn(
  622. '<a class="btn btn-secondary btn-sm" '
  623. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  624. self.set_up_git_repo(new_project=None, branch_from='feature')
  625. output = self.app.get('/test/pull-requests')
  626. self.assertEqual(output.status_code, 200)
  627. self.assertIn(
  628. '<h2 class="p-b-1">\n 1 Pull Requests (of 1)\n </h2>',
  629. output.data)
  630. # Open is primary
  631. self.assertIn(
  632. '<a class="btn btn-primary btn-sm" '
  633. 'href="/test/pull-requests">Open</a>', output.data)
  634. self.assertIn(
  635. '<a class="btn btn-secondary btn-sm" '
  636. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  637. output = self.app.get('/test/pull-requests?status=Closed')
  638. self.assertEqual(output.status_code, 200)
  639. self.assertIn(
  640. '<h2 class="p-b-1">\n 0 Closed Pull Requests (of 0)\n </h2>',
  641. output.data)
  642. # Close is primary
  643. self.assertIn(
  644. '<a class="btn btn-secondary btn-sm" '
  645. 'href="/test/pull-requests">Open</a>', output.data)
  646. self.assertIn(
  647. '<a class="btn btn-primary btn-sm" '
  648. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  649. output = self.app.get('/test/pull-requests?status=0')
  650. self.assertEqual(output.status_code, 200)
  651. self.assertIn(
  652. '<h2 class="p-b-1">\n 0 Closed/Merged Pull Requests (of 0)\n </h2>',
  653. output.data)
  654. # Close is primary
  655. self.assertIn(
  656. '<a class="btn btn-secondary btn-sm" '
  657. 'href="/test/pull-requests">Open</a>', output.data)
  658. self.assertIn(
  659. '<a class="btn btn-primary btn-sm" '
  660. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  661. # Project w/o pull-request
  662. repo = pagure.get_authorized_project(self.session, 'test')
  663. settings = repo.settings
  664. settings['pull_requests'] = False
  665. repo.settings = settings
  666. self.session.add(repo)
  667. self.session.commit()
  668. output = self.app.get('/test/pull-requests')
  669. self.assertEqual(output.status_code, 404)
  670. @patch('pagure.lib.notify.send_email')
  671. def test_request_pull_patch(self, send_email):
  672. """ Test the request_pull_patch endpoint. """
  673. send_email.return_value = True
  674. output = self.app.get('/test/pull-request/1.patch')
  675. self.assertEqual(output.status_code, 404)
  676. tests.create_projects(self.session)
  677. tests.create_projects_git(
  678. os.path.join(self.path, 'requests'), bare=True)
  679. self.set_up_git_repo(
  680. new_project=None, branch_from='feature', mtype='merge')
  681. output = self.app.get('/test/pull-request/100.patch')
  682. self.assertEqual(output.status_code, 404)
  683. output = self.app.get('/test/pull-request/1.patch')
  684. self.assertEqual(output.status_code, 200)
  685. npatch = []
  686. for row in output.data.split('\n'):
  687. if row.startswith('Date:'):
  688. continue
  689. if row.startswith('From '):
  690. row = row.split(' ', 2)[2]
  691. npatch.append(row)
  692. exp = """Mon Sep 17 00:00:00 2001
  693. From: Alice Author <alice@authors.tld>
  694. Subject: A commit on branch feature
  695. ---
  696. diff --git a/.gitignore b/.gitignore
  697. new file mode 100644
  698. index 0000000..e4e5f6c
  699. --- /dev/null
  700. +++ b/.gitignore
  701. @@ -0,0 +1 @@
  702. +*~
  703. \ No newline at end of file
  704. diff --git a/sources b/sources
  705. index 9f44358..2a552bb 100644
  706. --- a/sources
  707. +++ b/sources
  708. @@ -1,2 +1,4 @@
  709. foo
  710. - bar
  711. \ No newline at end of file
  712. + bar
  713. +baz
  714. + boose
  715. \ No newline at end of file
  716. """
  717. patch = '\n'.join(npatch)
  718. #print patch
  719. self.assertEqual(patch, exp)
  720. # Project w/o pull-request
  721. repo = pagure.get_authorized_project(self.session, 'test')
  722. settings = repo.settings
  723. settings['pull_requests'] = False
  724. repo.settings = settings
  725. self.session.add(repo)
  726. self.session.commit()
  727. output = self.app.get('/test/pull-request/1.patch')
  728. self.assertEqual(output.status_code, 404)
  729. @patch('pagure.lib.notify.send_email')
  730. def test_request_pull_patch_close(self, send_email):
  731. """ Test the request_pull_patch endpoint with a closed PR. """
  732. send_email.return_value = True
  733. self.test_merge_request_pull_FF()
  734. output = self.app.get('/test/pull-request/1.patch')
  735. self.assertEqual(output.status_code, 200)
  736. npatch = []
  737. for row in output.data.split('\n'):
  738. if row.startswith('Date:'):
  739. continue
  740. if row.startswith('From '):
  741. row = row.split(' ', 2)[2]
  742. npatch.append(row)
  743. exp = """Mon Sep 17 00:00:00 2001
  744. From: Alice Author <alice@authors.tld>
  745. Subject: A commit on branch feature
  746. ---
  747. diff --git a/sources b/sources
  748. index 9f44358..2a552bb 100644
  749. --- a/sources
  750. +++ b/sources
  751. @@ -1,2 +1,4 @@
  752. foo
  753. - bar
  754. \ No newline at end of file
  755. + bar
  756. +baz
  757. + boose
  758. \ No newline at end of file
  759. """
  760. patch = '\n'.join(npatch)
  761. #print patch
  762. self.assertEqual(patch, exp)
  763. @patch('pagure.lib.notify.send_email')
  764. def test_request_pull_patch_empty_repo(self, send_email):
  765. """ Test the request_pull_patch endpoint against an empty repo. """
  766. send_email.return_value = True
  767. tests.create_projects(self.session)
  768. item = pagure.lib.model.Project(
  769. user_id=2, # foo
  770. name='test',
  771. description='test project #1',
  772. hook_token='aaabbb',
  773. is_fork=True,
  774. parent_id=1,
  775. )
  776. self.session.add(item)
  777. self.session.commit()
  778. tests.create_projects_git(
  779. os.path.join(self.path, 'requests'), bare=True)
  780. tests.create_projects_git(
  781. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  782. # Create a git repo to play with
  783. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  784. self.assertFalse(os.path.exists(gitrepo))
  785. os.makedirs(gitrepo)
  786. repo = pygit2.init_repository(gitrepo, bare=True)
  787. # Create a fork of this repo
  788. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  789. gitrepo = os.path.join(
  790. self.path, 'repos', 'forks', 'foo', 'test.git')
  791. new_repo = pygit2.clone_repository(gitrepo, newpath)
  792. # Edit the sources file again
  793. with open(os.path.join(newpath, 'sources'), 'w') as stream:
  794. stream.write('foo\n bar\nbaz\n boose')
  795. new_repo.index.add('sources')
  796. new_repo.index.write()
  797. # Commits the files added
  798. tree = new_repo.index.write_tree()
  799. author = pygit2.Signature(
  800. 'Alice Author', 'alice@authors.tld')
  801. committer = pygit2.Signature(
  802. 'Cecil Committer', 'cecil@committers.tld')
  803. new_repo.create_commit(
  804. 'refs/heads/feature',
  805. author,
  806. committer,
  807. 'A commit on branch feature',
  808. tree,
  809. []
  810. )
  811. refname = 'refs/heads/feature:refs/heads/feature'
  812. ori_remote = new_repo.remotes[0]
  813. PagureRepo.push(ori_remote, refname)
  814. # Create a PR for these "changes" (there are none, both repos are
  815. # empty)
  816. project = pagure.get_authorized_project(self.session, 'test')
  817. req = pagure.lib.new_pull_request(
  818. session=self.session,
  819. repo_from=item,
  820. branch_from='feature',
  821. repo_to=project,
  822. branch_to='master',
  823. title='PR from the feature branch',
  824. user='pingou',
  825. requestfolder=None,
  826. )
  827. self.session.commit()
  828. self.assertEqual(req.id, 1)
  829. self.assertEqual(req.title, 'PR from the feature branch')
  830. output = self.app.get(
  831. '/test/pull-request/1.patch', follow_redirects=True)
  832. self.assertEqual(output.status_code, 200)
  833. npatch = []
  834. for row in output.data.split('\n'):
  835. if row.startswith('Date:'):
  836. continue
  837. if row.startswith('From '):
  838. row = row.split(' ', 2)[2]
  839. npatch.append(row)
  840. exp = """Mon Sep 17 00:00:00 2001
  841. From: Alice Author <alice@authors.tld>
  842. Subject: A commit on branch feature
  843. ---
  844. diff --git a/sources b/sources
  845. new file mode 100644
  846. index 0000000..2a552bb
  847. --- /dev/null
  848. +++ b/sources
  849. @@ -0,0 +1,4 @@
  850. +foo
  851. + bar
  852. +baz
  853. + boose
  854. \ No newline at end of file
  855. """
  856. patch = '\n'.join(npatch)
  857. #print patch
  858. self.assertEqual(patch, exp)
  859. shutil.rmtree(newpath)
  860. @patch('pagure.lib.notify.send_email')
  861. def test_request_pull_patch_empty_fork(self, send_email):
  862. """ Test the request_pull_patch endpoint from an empty fork. """
  863. send_email.return_value = True
  864. tests.create_projects(self.session)
  865. item = pagure.lib.model.Project(
  866. user_id=2, # foo
  867. name='test',
  868. description='test project #1',
  869. hook_token='aaabbb',
  870. is_fork=True,
  871. parent_id=1,
  872. )
  873. self.session.add(item)
  874. self.session.commit()
  875. tests.create_projects_git(
  876. os.path.join(self.path, 'requests'), bare=True)
  877. tests.create_projects_git(
  878. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  879. # Create a git repo to play with
  880. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  881. self.assertFalse(os.path.exists(gitrepo))
  882. os.makedirs(gitrepo)
  883. repo = pygit2.init_repository(gitrepo, bare=True)
  884. # Create a fork of this repo
  885. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  886. gitrepo = os.path.join(
  887. self.path, 'repos', 'forks', 'foo', 'test.git')
  888. new_repo = pygit2.clone_repository(gitrepo, newpath)
  889. # Create a PR for these "changes" (there are none, both repos are
  890. # empty)
  891. project = pagure.get_authorized_project(self.session, 'test')
  892. req = pagure.lib.new_pull_request(
  893. session=self.session,
  894. repo_from=item,
  895. branch_from='feature',
  896. repo_to=project,
  897. branch_to='master',
  898. title='PR from the feature branch',
  899. user='pingou',
  900. requestfolder=None,
  901. )
  902. self.session.commit()
  903. self.assertEqual(req.id, 1)
  904. self.assertEqual(req.title, 'PR from the feature branch')
  905. output = self.app.get('/test/pull-request/1.patch', follow_redirects=True)
  906. self.assertEqual(output.status_code, 200)
  907. self.assertIn(
  908. '<title>Overview - test - Pagure</title>', output.data)
  909. self.assertIn(
  910. '</button>\n Fork is empty, there are no '
  911. 'commits to create a pull request with', output.data)
  912. shutil.rmtree(newpath)
  913. @patch('pagure.lib.notify.send_email')
  914. def test_cancel_request_pull(self, send_email):
  915. """ Test the cancel_request_pull endpoint. """
  916. send_email.return_value = True
  917. tests.create_projects(self.session)
  918. tests.create_projects_git(
  919. os.path.join(self.path, 'requests'), bare=True)
  920. self.set_up_git_repo(
  921. new_project=None, branch_from='feature', mtype='merge')
  922. user = tests.FakeUser()
  923. with tests.user_set(pagure.APP, user):
  924. output = self.app.post('/test/pull-request/cancel/1')
  925. self.assertEqual(output.status_code, 302)
  926. output = self.app.post(
  927. '/test/pull-request/cancel/1', follow_redirects=True)
  928. self.assertEqual(output.status_code, 200)
  929. self.assertIn(
  930. '<title>Overview - test - Pagure</title>', output.data)
  931. self.assertIn(
  932. '</button>\n Invalid input submitted',
  933. output.data)
  934. output = self.app.get('/test/pull-request/1')
  935. self.assertEqual(output.status_code, 200)
  936. csrf_token = output.data.split(
  937. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  938. data = {
  939. 'csrf_token': csrf_token,
  940. }
  941. # Invalid project
  942. output = self.app.post(
  943. '/foo/pull-request/cancel/1', data=data,
  944. follow_redirects=True)
  945. self.assertEqual(output.status_code, 404)
  946. # Invalid PR id
  947. output = self.app.post(
  948. '/test/pull-request/cancel/100', data=data,
  949. follow_redirects=True)
  950. self.assertEqual(output.status_code, 404)
  951. # Invalid user for this project
  952. output = self.app.post(
  953. '/test/pull-request/cancel/1', data=data,
  954. follow_redirects=True)
  955. self.assertEqual(output.status_code, 403)
  956. user.username = 'pingou'
  957. with tests.user_set(pagure.APP, user):
  958. # Project w/o pull-request
  959. repo = pagure.get_authorized_project(self.session, 'test')
  960. settings = repo.settings
  961. settings['pull_requests'] = False
  962. repo.settings = settings
  963. self.session.add(repo)
  964. self.session.commit()
  965. output = self.app.post(
  966. '/test/pull-request/cancel/1', data=data,
  967. follow_redirects=True)
  968. self.assertEqual(output.status_code, 404)
  969. # Project w/ pull-request
  970. repo = pagure.get_authorized_project(self.session, 'test')
  971. settings = repo.settings
  972. settings['pull_requests'] = True
  973. repo.settings = settings
  974. self.session.add(repo)
  975. self.session.commit()
  976. output = self.app.post(
  977. '/test/pull-request/cancel/1', data=data,
  978. follow_redirects=True)
  979. self.assertEqual(output.status_code, 200)
  980. self.assertIn(
  981. '<title>Overview - test - Pagure</title>', output.data)
  982. self.assertIn(
  983. '</button>\n Pull request canceled!',
  984. output.data)
  985. @patch('pagure.lib.notify.send_email')
  986. def test_set_assignee_requests(self, send_email):
  987. """ Test the set_assignee_requests endpoint. """
  988. send_email.return_value = True
  989. tests.create_projects(self.session)
  990. tests.create_projects_git(
  991. os.path.join(self.path, 'requests'), bare=True)
  992. self.set_up_git_repo(new_project=None, branch_from='feature')
  993. user = tests.FakeUser()
  994. user.username = 'pingou'
  995. with tests.user_set(pagure.APP, user):
  996. # No such project
  997. output = self.app.post('/foo/pull-request/1/assign')
  998. self.assertEqual(output.status_code, 404)
  999. output = self.app.post('/test/pull-request/100/assign')
  1000. self.assertEqual(output.status_code, 404)
  1001. # Invalid input
  1002. output = self.app.post(
  1003. '/test/pull-request/1/assign', follow_redirects=True)
  1004. self.assertEqual(output.status_code, 200)
  1005. self.assertIn(
  1006. '<title>PR#1: PR from the feature branch - test\n - '
  1007. 'Pagure</title>', output.data)
  1008. self.assertIn(
  1009. '<h3><span class="label label-default">PR#1</span>\n'
  1010. ' PR from the feature branch\n', output.data)
  1011. self.assertNotIn(
  1012. '</button>\n Request assigned',
  1013. output.data)
  1014. output = self.app.get('/test/pull-request/1')
  1015. self.assertEqual(output.status_code, 200)
  1016. csrf_token = output.data.split(
  1017. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1018. data = {
  1019. 'user': 'pingou',
  1020. }
  1021. # No CSRF
  1022. output = self.app.post(
  1023. '/test/pull-request/1/assign', data=data,
  1024. follow_redirects=True)
  1025. self.assertEqual(output.status_code, 200)
  1026. self.assertIn(
  1027. '<title>PR#1: PR from the feature branch - test\n - '
  1028. 'Pagure</title>', output.data)
  1029. self.assertIn(
  1030. '<h3><span class="label label-default">PR#1</span>\n'
  1031. ' PR from the feature branch\n', output.data)
  1032. self.assertNotIn(
  1033. '</button>\n Request assigned',
  1034. output.data)
  1035. # Invalid assignee
  1036. data = {
  1037. 'csrf_token': csrf_token,
  1038. 'user': 'bar',
  1039. }
  1040. output = self.app.post(
  1041. '/test/pull-request/1/assign', data=data,
  1042. follow_redirects=True)
  1043. self.assertEqual(output.status_code, 200)
  1044. self.assertIn(
  1045. '<title>PR#1: PR from the feature branch - test\n - '
  1046. 'Pagure</title>', output.data)
  1047. self.assertIn(
  1048. '<h3><span class="label label-default">PR#1</span>\n'
  1049. ' PR from the feature branch\n', output.data)
  1050. self.assertIn(
  1051. '</button>\n No user &#34;bar&#34; found',
  1052. output.data)
  1053. # Assign the PR
  1054. data = {
  1055. 'csrf_token': csrf_token,
  1056. 'user': 'pingou',
  1057. }
  1058. user.username = 'foo'
  1059. with tests.user_set(pagure.APP, user):
  1060. output = self.app.post(
  1061. '/test/pull-request/1/assign', data=data,
  1062. follow_redirects=True)
  1063. self.assertEqual(output.status_code, 403)
  1064. user.username = 'pingou'
  1065. with tests.user_set(pagure.APP, user):
  1066. output = self.app.post(
  1067. '/test/pull-request/1/assign', data=data,
  1068. follow_redirects=True)
  1069. self.assertEqual(output.status_code, 200)
  1070. self.assertIn(
  1071. '<title>PR#1: PR from the feature branch - test\n - '
  1072. 'Pagure</title>', output.data)
  1073. self.assertIn(
  1074. '<h3><span class="label label-default">PR#1</span>\n'
  1075. ' PR from the feature branch\n', output.data)
  1076. self.assertIn(
  1077. '</button>\n Request assigned',
  1078. output.data)
  1079. # Pull-Request closed
  1080. repo = pagure.get_authorized_project(self.session, 'test')
  1081. req = repo.requests[0]
  1082. req.status = 'Closed'
  1083. req.closed_by_in = 1
  1084. self.session.add(req)
  1085. self.session.commit()
  1086. output = self.app.post(
  1087. '/test/pull-request/1/assign', data=data,
  1088. follow_redirects=True)
  1089. self.assertEqual(output.status_code, 403)
  1090. # Project w/o pull-request
  1091. repo = pagure.get_authorized_project(self.session, 'test')
  1092. settings = repo.settings
  1093. settings['pull_requests'] = False
  1094. repo.settings = settings
  1095. self.session.add(repo)
  1096. self.session.commit()
  1097. output = self.app.post(
  1098. '/test/pull-request/1/assign', data=data,
  1099. follow_redirects=True)
  1100. self.assertEqual(output.status_code, 404)
  1101. @patch('pagure.lib.notify.send_email')
  1102. def test_fork_project(self, send_email):
  1103. """ Test the fork_project endpoint. """
  1104. send_email.return_value = True
  1105. tests.create_projects(self.session)
  1106. for folder in ['docs', 'tickets', 'requests', 'repos']:
  1107. tests.create_projects_git(
  1108. os.path.join(self.path, folder), bare=True)
  1109. user = tests.FakeUser()
  1110. user.username = 'pingou'
  1111. with tests.user_set(pagure.APP, user):
  1112. output = self.app.post('/do_fork/test')
  1113. self.assertEqual(output.status_code, 400)
  1114. output = self.app.get('/new/')
  1115. self.assertEqual(output.status_code, 200)
  1116. self.assertIn('<strong>Create new Project</strong>', output.data)
  1117. csrf_token = output.data.split(
  1118. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1119. data = {
  1120. 'csrf_token': csrf_token,
  1121. }
  1122. output = self.app.post(
  1123. '/do_fork/foo', data=data, follow_redirects=True)
  1124. self.assertEqual(output.status_code, 404)
  1125. user.username = 'foo'
  1126. with tests.user_set(pagure.APP, user):
  1127. output = self.app.post('/do_fork/test')
  1128. self.assertEqual(output.status_code, 400)
  1129. data = {
  1130. 'csrf_token': csrf_token,
  1131. }
  1132. output = self.app.post(
  1133. '/do_fork/test', data=data, follow_redirects=True)
  1134. self.assertEqual(output.status_code, 200)
  1135. @patch('pagure.lib.notify.send_email')
  1136. def test_new_request_pull(self, send_email):
  1137. """ Test the new_request_pull endpoint. """
  1138. send_email.return_value = True
  1139. self.test_fork_project()
  1140. tests.create_projects_git(
  1141. os.path.join(self.path, 'requests'), bare=True)
  1142. repo = pagure.get_authorized_project(self.session, 'test')
  1143. fork = pagure.get_authorized_project(self.session, 'test', user='foo')
  1144. self.set_up_git_repo(
  1145. new_project=fork, branch_from='feature', mtype='FF')
  1146. user = tests.FakeUser()
  1147. user.username = 'foo'
  1148. with tests.user_set(pagure.APP, user):
  1149. output = self.app.get('/foo/diff/master..feature')
  1150. self.assertEqual(output.status_code, 404)
  1151. output = self.app.get('/test/diff/master..foo')
  1152. self.assertEqual(output.status_code, 400)
  1153. output = self.app.get('/test/diff/foo..master')
  1154. self.assertEqual(output.status_code, 400)
  1155. output = self.app.get('/test/diff/feature..master')
  1156. self.assertEqual(output.status_code, 200)
  1157. self.assertIn(
  1158. '<title>Diff from master to feature - test\n - '
  1159. 'Pagure</title>', output.data)
  1160. self.assertIn(
  1161. '<p class="error"> No commits found </p>', output.data)
  1162. output = self.app.get('/test/diff/master..feature')
  1163. self.assertEqual(output.status_code, 200)
  1164. self.assertIn(
  1165. '<title>Diff from feature to master - test\n - '
  1166. 'Pagure</title>', output.data)
  1167. self.assertNotIn(
  1168. '<input type="submit" class="submit positive button" '
  1169. 'value="Create">', output.data)
  1170. user.username = 'pingou'
  1171. with tests.user_set(pagure.APP, user):
  1172. output = self.app.get('/test/diff/master..feature')
  1173. self.assertEqual(output.status_code, 200)
  1174. self.assertIn(
  1175. '<title>Create new Pull Request for master - test\n - '
  1176. 'Pagure</title>', output.data)
  1177. self.assertIn(
  1178. '<input type="submit" class="btn btn-primary" value="Create">',
  1179. output.data)
  1180. csrf_token = output.data.split(
  1181. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1182. # Case 1 - Add an initial comment
  1183. data = {
  1184. 'csrf_token': csrf_token,
  1185. 'title': 'foo bar PR',
  1186. 'initial_comment': 'Test Initial Comment',
  1187. }
  1188. output = self.app.post(
  1189. '/test/diff/master..feature', data=data, follow_redirects=True)
  1190. self.assertEqual(output.status_code, 200)
  1191. self.assertIn(
  1192. '<title>PR#2: foo bar PR - test\n - Pagure</title>',
  1193. output.data)
  1194. self.assertIn('<p>Test Initial Comment</p>', output.data)
  1195. # Test if the `open changed file icon` is displayed.
  1196. self.assertIn(
  1197. 'class="open_changed_file_icon_wrap"><span '
  1198. 'class="oi open_changed_file_icon" data-glyph="eye" '
  1199. 'alt="Open changed file" title="Open changed file"></span>'
  1200. '</a>', output.data)
  1201. # Case 2 - Add an empty initial comment
  1202. data = {
  1203. 'csrf_token': csrf_token,
  1204. 'title': 'foo bar PR',
  1205. 'initial_comment': '',
  1206. }
  1207. output = self.app.post(
  1208. '/test/diff/master..feature', data=data, follow_redirects=True)
  1209. self.assertEqual(output.status_code, 200)
  1210. self.assertIn(
  1211. '<title>PR#3: foo bar PR - test\n - Pagure</title>',
  1212. output.data)
  1213. self.assertNotIn('<div id="comment-', output.data)
  1214. @patch('pagure.lib.notify.send_email')
  1215. def test_request_pull_commit_start_stop(self, send_email):
  1216. """ Test the the commit start and stop of brand new PR. """
  1217. send_email.return_value = True
  1218. self.test_fork_project()
  1219. tests.create_projects_git(
  1220. os.path.join(self.path, 'requests'), bare=True)
  1221. repo = pagure.get_authorized_project(self.session, 'test')
  1222. fork = pagure.get_authorized_project(self.session, 'test', user='foo')
  1223. self.set_up_git_repo(
  1224. new_project=fork, branch_from='feature', mtype='FF')
  1225. user = tests.FakeUser()
  1226. user.username = 'pingou'
  1227. with tests.user_set(pagure.APP, user):
  1228. output = self.app.get('/test/diff/master..feature')
  1229. self.assertEqual(output.status_code, 200)
  1230. self.assertIn(
  1231. '<title>Create new Pull Request for master - test\n - '
  1232. 'Pagure</title>', output.data)
  1233. self.assertIn(
  1234. '<input type="submit" class="btn btn-primary" value="Create">',
  1235. output.data)
  1236. csrf_token = output.data.split(
  1237. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1238. # Case 1 - Add an initial comment
  1239. data = {
  1240. 'csrf_token': csrf_token,
  1241. 'title': 'foo bar PR',
  1242. 'initial_comment': 'Test Initial Comment',
  1243. }
  1244. output = self.app.post(
  1245. '/test/diff/master..feature', data=data, follow_redirects=True)
  1246. self.assertEqual(output.status_code, 200)
  1247. self.assertIn(
  1248. '<title>PR#2: foo bar PR - test\n - Pagure</title>',
  1249. output.data)
  1250. self.assertIn('<p>Test Initial Comment</p>', output.data)
  1251. # Check if commit start and stop have been set for PR#2
  1252. request = pagure.lib.search_pull_requests(
  1253. self.session, project_id=1, requestid=2)
  1254. self.assertIsNotNone(request.commit_start)
  1255. self.assertIsNotNone(request.commit_stop)
  1256. @patch('pagure.lib.notify.send_email')
  1257. def test_new_request_pull_empty_repo(self, send_email):
  1258. """ Test the new_request_pull endpoint against an empty repo. """
  1259. send_email.return_value = True
  1260. self.test_fork_project()
  1261. tests.create_projects_git(
  1262. os.path.join(self.path, 'requests'), bare=True)
  1263. repo = pagure.get_authorized_project(self.session, 'test')
  1264. fork = pagure.get_authorized_project(self.session, 'test', user='foo')
  1265. # Create a git repo to play with
  1266. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1267. repo = pygit2.init_repository(gitrepo, bare=True)
  1268. # Create a fork of this repo
  1269. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  1270. gitrepo = os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git')
  1271. new_repo = pygit2.clone_repository(gitrepo, newpath)
  1272. user = tests.FakeUser()
  1273. user.username = 'foo'
  1274. with tests.user_set(pagure.APP, user):
  1275. output = self.app.get(
  1276. '/fork/foo/test/diff/master..feature',
  1277. follow_redirects=True)
  1278. self.assertEqual(output.status_code, 400)
  1279. self.assertIn(
  1280. '<p>Fork is empty, there are no commits to create a '
  1281. 'pull request with</p>', output.data)
  1282. output = self.app.get('/test/new_issue')
  1283. csrf_token = output.data.split(
  1284. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1285. data = {
  1286. 'csrf_token': csrf_token,
  1287. 'title': 'foo bar PR',
  1288. }
  1289. output = self.app.post(
  1290. '/test/diff/master..feature', data=data, follow_redirects=True)
  1291. self.assertEqual(output.status_code, 400)
  1292. self.assertIn(
  1293. '<p>Fork is empty, there are no commits to create a '
  1294. 'pull request with</p>', output.data)
  1295. shutil.rmtree(newpath)
  1296. @patch('pagure.lib.notify.send_email')
  1297. def test_new_request_pull_empty_fork(self, send_email):
  1298. """ Test the new_request_pull endpoint against an empty repo. """
  1299. send_email.return_value = True
  1300. self.test_fork_project()
  1301. tests.create_projects_git(
  1302. os.path.join(self.path, 'requests'), bare=True)
  1303. repo = pagure.get_authorized_project(self.session, 'test')
  1304. fork = pagure.get_authorized_project(self.session, 'test', user='foo')
  1305. # Create a git repo to play with
  1306. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1307. repo = pygit2.init_repository(gitrepo, bare=True)
  1308. # Create a fork of this repo
  1309. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  1310. gitrepo = os.path.join(
  1311. self.path, 'repos', 'forks', 'foo', 'test.git')
  1312. new_repo = pygit2.clone_repository(gitrepo, newpath)
  1313. user = tests.FakeUser()
  1314. user.username = 'foo'
  1315. with tests.user_set(pagure.APP, user):
  1316. output = self.app.get(
  1317. '/fork/foo/test/diff/master..master', follow_redirects=True)
  1318. self.assertEqual(output.status_code, 400)
  1319. self.assertIn(
  1320. '<p>Fork is empty, there are no commits to create a '
  1321. 'pull request with</p>', output.data)
  1322. shutil.rmtree(newpath)
  1323. @patch('pagure.lib.notify.send_email')
  1324. def test_pull_request_add_comment(self, send_email):
  1325. """ Test the pull_request_add_comment endpoint. """
  1326. send_email.return_value = True
  1327. self.test_request_pull()
  1328. user = tests.FakeUser()
  1329. user.username = 'pingou'
  1330. with tests.user_set(pagure.APP, user):
  1331. output = self.app.post('/foo/pull-request/1/comment')
  1332. self.assertEqual(output.status_code, 404)
  1333. output = self.app.post('/test/pull-request/100/comment')
  1334. self.assertEqual(output.status_code, 404)
  1335. output = self.app.post('/test/pull-request/1/comment')
  1336. self.assertEqual(output.status_code, 200)
  1337. self.assertTrue(
  1338. output.data.startswith('\n<section class="add_comment">'))
  1339. csrf_token = output.data.split(
  1340. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1341. data = {
  1342. 'csrf_token': csrf_token,
  1343. 'comment': 'This look alright but we can do better',
  1344. }
  1345. output = self.app.post(
  1346. '/test/pull-request/1/comment', data=data,
  1347. follow_redirects=True)
  1348. self.assertEqual(output.status_code, 200)
  1349. self.assertIn(
  1350. '<title>PR#1: PR from the feature branch - test\n - '
  1351. 'Pagure</title>', output.data)
  1352. self.assertIn(
  1353. '</button>\n Comment added',
  1354. output.data)
  1355. # Project w/o pull-request
  1356. repo = pagure.get_authorized_project(self.session, 'test')
  1357. settings = repo.settings
  1358. settings['pull_requests'] = False
  1359. repo.settings = settings
  1360. self.session.add(repo)
  1361. self.session.commit()
  1362. output = self.app.post(
  1363. '/test/pull-request/1/comment', data=data,
  1364. follow_redirects=True)
  1365. self.assertEqual(output.status_code, 404)
  1366. @patch('pagure.lib.notify.send_email')
  1367. def test_pull_request_drop_comment(self, send_email):
  1368. """ Test the pull_request_drop_comment endpoint. """
  1369. send_email.return_value = True
  1370. self.test_pull_request_add_comment()
  1371. # Project w/ pull-request
  1372. repo = pagure.get_authorized_project(self.session, 'test')
  1373. settings = repo.settings
  1374. settings['pull_requests'] = True
  1375. repo.settings = settings
  1376. self.session.add(repo)
  1377. self.session.commit()
  1378. user = tests.FakeUser()
  1379. user.username = 'foo'
  1380. with tests.user_set(pagure.APP, user):
  1381. output = self.app.post('/foo/pull-request/1/comment/drop')
  1382. self.assertEqual(output.status_code, 404)
  1383. output = self.app.post('/test/pull-request/100/comment/drop')
  1384. self.assertEqual(output.status_code, 404)
  1385. output = self.app.post(
  1386. '/test/pull-request/1/comment/drop', follow_redirects=True)
  1387. self.assertEqual(output.status_code, 200)
  1388. self.assertIn(
  1389. '<h3><span class="label label-default">PR#1</span>\n'
  1390. ' PR from the feature branch\n</h3>', output.data)
  1391. #self.assertIn('href="#comment-1">¶</a>', output.data)
  1392. self.assertIn(
  1393. '<p>This look alright but we can do better</p>',
  1394. output.data)
  1395. csrf_token = output.data.split(
  1396. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1397. # Invalid comment id
  1398. data = {
  1399. 'csrf_token': csrf_token,
  1400. 'drop_comment': '10',
  1401. }
  1402. output = self.app.post(
  1403. '/test/pull-request/1/comment/drop', data=data,
  1404. follow_redirects=True)
  1405. self.assertEqual(output.status_code, 404)
  1406. data['drop_comment'] = '1'
  1407. output = self.app.post(
  1408. '/test/pull-request/1/comment/drop', data=data,
  1409. follow_redirects=True)
  1410. self.assertEqual(output.status_code, 403)
  1411. user.username = 'pingou'
  1412. with tests.user_set(pagure.APP, user):
  1413. # Drop comment
  1414. output = self.app.post(
  1415. '/test/pull-request/1/comment/drop', data=data,
  1416. follow_redirects=True)
  1417. self.assertEqual(output.status_code, 200)
  1418. self.assertIn(
  1419. '<h3><span class="label label-default">PR#1</span>\n'
  1420. ' PR from the feature branch\n <span class="pull-xs-right">',
  1421. output.data)
  1422. self.assertIn(
  1423. '</button>\n Comment removed',
  1424. output.data)
  1425. # Project w/o pull-request
  1426. repo = pagure.get_authorized_project(self.session, 'test')
  1427. settings = repo.settings
  1428. settings['pull_requests'] = False
  1429. repo.settings = settings
  1430. self.session.add(repo)
  1431. self.session.commit()
  1432. output = self.app.post(
  1433. '/test/pull-request/1/comment/drop', data=data,
  1434. follow_redirects=True)
  1435. self.assertEqual(output.status_code, 404)
  1436. @patch('pagure.lib.notify.send_email')
  1437. def test_pull_request_edit_comment(self, send_email):
  1438. """ Test the pull request edit comment endpoint """
  1439. send_email.return_value = True
  1440. self.test_request_pull()
  1441. user = tests.FakeUser()
  1442. user.username = 'pingou'
  1443. with tests.user_set(pagure.APP, user):
  1444. # Repo 'foo' does not exist so it is verifying that condition
  1445. output = self.app.post('/foo/pull-request/1/comment/1/edit')
  1446. self.assertEqual(output.status_code, 404)
  1447. # Here no comment is present in the PR so its verifying that condition
  1448. output = self.app.post('/test/pull-request/100/comment/100/edit')
  1449. self.assertEqual(output.status_code, 404)
  1450. output = self.app.post('/test/pull-request/1/comment')
  1451. self.assertEqual(output.status_code, 200)
  1452. # Creating comment to play with
  1453. self.assertTrue(
  1454. output.data.startswith('\n<section class="add_comment">'))
  1455. csrf_token = output.data.split(
  1456. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1457. data = {
  1458. 'csrf_token': csrf_token,
  1459. 'comment': 'This look alright but we can do better',
  1460. }
  1461. output = self.app.post(
  1462. '/test/pull-request/1/comment', data=data,
  1463. follow_redirects=True)
  1464. self.assertEqual(output.status_code, 200)
  1465. self.assertIn(
  1466. '<h3><span class="label label-default">PR#1</span>\n'
  1467. ' PR from the feature branch\n <span class="pull-xs-right">',
  1468. output.data)
  1469. self.assertIn(
  1470. '</button>\n Comment added',
  1471. output.data)
  1472. # Check if the comment is there
  1473. self.assertIn(
  1474. '<p>This look alright but we can do better</p>', output.data)
  1475. output = self.app.get('/test/pull-request/1/comment/1/edit')
  1476. self.assertEqual(output.status_code, 200)
  1477. self.assertIn('<section class="edit_comment">', output.data)
  1478. # Checking if the comment is there in the update page
  1479. self.assertIn(
  1480. 'This look alright but we can do better</textarea>', output.data)
  1481. csrf_token = output.data.split(
  1482. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1483. data = {
  1484. 'csrf_token': csrf_token,
  1485. 'update_comment': 'This look alright but we can do better than this.',
  1486. }
  1487. output = self.app.post(
  1488. '/test/pull-request/1/comment/1/edit', data=data,
  1489. follow_redirects=True)
  1490. # Checking if the comment is updated in the main page
  1491. self.assertIn(
  1492. '<p>This look alright but we can do better than this.</p>', output.data)
  1493. self.assertIn(
  1494. '<h3><span class="label label-default">PR#1</span>\n'
  1495. ' PR from the feature branch\n <span class="pull-xs-right">',
  1496. output.data)
  1497. # Checking if Edited by User is there or not
  1498. self.assertTrue(
  1499. '<small class="text-muted">Edited just now by pingou </small>'
  1500. in output.data
  1501. or
  1502. '<small class="text-muted">Edited seconds ago by pingou </small>'
  1503. in output.data)
  1504. self.assertIn(
  1505. '</button>\n Comment updated', output.data)
  1506. # Project w/o pull-request
  1507. repo = pagure.get_authorized_project(self.session, 'test')
  1508. settings = repo.settings
  1509. settings['pull_requests'] = False
  1510. repo.settings = settings
  1511. self.session.add(repo)
  1512. self.session.commit()
  1513. output = self.app.post(
  1514. '/test/pull-request/1/comment/edit/1', data=data,
  1515. follow_redirects=True)
  1516. self.assertEqual(output.status_code, 404)
  1517. @patch('pagure.lib.notify.send_email')
  1518. def test_merge_request_pull_FF_w_merge_commit(self, send_email):
  1519. """ Test the merge_request_pull endpoint with a FF PR but with a
  1520. merge commit.
  1521. """
  1522. send_email.return_value = True
  1523. self.test_request_pull()
  1524. user = tests.FakeUser()
  1525. with tests.user_set(pagure.APP, user):
  1526. output = self.app.get('/test/pull-request/1')
  1527. self.assertEqual(output.status_code, 200)
  1528. csrf_token = output.data.split(
  1529. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1530. # No CSRF
  1531. output = self.app.post(
  1532. '/test/pull-request/1/merge', data={}, follow_redirects=True)
  1533. self.assertEqual(output.status_code, 200)
  1534. self.assertIn(
  1535. '<title>PR#1: PR from the feature branch - test\n - '
  1536. 'Pagure</title>', output.data)
  1537. self.assertIn(
  1538. '<h3><span class="label label-default">PR#1</span>\n'
  1539. ' PR from the feature branch\n</h3>', output.data)
  1540. self.assertIn(
  1541. 'title="View file as of 2a552b">sources</a>', output.data)
  1542. # Wrong project
  1543. data = {
  1544. 'csrf_token': csrf_token,
  1545. }
  1546. output = self.app.post(
  1547. '/foobar/pull-request/100/merge', data=data, follow_redirects=True)
  1548. self.assertEqual(output.status_code, 404)
  1549. # Wrong project
  1550. data = {
  1551. 'csrf_token': csrf_token,
  1552. }
  1553. output = self.app.post(
  1554. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  1555. self.assertEqual(output.status_code, 403)
  1556. user.username = 'pingou'
  1557. with tests.user_set(pagure.APP, user):
  1558. # Wrong request id
  1559. data = {
  1560. 'csrf_token': csrf_token,
  1561. }
  1562. output = self.app.post(
  1563. '/test/pull-request/100/merge', data=data, follow_redirects=True)
  1564. self.assertEqual(output.status_code, 404)
  1565. # Project requiring a merge commit
  1566. repo = pagure.get_authorized_project(self.session, 'test')
  1567. settings = repo.settings
  1568. settings['always_merge'] = True
  1569. repo.settings = settings
  1570. self.session.add(repo)
  1571. self.session.commit()
  1572. # Merge
  1573. output = self.app.post(
  1574. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  1575. self.assertEqual(output.status_code, 200)
  1576. self.assertIn(
  1577. '<title>Overview - test - Pagure</title>', output.data)
  1578. self.assertIn(
  1579. 'Merge #1 `PR from the feature branch`', output.data)
  1580. self.assertIn(
  1581. 'A commit on branch feature', output.data)
  1582. # Ensure we have the merge commit
  1583. commits = _get_commits(output.data)
  1584. self.assertEqual(commits, [
  1585. 'Merge #1 `PR from the feature branch`',
  1586. 'Add sources file for testing',
  1587. 'A commit on branch feature',
  1588. ])
  1589. # Check if the closing notification was added
  1590. output = self.app.get('/test/pull-request/1')
  1591. self.assertIn(
  1592. '<small><p>Pull-Request has been merged by pingou</p></small>',
  1593. output.data)
  1594. @patch('pagure.lib.notify.send_email')
  1595. def test_internal_endpoint_main_ahead(self, send_email):
  1596. """ Test the new_request_pull endpoint when the main repo is ahead
  1597. of the fork.
  1598. """
  1599. send_email.return_value = True
  1600. tests.create_projects(self.session)
  1601. tests.create_projects_git(
  1602. os.path.join(self.path, 'requests'), bare=True)
  1603. self.set_up_git_repo(
  1604. new_project=None,
  1605. branch_from='feature')
  1606. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1607. repo = pygit2.init_repository(gitrepo, bare=True)
  1608. # Make the main repo be ahead of the fork
  1609. # First commit
  1610. newpath = tempfile.mkdtemp(prefix='pagure-test')
  1611. repopath = os.path.join(newpath, 'test')
  1612. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  1613. # Create a file in that git repo
  1614. with open(os.path.join(repopath, 'testfile'), 'w') as stream:
  1615. stream.write('foo\n bar')
  1616. clone_repo.index.add('testfile')
  1617. clone_repo.index.write()
  1618. # Commits the files added
  1619. last_commit = clone_repo.revparse_single('HEAD')
  1620. tree = clone_repo.index.write_tree()
  1621. author = pygit2.Signature(
  1622. 'Alice Author', 'alice@authors.tld')
  1623. committer = pygit2.Signature(
  1624. 'Cecil Committer', 'cecil@committers.tld')
  1625. clone_repo.create_commit(
  1626. 'refs/heads/master', # the name of the reference to update
  1627. author,
  1628. committer,
  1629. 'Add testfile file for testing',
  1630. # binary string representing the tree object ID
  1631. tree,
  1632. # list of binary strings representing parents of the new commit
  1633. [last_commit.oid.hex]
  1634. )
  1635. # Second commit
  1636. with open(os.path.join(repopath, 'testfile'), 'a') as stream:
  1637. stream.write('\nfoo2\n bar2')
  1638. clone_repo.index.add('testfile')
  1639. clone_repo.index.write()
  1640. # Commits the files added
  1641. last_commit = clone_repo.revparse_single('HEAD')
  1642. tree = clone_repo.index.write_tree()
  1643. author = pygit2.Signature(
  1644. 'Alice Author', 'alice@authors.tld')
  1645. committer = pygit2.Signature(
  1646. 'Cecil Committer', 'cecil@committers.tld')
  1647. clone_repo.create_commit(
  1648. 'refs/heads/master', # the name of the reference to update
  1649. author,
  1650. committer,
  1651. 'Add a second commit to testfile for testing',
  1652. # binary string representing the tree object ID
  1653. tree,
  1654. # list of binary strings representing parents of the new commit
  1655. [last_commit.oid.hex]
  1656. )
  1657. # Third commit
  1658. with open(os.path.join(repopath, 'testfile'), 'a') as stream:
  1659. stream.write('\nfoo3\n bar3')
  1660. clone_repo.index.add('testfile')
  1661. clone_repo.index.write()
  1662. # Commits the files added
  1663. last_commit = clone_repo.revparse_single('HEAD')
  1664. tree = clone_repo.index.write_tree()
  1665. author = pygit2.Signature(
  1666. 'Alice Author', 'alice@authors.tld')
  1667. committer = pygit2.Signature(
  1668. 'Cecil Committer', 'cecil@committers.tld')
  1669. clone_repo.create_commit(
  1670. 'refs/heads/master', # the name of the reference to update
  1671. author,
  1672. committer,
  1673. 'Add a third commit to testfile for testing',
  1674. # binary string representing the tree object ID
  1675. tree,
  1676. # list of binary strings representing parents of the new commit
  1677. [last_commit.oid.hex]
  1678. )
  1679. refname = 'refs/heads/master:refs/heads/master'
  1680. ori_remote = clone_repo.remotes[0]
  1681. PagureRepo.push(ori_remote, refname)
  1682. shutil.rmtree(newpath)
  1683. user = tests.FakeUser()
  1684. user.username = 'foo'
  1685. with tests.user_set(pagure.APP, user):
  1686. output = self.app.get('/new')
  1687. csrf_token = output.data.split(
  1688. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1689. output = self.app.post(
  1690. '/pv/pull-request/ready',
  1691. data={'repo': 'test', 'csrf_token': csrf_token}
  1692. )
  1693. self.assertEqual(output.status_code, 200)
  1694. data = json.loads(output.data)
  1695. self.assertEqual(
  1696. data,
  1697. {
  1698. "code": "OK",
  1699. "message": {
  1700. "branch_w_pr": {
  1701. "feature": 1
  1702. },
  1703. "new_branch": {}
  1704. }
  1705. }
  1706. )
  1707. @patch('pagure.lib.notify.send_email')
  1708. def test_fork_edit_file(self, send_email):
  1709. """ Test the fork_edit file endpoint. """
  1710. send_email.return_value = True
  1711. # Git repo not found
  1712. output = self.app.post('fork_edit/test/edit/master/f/sources')
  1713. self.assertEqual(output.status_code, 404)
  1714. tests.create_projects(self.session)
  1715. for folder in ['docs', 'tickets', 'requests', 'repos']:
  1716. tests.create_projects_git(
  1717. os.path.join(self.path, folder), bare=True)
  1718. # User not logged in
  1719. output = self.app.post('fork_edit/test/edit/master/f/sources')
  1720. self.assertEqual(output.status_code, 302)
  1721. user = tests.FakeUser()
  1722. user.username = 'pingou'
  1723. with tests.user_set(pagure.APP, user):
  1724. # Invalid request
  1725. output = self.app.post('fork_edit/test/edit/master/f/source')
  1726. self.assertEqual(output.status_code, 400)
  1727. output = self.app.get('/new/')
  1728. self.assertEqual(output.status_code, 200)
  1729. self.assertIn('<strong>Create new Project</strong>', output.data)
  1730. csrf_token = output.data.split(
  1731. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1732. data = {
  1733. 'csrf_token': csrf_token,
  1734. }
  1735. # No files can be found since they are not added
  1736. output = self.app.post('fork_edit/test/edit/master/f/sources',
  1737. data=data, follow_redirects=True)
  1738. self.assertEqual(output.status_code, 404)
  1739. user = tests.FakeUser()
  1740. user.username = 'foo'
  1741. with tests.user_set(pagure.APP, user):
  1742. data = {
  1743. 'csrf_token': csrf_token,
  1744. }
  1745. # Invalid request
  1746. output = self.app.post('fork_edit/test/edit/master/f/sources',
  1747. follow_redirects=True)
  1748. self.assertEqual(output.status_code, 400)
  1749. # Add content to the repo
  1750. tests.add_content_git_repo(os.path.join(
  1751. pagure.APP.config['GIT_FOLDER'], 'test.git'))
  1752. tests.add_readme_git_repo(os.path.join(
  1753. pagure.APP.config['GIT_FOLDER'], 'test.git'))
  1754. tests.add_binary_git_repo(
  1755. os.path.join(
  1756. pagure.APP.config['GIT_FOLDER'], 'test.git'), 'test.jpg')
  1757. # Check if button exists
  1758. output = self.app.get('/test/blob/master/f/sources')
  1759. self.assertEqual(output.status_code, 200)
  1760. self.assertIn(
  1761. 'Fork and Edit\n </button>\n',
  1762. output.data)
  1763. # Check fork-edit doesn't show for binary files
  1764. output = self.app.get('/test/blob/master/f/test.jpg')
  1765. self.assertEqual(output.status_code, 200)
  1766. self.assertNotIn(
  1767. 'Fork and Edit\n </button>\n',
  1768. output.data)
  1769. # Check for edit panel
  1770. output = self.app.post('fork_edit/test/edit/master/f/sources',
  1771. data=data, follow_redirects=True)
  1772. self.assertEqual(output.status_code, 200)
  1773. self.assertIn(
  1774. '<li><a href="/fork/foo/test/tree/master">'
  1775. '<span class="oi" data-glyph="random"></span>&nbsp; master</a>'
  1776. '</li><li class="active"><span class="oi" data-glyph="file">'
  1777. '</span>&nbsp; sources</li>',
  1778. output.data)
  1779. self.assertIn(
  1780. '<textarea id="textareaCode" name="content">foo\n bar</textarea>',
  1781. output.data)
  1782. # View what's supposed to be an image
  1783. output = self.app.post('fork_edit/test/edit/master/f/test.jpg',
  1784. data=data, follow_redirects=True)
  1785. self.assertEqual(output.status_code, 400)
  1786. self.assertIn('<p>Cannot edit binary files</p>', output.data)
  1787. # Check fork-edit shows when user is not logged in
  1788. output = self.app.get('/test/blob/master/f/sources')
  1789. self.assertEqual(output.status_code, 200)
  1790. self.assertIn(
  1791. 'Fork and Edit\n </button>\n',
  1792. output.data)
  1793. # Check if fork-edit shows for different user
  1794. user.username = 'pingou'
  1795. with tests.user_set(pagure.APP, user):
  1796. # Check if button exists
  1797. output = self.app.get('/test/blob/master/f/sources')
  1798. self.assertEqual(output.status_code, 200)
  1799. self.assertIn(
  1800. 'Fork and Edit\n </button>\n',
  1801. output.data)
  1802. # Check fork-edit doesn't show for binary
  1803. output = self.app.get('/test/blob/master/f/test.jpg')
  1804. self.assertEqual(output.status_code, 200)
  1805. self.assertNotIn(
  1806. 'Fork and Edit\n </button>\n',
  1807. output.data)
  1808. @patch('pagure.lib.notify.send_email')
  1809. def test_fork_without_main_repo(self, send_email):
  1810. """ Test the fork without the main repo. """
  1811. send_email.return_value = True
  1812. tests.create_projects(self.session)
  1813. # Create a fork with no parent i.e parent_id = None
  1814. item = pagure.lib.model.Project(
  1815. user_id=2, # foo
  1816. name='test',
  1817. description='test project #1',
  1818. hook_token='aaabbb',
  1819. is_fork=True,
  1820. parent_id=None,
  1821. )
  1822. self.session.add(item)
  1823. self.session.commit()
  1824. # Get fork project
  1825. project = pagure.lib._get_project(self.session, 'test', 'foo')
  1826. # Pull-requests and issue-trackers are off for forks
  1827. # lib function is not used here so mannually turning them off
  1828. project_settings = project.settings
  1829. project_settings['pull_requests'] = False
  1830. project_settings['issue_tracker'] = False
  1831. project.settings = project_settings
  1832. self.session.add(project)
  1833. self.session.commit()
  1834. tests.create_projects_git(
  1835. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  1836. # Create a git repo to play with
  1837. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1838. self.assertFalse(os.path.exists(gitrepo))
  1839. os.makedirs(gitrepo)
  1840. repo = pygit2.init_repository(gitrepo, bare=True)
  1841. # Create a fork of this repo
  1842. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  1843. gitrepo = os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git')
  1844. new_repo = pygit2.clone_repository(gitrepo, newpath)
  1845. tests.add_content_git_repo(gitrepo)
  1846. # UI test for deleted main
  1847. output = self.app.get('/fork/foo/test')
  1848. self.assertEqual(output.status_code, 200)
  1849. self.assertIn('Fork from a deleted repository\n', output.data)
  1850. # Testing commit endpoint
  1851. output = self.app.get('/fork/foo/test/commits/master')
  1852. self.assertEqual(output.status_code, 200)
  1853. self.assertIn('Commits <span class="label label-default"> 2</span>\n </h3>\n', output.data)
  1854. # Test pull-request endpoint
  1855. output = self.app.get('/fork/foo/test/pull-requests')
  1856. self.assertEqual(output.status_code, 404)
  1857. # Test issue-tracker endpoint
  1858. output = self.app.get('/fork/foo/test/issues')
  1859. self.assertEqual(output.status_code, 404)
  1860. shutil.rmtree(newpath)
  1861. if __name__ == '__main__':
  1862. unittest.main(verbosity=2)