test_pagure_flask_ui_fork.py 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847
  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.lib
  20. import tests
  21. from pagure.lib.repo import PagureRepo
  22. def _get_commits(output):
  23. ''' Returns the commits message in the output. All commits must have
  24. been made by `Alice Author` or `PY C` to be found.
  25. '''
  26. commits = []
  27. save = False
  28. cnt = 0
  29. for row in output.split('\n'):
  30. if row.strip() in ['Alice Author', 'Alice Äuthòr', 'PY C']:
  31. save = True
  32. if save:
  33. cnt += 1
  34. if cnt == 7:
  35. commits.append(row.strip())
  36. save = False
  37. cnt = 0
  38. return commits
  39. class PagureFlaskForktests(tests.Modeltests):
  40. """ Tests for flask fork controller of pagure """
  41. def setUp(self):
  42. """ Set up the environnment, ran before every tests. """
  43. super(PagureFlaskForktests, self).setUp()
  44. pagure.APP.config['TESTING'] = True
  45. pagure.SESSION = self.session
  46. pagure.lib.SESSION = self.session
  47. pagure.ui.SESSION = self.session
  48. pagure.ui.app.SESSION = self.session
  49. pagure.ui.filters.SESSION = self.session
  50. pagure.ui.fork.SESSION = self.session
  51. pagure.ui.repo.SESSION = self.session
  52. pagure.ui.issues.SESSION = self.session
  53. pagure.APP.config['GIT_FOLDER'] = os.path.join(tests.HERE, 'repos')
  54. pagure.APP.config['TICKETS_FOLDER'] = os.path.join(
  55. tests.HERE, 'tickets')
  56. pagure.APP.config['DOCS_FOLDER'] = os.path.join(
  57. tests.HERE, 'docs')
  58. pagure.APP.config['REQUESTS_FOLDER'] = os.path.join(
  59. tests.HERE, 'requests')
  60. self.app = pagure.APP.test_client()
  61. def set_up_git_repo(
  62. self, new_project=None, branch_from='feature', mtype='FF'):
  63. """ Set up the git repo and create the corresponding PullRequest
  64. object.
  65. """
  66. # Create a git repo to play with
  67. gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
  68. repo = pygit2.init_repository(gitrepo, bare=True)
  69. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  70. repopath = os.path.join(newpath, 'test')
  71. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  72. # Create a file in that git repo
  73. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  74. stream.write('foo\n bar')
  75. clone_repo.index.add('sources')
  76. clone_repo.index.write()
  77. # Commits the files added
  78. tree = clone_repo.index.write_tree()
  79. author = pygit2.Signature(
  80. 'Alice Author', 'alice@authors.tld')
  81. committer = pygit2.Signature(
  82. 'Cecil Committer', 'cecil@committers.tld')
  83. clone_repo.create_commit(
  84. 'refs/heads/master', # the name of the reference to update
  85. author,
  86. committer,
  87. 'Add sources file for testing',
  88. # binary string representing the tree object ID
  89. tree,
  90. # list of binary strings representing parents of the new commit
  91. []
  92. )
  93. refname = 'refs/heads/master:refs/heads/master'
  94. ori_remote = clone_repo.remotes[0]
  95. PagureRepo.push(ori_remote, refname)
  96. first_commit = repo.revparse_single('HEAD')
  97. if mtype == 'merge':
  98. with open(os.path.join(repopath, '.gitignore'), 'w') as stream:
  99. stream.write('*~')
  100. clone_repo.index.add('.gitignore')
  101. clone_repo.index.write()
  102. # Commits the files added
  103. tree = clone_repo.index.write_tree()
  104. author = pygit2.Signature(
  105. 'Alice Äuthòr', 'alice@äuthòrs.tld')
  106. committer = pygit2.Signature(
  107. 'Cecil Cõmmîttër', 'cecil@cõmmîttërs.tld')
  108. clone_repo.create_commit(
  109. 'refs/heads/master',
  110. author,
  111. committer,
  112. 'Add .gitignore file for testing',
  113. # binary string representing the tree object ID
  114. tree,
  115. # list of binary strings representing parents of the new commit
  116. [first_commit.oid.hex]
  117. )
  118. refname = 'refs/heads/master:refs/heads/master'
  119. ori_remote = clone_repo.remotes[0]
  120. PagureRepo.push(ori_remote, refname)
  121. if mtype == 'conflicts':
  122. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  123. stream.write('foo\n bar\nbaz')
  124. clone_repo.index.add('sources')
  125. clone_repo.index.write()
  126. # Commits the files added
  127. tree = clone_repo.index.write_tree()
  128. author = pygit2.Signature(
  129. 'Alice Author', 'alice@authors.tld')
  130. committer = pygit2.Signature(
  131. 'Cecil Committer', 'cecil@committers.tld')
  132. clone_repo.create_commit(
  133. 'refs/heads/master',
  134. author,
  135. committer,
  136. 'Add sources conflicting',
  137. # binary string representing the tree object ID
  138. tree,
  139. # list of binary strings representing parents of the new commit
  140. [first_commit.oid.hex]
  141. )
  142. refname = 'refs/heads/master:refs/heads/master'
  143. ori_remote = clone_repo.remotes[0]
  144. PagureRepo.push(ori_remote, refname)
  145. # Set the second repo
  146. new_gitrepo = repopath
  147. if new_project:
  148. # Create a new git repo to play with
  149. new_gitrepo = os.path.join(newpath, new_project.fullname)
  150. if not os.path.exists(new_gitrepo):
  151. os.makedirs(new_gitrepo)
  152. new_repo = pygit2.clone_repository(gitrepo, new_gitrepo)
  153. repo = pygit2.Repository(new_gitrepo)
  154. if mtype != 'nochanges':
  155. # Edit the sources file again
  156. with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream:
  157. stream.write('foo\n bar\nbaz\n boose')
  158. repo.index.add('sources')
  159. repo.index.write()
  160. # Commits the files added
  161. tree = repo.index.write_tree()
  162. author = pygit2.Signature(
  163. 'Alice Author', 'alice@authors.tld')
  164. committer = pygit2.Signature(
  165. 'Cecil Committer', 'cecil@committers.tld')
  166. repo.create_commit(
  167. 'refs/heads/%s' % branch_from,
  168. author,
  169. committer,
  170. 'A commit on branch %s' % branch_from,
  171. tree,
  172. [first_commit.oid.hex]
  173. )
  174. refname = 'refs/heads/%s' % (branch_from)
  175. ori_remote = repo.remotes[0]
  176. PagureRepo.push(ori_remote, refname)
  177. # Create a PR for these changes
  178. project = pagure.lib.get_project(self.session, 'test')
  179. req = pagure.lib.new_pull_request(
  180. session=self.session,
  181. repo_from=project,
  182. branch_from=branch_from,
  183. repo_to=project,
  184. branch_to='master',
  185. title='PR from the %s branch' % branch_from,
  186. user='pingou',
  187. requestfolder=None,
  188. )
  189. self.session.commit()
  190. self.assertEqual(req.id, 1)
  191. self.assertEqual(req.title, 'PR from the %s branch' % branch_from)
  192. shutil.rmtree(newpath)
  193. @patch('pagure.lib.notify.send_email')
  194. def test_request_pull(self, send_email):
  195. """ Test the request_pull endpoint. """
  196. send_email.return_value = True
  197. tests.create_projects(self.session)
  198. tests.create_projects_git(
  199. os.path.join(tests.HERE, 'requests'), bare=True)
  200. # Non-existant project
  201. output = self.app.get('/foobar/pull-request/1')
  202. self.assertEqual(output.status_code, 404)
  203. # Project has no PR
  204. output = self.app.get('/test/pull-request/1')
  205. self.assertEqual(output.status_code, 404)
  206. self.set_up_git_repo(new_project=None, branch_from='feature')
  207. project = pagure.lib.get_project(self.session, 'test')
  208. self.assertEqual(len(project.requests), 1)
  209. # View the pull-request
  210. output = self.app.get('/test/pull-request/1')
  211. self.assertEqual(output.status_code, 200)
  212. self.assertIn(
  213. '<h3><span class="label label-default">PR#1</span>\n'
  214. ' PR from the feature branch\n</h3>', output.data)
  215. self.assertIn(
  216. 'title="View file as of 2a552b">sources</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.lib.get_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.lib.get_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. '</button>\n Changes merged!',
  338. output.data)
  339. self.assertIn(
  340. 'A commit on branch feature', output.data)
  341. self.assertNotIn(
  342. 'Merge #1 `PR from the feature branch`', output.data)
  343. # Ensure we have the new commit
  344. commits = _get_commits(output.data)
  345. self.assertEqual(
  346. commits,
  347. [
  348. 'A commit on branch feature',
  349. 'Add sources file for testing'
  350. ]
  351. )
  352. # Check if the closing notification was added
  353. output = self.app.get('/test/pull-request/1')
  354. self.assertIn(
  355. '<small><p>Pull-Request has been merged by pingou</p></small>',
  356. output.data)
  357. @patch('pagure.lib.notify.send_email')
  358. def test_merge_request_pull_merge(self, send_email):
  359. """ Test the merge_request_pull endpoint with a merge PR. """
  360. send_email.return_value = True
  361. tests.create_projects(self.session)
  362. tests.create_projects_git(
  363. os.path.join(tests.HERE, 'requests'), bare=True)
  364. self.set_up_git_repo(
  365. new_project=None, branch_from='feature', mtype='merge')
  366. user = tests.FakeUser()
  367. user.username = 'pingou'
  368. with tests.user_set(pagure.APP, user):
  369. output = self.app.get('/test/pull-request/1')
  370. self.assertEqual(output.status_code, 200)
  371. csrf_token = output.data.split(
  372. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  373. data = {
  374. 'csrf_token': csrf_token,
  375. }
  376. # Merge
  377. output = self.app.post(
  378. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  379. self.assertEqual(output.status_code, 200)
  380. self.assertIn(
  381. '<title>Overview - test - Pagure</title>', output.data)
  382. self.assertIn(
  383. '</button>\n Changes merged!',
  384. output.data)
  385. # Check if the closing notification was added
  386. output = self.app.get('/test/pull-request/1')
  387. self.assertIn(
  388. '<small><p>Pull-Request has been merged by pingou</p></small>',
  389. output.data)
  390. @patch('pagure.lib.notify.send_email')
  391. def test_merge_request_pull_conflicts(self, send_email):
  392. """ Test the merge_request_pull endpoint with a conflicting PR. """
  393. send_email.return_value = True
  394. tests.create_projects(self.session)
  395. tests.create_projects_git(
  396. os.path.join(tests.HERE, 'requests'), bare=True)
  397. self.set_up_git_repo(
  398. new_project=None, branch_from='feature', mtype='conflicts')
  399. user = tests.FakeUser()
  400. user.username = 'pingou'
  401. with tests.user_set(pagure.APP, user):
  402. output = self.app.get('/test/pull-request/1')
  403. self.assertEqual(output.status_code, 200)
  404. csrf_token = output.data.split(
  405. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  406. data = {
  407. 'csrf_token': csrf_token,
  408. }
  409. # Merge conflicts
  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. '<h3><span class="label label-default">PR#1</span>\n'
  415. ' PR from the feature branch\n <span class="pull-xs-right">',
  416. output.data)
  417. self.assertIn(
  418. '</button>\n Merge conflicts!',
  419. output.data)
  420. @patch('pagure.lib.notify.send_email')
  421. def test_merge_request_pull_nochange(self, send_email):
  422. """ Test the merge_request_pull endpoint. """
  423. send_email.return_value = True
  424. tests.create_projects(self.session)
  425. tests.create_projects_git(
  426. os.path.join(tests.HERE, 'requests'), bare=True)
  427. self.set_up_git_repo(
  428. new_project=None, branch_from='master', mtype='nochanges')
  429. user = tests.FakeUser()
  430. user.username = 'pingou'
  431. with tests.user_set(pagure.APP, user):
  432. output = self.app.get('/test/pull-request/1')
  433. self.assertEqual(output.status_code, 200)
  434. csrf_token = output.data.split(
  435. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  436. data = {
  437. 'csrf_token': csrf_token,
  438. }
  439. # Nothing to merge
  440. output = self.app.post(
  441. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  442. self.assertEqual(output.status_code, 200)
  443. self.assertIn(
  444. '<h3><span class="label label-default">PR#1</span>\n'
  445. ' <span class="label label-success">Merged</span>',
  446. output.data)
  447. self.assertIn(
  448. '</button>\n Nothing to do, changes '
  449. 'were already merged', output.data)
  450. # Check if the closing notification was added
  451. output = self.app.get('/test/pull-request/1')
  452. self.assertIn(
  453. '<small><p>Pull-Request has been merged by pingou</p></small>',
  454. output.data)
  455. @patch('pagure.lib.notify.send_email')
  456. def test_request_pull_close(self, send_email):
  457. """ Test the request_pull endpoint with a closed PR. """
  458. send_email.return_value = True
  459. self.test_merge_request_pull_FF()
  460. output = self.app.get('/test/pull-request/1')
  461. self.assertEqual(output.status_code, 200)
  462. self.assertIn(
  463. '<h3><span class="label label-default">PR#1</span>\n'
  464. ' <span class="label label-success">', output.data)
  465. self.assertIn('<div>Merged by\n', output.data)
  466. self.assertIn(
  467. 'title="View file as of 2a552b">sources</a>', output.data)
  468. @patch('pagure.lib.notify.send_email')
  469. def test_request_pull_disabled(self, send_email):
  470. """ Test the request_pull endpoint with PR disabled. """
  471. send_email.return_value = True
  472. tests.create_projects(self.session)
  473. tests.create_projects_git(
  474. os.path.join(tests.HERE, 'requests'), bare=True)
  475. self.set_up_git_repo(new_project=None, branch_from='feature')
  476. # Project w/o pull-request
  477. repo = pagure.lib.get_project(self.session, 'test')
  478. settings = repo.settings
  479. settings['pull_requests'] = False
  480. repo.settings = settings
  481. self.session.add(repo)
  482. self.session.commit()
  483. output = self.app.get('/test/pull-request/1')
  484. self.assertEqual(output.status_code, 404)
  485. @patch('pagure.lib.notify.send_email')
  486. def test_request_pull_empty_repo(self, send_email):
  487. """ Test the request_pull endpoint against an empty repo. """
  488. send_email.return_value = True
  489. tests.create_projects(self.session)
  490. item = pagure.lib.model.Project(
  491. user_id=2, # foo
  492. name='test',
  493. description='test project #1',
  494. hook_token='aaabbb',
  495. parent_id=1,
  496. )
  497. self.session.add(item)
  498. self.session.commit()
  499. tests.create_projects_git(
  500. os.path.join(tests.HERE, 'requests'), bare=True)
  501. tests.create_projects_git(
  502. os.path.join(tests.HERE, 'repos', 'forks', 'foo'), bare=True)
  503. # Create a git repo to play with
  504. gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
  505. self.assertFalse(os.path.exists(gitrepo))
  506. os.makedirs(gitrepo)
  507. repo = pygit2.init_repository(gitrepo, bare=True)
  508. # Create a fork of this repo
  509. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  510. gitrepo = os.path.join(tests.HERE, 'repos', 'forks', 'foo', 'test.git')
  511. new_repo = pygit2.clone_repository(gitrepo, newpath)
  512. # Edit the sources file again
  513. with open(os.path.join(newpath, 'sources'), 'w') as stream:
  514. stream.write('foo\n bar\nbaz\n boose')
  515. new_repo.index.add('sources')
  516. new_repo.index.write()
  517. # Commits the files added
  518. tree = new_repo.index.write_tree()
  519. author = pygit2.Signature(
  520. 'Alice Author', 'alice@authors.tld')
  521. committer = pygit2.Signature(
  522. 'Cecil Committer', 'cecil@committers.tld')
  523. new_repo.create_commit(
  524. 'refs/heads/feature',
  525. author,
  526. committer,
  527. 'A commit on branch feature',
  528. tree,
  529. []
  530. )
  531. refname = 'refs/heads/feature:refs/heads/feature'
  532. ori_remote = new_repo.remotes[0]
  533. PagureRepo.push(ori_remote, refname)
  534. # Create a PR for these changes
  535. project = pagure.lib.get_project(self.session, 'test')
  536. req = pagure.lib.new_pull_request(
  537. session=self.session,
  538. repo_from=item,
  539. branch_from='feature',
  540. repo_to=project,
  541. branch_to='master',
  542. title='PR from the feature branch',
  543. user='pingou',
  544. requestfolder=None,
  545. )
  546. self.session.commit()
  547. self.assertEqual(req.id, 1)
  548. self.assertEqual(req.title, 'PR from the feature branch')
  549. output = self.app.get('/test/pull-request/1')
  550. self.assertEqual(output.status_code, 200)
  551. self.assertIn(
  552. '<h3><span class="label label-default">PR#1</span>\n'
  553. ' PR from the feature branch\n</h3>', output.data)
  554. self.assertTrue(
  555. output.data.count('<span class="commitdate" title='), 1)
  556. shutil.rmtree(newpath)
  557. @patch('pagure.lib.notify.send_email')
  558. def test_request_pull_empty_fork(self, send_email):
  559. """ Test the request_pull endpoint from an empty fork. """
  560. send_email.return_value = True
  561. tests.create_projects(self.session)
  562. item = pagure.lib.model.Project(
  563. user_id=2, # foo
  564. name='test',
  565. description='test project #1',
  566. hook_token='aaabbb',
  567. parent_id=1,
  568. )
  569. self.session.add(item)
  570. self.session.commit()
  571. tests.create_projects_git(
  572. os.path.join(tests.HERE, 'requests'), bare=True)
  573. tests.create_projects_git(
  574. os.path.join(tests.HERE, 'repos', 'forks', 'foo'), bare=True)
  575. # Create a git repo to play with
  576. gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
  577. self.assertFalse(os.path.exists(gitrepo))
  578. os.makedirs(gitrepo)
  579. repo = pygit2.init_repository(gitrepo, bare=True)
  580. # Create a fork of this repo
  581. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  582. gitrepo = os.path.join(
  583. tests.HERE, 'repos', 'forks', 'foo', 'test.git')
  584. new_repo = pygit2.clone_repository(gitrepo, newpath)
  585. # Create a PR for these "changes" (there are none, both repos are
  586. # empty)
  587. project = pagure.lib.get_project(self.session, 'test')
  588. req = pagure.lib.new_pull_request(
  589. session=self.session,
  590. repo_from=item,
  591. branch_from='feature',
  592. repo_to=project,
  593. branch_to='master',
  594. title='PR from the feature branch',
  595. user='pingou',
  596. requestfolder=None,
  597. )
  598. self.session.commit()
  599. self.assertEqual(req.id, 1)
  600. self.assertEqual(req.title, 'PR from the feature branch')
  601. output = self.app.get('/test/pull-request/1', follow_redirects=True)
  602. self.assertEqual(output.status_code, 200)
  603. self.assertIn(
  604. '<title>Overview - test - Pagure</title>', output.data)
  605. self.assertIn(
  606. '</button>\n Fork is empty, there are no '
  607. 'commits to request pulling', output.data)
  608. shutil.rmtree(newpath)
  609. @patch('pagure.lib.notify.send_email')
  610. def test_request_pulls(self, send_email):
  611. """ Test the request_pulls endpoint. """
  612. send_email.return_value = True
  613. # No such project
  614. output = self.app.get('/test/pull-requests')
  615. self.assertEqual(output.status_code, 404)
  616. tests.create_projects(self.session)
  617. tests.create_projects_git(
  618. os.path.join(tests.HERE, 'repos'), bare=True)
  619. output = self.app.get('/test/pull-requests')
  620. self.assertEqual(output.status_code, 200)
  621. self.assertIn(
  622. 'Pull Requests <span class="label label-default">0</span>',
  623. output.data)
  624. # Open is primary
  625. self.assertIn(
  626. '<a class="btn btn-primary btn-sm" '
  627. 'href="/test/pull-requests">Open</a>', output.data)
  628. self.assertIn(
  629. '<a class="btn btn-secondary btn-sm" '
  630. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  631. self.set_up_git_repo(new_project=None, branch_from='feature')
  632. output = self.app.get('/test/pull-requests')
  633. self.assertEqual(output.status_code, 200)
  634. self.assertIn(
  635. 'Pull Requests <span class="label label-default">1</span>',
  636. output.data)
  637. # Open is primary
  638. self.assertIn(
  639. '<a class="btn btn-primary btn-sm" '
  640. 'href="/test/pull-requests">Open</a>', output.data)
  641. self.assertIn(
  642. '<a class="btn btn-secondary btn-sm" '
  643. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  644. output = self.app.get('/test/pull-requests?status=Closed')
  645. self.assertEqual(output.status_code, 200)
  646. self.assertIn(
  647. 'Closed Pull Requests <span class="label label-default">0</span>',
  648. output.data)
  649. # Close is primary
  650. self.assertIn(
  651. '<a class="btn btn-secondary btn-sm" '
  652. 'href="/test/pull-requests">Open</a>', output.data)
  653. self.assertIn(
  654. '<a class="btn btn-primary btn-sm" '
  655. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  656. output = self.app.get('/test/pull-requests?status=0')
  657. self.assertEqual(output.status_code, 200)
  658. self.assertIn(
  659. 'Closed/Merged Pull Requests <span class="label label-default">0</span>',
  660. output.data)
  661. # Close is primary
  662. self.assertIn(
  663. '<a class="btn btn-secondary btn-sm" '
  664. 'href="/test/pull-requests">Open</a>', output.data)
  665. self.assertIn(
  666. '<a class="btn btn-primary btn-sm" '
  667. 'href="/test/pull-requests?status=0">Closed</a>', output.data)
  668. # Project w/o pull-request
  669. repo = pagure.lib.get_project(self.session, 'test')
  670. settings = repo.settings
  671. settings['pull_requests'] = False
  672. repo.settings = settings
  673. self.session.add(repo)
  674. self.session.commit()
  675. output = self.app.get('/test/pull-requests')
  676. self.assertEqual(output.status_code, 404)
  677. @patch('pagure.lib.notify.send_email')
  678. def test_request_pull_patch(self, send_email):
  679. """ Test the request_pull_patch endpoint. """
  680. send_email.return_value = True
  681. output = self.app.get('/test/pull-request/1.patch')
  682. self.assertEqual(output.status_code, 404)
  683. tests.create_projects(self.session)
  684. tests.create_projects_git(
  685. os.path.join(tests.HERE, 'requests'), bare=True)
  686. self.set_up_git_repo(
  687. new_project=None, branch_from='feature', mtype='merge')
  688. output = self.app.get('/test/pull-request/100.patch')
  689. self.assertEqual(output.status_code, 404)
  690. output = self.app.get('/test/pull-request/1.patch')
  691. self.assertEqual(output.status_code, 200)
  692. npatch = []
  693. for row in output.data.split('\n'):
  694. if row.startswith('Date:'):
  695. continue
  696. if row.startswith('From '):
  697. row = row.split(' ', 2)[2]
  698. npatch.append(row)
  699. exp = """Mon Sep 17 00:00:00 2001
  700. From: Alice Author <alice@authors.tld>
  701. Subject: A commit on branch feature
  702. ---
  703. diff --git a/.gitignore b/.gitignore
  704. new file mode 100644
  705. index 0000000..e4e5f6c
  706. --- /dev/null
  707. +++ b/.gitignore
  708. @@ -0,0 +1 @@
  709. +*~
  710. \ No newline at end of file
  711. diff --git a/sources b/sources
  712. index 9f44358..2a552bb 100644
  713. --- a/sources
  714. +++ b/sources
  715. @@ -1,2 +1,4 @@
  716. foo
  717. - bar
  718. \ No newline at end of file
  719. + bar
  720. +baz
  721. + boose
  722. \ No newline at end of file
  723. """
  724. patch = '\n'.join(npatch)
  725. #print patch
  726. self.assertEqual(patch, exp)
  727. # Project w/o pull-request
  728. repo = pagure.lib.get_project(self.session, 'test')
  729. settings = repo.settings
  730. settings['pull_requests'] = False
  731. repo.settings = settings
  732. self.session.add(repo)
  733. self.session.commit()
  734. output = self.app.get('/test/pull-request/1.patch')
  735. self.assertEqual(output.status_code, 404)
  736. @patch('pagure.lib.notify.send_email')
  737. def test_request_pull_patch_close(self, send_email):
  738. """ Test the request_pull_patch endpoint with a closed PR. """
  739. send_email.return_value = True
  740. self.test_merge_request_pull_FF()
  741. output = self.app.get('/test/pull-request/1.patch')
  742. self.assertEqual(output.status_code, 200)
  743. npatch = []
  744. for row in output.data.split('\n'):
  745. if row.startswith('Date:'):
  746. continue
  747. if row.startswith('From '):
  748. row = row.split(' ', 2)[2]
  749. npatch.append(row)
  750. exp = """Mon Sep 17 00:00:00 2001
  751. From: Alice Author <alice@authors.tld>
  752. Subject: A commit on branch feature
  753. ---
  754. diff --git a/sources b/sources
  755. index 9f44358..2a552bb 100644
  756. --- a/sources
  757. +++ b/sources
  758. @@ -1,2 +1,4 @@
  759. foo
  760. - bar
  761. \ No newline at end of file
  762. + bar
  763. +baz
  764. + boose
  765. \ No newline at end of file
  766. """
  767. patch = '\n'.join(npatch)
  768. #print patch
  769. self.assertEqual(patch, exp)
  770. @patch('pagure.lib.notify.send_email')
  771. def test_request_pull_patch_empty_repo(self, send_email):
  772. """ Test the request_pull_patch endpoint against an empty repo. """
  773. send_email.return_value = True
  774. tests.create_projects(self.session)
  775. item = pagure.lib.model.Project(
  776. user_id=2, # foo
  777. name='test',
  778. description='test project #1',
  779. hook_token='aaabbb',
  780. parent_id=1,
  781. )
  782. self.session.add(item)
  783. self.session.commit()
  784. tests.create_projects_git(
  785. os.path.join(tests.HERE, 'requests'), bare=True)
  786. tests.create_projects_git(
  787. os.path.join(tests.HERE, 'repos', 'forks', 'foo'), bare=True)
  788. # Create a git repo to play with
  789. gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
  790. self.assertFalse(os.path.exists(gitrepo))
  791. os.makedirs(gitrepo)
  792. repo = pygit2.init_repository(gitrepo, bare=True)
  793. # Create a fork of this repo
  794. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  795. gitrepo = os.path.join(
  796. tests.HERE, 'repos', 'forks', 'foo', 'test.git')
  797. new_repo = pygit2.clone_repository(gitrepo, newpath)
  798. # Edit the sources file again
  799. with open(os.path.join(newpath, 'sources'), 'w') as stream:
  800. stream.write('foo\n bar\nbaz\n boose')
  801. new_repo.index.add('sources')
  802. new_repo.index.write()
  803. # Commits the files added
  804. tree = new_repo.index.write_tree()
  805. author = pygit2.Signature(
  806. 'Alice Author', 'alice@authors.tld')
  807. committer = pygit2.Signature(
  808. 'Cecil Committer', 'cecil@committers.tld')
  809. new_repo.create_commit(
  810. 'refs/heads/feature',
  811. author,
  812. committer,
  813. 'A commit on branch feature',
  814. tree,
  815. []
  816. )
  817. refname = 'refs/heads/feature:refs/heads/feature'
  818. ori_remote = new_repo.remotes[0]
  819. PagureRepo.push(ori_remote, refname)
  820. # Create a PR for these "changes" (there are none, both repos are
  821. # empty)
  822. project = pagure.lib.get_project(self.session, 'test')
  823. req = pagure.lib.new_pull_request(
  824. session=self.session,
  825. repo_from=item,
  826. branch_from='feature',
  827. repo_to=project,
  828. branch_to='master',
  829. title='PR from the feature branch',
  830. user='pingou',
  831. requestfolder=None,
  832. )
  833. self.session.commit()
  834. self.assertEqual(req.id, 1)
  835. self.assertEqual(req.title, 'PR from the feature branch')
  836. output = self.app.get(
  837. '/test/pull-request/1.patch', follow_redirects=True)
  838. self.assertEqual(output.status_code, 200)
  839. npatch = []
  840. for row in output.data.split('\n'):
  841. if row.startswith('Date:'):
  842. continue
  843. if row.startswith('From '):
  844. row = row.split(' ', 2)[2]
  845. npatch.append(row)
  846. exp = """Mon Sep 17 00:00:00 2001
  847. From: Alice Author <alice@authors.tld>
  848. Subject: A commit on branch feature
  849. ---
  850. diff --git a/sources b/sources
  851. new file mode 100644
  852. index 0000000..2a552bb
  853. --- /dev/null
  854. +++ b/sources
  855. @@ -0,0 +1,4 @@
  856. +foo
  857. + bar
  858. +baz
  859. + boose
  860. \ No newline at end of file
  861. """
  862. patch = '\n'.join(npatch)
  863. #print patch
  864. self.assertEqual(patch, exp)
  865. shutil.rmtree(newpath)
  866. @patch('pagure.lib.notify.send_email')
  867. def test_request_pull_patch_empty_fork(self, send_email):
  868. """ Test the request_pull_patch endpoint from an empty fork. """
  869. send_email.return_value = True
  870. tests.create_projects(self.session)
  871. item = pagure.lib.model.Project(
  872. user_id=2, # foo
  873. name='test',
  874. description='test project #1',
  875. hook_token='aaabbb',
  876. parent_id=1,
  877. )
  878. self.session.add(item)
  879. self.session.commit()
  880. tests.create_projects_git(
  881. os.path.join(tests.HERE, 'requests'), bare=True)
  882. tests.create_projects_git(
  883. os.path.join(tests.HERE, 'repos', 'forks', 'foo'), bare=True)
  884. # Create a git repo to play with
  885. gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
  886. self.assertFalse(os.path.exists(gitrepo))
  887. os.makedirs(gitrepo)
  888. repo = pygit2.init_repository(gitrepo, bare=True)
  889. # Create a fork of this repo
  890. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  891. gitrepo = os.path.join(
  892. tests.HERE, 'repos', 'forks', 'foo', 'test.git')
  893. new_repo = pygit2.clone_repository(gitrepo, newpath)
  894. # Create a PR for these "changes" (there are none, both repos are
  895. # empty)
  896. project = pagure.lib.get_project(self.session, 'test')
  897. req = pagure.lib.new_pull_request(
  898. session=self.session,
  899. repo_from=item,
  900. branch_from='feature',
  901. repo_to=project,
  902. branch_to='master',
  903. title='PR from the feature branch',
  904. user='pingou',
  905. requestfolder=None,
  906. )
  907. self.session.commit()
  908. self.assertEqual(req.id, 1)
  909. self.assertEqual(req.title, 'PR from the feature branch')
  910. output = self.app.get('/test/pull-request/1.patch', follow_redirects=True)
  911. self.assertEqual(output.status_code, 200)
  912. self.assertIn(
  913. '<title>Overview - test - Pagure</title>', output.data)
  914. self.assertIn(
  915. '</button>\n Fork is empty, there are no '
  916. 'commits to request pulling', output.data)
  917. shutil.rmtree(newpath)
  918. @patch('pagure.lib.notify.send_email')
  919. def test_cancel_request_pull(self, send_email):
  920. """ Test the cancel_request_pull endpoint. """
  921. send_email.return_value = True
  922. tests.create_projects(self.session)
  923. tests.create_projects_git(
  924. os.path.join(tests.HERE, 'requests'), bare=True)
  925. self.set_up_git_repo(
  926. new_project=None, branch_from='feature', mtype='merge')
  927. user = tests.FakeUser()
  928. with tests.user_set(pagure.APP, user):
  929. output = self.app.post('/test/pull-request/cancel/1')
  930. self.assertEqual(output.status_code, 302)
  931. output = self.app.post(
  932. '/test/pull-request/cancel/1', follow_redirects=True)
  933. self.assertEqual(output.status_code, 200)
  934. self.assertIn(
  935. '<title>Overview - test - Pagure</title>', output.data)
  936. self.assertIn(
  937. '</button>\n Invalid input submitted',
  938. output.data)
  939. output = self.app.get('/test/pull-request/1')
  940. self.assertEqual(output.status_code, 200)
  941. csrf_token = output.data.split(
  942. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  943. data = {
  944. 'csrf_token': csrf_token,
  945. }
  946. # Invalid project
  947. output = self.app.post(
  948. '/foo/pull-request/cancel/1', data=data, follow_redirects=True)
  949. self.assertEqual(output.status_code, 404)
  950. # Invalid PR id
  951. output = self.app.post(
  952. '/test/pull-request/cancel/100', data=data, follow_redirects=True)
  953. self.assertEqual(output.status_code, 404)
  954. # Invalid user for this project
  955. output = self.app.post(
  956. '/test/pull-request/cancel/1', data=data, follow_redirects=True)
  957. self.assertEqual(output.status_code, 403)
  958. user.username = 'pingou'
  959. with tests.user_set(pagure.APP, user):
  960. # Project w/o pull-request
  961. repo = pagure.lib.get_project(self.session, 'test')
  962. settings = repo.settings
  963. settings['pull_requests'] = False
  964. repo.settings = settings
  965. self.session.add(repo)
  966. self.session.commit()
  967. output = self.app.post(
  968. '/test/pull-request/cancel/1', data=data, follow_redirects=True)
  969. self.assertEqual(output.status_code, 404)
  970. # Project w/o pull-request
  971. repo = pagure.lib.get_project(self.session, 'test')
  972. settings = repo.settings
  973. settings['pull_requests'] = True
  974. repo.settings = settings
  975. self.session.add(repo)
  976. self.session.commit()
  977. output = self.app.post(
  978. '/test/pull-request/cancel/1', data=data, 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 Request pull 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(tests.HERE, '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.lib.get_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.lib.get_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(tests.HERE, 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. self.assertIn(
  1136. '</button>\n Repo &#34;test&#34; '
  1137. 'cloned to &#34;foo/test&#34;', output.data)
  1138. @patch('pagure.lib.notify.send_email')
  1139. def test_new_request_pull(self, send_email):
  1140. """ Test the new_request_pull endpoint. """
  1141. send_email.return_value = True
  1142. self.test_fork_project()
  1143. tests.create_projects_git(
  1144. os.path.join(tests.HERE, 'requests'), bare=True)
  1145. repo = pagure.lib.get_project(self.session, 'test')
  1146. fork = pagure.lib.get_project(self.session, 'test', user='foo')
  1147. self.set_up_git_repo(
  1148. new_project=fork, branch_from='feature', mtype='FF')
  1149. user = tests.FakeUser()
  1150. user.username = 'foo'
  1151. with tests.user_set(pagure.APP, user):
  1152. output = self.app.get('/foo/diff/master..feature')
  1153. self.assertEqual(output.status_code, 404)
  1154. output = self.app.get('/test/diff/master..foo')
  1155. self.assertEqual(output.status_code, 400)
  1156. output = self.app.get('/test/diff/foo..master')
  1157. self.assertEqual(output.status_code, 400)
  1158. output = self.app.get('/test/diff/feature..master')
  1159. self.assertEqual(output.status_code, 200)
  1160. self.assertIn(
  1161. '<title>Diff from master to feature - test - Pagure</title>',
  1162. output.data)
  1163. self.assertIn(
  1164. '<p class="error"> No commits found </p>', output.data)
  1165. output = self.app.get('/test/diff/master..feature')
  1166. self.assertEqual(output.status_code, 200)
  1167. self.assertIn(
  1168. '<title>Diff from feature to master - test - Pagure</title>',
  1169. output.data)
  1170. self.assertNotIn(
  1171. '<input type="submit" class="submit positive button" '
  1172. 'value="Create">', output.data)
  1173. user.username = 'pingou'
  1174. with tests.user_set(pagure.APP, user):
  1175. output = self.app.get('/test/diff/master..feature')
  1176. self.assertEqual(output.status_code, 200)
  1177. self.assertIn(
  1178. '<title> Create new Pull Request for master - test - '
  1179. 'Pagure</title>', output.data)
  1180. self.assertIn(
  1181. '<input type="submit" class="btn btn-primary" value="Create">',
  1182. output.data)
  1183. csrf_token = output.data.split(
  1184. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1185. # Case 1 - Add an initial comment
  1186. data = {
  1187. 'csrf_token': csrf_token,
  1188. 'title': 'foo bar PR',
  1189. 'initial_comment': 'Test Initial Comment',
  1190. }
  1191. output = self.app.post(
  1192. '/test/diff/master..feature', data=data, follow_redirects=True)
  1193. self.assertEqual(output.status_code, 200)
  1194. self.assertIn(
  1195. '<title>PR#2: foo bar PR - test\n - Pagure</title>',
  1196. output.data)
  1197. self.assertIn('<p>Test Initial Comment</p>', output.data)
  1198. # Case 2 - Add an empty initial comment
  1199. data = {
  1200. 'csrf_token': csrf_token,
  1201. 'title': 'foo bar PR',
  1202. 'initial_comment': '',
  1203. }
  1204. output = self.app.post(
  1205. '/test/diff/master..feature', data=data, follow_redirects=True)
  1206. self.assertEqual(output.status_code, 200)
  1207. self.assertIn(
  1208. '<title>PR#3: foo bar PR - test\n - Pagure</title>',
  1209. output.data)
  1210. self.assertNotIn('<div id="comment-', output.data)
  1211. @patch('pagure.lib.notify.send_email')
  1212. def test_new_request_pull_empty_repo(self, send_email):
  1213. """ Test the new_request_pull endpoint against an empty repo. """
  1214. send_email.return_value = True
  1215. self.test_fork_project()
  1216. tests.create_projects_git(
  1217. os.path.join(tests.HERE, 'requests'), bare=True)
  1218. repo = pagure.lib.get_project(self.session, 'test')
  1219. fork = pagure.lib.get_project(self.session, 'test', user='foo')
  1220. # Create a git repo to play with
  1221. gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
  1222. repo = pygit2.init_repository(gitrepo, bare=True)
  1223. # Create a fork of this repo
  1224. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  1225. gitrepo = os.path.join(tests.HERE, 'repos', 'forks', 'foo', 'test.git')
  1226. new_repo = pygit2.clone_repository(gitrepo, newpath)
  1227. user = tests.FakeUser()
  1228. user.username = 'foo'
  1229. with tests.user_set(pagure.APP, user):
  1230. output = self.app.get(
  1231. '/fork/foo/test/diff/master..feature',
  1232. follow_redirects=True)
  1233. self.assertEqual(output.status_code, 200)
  1234. self.assertIn(
  1235. '<title>Overview - test - Pagure</title>', output.data)
  1236. self.assertIn(
  1237. '</button>\n Fork is empty, there are '
  1238. 'no commits to request pulling', output.data)
  1239. output = self.app.get('/test/new_issue')
  1240. csrf_token = output.data.split(
  1241. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1242. data = {
  1243. 'csrf_token': csrf_token,
  1244. 'title': 'foo bar PR',
  1245. }
  1246. output = self.app.post(
  1247. '/test/diff/master..feature', data=data, follow_redirects=True)
  1248. self.assertEqual(output.status_code, 200)
  1249. self.assertIn(
  1250. '<title>Overview - test - Pagure</title>', output.data)
  1251. self.assertIn(
  1252. '</button>\n Fork is empty, there are '
  1253. 'no commits to request pulling', output.data)
  1254. shutil.rmtree(newpath)
  1255. @patch('pagure.lib.notify.send_email')
  1256. def test_new_request_pull_empty_fork(self, send_email):
  1257. """ Test the new_request_pull endpoint against an empty repo. """
  1258. send_email.return_value = True
  1259. self.test_fork_project()
  1260. tests.create_projects_git(
  1261. os.path.join(tests.HERE, 'requests'), bare=True)
  1262. repo = pagure.lib.get_project(self.session, 'test')
  1263. fork = pagure.lib.get_project(self.session, 'test', user='foo')
  1264. # Create a git repo to play with
  1265. gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
  1266. repo = pygit2.init_repository(gitrepo, bare=True)
  1267. # Create a fork of this repo
  1268. newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  1269. gitrepo = os.path.join(
  1270. tests.HERE, '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..master', follow_redirects=True)
  1277. self.assertIn(
  1278. '<title>Overview - test - Pagure</title>', output.data)
  1279. self.assertIn(
  1280. '</button>\n Fork is empty, there are '
  1281. 'no commits to request pulling', output.data)
  1282. shutil.rmtree(newpath)
  1283. @patch('pagure.lib.notify.send_email')
  1284. def test_pull_request_add_comment(self, send_email):
  1285. """ Test the pull_request_add_comment endpoint. """
  1286. send_email.return_value = True
  1287. self.test_request_pull()
  1288. user = tests.FakeUser()
  1289. user.username = 'pingou'
  1290. with tests.user_set(pagure.APP, user):
  1291. output = self.app.post('/foo/pull-request/1/comment')
  1292. self.assertEqual(output.status_code, 404)
  1293. output = self.app.post('/test/pull-request/100/comment')
  1294. self.assertEqual(output.status_code, 404)
  1295. output = self.app.post('/test/pull-request/1/comment')
  1296. self.assertEqual(output.status_code, 200)
  1297. self.assertTrue(
  1298. output.data.startswith('\n<section class="add_comment">'))
  1299. csrf_token = output.data.split(
  1300. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1301. data = {
  1302. 'csrf_token': csrf_token,
  1303. 'comment': 'This look alright but we can do better',
  1304. }
  1305. output = self.app.post(
  1306. '/test/pull-request/1/comment', data=data,
  1307. follow_redirects=True)
  1308. self.assertEqual(output.status_code, 200)
  1309. self.assertIn(
  1310. '<title>PR#1: PR from the feature branch - test\n - '
  1311. 'Pagure</title>', output.data)
  1312. self.assertIn(
  1313. '</button>\n Comment added',
  1314. output.data)
  1315. # Project w/o pull-request
  1316. repo = pagure.lib.get_project(self.session, 'test')
  1317. settings = repo.settings
  1318. settings['pull_requests'] = False
  1319. repo.settings = settings
  1320. self.session.add(repo)
  1321. self.session.commit()
  1322. output = self.app.post(
  1323. '/test/pull-request/1/comment', data=data,
  1324. follow_redirects=True)
  1325. self.assertEqual(output.status_code, 404)
  1326. @patch('pagure.lib.notify.send_email')
  1327. def test_pull_request_drop_comment(self, send_email):
  1328. """ Test the pull_request_drop_comment endpoint. """
  1329. send_email.return_value = True
  1330. self.test_pull_request_add_comment()
  1331. # Project w/ pull-request
  1332. repo = pagure.lib.get_project(self.session, 'test')
  1333. settings = repo.settings
  1334. settings['pull_requests'] = True
  1335. repo.settings = settings
  1336. self.session.add(repo)
  1337. self.session.commit()
  1338. user = tests.FakeUser()
  1339. user.username = 'foo'
  1340. with tests.user_set(pagure.APP, user):
  1341. output = self.app.post('/foo/pull-request/1/comment/drop')
  1342. self.assertEqual(output.status_code, 404)
  1343. output = self.app.post('/test/pull-request/100/comment/drop')
  1344. self.assertEqual(output.status_code, 404)
  1345. output = self.app.post(
  1346. '/test/pull-request/1/comment/drop', follow_redirects=True)
  1347. self.assertEqual(output.status_code, 200)
  1348. self.assertIn(
  1349. '<h3><span class="label label-default">PR#1</span>\n'
  1350. ' PR from the feature branch\n</h3>', output.data)
  1351. #self.assertIn('href="#comment-1">¶</a>', output.data)
  1352. self.assertIn(
  1353. '<p>This look alright but we can do better</p>',
  1354. output.data)
  1355. csrf_token = output.data.split(
  1356. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1357. # Invalid comment id
  1358. data = {
  1359. 'csrf_token': csrf_token,
  1360. 'drop_comment': '10',
  1361. }
  1362. output = self.app.post(
  1363. '/test/pull-request/1/comment/drop', data=data,
  1364. follow_redirects=True)
  1365. self.assertEqual(output.status_code, 404)
  1366. data['drop_comment'] = '1'
  1367. output = self.app.post(
  1368. '/test/pull-request/1/comment/drop', data=data,
  1369. follow_redirects=True)
  1370. self.assertEqual(output.status_code, 403)
  1371. user.username = 'pingou'
  1372. with tests.user_set(pagure.APP, user):
  1373. # Drop comment
  1374. output = self.app.post(
  1375. '/test/pull-request/1/comment/drop', data=data,
  1376. follow_redirects=True)
  1377. self.assertEqual(output.status_code, 200)
  1378. self.assertIn(
  1379. '<h3><span class="label label-default">PR#1</span>\n'
  1380. ' PR from the feature branch\n <span class="pull-xs-right">',
  1381. output.data)
  1382. self.assertIn(
  1383. '</button>\n Comment removed',
  1384. output.data)
  1385. # Project w/o pull-request
  1386. repo = pagure.lib.get_project(self.session, 'test')
  1387. settings = repo.settings
  1388. settings['pull_requests'] = False
  1389. repo.settings = settings
  1390. self.session.add(repo)
  1391. self.session.commit()
  1392. output = self.app.post(
  1393. '/test/pull-request/1/comment/drop', data=data,
  1394. follow_redirects=True)
  1395. self.assertEqual(output.status_code, 404)
  1396. @patch('pagure.lib.notify.send_email')
  1397. def test_pull_request_edit_comment(self, send_email):
  1398. """ Test the pull request edit comment endpoint """
  1399. send_email.return_value = True
  1400. self.test_request_pull()
  1401. user = tests.FakeUser()
  1402. user.username = 'pingou'
  1403. with tests.user_set(pagure.APP, user):
  1404. # Repo 'foo' does not exist so it is verifying that condition
  1405. output = self.app.post('/foo/pull-request/1/comment/1/edit')
  1406. self.assertEqual(output.status_code, 404)
  1407. # Here no comment is present in the PR so its verifying that condition
  1408. output = self.app.post('/test/pull-request/100/comment/100/edit')
  1409. self.assertEqual(output.status_code, 404)
  1410. output = self.app.post('/test/pull-request/1/comment')
  1411. self.assertEqual(output.status_code, 200)
  1412. # Creating comment to play with
  1413. self.assertTrue(
  1414. output.data.startswith('\n<section class="add_comment">'))
  1415. csrf_token = output.data.split(
  1416. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1417. data = {
  1418. 'csrf_token': csrf_token,
  1419. 'comment': 'This look alright but we can do better',
  1420. }
  1421. output = self.app.post(
  1422. '/test/pull-request/1/comment', data=data,
  1423. follow_redirects=True)
  1424. self.assertEqual(output.status_code, 200)
  1425. self.assertIn(
  1426. '<h3><span class="label label-default">PR#1</span>\n'
  1427. ' PR from the feature branch\n <span class="pull-xs-right">',
  1428. output.data)
  1429. self.assertIn(
  1430. '</button>\n Comment added',
  1431. output.data)
  1432. # Check if the comment is there
  1433. self.assertIn(
  1434. '<p>This look alright but we can do better</p>', output.data)
  1435. output = self.app.get('/test/pull-request/1/comment/1/edit')
  1436. self.assertEqual(output.status_code, 200)
  1437. self.assertIn('<section class="edit_comment">', output.data)
  1438. # Checking if the comment is there in the update page
  1439. self.assertIn(
  1440. 'This look alright but we can do better</textarea>', output.data)
  1441. csrf_token = output.data.split(
  1442. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1443. data = {
  1444. 'csrf_token': csrf_token,
  1445. 'update_comment': 'This look alright but we can do better than this.',
  1446. }
  1447. output = self.app.post(
  1448. '/test/pull-request/1/comment/1/edit', data=data,
  1449. follow_redirects=True)
  1450. # Checking if the comment is updated in the main page
  1451. self.assertIn(
  1452. '<p>This look alright but we can do better than this.</p>', output.data)
  1453. self.assertIn(
  1454. '<h3><span class="label label-default">PR#1</span>\n'
  1455. ' PR from the feature branch\n <span class="pull-xs-right">',
  1456. output.data)
  1457. # Checking if Edited by User is there or not
  1458. self.assertIn(
  1459. '<small class="text-muted">Edited just now by pingou </small>',
  1460. output.data)
  1461. self.assertIn(
  1462. '</button>\n Comment updated', output.data)
  1463. # Project w/o pull-request
  1464. repo = pagure.lib.get_project(self.session, 'test')
  1465. settings = repo.settings
  1466. settings['pull_requests'] = False
  1467. repo.settings = settings
  1468. self.session.add(repo)
  1469. self.session.commit()
  1470. output = self.app.post(
  1471. '/test/pull-request/1/comment/edit/1', data=data,
  1472. follow_redirects=True)
  1473. self.assertEqual(output.status_code, 404)
  1474. @patch('pagure.lib.notify.send_email')
  1475. def test_merge_request_pull_FF_w_merge_commit(self, send_email):
  1476. """ Test the merge_request_pull endpoint with a FF PR but with a
  1477. merge commit.
  1478. """
  1479. send_email.return_value = True
  1480. self.test_request_pull()
  1481. user = tests.FakeUser()
  1482. with tests.user_set(pagure.APP, user):
  1483. output = self.app.get('/test/pull-request/1')
  1484. self.assertEqual(output.status_code, 200)
  1485. csrf_token = output.data.split(
  1486. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  1487. # No CSRF
  1488. output = self.app.post(
  1489. '/test/pull-request/1/merge', data={}, follow_redirects=True)
  1490. self.assertEqual(output.status_code, 200)
  1491. self.assertIn(
  1492. '<title>PR#1: PR from the feature branch - test\n - '
  1493. 'Pagure</title>', output.data)
  1494. self.assertIn(
  1495. '<h3><span class="label label-default">PR#1</span>\n'
  1496. ' PR from the feature branch\n</h3>', output.data)
  1497. self.assertIn(
  1498. 'title="View file as of 2a552b">sources</a>', output.data)
  1499. # Wrong project
  1500. data = {
  1501. 'csrf_token': csrf_token,
  1502. }
  1503. output = self.app.post(
  1504. '/foobar/pull-request/100/merge', data=data, follow_redirects=True)
  1505. self.assertEqual(output.status_code, 404)
  1506. # Wrong project
  1507. data = {
  1508. 'csrf_token': csrf_token,
  1509. }
  1510. output = self.app.post(
  1511. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  1512. self.assertEqual(output.status_code, 403)
  1513. user.username = 'pingou'
  1514. with tests.user_set(pagure.APP, user):
  1515. # Wrong request id
  1516. data = {
  1517. 'csrf_token': csrf_token,
  1518. }
  1519. output = self.app.post(
  1520. '/test/pull-request/100/merge', data=data, follow_redirects=True)
  1521. self.assertEqual(output.status_code, 404)
  1522. # Project requiring a merge commit
  1523. repo = pagure.lib.get_project(self.session, 'test')
  1524. settings = repo.settings
  1525. settings['always_merge'] = True
  1526. repo.settings = settings
  1527. self.session.add(repo)
  1528. self.session.commit()
  1529. # Merge
  1530. output = self.app.post(
  1531. '/test/pull-request/1/merge', data=data, follow_redirects=True)
  1532. self.assertEqual(output.status_code, 200)
  1533. self.assertIn(
  1534. '<title>Overview - test - Pagure</title>', output.data)
  1535. self.assertIn(
  1536. '</button>\n Changes merged!',
  1537. output.data)
  1538. self.assertIn(
  1539. 'Merge #1 `PR from the feature branch`', output.data)
  1540. self.assertIn(
  1541. 'A commit on branch feature', output.data)
  1542. # Ensure we have the merge commit
  1543. commits = _get_commits(output.data)
  1544. self.assertEqual(commits, [
  1545. 'Merge #1 `PR from the feature branch`',
  1546. 'Add sources file for testing',
  1547. 'A commit on branch feature',
  1548. ])
  1549. # Check if the closing notification was added
  1550. output = self.app.get('/test/pull-request/1')
  1551. self.assertIn(
  1552. '<small><p>Pull-Request has been merged by pingou</p></small>',
  1553. output.data)
  1554. if __name__ == '__main__':
  1555. SUITE = unittest.TestLoader().loadTestsFromTestCase(PagureFlaskForktests)
  1556. unittest.TextTestRunner(verbosity=2).run(SUITE)