# Copyright (C) 2021-2022 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import logging
import os
import time

from mock import patch
from webkitbugspy import Tracker, User, bugzilla, radar, mocks as bmocks
from webkitcorepy import OutputCapture, testing
from webkitcorepy.mocks import Terminal as MockTerminal, Time as MockTime, Environment
from webkitscmpy import Contributor, Commit, local, program, mocks


def repository(path, has_oops=True, remote=None, remotes=None, git_svn=False, issue_url=None):
    branch = 'eng/example'
    result = mocks.local.Git(path, remote=remote, remotes=remotes, git_svn=git_svn)
    result.commits[branch] = [
        result.commits[result.default_branch][2],
        Commit(
            hash='a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd',
            identifier='3.1@{}'.format(branch),
            revision=10,
            timestamp=int(time.time()) - 60,
            author=Contributor('Tim Committer', ['tcommitter@webkit.org']),
            message='To Be Committed\n{}\nReviewed by {}.\n{}'.format(
                '{}\n'.format(issue_url) if issue_url else '',
                'NOBODY (OOPS!)' if has_oops else 'Ricky Reviewer',
                '\ngit-svn-id: https://svn.{}/repository/{}/trunk@10 268f45cc-cd09-0410-ab3c-d52691b4dbfc\n'.format(
                    result.remote.split('@')[-1].split(':')[0],
                    os.path.basename(result.path),
                ) if git_svn else '',
            ),
        )
    ]
    result.head = result.commits[branch][-1]
    return result


