diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index 49be640321..16648b4f86 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -45,7 +45,27 @@ public enum Role { */ MAINTAINER, /** A normal member of the team. */ - MEMBER + MEMBER, + /** Unknown role. */ + UNKNOWN + } + + /** + * Notification setting across a team + */ + public enum NotificationSetting { + /** + * Team members receive notifications when the team is @mentioned. + */ + NOTIFICATIONS_ENABLED, + /** + * No one receives notifications. + */ + NOTIFICATIONS_DISABLED, + /** + * Unknown notification setting. + */ + UNKNOWN } /** @@ -511,6 +531,15 @@ public void setPrivacy(Privacy privacy) throws IOException { root().createRequest().method("PATCH").with("privacy", privacy).withUrlPath(api("")).send(); } + /** + * Start constructing an update request for multiple properties of this team. + * + * @return a builder to update this team + */ + public GHTeamUpdateBuilder updateTeam() { + return new GHTeamUpdateBuilder(root(), organization.getLogin(), name); + } + private String api(String tail) { if (organization == null) { // Teams returned from pull requests to do not have an organization. Attempt to use url. diff --git a/src/main/java/org/kohsuke/github/GHTeamUpdateBuilder.java b/src/main/java/org/kohsuke/github/GHTeamUpdateBuilder.java new file mode 100644 index 0000000000..2a1e4357c5 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHTeamUpdateBuilder.java @@ -0,0 +1,123 @@ +package org.kohsuke.github; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +import java.io.IOException; + +/** + * Updates a team. + * + * @see Update team docs + * @author Rory Kelly + */ +public class GHTeamUpdateBuilder extends GitHubInteractiveObject { + + private final String orgName; + private final String existingName; + /** The builder. */ + protected final Requester builder; + + /** + * Instantiates a new GH team update builder. + * + * @param root + * the root + * @param orgName + * the org name + * @param existingName + * the current name of the existing team + */ + @SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, justification = "Expected") + public GHTeamUpdateBuilder(GitHub root, String orgName, String existingName) { + super(root); + this.orgName = orgName; + this.existingName = existingName; + this.builder = root.createRequest(); + } + + /** + * Updates a team with all the provided parameters. + * + * @return the gh team + * @throws IOException + * if team cannot be updated + */ + public GHTeam update() throws IOException { + return builder.method("PATCH").withUrlPath("/orgs/" + orgName + "/teams/" + existingName).fetch(GHTeam.class).wrapUp(root()); + } + + /** + * Name for this team. + * + * @param name + * name of team + * @return a builder to continue with building + */ + public GHTeamUpdateBuilder name(String name) { + this.builder.with("name", name); + return this; + } + + /** + * Description for this team. + * + * @param description + * description of team + * @return a builder to continue with building + */ + public GHTeamUpdateBuilder description(String description) { + this.builder.with("description", description); + return this; + } + + /** + * Privacy for this team. + * + * @param privacy + * privacy of team + * @return a builder to continue with building + */ + public GHTeamUpdateBuilder privacy(GHTeam.Privacy privacy) { + this.builder.with("privacy", privacy); + return this; + } + + /** + * The notification setting explicitly set for this team. + * + * @param notificationSetting + * notification setting to be applied + * @return a builder to continue with building + */ + public GHTeamUpdateBuilder notifications(GHTeam.NotificationSetting notificationSetting) { + this.builder.with("notification_setting", notificationSetting); + return this; + } + + /** + * The permission that new repositories will be added to the team with when none is specified. + * + * @param permission + * permission to be applied + * @return a builder to continue with building + * @deprecated see + * Update team docs + */ + @Deprecated + public GHTeamUpdateBuilder permission(GHOrganization.Permission permission) { + this.builder.with("permission", permission); + return this; + } + + /** + * Parent team id for this team. + * + * @param parentTeamId + * parentTeamId of team, or null if you are removing the parent + * @return a builder to continue with building + */ + public GHTeamUpdateBuilder parentTeamId(Long parentTeamId) { + this.builder.with("parent_team_id", parentTeamId); + return this; + } +} diff --git a/src/test/java/org/kohsuke/github/GHTeamUpdateBuilderTest.java b/src/test/java/org/kohsuke/github/GHTeamUpdateBuilderTest.java new file mode 100644 index 0000000000..cc5cd230b5 --- /dev/null +++ b/src/test/java/org/kohsuke/github/GHTeamUpdateBuilderTest.java @@ -0,0 +1,120 @@ +package org.kohsuke.github; + +import org.junit.Test; + +import java.io.IOException; + +import static org.hamcrest.Matchers.equalTo; + +// TODO: Auto-generated Javadoc + +/** + * The Class GHTeamUpdateBuilderTest. + * + * @author Rory Kelly + */ +public class GHTeamUpdateBuilderTest extends AbstractGitHubWireMockTest { + + private static final String TEAM_TO_UPDATE_SLUG = "dummy-team-to-update"; + + private static final String TEAM_TO_UPDATE_NEW_NAME = "dummy-team-updated"; + private static final String TEAM_TO_UPDATE_NEW_DESCRIPTION = "This is an updated description!"; + private static final GHTeam.Privacy TEAM_TO_UPDATE_NEW_PRIVACY = GHTeam.Privacy.SECRET; + private static final GHTeam.NotificationSetting TEAM_TO_UPDATE_NEW_NOTIFICATIONS = GHTeam.NotificationSetting.NOTIFICATIONS_DISABLED; + @Deprecated + private static final GHOrganization.Permission TEAM_TO_UPDATE_NEW_PERMISSIONS = GHOrganization.Permission.PUSH; + + // private static final String CURRENT_PARENT_TEAM_SLUG = "dummy-current-parent-team"; + private static final String NEW_PARENT_TEAM_SLUG = "dummy-new-parent-team"; + + /** + * Create default GHTeamBuilderTest instance + */ + public GHTeamUpdateBuilderTest() { + } + + /** + * Given a team, when updating the team with a different parent team, then the team is updated with the new parent team. + * @throws IOException exception thrown if there is an issue with Wiremock + */ + @Test + public void testUpdateTeamWithNewParentTeam() throws IOException { + // Get the org and teams + GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); + GHTeam teamToUpdate = org.getTeamBySlug(TEAM_TO_UPDATE_SLUG); + GHTeam newParentTeam = org.getTeamBySlug(NEW_PARENT_TEAM_SLUG); + + // Update team with different parent team + GHTeam updatedTeam = getCommonBuilder(teamToUpdate) + .parentTeamId(newParentTeam.getId()) + .update(); + + assertUpdatedTeam(updatedTeam); + // assertThat(updatedTeam.getParentTeam().getId(), equalTo(newParentTeam.getId())); + } + + /** + * Given a team, when updating the team with no change to parent team, then the team is updated with no change to the parent team. + * @throws IOException exception thrown if there is an issue with Wiremock + */ + @Test + public void testUpdateTeamWithNoChangeToParentTeam() throws IOException { + // Get the org and team + GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); + GHTeam teamToUpdate = org.getTeamBySlug(TEAM_TO_UPDATE_SLUG); + // GHTeam existingParentTeam = org.getTeamBySlug(CURRENT_PARENT_TEAM_SLUG); + + // update team with no change to parent team + GHTeam updatedTeam = getCommonBuilder(teamToUpdate).update(); + + assertUpdatedTeam(updatedTeam); + // assertThat(teamToUpdate.getParentTeam().getId(), equalTo(existingParentTeam.getId())); + } + + /** + * Given a team, when updating the team with a removed parent team, then the team is updated and has no parent team. + * @throws IOException exception thrown if there is an issue with Wiremock + */ + @Test + public void testUpdateTeamWithRemovedParentTeam() throws IOException { + // Get the org and team + GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); + GHTeam teamToUpdate = org.getTeamBySlug(TEAM_TO_UPDATE_SLUG); + + // Update team with removed parent team + GHTeam updatedTeam = getCommonBuilder(teamToUpdate) + .parentTeamId(null) + .update(); + + assertUpdatedTeam(updatedTeam); + // assertThat(teamToUpdate.getParentTeam(), equalTo(null)); + } + + /** + * Get the GHTeamUpdateBuilder instance with the common fields set for updating a team, to be used in the different update scenarios. + * + * @param teamToUpdate the base team to update + * @return the GHTeamUpdateBuilder instance with the common fields set for updating a team + */ + private GHTeamUpdateBuilder getCommonBuilder(GHTeam teamToUpdate) { + return teamToUpdate.updateTeam() + .name(TEAM_TO_UPDATE_NEW_NAME) + .description(TEAM_TO_UPDATE_NEW_DESCRIPTION) + .privacy(TEAM_TO_UPDATE_NEW_PRIVACY) + .notifications(TEAM_TO_UPDATE_NEW_NOTIFICATIONS) + .permission(TEAM_TO_UPDATE_NEW_PERMISSIONS); + } + + /** + * Assert that the updated team has the expected updated values. + * + * @param updatedTeam the team to assert the updated values on + */ + private void assertUpdatedTeam(GHTeam updatedTeam) { + assertThat(updatedTeam.getName(), equalTo(TEAM_TO_UPDATE_NEW_NAME)); + assertThat(updatedTeam.getDescription(), equalTo(TEAM_TO_UPDATE_NEW_DESCRIPTION)); + assertThat(updatedTeam.getPrivacy(), equalTo(TEAM_TO_UPDATE_NEW_PRIVACY)); + // assertThat(updatedTeam.getNotificationSetting(), equalTo(TEAM_TO_UPDATE_NEW_NOTIFICATIONS)); + assertThat(updatedTeam.getPermission(), equalTo(TEAM_TO_UPDATE_NEW_PERMISSIONS)); + } +}