From 52bfe5dad04031e38dbc31e0986107e9595421c5 Mon Sep 17 00:00:00 2001 From: shodgetts Date: Wed, 3 Dec 2025 12:53:03 -0700 Subject: [PATCH 1/2] Add bulk deactivate/reactivate users APIs and tests --- .../io/getstream/chat/java/models/User.java | 117 +++++++++++++++++- .../chat/java/services/UserService.java | 8 ++ 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/getstream/chat/java/models/User.java b/src/main/java/io/getstream/chat/java/models/User.java index 622db2c48..7f03aada8 100644 --- a/src/main/java/io/getstream/chat/java/models/User.java +++ b/src/main/java/io/getstream/chat/java/models/User.java @@ -927,6 +927,94 @@ public static class UserDeleteManyResponse extends StreamResponseObject { private String taskId; } + @Builder( + builderClassName = "UserDeactivateManyRequest", + builderMethodName = "", + buildMethodName = "internalBuild") + @Getter + @EqualsAndHashCode + public static class UserDeactivateManyRequestData { + @NotNull + @JsonProperty("user_ids") + private List userIds; + + @Nullable + @JsonProperty("created_by_id") + private String createdById; + + @Nullable + @JsonProperty("mark_channels_deleted") + private Boolean markChannelsDeleted; + + @Nullable + @JsonProperty("mark_messages_deleted") + private Boolean markMessagesDeleted; + + public static class UserDeactivateManyRequest + extends StreamRequest { + @Override + protected Call generateCall(Client client) + throws StreamException { + var data = this.internalBuild(); + return client.create(UserService.class).deactivateUsers(data); + } + } + } + + @Data + @EqualsAndHashCode(callSuper = true) + public static class UserDeactivateManyResponse extends StreamResponseObject { + @JsonProperty("task_id") + private String taskId; + + @JsonProperty("duration") + private String duration; + } + + @Builder( + builderClassName = "UserReactivateManyRequest", + builderMethodName = "", + buildMethodName = "internalBuild") + @Getter + @EqualsAndHashCode + public static class UserReactivateManyRequestData { + @NotNull + @JsonProperty("user_ids") + private List userIds; + + @Nullable + @JsonProperty("created_by_id") + private String createdById; + + @Nullable + @JsonProperty("restore_channels") + private Boolean restoreChannels; + + @Nullable + @JsonProperty("restore_messages") + private Boolean restoreMessages; + + public static class UserReactivateManyRequest + extends StreamRequest { + @Override + protected Call generateCall(Client client) + throws StreamException { + var data = this.internalBuild(); + return client.create(UserService.class).reactivateUsers(data); + } + } + } + + @Data + @EqualsAndHashCode(callSuper = true) + public static class UserReactivateManyResponse extends StreamResponseObject { + @JsonProperty("task_id") + private String taskId; + + @JsonProperty("duration") + private String duration; + } + @Builder( builderClassName = "UserReactivateRequest", builderMethodName = "", @@ -1334,8 +1422,33 @@ public static UserDeleteRequest delete(@NotNull String userId) { * @return the created request */ @NotNull - public static UserDeleteManyRequest deleteMany(@NotNull List userIds) { - return new UserDeleteManyRequest().userIds(userIds); + public static UserDeleteManyRequestData.UserDeleteManyRequest deleteMany( + @NotNull List userIds) { + return new UserDeleteManyRequestData.UserDeleteManyRequest().userIds(userIds); + } + + /** + * Creates a deactivate users request + * + * @param userIds list of user ids to be deactivated + * @return the created request + */ + @NotNull + public static UserDeactivateManyRequestData.UserDeactivateManyRequest deactivateUsers( + @NotNull List userIds) { + return new UserDeactivateManyRequestData.UserDeactivateManyRequest().userIds(userIds); + } + + /** + * Creates a reactivate users request + * + * @param userIds list of user ids to be reactivated + * @return the created request + */ + @NotNull + public static UserReactivateManyRequestData.UserReactivateManyRequest reactivateUsers( + @NotNull List userIds) { + return new UserReactivateManyRequestData.UserReactivateManyRequest().userIds(userIds); } /** diff --git a/src/main/java/io/getstream/chat/java/services/UserService.java b/src/main/java/io/getstream/chat/java/services/UserService.java index d6032e30e..9dd3e6018 100644 --- a/src/main/java/io/getstream/chat/java/services/UserService.java +++ b/src/main/java/io/getstream/chat/java/services/UserService.java @@ -39,6 +39,10 @@ Call delete( @Nullable @Query("hard_delete") Boolean hardDelete, @Nullable @Query("delete_conversation_channels") Boolean deleteConversationChannels); + @POST("users/deactivate") + Call deactivateUsers( + @NotNull @Body UserDeactivateManyRequestData userDeactivateManyRequestData); + @POST("users/delete") Call deleteMany(@NotNull @Body UserDeleteManyRequestData data); @@ -47,6 +51,10 @@ Call reactivate( @NotNull @Path("user_id") String userId, @NotNull @Body UserReactivateRequestData userReactivateRequestData); + @POST("users/reactivate") + Call reactivateUsers( + @NotNull @Body UserReactivateManyRequestData userReactivateManyRequestData); + @POST("moderation/mute") Call mute(@NotNull @Body UserMuteRequestData userMuteRequestData); From d24ba32874da14618992cba1ea2146799c35fa26 Mon Sep 17 00:00:00 2001 From: shodgetts Date: Thu, 4 Dec 2025 07:04:34 -0700 Subject: [PATCH 2/2] fixed formatting --- local.properties.example | 10 --- .../io/getstream/chat/java/models/User.java | 1 - .../java/io/getstream/chat/java/UserTest.java | 62 +++++++++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) delete mode 100644 local.properties.example diff --git a/local.properties.example b/local.properties.example deleted file mode 100644 index 76d4d108f..000000000 --- a/local.properties.example +++ /dev/null @@ -1,10 +0,0 @@ -ossrhUsername= -ossrhPassword= -signing.keyId= -signing.password= -signing.secretKeyRingFile= -sonatypeStagingProfileId= -io.getstream.chat.apiKey= -io.getstream.chat.apiSecret= -io.getstream.chat.url=https://chat.stream-io-api.com -io.getstream.chat.timeout=10000 diff --git a/src/main/java/io/getstream/chat/java/models/User.java b/src/main/java/io/getstream/chat/java/models/User.java index 7f03aada8..75818ce4d 100644 --- a/src/main/java/io/getstream/chat/java/models/User.java +++ b/src/main/java/io/getstream/chat/java/models/User.java @@ -10,7 +10,6 @@ import io.getstream.chat.java.models.User.UserBanRequestData.UserBanRequest; import io.getstream.chat.java.models.User.UserCreateGuestRequestData.UserCreateGuestRequest; import io.getstream.chat.java.models.User.UserDeactivateRequestData.UserDeactivateRequest; -import io.getstream.chat.java.models.User.UserDeleteManyRequestData.UserDeleteManyRequest; import io.getstream.chat.java.models.User.UserListRequestData.UserListRequest; import io.getstream.chat.java.models.User.UserMuteRequestData.UserMuteRequest; import io.getstream.chat.java.models.User.UserPartialUpdateRequestData.UserPartialUpdateRequest; diff --git a/src/test/java/io/getstream/chat/java/UserTest.java b/src/test/java/io/getstream/chat/java/UserTest.java index afc61d5c6..d302698d3 100644 --- a/src/test/java/io/getstream/chat/java/UserTest.java +++ b/src/test/java/io/getstream/chat/java/UserTest.java @@ -356,6 +356,68 @@ void whenDeleteManyUsersWithIllegalCondition_thenItFails() { }); } + @Test + @DisplayName("Can deactivate many users") + void whenDeactivateManyUsers_thenTaskIdIsReturned() { + var userIds = new ArrayList(); + + for (var i = 0; i < 3; i++) { + String userId = RandomStringUtils.randomAlphabetic(10); + UserUpsertRequest usersUpsertRequest = User.upsert(); + var userObject = UserRequestObject.builder().id(userId).name("User to deactivate").build(); + usersUpsertRequest.user(userObject); + Assertions.assertDoesNotThrow( + (ThrowingSupplier) usersUpsertRequest::request); + userIds.add(userId); + } + + Assertions.assertDoesNotThrow( + () -> { + var taskId = + User.deactivateUsers(userIds) + .createdById(testUserRequestObject.getId()) + .request() + .getTaskId(); + + Assertions.assertNotNull(taskId); + }); + } + + @Test + @DisplayName("Can reactivate many users") + void whenReactivateManyUsers_thenTaskIdIsReturned() { + var userIds = new ArrayList(); + + for (var i = 0; i < 3; i++) { + String userId = RandomStringUtils.randomAlphabetic(10); + UserUpsertRequest usersUpsertRequest = User.upsert(); + var userObject = UserRequestObject.builder().id(userId).name("User to reactivate").build(); + usersUpsertRequest.user(userObject); + Assertions.assertDoesNotThrow( + (ThrowingSupplier) usersUpsertRequest::request); + userIds.add(userId); + } + + // First deactivate them in bulk so they can be reactivated + Assertions.assertDoesNotThrow( + () -> + User.deactivateUsers(userIds) + .createdById(testUserRequestObject.getId()) + .request() + .getTaskId()); + + Assertions.assertDoesNotThrow( + () -> { + var taskId = + User.reactivateUsers(userIds) + .createdById(testUserRequestObject.getId()) + .request() + .getTaskId(); + + Assertions.assertNotNull(taskId); + }); + } + @DisplayName("Can mute user") @Test void whenMutingUser_thenIsMuted() {