class TestLand(testing.PathTestCase):
    basepath = 'mock/repository'
    BUGZILLA = 'https://bugs.example.com'

    def setUp(self):
        super(TestLand, self).setUp()
        os.mkdir(os.path.join(self.path, '.git'))
        os.mkdir(os.path.join(self.path, '.svn'))

    def test_none(self):
        with OutputCapture(level=logging.INFO) as captured, mocks.local.Git(), mocks.local.Svn():
            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
        self.assertEqual(captured.stderr.getvalue(), 'No repository provided\n')

    def test_non_editable(self):
        with OutputCapture(level=logging.INFO) as captured, mocks.local.Git(self.path), mocks.local.Svn():
            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '5@main')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual([line for line in log if 'Mock process' not in line], [])
        self.assertEqual(
            captured.stderr.getvalue(),
            "Can only 'land' editable branches\n",
        )
        self.assertEqual(captured.stdout.getvalue(), '')

    def test_with_oops(self):
        with OutputCapture(level=logging.INFO) as captured, repository(self.path), mocks.local.Svn():
            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '3.1@eng/example')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...'
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Failed to find pull-request associated with 'eng/example'\n"
            "Found '(OOPS!)' message in commit messages, please resolve before committing\n",
        )
        self.assertEqual(captured.stdout.getvalue(), '')

    def test_default(self):
        with OutputCapture(level=logging.INFO) as captured, repository(self.path, has_oops=False), mocks.local.Svn(), MockTerminal.input('n'):
            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '6@main')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Failed to find pull-request associated with 'eng/example'\n",
        )
        self.assertEqual(
            captured.stdout.getvalue(),
            'Landed a5fe8afe9bf7!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )

    def test_canonicalize(self):
        with OutputCapture(level=logging.INFO) as captured, repository(self.path, has_oops=False), mocks.local.Svn(), MockTerminal.input('n'):
            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path,
                identifier_template='Canonical link: https://commits.webkit.org/{}',
            ))

            commit = local.Git(self.path).commit(branch='main')
            self.assertEqual(str(commit), '6@main')
            self.assertEqual(
                commit.message,
                'To Be Committed\n\n'
                'Reviewed by Ricky Reviewer.\n\n'
                'Canonical link: https://commits.webkit.org/6@main',
            )

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
                '1 commit to be edited...',
                'Base commit is 5@main (ref d8bce26fa65c6fc8f39c17927abb77f69fab82fc)',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Failed to find pull-request associated with 'eng/example'\n",
        )
        self.assertEqual(
            captured.stdout.getvalue(),
            'Rewrite a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd (1/1) (--- seconds passed, remaining --- predicted)\n'
            'Overwriting a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd\n'
            '1 commit successfully canonicalized!\n'
            'Landed https://commits.webkit.org/6@main (a5fe8afe9bf7)!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )

    def test_no_svn_canonical_svn(self):
        with OutputCapture(level=logging.INFO) as captured, repository(self.path, has_oops=False), mocks.local.Svn():
            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path, canonical_svn=True,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '3.1@eng/example')

        self.assertEqual(
            captured.stderr.getvalue(),
            "Cannot 'land' on a canonical SVN repository that is not configured as git-svn\n",
        )
        self.assertEqual(captured.stdout.getvalue(), '')

    def test_svn(self):
        with MockTime, OutputCapture(level=logging.INFO) as captured, repository(self.path, has_oops=False, git_svn=True), mocks.local.Svn(), MockTerminal.input('n'):
            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path, canonical_svn=True,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '6@main')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
                '    Verifying mirror processesed change',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Failed to find pull-request associated with 'eng/example'\n",
        )
        self.assertEqual(
            captured.stdout.getvalue(),
            'Landed a5fe8afe9bf7!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )

    def test_default_with_radar(self):
        with OutputCapture(level=logging.INFO) as captured, repository(self.path, has_oops=False, issue_url='<rdar://problem/1>'), mocks.local.Svn(), \
                MockTerminal.input('n'), Environment(RADAR_USERNAME='tcontributor'), bmocks.Radar(issues=bmocks.ISSUES), \
                patch('webkitbugspy.Tracker._trackers', [radar.Tracker()]):

            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '6@main')
            self.assertEqual(
                Tracker.instance().issue(1).comments[-1].content,
                'Landed a5fe8afe9bf7!',
            )
            self.assertFalse(Tracker.instance().issue(1).opened)

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Failed to find pull-request associated with 'eng/example'\n",
        )
        self.assertEqual(
            captured.stdout.getvalue(),
            'Landed a5fe8afe9bf7!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )

    def test_canonicalize_with_bugzilla(self):
        with OutputCapture(level=logging.INFO) as captured, repository(self.path, has_oops=False, issue_url='{}/show_bug.cgi?id=1'.format(self.BUGZILLA)), \
                mocks.local.Svn(), MockTerminal.input('n'), patch('webkitbugspy.Tracker._trackers', [bugzilla.Tracker(self.BUGZILLA)]), bmocks.Bugzilla(
                    self.BUGZILLA.split('://')[-1],
                    issues=bmocks.ISSUES,
                    environment=Environment(
                        BUGS_EXAMPLE_COM_USERNAME='tcontributor@example.com',
                        BUGS_EXAMPLE_COM_PASSWORD='password',
                )):

            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path,
                identifier_template='Canonical link: https://commits.webkit.org/{}',
            ))
            self.assertEqual(
                Tracker.instance().issue(1).comments[-1].content,
                'Landed https://commits.webkit.org/6@main (a5fe8afe9bf7)!',
            )
            self.assertFalse(Tracker.instance().issue(1).opened)

            commit = local.Git(self.path).commit(branch='main')
            self.assertEqual(str(commit), '6@main')
            self.assertEqual(
                commit.message,
                'To Be Committed\n'
                'https://bugs.example.com/show_bug.cgi?id=1\n\n'
                'Reviewed by Ricky Reviewer.\n\n'
                'Canonical link: https://commits.webkit.org/6@main',
            )

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
                '1 commit to be edited...',
                'Base commit is 5@main (ref d8bce26fa65c6fc8f39c17927abb77f69fab82fc)',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Failed to find pull-request associated with 'eng/example'\n",
        )
        self.assertEqual(
            captured.stdout.getvalue(),
            'Rewrite a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd (1/1) (--- seconds passed, remaining --- predicted)\n'
            'Overwriting a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd\n'
            '1 commit successfully canonicalized!\n'
            'Landed https://commits.webkit.org/6@main (a5fe8afe9bf7)!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )

    def test_svn_with_bugzilla(self):
        with MockTime, OutputCapture(level=logging.INFO) as captured, \
                repository(self.path, has_oops=False, git_svn=True, issue_url='{}/show_bug.cgi?id=1'.format(self.BUGZILLA)), \
                mocks.local.Svn(), MockTerminal.input('n'), patch('webkitbugspy.Tracker._trackers', [bugzilla.Tracker(self.BUGZILLA)]), \
                bmocks.Bugzilla(
                    self.BUGZILLA.split('://')[-1],
                    issues=bmocks.ISSUES,
                    environment=Environment(
                        BUGS_EXAMPLE_COM_USERNAME='tcontributor@example.com',
                        BUGS_EXAMPLE_COM_PASSWORD='password',
                )):

            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path, canonical_svn=True,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '6@main')
            self.assertEqual(
                Tracker.instance().issue(1).comments[-1].content,
                'Landed r10!',
            )
            self.assertFalse(Tracker.instance().issue(1).opened)

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
                '    Verifying mirror processesed change',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Failed to find pull-request associated with 'eng/example'\n",
        )
        self.assertEqual(
            captured.stdout.getvalue(),
            'Landed a5fe8afe9bf7!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )


class TestLandGitHub(testing.PathTestCase):
    basepath = 'mock/repository'

    def setUp(self):
        super(TestLandGitHub, self).setUp()
        os.mkdir(os.path.join(self.path, '.git'))
        os.mkdir(os.path.join(self.path, '.svn'))

    @classmethod
    def webserver(cls, approved=None, labels=None):
        result = mocks.remote.GitHub(labels=labels)
        result.users.create('Ricky Reviewer', 'rreviewer', ['rreviewer@webkit.org'])
        result.users.create('Tim Contributor', 'tcontributor', ['tcontributor@webkit.org'])
        result.issues = {
            1: dict(
                number=1,
                opened=True,
                title='Example Change',
                description='?',
                creator=result.users.create(name='Tim Contributor', username='tcontributor'),
                timestamp=1639536160,
                assignee=None,
                comments=[],
            ),
        }
        result.pull_requests = [dict(
            number=1,
            state='open',
            title='Example Change',
            user=dict(login='tcontributor'),
            body='''#### a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd
    <pre>
    To Be Committed

    Reviewed by NOBODY (OOPS!).
    </pre>
    ''',
            head=dict(ref='username:eng/example'),
            base=dict(ref='main'),
            requested_reviews=[dict(login='rreviewer')],
            reviews=[
                dict(user=dict(login='rreviewer'), state='APPROVED')
            ] if approved else [] + [
                dict(user=dict(login='rreviewer'), state='CHANGES_REQUESTED')
            ] if approved is not None else [], _links=dict(
                issue=dict(href='https://{}/issues/1'.format(result.api_remote)),
            ), draft=False,
        )]
        return result

    def test_no_reviewer(self):
        with OutputCapture(level=logging.INFO) as captured, self.webserver() as remote, \
                repository(self.path, remote='https://{}'.format(remote.remote)), mocks.local.Svn():

            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '3.1@eng/example')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Found '(OOPS!)' message in commit messages, please resolve before committing\n",
        )
        self.assertEqual(captured.stdout.getvalue(), '')

    def test_blocking_reviewer(self):
        with OutputCapture(level=logging.INFO) as captured, self.webserver(approved=False) as remote, \
                repository(self.path, has_oops=False, remote='https://{}'.format(remote.remote)), mocks.local.Svn():

            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '3.1@eng/example')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Ricky Reviewer is blocking landing 'PR 1 | Example Change'\n",
        )
        self.assertEqual(captured.stdout.getvalue(), '')

    def test_insert_review(self):
        with OutputCapture(level=logging.INFO) as captured, MockTerminal.input('y', 'n'), self.webserver(
                approved=True) as remote, \
                repository(self.path, has_oops=True, remote='https://{}'.format(remote.remote)), mocks.local.Svn():
            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path,
            ))

            repo = local.Git(self.path)
            self.assertEqual(str(repo.commit()), '6@main')
            self.assertEqual(
                [comment.content for comment in repo.remote().pull_requests.get(1).comments],
                ['Landed a5fe8afe9bf7!'],
            )

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                'Setting Ricky Reviewer as reviewer',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
                "Updating 'PR 1 | Example Change' to match landing commits...",
            ],
        )
        self.assertEqual(captured.stderr.getvalue(), '')
        self.assertEqual(
            captured.stdout.getvalue(),
            "Set 'Ricky Reviewer' as your reviewer? ([Yes]/No): \n"
            'Landed a5fe8afe9bf7!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )

    def test_merge_queue(self):
        with OutputCapture(level=logging.INFO) as captured, MockTerminal.input('y', 'n'), self.webserver(
            approved=True, labels={'merge-queue': dict(color='3AE653', description="Send PR to merge-queue")},
        ) as remote, mocks.local.Svn(), repository(
            self.path, has_oops=True,
            remote='https://{}'.format(remote.remote),
            remotes=dict(fork='https://{}/Contributor/WebKit'.format(remote.hosts[0])),
        ):
            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path,
            ))

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                'Detected merging automation, using that instead of local git tooling',
                "Rebasing 'eng/example' on 'main'...",
                "Rebased 'eng/example' on 'main!'",
                '    Found 1 commit...',
                'Running pre-PR checks...',
                'No pre-PR checks to run',
                'Checking PR labels for active labels...',
                "Pushing 'eng/example' to 'fork'...",
                "Syncing 'main' to remote 'fork'",
                "Creating 'eng/example-1' as a reference branch",
                "Updating pull-request for 'eng/example'...",
                "Adding 'merge-queue' to 'PR 1 | To Be Committed'",
            ],
        )
        self.assertEqual(captured.stderr.getvalue(), '')
        self.assertEqual(
            captured.stdout.getvalue(),
            "Updated 'PR 1 | To Be Committed'!\n"
            "https://github.example.com/WebKit/WebKit/pull/1\n"
            "Added 'merge-queue' to 'PR 1 | To Be Committed', change is in the queue to be landed\n",
        )


