Blame tests/test_progit_flask_ui_fork.py

Pierre-Yves Chibon 9347b5
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
"""
Pierre-Yves Chibon 9347b5
 (c) 2015 - Copyright Red Hat Inc
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
 Authors:
Pierre-Yves Chibon 9347b5
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
"""
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
__requires__ = ['SQLAlchemy >= 0.8']
Pierre-Yves Chibon 9347b5
import pkg_resources
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
import json
Pierre-Yves Chibon 9347b5
import unittest
Pierre-Yves Chibon 9347b5
import shutil
Pierre-Yves Chibon 9347b5
import sys
Pierre-Yves Chibon 9347b5
import tempfile
Pierre-Yves Chibon 9347b5
import os
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
import pygit2
Pierre-Yves Chibon 9347b5
from mock import patch
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
sys.path.insert(0, os.path.join(os.path.dirname(
Pierre-Yves Chibon 9347b5
    os.path.abspath(__file__)), '..'))
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
import pagure.lib
Pierre-Yves Chibon 9347b5
import tests
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
class PagureFlaskForktests(tests.Modeltests):
Pierre-Yves Chibon 9347b5
    """ Tests for flask fork controller of pagure """
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
    def setUp(self):
Pierre-Yves Chibon 9347b5
        """ Set up the environnment, ran before every tests. """
Pierre-Yves Chibon 9347b5
        super(PagureFlaskForktests, self).setUp()
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        pagure.APP.config['TESTING'] = True
Pierre-Yves Chibon 9347b5
        pagure.SESSION = self.session
Pierre-Yves Chibon 9347b5
        pagure.ui.SESSION = self.session
Pierre-Yves Chibon 9347b5
        pagure.ui.app.SESSION = self.session
Pierre-Yves Chibon 9347b5
        pagure.ui.fork.SESSION = self.session
Pierre-Yves Chibon 9347b5
        pagure.ui.repo.SESSION = self.session
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon ae1f3a
        pagure.APP.config['GIT_FOLDER'] = os.path.join(tests.HERE, 'repos')
Pierre-Yves Chibon ae1f3a
        pagure.APP.config['FORK_FOLDER'] = os.path.join(tests.HERE, 'forks')
Pierre-Yves Chibon 9347b5
        pagure.APP.config['TICKETS_FOLDER'] = os.path.join(
Pierre-Yves Chibon 9347b5
            tests.HERE, 'tickets')
Pierre-Yves Chibon 9347b5
        pagure.APP.config['DOCS_FOLDER'] = os.path.join(
Pierre-Yves Chibon 9347b5
            tests.HERE, 'docs')
Pierre-Yves Chibon 9347b5
        pagure.APP.config['REQUESTS_FOLDER'] = os.path.join(
Pierre-Yves Chibon 9347b5
            tests.HERE, 'requests')
Pierre-Yves Chibon 9347b5
        self.app = pagure.APP.test_client()
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
    def set_up_git_repo(self, new_project=None, branch_from='feature'):
Pierre-Yves Chibon 9347b5
        """ Set up the git repo and create the corresponding PullRequest
Pierre-Yves Chibon 9347b5
        object.
Pierre-Yves Chibon 9347b5
        """
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Create a git repo to play with
Pierre-Yves Chibon ae1f3a
        gitrepo = os.path.join(tests.HERE, 'repos', 'test.git')
Pierre-Yves Chibon 9347b5
        self.assertFalse(os.path.exists(gitrepo))
Pierre-Yves Chibon 9347b5
        os.makedirs(gitrepo)
Pierre-Yves Chibon 9347b5
        repo = pygit2.init_repository(gitrepo, bare=True)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        newpath = tempfile.mkdtemp(prefix='pagure-fork-test')
Pierre-Yves Chibon 9347b5
        clone_repo = pygit2.clone_repository(gitrepo, newpath)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Create a file in that git repo
Pierre-Yves Chibon 9347b5
        with open(os.path.join(newpath, 'sources'), 'w') as stream:
Pierre-Yves Chibon 9347b5
            stream.write('foo\n bar')
Pierre-Yves Chibon 9347b5
        clone_repo.index.add('sources')
Pierre-Yves Chibon 9347b5
        clone_repo.index.write()
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Commits the files added
Pierre-Yves Chibon 9347b5
        tree = clone_repo.index.write_tree()
Pierre-Yves Chibon 9347b5
        author = pygit2.Signature(
Pierre-Yves Chibon 9347b5
            'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon 9347b5
        committer = pygit2.Signature(
Pierre-Yves Chibon 9347b5
            'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon 9347b5
        clone_repo.create_commit(
Pierre-Yves Chibon 9347b5
            'refs/heads/master',  # the name of the reference to update
Pierre-Yves Chibon 9347b5
            author,
Pierre-Yves Chibon 9347b5
            committer,
Pierre-Yves Chibon 9347b5
            'Add sources file for testing',
Pierre-Yves Chibon 9347b5
            # binary string representing the tree object ID
Pierre-Yves Chibon 9347b5
            tree,
Pierre-Yves Chibon 9347b5
            # list of binary strings representing parents of the new commit
Pierre-Yves Chibon 9347b5
            []
Pierre-Yves Chibon 9347b5
        )
Pierre-Yves Chibon 9347b5
        refname = 'refs/heads/master:refs/heads/master'
Pierre-Yves Chibon 9347b5
        ori_remote = clone_repo.remotes[0]
Pierre-Yves Chibon 9347b5
        ori_remote.push(refname)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        first_commit = repo.revparse_single('HEAD')
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Set the second repo
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        new_gitrepo = newpath
Pierre-Yves Chibon 9347b5
        if new_project:
Pierre-Yves Chibon 9347b5
            # Create a new git repo to play with
Pierre-Yves Chibon 9347b5
            new_gitrepo = new_project.path
Pierre-Yves Chibon 9347b5
            if not os.path.exists(new_gitrepo):
Pierre-Yves Chibon 9347b5
                os.makedirs(new_gitrepo)
Pierre-Yves Chibon 9347b5
                new_repo = pygit2.clone_repository(gitrepo, new_gitrepo)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        repo = pygit2.Repository(new_gitrepo)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Edit the sources file again
Pierre-Yves Chibon 9347b5
        with open(os.path.join(new_gitrepo, 'sources'), 'w') as stream:
Pierre-Yves Chibon 9347b5
            stream.write('foo\n bar\nbaz\n boose')
Pierre-Yves Chibon 9347b5
        repo.index.add('sources')
Pierre-Yves Chibon 9347b5
        repo.index.write()
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Commits the files added
Pierre-Yves Chibon 9347b5
        tree = repo.index.write_tree()
Pierre-Yves Chibon 9347b5
        author = pygit2.Signature(
Pierre-Yves Chibon 9347b5
            'Alice Author', 'alice@authors.tld')
Pierre-Yves Chibon 9347b5
        committer = pygit2.Signature(
Pierre-Yves Chibon 9347b5
            'Cecil Committer', 'cecil@committers.tld')
Pierre-Yves Chibon 9347b5
        repo.create_commit(
Pierre-Yves Chibon 9347b5
            'refs/heads/%s' % branch_from,
Pierre-Yves Chibon 9347b5
            author,
Pierre-Yves Chibon 9347b5
            committer,
Pierre-Yves Chibon 9347b5
            'A commit on branch %s' % branch_from,
Pierre-Yves Chibon 9347b5
            tree,
Pierre-Yves Chibon 9347b5
            [first_commit.oid.hex]
Pierre-Yves Chibon 9347b5
        )
Pierre-Yves Chibon 9347b5
        refname = 'refs/heads/%s:refs/heads/%s' % (branch_from, branch_from)
Pierre-Yves Chibon 9347b5
        ori_remote = clone_repo.remotes[0]
Pierre-Yves Chibon 9347b5
        ori_remote.push(refname)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        second_commit = repo.revparse_single('HEAD')
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Create a PR for these changes
Pierre-Yves Chibon 9347b5
        project = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 9347b5
        msg = pagure.lib.new_pull_request(
Pierre-Yves Chibon 9347b5
            session=self.session,
Pierre-Yves Chibon 9347b5
            repo_from=project,
Pierre-Yves Chibon 9347b5
            branch_from=branch_from,
Pierre-Yves Chibon 9347b5
            repo_to=project,
Pierre-Yves Chibon 9347b5
            branch_to='master',
Pierre-Yves Chibon 9347b5
            title='PR from the %s branch' % branch_from,
Pierre-Yves Chibon 9347b5
            user='pingou',
Pierre-Yves Chibon 9347b5
            requestfolder=None,
Pierre-Yves Chibon 9347b5
        )
Pierre-Yves Chibon 9347b5
        self.session.commit()
Pierre-Yves Chibon 9347b5
        self.assertEqual(msg, 'Request created')
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
    @patch('pagure.lib.notify.send_email')
Pierre-Yves Chibon 9347b5
    def test_request_pull(self, send_email):
Pierre-Yves Chibon 9347b5
        """ Test the request_pull endpoint. """
Pierre-Yves Chibon 9347b5
        send_email.return_value = True
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        tests.create_projects(self.session)
Pierre-Yves Chibon 9347b5
        tests.create_projects_git(
Pierre-Yves Chibon 9347b5
            os.path.join(tests.HERE, 'requests'), bare=True)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Non-existant project
Pierre-Yves Chibon 9347b5
        output = self.app.get('/foobar/pull-request/1')
Pierre-Yves Chibon 9347b5
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # Project has no PR
Pierre-Yves Chibon 9347b5
        output = self.app.get('/test/pull-request/1')
Pierre-Yves Chibon 9347b5
        self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        self.set_up_git_repo(new_project=None, branch_from='feature')
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        project = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 9347b5
        self.assertEqual(len(project.requests), 1)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 9347b5
        # View the pull-request
Pierre-Yves Chibon 9347b5
        output = self.app.get('/test/pull-request/1')
Pierre-Yves Chibon 9347b5
        self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 9347b5
        self.assertIn(
Pierre-Yves Chibon 9347b5
            '<title>Pull request #1 - test - Pagure</title>', output.data)
Pierre-Yves Chibon 9347b5
        self.assertIn(
Pierre-Yves Chibon 9347b5
            'title="View file as of 2a552b">View', output.data)
Pierre-Yves Chibon 9347b5
Pierre-Yves Chibon 502b7a
    @patch('pagure.lib.notify.send_email')
Pierre-Yves Chibon 502b7a
    def test_merge_request_pull_FF(self, send_email):
Pierre-Yves Chibon 502b7a
        """ Test the merge_request_pull endpoint. """
Pierre-Yves Chibon 502b7a
        send_email.return_value = True
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
        self.test_request_pull()
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
        user = tests.FakeUser()
Pierre-Yves Chibon 502b7a
        with tests.user_set(pagure.APP, user):
Pierre-Yves Chibon 502b7a
            output = self.app.get('/test/pull-request/1')
Pierre-Yves Chibon 502b7a
            self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            csrf_token = output.data.split(
Pierre-Yves Chibon 502b7a
                'name="csrf_token" type="hidden" value="')[1].split('">')[0]
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            # No CSRF
Pierre-Yves Chibon 502b7a
            output = self.app.post(
Pierre-Yves Chibon 502b7a
                '/test/pull-request/1/merge', data={}, follow_redirects=True)
Pierre-Yves Chibon 502b7a
            self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 502b7a
            self.assertIn(
Pierre-Yves Chibon 502b7a
                '<title>Pull request #1 - test - Pagure</title>', output.data)
Pierre-Yves Chibon 502b7a
            self.assertIn(
Pierre-Yves Chibon 502b7a
                'title="View file as of 2a552b">View', output.data)
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            # Wrong project
Pierre-Yves Chibon 502b7a
            data = {
Pierre-Yves Chibon 502b7a
                'csrf_token': csrf_token,
Pierre-Yves Chibon 502b7a
            }
Pierre-Yves Chibon 502b7a
            output = self.app.post(
Pierre-Yves Chibon 502b7a
                '/foobar/pull-request/100/merge', data=data, follow_redirects=True)
Pierre-Yves Chibon 502b7a
            self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            # Wrong project
Pierre-Yves Chibon 502b7a
            data = {
Pierre-Yves Chibon 502b7a
                'csrf_token': csrf_token,
Pierre-Yves Chibon 502b7a
            }
Pierre-Yves Chibon 502b7a
            output = self.app.post(
Pierre-Yves Chibon 502b7a
                '/test/pull-request/1/merge', data=data, follow_redirects=True)
Pierre-Yves Chibon 502b7a
            self.assertEqual(output.status_code, 403)
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
        user.username = 'pingou'
Pierre-Yves Chibon 502b7a
        with tests.user_set(pagure.APP, user):
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            # Wrong request id
Pierre-Yves Chibon 502b7a
            data = {
Pierre-Yves Chibon 502b7a
                'csrf_token': csrf_token,
Pierre-Yves Chibon 502b7a
            }
Pierre-Yves Chibon 502b7a
            output = self.app.post(
Pierre-Yves Chibon 502b7a
                '/test/pull-request/100/merge', data=data, follow_redirects=True)
Pierre-Yves Chibon 502b7a
            self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            # Project w/o pull-request
Pierre-Yves Chibon 502b7a
            repo = pagure.lib.get_project(self.session, 'test')
Pierre-Yves Chibon 502b7a
            settings = repo.settings
Pierre-Yves Chibon 502b7a
            settings['pull_requests'] = False
Pierre-Yves Chibon 502b7a
            repo.settings = settings
Pierre-Yves Chibon 502b7a
            self.session.add(repo)
Pierre-Yves Chibon 502b7a
            self.session.commit()
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            # Pull-request disabled
Pierre-Yves Chibon 502b7a
            output = self.app.post(
Pierre-Yves Chibon 502b7a
                '/test/pull-request/1/merge', data=data, follow_redirects=True)
Pierre-Yves Chibon 502b7a
            self.assertEqual(output.status_code, 404)
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            # Project w pull-request but only assignee can merge
Pierre-Yves Chibon 502b7a
            settings['pull_requests'] = True
Pierre-Yves Chibon 502b7a
            settings['Only_assignee_can_merge_pull-request'] = True
Pierre-Yves Chibon 502b7a
            repo.settings = settings
Pierre-Yves Chibon 502b7a
            self.session.add(repo)
Pierre-Yves Chibon 502b7a
            self.session.commit()
Pierre-Yves Chibon 502b7a
Pierre-Yves Chibon 502b7a
            output = self.app.post(
Pierre-Yves Chibon 502b7a
                '/test/pull-request/1/merge', data=data, follow_redirects=True)
Pierre-Yves Chibon 502b7a
            self.assertEqual(output.status_code, 200)
Pierre-Yves Chibon 502b7a
            self.assertIn(
Pierre-Yves Chibon 502b7a
                '<title>Pull request #1 - test - Pagure</title>',
Pierre-Yves Chibon 502b7a
                output.data)
Pierre-Yves Chibon 502b7a
            self.assertIn(
Pierre-Yves Chibon 502b7a
                '
  • This request must be assigned to be merged
  • ',
    Pierre-Yves Chibon 502b7a
                    output.data)
    Pierre-Yves Chibon 502b7a
    Pierre-Yves Chibon 502b7a
                # PR assigned but not to this user
    Pierre-Yves Chibon 502b7a
                repo = pagure.lib.get_project(self.session, 'test')
    Pierre-Yves Chibon 502b7a
                req = repo.requests[0]
    Pierre-Yves Chibon 502b7a
                req.assignee_id = 2
    Pierre-Yves Chibon 502b7a
                self.session.add(req)
    Pierre-Yves Chibon 502b7a
                self.session.commit()
    Pierre-Yves Chibon 502b7a
    Pierre-Yves Chibon 502b7a
                output = self.app.post(
    Pierre-Yves Chibon 502b7a
                    '/test/pull-request/1/merge', data=data, follow_redirects=True)
    Pierre-Yves Chibon 502b7a
                self.assertEqual(output.status_code, 200)
    Pierre-Yves Chibon 502b7a
                self.assertIn(
    Pierre-Yves Chibon 502b7a
                    '<title>Pull request #1 - test - Pagure</title>',
    Pierre-Yves Chibon 502b7a
                    output.data)
    Pierre-Yves Chibon 502b7a
                self.assertIn(
    Pierre-Yves Chibon 502b7a
                    '
  • Only the assignee can merge this review
  • ',
    Pierre-Yves Chibon 502b7a
                    output.data)
    Pierre-Yves Chibon 502b7a
    Pierre-Yves Chibon 502b7a
                # Project w/ minimal PR score
    Pierre-Yves Chibon 502b7a
                settings['Only_assignee_can_merge_pull-request'] = False
    Pierre-Yves Chibon 502b7a
                settings['Minimum_score_to_merge_pull-request'] = 2
    Pierre-Yves Chibon 502b7a
                repo.settings = settings
    Pierre-Yves Chibon 502b7a
                self.session.add(repo)
    Pierre-Yves Chibon 502b7a
                self.session.commit()
    Pierre-Yves Chibon 502b7a
    Pierre-Yves Chibon 502b7a
                output = self.app.post(
    Pierre-Yves Chibon 502b7a
                    '/test/pull-request/1/merge', data=data, follow_redirects=True)
    Pierre-Yves Chibon 502b7a
                self.assertEqual(output.status_code, 200)
    Pierre-Yves Chibon 502b7a
                self.assertIn(
    Pierre-Yves Chibon 502b7a
                    '<title>Pull request #1 - test - Pagure</title>',
    Pierre-Yves Chibon 502b7a
                    output.data)
    Pierre-Yves Chibon 502b7a
                self.assertIn(
    Pierre-Yves Chibon 502b7a
                    '
  • This request does not have the minimum '
  • Pierre-Yves Chibon 502b7a
                    'review score necessary to be merged', output.data)
    Pierre-Yves Chibon 502b7a
    Pierre-Yves Chibon 502b7a
                # Merge
    Pierre-Yves Chibon 502b7a
                settings['Minimum_score_to_merge_pull-request'] = -1
    Pierre-Yves Chibon 502b7a
                repo.settings = settings
    Pierre-Yves Chibon 502b7a
                self.session.add(repo)
    Pierre-Yves Chibon 502b7a
                self.session.commit()
    Pierre-Yves Chibon 502b7a
                output = self.app.post(
    Pierre-Yves Chibon 502b7a
                    '/test/pull-request/1/merge', data=data, follow_redirects=True)
    Pierre-Yves Chibon 502b7a
                self.assertEqual(output.status_code, 200)
    Pierre-Yves Chibon 502b7a
                self.assertIn(
    Pierre-Yves Chibon 502b7a
                    '<title>Overview - test - Pagure</title>', output.data)
    Pierre-Yves Chibon 502b7a
                self.assertIn(
    Pierre-Yves Chibon 502b7a
                    '
  • Changes merged!
  • ', output.data)
    Pierre-Yves Chibon 502b7a
    Pierre-Yves Chibon 9347b5
    Pierre-Yves Chibon 9347b5
    if __name__ == '__main__':
    Pierre-Yves Chibon 9347b5
        SUITE = unittest.TestLoader().loadTestsFromTestCase(PagureFlaskForktests)
    Pierre-Yves Chibon 9347b5
        unittest.TextTestRunner(verbosity=2).run(SUITE)