Skip to content

Commit f1c654e

Browse files
Add paged version of getTeamMembers (#176)
* Add paged version of getTeamMembers * Add test case for paged team client
1 parent d4a0d3c commit f1c654e

File tree

4 files changed

+100
-4
lines changed

4 files changed

+100
-4
lines changed

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@
2121

2222
package com.spotify.github.v3.clients;
2323

24-
import static com.spotify.github.v3.clients.GitHubClient.IGNORE_RESPONSE_CONSUMER;
25-
import static com.spotify.github.v3.clients.GitHubClient.LIST_PENDING_TEAM_INVITATIONS;
26-
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAMS;
27-
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAM_MEMBERS;
24+
import static com.spotify.github.v3.clients.GitHubClient.*;
2825

26+
import com.spotify.github.async.AsyncPage;
2927
import com.spotify.github.v3.Team;
3028
import com.spotify.github.v3.User;
3129
import com.spotify.github.v3.orgs.Membership;
@@ -34,6 +32,7 @@
3432
import com.spotify.github.v3.orgs.requests.TeamCreate;
3533
import com.spotify.github.v3.orgs.requests.TeamUpdate;
3634
import java.lang.invoke.MethodHandles;
35+
import java.util.Iterator;
3736
import java.util.List;
3837
import java.util.concurrent.CompletableFuture;
3938
import org.slf4j.Logger;
@@ -49,6 +48,8 @@ public class TeamClient {
4948

5049
private static final String MEMBERS_TEMPLATE = "/orgs/%s/teams/%s/members";
5150

51+
private static final String PAGED_MEMBERS_TEMPLATE = "/orgs/%s/teams/%s/members?per_page=%d";
52+
5253
private static final String MEMBERSHIP_TEMPLATE = "/orgs/%s/teams/%s/memberships/%s";
5354

5455
private static final String INVITATIONS_TEMPLATE = "/orgs/%s/teams/%s/invitations";
@@ -163,6 +164,19 @@ public CompletableFuture<List<User>> listTeamMembers(final String slug) {
163164
return github.request(path, LIST_TEAM_MEMBERS);
164165
}
165166

167+
/**
168+
* List members of a specific team.
169+
*
170+
* @param slug the team slug
171+
* @param pageSize the number of users to fetch per page
172+
* @return list of all users in a team
173+
*/
174+
public Iterator<AsyncPage<User>> listTeamMembers(final String slug, final int pageSize) {
175+
final String path = String.format(PAGED_MEMBERS_TEMPLATE, org, slug, pageSize);
176+
log.debug("Fetching members for: " + path);
177+
return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_TEAM_MEMBERS));
178+
}
179+
166180
/**
167181
* Delete a membership for a user.
168182
*

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,30 @@
2424
import static com.spotify.github.v3.clients.GitHubClient.LIST_PENDING_TEAM_INVITATIONS;
2525
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAMS;
2626
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAM_MEMBERS;
27+
import static com.spotify.github.v3.clients.MockHelper.createMockResponse;
2728
import static java.nio.charset.Charset.defaultCharset;
2829
import static java.util.concurrent.CompletableFuture.completedFuture;
30+
import static java.util.stream.Collectors.toList;
31+
import static java.util.stream.StreamSupport.stream;
2932
import static org.hamcrest.MatcherAssert.assertThat;
3033
import static org.hamcrest.core.Is.is;
3134
import static org.mockito.ArgumentMatchers.any;
3235
import static org.mockito.ArgumentMatchers.eq;
3336
import static org.mockito.Mockito.*;
3437

3538
import com.google.common.io.Resources;
39+
import com.spotify.github.async.AsyncPage;
3640
import com.spotify.github.jackson.Json;
3741
import com.spotify.github.v3.Team;
3842
import com.spotify.github.v3.User;
43+
import com.spotify.github.v3.comment.Comment;
3944
import com.spotify.github.v3.orgs.Membership;
4045
import com.spotify.github.v3.orgs.TeamInvitation;
4146
import com.spotify.github.v3.orgs.requests.MembershipCreate;
4247
import com.spotify.github.v3.orgs.requests.TeamCreate;
4348
import com.spotify.github.v3.orgs.requests.TeamUpdate;
4449
import java.io.IOException;
50+
import java.util.Iterator;
4551
import java.util.List;
4652
import java.util.concurrent.CompletableFuture;
4753
import okhttp3.Response;
@@ -67,6 +73,7 @@ public void setUp() {
6773
teamClient = new TeamClient(github, "github");
6874
json = Json.create();
6975
when(github.json()).thenReturn(json);
76+
when(github.urlFor("")).thenReturn("https://github.com/api/v3");
7077
}
7178

7279
@Test
@@ -156,6 +163,37 @@ public void listTeamMembers() throws Exception {
156163
assertThat(teamMembers.size(), is(2));
157164
}
158165

166+
@Test
167+
public void listTeamMembersPaged() throws Exception {
168+
final String firstPageLink =
169+
"<https://github.com/api/v3/orgs/github/teams/1/members?page=2>; rel=\"next\", <https://github.com/api/v3/orgs/github/teams/1/members?page=2>; rel=\"last\"";
170+
final String firstPageBody =
171+
Resources.toString(getResource(this.getClass(), "list_members_page1.json"), defaultCharset());
172+
final Response firstPageResponse = createMockResponse(firstPageLink, firstPageBody);
173+
174+
final String lastPageLink =
175+
"<https://github.com/api/v3/orgs/github/teams/1/members>; rel=\"first\", <https://github.com/api/v3/orgs/github/teams/1/members>; rel=\"prev\"";
176+
final String lastPageBody =
177+
Resources.toString(getResource(this.getClass(), "list_members_page2.json"), defaultCharset());
178+
179+
final Response lastPageResponse = createMockResponse(lastPageLink, lastPageBody);
180+
181+
when(github.request(endsWith("/orgs/github/teams/1/members?per_page=1")))
182+
.thenReturn(completedFuture(firstPageResponse));
183+
when(github.request(endsWith("/orgs/github/teams/1/members?page=2")))
184+
.thenReturn(completedFuture(lastPageResponse));
185+
186+
final Iterable<AsyncPage<User>> pageIterator = () -> teamClient.listTeamMembers("1", 1);
187+
final List<User> users =
188+
stream(pageIterator.spliterator(), false)
189+
.flatMap(page -> stream(page.spliterator(), false))
190+
.collect(toList());
191+
192+
assertThat(users.size(), is(2));
193+
assertThat(users.get(0).login(), is("octocat"));
194+
assertThat(users.get(1).id(), is(2));
195+
}
196+
159197
@Test
160198
public void updateMembership() throws Exception {
161199
final MembershipCreate membershipCreateRequest =
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"login": "octocat",
4+
"id": 1,
5+
"node_id": "MDQ6VXNlcjE=",
6+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
7+
"gravatar_id": "",
8+
"url": "https://api.github.com/users/octocat",
9+
"html_url": "https://github.com/octocat",
10+
"followers_url": "https://api.github.com/users/octocat/followers",
11+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
12+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
13+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
14+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
15+
"organizations_url": "https://api.github.com/users/octocat/orgs",
16+
"repos_url": "https://api.github.com/users/octocat/repos",
17+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
18+
"received_events_url": "https://api.github.com/users/octocat/received_events",
19+
"type": "User",
20+
"site_admin": false
21+
}
22+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"login": "octocat2",
4+
"id": 2,
5+
"node_id": "MDQ2VXNlcjE=",
6+
"avatar_url": "https://github.com/images/error/octocat2_happy.gif",
7+
"gravatar_id": "",
8+
"url": "https://api.github.com/users/octocat2",
9+
"html_url": "https://github.com/octocat2",
10+
"followers_url": "https://api.github.com/users/octocat2/followers",
11+
"following_url": "https://api.github.com/users/octoca2t/following{/other_user}",
12+
"gists_url": "https://api.github.com/users/octocat2/gists{/gist_id}",
13+
"starred_url": "https://api.github.com/users/octocat2/starred{/owner}{/repo}",
14+
"subscriptions_url": "https://api.github.com/users/octocat2/subscriptions",
15+
"organizations_url": "https://api.github.com/users/octocat2/orgs",
16+
"repos_url": "https://api.github.com/users/octocat2/repos",
17+
"events_url": "https://api.github.com/users/octocat2/events{/privacy}",
18+
"received_events_url": "https://api.github.com/users/octocat2/received_events",
19+
"type": "User",
20+
"site_admin": false
21+
}
22+
]

0 commit comments

Comments
 (0)