class TestLandBitBucket(testing.PathTestCase):
    basepath = 'mock/repository'

    def setUp(self):
        super(TestLandBitBucket, self).setUp()
        os.mkdir(os.path.join(self.path, '.git'))
        os.mkdir(os.path.join(self.path, '.svn'))

    @classmethod
    def webserver(cls, approved=None):
        result = mocks.remote.BitBucket()
        result.pull_requests = [dict(
            id=1,
            state='OPEN',
            open=True,
            closed=False,
            activities=[],
            title='Example Change',
            author=dict(
                user=dict(
                    name='tcontributor',
                    emailAddress='tcontributor@apple.com',
                    displayName='Tim Contributor',
                ),
            ), body='''#### a5fe8afe9bf7d07158fcd9e9732ff02a712db2fd
    ```
    To Be Committed

    Reviewed by NOBODY (OOPS!).
    ```
    ''',
            fromRef=dict(displayId='eng/example', id='refs/heads/eng/example'),
            toRef=dict(displayId='main', id='refs/heads/main'),
            reviewers=[
                dict(
                    user=dict(
                        displayName='Ricky Reviewer',
                        emailAddress='rreviewer@webkit.org',
                    ), approved=True if approved else False,
                    status='NEEDS_WORK' if approved is False else None,
                ),
            ],
        )]
        return result

    def test_no_reviewer(self):
        with OutputCapture(level=logging.INFO) as captured, self.webserver() as remote, repository(
                self.path, remote='ssh://git@{}/{}/{}.git'.format(
                    remote.hosts[0], remote.project.split('/')[1], remote.project.split('/')[3],
                )), mocks.local.Svn():

            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '3.1@eng/example')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Found '(OOPS!)' message in commit messages, please resolve before committing\n",
        )
        self.assertEqual(captured.stdout.getvalue(), '')

    def test_blocking_reviewer(self):
        with OutputCapture(level=logging.INFO) as captured, self.webserver(approved=False) as remote, repository(
                self.path, has_oops=False, remote='ssh://git@{}/{}/{}.git'.format(
                    remote.hosts[0], remote.project.split('/')[1], remote.project.split('/')[3],
                )), mocks.local.Svn():

            self.assertEqual(1, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            self.assertEqual(str(local.Git(self.path).commit()), '3.1@eng/example')

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
            ],
        )
        self.assertEqual(
            captured.stderr.getvalue(),
            "Ricky Reviewer is blocking landing 'PR 1 | Example Change'\n",
        )
        self.assertEqual(captured.stdout.getvalue(), '')

    def test_insert_review(self):
        with OutputCapture(level=logging.INFO) as captured, MockTerminal.input('y', 'n'), self.webserver(approved=True) as remote, repository(
                self.path, has_oops=True, remote='ssh://git@{}/{}/{}.git'.format(
                    remote.hosts[0], remote.project.split('/')[1], remote.project.split('/')[3],
                )), mocks.local.Svn():

            self.assertEqual(0, program.main(
                args=('land', '-v'),
                path=self.path,
            ))
            repo = local.Git(self.path)
            self.assertEqual(str(repo.commit()), '6@main')
            self.assertEqual(
                [comment.content for comment in repo.remote().pull_requests.get(1).comments],
                ['Landed a5fe8afe9bf7!'],
            )

        log = captured.root.log.getvalue().splitlines()
        self.assertEqual(
            [line for line in log if 'Mock process' not in line], [
                '    Found 1 commit...',
                'Using committed changes...',
                'Setting Ricky Reviewer as reviewer',
                "Rebasing 'eng/example' from 'main' to 'main'...",
                "Rebased 'eng/example' from 'main' to 'main'!",
                "Updating 'PR 1 | Example Change' to match landing commits...",
            ],
        )
        self.assertEqual(captured.stderr.getvalue(), '')
        self.assertEqual(
            captured.stdout.getvalue(),
            "Set 'Ricky Reviewer' as your reviewer? ([Yes]/No): \n"
            'Landed a5fe8afe9bf7!\n'
            "Delete branch 'eng/example'? ([Yes]/No): \n",
        )
