Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(api): fix saving merge request approval rules #2773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 4 additions & 56 deletions gitlab/v4/objects/merge_request_approvals.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, cast, Dict, List, Optional, TYPE_CHECKING, Union
from typing import Any, cast, List, Optional, TYPE_CHECKING, Union

from gitlab import exceptions as exc
from gitlab.base import RESTManager, RESTObject
Expand Down Expand Up @@ -132,42 +132,16 @@ def set_approvers(

class ProjectMergeRequestApprovalRule(SaveMixin, ObjectDeleteMixin, RESTObject):
_repr_attr = "name"
id: int
approval_rule_id: int
merge_request_iid: int

@exc.on_http_error(exc.GitlabUpdateError)
def save(self, **kwargs: Any) -> None:
"""Save the changes made to the object to the server.

The object is updated to match what the server returns.

Args:
**kwargs: Extra options to send to the server (e.g. sudo)

Raise:
GitlabAuthenticationError: If authentication is not correct
GitlabUpdateError: If the server cannot perform the request
"""
# There is a mismatch between the name of our id attribute and the put
# REST API name for the project_id, so we override it here.
self.approval_rule_id = self.id
self.merge_request_iid = self._parent_attrs["mr_iid"]
self.id = self._parent_attrs["project_id"]
# save will update self.id with the result from the server, so no need
# to overwrite with what it was before we overwrote it.
SaveMixin.save(self, **kwargs)


class ProjectMergeRequestApprovalRuleManager(CRUDMixin, RESTManager):
_path = "/projects/{project_id}/merge_requests/{mr_iid}/approval_rules"
_path = "/projects/{project_id}/merge_requests/{merge_request_iid}/approval_rules"
_obj_cls = ProjectMergeRequestApprovalRule
_from_parent_attrs = {"project_id": "project_id", "mr_iid": "iid"}
_from_parent_attrs = {"project_id": "project_id", "merge_request_iid": "iid"}
_update_attrs = RequiredOptional(
required=(
"id",
"merge_request_iid",
"approval_rule_id",
"name",
"approvals_required",
),
Expand All @@ -177,7 +151,7 @@ class ProjectMergeRequestApprovalRuleManager(CRUDMixin, RESTManager):
# groups of project-level rule will be copied. The approvals_required
# specified will be used.
_create_attrs = RequiredOptional(
required=("id", "merge_request_iid", "name", "approvals_required"),
required=("name", "approvals_required"),
optional=("approval_project_rule_id", "user_ids", "group_ids"),
)

Expand All @@ -188,32 +162,6 @@ def get(
ProjectMergeRequestApprovalRule, super().get(id=id, lazy=lazy, **kwargs)
)

def create(
self, data: Optional[Dict[str, Any]] = None, **kwargs: Any
) -> RESTObject:
"""Create a new object.

Args:
data: Parameters to send to the server to create the
resource
**kwargs: Extra options to send to the server (e.g. sudo or
'ref_name', 'stage', 'name', 'all')

Raises:
GitlabAuthenticationError: If authentication is not correct
GitlabCreateError: If the server cannot perform the request

Returns:
A new instance of the manage object class build with
the data sent by the server
"""
if TYPE_CHECKING:
assert data is not None
new_data = data.copy()
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
Expand Down
30 changes: 15 additions & 15 deletions tests/unit/objects/test_project_merge_request_approvals.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import gitlab
from gitlab.mixins import UpdateMethod

approval_rule_id = 1
approval_rule_id = 7
approval_rule_name = "security"
approvals_required = 3
user_ids = [5, 50]
Expand Down Expand Up @@ -96,21 +96,21 @@ def resp_mr_approval_rules():
with responses.RequestsMock(assert_all_requests_are_fired=False) as rsps:
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules",
url="http://localhost/api/v4/projects/1/merge_requests/3/approval_rules",
json=mr_ars_content,
content_type="application/json",
status=200,
)
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules/1",
url="http://localhost/api/v4/projects/1/merge_requests/3/approval_rules/7",
json=mr_ars_content[0],
content_type="application/json",
status=200,
)
rsps.add(
method=responses.GET,
url="http://localhost/api/v4/projects/1/merge_requests/1/approval_state",
url="http://localhost/api/v4/projects/1/merge_requests/3/approval_state",
json=mr_approval_state_content,
content_type="application/json",
status=200,
Expand All @@ -122,7 +122,7 @@ def resp_mr_approval_rules():

rsps.add(
method=responses.POST,
url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules",
url="http://localhost/api/v4/projects/1/merge_requests/3/approval_rules",
json=new_mr_ars_content,
content_type="application/json",
status=200,
Expand All @@ -139,7 +139,7 @@ def resp_mr_approval_rules():

rsps.add(
method=responses.PUT,
url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules/1",
url="http://localhost/api/v4/projects/1/merge_requests/3/approval_rules/7",
json=updated_mr_ars_content,
content_type="application/json",
status=200,
Expand All @@ -152,7 +152,7 @@ def resp_delete_mr_approval_rule():
with responses.RequestsMock() as rsps:
rsps.add(
method=responses.DELETE,
url="http://localhost/api/v4/projects/1/merge_requests/1/approval_rules/1",
url="http://localhost/api/v4/projects/1/merge_requests/3/approval_rules/7",
status=204,
)
yield rsps
Expand All @@ -170,20 +170,20 @@ def test_project_approval_manager_update_method_post(project):


def test_list_merge_request_approval_rules(project, resp_mr_approval_rules):
approval_rules = project.mergerequests.get(1, lazy=True).approval_rules.list()
approval_rules = project.mergerequests.get(3, lazy=True).approval_rules.list()
assert len(approval_rules) == 1
assert approval_rules[0].name == approval_rule_name
assert approval_rules[0].id == approval_rule_id
repr(approval_rules) # ensure that `repr()` doesn't raise an exception


def test_delete_merge_request_approval_rule(project, resp_delete_mr_approval_rule):
merge_request = project.mergerequests.get(1, lazy=True)
merge_request = project.mergerequests.get(3, lazy=True)
merge_request.approval_rules.delete(approval_rule_id)


def test_update_merge_request_approvals_set_approvers(project, resp_mr_approval_rules):
approvals = project.mergerequests.get(1, lazy=True).approvals
approvals = project.mergerequests.get(3, lazy=True).approvals
assert isinstance(
approvals,
gitlab.v4.objects.merge_request_approvals.ProjectMergeRequestApprovalManager,
Expand All @@ -203,7 +203,7 @@ def test_update_merge_request_approvals_set_approvers(project, resp_mr_approval_


def test_create_merge_request_approvals_set_approvers(project, resp_mr_approval_rules):
approvals = project.mergerequests.get(1, lazy=True).approvals
approvals = project.mergerequests.get(3, lazy=True).approvals
assert isinstance(
approvals,
gitlab.v4.objects.merge_request_approvals.ProjectMergeRequestApprovalManager,
Expand All @@ -222,7 +222,7 @@ def test_create_merge_request_approvals_set_approvers(project, resp_mr_approval_


def test_create_merge_request_approval_rule(project, resp_mr_approval_rules):
approval_rules = project.mergerequests.get(1, lazy=True).approval_rules
approval_rules = project.mergerequests.get(3, lazy=True).approval_rules
data = {
"name": new_approval_rule_name,
"approvals_required": new_approval_rule_approvals_required,
Expand All @@ -238,7 +238,7 @@ def test_create_merge_request_approval_rule(project, resp_mr_approval_rules):


def test_update_merge_request_approval_rule(project, resp_mr_approval_rules):
approval_rules = project.mergerequests.get(1, lazy=True).approval_rules
approval_rules = project.mergerequests.get(3, lazy=True).approval_rules
ar_1 = approval_rules.list()[0]
ar_1.user_ids = updated_approval_rule_user_ids
ar_1.approvals_required = updated_approval_rule_approvals_required
Expand All @@ -250,7 +250,7 @@ def test_update_merge_request_approval_rule(project, resp_mr_approval_rules):


def test_get_merge_request_approval_rule(project, resp_mr_approval_rules):
merge_request = project.mergerequests.get(1, lazy=True)
merge_request = project.mergerequests.get(3, lazy=True)
approval_rule = merge_request.approval_rules.get(approval_rule_id)
assert isinstance(
approval_rule,
Expand All @@ -261,7 +261,7 @@ def test_get_merge_request_approval_rule(project, resp_mr_approval_rules):


def test_get_merge_request_approval_state(project, resp_mr_approval_rules):
merge_request = project.mergerequests.get(1, lazy=True)
merge_request = project.mergerequests.get(3, lazy=True)
approval_state = merge_request.approval_state.get()
assert isinstance(
approval_state,
Expand Down