1
0

test_pagure_flask_internal.py 69 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2015-2017 - 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 datetime
  10. import json
  11. import unittest
  12. import shutil
  13. import sys
  14. import time
  15. import os
  16. import pygit2
  17. from mock import patch
  18. sys.path.insert(0, os.path.join(os.path.dirname(
  19. os.path.abspath(__file__)), '..'))
  20. import pagure
  21. import pagure.lib
  22. import tests
  23. from pagure.lib.repo import PagureRepo
  24. class PagureFlaskInternaltests(tests.Modeltests):
  25. """ Tests for flask Internal controller of pagure """
  26. def setUp(self):
  27. """ Set up the environnment, ran before every tests. """
  28. super(PagureFlaskInternaltests, self).setUp()
  29. pagure.config.config['IP_ALLOWED_INTERNAL'] = list(set(
  30. pagure.config.config['IP_ALLOWED_INTERNAL'] + [None]))
  31. pagure.config.config['GIT_FOLDER'] = os.path.join(
  32. self.path, 'repos')
  33. pagure.config.config['REQUESTS_FOLDER'] = None
  34. pagure.config.config['TICKETS_FOLDER'] = None
  35. pagure.config.config['DOCS_FOLDER'] = None
  36. @patch('pagure.lib.notify.send_email')
  37. def test_pull_request_add_comment(self, send_email):
  38. """ Test the pull_request_add_comment function. """
  39. send_email.return_value = True
  40. tests.create_projects(self.session)
  41. repo = pagure.lib.get_authorized_project(self.session, 'test')
  42. req = pagure.lib.new_pull_request(
  43. session=self.session,
  44. repo_from=repo,
  45. branch_from='feature',
  46. repo_to=repo,
  47. branch_to='master',
  48. title='PR from the feature branch',
  49. user='pingou',
  50. requestfolder=None,
  51. )
  52. self.session.commit()
  53. self.assertEqual(req.id, 1)
  54. self.assertEqual(req.title, 'PR from the feature branch')
  55. request = repo.requests[0]
  56. self.assertEqual(len(request.comments), 0)
  57. self.assertEqual(len(request.discussion), 0)
  58. data = {
  59. 'objid': 'foo',
  60. }
  61. # Wrong http request
  62. output = self.app.post('/pv/pull-request/comment/', data=data)
  63. self.assertEqual(output.status_code, 405)
  64. # Invalid request
  65. output = self.app.put('/pv/pull-request/comment/', data=data)
  66. self.assertEqual(output.status_code, 400)
  67. data = {
  68. 'objid': 'foo',
  69. 'useremail': 'foo@pingou.com',
  70. }
  71. # Invalid objid
  72. output = self.app.put('/pv/pull-request/comment/', data=data)
  73. self.assertEqual(output.status_code, 404)
  74. data = {
  75. 'objid': request.uid,
  76. 'useremail': 'foo@pingou.com',
  77. }
  78. # Valid objid, in-complete data for a comment
  79. output = self.app.put('/pv/pull-request/comment/', data=data)
  80. self.assertEqual(output.status_code, 400)
  81. data = {
  82. 'objid': request.uid,
  83. 'useremail': 'foo@pingou.com',
  84. 'comment': 'Looks good to me!',
  85. }
  86. # Add comment
  87. output = self.app.put('/pv/pull-request/comment/', data=data)
  88. self.assertEqual(output.status_code, 200)
  89. js_data = json.loads(output.data)
  90. self.assertDictEqual(js_data, {'message': 'Comment added'})
  91. self.session.commit()
  92. repo = pagure.lib.get_authorized_project(self.session, 'test')
  93. request = repo.requests[0]
  94. self.assertEqual(len(request.comments), 1)
  95. self.assertEqual(len(request.discussion), 1)
  96. # Check the @localonly
  97. before = pagure.config.config['IP_ALLOWED_INTERNAL'][:]
  98. pagure.config.config['IP_ALLOWED_INTERNAL'] = []
  99. output = self.app.put('/pv/pull-request/comment/', data=data)
  100. self.assertEqual(output.status_code, 403)
  101. pagure.config.config['IP_ALLOWED_INTERNAL'] = before[:]
  102. @patch('pagure.lib.notify.send_email')
  103. def test_ticket_add_comment(self, send_email):
  104. """ Test the ticket_add_comment function. """
  105. send_email.return_value = True
  106. tests.create_projects(self.session)
  107. # Create issues to play with
  108. repo = pagure.lib.get_authorized_project(self.session, 'test')
  109. msg = pagure.lib.new_issue(
  110. session=self.session,
  111. repo=repo,
  112. title='Test issue',
  113. content='We should work on this',
  114. user='pingou',
  115. ticketfolder=None
  116. )
  117. self.session.commit()
  118. self.assertEqual(msg.title, 'Test issue')
  119. issue = repo.issues[0]
  120. self.assertEqual(len(issue.comments), 0)
  121. data = {
  122. 'objid': 'foo',
  123. }
  124. # Wrong http request
  125. output = self.app.post('/pv/ticket/comment/', data=data)
  126. self.assertEqual(output.status_code, 405)
  127. # Invalid request
  128. output = self.app.put('/pv/ticket/comment/', data=data)
  129. self.assertEqual(output.status_code, 400)
  130. data = {
  131. 'objid': 'foo',
  132. 'useremail': 'foo@pingou.com',
  133. }
  134. # Invalid objid
  135. output = self.app.put('/pv/ticket/comment/', data=data)
  136. self.assertEqual(output.status_code, 404)
  137. data = {
  138. 'objid': issue.uid,
  139. 'useremail': 'foo@pingou.com',
  140. }
  141. # Valid objid, in-complete data for a comment
  142. output = self.app.put('/pv/ticket/comment/', data=data)
  143. self.assertEqual(output.status_code, 400)
  144. data = {
  145. 'objid': issue.uid,
  146. 'useremail': 'foo@pingou.com',
  147. 'comment': 'Looks good to me!',
  148. }
  149. # Add comment
  150. output = self.app.put('/pv/ticket/comment/', data=data)
  151. self.assertEqual(output.status_code, 200)
  152. js_data = json.loads(output.data)
  153. self.assertDictEqual(js_data, {'message': 'Comment added'})
  154. self.session.commit()
  155. repo = pagure.lib.get_authorized_project(self.session, 'test')
  156. issue = repo.issues[0]
  157. self.assertEqual(len(issue.comments), 1)
  158. # Check the @localonly
  159. pagure.config.config['IP_ALLOWED_INTERNAL'].remove(None)
  160. before = pagure.config.config['IP_ALLOWED_INTERNAL'][:]
  161. pagure.config.config['IP_ALLOWED_INTERNAL'] = []
  162. output = self.app.put('/pv/ticket/comment/', data=data)
  163. self.assertEqual(output.status_code, 403)
  164. pagure.config.config['IP_ALLOWED_INTERNAL'] = before[:]
  165. @patch('pagure.lib.notify.send_email')
  166. def test_private_ticket_add_comment(self, send_email):
  167. """ Test the ticket_add_comment function on a private ticket. """
  168. send_email.return_value = True
  169. tests.create_projects(self.session)
  170. # Create issues to play with
  171. repo = pagure.lib.get_authorized_project(self.session, 'test')
  172. msg = pagure.lib.new_issue(
  173. session=self.session,
  174. repo=repo,
  175. title='Test issue',
  176. content='We should work on this, really',
  177. user='pingou',
  178. private=True,
  179. ticketfolder=None
  180. )
  181. self.session.commit()
  182. self.assertEqual(msg.title, 'Test issue')
  183. issue = repo.issues[0]
  184. self.assertEqual(len(issue.comments), 0)
  185. data = {
  186. 'objid': 'foo',
  187. }
  188. # Wrong http request
  189. output = self.app.post('/pv/ticket/comment/', data=data)
  190. self.assertEqual(output.status_code, 405)
  191. # Invalid request
  192. output = self.app.put('/pv/ticket/comment/', data=data)
  193. self.assertEqual(output.status_code, 400)
  194. data = {
  195. 'objid': 'foo',
  196. 'useremail': 'foo@pingou.com',
  197. }
  198. # Invalid objid
  199. output = self.app.put('/pv/ticket/comment/', data=data)
  200. self.assertEqual(output.status_code, 404)
  201. data = {
  202. 'objid': issue.uid,
  203. 'useremail': 'foo@bar.com',
  204. }
  205. # Valid objid, un-allowed user for this (private) ticket
  206. output = self.app.put('/pv/ticket/comment/', data=data)
  207. self.assertEqual(output.status_code, 403)
  208. data = {
  209. 'objid': issue.uid,
  210. 'useremail': 'foo@pingou.com',
  211. }
  212. # Valid objid, un-allowed user for this (private) ticket
  213. output = self.app.put('/pv/ticket/comment/', data=data)
  214. self.assertEqual(output.status_code, 400)
  215. data = {
  216. 'objid': issue.uid,
  217. 'useremail': 'foo@pingou.com',
  218. 'comment': 'Looks good to me!',
  219. }
  220. # Add comment
  221. output = self.app.put('/pv/ticket/comment/', data=data)
  222. self.assertEqual(output.status_code, 200)
  223. js_data = json.loads(output.data)
  224. self.assertDictEqual(js_data, {'message': 'Comment added'})
  225. self.session.commit()
  226. repo = pagure.lib.get_authorized_project(self.session, 'test')
  227. issue = repo.issues[0]
  228. self.assertEqual(len(issue.comments), 1)
  229. # Check the @localonly
  230. before = pagure.config.config['IP_ALLOWED_INTERNAL'][:]
  231. pagure.config.config['IP_ALLOWED_INTERNAL'] = []
  232. output = self.app.put('/pv/ticket/comment/', data=data)
  233. self.assertEqual(output.status_code, 403)
  234. pagure.config.config['IP_ALLOWED_INTERNAL'] = before[:]
  235. @patch('pagure.lib.notify.send_email')
  236. def test_private_ticket_add_comment_acl(self, send_email):
  237. """ Test the ticket_add_comment function on a private ticket. """
  238. send_email.return_value = True
  239. tests.create_projects(self.session)
  240. # Create issues to play with
  241. repo = pagure.lib.get_authorized_project(self.session, 'test')
  242. msg = pagure.lib.new_issue(
  243. session=self.session,
  244. repo=repo,
  245. title='Test issue',
  246. content='We should work on this, really',
  247. user='pingou',
  248. private=True,
  249. ticketfolder=None
  250. )
  251. self.session.commit()
  252. self.assertEqual(msg.title, 'Test issue')
  253. repo = pagure.lib.get_authorized_project(self.session, 'test')
  254. issue = repo.issues[0]
  255. self.assertEqual(len(issue.comments), 0)
  256. # Currently, he is just an average user,
  257. # He doesn't have any access in this repo
  258. data = {
  259. 'objid': issue.uid,
  260. 'useremail': 'foo@bar.com',
  261. 'comment': 'Looks good to me!',
  262. }
  263. # Valid objid, un-allowed user for this (private) ticket
  264. output = self.app.put('/pv/ticket/comment/', data=data)
  265. self.assertEqual(output.status_code, 403)
  266. repo = pagure.lib.get_authorized_project(self.session, 'test')
  267. # Let's promote him to be a ticketer
  268. # He shoudn't be able to comment even then though
  269. msg = pagure.lib.add_user_to_project(
  270. self.session,
  271. project=repo,
  272. new_user='foo',
  273. user='pingou',
  274. access='ticket'
  275. )
  276. self.session.commit()
  277. self.assertEqual(msg, 'User added')
  278. repo = pagure.lib.get_authorized_project(self.session, 'test')
  279. self.assertEqual(
  280. sorted([u.username for u in repo.users]), ['foo'])
  281. self.assertEqual(
  282. sorted([u.username for u in repo.committers]), [])
  283. self.assertEqual(
  284. sorted([u.username for u in repo.admins]), [])
  285. output = self.app.put('/pv/ticket/comment/', data=data)
  286. self.assertEqual(output.status_code, 403)
  287. repo = pagure.lib.get_authorized_project(self.session, 'test')
  288. # Let's promote him to be a committer
  289. # He should be able to comment
  290. msg = pagure.lib.add_user_to_project(
  291. self.session,
  292. project=repo,
  293. new_user='foo',
  294. user='pingou',
  295. access='commit'
  296. )
  297. self.session.commit()
  298. self.assertEqual(msg, 'User access updated')
  299. repo = pagure.lib.get_authorized_project(self.session, 'test')
  300. self.assertEqual(
  301. sorted([u.username for u in repo.users]), ['foo'])
  302. self.assertEqual(
  303. sorted([u.username for u in repo.committers]), ['foo'])
  304. self.assertEqual(
  305. sorted([u.username for u in repo.admins]), [])
  306. # Add comment
  307. output = self.app.put('/pv/ticket/comment/', data=data)
  308. self.assertEqual(output.status_code, 200)
  309. js_data = json.loads(output.data)
  310. self.assertDictEqual(js_data, {'message': 'Comment added'})
  311. repo = pagure.lib.get_authorized_project(self.session, 'test')
  312. issue = repo.issues[0]
  313. self.assertEqual(len(issue.comments), 1)
  314. # Let's promote him to be a admin
  315. # He should be able to comment
  316. msg = pagure.lib.add_user_to_project(
  317. self.session,
  318. project=repo,
  319. new_user='foo',
  320. user='pingou',
  321. access='admin'
  322. )
  323. self.session.commit()
  324. self.assertEqual(msg, 'User access updated')
  325. repo = pagure.lib.get_authorized_project(self.session, 'test')
  326. self.assertEqual(
  327. sorted([u.username for u in repo.users]), ['foo'])
  328. self.assertEqual(
  329. sorted([u.username for u in repo.committers]), ['foo'])
  330. self.assertEqual(
  331. sorted([u.username for u in repo.admins]), ['foo'])
  332. # Add comment
  333. output = self.app.put('/pv/ticket/comment/', data=data)
  334. self.assertEqual(output.status_code, 200)
  335. js_data = json.loads(output.data)
  336. self.assertDictEqual(js_data, {'message': 'Comment added'})
  337. repo = pagure.lib.get_authorized_project(self.session, 'test')
  338. issue = repo.issues[0]
  339. self.assertEqual(len(issue.comments), 2)
  340. # Check the @localonly
  341. before = pagure.config.config['IP_ALLOWED_INTERNAL'][:]
  342. pagure.config.config['IP_ALLOWED_INTERNAL'] = []
  343. output = self.app.put('/pv/ticket/comment/', data=data)
  344. self.assertEqual(output.status_code, 403)
  345. pagure.config.config['IP_ALLOWED_INTERNAL'] = before[:]
  346. @patch('pagure.lib.notify.send_email')
  347. def test_mergeable_request_pull_FF(self, send_email):
  348. """ Test the mergeable_request_pull endpoint with a fast-forward
  349. merge.
  350. """
  351. send_email.return_value = True
  352. # Create a git repo to play with
  353. origgitrepo = os.path.join(self.path, 'repos', 'test.git')
  354. self.assertFalse(os.path.exists(origgitrepo))
  355. os.makedirs(origgitrepo)
  356. orig_repo = pygit2.init_repository(origgitrepo, bare=True)
  357. os.makedirs(os.path.join(self.path, 'repos_tmp'))
  358. gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git')
  359. repo = pygit2.clone_repository(origgitrepo, gitrepo)
  360. # Create a file in that git repo
  361. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  362. stream.write('foo\n bar')
  363. repo.index.add('sources')
  364. repo.index.write()
  365. # Commits the files added
  366. tree = repo.index.write_tree()
  367. author = pygit2.Signature(
  368. 'Alice Author', 'alice@authors.tld')
  369. committer = pygit2.Signature(
  370. 'Cecil Committer', 'cecil@committers.tld')
  371. repo.create_commit(
  372. 'refs/heads/master', # the name of the reference to update
  373. author,
  374. committer,
  375. 'Add sources file for testing',
  376. # binary string representing the tree object ID
  377. tree,
  378. # list of binary strings representing parents of the new commit
  379. []
  380. )
  381. first_commit = repo.revparse_single('HEAD')
  382. refname = 'refs/heads/master:refs/heads/master'
  383. ori_remote = repo.remotes[0]
  384. PagureRepo.push(ori_remote, refname)
  385. # Edit the sources file again
  386. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  387. stream.write('foo\n bar\nbaz\n boose')
  388. repo.index.add('sources')
  389. repo.index.write()
  390. # Commits the files added
  391. tree = repo.index.write_tree()
  392. author = pygit2.Signature(
  393. 'Alice Author', 'alice@authors.tld')
  394. committer = pygit2.Signature(
  395. 'Cecil Committer', 'cecil@committers.tld')
  396. repo.create_commit(
  397. 'refs/heads/feature', # the name of the reference to update
  398. author,
  399. committer,
  400. 'Add baz and boose to the sources\n\n There are more objects to '
  401. 'consider',
  402. # binary string representing the tree object ID
  403. tree,
  404. # list of binary strings representing parents of the new commit
  405. [first_commit.oid.hex]
  406. )
  407. second_commit = repo.revparse_single('HEAD')
  408. refname = 'refs/heads/feature:refs/heads/feature'
  409. ori_remote = repo.remotes[0]
  410. PagureRepo.push(ori_remote, refname)
  411. # Create a PR for these changes
  412. tests.create_projects(self.session)
  413. project = pagure.lib.get_authorized_project(self.session, 'test')
  414. req = pagure.lib.new_pull_request(
  415. session=self.session,
  416. repo_from=project,
  417. branch_from='feature',
  418. repo_to=project,
  419. branch_to='master',
  420. title='PR from the feature branch',
  421. user='pingou',
  422. requestfolder=None,
  423. )
  424. self.session.commit()
  425. self.assertEqual(req.id, 1)
  426. self.assertEqual(req.title, 'PR from the feature branch')
  427. # Check if the PR can be merged
  428. data = {
  429. 'objid': 'blah',
  430. }
  431. # Missing CSRF
  432. output = self.app.post('/pv/pull-request/merge', data=data)
  433. self.assertEqual(output.status_code, 400)
  434. user = tests.FakeUser()
  435. user.username = 'pingou'
  436. with tests.user_set(self.app.application, user):
  437. output = self.app.get('/test/adduser')
  438. csrf_token = output.data.split(
  439. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  440. # Missing request identifier
  441. data = {
  442. 'csrf_token': csrf_token,
  443. }
  444. output = self.app.post('/pv/pull-request/merge', data=data)
  445. self.assertEqual(output.status_code, 404)
  446. # With all the desired information
  447. project = pagure.lib.get_authorized_project(self.session, 'test')
  448. data = {
  449. 'csrf_token': csrf_token,
  450. 'requestid': project.requests[0].uid,
  451. }
  452. output = self.app.post('/pv/pull-request/merge', data=data)
  453. self.assertEqual(output.status_code, 200)
  454. exp = {
  455. "code": "FFORWARD",
  456. "message": "The pull-request can be merged and fast-forwarded",
  457. "short_code": "Ok"
  458. }
  459. js_data = json.loads(output.data)
  460. self.assertDictEqual(js_data, exp)
  461. @patch('pagure.lib.notify.send_email')
  462. def test_mergeable_request_pull_no_change(self, send_email):
  463. """ Test the mergeable_request_pull endpoint when there are no
  464. changes to merge.
  465. """
  466. send_email.return_value = True
  467. # Create a git repo to play with
  468. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  469. self.assertFalse(os.path.exists(gitrepo))
  470. os.makedirs(gitrepo)
  471. repo = pygit2.init_repository(gitrepo)
  472. # Create a file in that git repo
  473. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  474. stream.write('foo\n bar')
  475. repo.index.add('sources')
  476. repo.index.write()
  477. # Commits the files added
  478. tree = repo.index.write_tree()
  479. author = pygit2.Signature(
  480. 'Alice Author', 'alice@authors.tld')
  481. committer = pygit2.Signature(
  482. 'Cecil Committer', 'cecil@committers.tld')
  483. repo.create_commit(
  484. 'refs/heads/master', # the name of the reference to update
  485. author,
  486. committer,
  487. 'Add sources file for testing',
  488. # binary string representing the tree object ID
  489. tree,
  490. # list of binary strings representing parents of the new commit
  491. []
  492. )
  493. first_commit = repo.revparse_single('HEAD')
  494. # Edit the sources file again
  495. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  496. stream.write('foo\n bar\nbaz\n boose')
  497. repo.index.add('sources')
  498. repo.index.write()
  499. # Commits the files added
  500. tree = repo.index.write_tree()
  501. author = pygit2.Signature(
  502. 'Alice Author', 'alice@authors.tld')
  503. committer = pygit2.Signature(
  504. 'Cecil Committer', 'cecil@committers.tld')
  505. repo.create_commit(
  506. 'refs/heads/master', # the name of the reference to update
  507. author,
  508. committer,
  509. 'Add baz and boose to the sources\n\n There are more objects to '
  510. 'consider',
  511. # binary string representing the tree object ID
  512. tree,
  513. # list of binary strings representing parents of the new commit
  514. [first_commit.oid.hex]
  515. )
  516. second_commit = repo.revparse_single('HEAD')
  517. # Create a PR for these changes
  518. tests.create_projects(self.session)
  519. project = pagure.lib.get_authorized_project(self.session, 'test')
  520. req = pagure.lib.new_pull_request(
  521. session=self.session,
  522. repo_from=project,
  523. branch_from='master',
  524. repo_to=project,
  525. branch_to='master',
  526. title='PR from the feature branch',
  527. user='pingou',
  528. requestfolder=None,
  529. )
  530. self.session.commit()
  531. self.assertEqual(req.id, 1)
  532. self.assertEqual(req.title, 'PR from the feature branch')
  533. # Check if the PR can be merged
  534. data = {
  535. 'objid': 'blah',
  536. }
  537. # Missing CSRF
  538. output = self.app.post('/pv/pull-request/merge', data=data)
  539. self.assertEqual(output.status_code, 400)
  540. user = tests.FakeUser()
  541. user.username = 'pingou'
  542. with tests.user_set(self.app.application, user):
  543. output = self.app.get('/test/adduser')
  544. csrf_token = output.data.split(
  545. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  546. # Missing request identifier
  547. data = {
  548. 'csrf_token': csrf_token,
  549. }
  550. output = self.app.post('/pv/pull-request/merge', data=data)
  551. self.assertEqual(output.status_code, 404)
  552. # With all the desired information
  553. project = pagure.lib.get_authorized_project(self.session, 'test')
  554. data = {
  555. 'csrf_token': csrf_token,
  556. 'requestid': project.requests[0].uid,
  557. }
  558. output = self.app.post('/pv/pull-request/merge', data=data)
  559. self.assertEqual(output.status_code, 200)
  560. exp = {
  561. "code": "NO_CHANGE",
  562. "message": "Nothing to change, git is up to date",
  563. "short_code": "No changes"
  564. }
  565. js_data = json.loads(output.data)
  566. self.assertDictEqual(js_data, exp)
  567. @patch('pagure.lib.notify.send_email')
  568. def test_mergeable_request_pull_merge(self, send_email):
  569. """ Test the mergeable_request_pull endpoint when the changes can
  570. be merged with a merge commit.
  571. """
  572. send_email.return_value = True
  573. # Create a git repo to play with
  574. origgitrepo = os.path.join(self.path, 'repos', 'test.git')
  575. self.assertFalse(os.path.exists(origgitrepo))
  576. os.makedirs(origgitrepo)
  577. orig_repo = pygit2.init_repository(origgitrepo, bare=True)
  578. os.makedirs(os.path.join(self.path, 'repos_tmp'))
  579. gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git')
  580. repo = pygit2.clone_repository(origgitrepo, gitrepo)
  581. # Create a file in that git repo
  582. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  583. stream.write('foo\n bar')
  584. repo.index.add('sources')
  585. repo.index.write()
  586. # Commits the files added
  587. tree = repo.index.write_tree()
  588. author = pygit2.Signature(
  589. 'Alice Author', 'alice@authors.tld')
  590. committer = pygit2.Signature(
  591. 'Cecil Committer', 'cecil@committers.tld')
  592. repo.create_commit(
  593. 'refs/heads/master', # the name of the reference to update
  594. author,
  595. committer,
  596. 'Add sources file for testing',
  597. # binary string representing the tree object ID
  598. tree,
  599. # list of binary strings representing parents of the new commit
  600. []
  601. )
  602. first_commit = repo.revparse_single('HEAD')
  603. refname = 'refs/heads/master:refs/heads/master'
  604. ori_remote = repo.remotes[0]
  605. PagureRepo.push(ori_remote, refname)
  606. # Edit the sources file again
  607. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  608. stream.write('foo\n bar\nbaz\n boose')
  609. repo.index.add('sources')
  610. repo.index.write()
  611. # Commits the files added
  612. tree = repo.index.write_tree()
  613. author = pygit2.Signature(
  614. 'Alice Author', 'alice@authors.tld')
  615. committer = pygit2.Signature(
  616. 'Cecil Committer', 'cecil@committers.tld')
  617. repo.create_commit(
  618. 'refs/heads/feature', # the name of the reference to update
  619. author,
  620. committer,
  621. 'Add baz and boose to the sources\n\n There are more objects to '
  622. 'consider',
  623. # binary string representing the tree object ID
  624. tree,
  625. # list of binary strings representing parents of the new commit
  626. [first_commit.oid.hex]
  627. )
  628. refname = 'refs/heads/feature:refs/heads/feature'
  629. ori_remote = repo.remotes[0]
  630. PagureRepo.push(ori_remote, refname)
  631. # Create another file in the master branch
  632. with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream:
  633. stream.write('*~')
  634. repo.index.add('.gitignore')
  635. repo.index.write()
  636. # Commits the files added
  637. tree = repo.index.write_tree()
  638. author = pygit2.Signature(
  639. 'Alice Author', 'alice@authors.tld')
  640. committer = pygit2.Signature(
  641. 'Cecil Committer', 'cecil@committers.tld')
  642. repo.create_commit(
  643. 'refs/heads/master', # the name of the reference to update
  644. author,
  645. committer,
  646. 'Add .gitignore file for testing',
  647. # binary string representing the tree object ID
  648. tree,
  649. # list of binary strings representing parents of the new commit
  650. [first_commit.oid.hex]
  651. )
  652. refname = 'refs/heads/master:refs/heads/master'
  653. ori_remote = repo.remotes[0]
  654. PagureRepo.push(ori_remote, refname)
  655. # Create a PR for these changes
  656. tests.create_projects(self.session)
  657. project = pagure.lib.get_authorized_project(self.session, 'test')
  658. req = pagure.lib.new_pull_request(
  659. session=self.session,
  660. repo_from=project,
  661. branch_from='feature',
  662. repo_to=project,
  663. branch_to='master',
  664. title='PR from the feature branch',
  665. user='pingou',
  666. requestfolder=None,
  667. )
  668. self.session.commit()
  669. self.assertEqual(req.id, 1)
  670. self.assertEqual(req.title, 'PR from the feature branch')
  671. # Check if the PR can be merged
  672. data = {}
  673. # Missing CSRF
  674. output = self.app.post('/pv/pull-request/merge', data=data)
  675. self.assertEqual(output.status_code, 400)
  676. user = tests.FakeUser()
  677. user.username = 'pingou'
  678. with tests.user_set(self.app.application, user):
  679. output = self.app.get('/test/adduser')
  680. csrf_token = output.data.split(
  681. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  682. # Missing request identifier
  683. data = {
  684. 'csrf_token': csrf_token,
  685. }
  686. output = self.app.post('/pv/pull-request/merge', data=data)
  687. self.assertEqual(output.status_code, 404)
  688. # With all the desired information
  689. project = pagure.lib.get_authorized_project(self.session, 'test')
  690. data = {
  691. 'csrf_token': csrf_token,
  692. 'requestid': project.requests[0].uid,
  693. }
  694. output = self.app.post('/pv/pull-request/merge', data=data)
  695. self.assertEqual(output.status_code, 200)
  696. exp = {
  697. "code": "MERGE",
  698. "message": "The pull-request can be merged with a merge commit",
  699. "short_code": "With merge"
  700. }
  701. js_data = json.loads(output.data)
  702. self.assertDictEqual(js_data, exp)
  703. @patch('pagure.lib.notify.send_email')
  704. def test_mergeable_request_pull_conflicts(self, send_email):
  705. """ Test the mergeable_request_pull endpoint when the changes cannot
  706. be merged due to conflicts.
  707. """
  708. send_email.return_value = True
  709. # Create a git repo to play with
  710. origgitrepo = os.path.join(self.path, 'repos', 'test.git')
  711. self.assertFalse(os.path.exists(origgitrepo))
  712. os.makedirs(origgitrepo)
  713. orig_repo = pygit2.init_repository(origgitrepo, bare=True)
  714. os.makedirs(os.path.join(self.path, 'repos_tmp'))
  715. gitrepo = os.path.join(self.path, 'repos_tmp', 'test.git')
  716. repo = pygit2.clone_repository(origgitrepo, gitrepo)
  717. # Create a file in that git repo
  718. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  719. stream.write('foo\n bar')
  720. repo.index.add('sources')
  721. repo.index.write()
  722. # Commits the files added
  723. tree = repo.index.write_tree()
  724. author = pygit2.Signature(
  725. 'Alice Author', 'alice@authors.tld')
  726. committer = pygit2.Signature(
  727. 'Cecil Committer', 'cecil@committers.tld')
  728. repo.create_commit(
  729. 'refs/heads/master', # the name of the reference to update
  730. author,
  731. committer,
  732. 'Add sources file for testing',
  733. # binary string representing the tree object ID
  734. tree,
  735. # list of binary strings representing parents of the new commit
  736. []
  737. )
  738. first_commit = repo.revparse_single('HEAD')
  739. refname = 'refs/heads/master:refs/heads/master'
  740. ori_remote = repo.remotes[0]
  741. PagureRepo.push(ori_remote, refname)
  742. # Edit the sources file again
  743. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  744. stream.write('foo\n bar\nbaz\n boose')
  745. repo.index.add('sources')
  746. repo.index.write()
  747. # Commits the files added
  748. tree = repo.index.write_tree()
  749. author = pygit2.Signature(
  750. 'Alice Author', 'alice@authors.tld')
  751. committer = pygit2.Signature(
  752. 'Cecil Committer', 'cecil@committers.tld')
  753. repo.create_commit(
  754. 'refs/heads/feature', # the name of the reference to update
  755. author,
  756. committer,
  757. 'Add baz and boose to the sources\n\n There are more objects to '
  758. 'consider',
  759. # binary string representing the tree object ID
  760. tree,
  761. # list of binary strings representing parents of the new commit
  762. [first_commit.oid.hex]
  763. )
  764. refname = 'refs/heads/feature:refs/heads/feature'
  765. ori_remote = repo.remotes[0]
  766. PagureRepo.push(ori_remote, refname)
  767. # Create another file in the master branch
  768. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  769. stream.write('foo\n bar\nbaz\n')
  770. repo.index.add('sources')
  771. repo.index.write()
  772. # Commits the files added
  773. tree = repo.index.write_tree()
  774. author = pygit2.Signature(
  775. 'Alice Author', 'alice@authors.tld')
  776. committer = pygit2.Signature(
  777. 'Cecil Committer', 'cecil@committers.tld')
  778. repo.create_commit(
  779. 'refs/heads/master', # the name of the reference to update
  780. author,
  781. committer,
  782. 'Add .gitignore file for testing',
  783. # binary string representing the tree object ID
  784. tree,
  785. # list of binary strings representing parents of the new commit
  786. [first_commit.oid.hex]
  787. )
  788. refname = 'refs/heads/master:refs/heads/master'
  789. ori_remote = repo.remotes[0]
  790. PagureRepo.push(ori_remote, refname)
  791. # Create a PR for these changes
  792. tests.create_projects(self.session)
  793. project = pagure.lib.get_authorized_project(self.session, 'test')
  794. req = pagure.lib.new_pull_request(
  795. session=self.session,
  796. repo_from=project,
  797. branch_from='feature',
  798. repo_to=project,
  799. branch_to='master',
  800. title='PR from the feature branch',
  801. user='pingou',
  802. requestfolder=None,
  803. )
  804. self.session.commit()
  805. self.assertEqual(req.id, 1)
  806. self.assertEqual(req.title, 'PR from the feature branch')
  807. # Check if the PR can be merged
  808. data = {}
  809. # Missing CSRF
  810. output = self.app.post('/pv/pull-request/merge', data=data)
  811. self.assertEqual(output.status_code, 400)
  812. user = tests.FakeUser()
  813. user.username = 'pingou'
  814. with tests.user_set(self.app.application, user):
  815. output = self.app.get('/test/adduser')
  816. csrf_token = output.data.split(
  817. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  818. # Missing request identifier
  819. data = {
  820. 'csrf_token': csrf_token,
  821. }
  822. output = self.app.post('/pv/pull-request/merge', data=data)
  823. self.assertEqual(output.status_code, 404)
  824. # With all the desired information
  825. project = pagure.lib.get_authorized_project(self.session, 'test')
  826. data = {
  827. 'csrf_token': csrf_token,
  828. 'requestid': project.requests[0].uid,
  829. }
  830. output = self.app.post('/pv/pull-request/merge', data=data)
  831. self.assertEqual(output.status_code, 200)
  832. exp = {
  833. "code": "CONFLICTS",
  834. "message": "The pull-request cannot be merged due to conflicts",
  835. "short_code": "Conflicts"
  836. }
  837. js_data = json.loads(output.data)
  838. self.assertDictEqual(js_data, exp)
  839. def test_get_branches_of_commit(self):
  840. ''' Test the get_branches_of_commit from the internal API. '''
  841. tests.create_projects(self.session)
  842. tests.create_projects_git(os.path.join(self.path, 'repos'))
  843. user = tests.FakeUser()
  844. user.username = 'pingou'
  845. with tests.user_set(self.app.application, user):
  846. output = self.app.get('/test/adduser')
  847. self.assertEqual(output.status_code, 200)
  848. csrf_token = output.data.split(
  849. b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0]
  850. # No CSRF token
  851. data = {
  852. 'repo': 'fakerepo',
  853. 'commit_id': 'foo',
  854. }
  855. output = self.app.post('/pv/branches/commit/', data=data)
  856. self.assertEqual(output.status_code, 400)
  857. js_data = json.loads(output.data.decode('utf-8'))
  858. self.assertDictEqual(
  859. js_data,
  860. {u'code': u'ERROR', u'message': u'Invalid input submitted'}
  861. )
  862. # Invalid repo
  863. data = {
  864. 'repo': 'fakerepo',
  865. 'commit_id': 'foo',
  866. 'csrf_token': csrf_token,
  867. }
  868. output = self.app.post('/pv/branches/commit/', data=data)
  869. self.assertEqual(output.status_code, 404)
  870. js_data = json.loads(output.data.decode('utf-8'))
  871. self.assertDictEqual(
  872. js_data,
  873. {
  874. u'code': u'ERROR',
  875. u'message': u'No repo found with the information provided'
  876. }
  877. )
  878. # Rigth repo, no commit
  879. data = {
  880. 'repo': 'test',
  881. 'csrf_token': csrf_token,
  882. }
  883. output = self.app.post('/pv/branches/commit/', data=data)
  884. self.assertEqual(output.status_code, 400)
  885. js_data = json.loads(output.data.decode('utf-8'))
  886. self.assertDictEqual(
  887. js_data,
  888. {u'code': u'ERROR', u'message': u'No commit id submitted'}
  889. )
  890. # Request is fine, but git repo doesn't exist
  891. item = pagure.lib.model.Project(
  892. user_id=1, # pingou
  893. name='test20',
  894. description='test project #20',
  895. hook_token='aaabbbhhh',
  896. )
  897. self.session.add(item)
  898. self.session.commit()
  899. data = {
  900. 'repo': 'test20',
  901. 'commit_id': 'foo',
  902. 'csrf_token': csrf_token,
  903. }
  904. output = self.app.post('/pv/branches/commit/', data=data)
  905. self.assertEqual(output.status_code, 404)
  906. js_data = json.loads(output.data.decode('utf-8'))
  907. self.assertDictEqual(
  908. js_data,
  909. {
  910. u'code': u'ERROR',
  911. u'message': u'No git repo found with the information provided'
  912. }
  913. )
  914. # Create a git repo to play with
  915. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  916. self.assertTrue(os.path.exists(gitrepo))
  917. repo = pygit2.Repository(gitrepo)
  918. # Create a file in that git repo
  919. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  920. stream.write('foo\n bar')
  921. repo.index.add('sources')
  922. repo.index.write()
  923. # Commits the files added
  924. tree = repo.index.write_tree()
  925. author = pygit2.Signature(
  926. 'Alice Author', 'alice@authors.tld')
  927. committer = pygit2.Signature(
  928. 'Cecil Committer', 'cecil@committers.tld')
  929. repo.create_commit(
  930. 'refs/heads/master', # the name of the reference to update
  931. author,
  932. committer,
  933. 'Add sources file for testing',
  934. # binary string representing the tree object ID
  935. tree,
  936. # list of binary strings representing parents of the new commit
  937. []
  938. )
  939. first_commit = repo.revparse_single('HEAD')
  940. # Edit the sources file again
  941. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  942. stream.write('foo\n bar\nbaz\n boose')
  943. repo.index.add('sources')
  944. repo.index.write()
  945. # Commits the files added
  946. tree = repo.index.write_tree()
  947. author = pygit2.Signature(
  948. 'Alice Author', 'alice@authors.tld')
  949. committer = pygit2.Signature(
  950. 'Cecil Committer', 'cecil@committers.tld')
  951. repo.create_commit(
  952. 'refs/heads/feature', # the name of the reference to update
  953. author,
  954. committer,
  955. 'Add baz and boose to the sources\n\n There are more objects to '
  956. 'consider',
  957. # binary string representing the tree object ID
  958. tree,
  959. # list of binary strings representing parents of the new commit
  960. [first_commit.oid.hex]
  961. )
  962. # Create another file in the master branch
  963. with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream:
  964. stream.write('*~')
  965. repo.index.add('.gitignore')
  966. repo.index.write()
  967. # Commits the files added
  968. tree = repo.index.write_tree()
  969. author = pygit2.Signature(
  970. 'Alice Author', 'alice@authors.tld')
  971. committer = pygit2.Signature(
  972. 'Cecil Committer', 'cecil@committers.tld')
  973. commit_hash = repo.create_commit(
  974. 'refs/heads/feature_branch', # the name of the reference to update
  975. author,
  976. committer,
  977. 'Add .gitignore file for testing',
  978. # binary string representing the tree object ID
  979. tree,
  980. # list of binary strings representing parents of the new commit
  981. [first_commit.oid.hex]
  982. )
  983. # All good but the commit id
  984. data = {
  985. 'repo': 'test',
  986. 'commit_id': 'foo',
  987. 'csrf_token': csrf_token,
  988. }
  989. output = self.app.post('/pv/branches/commit/', data=data)
  990. self.assertEqual(output.status_code, 404)
  991. js_data = json.loads(output.data.decode('utf-8'))
  992. self.assertDictEqual(
  993. js_data,
  994. {
  995. u'code': u'ERROR',
  996. u'message': 'This commit could not be found in this repo'
  997. }
  998. )
  999. # All good
  1000. data = {
  1001. 'repo': 'test',
  1002. 'commit_id': commit_hash,
  1003. 'csrf_token': csrf_token,
  1004. }
  1005. output = self.app.post('/pv/branches/commit/', data=data)
  1006. self.assertEqual(output.status_code, 200)
  1007. js_data = json.loads(output.data.decode('utf-8'))
  1008. self.assertDictEqual(
  1009. js_data,
  1010. {
  1011. u'code': u'OK',
  1012. u'branches': ['feature_branch'],
  1013. }
  1014. )
  1015. def test_get_branches_of_commit_with_unrelated_branches(self):
  1016. ''' Test the get_branches_of_commit from the internal API. '''
  1017. tests.create_projects(self.session)
  1018. tests.create_projects_git(os.path.join(self.path, 'repos'))
  1019. user = tests.FakeUser(username='pingou')
  1020. with tests.user_set(self.app.application, user):
  1021. csrf_token = self.get_csrf()
  1022. # Create a git repo to play with
  1023. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1024. self.assertTrue(os.path.exists(gitrepo))
  1025. repo = pygit2.Repository(gitrepo)
  1026. # Create a file in that git repo
  1027. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  1028. stream.write('foo\n bar')
  1029. repo.index.add('sources')
  1030. repo.index.write()
  1031. # Commits the files added
  1032. tree = repo.index.write_tree()
  1033. author = pygit2.Signature(
  1034. 'Alice Author', 'alice@authors.tld')
  1035. committer = pygit2.Signature(
  1036. 'Cecil Committer', 'cecil@committers.tld')
  1037. repo.create_commit(
  1038. 'refs/heads/master', # the name of the reference to update
  1039. author,
  1040. committer,
  1041. 'Add sources file for testing',
  1042. # binary string representing the tree object ID
  1043. tree,
  1044. # list of binary strings representing parents of the new commit
  1045. []
  1046. )
  1047. first_commit = repo.revparse_single('HEAD')
  1048. # Edit the sources file again
  1049. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  1050. stream.write('foo\n bar\nbaz\n boose')
  1051. repo.index.add('sources')
  1052. repo.index.write()
  1053. # Commits the files added, but unrelated with the first commit
  1054. tree = repo.index.write_tree()
  1055. author = pygit2.Signature(
  1056. 'Alice Author', 'alice@authors.tld')
  1057. committer = pygit2.Signature(
  1058. 'Cecil Committer', 'cecil@committers.tld')
  1059. commit = repo.create_commit(
  1060. 'refs/heads/feature', # the name of the reference to update
  1061. author,
  1062. committer,
  1063. 'Add baz and boose to the sources\n\n There are more objects to '
  1064. 'consider',
  1065. # binary string representing the tree object ID
  1066. tree,
  1067. # list of binary strings representing parents of the new commit
  1068. []
  1069. )
  1070. commit_hash = commit.hex
  1071. # All good
  1072. data = {
  1073. 'repo': 'test',
  1074. 'commit_id': commit_hash,
  1075. 'csrf_token': csrf_token,
  1076. }
  1077. output = self.app.post('/pv/branches/commit/', data=data)
  1078. self.assertEqual(output.status_code, 200)
  1079. js_data = json.loads(output.data.decode('utf-8'))
  1080. self.assertDictEqual(
  1081. js_data,
  1082. {
  1083. u'code': u'OK',
  1084. u'branches': ['feature'],
  1085. }
  1086. )
  1087. def test_get_branches_head(self):
  1088. ''' Test the get_branches_head from the internal API. '''
  1089. tests.create_projects(self.session)
  1090. tests.create_projects_git(os.path.join(self.path, 'repos'))
  1091. user = tests.FakeUser()
  1092. user.username = 'pingou'
  1093. with tests.user_set(self.app.application, user):
  1094. csrf_token = self.get_csrf()
  1095. # No CSRF token
  1096. data = {
  1097. 'repo': 'fakerepo',
  1098. }
  1099. output = self.app.post('/pv/branches/heads/', data=data)
  1100. self.assertEqual(output.status_code, 400)
  1101. js_data = json.loads(output.data.decode('utf-8'))
  1102. self.assertDictEqual(
  1103. js_data,
  1104. {u'code': u'ERROR', u'message': u'Invalid input submitted'}
  1105. )
  1106. # Invalid repo
  1107. data = {
  1108. 'repo': 'fakerepo',
  1109. 'commit_id': 'foo',
  1110. 'csrf_token': csrf_token,
  1111. }
  1112. output = self.app.post('/pv/branches/heads/', data=data)
  1113. self.assertEqual(output.status_code, 404)
  1114. js_data = json.loads(output.data.decode('utf-8'))
  1115. self.assertDictEqual(
  1116. js_data,
  1117. {
  1118. u'code': u'ERROR',
  1119. u'message': u'No repo found with the information provided'
  1120. }
  1121. )
  1122. # Rigth repo, no commit
  1123. data = {
  1124. 'repo': 'test',
  1125. 'csrf_token': csrf_token,
  1126. }
  1127. output = self.app.post('/pv/branches/heads/', data=data)
  1128. self.assertEqual(output.status_code, 200)
  1129. js_data = json.loads(output.data.decode('utf-8'))
  1130. self.assertDictEqual(
  1131. js_data,
  1132. {u"branches": {}, u"code": u"OK", u"heads": {}}
  1133. )
  1134. # Request is fine, but git repo doesn't exist
  1135. item = pagure.lib.model.Project(
  1136. user_id=1, # pingou
  1137. name='test20',
  1138. description='test project #20',
  1139. hook_token='aaabbbhhh',
  1140. )
  1141. self.session.add(item)
  1142. self.session.commit()
  1143. data = {
  1144. 'repo': 'test20',
  1145. 'csrf_token': csrf_token,
  1146. }
  1147. output = self.app.post('/pv/branches/heads/', data=data)
  1148. self.assertEqual(output.status_code, 404)
  1149. js_data = json.loads(output.data.decode('utf-8'))
  1150. self.assertDictEqual(
  1151. js_data,
  1152. {
  1153. u'code': u'ERROR',
  1154. u'message': u'No git repo found with the information provided'
  1155. }
  1156. )
  1157. # Create a git repo to play with
  1158. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  1159. self.assertTrue(os.path.exists(gitrepo))
  1160. repo = pygit2.Repository(gitrepo)
  1161. # Create a file in that git repo
  1162. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  1163. stream.write('foo\n bar')
  1164. repo.index.add('sources')
  1165. repo.index.write()
  1166. # Commits the files added
  1167. tree = repo.index.write_tree()
  1168. author = pygit2.Signature(
  1169. 'Alice Author', 'alice@authors.tld')
  1170. committer = pygit2.Signature(
  1171. 'Cecil Committer', 'cecil@committers.tld')
  1172. repo.create_commit(
  1173. 'refs/heads/master', # the name of the reference to update
  1174. author,
  1175. committer,
  1176. 'Add sources file for testing',
  1177. # binary string representing the tree object ID
  1178. tree,
  1179. # list of binary strings representing parents of the new commit
  1180. []
  1181. )
  1182. first_commit = repo.revparse_single('HEAD')
  1183. # Edit the sources file again
  1184. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  1185. stream.write('foo\n bar\nbaz\n boose')
  1186. repo.index.add('sources')
  1187. repo.index.write()
  1188. # Commits the files added
  1189. tree = repo.index.write_tree()
  1190. author = pygit2.Signature(
  1191. 'Alice Author', 'alice@authors.tld')
  1192. committer = pygit2.Signature(
  1193. 'Cecil Committer', 'cecil@committers.tld')
  1194. repo.create_commit(
  1195. 'refs/heads/feature', # the name of the reference to update
  1196. author,
  1197. committer,
  1198. 'Add baz and boose to the sources\n\n There are more objects to '
  1199. 'consider',
  1200. # binary string representing the tree object ID
  1201. tree,
  1202. # list of binary strings representing parents of the new commit
  1203. [first_commit.oid.hex]
  1204. )
  1205. # Create another file in the master branch
  1206. with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream:
  1207. stream.write('*~')
  1208. repo.index.add('.gitignore')
  1209. repo.index.write()
  1210. # Commits the files added
  1211. tree = repo.index.write_tree()
  1212. author = pygit2.Signature(
  1213. 'Alice Author', 'alice@authors.tld')
  1214. committer = pygit2.Signature(
  1215. 'Cecil Committer', 'cecil@committers.tld')
  1216. commit_hash = repo.create_commit(
  1217. 'refs/heads/feature_branch', # the name of the reference to update
  1218. author,
  1219. committer,
  1220. 'Add .gitignore file for testing',
  1221. # binary string representing the tree object ID
  1222. tree,
  1223. # list of binary strings representing parents of the new commit
  1224. [first_commit.oid.hex]
  1225. )
  1226. # All good
  1227. data = {
  1228. 'repo': 'test',
  1229. 'csrf_token': csrf_token,
  1230. }
  1231. output = self.app.post('/pv/branches/heads/', data=data)
  1232. self.assertEqual(output.status_code, 200)
  1233. js_data = json.loads(output.data.decode('utf-8'))
  1234. # We can't test the content since the commit hash will change all
  1235. # the time, so let's just check the structure
  1236. self.assertEqual(
  1237. sorted(js_data.keys()), ['branches', 'code', 'heads'])
  1238. self.assertEqual(js_data['code'], 'OK')
  1239. self.assertEqual(len(js_data['heads']), 3)
  1240. self.assertEqual(len(js_data['branches']), 3)
  1241. def test_get_stats_commits_no_token(self):
  1242. ''' Test the get_stats_commits from the internal API. '''
  1243. # No CSRF token
  1244. data = {
  1245. 'repo': 'fakerepo',
  1246. }
  1247. output = self.app.post('/pv/stats/commits/authors', data=data)
  1248. self.assertEqual(output.status_code, 400)
  1249. js_data = json.loads(output.data.decode('utf-8'))
  1250. self.assertDictEqual(
  1251. js_data,
  1252. {u'code': u'ERROR', u'message': u'Invalid input submitted'}
  1253. )
  1254. def test_get_stats_commits_invalid_repo(self):
  1255. ''' Test the get_stats_commits from the internal API. '''
  1256. user = tests.FakeUser()
  1257. user.username = 'pingou'
  1258. with tests.user_set(self.app.application, user):
  1259. csrf_token = self.get_csrf()
  1260. # Invalid repo
  1261. data = {
  1262. 'repo': 'fakerepo',
  1263. 'csrf_token': csrf_token,
  1264. }
  1265. output = self.app.post('/pv/stats/commits/authors', data=data)
  1266. self.assertEqual(output.status_code, 404)
  1267. js_data = json.loads(output.data.decode('utf-8'))
  1268. self.assertDictEqual(
  1269. js_data,
  1270. {u'code': u'ERROR',
  1271. u'message': u'No repo found with the information provided'}
  1272. )
  1273. def test_get_stats_commits_empty_git(self):
  1274. ''' Test the get_stats_commits from the internal API. '''
  1275. tests.create_projects(self.session)
  1276. tests.create_projects_git(os.path.join(self.path, 'repos'))
  1277. user = tests.FakeUser()
  1278. user.username = 'pingou'
  1279. with tests.user_set(self.app.application, user):
  1280. csrf_token = self.get_csrf()
  1281. # No content in git
  1282. data = {
  1283. 'repo': 'test',
  1284. 'csrf_token': csrf_token,
  1285. }
  1286. output = self.app.post('/pv/stats/commits/authors', data=data)
  1287. self.assertEqual(output.status_code, 200)
  1288. js_data = json.loads(output.data.decode('utf-8'))
  1289. self.assertEqual(
  1290. sorted(js_data.keys()),
  1291. ['code', 'message', 'task_id', 'url']
  1292. )
  1293. self.assertEqual(js_data['code'], 'OK')
  1294. self.assertEqual(js_data['message'], 'Stats asked')
  1295. self.assertTrue(js_data['url'].startswith('/pv/task/'))
  1296. output = self.app.get(js_data['url'])
  1297. js_data2 = json.loads(output.data.decode('utf-8'))
  1298. self.assertTrue(
  1299. js_data2 in [
  1300. {u'results': u"reference 'refs/heads/master' not found"},
  1301. {u'results': u"Reference 'refs/heads/master' not found"}
  1302. ]
  1303. )
  1304. def test_get_stats_commits_git_populated(self):
  1305. ''' Test the get_stats_commits from the internal API. '''
  1306. tests.create_projects(self.session)
  1307. tests.create_projects_git(
  1308. os.path.join(self.path, 'repos'), bare=True)
  1309. tests.add_content_git_repo(
  1310. os.path.join(self.path, 'repos', 'test.git'))
  1311. user = tests.FakeUser()
  1312. user.username = 'pingou'
  1313. with tests.user_set(self.app.application, user):
  1314. csrf_token = self.get_csrf()
  1315. # Content in git
  1316. data = {
  1317. 'repo': 'test',
  1318. 'csrf_token': csrf_token,
  1319. }
  1320. output = self.app.post('/pv/stats/commits/authors', data=data)
  1321. self.assertEqual(output.status_code, 200)
  1322. js_data = json.loads(output.data.decode('utf-8'))
  1323. self.assertEqual(
  1324. sorted(js_data.keys()),
  1325. ['code', 'message', 'task_id', 'url']
  1326. )
  1327. self.assertEqual(js_data['code'], 'OK')
  1328. self.assertEqual(js_data['message'], 'Stats asked')
  1329. self.assertTrue(js_data['url'].startswith('/pv/task/'))
  1330. output = self.app.get(js_data['url'])
  1331. while output.status_code == 418:
  1332. time.sleep(0.5)
  1333. output = self.app.get(js_data['url'])
  1334. js_data2 = json.loads(output.data.decode('utf-8'))
  1335. self.assertTrue(js_data2['results'][3] > 1509110062)
  1336. js_data2['results'][3] = 1509110062
  1337. self.assertDictEqual(
  1338. js_data2,
  1339. {u'results': [
  1340. 2,
  1341. [[2, [[u'Alice Author', u'alice@authors.tld']]]],
  1342. 1,
  1343. 1509110062
  1344. ]
  1345. }
  1346. )
  1347. def test_get_stats_commits_trend_no_token(self):
  1348. ''' Test the get_stats_commits_trend from the internal API. '''
  1349. # No CSRF token
  1350. data = {
  1351. 'repo': 'fakerepo',
  1352. }
  1353. output = self.app.post('/pv/stats/commits/trend', data=data)
  1354. self.assertEqual(output.status_code, 400)
  1355. js_data = json.loads(output.data.decode('utf-8'))
  1356. self.assertDictEqual(
  1357. js_data,
  1358. {u'code': u'ERROR', u'message': u'Invalid input submitted'}
  1359. )
  1360. def test_get_stats_commits_trend_invalid_repo(self):
  1361. """ Test the get_stats_commits_trend from the internal API. """
  1362. user = tests.FakeUser()
  1363. user.username = 'pingou'
  1364. with tests.user_set(self.app.application, user):
  1365. csrf_token = self.get_csrf()
  1366. # Invalid repo
  1367. data = {
  1368. 'repo': 'fakerepo',
  1369. 'csrf_token': csrf_token,
  1370. }
  1371. output = self.app.post('/pv/stats/commits/trend', data=data)
  1372. self.assertEqual(output.status_code, 404)
  1373. js_data = json.loads(output.data.decode('utf-8'))
  1374. self.assertDictEqual(
  1375. js_data,
  1376. {u'code': u'ERROR',
  1377. u'message': u'No repo found with the information provided'}
  1378. )
  1379. def test_get_stats_commits_trend_empty_git(self):
  1380. ''' Test the get_stats_commits_trend from the internal API. '''
  1381. tests.create_projects(self.session)
  1382. tests.create_projects_git(os.path.join(self.path, 'repos'))
  1383. user = tests.FakeUser()
  1384. user.username = 'pingou'
  1385. with tests.user_set(self.app.application, user):
  1386. csrf_token = self.get_csrf()
  1387. # No content in git
  1388. data = {
  1389. 'repo': 'test',
  1390. 'csrf_token': csrf_token,
  1391. }
  1392. output = self.app.post('/pv/stats/commits/trend', data=data)
  1393. self.assertEqual(output.status_code, 200)
  1394. js_data = json.loads(output.data.decode('utf-8'))
  1395. self.assertEqual(
  1396. sorted(js_data.keys()),
  1397. ['code', 'message', 'task_id', 'url']
  1398. )
  1399. self.assertEqual(js_data['code'], 'OK')
  1400. self.assertEqual(js_data['message'], 'Stats asked')
  1401. self.assertTrue(js_data['url'].startswith('/pv/task/'))
  1402. output = self.app.get(js_data['url'])
  1403. js_data2 = json.loads(output.data.decode('utf-8'))
  1404. self.assertTrue(
  1405. js_data2 in [
  1406. {u'results': u"reference 'refs/heads/master' not found"},
  1407. {u'results': u"Reference 'refs/heads/master' not found"}
  1408. ]
  1409. )
  1410. def test_get_stats_commits_trend_git_populated(self):
  1411. ''' Test the get_stats_commits_trend from the internal API. '''
  1412. tests.create_projects(self.session)
  1413. tests.create_projects_git(
  1414. os.path.join(self.path, 'repos'), bare=True)
  1415. tests.add_content_git_repo(
  1416. os.path.join(self.path, 'repos', 'test.git'))
  1417. user = tests.FakeUser()
  1418. user.username = 'pingou'
  1419. with tests.user_set(self.app.application, user):
  1420. csrf_token = self.get_csrf()
  1421. # Content in git
  1422. data = {
  1423. 'repo': 'test',
  1424. 'csrf_token': csrf_token,
  1425. }
  1426. output = self.app.post('/pv/stats/commits/trend', data=data)
  1427. self.assertEqual(output.status_code, 200)
  1428. js_data = json.loads(output.data.decode('utf-8'))
  1429. self.assertEqual(
  1430. sorted(js_data.keys()),
  1431. ['code', 'message', 'task_id', 'url']
  1432. )
  1433. self.assertEqual(js_data['code'], 'OK')
  1434. self.assertEqual(js_data['message'], 'Stats asked')
  1435. self.assertTrue(js_data['url'].startswith('/pv/task/'))
  1436. output = self.app.get(js_data['url'])
  1437. js_data2 = json.loads(output.data.decode('utf-8'))
  1438. today = datetime.datetime.utcnow().date()
  1439. self.assertDictEqual(
  1440. js_data2,
  1441. {u'results': [[str(today), 2]]}
  1442. )
  1443. def test_get_project_family_no_project(self):
  1444. ''' Test the get_project_family from the internal API. '''
  1445. output = self.app.post('/pv/test/family')
  1446. self.assertEqual(output.status_code, 404)
  1447. def test_get_project_family_no_csrf(self):
  1448. ''' Test the get_project_family from the internal API. '''
  1449. tests.create_projects(self.session)
  1450. tests.create_projects_git(
  1451. os.path.join(self.path, 'repos'), bare=True)
  1452. tests.add_content_git_repo(
  1453. os.path.join(self.path, 'repos', 'test.git'))
  1454. output = self.app.post('/pv/test/family')
  1455. self.assertEqual(output.status_code, 400)
  1456. js_data = json.loads(output.data.decode('utf-8'))
  1457. self.assertEqual(
  1458. sorted(js_data.keys()),
  1459. [u'code', u'message']
  1460. )
  1461. self.assertEqual(js_data['code'], u'ERROR')
  1462. self.assertEqual(js_data['message'], u'Invalid input submitted')
  1463. def test_get_project_family(self):
  1464. ''' Test the get_project_family from the internal API. '''
  1465. tests.create_projects(self.session)
  1466. tests.create_projects_git(
  1467. os.path.join(self.path, 'repos'), bare=True)
  1468. tests.add_content_git_repo(
  1469. os.path.join(self.path, 'repos', 'test.git'))
  1470. user = tests.FakeUser()
  1471. user.username = 'pingou'
  1472. with tests.user_set(self.app.application, user):
  1473. csrf_token = self.get_csrf()
  1474. data = {
  1475. 'csrf_token': csrf_token,
  1476. }
  1477. output = self.app.post('/pv/test/family', data=data)
  1478. self.assertEqual(output.status_code, 200)
  1479. js_data = json.loads(output.data.decode('utf-8'))
  1480. self.assertEqual(
  1481. sorted(js_data.keys()),
  1482. [u'code', u'family']
  1483. )
  1484. self.assertEqual(js_data['code'], 'OK')
  1485. self.assertEqual(js_data['family'], [u'test'])
  1486. def test_get_project_larger_family(self):
  1487. ''' Test the get_project_family from the internal API. '''
  1488. tests.create_projects(self.session)
  1489. tests.create_projects_git(
  1490. os.path.join(self.path, 'repos'), bare=True)
  1491. # Create a 3rd user
  1492. item = pagure.lib.model.User(
  1493. user='ralph',
  1494. fullname='Ralph bar',
  1495. password='ralph_foo',
  1496. default_email='ralph@bar.com',
  1497. )
  1498. self.session.add(item)
  1499. item = pagure.lib.model.UserEmail(
  1500. user_id=3,
  1501. email='ralph@bar.com')
  1502. self.session.add(item)
  1503. self.session.commit()
  1504. # Create a couple of forks of the test project
  1505. item = pagure.lib.model.Project(
  1506. user_id=2, # foo
  1507. name='test',
  1508. is_fork=True,
  1509. parent_id=1, # test
  1510. description='test project #1',
  1511. hook_token='aaabbbcccddd',
  1512. )
  1513. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  1514. self.session.add(item)
  1515. item = pagure.lib.model.Project(
  1516. user_id=3, # Ralph
  1517. name='test',
  1518. is_fork=True,
  1519. parent_id=1, # test
  1520. description='test project #1',
  1521. hook_token='aaabbbccceee',
  1522. )
  1523. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  1524. self.session.add(item)
  1525. self.session.commit()
  1526. # Get on with testing
  1527. user = tests.FakeUser()
  1528. user.username = 'pingou'
  1529. with tests.user_set(self.app.application, user):
  1530. csrf_token = self.get_csrf()
  1531. data = {
  1532. 'csrf_token': csrf_token,
  1533. }
  1534. output = self.app.post('/pv/test/family', data=data)
  1535. self.assertEqual(output.status_code, 200)
  1536. js_data = json.loads(output.data.decode('utf-8'))
  1537. self.assertEqual(
  1538. sorted(js_data.keys()),
  1539. [u'code', u'family']
  1540. )
  1541. self.assertEqual(js_data['code'], 'OK')
  1542. self.assertEqual(
  1543. js_data['family'],
  1544. [u'test', u'fork/foo/test', u'fork/ralph/test'])
  1545. def test_get_pull_request_ready_branch_main_repo_no_branch(self):
  1546. '''Test the get_pull_request_ready_branch from the internal API
  1547. on the main repository
  1548. '''
  1549. tests.create_projects(self.session)
  1550. tests.create_projects_git(
  1551. os.path.join(self.path, 'repos'), bare=True)
  1552. # Get on with testing
  1553. user = tests.FakeUser()
  1554. user.username = 'pingou'
  1555. with tests.user_set(self.app.application, user):
  1556. csrf_token = self.get_csrf()
  1557. # Query branches on the main repo
  1558. data = {
  1559. 'csrf_token': csrf_token,
  1560. 'repo': 'test',
  1561. }
  1562. output = self.app.post('/pv/pull-request/ready', data=data)
  1563. self.assertEqual(output.status_code, 200)
  1564. js_data = json.loads(output.data.decode('utf-8'))
  1565. self.assertEqual(
  1566. sorted(js_data.keys()),
  1567. [u'code', u'message']
  1568. )
  1569. self.assertEqual(js_data['code'], 'OK')
  1570. self.assertEqual(
  1571. js_data['message'],
  1572. {u'branch_w_pr': {}, u'new_branch': {}})
  1573. def test_get_pull_request_ready_branch_on_fork(self):
  1574. '''Test the get_pull_request_ready_branch from the internal API on
  1575. a fork
  1576. '''
  1577. tests.create_projects(self.session)
  1578. tests.create_projects_git(
  1579. os.path.join(self.path, 'repos'), bare=True)
  1580. tests.create_projects_git(
  1581. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  1582. tests.add_content_git_repo(
  1583. os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git'),
  1584. branch='feature')
  1585. # Create foo's fork of the test project
  1586. item = pagure.lib.model.Project(
  1587. user_id=2, # foo
  1588. name='test',
  1589. is_fork=True,
  1590. parent_id=1, # test
  1591. description='test project #1',
  1592. hook_token='aaabbbcccddd',
  1593. )
  1594. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  1595. self.session.add(item)
  1596. self.session.commit()
  1597. # Get on with testing
  1598. user = tests.FakeUser()
  1599. user.username = 'pingou'
  1600. with tests.user_set(self.app.application, user):
  1601. csrf_token = self.get_csrf()
  1602. # Query branches on the Ralph's fork
  1603. data = {
  1604. 'csrf_token': csrf_token,
  1605. 'repo': 'test',
  1606. 'repouser': 'foo',
  1607. }
  1608. output = self.app.post('/pv/pull-request/ready', data=data)
  1609. self.assertEqual(output.status_code, 200)
  1610. js_data = json.loads(output.data.decode('utf-8'))
  1611. self.assertEqual(
  1612. sorted(js_data.keys()),
  1613. [u'code', u'message']
  1614. )
  1615. self.assertEqual(js_data['code'], 'OK')
  1616. self.assertListEqual(
  1617. sorted(js_data['message'].keys()),
  1618. [u'branch_w_pr', u'new_branch'])
  1619. self.assertEqual(js_data['message']['branch_w_pr'], {})
  1620. self.assertEqual(js_data['message']['new_branch'].keys(), ['feature'])
  1621. self.assertEqual(len(js_data['message']['new_branch']['feature']), 2)
  1622. def test_get_pull_request_ready_branch_on_fork_no_parent_no_pr(self):
  1623. '''Test the get_pull_request_ready_branch from the internal API on
  1624. a fork that has no parent repo (deleted) and doesn't allow PR
  1625. '''
  1626. tests.create_projects(self.session)
  1627. tests.create_projects_git(
  1628. os.path.join(self.path, 'repos'), bare=True)
  1629. tests.create_projects_git(
  1630. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  1631. tests.add_content_git_repo(
  1632. os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git'),
  1633. branch='feature')
  1634. # Create foo's fork of the test project
  1635. item = pagure.lib.model.Project(
  1636. user_id=2, # foo
  1637. name='test',
  1638. is_fork=True,
  1639. parent_id=1, # test
  1640. description='test project #1',
  1641. hook_token='aaabbbcccddd',
  1642. )
  1643. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  1644. self.session.add(item)
  1645. self.session.commit()
  1646. settings = item.settings
  1647. settings['pull_requests'] = False
  1648. item.settings = settings
  1649. self.session.add(item)
  1650. self.session.commit()
  1651. # Delete the parent project
  1652. project = pagure.lib.get_authorized_project(self.session, 'test')
  1653. self.session.delete(project)
  1654. self.session.commit()
  1655. # Get on with testing
  1656. user = tests.FakeUser()
  1657. user.username = 'pingou'
  1658. with tests.user_set(self.app.application, user):
  1659. csrf_token = self.get_csrf()
  1660. # Query branches on the Ralph's fork
  1661. data = {
  1662. 'csrf_token': csrf_token,
  1663. 'repo': 'test',
  1664. 'repouser': 'foo',
  1665. }
  1666. output = self.app.post('/pv/pull-request/ready', data=data)
  1667. self.assertEqual(output.status_code, 400)
  1668. js_data = json.loads(output.data.decode('utf-8'))
  1669. self.assertEqual(
  1670. sorted(js_data.keys()),
  1671. [u'code', u'message']
  1672. )
  1673. self.assertEqual(js_data['code'], 'ERROR')
  1674. self.assertEqual(
  1675. js_data['message'],
  1676. 'Pull-request have been disabled for this repo')
  1677. def test_get_pull_request_ready_branch_on_fork_no_parent(self):
  1678. '''Test the get_pull_request_ready_branch from the internal API on
  1679. a fork that has no parent repo (deleted).
  1680. '''
  1681. tests.create_projects(self.session)
  1682. tests.create_projects_git(
  1683. os.path.join(self.path, 'repos'), bare=True)
  1684. tests.create_projects_git(
  1685. os.path.join(self.path, 'repos', 'forks', 'foo'), bare=True)
  1686. tests.add_content_git_repo(
  1687. os.path.join(self.path, 'repos', 'forks', 'foo', 'test.git'),
  1688. branch='feature')
  1689. # Create foo's fork of the test project
  1690. item = pagure.lib.model.Project(
  1691. user_id=2, # foo
  1692. name='test',
  1693. is_fork=True,
  1694. parent_id=1, # test
  1695. description='test project #1',
  1696. hook_token='aaabbbcccddd',
  1697. )
  1698. item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
  1699. self.session.add(item)
  1700. self.session.commit()
  1701. settings = item.settings
  1702. settings['pull_requests'] = True
  1703. item.settings = settings
  1704. self.session.add(item)
  1705. self.session.commit()
  1706. # Delete the parent project
  1707. project = pagure.lib.get_authorized_project(self.session, 'test')
  1708. self.session.delete(project)
  1709. self.session.commit()
  1710. # Get on with testing
  1711. user = tests.FakeUser()
  1712. user.username = 'pingou'
  1713. with tests.user_set(self.app.application, user):
  1714. csrf_token = self.get_csrf()
  1715. # Query branches on the Ralph's fork
  1716. data = {
  1717. 'csrf_token': csrf_token,
  1718. 'repo': 'test',
  1719. 'repouser': 'foo',
  1720. }
  1721. output = self.app.post('/pv/pull-request/ready', data=data)
  1722. self.assertEqual(output.status_code, 200)
  1723. js_data = json.loads(output.data.decode('utf-8'))
  1724. self.assertEqual(
  1725. sorted(js_data.keys()),
  1726. [u'code', u'message']
  1727. )
  1728. self.assertEqual(js_data['code'], 'OK')
  1729. self.assertEqual(
  1730. sorted(js_data['message'].keys()),
  1731. [u'branch_w_pr', u'new_branch'])
  1732. self.assertEqual(js_data['message']['branch_w_pr'], {})
  1733. self.assertEqual(js_data['message']['new_branch'].keys(), ['feature'])
  1734. self.assertEqual(len(js_data['message']['new_branch']['feature']), 2)
  1735. if __name__ == '__main__':
  1736. unittest.main(verbosity=2)