diff --git a/gitlab4j-api/src/main/java/org/gitlab4j/api/DiscussionsApi.java b/gitlab4j-api/src/main/java/org/gitlab4j/api/DiscussionsApi.java index 9dfa82d59..e2add7758 100644 --- a/gitlab4j-api/src/main/java/org/gitlab4j/api/DiscussionsApi.java +++ b/gitlab4j-api/src/main/java/org/gitlab4j/api/DiscussionsApi.java @@ -361,6 +361,50 @@ public Stream getMergeRequestDiscussionsStream(Object projectIdOrPat return (pager.stream()); } + /** + * Get a single discussion for the specified merge request. + * + *
GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/discussions/:discussion_id
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance + * @param mergeRequestIid the internal ID of the merge request + * @param discussionId the ID of the discussion + * @return the Discussion instance specified by discussionId for the specified merge request + * @throws GitLabApiException if any exception occurs during execution + */ + public Discussion getMergeRequestDiscussion(Object projectIdOrPath, Long mergeRequestIid, String discussionId) + throws GitLabApiException { + Response response = get( + Response.Status.OK, + null, + "projects", + getProjectIdOrPath(projectIdOrPath), + "merge_requests", + mergeRequestIid, + "discussions", + discussionId); + return (response.readEntity(Discussion.class)); + } + + /** + * Get an Optional instance of a single discussion for the specified merge request. + * + *
GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/discussions/:discussion_id
+ * + * @param projectIdOrPath projectIdOrPath the project in the form of an Long(ID), String(path), or Project instance + * @param mergeRequestIid the internal ID of the merge request + * @param discussionId the ID of the discussion + * @return an Optional instance with the specified Discussion instance as a value + */ + public Optional getOptionalMergeRequestDiscussion( + Object projectIdOrPath, Long mergeRequestIid, String discussionId) throws GitLabApiException { + try { + return (Optional.ofNullable(getMergeRequestDiscussion(projectIdOrPath, mergeRequestIid, discussionId))); + } catch (GitLabApiException glae) { + return (GitLabApi.createOptionalFromException(glae)); + } + } + /** * Creates a new discussion to a single project merge request. This is similar to creating * a note but other comments (replies) can be added to it later. diff --git a/gitlab4j-api/src/test/java/org/gitlab4j/api/TestMergeRequestDiscussionsApi.java b/gitlab4j-api/src/test/java/org/gitlab4j/api/TestMergeRequestDiscussionsApi.java index 233bb9d32..850fd02ae 100644 --- a/gitlab4j-api/src/test/java/org/gitlab4j/api/TestMergeRequestDiscussionsApi.java +++ b/gitlab4j-api/src/test/java/org/gitlab4j/api/TestMergeRequestDiscussionsApi.java @@ -8,6 +8,7 @@ import static org.mockito.MockitoAnnotations.openMocks; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -38,7 +39,8 @@ public class TestMergeRequestDiscussionsApi implements Constants { @BeforeEach public void setUp() throws Exception { openMocks(this); - response = new MockResponse(Discussion.class, null, "merge-request-discussions.json"); + response = + new MockResponse(Discussion.class, "merge-request-discussion.json", "merge-request-discussions.json"); when(gitLabApi.getApiClient()).thenReturn(gitLabApiClient); when(gitLabApiClient.validateSecretToken(any())).thenReturn(true); when(gitLabApiClient.get(attributeCaptor.capture(), Mockito.any(Object[].class))) @@ -73,4 +75,18 @@ public void testGetMergeRequestDiscussionsByStream() throws Exception { List discussions = stream.collect(Collectors.toList()); assertTrue(compareJson(discussions, "merge-request-discussions.json")); } + + @Test + public void testGetMergeRequestDiscussion() throws Exception { + Discussion discussion = new DiscussionsApi(gitLabApi).getMergeRequestDiscussion(1L, 1L, "1"); + assertNotNull(discussion); + assertTrue(compareJson(discussion, "merge-request-discussion.json")); + } + + @Test + public void testGetOptionalMergeRequestDiscussion() throws Exception { + Optional discussion = new DiscussionsApi(gitLabApi).getOptionalMergeRequestDiscussion(1L, 1L, ""); + assertTrue(discussion.isPresent()); + assertTrue(compareJson(discussion.get(), "merge-request-discussion.json")); + } } diff --git a/gitlab4j-api/src/test/resources/org/gitlab4j/api/merge-request-discussion.json b/gitlab4j-api/src/test/resources/org/gitlab4j/api/merge-request-discussion.json new file mode 100644 index 000000000..98187c41d --- /dev/null +++ b/gitlab4j-api/src/test/resources/org/gitlab4j/api/merge-request-discussion.json @@ -0,0 +1,45 @@ +{ + "id": "6a9c1750b37d513a43987b574953fceb50b03ce7", + "individual_note": false, + "notes": [ + { + "id": 1126, + "type": "DiscussionNote", + "author": { + "id": 1, + "name": "root", + "username": "root", + "state": "active", + "avatar_url": "https://www.gravatar.com/avatar/00afb8fb6ab07c3ee3e9c1f38777e2f4?s=80&d=identicon", + "web_url": "http://localhost:3000/root" + }, + "created_at": "2018-03-03T21:54:39.668Z", + "updated_at": "2018-03-03T21:54:39.668Z", + "system": false, + "noteable_id": 3, + "noteable_type": "Merge request", + "resolved": false, + "resolvable": true + }, + { + "id": 1129, + "type": "DiscussionNote", + "body": "reply to the discussion", + "author": { + "id": 1, + "name": "root", + "username": "root", + "state": "active", + "avatar_url": "https://www.gravatar.com/avatar/00afb8fb6ab07c3ee3e9c1f38777e2f4?s=80&d=identicon", + "web_url": "http://localhost:3000/root" + }, + "created_at": "2018-03-04T13:38:02.127Z", + "updated_at": "2018-03-04T13:38:02.127Z", + "system": false, + "noteable_id": 3, + "noteable_type": "Merge request", + "resolved": false, + "resolvable": true + } + ] +}