Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion src/main/java/org/kohsuke/github/GHTeam.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@
*/
public class GHTeam extends GHObject implements Refreshable {

/**
* Notification setting across a team
*/
public enum NotificationSetting {
/**
* No one receives notifications.
*/
NOTIFICATIONS_DISABLED,
/**
* Team members receive notifications when the team is @mentioned.
*/
NOTIFICATIONS_ENABLED,
/**
* Unknown notification setting.
*/
UNKNOWN
}

/**
* The Enum Privacy.
*/
Expand All @@ -45,7 +63,9 @@ public enum Role {
*/
MAINTAINER,
/** A normal member of the team. */
MEMBER
MEMBER,
/** Unknown role. */
UNKNOWN
}

/**
Expand Down Expand Up @@ -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.
Expand Down
125 changes: 125 additions & 0 deletions src/main/java/org/kohsuke/github/GHTeamUpdateBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package org.kohsuke.github;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;

import java.io.IOException;

/**
* Updates a team.
*
* @see <a href=https://developer.github.com/v3/teams/#update-team>Update team docs</a>
* @author Rory Kelly
*/
public class GHTeamUpdateBuilder extends GitHubInteractiveObject {

private final String existingName;
private final String orgName;
/** 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();
}

/**
* 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;
}

/**
* 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;
}

/**
* 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;
}

/**
* 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;
}

/**
* 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 <a href=https://developer.github.com/v3/teams/#update-team>Update team docs</a>
*/
@Deprecated
public GHTeamUpdateBuilder permission(GHOrganization.Permission permission) {
this.builder.with("permission", permission);
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;
}

/**
* 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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5804,6 +5804,21 @@
"allPublicClasses": true,
"allDeclaredClasses": true
},
{
"name": "org.kohsuke.github.GHTeam$NotificationSetting",
"allPublicFields": true,
"allDeclaredFields": true,
"queryAllPublicConstructors": true,
"queryAllDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredConstructors": true,
"queryAllPublicMethods": true,
"queryAllDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredMethods": true,
"allPublicClasses": true,
"allDeclaredClasses": true
},
{
"name": "org.kohsuke.github.GHTeam$Privacy",
"allPublicFields": true,
Expand Down Expand Up @@ -5939,6 +5954,21 @@
"allPublicClasses": true,
"allDeclaredClasses": true
},
{
"name": "org.kohsuke.github.GHTeamUpdateBuilder",
"allPublicFields": true,
"allDeclaredFields": true,
"queryAllPublicConstructors": true,
"queryAllDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredConstructors": true,
"queryAllPublicMethods": true,
"queryAllDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredMethods": true,
"allPublicClasses": true,
"allDeclaredClasses": true
},
{
"name": "org.kohsuke.github.GHThread",
"allPublicFields": true,
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/org/kohsuke/github/EnumTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ public void touchEnums() {

assertThat(GHTargetType.values().length, equalTo(3));

assertThat(GHTeam.Role.values().length, equalTo(2));
assertThat(GHTeam.NotificationSetting.values().length, equalTo(3));
assertThat(GHTeam.Role.values().length, equalTo(3));
assertThat(GHTeam.Privacy.values().length, equalTo(3));

assertThat(GHUserSearchBuilder.Sort.values().length, equalTo(3));
Expand Down
127 changes: 127 additions & 0 deletions src/test/java/org/kohsuke/github/GHTeamUpdateBuilderTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
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 CURRENT_PARENT_TEAM_SLUG = "dummy-current-parent-team";
private static final String NEW_PARENT_TEAM_SLUG = "dummy-new-parent-team";

private static final String TEAM_TO_UPDATE_NEW_DESCRIPTION = "Updated by GHTeamUpdateBuilderTest";
private static final String TEAM_TO_UPDATE_NEW_NAME = "dummy-team-updated";
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 GHTeam.Privacy TEAM_TO_UPDATE_NEW_PRIVACY = GHTeam.Privacy.CLOSED;

private static final String TEAM_TO_UPDATE_SLUG = "dummy-team-to-update";

/**
* 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();

validateUpdatedTeam(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();

validateUpdatedTeam(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();

validateUpdatedTeam(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 validateUpdatedTeam(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.name().toLowerCase()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"login": "rozza-sb",
"id": 136339038,
"node_id": "U_kgDOCCBeXg",
"avatar_url": "https://avatars.githubusercontent.com/u/136339038?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/rozza-sb",
"html_url": "https://github.com/rozza-sb",
"followers_url": "https://api.github.com/users/rozza-sb/followers",
"following_url": "https://api.github.com/users/rozza-sb/following{/other_user}",
"gists_url": "https://api.github.com/users/rozza-sb/gists{/gist_id}",
"starred_url": "https://api.github.com/users/rozza-sb/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/rozza-sb/subscriptions",
"organizations_url": "https://api.github.com/users/rozza-sb/orgs",
"repos_url": "https://api.github.com/users/rozza-sb/repos",
"events_url": "https://api.github.com/users/rozza-sb/events{/privacy}",
"received_events_url": "https://api.github.com/users/rozza-sb/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false,
"name": "Rory Kelly",
"company": null,
"blog": "",
"location": null,
"email": null,
"hireable": null,
"bio": null,
"twitter_username": null,
"notification_email": null,
"public_repos": 2,
"public_gists": 1,
"followers": 0,
"following": 0,
"created_at": "2023-06-12T12:41:11Z",
"updated_at": "2026-09-21T10:04:39Z"
}
Loading
Loading