diff --git a/docs/gl_objects/mr_approvals.rst b/docs/gl_objects/mr_approvals.rst index 9e4753520..2c1b8404d 100644 --- a/docs/gl_objects/mr_approvals.rst +++ b/docs/gl_objects/mr_approvals.rst @@ -21,6 +21,9 @@ References + :class:`gitlab.v4.objects.ProjectMergeRequestApprovalRule` + :class:`gitlab.v4.objects.ProjectMergeRequestApprovalRuleManager` + :attr:`gitlab.v4.objects.ProjectMergeRequest.approval_rules` + + :class:`gitlab.v4.objects.ProjectMergeRequestApprovalState` + + :class:`gitlab.v4.objects.ProjectMergeRequestApprovalStateManager` + + :attr:`gitlab.v4.objects.ProjectMergeRequest.approval_state` * GitLab API: https://docs.gitlab.com/ee/api/merge_request_approvals.html @@ -46,6 +49,10 @@ Get project-level or MR-level MR approvals settings:: mr_mras = mr.approvals.get() +Get MR-level approval state:: + + mr_approval_state = mr.approval_state.get() + Change project-level or MR-level MR approvals settings:: p_mras.approvals_before_merge = 2 diff --git a/gitlab/v4/objects/merge_request_approvals.py b/gitlab/v4/objects/merge_request_approvals.py index 4a41ca46a..b8443f144 100644 --- a/gitlab/v4/objects/merge_request_approvals.py +++ b/gitlab/v4/objects/merge_request_approvals.py @@ -19,6 +19,8 @@ "ProjectMergeRequestApprovalManager", "ProjectMergeRequestApprovalRule", "ProjectMergeRequestApprovalRuleManager", + "ProjectMergeRequestApprovalState", + "ProjectMergeRequestApprovalStateManager", ] @@ -204,3 +206,13 @@ def create(self, data, **kwargs): new_data["id"] = self._from_parent_attrs["project_id"] new_data["merge_request_iid"] = self._from_parent_attrs["mr_iid"] return CreateMixin.create(self, new_data, **kwargs) + + +class ProjectMergeRequestApprovalState(RESTObject): + pass + + +class ProjectMergeRequestApprovalStateManager(GetWithoutIdMixin, RESTManager): + _path = "/projects/%(project_id)s/merge_requests/%(mr_iid)s/approval_state" + _obj_cls = ProjectMergeRequestApprovalState + _from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"} diff --git a/gitlab/v4/objects/merge_requests.py b/gitlab/v4/objects/merge_requests.py index 4def98c4f..2a32e41d7 100644 --- a/gitlab/v4/objects/merge_requests.py +++ b/gitlab/v4/objects/merge_requests.py @@ -26,6 +26,7 @@ from .merge_request_approvals import ( # noqa: F401 ProjectMergeRequestApprovalManager, ProjectMergeRequestApprovalRuleManager, + ProjectMergeRequestApprovalStateManager, ) from .notes import ProjectMergeRequestNoteManager # noqa: F401 from .pipelines import ProjectMergeRequestPipelineManager # noqa: F401 @@ -140,6 +141,7 @@ class ProjectMergeRequest( _id_attr = "iid" approval_rules: ProjectMergeRequestApprovalRuleManager + approval_state: ProjectMergeRequestApprovalStateManager approvals: ProjectMergeRequestApprovalManager awardemojis: ProjectMergeRequestAwardEmojiManager diffs: "ProjectMergeRequestDiffManager" diff --git a/tests/unit/objects/test_project_merge_request_approvals.py b/tests/unit/objects/test_project_merge_request_approvals.py index 16d58bd01..47e29dda8 100644 --- a/tests/unit/objects/test_project_merge_request_approvals.py +++ b/tests/unit/objects/test_project_merge_request_approvals.py @@ -178,6 +178,15 @@ def resp_snippet(): } ] + approval_state_rules = copy.deepcopy(mr_ars_content) + approval_state_rules[0]["approved"] = False + approval_state_rules[0]["approved_by"] = [] + + mr_approval_state_content = { + "approval_rules_overwritten": False, + "rules": approval_state_rules, + } + with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps: rsps.add( method=responses.GET, @@ -200,6 +209,13 @@ def resp_snippet(): content_type="application/json", status=200, ) + rsps.add( + method=responses.GET, + url="http://localhost/api/v4/projects/1/merge_requests/1/approval_state", + json=mr_approval_state_content, + content_type="application/json", + status=200, + ) new_mr_ars_content = dict(mr_ars_content[0]) new_mr_ars_content["name"] = new_approval_rule_name @@ -315,3 +331,18 @@ def test_update_merge_request_approval_rule(project, resp_snippet): assert ar_1.approvals_required == updated_approval_rule_approvals_required assert len(ar_1.eligible_approvers) == len(updated_approval_rule_user_ids) assert ar_1.eligible_approvers[0]["id"] == updated_approval_rule_user_ids[0] + + +def test_get_merge_request_approval_state(project, resp_snippet): + merge_request = project.mergerequests.get(1) + approval_state = merge_request.approval_state.get() + assert isinstance( + approval_state, + gitlab.v4.objects.merge_request_approvals.ProjectMergeRequestApprovalState, + ) + assert not approval_state.approval_rules_overwritten + assert len(approval_state.rules) == 1 + assert approval_state.rules[0]["name"] == approval_rule_name + assert approval_state.rules[0]["id"] == approval_rule_id + assert not approval_state.rules[0]["approved"] + assert approval_state.rules[0]["approved_by"] == []