Skip to content
Merged
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Add provisionalExpirationDate field to the User model
- Add provisionalExpirationDate field to the UserPlan model
- Remove integration tests from the sdk test suite and workflows
- Support for POST /2.0/users/{userId}/reactivate endpoint
- Support for POST /2.0/users/{userId}/deactivate endpoint
### Updated
- Folder structure for the Users related WireMock tests

Expand Down
38 changes: 38 additions & 0 deletions src/main/java/com/smartsheet/api/UserResources.java
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,44 @@ PagedResult<User> listUsers(Set<String> email, Long planId,
*/
void deleteUser(long id, DeleteUserParameters parameters) throws SmartsheetException;

/**
* <p>Reactivates a user.</p>
*
* <p>Reactivates the user associated with the current Smartsheet plan, restoring the user's access to
* Smartsheet, owned items, and shared items.</p>
*
* <p>Important: You can reactivate the user only if that user has been deactivated for less than thirty (30) days.</p>
*
* <p>It mirrors to the following Smartsheet REST API method: POST /users/{userId}/reactivate</p>
*
* @param id the id of the user to reactivate
* @throws IllegalArgumentException if any argument is null or empty string
* @throws InvalidRequestException if there is any problem with the REST API request (e.g., user email belongs to ISP domain)
* @throws AuthorizationException if there is any problem with the REST API authorization (access token)
* @throws ResourceNotFoundException if the resource cannot be found
* @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
* @throws SmartsheetException if there is any other error during the operation
*/
void reactivateUser(long id) throws SmartsheetException;

/**
* <p>Deactivates a user.</p>
*
* <p>Deactivates the user associated with the current Smartsheet plan, blocking the user from using Smartsheet in any way.
* Deactivating a user does not affect their existing permissions on owned or shared items.</p>
*
* <p>It mirrors to the following Smartsheet REST API method: POST /users/{userId}/deactivate</p>
*
* @param id the id of the user to deactivate
* @throws IllegalArgumentException if any argument is null or empty string
* @throws InvalidRequestException if there is any problem with the REST API request (e.g., user email belongs to ISP domain or user is managed by external source)
* @throws AuthorizationException if there is any problem with the REST API authorization (access token)
* @throws ResourceNotFoundException if the resource cannot be found
* @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
* @throws SmartsheetException if there is any other error during the operation
*/
void deactivateUser(long id) throws SmartsheetException;

/**
* <p>List all organisation sheets.</p>
*
Expand Down
44 changes: 44 additions & 0 deletions src/main/java/com/smartsheet/api/internal/UserResourcesImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,50 @@ private void changeSeatType(String seatType, String path) throws SmartsheetExcep
createResource(path, Result.class, body);
}

/**
* <p>Reactivates a user.</p>
*
* <p>Reactivates the user associated with the current Smartsheet plan, restoring the user's access to
* Smartsheet, owned items, and shared items.</p>
*
* <p>Important: You can reactivate the user only if that user has been deactivated for less than thirty (30) days.</p>
*
* <p>It mirrors to the following Smartsheet REST API method: POST /users/{userId}/reactivate</p>
*
* @param userId the id of the user to reactivate
* @throws IllegalArgumentException if any argument is null or empty string
* @throws InvalidRequestException if there is any problem with the REST API request (e.g., user email belongs to ISP domain)
* @throws AuthorizationException if there is any problem with the REST API authorization (access token)
* @throws ResourceNotFoundException if the resource cannot be found
* @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
* @throws SmartsheetException if there is any other error during the operation
*/
@Override
public void reactivateUser(long userId) throws SmartsheetException {
createResource(USERS + "/" + userId + "/reactivate", Result.class, Collections.emptyMap());
}

/**
* <p>Deactivates a user.</p>
*
* <p>Deactivates the user associated with the current Smartsheet plan, blocking the user from using Smartsheet in any way.
* Deactivating a user does not affect their existing permissions on owned or shared items.</p>
*
* <p>It mirrors to the following Smartsheet REST API method: POST /users/{userId}/deactivate</p>
*
* @param userId the id of the user to deactivate
* @throws IllegalArgumentException if any argument is null or empty string
* @throws InvalidRequestException if there is any problem with the REST API request (e.g., user email belongs to ISP domain or user is managed by external source)
* @throws AuthorizationException if there is any problem with the REST API authorization (access token)
* @throws ResourceNotFoundException if the resource cannot be found
* @throws ServiceUnavailableException if the REST API service is not available (possibly due to rate limiting)
* @throws SmartsheetException if there is any other error during the operation
*/
@Override
public void deactivateUser(long userId) throws SmartsheetException {
createResource(USERS + "/" + userId + "/deactivate", Result.class, Collections.emptyMap());
}

@Override
public void deleteUser(long userId, DeleteUserParameters parameters) throws SmartsheetException {
String path = USERS + "/" + userId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2025 Smartsheet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.smartsheet.api.sdktest.users;

import com.github.tomakehurst.wiremock.verification.LoggedRequest;
import com.smartsheet.api.Smartsheet;
import com.smartsheet.api.SmartsheetException;
import com.smartsheet.api.WiremockClient;
import com.smartsheet.api.WiremockClientWrapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.net.URI;
import java.util.UUID;

import static com.smartsheet.api.sdktest.users.CommonTestConstants.TEST_USER_ID;
import static org.assertj.core.api.Assertions.assertThat;

public class TestDeactivateUser {
@Test
void testDeactivateUserGeneratedUrlIsCorrect() throws SmartsheetException {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient(
"/users/deactivate-user/all-response-body-properties",
requestId
);
Smartsheet smartsheet = wrapper.getSmartsheet();
WiremockClient wiremockClient = wrapper.getWiremockClient();

smartsheet.userResources().deactivateUser(TEST_USER_ID);
LoggedRequest wiremockRequest = wiremockClient.findWiremockRequest(requestId);
String path = URI.create(wiremockRequest.getUrl()).getPath();

assertThat(path).isEqualTo("/2.0/users/" + TEST_USER_ID + "/deactivate");
}

@Test
void testDeactivateUserAllResponseBodyProperties() throws SmartsheetException {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient(
"/users/deactivate-user/all-response-body-properties",
requestId
);
Smartsheet smartsheet = wrapper.getSmartsheet();

Assertions.assertDoesNotThrow(() -> {
smartsheet.userResources().deactivateUser(TEST_USER_ID);
});
}

@Test
void testDeactivateUserError500Response() {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient("/errors/500-response", requestId);
Smartsheet smartsheet = wrapper.getSmartsheet();

SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> {
smartsheet.userResources().deactivateUser(TEST_USER_ID);
});

assertThat(exception.getMessage()).isEqualTo("Internal Server Error");
}

@Test
void testDeactivateUserError400Response() {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient("/errors/400-response", requestId);
Smartsheet smartsheet = wrapper.getSmartsheet();

SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> {
smartsheet.userResources().deactivateUser(TEST_USER_ID);
});

assertThat(exception.getMessage()).isEqualTo("Malformed Request");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2025 Smartsheet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.smartsheet.api.sdktest.users;

import com.github.tomakehurst.wiremock.verification.LoggedRequest;
import com.smartsheet.api.Smartsheet;
import com.smartsheet.api.SmartsheetException;
import com.smartsheet.api.WiremockClient;
import com.smartsheet.api.WiremockClientWrapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.net.URI;
import java.util.UUID;

import static com.smartsheet.api.sdktest.users.CommonTestConstants.TEST_USER_ID;
import static org.assertj.core.api.Assertions.assertThat;

public class TestReactivateUser {
@Test
void testReactivateUserGeneratedUrlIsCorrect() throws SmartsheetException {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient(
"/users/reactivate-user/all-response-body-properties",
requestId
);
Smartsheet smartsheet = wrapper.getSmartsheet();
WiremockClient wiremockClient = wrapper.getWiremockClient();

smartsheet.userResources().reactivateUser(TEST_USER_ID);
LoggedRequest wiremockRequest = wiremockClient.findWiremockRequest(requestId);
String path = URI.create(wiremockRequest.getUrl()).getPath();

assertThat(path).isEqualTo("/2.0/users/" + TEST_USER_ID + "/reactivate");
}

@Test
void testReactivateUserAllResponseBodyProperties() throws SmartsheetException {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient(
"/users/reactivate-user/all-response-body-properties",
requestId
);
Smartsheet smartsheet = wrapper.getSmartsheet();

Assertions.assertDoesNotThrow(() -> {
smartsheet.userResources().reactivateUser(TEST_USER_ID);
});
}

@Test
void testReactivateUserError500Response() {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient("/errors/500-response", requestId);
Smartsheet smartsheet = wrapper.getSmartsheet();

SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> {
smartsheet.userResources().reactivateUser(TEST_USER_ID);
});

assertThat(exception.getMessage()).isEqualTo("Internal Server Error");
}

@Test
void testReactivateUserError400Response() {
String requestId = UUID.randomUUID().toString();
WiremockClientWrapper wrapper = Utils.createWiremockSmartsheetClient("/errors/400-response", requestId);
Smartsheet smartsheet = wrapper.getSmartsheet();

SmartsheetException exception = Assertions.assertThrows(SmartsheetException.class, () -> {
smartsheet.userResources().reactivateUser(TEST_USER_ID);
});

assertThat(exception.getMessage()).isEqualTo("Malformed Request");
}
}