diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index db302379..1439ea00 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -20,7 +20,7 @@ jobs:
java-version: 11
distribution: corretto
cache: maven
- server-id: ossrh # Value of distributionManagement.repository.id field of pom.xml
+ server-id: central # Value of distributionManagement.repository.id field of pom.xml
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
settings-path: ${{ github.workspace }} # Location for settings.xml file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7a49889b..af4ce57a 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,7 +5,7 @@ alternative to the GitHub API.
## Getting Started
-The Github Java Clients's [open issues are here](https://github.com/github-java-client/github-java-client/issues).
+The Github Java Clients's [open issues are here](https://github.com/spotify/github-java-client/issues).
In time, we'll tag issues that would make a good first pull request for new contributors. An easy
way to get started helping the project is to *file an issue*. Issues can include bugs to fix,
features to add, or documentation that looks outdated.
@@ -39,4 +39,4 @@ feedback for changes that would be required.
[/orgs/{org}/teams/{team_slug}](https://docs.github.com/en/rest/teams/teams?apiVersion=2022-11-28#list-teams) endpoint
- We operate a monkey see, monkey do approach to this library. We understand that there are some inconsistencies in the library
in terms of how the tests and/or endpoints are written but we, with your help, are working on creating a more consistent codebase.
-- All bug fixes and new features need to be fully tested.
\ No newline at end of file
+- All bug fixes and new features need to be fully tested.
diff --git a/README.md b/README.md
index c4463be5..9d37526a 100644
--- a/README.md
+++ b/README.md
@@ -21,11 +21,13 @@ You can find this library in [maven central repository](https://mvnrepository.co
Include the latest version of github-client into your project:
In Maven:
+
```xml
+
- com.spotify
- github-client
- version
+ com.spotify
+ github-client
+ version
```
@@ -43,10 +45,10 @@ To authenticate as a GitHub App, you must provide a private key and the App ID,
```java
final GitHubClient githubClient =
- GitHubClient.create(
- URI.create("https://api.github.com/"),
- new File("/path-to-the/private-key.pem"),
- APP_ID);
+ GitHubClient.create(
+ URI.create("https://api.github.com/"),
+ new File("/path-to-the/private-key.pem"),
+ APP_ID);
```
Then, you can scope the client for a specific Installation ID, to do the operations at the installation level.
@@ -59,12 +61,16 @@ final GitHubClient scopedClient = GitHubClient.scopeForInstallationId(githubClie
It is also possible to provide the installation to the root client.
-Refer to [GitHub App Authentication Guide](https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/) for more information.
+Refer
+to [GitHub App Authentication Guide](https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/)
+for more information.
## Usage
-This library attempts to mirror the structure of GitHub API endpoints. As an example, to get details of a Commit, there is
-the `GET /repos/:owner/:repo/commits` API call, under the `repos` API. Therefore, the `getCommit` method lives in the RepositoryClient.
+This library attempts to mirror the structure of GitHub API endpoints. As an example, to get details of a Commit, there
+is
+the `GET /repos/:owner/:repo/commits` API call, under the `repos` API. Therefore, the `getCommit` method lives in the
+RepositoryClient.
```java
final RepositoryClient repositoryClient = githubClient.createRepositoryClient("my-org", "my-repo");
@@ -79,8 +85,9 @@ final ChecksClient checksClient = repositoryClient.createChecksApiClient();
checksClient.createCheckRun(CHECK_RUN_REQUEST);
final IssueClient issueClient = repositoryClient.createIssueClient();
-issueClient.createComment(ISSUE_ID, "comment body")
- .thenAccept(comment -> log.info("created comment " + comment.htmlUrl()));
+issueClient
+ .createComment(ISSUE_ID, "comment body")
+ .thenAccept(comment ->log.info("created comment "+comment.htmlUrl()));
```
@@ -88,7 +95,7 @@ And endpoints related to teams and memberships are nested under the Organisation
```java
final TeamClient teamClient = organisationClient.createTeamClient();
- teamClient.getMembership("username");
+teamClient.getMembership("username");
```
## Tracing
@@ -144,8 +151,12 @@ This project uses Maven. To run the tests locally, just run:
mvn clean verify
```
-If you are a maintainer, you can release a new version by just triggering the workflow
-[prepare-release](./.github/workflows/prepare-release.yml) through the
+### Maintainers
+
+#### Publishing a new version
+
+If you are a maintainer, you can release a new version by just triggering the workflow
+[prepare-release](./.github/workflows/prepare-release.yml) through the
[web UI](https://github.com/spotify/github-java-client/actions/workflows/prepare-release.yml).
- Select whether the new release should be a `major`, `minor` or `patch` release
@@ -156,15 +167,56 @@ If you are a maintainer, you can release a new version by just triggering the wo
[github-release](https://github.com/spotify/github-java-client/actions/workflows/release-on-github.yml)
workflow with the automatically created tag
+The `prepare-release` workflow will also update the snapshot version in the `pom.xml` file to the next version. The
+version which will be published to Maven Central will be the one specified in the `pom.xml` file (without the
+`-SNAPSHOT` suffix).
+
+#### Updating the GPG signing key
+
+If you need to update the GPG signing key used for signing the releases when the existing key expires, you can do so by
+following these steps:
+
+1. Generate a new GPG key pair or use an existing one.
+ If you don't have a GPG key pair, you can generate one using the following command:
+ ```bash
+ gpg --full-generate-key
+ ```
+ Follow the prompts to create your key pair. Make sure to remember the passphrase you set.
+2. List your GPG keys to find the key ID:
+ ```bash
+ gpg --list-keys
+ ```
+ Look for the `pub` line, which will show the key ID in the format `XXXXXXXX`.
+3. Export the public key to a file:
+ ```bash
+ gpg --armor --export > publickey.asc
+ ```
+4. export the private key to a file:
+ ```bash
+ gpg --armor --export-secret-key > privatekey.asc
+ ```
+5. Upload the private key to the GitHub repository secrets in `GPG_PRIVATE_KEY` and paste the contents of
+ `privatekey.asc`.
+6. Update the passphrase in the `GPG_PASSPHRASE` secret with the passphrase you set when generating the key.
+7. Upload the public key to the OpenGpg key server at https://keys.openpgp.org/
+8. Make sure to verify the public key with your email address on OpenGPG and that it is available on the key server.
+9. Make sure that the release workflow is configured to use the `GPG_PRIVATE_KEY` and `GPG_PASSPHRASE` secrets.
+10. Run the release workflow to publish a new version of the library.
+
## Notes about maturity
This module was created after existing libraries were evaluated and dismissed, and we found that we were writing similar
-code in multiple projects. As such, it at least initially only contains enough functionality for our internal requirements
-which reflects that we were working on build system integration with the GitHub pull requests. It has been widely used for 4+
-years. It's important to notice that it does not cover all GitHub v3 API. Adding missing endpoints should be very straightforward.
+code in multiple projects. As such, it at least initially only contains enough functionality for our internal
+requirements
+which reflects that we were working on build system integration with the GitHub pull requests. It has been widely used
+for 4+
+years. It's important to notice that it does not cover all GitHub v3 API. Adding missing endpoints should be very
+straightforward.
Pull Requests are welcome.
## Code of conduct
-This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to honor this code.
+
+This project adheres to the [Open Code of Conduct][code-of-conduct]. By participating, you are expected to honor this
+code.
[code-of-conduct]: https://github.com/spotify/code-of-conduct/blob/master/code-of-conduct.md
diff --git a/pom.xml b/pom.xml
index 6f35a659..b8138ade 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,9 +1,9 @@
4.0.0
-
+ github-java-client
github-client
- 0.4.9
+ 0.4.13-SNAPSHOT
com.spotify
@@ -23,7 +23,7 @@
scm:git:https://github.com/spotify/github-java-client.git
scm:git:git@github.com:spotify/github-java-client.git
scm:https://github.com/spotify/github-java-client/
- v0.4.9
+ v0.3.7
@@ -33,12 +33,12 @@
- ossrh
- https://oss.sonatype.org/content/repositories/snapshots
+ central
+ https://central.sonatype.com/repository/maven-snapshots/
- ossrh
- https://oss.sonatype.org/service/local/staging/deploy/maven2/
+ central
+ https://central.sonatype.com/repository/maven-releases/
@@ -67,7 +67,7 @@
UTF-8
UTF-8
- 1750930802
+ 1754383033
spotbugsexclude.xml
error
checkstyle.xml
@@ -286,60 +286,60 @@
- coverage
-
-
-
- org.jacoco
- jacoco-maven-plugin
- 0.8.5
-
-
-
-
- **/*Builder*
- **/*Immutable*
- **/*_Factory*
- **/*_*Factory*.*
- **/generated-sources*.*
-
-
-
- BUNDLE
-
-
- INSTRUCTION
- COVEREDRATIO
- 0.60
-
-
-
-
-
-
-
- pre-test
-
- prepare-agent
-
-
-
- default-check
-
- check
-
-
-
- post-unit-test
- test
-
- report
-
-
-
-
-
-
+ coverage
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.5
+
+
+
+
+ **/*Builder*
+ **/*Immutable*
+ **/*_Factory*
+ **/*_*Factory*.*
+ **/generated-sources*.*
+
+
+
+ BUNDLE
+
+
+ INSTRUCTION
+ COVEREDRATIO
+ 0.60
+
+
+
+
+
+
+
+ pre-test
+
+ prepare-agent
+
+
+
+ default-check
+
+ check
+
+
+
+ post-unit-test
+ test
+
+ report
+
+
+
+
+
+
@@ -359,9 +359,11 @@
sign
+
--pinentry-mode
loopback
+ --no-tty
@@ -381,22 +383,21 @@
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.6.13
+ org.sonatype.central
+ central-publishing-maven-plugin
+ 0.8.0
true
- ossrh
- https://oss.sonatype.org/
- true
- 600000
- 600000
+ central
+ github-java-client
+ true
+ published
-
+
diff --git a/src/main/java/com/spotify/github/v3/clients/IssueClient.java b/src/main/java/com/spotify/github/v3/clients/IssueClient.java
index ae9bdec2..7db3a41b 100644
--- a/src/main/java/com/spotify/github/v3/clients/IssueClient.java
+++ b/src/main/java/com/spotify/github/v3/clients/IssueClient.java
@@ -43,7 +43,9 @@ public class IssueClient {
static final String COMMENTS_URI_TEMPLATE = "/repos/%s/%s/issues/comments";
static final String COMMENTS_URI_ID_TEMPLATE = "/repos/%s/%s/issues/comments/%s";
static final String COMMENTS_REACTION_TEMPLATE = "/repos/%s/%s/issues/comments/%s/reactions";
- static final String COMMENTS_REACTION_ID_TEMPLATE = "/repos/%s/%s/issues/%s/reactions/%s";
+ static final String COMMENTS_REACTION_ID_TEMPLATE = "/repos/%s/%s/issues/comments/%s/reactions/%s";
+ static final String ISSUES_REACTION_TEMPLATE = "/repos/%s/%s/issues/%s/reactions";
+ static final String ISSUES_REACTION_ID_TEMPLATE = "/repos/%s/%s/issues/%s/reactions/%s";
static final String ISSUES_URI_ID_TEMPLATE = "/repos/%s/%s/issues/%s";
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@@ -53,7 +55,6 @@ public class IssueClient {
/**
* Constructs an IssueClient.
- *
* @param github the GitHub client
* @param owner the repository owner
* @param repo the repository name
@@ -260,14 +261,14 @@ public CompletableFuture createCommentReaction(
* href="https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28#delete-an-issue-comment-reaction">List
* reactions for an issue comment
*
- * @param issueNumber the issue number
+ * @param commentId the comment id
* @param reactionId the reaction id
* @return a CompletableFuture containing the HTTP response
*/
public CompletableFuture deleteCommentReaction(
- final long issueNumber, final long reactionId) {
+ final long commentId, final long reactionId) {
final String path =
- String.format(COMMENTS_REACTION_ID_TEMPLATE, owner, repo, issueNumber, reactionId);
+ String.format(COMMENTS_REACTION_ID_TEMPLATE, owner, repo, commentId, reactionId);
return github.delete(path);
}
@@ -284,4 +285,35 @@ public GithubPageIterator listCommentReaction(final long commen
return new GithubPageIterator<>(
new GithubPage<>(github, path, LIST_COMMENT_REACTION_TYPE_REFERENCE));
}
+
+ /**
+ * Creates a reaction on an issue.
+ *
+ * @param issueNumber the issue number
+ * @param reaction the reaction content
+ * @return a CompletableFuture containing the created reaction
+ */
+ public CompletableFuture createIssueReaction(
+ final long issueNumber, final CommentReactionContent reaction) {
+ final String path = String.format(ISSUES_REACTION_TEMPLATE, owner, repo, issueNumber);
+ final String requestBody =
+ github.json().toJsonUnchecked(ImmutableMap.of("content", reaction.toString()));
+ return github.post(path, requestBody, CommentReaction.class);
+ }
+
+ /**
+ * Deletes a reaction on an issue. See Delete
+ * an issue reaction
+ *
+ * @param issueNumber the issue number
+ * @param reactionId the reaction id
+ * @return a CompletableFuture containing the HTTP response
+ */
+ public CompletableFuture deleteIssueReaction(
+ final long issueNumber, final long reactionId) {
+ final String path =
+ String.format(ISSUES_REACTION_ID_TEMPLATE, owner, repo, issueNumber, reactionId);
+ return github.delete(path);
+ }
}
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 e54f9180..36d2783e 100644
--- a/src/main/java/com/spotify/github/v3/clients/PullRequestClient.java
+++ b/src/main/java/com/spotify/github/v3/clients/PullRequestClient.java
@@ -27,8 +27,8 @@
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;
-import static java.util.Objects.isNull;
import static java.lang.Math.toIntExact;
+import static java.util.Objects.isNull;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
@@ -66,6 +66,8 @@ 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_REVIEW_COMMENTS_TEMPLATE =
+ "/repos/%s/%s/pulls/%s/reviews/%s/comments";
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 =
@@ -192,14 +194,19 @@ public CompletableFuture> listCommits(final int prNumber) {
public CompletableFuture> listCommits(final long prNumber) {
final String path = String.format(PR_COMMITS_TEMPLATE, owner, repo, prNumber);
log.debug("Fetching pull request commits from " + path);
- return github.request(path).thenApply(
- response -> Json.create().fromJsonUncheckedNotNull(response.bodyString(), LIST_COMMIT_TYPE_REFERENCE));
+ return github
+ .request(path)
+ .thenApply(
+ response ->
+ Json.create()
+ .fromJsonUncheckedNotNull(response.bodyString(), LIST_COMMIT_TYPE_REFERENCE));
}
public Iterator> listCommits(final long prNumber, final int itemsPerPage) {
final String path = String.format(PR_COMMITS_TEMPLATE, owner, repo, prNumber);
- return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_COMMIT_TYPE_REFERENCE, itemsPerPage));
+ return new GithubPageIterator<>(
+ new GithubPage<>(github, path, LIST_COMMIT_TYPE_REFERENCE, itemsPerPage));
}
/**
@@ -249,7 +256,8 @@ public Iterator> listReviews(final int prNumber, final int ite
public Iterator> listReviews(final long prNumber, final long itemsPerPage) {
final String path = String.format(PR_REVIEWS_TEMPLATE, owner, repo, prNumber);
log.debug("Fetching pull request reviews from " + path);
- return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_REVIEW_TYPE_REFERENCE, toIntExact(itemsPerPage)));
+ return new GithubPageIterator<>(
+ new GithubPage<>(github, path, LIST_REVIEW_TYPE_REFERENCE, toIntExact(itemsPerPage)));
}
/**
@@ -506,4 +514,17 @@ public CompletableFuture createCommentReply(
log.debug("Creating reply to PR comment: " + path);
return github.post(path, jsonPayload, Comment.class);
}
+
+ /**
+ * List pull request review comments for a specific review with pagination.
+ *
+ * @param prNumber pull request number
+ * @param reviewId the ID of the review
+ * @return iterator of comments for the review
+ * @see "https://docs.github.com/en/rest/pulls/comments#list-comments-for-a-pull-request-review"
+ */
+ public Iterator> listReviewComments(final long prNumber, final long reviewId) {
+ final String path = String.format(PR_REVIEW_COMMENTS_TEMPLATE, owner, repo, prNumber, reviewId);
+ return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_PR_COMMENT_TYPE_REFERENCE));
+ }
}
diff --git a/src/test/java/com/spotify/github/v3/clients/IssueClientTest.java b/src/test/java/com/spotify/github/v3/clients/IssueClientTest.java
index 1007e8b7..65ac3054 100644
--- a/src/test/java/com/spotify/github/v3/clients/IssueClientTest.java
+++ b/src/test/java/com/spotify/github/v3/clients/IssueClientTest.java
@@ -217,15 +217,15 @@ public void testCreateIssueCommentReaction(CommentReactionContent reaction) {
@Test
public void testDeleteIssueCommentReaction() {
- long issueNumber = 42;
+ long commentId = 42;
long reactionId = 385825;
final String path =
- format(COMMENTS_REACTION_ID_TEMPLATE, "someowner", "somerepo", issueNumber, reactionId);
+ format(COMMENTS_REACTION_ID_TEMPLATE, "someowner", "somerepo", commentId, reactionId);
HttpResponse mockResponse = mock(HttpResponse.class);
when(mockResponse.statusCode()).thenReturn(204);
when(github.delete(eq(path))).thenReturn(completedFuture(mockResponse));
- final var response = issueClient.deleteCommentReaction(issueNumber, reactionId).join();
+ final var response = issueClient.deleteCommentReaction(commentId, reactionId).join();
assertThat(response.statusCode(), is(204));
assertThat(response, is(mockResponse));
@@ -271,6 +271,49 @@ public void testListIssueCommentReaction() throws IOException {
verify(github, atLeastOnce()).request(eq(path));
}
+ @ParameterizedTest
+ @EnumSource(CommentReactionContent.class)
+ public void testCreateIssueReaction(CommentReactionContent reaction) {
+ long issueNumber = 42;
+ final CompletableFuture reactionResponse =
+ completedFuture(
+ ImmutableCommentReaction.builder()
+ .id(123L)
+ .content(reaction)
+ .user(ImmutableUser.builder().login("octocat").build())
+ .build());
+ final String path = format(ISSUES_REACTION_TEMPLATE, "someowner", "somerepo", issueNumber);
+ final String requestBody =
+ github.json().toJsonUnchecked(ImmutableMap.of("content", reaction.toString()));
+ when(github.post(eq(path), eq(requestBody), eq(CommentReaction.class)))
+ .thenReturn(reactionResponse);
+
+ final var issueReaction = issueClient.createIssueReaction(issueNumber, reaction).join();
+
+ assertThat(issueReaction.id(), is(123L));
+ assertNotNull(issueReaction.user());
+ assertThat(issueReaction.user().login(), is("octocat"));
+ assertThat(issueReaction.content().toString(), is(reaction.toString()));
+ verify(github, times(1)).post(eq(path), eq(requestBody), eq(CommentReaction.class));
+ }
+
+ @Test
+ public void testDeleteIssueReaction() {
+ long issueNumber = 42;
+ long reactionId = 385825;
+ final String path =
+ format(ISSUES_REACTION_ID_TEMPLATE, "someowner", "somerepo", issueNumber, reactionId);
+ HttpResponse mockResponse = mock(HttpResponse.class);
+ when(mockResponse.statusCode()).thenReturn(204);
+ when(github.delete(eq(path))).thenReturn(completedFuture(mockResponse));
+
+ final var response = issueClient.deleteIssueReaction(issueNumber, reactionId).join();
+
+ assertThat(response.statusCode(), is(204));
+ assertThat(response, is(mockResponse));
+ verify(github, times(1)).delete(eq(path));
+ }
+
@Test
public void testGetIssueNoIssue() {
final String path = format(ISSUES_URI_ID_TEMPLATE, "someowner", "somerepo", 2);
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 1edaa80c..a203a602 100644
--- a/src/test/java/com/spotify/github/v3/clients/PullRequestClientTest.java
+++ b/src/test/java/com/spotify/github/v3/clients/PullRequestClientTest.java
@@ -74,7 +74,8 @@
public class PullRequestClientTest {
private static final String MOCK_GITHUB_HOST = "bogus.host";
- private static final URI MOCK_GITHUB_URI = URI.create(String.format("http://%s/api/v3", MOCK_GITHUB_HOST));
+ private static final URI MOCK_GITHUB_URI =
+ URI.create(String.format("http://%s/api/v3", MOCK_GITHUB_HOST));
private static final URI MOCK_GITHUB_URI_GQL = MOCK_GITHUB_URI.resolve("/graphql");
private static final String PR_CHANGED_FILES_TEMPLATE = "/repos/%s/%s/pulls/%s/files";
@@ -89,9 +90,7 @@ private static String getFixture(String resource) throws IOException {
@BeforeEach
public void setUp() {
client = mock(OkHttpClient.class);
- github =
- GitHubClient.create(
- client,MOCK_GITHUB_URI, MOCK_GITHUB_URI_GQL, "token");
+ github = GitHubClient.create(client, MOCK_GITHUB_URI, MOCK_GITHUB_URI_GQL, "token");
mockGithub = mock(GitHubClient.class);
}
@@ -429,7 +428,8 @@ void testChangedFiles() throws IOException {
final HttpResponse firstPageResponse = createMockResponse(pageLink, expectedBody);
- when(mockGithub.request(format(PR_CHANGED_FILES_TEMPLATE + "?per_page=30", "owner", "repo", "1")))
+ when(mockGithub.request(
+ format(PR_CHANGED_FILES_TEMPLATE + "?per_page=30", "owner", "repo", "1")))
.thenReturn(completedFuture(firstPageResponse));
when(mockGithub.json()).thenReturn(github.json());
@@ -449,7 +449,8 @@ public void testListComments() throws Throwable {
final String expectedBody = "[" + getFixture("pull_request_review_comment_reply.json") + "]";
final String pageLink =
- "; rel=\"first\"";
+ ";"
+ + " rel=\"first\"";
final HttpResponse firstPageResponse = createMockResponse(pageLink, expectedBody);
@@ -470,21 +471,52 @@ public void testListComments() throws Throwable {
assertThat(comments.get(0).user().login(), is("octocat"));
}
+ @Test
+ public void testListReviewComments() 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/reviews/123/comments?per_page=30"))
+ .thenReturn(completedFuture(firstPageResponse));
+
+ when(mockGithub.json()).thenReturn(github.json());
+
+ final PullRequestClient pullRequestClient =
+ PullRequestClient.create(mockGithub, "owner", "repo");
+
+ final Iterable> pageIterator =
+ () -> pullRequestClient.listReviewComments(1L, 123L);
+ 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"));
+ }
+
@Test
public void listCommitsWithoutSpecifyingPages() throws Exception {
// Given
final int COMMIT_PER_PAGE = 30;
final String firstPageLink =
- "; rel=\"next\", ; rel=\"last\"";
+ "; rel=\"next\","
+ + " ; rel=\"last\"";
final String firstPageBody =
- Resources.toString(getResource(this.getClass(), "pull_request_commits_page1.json"), defaultCharset());
+ Resources.toString(
+ getResource(this.getClass(), "pull_request_commits_page1.json"), defaultCharset());
final HttpResponse firstPageResponse = createMockResponse(firstPageLink, firstPageBody);
when(mockGithub.request("/repos/owner/repo/pulls/1/commits"))
.thenReturn(completedFuture(firstPageResponse));
- final PullRequestClient pullRequestClient = PullRequestClient.create(mockGithub, "owner", "repo");
+ final PullRequestClient pullRequestClient =
+ PullRequestClient.create(mockGithub, "owner", "repo");
// When
final List commits = pullRequestClient.listCommits(1L).get();
@@ -492,7 +524,8 @@ public void listCommitsWithoutSpecifyingPages() throws Exception {
// Then
assertThat(commits.size(), is(COMMIT_PER_PAGE));
assertThat(
- commits.get(COMMIT_PER_PAGE - 1).commit().tree().sha(), is("219cb4c1ffada21259876d390df1a85767481617"));
+ commits.get(COMMIT_PER_PAGE - 1).commit().tree().sha(),
+ is("219cb4c1ffada21259876d390df1a85767481617"));
}
@Test
@@ -500,30 +533,36 @@ public void listCommitsSpecifyingPages() throws Exception {
// Given
final int COMMIT_PER_PAGE = 30;
- final String firstPageLink = String.format(
- "<%s/repos/owner/repo/pulls/1/commits?page=2&per_page=30>; rel=\"next\", <%s/repos/owner/repo/pulls/1/commits?page=3&per_page=30>; rel=\"last\"",
- MOCK_GITHUB_URI,
- MOCK_GITHUB_URI);
+ final String firstPageLink =
+ String.format(
+ "<%s/repos/owner/repo/pulls/1/commits?page=2&per_page=30>; rel=\"next\","
+ + " <%s/repos/owner/repo/pulls/1/commits?page=3&per_page=30>; rel=\"last\"",
+ MOCK_GITHUB_URI, MOCK_GITHUB_URI);
final String firstPageBody =
- Resources.toString(getResource(this.getClass(), "pull_request_commits_page1.json"), defaultCharset());
+ Resources.toString(
+ getResource(this.getClass(), "pull_request_commits_page1.json"), defaultCharset());
final HttpResponse firstPageResponse = createMockResponse(firstPageLink, firstPageBody);
- final String secondPageLink = String.format(
- "<%s/repos/owner/repo/pulls/1/commits?page=1&per_page=30>; rel=\"prev\", <%s/repos/owner/repo/pulls/1/commits?page=3&per_page=30>; rel=\"next\", <%s/repos/owner/repo/pulls/1/commits?page=3&per_page=30>; rel=\"last\", <%s/repos/owner/repo/pulls/1/commits?page=1&per_page=30>; rel=\"first\"",
- MOCK_GITHUB_URI,
- MOCK_GITHUB_URI,
- MOCK_GITHUB_URI,
- MOCK_GITHUB_URI);
+ final String secondPageLink =
+ String.format(
+ "<%s/repos/owner/repo/pulls/1/commits?page=1&per_page=30>; rel=\"prev\","
+ + " <%s/repos/owner/repo/pulls/1/commits?page=3&per_page=30>; rel=\"next\","
+ + " <%s/repos/owner/repo/pulls/1/commits?page=3&per_page=30>; rel=\"last\","
+ + " <%s/repos/owner/repo/pulls/1/commits?page=1&per_page=30>; rel=\"first\"",
+ MOCK_GITHUB_URI, MOCK_GITHUB_URI, MOCK_GITHUB_URI, MOCK_GITHUB_URI);
final String secondPageBody =
- Resources.toString(getResource(this.getClass(), "pull_request_commits_page2.json"), defaultCharset());
+ Resources.toString(
+ getResource(this.getClass(), "pull_request_commits_page2.json"), defaultCharset());
final HttpResponse secondPageResponse = createMockResponse(secondPageLink, secondPageBody);
final String thirdPageLink =
- String.format("<%s/repos/owner/repo/pulls/1/commits?page=2&per_page=30>; rel=\"prev\", <%s/repos/owner/repo/pulls/1/commits?page=1&per_page=30>; rel=\"first\"",
- MOCK_GITHUB_URI,
- MOCK_GITHUB_URI);
+ String.format(
+ "<%s/repos/owner/repo/pulls/1/commits?page=2&per_page=30>; rel=\"prev\","
+ + " <%s/repos/owner/repo/pulls/1/commits?page=1&per_page=30>; rel=\"first\"",
+ MOCK_GITHUB_URI, MOCK_GITHUB_URI);
final String thirdPageBody =
- Resources.toString(getResource(this.getClass(), "pull_request_commits_page3.json"), defaultCharset());
+ Resources.toString(
+ getResource(this.getClass(), "pull_request_commits_page3.json"), defaultCharset());
final HttpResponse thirdPageResponse = createMockResponse(thirdPageLink, thirdPageBody);
when(mockGithub.urlFor("")).thenReturn(MOCK_GITHUB_URI.toString());
@@ -537,15 +576,19 @@ public void listCommitsSpecifyingPages() throws Exception {
when(mockGithub.request("/repos/owner/repo/pulls/1/commits?page=3&per_page=30"))
.thenReturn(completedFuture(thirdPageResponse));
- final PullRequestClient pullRequestClient = PullRequestClient.create(mockGithub, "owner", "repo");
+ final PullRequestClient pullRequestClient =
+ PullRequestClient.create(mockGithub, "owner", "repo");
// When
- final Iterable> pageIterator = () -> pullRequestClient.listCommits(1L, 30);
- final List commits = Async.streamFromPaginatingIterable(pageIterator).collect(toList());
+ final Iterable> pageIterator =
+ () -> pullRequestClient.listCommits(1L, 30);
+ final List commits =
+ Async.streamFromPaginatingIterable(pageIterator).collect(toList());
// Then
assertThat(commits.size(), is(COMMIT_PER_PAGE * 3));
assertThat(
- commits.get(COMMIT_PER_PAGE - 1).commit().tree().sha(), is("219cb4c1ffada21259876d390df1a85767481617"));
+ commits.get(COMMIT_PER_PAGE - 1).commit().tree().sha(),
+ is("219cb4c1ffada21259876d390df1a85767481617"));
}
}