Esempio n. 1
0
    def test_fetch_from_merge_request(self):
        api = self.api
        api.call = Mock(return_value=INFO)

        merge_request = MergeRequest(api, {
            'id': 74,
            'iid': 6,
            'project_id': 1234
        })
        approvals = merge_request.fetch_approvals()

        api.call.assert_called_once_with(
            GET('/projects/1234/merge_requests/6/approvals'))
        assert approvals.info == INFO
Esempio n. 2
0
    def make_job(self, options=None):
        api, mocklab = self.api, self.mocklab

        project_id = mocklab.project_info['id']
        merge_request_iid = mocklab.merge_request_info['iid']

        project = marge.project.Project.fetch_by_id(project_id, api)
        merge_request = MergeRequest.fetch_by_iid(project_id,
                                                  merge_request_iid, api)

        repo = Mock(marge.git.Repo)
        options = options or marge.job.MergeJobOptions.default()
        user = marge.user.User.myself(self.api)
        bot = marge.bot.Bot(
            api=self.api,
            user=user,
            ssh_key_file='id_rsa',
            add_reviewers=options.add_reviewers,
            add_tested=options.add_tested,
            impersonate_approvers=options.reapprove,
        )
        return marge.job.MergeJob(bot=bot,
                                  project=project,
                                  merge_request=merge_request,
                                  repo=repo)
Esempio n. 3
0
    def test_fetch_by_iid(self):
        api = self.api
        api.call = Mock(return_value=INFO)

        merge_request = MergeRequest.fetch_by_iid(project_id=1234, merge_request_iid=54, api=api)

        api.call.assert_called_once_with(GET('/projects/1234/merge_requests/54'))
        assert merge_request.info == INFO
Esempio n. 4
0
 def test_fetch_all_opened_for_me(self):
     api = self.api
     mr1, mr_not_me, mr2 = INFO, dict(INFO, assignee={'id': _MARGE_ID+1}, id=679), dict(INFO, id=678)
     api.collect_all_pages = Mock(return_value=[mr1, mr_not_me, mr2])
     result = MergeRequest.fetch_all_open_for_user(1234, user_id=_MARGE_ID, api=api)
     api.collect_all_pages.assert_called_once_with(GET(
         '/projects/1234/merge_requests',
         {'state': 'opened', 'order_by': 'created_at', 'sort': 'asc'},
     ))
     assert [mr.info for mr in result] == [mr1, mr2]
Esempio n. 5
0
    def test_fetch_from_merge_request_ce_compat(self):
        api = self.api
        api.version = Mock(return_value=Version.parse('9.2.3'))
        api.call = Mock()

        merge_request = MergeRequest(api, {
            'id': 74,
            'iid': 6,
            'project_id': 1234
        })
        approvals = merge_request.fetch_approvals()

        api.call.assert_not_called()
        assert approvals.info == {
            'id': 74,
            'iid': 6,
            'project_id': 1234,
            'approvals_left': 0,
            'approved_by': [],
        }
Esempio n. 6
0
 def test_fetch_assigned_at(self):
     api = self.api
     dis1, dis2 = DISCUSSION, dict(DISCUSSION, id=679)
     mr1 = INFO
     user = marge.user.User(api=None, info=dict(USER_INFO, id=_MARGE_ID))
     api.collect_all_pages = Mock(return_value=[dis1, dis2])
     result = MergeRequest.fetch_assigned_at(user=user,
                                             api=api,
                                             merge_request=mr1)
     api.collect_all_pages.assert_called_once_with(
         GET('/projects/1234/merge_requests/54/discussions', ))
     assert result == 1597733578
Esempio n. 7
0
        def make_mocks(initial_master_sha=None,
                       rewritten_sha=None,
                       extra_opts=None,
                       extra_mocklab_opts=None,
                       on_push=None):
            options = options_factory(**(extra_opts or {}))
            initial_master_sha = initial_master_sha or '505050505e'

            if not rewritten_sha:
                rewritten_sha = rewrite_sha(
                    update_sha(INITIAL_MR_SHA, initial_master_sha))

            mocklab = mocklab_factory(initial_master_sha=initial_master_sha,
                                      rewritten_sha=rewritten_sha,
                                      **(extra_mocklab_opts or {}))
            api = mocklab.api

            project_id = mocklab.project_info['id']
            merge_request_iid = mocklab.merge_request_info['iid']

            project = marge.project.Project.fetch_by_id(project_id, api)
            forked_project = None
            if mocklab.forked_project_info:
                forked_project_id = mocklab.forked_project_info['id']
                forked_project = marge.project.Project.fetch_by_id(
                    forked_project_id, api)

            merge_request = MergeRequest.fetch_by_iid(project_id,
                                                      merge_request_iid, api)

            def assert_can_push(*_args, **_kwargs):
                assert options.fusion is not Fusion.gitlab_rebase

            callback = on_push or mocklab.push_updated
            repo = RepoMock.init_for_merge_request(
                merge_request=merge_request,
                initial_target_sha=mocklab.initial_master_sha,
                project=project,
                forked_project=forked_project,
            )
            repo.mock_impl.on_push_callbacks.append(assert_can_push)
            repo.mock_impl.on_push_callbacks.append(callback)

            user = marge.user.User.myself(api)
            job = marge.single_merge_job.SingleMergeJob(
                api=api,
                user=user,
                project=project,
                merge_request=merge_request,
                repo=repo,
                options=options,
            )
            return self.Mocks(mocklab=mocklab, api=api, job=job)
