test_pagure_flask_ui_remote_pr.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. # -*- coding: utf-8 -*-
  2. """
  3. (c) 2018 - Copyright Red Hat Inc
  4. Authors:
  5. Pierre-Yves Chibon <pingou@pingoured.fr>
  6. """
  7. __requires__ = ['SQLAlchemy >= 0.8']
  8. import pkg_resources
  9. import json
  10. import unittest
  11. import shutil
  12. import sys
  13. import tempfile
  14. import time
  15. import os
  16. import pygit2
  17. from mock import patch, MagicMock
  18. from bs4 import BeautifulSoup
  19. sys.path.insert(0, os.path.join(os.path.dirname(
  20. os.path.abspath(__file__)), '..'))
  21. import pagure
  22. import pagure.lib
  23. import tests
  24. from pagure.lib.repo import PagureRepo
  25. class PagureRemotePRtests(tests.Modeltests):
  26. """ Tests for remote PRs in pagure """
  27. def setUp(self):
  28. """ Set up the environment. """
  29. super(PagureRemotePRtests, self).setUp()
  30. self.newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
  31. self.old_value = pagure.config.config['REMOTE_GIT_FOLDER']
  32. pagure.config.config['REMOTE_GIT_FOLDER'] = os.path.join(
  33. self.path, 'remotes')
  34. def tearDown(self):
  35. """ Clear things up. """
  36. super(PagureRemotePRtests, self).tearDown()
  37. pagure.config.config['REMOTE_GIT_FOLDER'] = self.old_value
  38. shutil.rmtree(self.newpath)
  39. def set_up_git_repo(self, new_project=None, branch_from='feature'):
  40. """ Set up the git repo and create the corresponding PullRequest
  41. object.
  42. """
  43. # Create a git repo to play with
  44. gitrepo = os.path.join(self.path, 'repos', 'test.git')
  45. repo = pygit2.init_repository(gitrepo, bare=True)
  46. repopath = os.path.join(self.newpath, 'test')
  47. clone_repo = pygit2.clone_repository(gitrepo, repopath)
  48. # Create a file in that git repo
  49. with open(os.path.join(repopath, 'sources'), 'w') as stream:
  50. stream.write('foo\n bar')
  51. clone_repo.index.add('sources')
  52. clone_repo.index.write()
  53. try:
  54. com = repo.revparse_single('HEAD')
  55. prev_commit = [com.oid.hex]
  56. except:
  57. prev_commit = []
  58. # Commits the files added
  59. tree = clone_repo.index.write_tree()
  60. author = pygit2.Signature(
  61. 'Alice Author', 'alice@authors.tld')
  62. committer = pygit2.Signature(
  63. 'Cecil Committer', 'cecil@committers.tld')
  64. clone_repo.create_commit(
  65. 'refs/heads/master', # the name of the reference to update
  66. author,
  67. committer,
  68. 'Add sources file for testing',
  69. # binary string representing the tree object ID
  70. tree,
  71. # list of binary strings representing parents of the new commit
  72. prev_commit
  73. )
  74. time.sleep(1)
  75. refname = 'refs/heads/master:refs/heads/master'
  76. ori_remote = clone_repo.remotes[0]
  77. PagureRepo.push(ori_remote, refname)
  78. first_commit = repo.revparse_single('HEAD')
  79. with open(os.path.join(repopath, '.gitignore'), 'w') as stream:
  80. stream.write('*~')
  81. clone_repo.index.add('.gitignore')
  82. clone_repo.index.write()
  83. # Commits the files added
  84. tree = clone_repo.index.write_tree()
  85. author = pygit2.Signature(
  86. 'Alice Äuthòr', 'alice@äuthòrs.tld')
  87. committer = pygit2.Signature(
  88. 'Cecil Cõmmîttër', 'cecil@cõmmîttërs.tld')
  89. clone_repo.create_commit(
  90. 'refs/heads/master',
  91. author,
  92. committer,
  93. 'Add .gitignore file for testing',
  94. # binary string representing the tree object ID
  95. tree,
  96. # list of binary strings representing parents of the new commit
  97. [first_commit.oid.hex]
  98. )
  99. refname = 'refs/heads/master:refs/heads/master'
  100. ori_remote = clone_repo.remotes[0]
  101. PagureRepo.push(ori_remote, refname)
  102. # Set the second repo
  103. new_gitrepo = repopath
  104. if new_project:
  105. # Create a new git repo to play with
  106. new_gitrepo = os.path.join(self.newpath, new_project.fullname)
  107. if not os.path.exists(new_gitrepo):
  108. os.makedirs(new_gitrepo)
  109. new_repo = pygit2.clone_repository(gitrepo, new_gitrepo)
  110. repo = pygit2.Repository(new_gitrepo)
  111. # Edit the sources file again
  112. with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream:
  113. stream.write('foo\n bar\nbaz\n boose')
  114. repo.index.add('sources')
  115. repo.index.write()
  116. # Commits the files added
  117. tree = repo.index.write_tree()
  118. author = pygit2.Signature(
  119. 'Alice Author', 'alice@authors.tld')
  120. committer = pygit2.Signature(
  121. 'Cecil Committer', 'cecil@committers.tld')
  122. repo.create_commit(
  123. 'refs/heads/%s' % branch_from,
  124. author,
  125. committer,
  126. 'A commit on branch %s' % branch_from,
  127. tree,
  128. [first_commit.oid.hex]
  129. )
  130. refname = 'refs/heads/%s' % (branch_from)
  131. ori_remote = repo.remotes[0]
  132. PagureRepo.push(ori_remote, refname)
  133. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  134. def test_new_remote_pr_unauth(self):
  135. """ Test creating a new remote PR un-authenticated. """
  136. tests.create_projects(self.session)
  137. tests.create_projects_git(
  138. os.path.join(self.path, 'requests'), bare=True)
  139. self.set_up_git_repo()
  140. # Before
  141. project = pagure.lib.get_authorized_project(self.session, 'test')
  142. self.assertEqual(len(project.requests), 0)
  143. # Try creating a remote PR
  144. output = self.app.get('/test/diff/remote')
  145. self.assertEqual(output.status_code, 302)
  146. self.assertIn(
  147. u'You should be redirected automatically to target URL: '
  148. u'<a href="/login/?', output.data)
  149. @patch('pagure.lib.notify.send_email', MagicMock(return_value=True))
  150. def test_new_remote_pr_auth(self):
  151. """ Test creating a new remote PR un-authenticated. """
  152. tests.create_projects(self.session)
  153. tests.create_projects_git(
  154. os.path.join(self.path, 'requests'), bare=True)
  155. self.set_up_git_repo()
  156. # Before
  157. self.session = pagure.lib.create_session(self.dbpath)
  158. project = pagure.lib.get_authorized_project(self.session, 'test')
  159. self.assertEqual(len(project.requests), 0)
  160. # Try creating a remote PR
  161. user = tests.FakeUser(username='foo')
  162. with tests.user_set(self.app.application, user):
  163. output = self.app.get('/test/diff/remote')
  164. self.assertEqual(output.status_code, 200)
  165. self.assertIn(u'<h2>New remote pull-request</h2>', output.data)
  166. csrf_token = self.get_csrf(output=output)
  167. data = {
  168. 'csrf_token': csrf_token,
  169. 'title': 'Remote PR title',
  170. 'branch_from': 'feature',
  171. 'branch_to': 'master',
  172. 'git_repo': os.path.join(self.newpath, 'test'),
  173. }
  174. output = self.app.post('/test/diff/remote', data=data)
  175. self.assertEqual(output.status_code, 200)
  176. self.assertIn(u'<h2>Create pull request</h2>', output.data)
  177. self.assertIn(
  178. u'<div class="card clearfix" id="_1">', output.data)
  179. self.assertNotIn(
  180. u'<div class="card clearfix" id="_2">', output.data)
  181. # Not saved yet
  182. self.session = pagure.lib.create_session(self.dbpath)
  183. project = pagure.lib.get_authorized_project(self.session, 'test')
  184. self.assertEqual(len(project.requests), 0)
  185. data = {
  186. 'csrf_token': csrf_token,
  187. 'title': 'Remote PR title',
  188. 'branch_from': 'feature',
  189. 'branch_to': 'master',
  190. 'git_repo': os.path.join(self.newpath, 'test'),
  191. 'confirm': 1,
  192. }
  193. output = self.app.post(
  194. '/test/diff/remote', data=data, follow_redirects=True)
  195. self.assertEqual(output.status_code, 200)
  196. self.assertIn(
  197. u'<h3><span class="label label-default">PR#1</span>',
  198. output.data)
  199. self.assertIn(
  200. u'<div class="card clearfix" id="_1">', output.data)
  201. self.assertNotIn(
  202. u'<div class="card clearfix" id="_2">', output.data)
  203. # Show the filename in the diff view
  204. self.assertIn(
  205. u'''<div class="clearfix">
  206. .gitignore
  207. <div><small>
  208. this is a remote pull-request, so we cannot provide you''',
  209. output.data)
  210. self.assertIn(
  211. u'''<div class="clearfix">
  212. sources
  213. <div><small>
  214. this is a remote pull-request, so we cannot provide you''',
  215. output.data)
  216. # Show the filename in the Changes summary
  217. self.assertIn(
  218. u'<a href="#_1">.gitignore</a>', output.data)
  219. self.assertIn(
  220. u'<a href="#_1">sources</a>', output.data)
  221. # Remote PR Created
  222. self.session = pagure.lib.create_session(self.dbpath)
  223. project = pagure.lib.get_authorized_project(self.session, 'test')
  224. self.assertEqual(len(project.requests), 1)
  225. if __name__ == '__main__':
  226. unittest.main(verbosity=2)