test_pagure_flask_internal.py 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  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 os
  14. import pygit2
  15. from mock import patch
  16. sys.path.insert(0, os.path.join(os.path.dirname(
  17. os.path.abspath(__file__)), '..'))
  18. import pagure.lib
  19. import tests
  20. class PagureFlaskInternaltests(tests.Modeltests):
  21. """ Tests for flask Internal controller of pagure """
  22. def setUp(self):
  23. """ Set up the environnment, ran before every tests. """
  24. super(PagureFlaskInternaltests, self).setUp()
  25. pagure.APP.config['TESTING'] = True
  26. pagure.APP.config['IP_ALLOWED_INTERNAL'] = list(set(
  27. pagure.APP.config['IP_ALLOWED_INTERNAL'] + [None]))
  28. pagure.SESSION = self.session
  29. pagure.internal.SESSION = self.session
  30. pagure.ui.repo.SESSION = self.session
  31. pagure.ui.filters.SESSION = self.session
  32. pagure.APP.config['GIT_FOLDER'] = self.path
  33. pagure.APP.config['FORK_FOLDER'] = os.path.join(
  34. self.path, 'forks')
  35. pagure.APP.config['REQUESTS_FOLDER'] = None
  36. pagure.APP.config['TICKETS_FOLDER'] = None
  37. pagure.APP.config['DOCS_FOLDER'] = None
  38. self.app = pagure.APP.test_client()
  39. @patch('pagure.lib.notify.send_email')
  40. def test_pull_request_add_comment(self, send_email):
  41. """ Test the pull_request_add_comment function. """
  42. send_email.return_value = True
  43. tests.create_projects(self.session)
  44. repo = pagure.lib.get_project(self.session, 'test')
  45. req = pagure.lib.new_pull_request(
  46. session=self.session,
  47. repo_from=repo,
  48. branch_from='feature',
  49. repo_to=repo,
  50. branch_to='master',
  51. title='PR from the feature branch',
  52. user='pingou',
  53. requestfolder=None,
  54. )
  55. self.session.commit()
  56. self.assertEqual(req.id, 1)
  57. self.assertEqual(req.title, 'PR from the feature branch')
  58. request = repo.requests[0]
  59. self.assertEqual(len(request.comments), 0)
  60. self.assertEqual(len(request.discussion), 0)
  61. data = {
  62. 'objid': 'foo',
  63. }
  64. # Wrong http request
  65. output = self.app.post('/pv/pull-request/comment/', data=data)
  66. self.assertEqual(output.status_code, 405)
  67. # Invalid request
  68. output = self.app.put('/pv/pull-request/comment/', data=data)
  69. self.assertEqual(output.status_code, 400)
  70. data = {
  71. 'objid': 'foo',
  72. 'useremail': 'foo@pingou.com',
  73. }
  74. # Invalid objid
  75. output = self.app.put('/pv/pull-request/comment/', data=data)
  76. self.assertEqual(output.status_code, 404)
  77. data = {
  78. 'objid': request.uid,
  79. 'useremail': 'foo@pingou.com',
  80. }
  81. # Valid objid, in-complete data for a comment
  82. output = self.app.put('/pv/pull-request/comment/', data=data)
  83. self.assertEqual(output.status_code, 400)
  84. data = {
  85. 'objid': request.uid,
  86. 'useremail': 'foo@pingou.com',
  87. 'comment': 'Looks good to me!',
  88. }
  89. # Add comment
  90. output = self.app.put('/pv/pull-request/comment/', data=data)
  91. self.assertEqual(output.status_code, 200)
  92. js_data = json.loads(output.data)
  93. self.assertDictEqual(js_data, {'message': 'Comment added'})
  94. repo = pagure.lib.get_project(self.session, 'test')
  95. request = repo.requests[0]
  96. self.assertEqual(len(request.comments), 1)
  97. self.assertEqual(len(request.discussion), 1)
  98. # Check the @localonly
  99. pagure.APP.config['IP_ALLOWED_INTERNAL'].remove(None)
  100. output = self.app.put('/pv/pull-request/comment/', data=data)
  101. self.assertEqual(output.status_code, 403)
  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_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. repo = pagure.lib.get_project(self.session, 'test')
  155. issue = repo.issues[0]
  156. self.assertEqual(len(issue.comments), 1)
  157. # Check the @localonly
  158. pagure.APP.config['IP_ALLOWED_INTERNAL'].remove(None)
  159. output = self.app.put('/pv/ticket/comment/', data=data)
  160. self.assertEqual(output.status_code, 403)
  161. @patch('pagure.lib.notify.send_email')
  162. def test_private_ticket_add_comment(self, send_email):
  163. """ Test the ticket_add_comment function on a private ticket. """
  164. send_email.return_value = True
  165. tests.create_projects(self.session)
  166. # Create issues to play with
  167. repo = pagure.lib.get_project(self.session, 'test')
  168. msg = pagure.lib.new_issue(
  169. session=self.session,
  170. repo=repo,
  171. title='Test issue',
  172. content='We should work on this, really',
  173. user='pingou',
  174. private=True,
  175. ticketfolder=None
  176. )
  177. self.session.commit()
  178. self.assertEqual(msg.title, 'Test issue')
  179. issue = repo.issues[0]
  180. self.assertEqual(len(issue.comments), 0)
  181. data = {
  182. 'objid': 'foo',
  183. }
  184. # Wrong http request
  185. output = self.app.post('/pv/ticket/comment/', data=data)
  186. self.assertEqual(output.status_code, 405)
  187. # Invalid request
  188. output = self.app.put('/pv/ticket/comment/', data=data)
  189. self.assertEqual(output.status_code, 400)
  190. data = {
  191. 'objid': 'foo',
  192. 'useremail': 'foo@pingou.com',
  193. }
  194. # Invalid objid
  195. output = self.app.put('/pv/ticket/comment/', data=data)
  196. self.assertEqual(output.status_code, 404)
  197. data = {
  198. 'objid': issue.uid,
  199. 'useremail': 'foo@bar.com',
  200. }
  201. # Valid objid, un-allowed user for this (private) ticket
  202. output = self.app.put('/pv/ticket/comment/', data=data)
  203. self.assertEqual(output.status_code, 403)
  204. data = {
  205. 'objid': issue.uid,
  206. 'useremail': 'foo@pingou.com',
  207. }
  208. # Valid objid, un-allowed user for this (private) ticket
  209. output = self.app.put('/pv/ticket/comment/', data=data)
  210. self.assertEqual(output.status_code, 400)
  211. data = {
  212. 'objid': issue.uid,
  213. 'useremail': 'foo@pingou.com',
  214. 'comment': 'Looks good to me!',
  215. }
  216. # Add comment
  217. output = self.app.put('/pv/ticket/comment/', data=data)
  218. self.assertEqual(output.status_code, 200)
  219. js_data = json.loads(output.data)
  220. self.assertDictEqual(js_data, {'message': 'Comment added'})
  221. repo = pagure.lib.get_project(self.session, 'test')
  222. issue = repo.issues[0]
  223. self.assertEqual(len(issue.comments), 1)
  224. # Check the @localonly
  225. pagure.APP.config['IP_ALLOWED_INTERNAL'].remove(None)
  226. output = self.app.put('/pv/ticket/comment/', data=data)
  227. self.assertEqual(output.status_code, 403)
  228. @patch('pagure.lib.notify.send_email')
  229. def test_mergeable_request_pull_FF(self, send_email):
  230. """ Test the mergeable_request_pull endpoint with a fast-forward
  231. merge.
  232. """
  233. send_email.return_value = True
  234. # Create a git repo to play with
  235. gitrepo = os.path.join(self.path, 'test.git')
  236. self.assertFalse(os.path.exists(gitrepo))
  237. os.makedirs(gitrepo)
  238. repo = pygit2.init_repository(gitrepo)
  239. # Create a file in that git repo
  240. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  241. stream.write('foo\n bar')
  242. repo.index.add('sources')
  243. repo.index.write()
  244. # Commits the files added
  245. tree = repo.index.write_tree()
  246. author = pygit2.Signature(
  247. 'Alice Author', 'alice@authors.tld')
  248. committer = pygit2.Signature(
  249. 'Cecil Committer', 'cecil@committers.tld')
  250. repo.create_commit(
  251. 'refs/heads/master', # the name of the reference to update
  252. author,
  253. committer,
  254. 'Add sources file for testing',
  255. # binary string representing the tree object ID
  256. tree,
  257. # list of binary strings representing parents of the new commit
  258. []
  259. )
  260. first_commit = repo.revparse_single('HEAD')
  261. # Edit the sources file again
  262. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  263. stream.write('foo\n bar\nbaz\n boose')
  264. repo.index.add('sources')
  265. repo.index.write()
  266. # Commits the files added
  267. tree = repo.index.write_tree()
  268. author = pygit2.Signature(
  269. 'Alice Author', 'alice@authors.tld')
  270. committer = pygit2.Signature(
  271. 'Cecil Committer', 'cecil@committers.tld')
  272. repo.create_commit(
  273. 'refs/heads/feature', # the name of the reference to update
  274. author,
  275. committer,
  276. 'Add baz and boose to the sources\n\n There are more objects to '
  277. 'consider',
  278. # binary string representing the tree object ID
  279. tree,
  280. # list of binary strings representing parents of the new commit
  281. [first_commit.oid.hex]
  282. )
  283. second_commit = repo.revparse_single('HEAD')
  284. # Create a PR for these changes
  285. tests.create_projects(self.session)
  286. project = pagure.lib.get_project(self.session, 'test')
  287. req = pagure.lib.new_pull_request(
  288. session=self.session,
  289. repo_from=project,
  290. branch_from='feature',
  291. repo_to=project,
  292. branch_to='master',
  293. title='PR from the feature branch',
  294. user='pingou',
  295. requestfolder=None,
  296. )
  297. self.session.commit()
  298. self.assertEqual(req.id, 1)
  299. self.assertEqual(req.title, 'PR from the feature branch')
  300. # Check if the PR can be merged
  301. data = {
  302. 'objid': 'blah',
  303. }
  304. # Missing CSRF
  305. output = self.app.post('/pv/pull-request/merge', data=data)
  306. self.assertEqual(output.status_code, 400)
  307. user = tests.FakeUser()
  308. user.username = 'pingou'
  309. with tests.user_set(pagure.APP, user):
  310. output = self.app.get('/test/adduser')
  311. csrf_token = output.data.split(
  312. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  313. # Missing request identifier
  314. data = {
  315. 'csrf_token': csrf_token,
  316. }
  317. output = self.app.post('/pv/pull-request/merge', data=data)
  318. self.assertEqual(output.status_code, 404)
  319. # With all the desired information
  320. project = pagure.lib.get_project(self.session, 'test')
  321. data = {
  322. 'csrf_token': csrf_token,
  323. 'requestid': project.requests[0].uid,
  324. }
  325. output = self.app.post('/pv/pull-request/merge', data=data)
  326. self.assertEqual(output.status_code, 200)
  327. exp = {
  328. "code": "FFORWARD",
  329. "message": "The pull-request can be merged and fast-forwarded",
  330. "short_code": "Ok"
  331. }
  332. js_data = json.loads(output.data)
  333. self.assertDictEqual(js_data, exp)
  334. @patch('pagure.lib.notify.send_email')
  335. def test_mergeable_request_pull_no_change(self, send_email):
  336. """ Test the mergeable_request_pull endpoint when there are no
  337. changes to merge.
  338. """
  339. send_email.return_value = True
  340. # Create a git repo to play with
  341. gitrepo = os.path.join(self.path, 'test.git')
  342. self.assertFalse(os.path.exists(gitrepo))
  343. os.makedirs(gitrepo)
  344. repo = pygit2.init_repository(gitrepo)
  345. # Create a file in that git repo
  346. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  347. stream.write('foo\n bar')
  348. repo.index.add('sources')
  349. repo.index.write()
  350. # Commits the files added
  351. tree = repo.index.write_tree()
  352. author = pygit2.Signature(
  353. 'Alice Author', 'alice@authors.tld')
  354. committer = pygit2.Signature(
  355. 'Cecil Committer', 'cecil@committers.tld')
  356. repo.create_commit(
  357. 'refs/heads/master', # the name of the reference to update
  358. author,
  359. committer,
  360. 'Add sources file for testing',
  361. # binary string representing the tree object ID
  362. tree,
  363. # list of binary strings representing parents of the new commit
  364. []
  365. )
  366. first_commit = repo.revparse_single('HEAD')
  367. # Edit the sources file again
  368. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  369. stream.write('foo\n bar\nbaz\n boose')
  370. repo.index.add('sources')
  371. repo.index.write()
  372. # Commits the files added
  373. tree = repo.index.write_tree()
  374. author = pygit2.Signature(
  375. 'Alice Author', 'alice@authors.tld')
  376. committer = pygit2.Signature(
  377. 'Cecil Committer', 'cecil@committers.tld')
  378. repo.create_commit(
  379. 'refs/heads/master', # the name of the reference to update
  380. author,
  381. committer,
  382. 'Add baz and boose to the sources\n\n There are more objects to '
  383. 'consider',
  384. # binary string representing the tree object ID
  385. tree,
  386. # list of binary strings representing parents of the new commit
  387. [first_commit.oid.hex]
  388. )
  389. second_commit = repo.revparse_single('HEAD')
  390. # Create a PR for these changes
  391. tests.create_projects(self.session)
  392. project = pagure.lib.get_project(self.session, 'test')
  393. req = pagure.lib.new_pull_request(
  394. session=self.session,
  395. repo_from=project,
  396. branch_from='master',
  397. repo_to=project,
  398. branch_to='master',
  399. title='PR from the feature branch',
  400. user='pingou',
  401. requestfolder=None,
  402. )
  403. self.session.commit()
  404. self.assertEqual(req.id, 1)
  405. self.assertEqual(req.title, 'PR from the feature branch')
  406. # Check if the PR can be merged
  407. data = {
  408. 'objid': 'blah',
  409. }
  410. # Missing CSRF
  411. output = self.app.post('/pv/pull-request/merge', data=data)
  412. self.assertEqual(output.status_code, 400)
  413. user = tests.FakeUser()
  414. user.username = 'pingou'
  415. with tests.user_set(pagure.APP, user):
  416. output = self.app.get('/test/adduser')
  417. csrf_token = output.data.split(
  418. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  419. # Missing request identifier
  420. data = {
  421. 'csrf_token': csrf_token,
  422. }
  423. output = self.app.post('/pv/pull-request/merge', data=data)
  424. self.assertEqual(output.status_code, 404)
  425. # With all the desired information
  426. project = pagure.lib.get_project(self.session, 'test')
  427. data = {
  428. 'csrf_token': csrf_token,
  429. 'requestid': project.requests[0].uid,
  430. }
  431. output = self.app.post('/pv/pull-request/merge', data=data)
  432. self.assertEqual(output.status_code, 200)
  433. exp = {
  434. "code": "NO_CHANGE",
  435. "message": "Nothing to change, git is up to date",
  436. "short_code": "No changes"
  437. }
  438. js_data = json.loads(output.data)
  439. self.assertDictEqual(js_data, exp)
  440. @patch('pagure.lib.notify.send_email')
  441. def test_mergeable_request_pull_merge(self, send_email):
  442. """ Test the mergeable_request_pull endpoint when the changes can
  443. be merged with a merge commit.
  444. """
  445. send_email.return_value = True
  446. # Create a git repo to play with
  447. gitrepo = os.path.join(self.path, 'test.git')
  448. self.assertFalse(os.path.exists(gitrepo))
  449. os.makedirs(gitrepo)
  450. repo = pygit2.init_repository(gitrepo)
  451. # Create a file in that git repo
  452. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  453. stream.write('foo\n bar')
  454. repo.index.add('sources')
  455. repo.index.write()
  456. # Commits the files added
  457. tree = repo.index.write_tree()
  458. author = pygit2.Signature(
  459. 'Alice Author', 'alice@authors.tld')
  460. committer = pygit2.Signature(
  461. 'Cecil Committer', 'cecil@committers.tld')
  462. repo.create_commit(
  463. 'refs/heads/master', # the name of the reference to update
  464. author,
  465. committer,
  466. 'Add sources file for testing',
  467. # binary string representing the tree object ID
  468. tree,
  469. # list of binary strings representing parents of the new commit
  470. []
  471. )
  472. first_commit = repo.revparse_single('HEAD')
  473. # Edit the sources file again
  474. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  475. stream.write('foo\n bar\nbaz\n boose')
  476. repo.index.add('sources')
  477. repo.index.write()
  478. # Commits the files added
  479. tree = repo.index.write_tree()
  480. author = pygit2.Signature(
  481. 'Alice Author', 'alice@authors.tld')
  482. committer = pygit2.Signature(
  483. 'Cecil Committer', 'cecil@committers.tld')
  484. repo.create_commit(
  485. 'refs/heads/feature', # the name of the reference to update
  486. author,
  487. committer,
  488. 'Add baz and boose to the sources\n\n There are more objects to '
  489. 'consider',
  490. # binary string representing the tree object ID
  491. tree,
  492. # list of binary strings representing parents of the new commit
  493. [first_commit.oid.hex]
  494. )
  495. # Create another file in the master branch
  496. with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream:
  497. stream.write('*~')
  498. repo.index.add('.gitignore')
  499. repo.index.write()
  500. # Commits the files added
  501. tree = repo.index.write_tree()
  502. author = pygit2.Signature(
  503. 'Alice Author', 'alice@authors.tld')
  504. committer = pygit2.Signature(
  505. 'Cecil Committer', 'cecil@committers.tld')
  506. repo.create_commit(
  507. 'refs/heads/master', # the name of the reference to update
  508. author,
  509. committer,
  510. 'Add .gitignore file for testing',
  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. # Create a PR for these changes
  517. tests.create_projects(self.session)
  518. project = pagure.lib.get_project(self.session, 'test')
  519. req = pagure.lib.new_pull_request(
  520. session=self.session,
  521. repo_from=project,
  522. branch_from='feature',
  523. repo_to=project,
  524. branch_to='master',
  525. title='PR from the feature branch',
  526. user='pingou',
  527. requestfolder=None,
  528. )
  529. self.session.commit()
  530. self.assertEqual(req.id, 1)
  531. self.assertEqual(req.title, 'PR from the feature branch')
  532. # Check if the PR can be merged
  533. data = {}
  534. # Missing CSRF
  535. output = self.app.post('/pv/pull-request/merge', data=data)
  536. self.assertEqual(output.status_code, 400)
  537. user = tests.FakeUser()
  538. user.username = 'pingou'
  539. with tests.user_set(pagure.APP, user):
  540. output = self.app.get('/test/adduser')
  541. csrf_token = output.data.split(
  542. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  543. # Missing request identifier
  544. data = {
  545. 'csrf_token': csrf_token,
  546. }
  547. output = self.app.post('/pv/pull-request/merge', data=data)
  548. self.assertEqual(output.status_code, 404)
  549. # With all the desired information
  550. project = pagure.lib.get_project(self.session, 'test')
  551. data = {
  552. 'csrf_token': csrf_token,
  553. 'requestid': project.requests[0].uid,
  554. }
  555. output = self.app.post('/pv/pull-request/merge', data=data)
  556. self.assertEqual(output.status_code, 200)
  557. exp = {
  558. "code": "MERGE",
  559. "message": "The pull-request can be merged with a merge commit",
  560. "short_code": "With merge"
  561. }
  562. js_data = json.loads(output.data)
  563. self.assertDictEqual(js_data, exp)
  564. @patch('pagure.lib.notify.send_email')
  565. def test_mergeable_request_pull_conflicts(self, send_email):
  566. """ Test the mergeable_request_pull endpoint when the changes cannot
  567. be merged due to conflicts.
  568. """
  569. send_email.return_value = True
  570. # Create a git repo to play with
  571. gitrepo = os.path.join(self.path, 'test.git')
  572. self.assertFalse(os.path.exists(gitrepo))
  573. os.makedirs(gitrepo)
  574. repo = pygit2.init_repository(gitrepo)
  575. # Create a file in that git repo
  576. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  577. stream.write('foo\n bar')
  578. repo.index.add('sources')
  579. repo.index.write()
  580. # Commits the files added
  581. tree = repo.index.write_tree()
  582. author = pygit2.Signature(
  583. 'Alice Author', 'alice@authors.tld')
  584. committer = pygit2.Signature(
  585. 'Cecil Committer', 'cecil@committers.tld')
  586. repo.create_commit(
  587. 'refs/heads/master', # the name of the reference to update
  588. author,
  589. committer,
  590. 'Add sources file for testing',
  591. # binary string representing the tree object ID
  592. tree,
  593. # list of binary strings representing parents of the new commit
  594. []
  595. )
  596. first_commit = repo.revparse_single('HEAD')
  597. # Edit the sources file again
  598. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  599. stream.write('foo\n bar\nbaz\n boose')
  600. repo.index.add('sources')
  601. repo.index.write()
  602. # Commits the files added
  603. tree = repo.index.write_tree()
  604. author = pygit2.Signature(
  605. 'Alice Author', 'alice@authors.tld')
  606. committer = pygit2.Signature(
  607. 'Cecil Committer', 'cecil@committers.tld')
  608. repo.create_commit(
  609. 'refs/heads/feature', # the name of the reference to update
  610. author,
  611. committer,
  612. 'Add baz and boose to the sources\n\n There are more objects to '
  613. 'consider',
  614. # binary string representing the tree object ID
  615. tree,
  616. # list of binary strings representing parents of the new commit
  617. [first_commit.oid.hex]
  618. )
  619. # Create another file in the master branch
  620. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  621. stream.write('foo\n bar\nbaz\n')
  622. repo.index.add('sources')
  623. repo.index.write()
  624. # Commits the files added
  625. tree = repo.index.write_tree()
  626. author = pygit2.Signature(
  627. 'Alice Author', 'alice@authors.tld')
  628. committer = pygit2.Signature(
  629. 'Cecil Committer', 'cecil@committers.tld')
  630. repo.create_commit(
  631. 'refs/heads/master', # the name of the reference to update
  632. author,
  633. committer,
  634. 'Add .gitignore file for testing',
  635. # binary string representing the tree object ID
  636. tree,
  637. # list of binary strings representing parents of the new commit
  638. [first_commit.oid.hex]
  639. )
  640. # Create a PR for these changes
  641. tests.create_projects(self.session)
  642. project = pagure.lib.get_project(self.session, 'test')
  643. req = pagure.lib.new_pull_request(
  644. session=self.session,
  645. repo_from=project,
  646. branch_from='feature',
  647. repo_to=project,
  648. branch_to='master',
  649. title='PR from the feature branch',
  650. user='pingou',
  651. requestfolder=None,
  652. )
  653. self.session.commit()
  654. self.assertEqual(req.id, 1)
  655. self.assertEqual(req.title, 'PR from the feature branch')
  656. # Check if the PR can be merged
  657. data = {}
  658. # Missing CSRF
  659. output = self.app.post('/pv/pull-request/merge', data=data)
  660. self.assertEqual(output.status_code, 400)
  661. user = tests.FakeUser()
  662. user.username = 'pingou'
  663. with tests.user_set(pagure.APP, user):
  664. output = self.app.get('/test/adduser')
  665. csrf_token = output.data.split(
  666. 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
  667. # Missing request identifier
  668. data = {
  669. 'csrf_token': csrf_token,
  670. }
  671. output = self.app.post('/pv/pull-request/merge', data=data)
  672. self.assertEqual(output.status_code, 404)
  673. # With all the desired information
  674. project = pagure.lib.get_project(self.session, 'test')
  675. data = {
  676. 'csrf_token': csrf_token,
  677. 'requestid': project.requests[0].uid,
  678. }
  679. output = self.app.post('/pv/pull-request/merge', data=data)
  680. self.assertEqual(output.status_code, 200)
  681. exp = {
  682. "code": "CONFLICTS",
  683. "message": "The pull-request cannot be merged due to conflicts",
  684. "short_code": "Conflicts"
  685. }
  686. js_data = json.loads(output.data)
  687. self.assertDictEqual(js_data, exp)
  688. def test_get_branches_of_commit(self):
  689. ''' Test the get_branches_of_commit from the internal API. '''
  690. tests.create_projects(self.session)
  691. tests.create_projects_git(self.path)
  692. user = tests.FakeUser()
  693. user.username = 'pingou'
  694. with tests.user_set(pagure.APP, user):
  695. output = self.app.get('/test/adduser')
  696. self.assertEqual(output.status_code, 200)
  697. csrf_token = output.data.split(
  698. b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0]
  699. # No CSRF token
  700. data = {
  701. 'repo': 'fakerepo',
  702. 'commit_id': 'foo',
  703. }
  704. output = self.app.post('/pv/branches/commit/', data=data)
  705. self.assertEqual(output.status_code, 400)
  706. js_data = json.loads(output.data.decode('utf-8'))
  707. self.assertDictEqual(
  708. js_data,
  709. {u'code': u'ERROR', u'message': u'Invalid input submitted'}
  710. )
  711. # Invalid repo
  712. data = {
  713. 'repo': 'fakerepo',
  714. 'commit_id': 'foo',
  715. 'csrf_token': csrf_token,
  716. }
  717. output = self.app.post('/pv/branches/commit/', data=data)
  718. self.assertEqual(output.status_code, 404)
  719. js_data = json.loads(output.data.decode('utf-8'))
  720. self.assertDictEqual(
  721. js_data,
  722. {
  723. u'code': u'ERROR',
  724. u'message': u'No repo found with the information provided'
  725. }
  726. )
  727. # Rigth repo, no commit
  728. data = {
  729. 'repo': 'test',
  730. 'csrf_token': csrf_token,
  731. }
  732. output = self.app.post('/pv/branches/commit/', data=data)
  733. self.assertEqual(output.status_code, 400)
  734. js_data = json.loads(output.data.decode('utf-8'))
  735. self.assertDictEqual(
  736. js_data,
  737. {u'code': u'ERROR', u'message': u'No commit id submitted'}
  738. )
  739. # Request is fine, but git repo doesn't exist
  740. item = pagure.lib.model.Project(
  741. user_id=1, # pingou
  742. name='test20',
  743. description='test project #20',
  744. hook_token='aaabbbhhh',
  745. )
  746. self.session.add(item)
  747. self.session.commit()
  748. data = {
  749. 'repo': 'test20',
  750. 'commit_id': 'foo',
  751. 'csrf_token': csrf_token,
  752. }
  753. output = self.app.post('/pv/branches/commit/', data=data)
  754. self.assertEqual(output.status_code, 404)
  755. js_data = json.loads(output.data.decode('utf-8'))
  756. self.assertDictEqual(
  757. js_data,
  758. {
  759. u'code': u'ERROR',
  760. u'message': u'No git repo found with the information provided'
  761. }
  762. )
  763. # Create a git repo to play with
  764. gitrepo = os.path.join(self.path, 'test.git')
  765. self.assertTrue(os.path.exists(gitrepo))
  766. repo = pygit2.Repository(gitrepo)
  767. # Create a file in that git repo
  768. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  769. stream.write('foo\n bar')
  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 sources 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. []
  787. )
  788. first_commit = repo.revparse_single('HEAD')
  789. # Edit the sources file again
  790. with open(os.path.join(gitrepo, 'sources'), 'w') as stream:
  791. stream.write('foo\n bar\nbaz\n boose')
  792. repo.index.add('sources')
  793. repo.index.write()
  794. # Commits the files added
  795. tree = repo.index.write_tree()
  796. author = pygit2.Signature(
  797. 'Alice Author', 'alice@authors.tld')
  798. committer = pygit2.Signature(
  799. 'Cecil Committer', 'cecil@committers.tld')
  800. repo.create_commit(
  801. 'refs/heads/feature', # the name of the reference to update
  802. author,
  803. committer,
  804. 'Add baz and boose to the sources\n\n There are more objects to '
  805. 'consider',
  806. # binary string representing the tree object ID
  807. tree,
  808. # list of binary strings representing parents of the new commit
  809. [first_commit.oid.hex]
  810. )
  811. # Create another file in the master branch
  812. with open(os.path.join(gitrepo, '.gitignore'), 'w') as stream:
  813. stream.write('*~')
  814. repo.index.add('.gitignore')
  815. repo.index.write()
  816. # Commits the files added
  817. tree = repo.index.write_tree()
  818. author = pygit2.Signature(
  819. 'Alice Author', 'alice@authors.tld')
  820. committer = pygit2.Signature(
  821. 'Cecil Committer', 'cecil@committers.tld')
  822. commit_hash = repo.create_commit(
  823. 'refs/heads/feature_branch', # the name of the reference to update
  824. author,
  825. committer,
  826. 'Add .gitignore file for testing',
  827. # binary string representing the tree object ID
  828. tree,
  829. # list of binary strings representing parents of the new commit
  830. [first_commit.oid.hex]
  831. )
  832. # All good but the commit id
  833. data = {
  834. 'repo': 'test',
  835. 'commit_id': 'foo',
  836. 'csrf_token': csrf_token,
  837. }
  838. output = self.app.post('/pv/branches/commit/', data=data)
  839. self.assertEqual(output.status_code, 404)
  840. js_data = json.loads(output.data.decode('utf-8'))
  841. self.assertDictEqual(
  842. js_data,
  843. {
  844. u'code': u'ERROR',
  845. u'message': 'This commit could not be found in this repo'
  846. }
  847. )
  848. # All good
  849. data = {
  850. 'repo': 'test',
  851. 'commit_id': commit_hash,
  852. 'csrf_token': csrf_token,
  853. }
  854. output = self.app.post('/pv/branches/commit/', data=data)
  855. self.assertEqual(output.status_code, 200)
  856. js_data = json.loads(output.data.decode('utf-8'))
  857. self.assertDictEqual(
  858. js_data,
  859. {
  860. u'code': u'OK',
  861. u'branches': ['feature_branch'],
  862. }
  863. )
  864. if __name__ == '__main__':
  865. SUITE = unittest.TestLoader().loadTestsFromTestCase(
  866. PagureFlaskInternaltests)
  867. unittest.TextTestRunner(verbosity=2).run(SUITE)