Esempio n. 8
0
    def make_job(self, api, mocklab, options=None):
        project_id = mocklab.project_info['id']
        merge_request_iid = mocklab.merge_request_info['iid']

        project = marge.project.Project.fetch_by_id(project_id, api)
        merge_request = MergeRequest.fetch_by_iid(project_id, merge_request_iid, api)

        repo = create_autospec(marge.git.Repo, spec_set=True)
        options = options or marge.job.MergeJobOptions.default()
        user = marge.user.User.myself(api)
        return marge.single_merge_job.SingleMergeJob(
            api=api, user=user,
            project=project, merge_request=merge_request, repo=repo,
            options=options,
        )
Esempio n. 9
0
    def get_batch_merge_job(self, api, mocklab, **batch_merge_kwargs):
        project_id = mocklab.project_info['id']
        merge_request_iid = mocklab.merge_request_info['iid']

        merge_request = MergeRequest.fetch_by_iid(project_id, merge_request_iid, api)

        params = {
            'api': api,
            'user': marge.user.User.myself(api),
            'project': marge.project.Project.fetch_by_id(project_id, api),
            'repo': create_autospec(marge.git.Repo, spec_set=True),
            'options': MergeJobOptions.default(),
            'merge_requests': [merge_request]
        }
        params.update(batch_merge_kwargs)
        return BatchMergeJob(**params)
Esempio n. 10
0
    def make_job(self, options=None):
        api, mocklab = self.api, self.mocklab

        project_id = mocklab.project_info['id']
        merge_request_iid = mocklab.merge_request_info['iid']

        project = marge.project.Project.fetch_by_id(project_id, api)
        merge_request = MergeRequest.fetch_by_iid(project_id, merge_request_iid, api)

        repo = Mock(marge.git.Repo)
        options = options or marge.job.MergeJobOptions.default()
        user = marge.user.User.myself(self.api)
        return marge.job.MergeJob(
            api=api, user=user,
            project=project, merge_request=merge_request, repo=repo,
            options=options,
        )
Esempio n. 11
0
 def setup_method(self, _method):
     self.api = Mock(Api)
     self.api.version = Mock(return_value=Version.parse('9.2.3-ee'))
     self.merge_request = MergeRequest(api=self.api, info=INFO)
