diff --git a/src/main/java/com/spotify/github/v3/clients/GitHubClient.java b/src/main/java/com/spotify/github/v3/clients/GitHubClient.java index 563dbc17..8d0a7fc2 100644 --- a/src/main/java/com/spotify/github/v3/clients/GitHubClient.java +++ b/src/main/java/com/spotify/github/v3/clients/GitHubClient.java @@ -97,6 +97,8 @@ public class GitHubClient { new TypeReference<>() {}; static final TypeReference> LIST_PR_TYPE_REFERENCE = new TypeReference<>() {}; + static final TypeReference> + LIST_PR_COMMENT_TYPE_REFERENCE = new TypeReference<>() {}; static final TypeReference> LIST_BRANCHES = new TypeReference<>() {}; static final TypeReference> LIST_REFERENCES = new TypeReference<>() {}; static final TypeReference> LIST_REPOSITORY_INVITATION = @@ -109,8 +111,7 @@ public class GitHubClient { static final TypeReference> LIST_PENDING_TEAM_INVITATIONS = new TypeReference<>() {}; - static final TypeReference> LIST_FILE_ITEMS = - new TypeReference<>() {}; + static final TypeReference> LIST_FILE_ITEMS = new TypeReference<>() {}; private static final String GET_ACCESS_TOKEN_URL = "app/installations/%s/access_tokens"; @@ -1090,7 +1091,8 @@ private CompletableFuture generateInstallationToken( if (response.bodyString() == null) { throw new RuntimeException( String.format( - "Got empty response body when getting an access token from GitHub, HTTP status was: %s", + "Got empty response body when getting an access token from GitHub, HTTP" + + " status was: %s", response.statusMessage())); } final String text = response.bodyString(); diff --git a/src/main/java/com/spotify/github/v3/clients/PullRequestClient.java b/src/main/java/com/spotify/github/v3/clients/PullRequestClient.java index 6a8ef8e3..1316a5e9 100644 --- a/src/main/java/com/spotify/github/v3/clients/PullRequestClient.java +++ b/src/main/java/com/spotify/github/v3/clients/PullRequestClient.java @@ -23,6 +23,7 @@ import static com.spotify.github.v3.clients.GitHubClient.IGNORE_RESPONSE_CONSUMER; import static com.spotify.github.v3.clients.GitHubClient.LIST_COMMIT_TYPE_REFERENCE; import static com.spotify.github.v3.clients.GitHubClient.LIST_FILE_ITEMS; +import static com.spotify.github.v3.clients.GitHubClient.LIST_PR_COMMENT_TYPE_REFERENCE; import static com.spotify.github.v3.clients.GitHubClient.LIST_PR_TYPE_REFERENCE; import static com.spotify.github.v3.clients.GitHubClient.LIST_REVIEW_REQUEST_TYPE_REFERENCE; import static com.spotify.github.v3.clients.GitHubClient.LIST_REVIEW_TYPE_REFERENCE; @@ -63,6 +64,7 @@ public class PullRequestClient { private static final String PR_NUMBER_TEMPLATE = "/repos/%s/%s/pulls/%s"; private static final String PR_COMMITS_TEMPLATE = "/repos/%s/%s/pulls/%s/commits"; private static final String PR_REVIEWS_TEMPLATE = "/repos/%s/%s/pulls/%s/reviews"; + private static final String PR_COMMENTS_TEMPLATE = "/repos/%s/%s/pulls/%s/comments"; private static final String PR_CHANGED_FILES_TEMPLATE = "/repos/%s/%s/pulls/%s/files"; private static final String PR_REVIEW_REQUESTS_TEMPLATE = "/repos/%s/%s/pulls/%s/requested_reviewers"; @@ -467,6 +469,17 @@ private CompletableFuture> list(final String parameterPath return github.request(path, LIST_PR_TYPE_REFERENCE); } + /** + * List pull request review comments. + * + * @param prNumber pull request number + * @return iterator of comments + */ + public Iterator> listComments(final long prNumber) { + final String path = String.format(PR_COMMENTS_TEMPLATE, owner, repo, prNumber); + return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_PR_COMMENT_TYPE_REFERENCE)); + } + /** * Creates a reply to a pull request review comment. * diff --git a/src/test/java/com/spotify/github/v3/clients/PullRequestClientTest.java b/src/test/java/com/spotify/github/v3/clients/PullRequestClientTest.java index 10a36dc0..599af94c 100644 --- a/src/test/java/com/spotify/github/v3/clients/PullRequestClientTest.java +++ b/src/test/java/com/spotify/github/v3/clients/PullRequestClientTest.java @@ -438,4 +438,30 @@ void testChangedFiles() throws IOException { assertEquals(actualFiles.get(0).filename(), expectedFiles.get(0).filename()); assertEquals(actualFiles.get(1).filename(), expectedFiles.get(1).filename()); } + + @Test + public void testListComments() throws Throwable { + final String expectedBody = "[" + getFixture("pull_request_review_comment_reply.json") + "]"; + + final String pageLink = + "; rel=\"first\""; + + final HttpResponse firstPageResponse = createMockResponse(pageLink, expectedBody); + + when(mockGithub.request("/repos/owner/repo/pulls/1/comments")) + .thenReturn(completedFuture(firstPageResponse)); + + when(mockGithub.json()).thenReturn(github.json()); + + final PullRequestClient pullRequestClient = + PullRequestClient.create(mockGithub, "owner", "repo"); + + final Iterable> pageIterator = () -> pullRequestClient.listComments(1L); + List comments = Async.streamFromPaginatingIterable(pageIterator).collect(toList()); + + assertEquals(1, comments.size()); + assertThat(comments.get(0).body(), is("Great stuff!")); + assertThat(comments.get(0).id(), is(10L)); + assertThat(comments.get(0).user().login(), is("octocat")); + } }