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/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);