Esempio n. 12
0
class TestMergeRequest:
    def setup_method(self, _method):
        self.api = Mock(Api)
        self.api.version = Mock(return_value=Version.parse('9.2.3-ee'))
        self.merge_request = MergeRequest(api=self.api, info=INFO)

    def test_fetch_by_iid(self):
        api = self.api
        api.call = Mock(return_value=INFO)

        merge_request = MergeRequest.fetch_by_iid(project_id=1234,
                                                  merge_request_iid=54,
                                                  api=api)

        api.call.assert_called_once_with(
            GET('/projects/1234/merge_requests/54'))
        assert merge_request.info == INFO

    def test_refetch_info(self):
        new_info = dict(INFO, state='closed')
        self.api.call = Mock(return_value=new_info)

        self.merge_request.refetch_info()
        self.api.call.assert_called_once_with(
            GET('/projects/1234/merge_requests/54'))
        assert self.merge_request.info == new_info

    def test_properties(self):
        assert self.merge_request.id == 42
        assert self.merge_request.project_id == 1234
        assert self.merge_request.iid == 54
        assert self.merge_request.title == 'a title'
        assert self.merge_request.assignee_ids == [77]
        assert self.merge_request.author_id == 88
        assert self.merge_request.state == 'opened'
        assert self.merge_request.source_branch == 'useless_new_feature'
        assert self.merge_request.target_branch == 'master'
        assert self.merge_request.sha == 'dead4g00d'
        assert self.merge_request.source_project_id == 5678
        assert self.merge_request.target_project_id == 1234
        assert self.merge_request.work_in_progress is False

        self._load({'assignees': []})
        assert self.merge_request.assignee_ids == []

    def test_comment(self):
        self.merge_request.comment('blah')
        self.api.call.assert_called_once_with(
            POST(
                '/projects/1234/merge_requests/54/notes',
                {'body': 'blah'},
            ), )

    def test_assign(self):
        self.merge_request.assign_to(42)
        self.api.call.assert_called_once_with(
            PUT('/projects/1234/merge_requests/54', {'assignee_id': 42}))

    def test_unassign(self):
        self.merge_request.unassign()
        self.api.call.assert_called_once_with(
            PUT('/projects/1234/merge_requests/54', {'assignee_id': 0}))

    def test_rebase_was_not_in_progress_no_error(self):
        expected = [
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> not in progress
                INFO),
            (PUT('/projects/1234/merge_requests/54/rebase'), True),
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> in progress
                dict(INFO, rebase_in_progress=True)),
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> succeeded
                dict(INFO, rebase_in_progress=False)),
        ]

        self.api.call = Mock(side_effect=[resp for (req, resp) in expected])
        self.merge_request.rebase()
        self.api.call.assert_has_calls([call(req) for (req, resp) in expected])

    def test_rebase_was_not_in_progress_error(self):
        expected = [
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> not in progress
                INFO),
            (PUT('/projects/1234/merge_requests/54/rebase'), True),
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> BOOM
                dict(INFO,
                     rebase_in_progress=False,
                     merge_error="Rebase failed. Please rebase locally")),
        ]

        self.api.call = Mock(side_effect=[resp for (req, resp) in expected])

        with pytest.raises(MergeRequestRebaseFailed):
            self.merge_request.rebase()
        self.api.call.assert_has_calls([call(req) for (req, resp) in expected])

    def test_rebase_was_in_progress_no_error(self):
        expected = [
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> in progress
                dict(INFO, rebase_in_progress=True)),
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> in progress
                dict(INFO, rebase_in_progress=True)),
            (
                GET('/projects/1234/merge_requests/54'
                    ),  # refetch_info -> succeeded
                dict(INFO, rebase_in_progress=False)),
        ]
        self.api.call = Mock(side_effect=[resp for (req, resp) in expected])
        self.merge_request.rebase()
        self.api.call.assert_has_calls([call(req) for (req, resp) in expected])

    def test_accept_remove_branch(self):
        self._load(dict(INFO, sha='badc0de'))

        for boolean in (True, False):
            self.merge_request.accept(remove_branch=boolean)
            self.api.call.assert_called_once_with(
                PUT(
                    '/projects/1234/merge_requests/54/merge',
                    dict(
                        merge_when_pipeline_succeeds=True,
                        should_remove_source_branch=boolean,
                        sha='badc0de',
                    )))
            self.api.call.reset_mock()

    def test_accept_sha(self):
        self._load(dict(INFO, sha='badc0de'))
        self.merge_request.accept(sha='g00dc0de')
        self.api.call.assert_called_once_with(
            PUT(
                '/projects/1234/merge_requests/54/merge',
                dict(
                    merge_when_pipeline_succeeds=True,
                    should_remove_source_branch=False,
                    sha='g00dc0de',
                )))

    def test_accept_merge_when_pipeline_succeeds(self):
        self._load(dict(INFO, sha='badc0de'))
        self.merge_request.accept(merge_when_pipeline_succeeds=False)
        self.api.call.assert_called_once_with(
            PUT(
                '/projects/1234/merge_requests/54/merge',
                dict(
                    merge_when_pipeline_succeeds=False,
                    should_remove_source_branch=False,
                    sha='badc0de',
                )))

    def test_fetch_all_opened_for_me(self):
        api = self.api
        mr1, mr_not_me, mr2 = INFO, dict(INFO,
                                         assignees=[{
                                             'id': _MARGE_ID + 1
                                         }],
                                         id=679), dict(INFO, id=678)
        user = marge.user.User(api=None, info=dict(USER_INFO, id=_MARGE_ID))
        api.collect_all_pages = Mock(return_value=[mr1, mr_not_me, mr2])
        result = MergeRequest.fetch_all_open_for_user(1234,
                                                      user=user,
                                                      api=api,
                                                      merge_order='created_at')
        api.collect_all_pages.assert_called_once_with(
            GET(
                '/projects/1234/merge_requests',
                {
                    'state': 'opened',
                    'order_by': 'created_at',
                    'sort': 'asc'
                },
            ))
        assert [mr.info for mr in result] == [mr1, mr2]

    def test_fetch_assigned_at(self):
        api = self.api
        dis1, dis2 = DISCUSSION, dict(DISCUSSION, id=679)
        mr1 = INFO
        user = marge.user.User(api=None, info=dict(USER_INFO, id=_MARGE_ID))
        api.collect_all_pages = Mock(return_value=[dis1, dis2])
        result = MergeRequest.fetch_assigned_at(user=user,
                                                api=api,
                                                merge_request=mr1)
        api.collect_all_pages.assert_called_once_with(
            GET('/projects/1234/merge_requests/54/discussions', ))
        assert result == 1597733578

    def _load(self, json):
        old_mock = self.api.call
        self.api.call = Mock(return_value=json)
        self.merge_request.refetch_info()
        self.api.call.assert_called_with(
            GET('/projects/1234/merge_requests/54'))
        self.api.call = old_mock
