Skip to content

Commit

Permalink
Add paged version of getTeamMembers (#176)
Browse files Browse the repository at this point in the history
* Add paged version of getTeamMembers

* Add test case for paged team client
  • Loading branch information
dennisgranath committed Jan 15, 2024
1 parent d4a0d3c commit f1c654e
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 4 deletions.
22 changes: 18 additions & 4 deletions src/main/java/com/spotify/github/v3/clients/TeamClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@

package com.spotify.github.v3.clients;

import static com.spotify.github.v3.clients.GitHubClient.IGNORE_RESPONSE_CONSUMER;
import static com.spotify.github.v3.clients.GitHubClient.LIST_PENDING_TEAM_INVITATIONS;
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAMS;
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAM_MEMBERS;
import static com.spotify.github.v3.clients.GitHubClient.*;

import com.spotify.github.async.AsyncPage;
import com.spotify.github.v3.Team;
import com.spotify.github.v3.User;
import com.spotify.github.v3.orgs.Membership;
Expand All @@ -34,6 +32,7 @@
import com.spotify.github.v3.orgs.requests.TeamCreate;
import com.spotify.github.v3.orgs.requests.TeamUpdate;
import java.lang.invoke.MethodHandles;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.slf4j.Logger;
Expand All @@ -49,6 +48,8 @@ public class TeamClient {

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

private static final String PAGED_MEMBERS_TEMPLATE = "/orgs/%s/teams/%s/members?per_page=%d";

private static final String MEMBERSHIP_TEMPLATE = "/orgs/%s/teams/%s/memberships/%s";

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

/**
* List members of a specific team.
*
* @param slug the team slug
* @param pageSize the number of users to fetch per page
* @return list of all users in a team
*/
public Iterator<AsyncPage<User>> listTeamMembers(final String slug, final int pageSize) {
final String path = String.format(PAGED_MEMBERS_TEMPLATE, org, slug, pageSize);
log.debug("Fetching members for: " + path);
return new GithubPageIterator<>(new GithubPage<>(github, path, LIST_TEAM_MEMBERS));
}

/**
* Delete a membership for a user.
*
Expand Down
38 changes: 38 additions & 0 deletions src/test/java/com/spotify/github/v3/clients/TeamClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,30 @@
import static com.spotify.github.v3.clients.GitHubClient.LIST_PENDING_TEAM_INVITATIONS;
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAMS;
import static com.spotify.github.v3.clients.GitHubClient.LIST_TEAM_MEMBERS;
import static com.spotify.github.v3.clients.MockHelper.createMockResponse;
import static java.nio.charset.Charset.defaultCharset;
import static java.util.concurrent.CompletableFuture.completedFuture;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamSupport.stream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;

import com.google.common.io.Resources;
import com.spotify.github.async.AsyncPage;
import com.spotify.github.jackson.Json;
import com.spotify.github.v3.Team;
import com.spotify.github.v3.User;
import com.spotify.github.v3.comment.Comment;
import com.spotify.github.v3.orgs.Membership;
import com.spotify.github.v3.orgs.TeamInvitation;
import com.spotify.github.v3.orgs.requests.MembershipCreate;
import com.spotify.github.v3.orgs.requests.TeamCreate;
import com.spotify.github.v3.orgs.requests.TeamUpdate;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import okhttp3.Response;
Expand All @@ -67,6 +73,7 @@ public void setUp() {
teamClient = new TeamClient(github, "github");
json = Json.create();
when(github.json()).thenReturn(json);
when(github.urlFor("")).thenReturn("https://github.com/api/v3");
}

@Test
Expand Down Expand Up @@ -156,6 +163,37 @@ public void listTeamMembers() throws Exception {
assertThat(teamMembers.size(), is(2));
}

@Test
public void listTeamMembersPaged() throws Exception {
final String firstPageLink =
"<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\"";
final String firstPageBody =
Resources.toString(getResource(this.getClass(), "list_members_page1.json"), defaultCharset());
final Response firstPageResponse = createMockResponse(firstPageLink, firstPageBody);

final String lastPageLink =
"<https://github.com/api/v3/orgs/github/teams/1/members>; rel=\"first\", <https://github.com/api/v3/orgs/github/teams/1/members>; rel=\"prev\"";
final String lastPageBody =
Resources.toString(getResource(this.getClass(), "list_members_page2.json"), defaultCharset());

final Response lastPageResponse = createMockResponse(lastPageLink, lastPageBody);

when(github.request(endsWith("/orgs/github/teams/1/members?per_page=1")))
.thenReturn(completedFuture(firstPageResponse));
when(github.request(endsWith("/orgs/github/teams/1/members?page=2")))
.thenReturn(completedFuture(lastPageResponse));

final Iterable<AsyncPage<User>> pageIterator = () -> teamClient.listTeamMembers("1", 1);
final List<User> users =
stream(pageIterator.spliterator(), false)
.flatMap(page -> stream(page.spliterator(), false))
.collect(toList());

assertThat(users.size(), is(2));
assertThat(users.get(0).login(), is("octocat"));
assertThat(users.get(1).id(), is(2));
}

@Test
public void updateMembership() throws Exception {
final MembershipCreate membershipCreateRequest =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"login": "octocat",
"id": 1,
"node_id": "MDQ6VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[
{
"login": "octocat2",
"id": 2,
"node_id": "MDQ2VXNlcjE=",
"avatar_url": "https://github.com/images/error/octocat2_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat2",
"html_url": "https://github.com/octocat2",
"followers_url": "https://api.github.com/users/octocat2/followers",
"following_url": "https://api.github.com/users/octoca2t/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat2/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat2/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat2/subscriptions",
"organizations_url": "https://api.github.com/users/octocat2/orgs",
"repos_url": "https://api.github.com/users/octocat2/repos",
"events_url": "https://api.github.com/users/octocat2/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat2/received_events",
"type": "User",
"site_admin": false
}
]

0 comments on commit f1c654e

Please sign in to comment.