Unverified Commit 174d992e authored by xakepnz's avatar xakepnz Committed by GitHub
Browse files

feat: introduce related_issues to merge requests (#2996)

parent a2ab54ce
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -144,6 +144,10 @@ List the changes of a MR::

    changes = mr.changes()

List issues related to this merge request::

    related_issues = mr.related_issues()

List issues that will close on merge::

    mr.closes_issues()
+29 −0
Original line number Diff line number Diff line
@@ -197,6 +197,35 @@ class ProjectMergeRequest(
            assert isinstance(server_data, dict)
        return server_data

    @cli.register_custom_action(cls_names="ProjectMergeRequest")
    @exc.on_http_error(exc.GitlabListError)
    def related_issues(self, **kwargs: Any) -> RESTObjectList:
        """List issues related to this merge request."

        Args:
            all: If True, return all the items, without pagination
            per_page: Number of items to retrieve per request
            page: ID of the page to return (starts with page 1)
            **kwargs: Extra options to send to the server (e.g. sudo)

        Raises:
            GitlabAuthenticationError: If authentication is not correct
            GitlabListError: If the list could not be retrieved

        Returns:
            List of issues
        """

        path = f"{self.manager.path}/{self.encoded_id}/related_issues"
        data_list = self.manager.gitlab.http_list(path, iterator=True, **kwargs)

        if TYPE_CHECKING:
            assert isinstance(data_list, gitlab.GitlabList)

        manager = ProjectIssueManager(self.manager.gitlab, parent=self.manager._parent)

        return RESTObjectList(manager, ProjectIssue, data_list)

    @cli.register_custom_action(cls_names="ProjectMergeRequest")
    @exc.on_http_error(exc.GitlabListError)
    def closes_issues(self, **kwargs: Any) -> RESTObjectList:
+104 −0
Original line number Diff line number Diff line
@@ -9,8 +9,10 @@ import re
import pytest
import responses

from gitlab.base import RESTObjectList
from gitlab.v4.objects import (
    ProjectDeploymentMergeRequest,
    ProjectIssue,
    ProjectMergeRequest,
    ProjectMergeRequestReviewerDetail,
)
@@ -57,6 +59,78 @@ reviewers_content = [
    }
]

related_issues = [
    {
        "id": 1,
        "iid": 1,
        "project_id": 1,
        "title": "Fake Title for Merge Requests via API",
        "description": "Something here",
        "state": "closed",
        "created_at": "2024-05-14T04:01:40.042Z",
        "updated_at": "2024-06-13T05:29:13.661Z",
        "closed_at": "2024-06-13T05:29:13.602Z",
        "closed_by": {
            "id": 2,
            "name": "Sam Bauch",
            "username": "kenyatta_oconnell",
            "state": "active",
            "avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
            "web_url": "http://gitlab.example.com/kenyatta_oconnell",
        },
        "labels": [
            "FakeCategory",
            "fake:ml",
        ],
        "assignees": [
            {
                "id": 2,
                "name": "Sam Bauch",
                "username": "kenyatta_oconnell",
                "state": "active",
                "avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
                "web_url": "http://gitlab.example.com/kenyatta_oconnell",
            }
        ],
        "author": {
            "id": 2,
            "name": "Sam Bauch",
            "username": "kenyatta_oconnell",
            "state": "active",
            "avatar_url": "https://www.gravatar.com/avatar/956c92487c6f6f7616b536927e22c9a0?s=80&d=identicon",
            "web_url": "http://gitlab.example.com//kenyatta_oconnell",
        },
        "type": "ISSUE",
        "assignee": {
            "id": 4459593,
            "username": "fakeuser",
            "name": "Fake User",
            "state": "active",
            "locked": False,
            "avatar_url": "https://example.com/uploads/-/system/user/avatar/4459593/avatar.png",
            "web_url": "https://example.com/fakeuser",
        },
        "user_notes_count": 9,
        "merge_requests_count": 0,
        "upvotes": 1,
        "downvotes": 0,
        "due_date": None,
        "confidential": False,
        "discussion_locked": None,
        "issue_type": "issue",
        "web_url": "https://example.com/fakeorg/fakeproject/-/issues/461536",
        "time_stats": {
            "time_estimate": 0,
            "total_time_spent": 0,
            "human_time_estimate": None,
            "human_total_time_spent": None,
        },
        "task_completion_status": {"count": 0, "completed_count": 0},
        "weight": None,
        "blocking_issues_count": 0,
    }
]


@pytest.fixture
def resp_list_merge_requests():
@@ -93,6 +167,26 @@ def resp_get_merge_request_reviewers():
        yield rsps


@pytest.fixture
def resp_list_merge_requests_related_issues():
    with responses.RequestsMock() as rsps:
        rsps.add(
            method=responses.GET,
            url="http://localhost/api/v4/projects/1/merge_requests/1",
            json=mr_content,
            content_type="application/json",
            status=200,
        )
        rsps.add(
            method=responses.GET,
            url="http://localhost/api/v4/projects/1/merge_requests/1/related_issues",
            json=related_issues,
            content_type="application/json",
            status=200,
        )
        yield rsps


def test_list_project_merge_requests(project, resp_list_merge_requests):
    mrs = project.mergerequests.list()
    assert isinstance(mrs[0], ProjectMergeRequest)
@@ -115,3 +209,13 @@ def test_get_merge_request_reviewers(project, resp_get_merge_request_reviewers):
    assert mr.reviewers[0]["name"] == reviewers_details[0].user["name"]
    assert reviewers_details[0].state == "unreviewed"
    assert reviewers_details[0].created_at == "2022-07-27T17:03:27.684Z"


def test_list_related_issues(project, resp_list_merge_requests_related_issues):
    mr = project.mergerequests.get(1)
    this_mr_related_issues = mr.related_issues()
    the_issue = next(iter(this_mr_related_issues))
    assert isinstance(mr, ProjectMergeRequest)
    assert isinstance(this_mr_related_issues, RESTObjectList)
    assert isinstance(the_issue, ProjectIssue)
    assert the_issue.title == related_issues[0]["title"]