Skip to content

Commit c220015

Browse files
authored
expose method for fetching issue by id (#213)
1 parent db129cf commit c220015

File tree

3 files changed

+107
-5
lines changed

3 files changed

+107
-5
lines changed

src/main/java/com/spotify/github/v3/clients/IssueClient.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.google.common.collect.ImmutableMap;
2727
import com.spotify.github.async.AsyncPage;
2828
import com.spotify.github.v3.comment.Comment;
29+
import com.spotify.github.v3.issues.Issue;
2930
import java.lang.invoke.MethodHandles;
3031
import java.util.Iterator;
3132
import java.util.concurrent.CompletableFuture;
@@ -38,6 +39,7 @@ public class IssueClient {
3839
static final String COMMENTS_URI_NUMBER_TEMPLATE = "/repos/%s/%s/issues/%s/comments";
3940
static final String COMMENTS_URI_TEMPLATE = "/repos/%s/%s/issues/comments";
4041
static final String COMMENTS_URI_ID_TEMPLATE = "/repos/%s/%s/issues/comments/%s";
42+
static final String ISSUES_URI_ID_TEMPLATE = "/repos/%s/%s/issues/%s";
4143
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
4244

4345
private final GitHubClient github;
@@ -125,4 +127,14 @@ public CompletableFuture<Void> deleteComment(final int id) {
125127
private Iterator<AsyncPage<Comment>> listComments(final String path) {
126128
return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_COMMENT_TYPE_REFERENCE));
127129
}
130+
131+
/***
132+
* Get issue by id
133+
*
134+
* @param id
135+
* @return the Issue for the given id if exists.
136+
*/
137+
public CompletableFuture<Issue> getIssue(final int id) {
138+
return github.request(String.format(ISSUES_URI_ID_TEMPLATE, owner, repo, id), Issue.class);
139+
}
128140
}

src/test/java/com/spotify/github/v3/clients/IssueClientTest.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@
2323
import static com.google.common.io.Resources.getResource;
2424
import static com.spotify.github.FixtureHelper.loadFixture;
2525
import static com.spotify.github.v3.clients.IssueClient.COMMENTS_URI_NUMBER_TEMPLATE;
26+
import static com.spotify.github.v3.clients.IssueClient.ISSUES_URI_ID_TEMPLATE;
2627
import static com.spotify.github.v3.clients.MockHelper.createMockResponse;
2728
import static java.lang.String.format;
2829
import static java.nio.charset.Charset.defaultCharset;
2930
import static java.util.concurrent.CompletableFuture.completedFuture;
31+
import static java.util.concurrent.CompletableFuture.failedFuture;
3032
import static java.util.stream.Collectors.toList;
3133
import static org.hamcrest.MatcherAssert.assertThat;
3234
import static org.hamcrest.core.Is.is;
35+
import static org.junit.jupiter.api.Assertions.assertFalse;
36+
import static org.junit.jupiter.api.Assertions.assertNotNull;
37+
import static org.junit.jupiter.api.Assertions.assertThrows;
3338
import static org.mockito.ArgumentMatchers.anyString;
3439
import static org.mockito.ArgumentMatchers.eq;
3540
import static org.mockito.Mockito.mock;
@@ -41,8 +46,13 @@
4146
import com.spotify.github.async.AsyncPage;
4247
import com.spotify.github.jackson.Json;
4348
import com.spotify.github.v3.comment.Comment;
49+
import com.spotify.github.v3.exceptions.RequestNotOkException;
50+
import com.spotify.github.v3.issues.Issue;
4451
import java.io.IOException;
52+
import java.util.HashMap;
4553
import java.util.List;
54+
import java.util.concurrent.CompletableFuture;
55+
import java.util.concurrent.CompletionException;
4656
import okhttp3.Response;
4757
import org.junit.jupiter.api.BeforeEach;
4858
import org.junit.jupiter.api.Test;
@@ -51,11 +61,14 @@ public class IssueClientTest {
5161

5262
private GitHubClient github;
5363
private IssueClient issueClient;
64+
private Json json;
65+
5466

5567
@BeforeEach
5668
public void setUp() {
69+
json = Json.create();
5770
github = mock(GitHubClient.class);
58-
when(github.json()).thenReturn(Json.create());
71+
when(github.json()).thenReturn(json);
5972
when(github.urlFor("")).thenReturn("https://github.com/api/v3");
6073
issueClient = new IssueClient(github, "someowner", "somerepo");
6174
}
@@ -132,4 +145,27 @@ public void testCommentCreated() throws IOException {
132145

133146
assertThat(comment.id(), is(114));
134147
}
148+
149+
@Test
150+
public void testGetIssue() throws IOException {
151+
final String fixture = loadFixture("issues/issue.json");
152+
final CompletableFuture<Issue> response = completedFuture(json.fromJson(fixture, Issue.class));
153+
final String path = format(ISSUES_URI_ID_TEMPLATE, "someowner", "somerepo", 2);
154+
when(github.request(eq(path), eq(Issue.class))).thenReturn(response);
155+
156+
final var issue = issueClient.getIssue(2).join();
157+
158+
assertThat(issue.id(), is(2));
159+
assertNotNull(issue.labels());
160+
assertFalse(issue.labels().isEmpty());
161+
assertThat(issue.labels().get(0).name(), is("bug"));
162+
}
163+
164+
@Test
165+
public void testGetIssueNoIssue() {
166+
final String path = format(ISSUES_URI_ID_TEMPLATE, "someowner", "somerepo", 2);
167+
when(github.request(eq(path), eq(Issue.class))).thenReturn(failedFuture(new RequestNotOkException("", "", 404, "", new HashMap<>())));
168+
169+
assertThrows(CompletionException.class, () -> issueClient.getIssue(2).join());
170+
}
135171
}

