# -*- coding: utf-8 -*- """ (c) 2018 - Copyright Red Hat Inc Authors: Pierre-Yves Chibon """ from __future__ import unicode_literals, absolute_import import datetime import unittest import shutil import sys import os import json import pagure_messages import pygit2 from fedora_messaging import api, testing from mock import ANY, patch, MagicMock sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") ) import pagure.lib.query import pagure.lib.tasks import tests class PagureRebaseBasetests(tests.Modeltests): """Tests rebasing pull-request in pagure""" maxDiff = None config_values = {"authbackend": "pagure"} @patch("pagure.lib.notify.send_email", MagicMock(return_value=True)) def setUp(self): """Set up the environnment, ran before every tests.""" super(PagureRebaseBasetests, self).setUp() pagure.config.config["REQUESTS_FOLDER"] = None tests.create_projects(self.session) tests.create_projects_git(os.path.join(self.path, "repos"), bare=True) tests.create_projects_git( os.path.join(self.path, "requests"), bare=True ) tests.add_content_to_git( os.path.join(self.path, "repos", "test.git"), branch="master", content="foobarbaz", filename="testfile", ) project = pagure.lib.query.get_authorized_project(self.session, "test") # Fork the project task = pagure.lib.query.fork_project( session=self.session, user="foo", repo=project ) self.session.commit() self.assertEqual( task.get(), { "endpoint": "ui_ns.view_repo", "repo": "test", "username": "foo", "namespace": None, }, ) tests.add_content_to_git( os.path.join(self.path, "repos", "forks", "foo", "test.git"), branch="test", content="foobar", filename="sources", ) fork_repo = pagure.lib.query.get_authorized_project( self.session, "test", user="foo" ) tests.add_readme_git_repo(os.path.join(self.path, "repos", "test.git")) # Create a PR for these changes req = pagure.lib.query.new_pull_request( session=self.session, repo_from=fork_repo, branch_from="test", repo_to=project, branch_to="master", title="PR from the test branch", user="foo", allow_rebase=True, ) self.session.commit() self.assertEqual(req.id, 1) self.assertEqual(req.title, "PR from the test branch") self.project = pagure.lib.query.get_authorized_project( self.session, "test" ) self.assertEqual(len(project.requests), 1) self.request = self.project.requests[0] class PagureRebasetests(PagureRebaseBasetests): """Tests rebasing pull-request in pagure""" def test_merge_status_merge(self): """Test that the PR can be merged with a merge commit.""" user = tests.FakeUser(username="pingou") with tests.user_set(self.app.application, user): data = { "requestid": self.request.uid, "csrf_token": self.get_csrf(), } output = self.app.post("/pv/pull-request/merge", data=data) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.assertEqual( data, { "code": "MERGE", "message": "The pull-request can be merged with a " "merge commit", "short_code": "With merge", }, ) def test_merge_status_needsrebase(self): """Test that the PR is marked as needing a rebase if the project disables non-fast-forward merges.""" self.project = pagure.lib.query.get_authorized_project( self.session, "test" ) settings = self.project.settings settings["disable_non_fast-forward_merges"] = True self.project.settings = settings self.session.add(self.project) self.session.commit() user = tests.FakeUser(username="pingou") with tests.user_set(self.app.application, user): data = { "requestid": self.request.uid, "csrf_token": self.get_csrf(), } output = self.app.post("/pv/pull-request/merge", data=data) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.assertEqual( data, { "code": "NEEDSREBASE", "message": "The pull-request must be rebased before " "merging", "short_code": "Needs rebase", }, ) def test_rebase_task(self): """Test the rebase PR task and its outcome.""" pagure.lib.tasks.rebase_pull_request( "test", namespace=None, user=None, requestid=self.request.id, user_rebaser="pingou", ) user = tests.FakeUser(username="pingou") with tests.user_set(self.app.application, user): data = { "requestid": self.request.uid, "csrf_token": self.get_csrf(), } output = self.app.post("/pv/pull-request/merge", data=data) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.assertEqual( data, { "code": "FFORWARD", "message": "The pull-request can be merged and " "fast-forwarded", "short_code": "Ok", }, ) def test_rebase_api_ui_logged_in_different_user(self): """Test the rebase PR API endpoint when logged in from the UI and its outcome.""" # Add 'bar' to the project 'test' so 'bar' can rebase the PR item = pagure.lib.model.User( user="bar", fullname="bar foo", password=b"foo", default_email="bar@foo.com", ) self.session.add(item) item = pagure.lib.model.UserEmail(user_id=2, email="bar@foo.com") self.session.add(item) self.session.commit() repo = pagure.lib.query._get_project(self.session, "test") msg = pagure.lib.query.add_user_to_project( session=self.session, project=repo, new_user="bar", user="pingou" ) self.session.commit() self.assertEqual(msg, "User added") user = tests.FakeUser(username="bar") with tests.user_set(self.app.application, user): # Get the merge status first so it's cached and can be refreshed csrf_token = self.get_csrf() data = {"requestid": self.request.uid, "csrf_token": csrf_token} output = self.app.post("/pv/pull-request/merge", data=data) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.assertEqual( data, { "code": "MERGE", "message": "The pull-request can be merged with " "a merge commit", "short_code": "With merge", }, ) output = self.app.post("/api/0/test/pull-request/1/rebase") self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.assertEqual(data, {"message": "Pull-request rebased"}) data = {"requestid": self.request.uid, "csrf_token": csrf_token} output = self.app.post("/pv/pull-request/merge", data=data) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) self.assertEqual( data, { "code": "FFORWARD", "message": "The pull-request can be merged and " "fast-forwarded", "short_code": "Ok", }, ) output = self.app.get("/test/pull-request/1") self.assertEqual(output.status_code, 200) output_text = output.get_data(as_text=True) orig_repo_obj = pygit2.Repository( os.path.join(self.path, "repos", "test.git") ) orig_commit = orig_repo_obj.lookup_branch("master").peel().hex expected = f'rebased onto