diff --git a/jira/client.py b/jira/client.py index dab6ede40..0964d2b2d 100644 --- a/jira/client.py +++ b/jira/client.py @@ -74,6 +74,7 @@ IssueTypeScheme, NotificationScheme, PermissionScheme, + PinnedComment, Priority, PriorityScheme, Project, @@ -5637,3 +5638,36 @@ def move_to_backlog(self, issue_keys: list[str]) -> Response: url = self._get_url("backlog/issue", base=self.AGILE_BASE_URL) payload = {"issues": issue_keys} # TODO: should be list of issues return self._session.post(url, data=json.dumps(payload)) + + @translate_resource_args + def pinned_comments(self, issue: int | str) -> list[PinnedComment]: + """Get a list of pinned comment Resources of the issue provided. + + Args: + issue (Union[int, str]): the issue ID or key to get the comments from + + Returns: + List[PinnedComment] + """ + r_json = self._get_json(f"issue/{issue}/pinned-comments", params={}) + + pinned_comments = [ + PinnedComment(self._options, self._session, raw_comment_json) + for raw_comment_json in r_json + ] + return pinned_comments + + @translate_resource_args + def pin_comment(self, issue: int | str, comment: int | str, pin: bool) -> Response: + """Pin/Unpin a comment on the issue. + + Args: + issue (Union[int, str]): the issue ID or key to get the comments from + comment (Union[int, str]): the comment ID + pin (bool): Pin (True) or Unpin (False) + + Returns: + Response + """ + url = self._get_url("issue/" + str(issue) + "/comment/" + str(comment) + "/pin") + return self._session.put(url, data=str(pin).lower()) diff --git a/jira/resources.py b/jira/resources.py index e72b7f456..29c86e604 100644 --- a/jira/resources.py +++ b/jira/resources.py @@ -69,6 +69,7 @@ class AnyLike: "ServiceDesk", "RequestType", "resource_class_map", + "PinnedComment", ) logging.getLogger("jira").addHandler(logging.NullHandler()) @@ -955,6 +956,21 @@ def update( # type: ignore[override] super().update(async_=async_, jira=jira, notify=notify, fields=data) +class PinnedComment(Resource): + """Pinned comment on an issue.""" + + def __init__( + self, + options: dict[str, str], + session: ResilientSession, + raw: dict[str, Any] | None = None, + ): + Resource.__init__(self, "issue/{0}/pinned-comments", options, session) + if raw: + self._parse_raw(raw) + self.raw: dict[str, Any] = cast(dict[str, Any], self.raw) + + class RemoteLink(Resource): """A link to a remote application from an issue.""" @@ -1659,6 +1675,7 @@ def dict2resource( r"filter/[^/]$": Filter, r"issue/[^/]+$": Issue, r"issue/[^/]+/comment/[^/]+$": Comment, + r"issue/[^/]+/pinned-comments$": PinnedComment, r"issue/[^/]+/votes$": Votes, r"issue/[^/]+/watchers$": Watchers, r"issue/[^/]+/worklog/[^/]+$": Worklog, diff --git a/tests/resources/test_pinned_comment.py b/tests/resources/test_pinned_comment.py new file mode 100644 index 000000000..5170d89f6 --- /dev/null +++ b/tests/resources/test_pinned_comment.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from tests.conftest import JiraTestCase + + +class PinnedCommentTests(JiraTestCase): + def setUp(self): + JiraTestCase.setUp(self) + self.issue_1_key = self.test_manager.project_b_issue1 + self.issue_2_key = self.test_manager.project_b_issue2 + self.issue_3_key = self.test_manager.project_b_issue3 + + def tearDown(self) -> None: + for issue in [self.issue_1_key, self.issue_2_key, self.issue_3_key]: + for comment in self.jira.comments(issue): + comment.delete() + + def test_pincomments(self): + for issue in [self.issue_1_key, self.jira.issue(self.issue_2_key)]: + self.jira.issue(issue) + comment1 = self.jira.add_comment(issue, "First comment") + self.jira.pin_comment(comment1.id, True) + comment2 = self.jira.add_comment(issue, "Second comment") + self.jira.pin_comment(comment2.id, True) + pinned_comments = self.jira.pinned_comments(issue) + assert pinned_comments[0].comment.body == "First comment" + assert pinned_comments[1].comment.body == "Second comment" + self.jira.pin_comment(comment1.id, False) + pinned_comments = self.jira.pinned_comments(issue) + assert len(pinned_comments) == 1 + assert pinned_comments[0].comment.body == "Second comment" + self.jira.pin_comment(comment2.id, False) + pinned_comments = self.jira.pinned_comments(issue) + assert len(pinned_comments) == 0