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));
+ }
+}