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
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)
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_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]
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': [], }
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 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)
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, )
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)
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, )
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)
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
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