src/test/resources/com/spotify/github/v3/issues/issue.json

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
2-
"id": 1,
2+
"id": 2,
3+
"node_id": "MDU6SXNzdWUx",
34
"url": "https://api.github.com/repos/octocat/Hello-World/issues/1347",
45
"repository_url": "https://api.github.com/repos/octocat/Hello-World",
56
"labels_url": "https://api.github.com/repos/octocat/Hello-World/issues/1347/labels{/name}",
@@ -13,6 +14,7 @@
1314
"user": {
1415
"login": "octocat",
1516
"id": 1,
17+
"node_id": "MDQ6VXNlcjE=",
1618
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
1719
"gravatar_id": "",
1820
"url": "https://api.github.com/users/octocat",
@@ -31,14 +33,19 @@
3133
},
3234
"labels": [
3335
{
36+
"id": 208045946,
37+
"node_id": "MDU6TGFiZWwyMDgwNDU5NDY=",
3438
"url": "https://api.github.com/repos/octocat/Hello-World/labels/bug",
3539
"name": "bug",
36-
"color": "f29513"
40+
"description": "Something isn't working",
41+
"color": "f29513",
42+
"default": true
3743
}
3844
],
3945
"assignee": {
4046
"login": "octocat",
4147
"id": 1,
48+
"node_id": "MDQ6VXNlcjE=",
4249
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
4350
"gravatar_id": "",
4451
"url": "https://api.github.com/users/octocat",
@@ -55,18 +62,42 @@
5562
"type": "User",
5663
"site_admin": false
5764
},
65+
"assignees": [
66+
{
67+
"login": "octocat",
68+
"id": 1,
69+
"node_id": "MDQ6VXNlcjE=",
70+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
71+
"gravatar_id": "",
72+
"url": "https://api.github.com/users/octocat",
73+
"html_url": "https://github.com/octocat",
74+
"followers_url": "https://api.github.com/users/octocat/followers",
75+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
76+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
77+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
78+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
79+
"organizations_url": "https://api.github.com/users/octocat/orgs",
80+
"repos_url": "https://api.github.com/users/octocat/repos",
81+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
82+
"received_events_url": "https://api.github.com/users/octocat/received_events",
83+
"type": "User",
84+
"site_admin": false
85+
}
86+
],
5887
"milestone": {
5988
"url": "https://api.github.com/repos/octocat/Hello-World/milestones/1",
6089
"html_url": "https://github.com/octocat/Hello-World/milestones/v1.0",
6190
"labels_url": "https://api.github.com/repos/octocat/Hello-World/milestones/1/labels",
6291
"id": 1002604,
92+
"node_id": "MDk6TWlsZXN0b25lMTAwMjYwNA==",
6393
"number": 1,
6494
"state": "open",
6595
"title": "v1.0",
6696
"description": "Tracking milestone for version 1.0",
6797
"creator": {
6898
"login": "octocat",
6999
"id": 1,
100+
"node_id": "MDQ6VXNlcjE=",
70101
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
71102
"gravatar_id": "",
72103
"url": "https://api.github.com/users/octocat",
@@ -90,7 +121,8 @@
90121
"closed_at": "2013-02-12T13:22:01Z",
91122
"due_on": "2012-10-09T23:39:01Z"
92123
},
93-
"locked": false,
124+
"locked": true,
125+
"active_lock_reason": "too heated",
94126
"comments": 0,
95127
"pull_request": {
96128
"url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347",
@@ -100,5 +132,27 @@
100132
},
101133
"closed_at": null,
102134
"created_at": "2011-04-22T13:33:48Z",
103-
"updated_at": "2011-04-22T13:33:48Z"
135+
"updated_at": "2011-04-22T13:33:48Z",
136+
"closed_by": {
137+
"login": "octocat",
138+
"id": 1,
139+
"node_id": "MDQ6VXNlcjE=",
140+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
141+
"gravatar_id": "",
142+
"url": "https://api.github.com/users/octocat",
143+
"html_url": "https://github.com/octocat",
144+
"followers_url": "https://api.github.com/users/octocat/followers",
145+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
146+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
147+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
148+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
149+
"organizations_url": "https://api.github.com/users/octocat/orgs",
150+
"repos_url": "https://api.github.com/users/octocat/repos",
151+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
152+
"received_events_url": "https://api.github.com/users/octocat/received_events",
153+
"type": "User",
154+
"site_admin": false
155+
},
156+
"author_association": "COLLABORATOR",
157+
"state_reason": "completed"
104158
}

0 commit comments

Comments
 (0)