Esempio n. 13
0
class TestMergeRequest(object):
    def setup_method(self, _method):
        self.api = Mock(Api)
        self.api.version = Mock(return_value=Version.parse('9.2.3-ee'))
        self.merge_request = MergeRequest(api=self.api, info=INFO)

    def test_fetch_by_iid(self):
        api = self.api
        api.call = Mock(return_value=INFO)

        merge_request = MergeRequest.fetch_by_iid(project_id=1234,
                                                  merge_request_iid=54,
                                                  api=api)

        api.call.assert_called_once_with(
            GET('/projects/1234/merge_requests/54'))
        assert merge_request.info == INFO

    def test_refetch_info(self):
        new_info = dict(INFO, state='closed')
        self.api.call = Mock(return_value=new_info)

        self.merge_request.refetch_info()
        self.api.call.assert_called_once_with(
            GET('/projects/1234/merge_requests/54'))
        assert self.merge_request.info == new_info

    def test_properties(self):
        assert self.merge_request.id == 42
        assert self.merge_request.project_id == 1234
        assert self.merge_request.iid == 54
        assert self.merge_request.title == 'a title'
        assert self.merge_request.assignee_id == 77
        assert self.merge_request.author_id == 88
        assert self.merge_request.state == 'opened'
        assert self.merge_request.source_branch == 'useless_new_feature'
        assert self.merge_request.target_branch == 'master'
        assert self.merge_request.sha == 'dead4g00d'
        assert self.merge_request.source_project_id == 5678
        assert self.merge_request.target_project_id == 1234
        assert self.merge_request.work_in_progress is False

        self._load({'assignee': {}})
        assert self.merge_request.assignee_id is None

    def test_comment(self):
        self.merge_request.comment('blah')
        self.api.call.assert_called_once_with(
            POST(
                '/projects/1234/merge_requests/54/notes',
                {'body': 'blah'},
            ), )

    def test_assign(self):
        self.merge_request.assign_to(42)
        self.api.call.assert_called_once_with(
            PUT('/projects/1234/merge_requests/54', {'assignee_id': 42}))

    def test_unassign(self):
        self.merge_request.unassign()
        self.api.call.assert_called_once_with(
            PUT('/projects/1234/merge_requests/54', {'assignee_id': None}))

    def test_accept(self):
        self._load(dict(INFO, sha='badc0de'))

        for boolean in (True, False):
            self.merge_request.accept(remove_branch=boolean)
            self.api.call.assert_called_once_with(
                PUT(
                    '/projects/1234/merge_requests/54/merge',
                    dict(
                        merge_when_pipeline_succeeds=True,
                        should_remove_source_branch=boolean,
                        sha='badc0de',
                    )))
            self.api.call.reset_mock()

        self.merge_request.accept(sha='g00dc0de')
        self.api.call.assert_called_once_with(
            PUT(
                '/projects/1234/merge_requests/54/merge',
                dict(
                    merge_when_pipeline_succeeds=True,
                    should_remove_source_branch=False,
                    sha='g00dc0de',
                )))

    def test_fetch_all_opened_for_me(self):
        api = self.api
        mr1, mr_not_me, mr2 = INFO, dict(INFO,
                                         assignee={'id': _MARGE_ID + 1},
                                         id=679), dict(INFO, id=678)
        api.collect_all_pages = Mock(return_value=[mr1, mr_not_me, mr2])
        result = MergeRequest.fetch_all_open_for_user(1234,
                                                      user_id=_MARGE_ID,
                                                      api=api,
                                                      merge_order='created_at')
        api.collect_all_pages.assert_called_once_with(
            GET(
                '/projects/1234/merge_requests',
                {
                    'state': 'opened',
                    'order_by': 'created_at',
                    'sort': 'asc'
                },
            ))
        assert [mr.info for mr in result] == [mr1, mr2]

    def _load(self, json):
        old_mock = self.api.call
        self.api.call = Mock(return_value=json)
        self.merge_request.refetch_info()
        self.api.call.assert_called_with(
            GET('/projects/1234/merge_requests/54'))
        self.api.call = old_mock