From 67794159fc53cac106a47d1ea0c6c057ae742c75 Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Mon, 23 Sep 2024 17:43:38 +0200 Subject: [PATCH] OZG-5031 OZG-6794 Implement grpc interface to provide list of user profiles including user settings belonging to Organisationseinheit --- .vscode/settings.json | 4 + .../src/main/protobuf/recipient.model.proto | 1 + .../src/main/protobuf/recipient.proto | 6 +- .../src/main/protobuf/userprofile.model.proto | 17 ++++ .../src/main/protobuf/userprofile.proto | 2 + .../java/de/ozgcloud/user/UserRepository.java | 7 +- .../java/de/ozgcloud/user/UserService.java | 19 +++-- .../user/recipient/RecipientGrpcService.java | 1 + .../user/recipient/RecipientMapper.java | 1 + .../user/recipient/RecipientRepository.java | 1 + .../user/recipient/RecipientService.java | 3 +- .../user/settings/UserSettingsMapper.java | 25 ++++++ .../userprofile/UserProfileGrpcService.java | 26 ++++-- .../user/userprofile/UserProfileMapper.java | 5 +- .../ozgcloud/user/UserRepositoryITCase.java | 53 +++++++++--- .../de/ozgcloud/user/UserRepositoryTest.java | 40 ++++++++-- .../de/ozgcloud/user/UserServiceTest.java | 41 ++++++++++ .../de/ozgcloud/user/UserTestFactory.java | 4 +- .../settings/GrpcUserSettingsTestFactory.java | 48 +++++++++++ .../user/settings/UserSettingsMapperTest.java | 23 ++++++ ...anisationsEinheitIdRequestTestFactory.java | 19 +++++ ...nisationsEinheitIdResponseTestFactory.java | 17 ++++ .../GrpcUserProfileTestFactory.java | 4 +- .../UserProfileGrpcServiceTest.java | 80 +++++++++++++++++++ .../userprofile/UserProfileMapperTest.java | 8 ++ 25 files changed, 422 insertions(+), 33 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 user-manager-server/src/main/java/de/ozgcloud/user/settings/UserSettingsMapper.java create mode 100644 user-manager-server/src/test/java/de/ozgcloud/user/settings/GrpcUserSettingsTestFactory.java create mode 100644 user-manager-server/src/test/java/de/ozgcloud/user/settings/UserSettingsMapperTest.java create mode 100644 user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdRequestTestFactory.java create mode 100644 user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdResponseTestFactory.java diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..9bd06c2e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic", + "java.debug.settings.onBuildFailureProceed": true +} \ No newline at end of file diff --git a/user-manager-interface/src/main/protobuf/recipient.model.proto b/user-manager-interface/src/main/protobuf/recipient.model.proto index 5c286982..5f07b59f 100644 --- a/user-manager-interface/src/main/protobuf/recipient.model.proto +++ b/user-manager-interface/src/main/protobuf/recipient.model.proto @@ -30,6 +30,7 @@ option java_package = "de.ozgcloud.user.recipient"; option java_outer_classname = "RecipientModelProto"; message GrpcRecipient { + option deprecated = true; string firstName = 1; string lastName = 2; string email = 3; diff --git a/user-manager-interface/src/main/protobuf/recipient.proto b/user-manager-interface/src/main/protobuf/recipient.proto index bbaae80c..8c3d9b27 100644 --- a/user-manager-interface/src/main/protobuf/recipient.proto +++ b/user-manager-interface/src/main/protobuf/recipient.proto @@ -32,13 +32,17 @@ option java_package = "de.ozgcloud.user.grpc.recipient"; option java_outer_classname = "RecipientProto"; service RecipientService { - rpc findRecipientByOrganisationsEinheitId(GrpcFindRecipientRequest) returns (GrpcFindRecipientResponse); + rpc findRecipientByOrganisationsEinheitId(GrpcFindRecipientRequest) returns (GrpcFindRecipientResponse){ + option deprecated = true; + }; } message GrpcFindRecipientRequest { + option deprecated = true; string organisationsEinheitId = 1; } message GrpcFindRecipientResponse { + option deprecated = true; repeated GrpcRecipient recipient = 1; } \ No newline at end of file diff --git a/user-manager-interface/src/main/protobuf/userprofile.model.proto b/user-manager-interface/src/main/protobuf/userprofile.model.proto index 0a5db433..910054b1 100644 --- a/user-manager-interface/src/main/protobuf/userprofile.model.proto +++ b/user-manager-interface/src/main/protobuf/userprofile.model.proto @@ -34,6 +34,15 @@ message GrpcUserProfile { string firstName = 2; string lastName = 3; string email = 4; + GrpcUserSettings userSettings = 5; +} + +message GrpcUserSettings { + bool notificationsSendForAll = 1; + bool vorgangCreated = 2; + bool vorgangAssignedToUser = 3; + bool postfachNachrichtFromAntragsteller = 4; + bool wiedervorlageOverdue = 5; } @@ -45,6 +54,14 @@ message GrpcGetUserProfileResponse { GrpcUserProfile userProfile = 1; } +message GrpcGetAllByOrganisationsEinheitIdRequest{ + string organisationsEinheitId = 1; +} + +message GrpcGetAllByOrganisationsEinheitIdResponse{ + repeated GrpcUserProfile userProfile = 1; +} + message GrpcFindInactiveUserIdsResponse { repeated GrpcUserProfileId userProfileIds = 1; } diff --git a/user-manager-interface/src/main/protobuf/userprofile.proto b/user-manager-interface/src/main/protobuf/userprofile.proto index ab445da5..0b22ea51 100644 --- a/user-manager-interface/src/main/protobuf/userprofile.proto +++ b/user-manager-interface/src/main/protobuf/userprofile.proto @@ -37,6 +37,8 @@ service UserProfileService { rpc GetByExternalId(GrpcGetUserProfileRequest) returns (GrpcGetUserProfileResponse); + rpc GetAllByOrganisationsEinheitId(GrpcGetAllByOrganisationsEinheitIdRequest) returns (GrpcGetAllByOrganisationsEinheitIdResponse); + rpc FindInactiveUserIds(GrpcFindInactiveUserIdsRequest) returns (GrpcFindInactiveUserIdsResponse); rpc DeleteInactiveUser(GrpcDeleteInactiveUserRequest) returns (GrpcDeleteInactiveUserResponse); diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/UserRepository.java b/user-manager-server/src/main/java/de/ozgcloud/user/UserRepository.java index 56f1b35b..df9598eb 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/UserRepository.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/UserRepository.java @@ -28,13 +28,14 @@ import static de.ozgcloud.user.User.*; import java.util.Optional; import java.util.stream.Stream; +import jakarta.enterprise.context.ApplicationScoped; + import org.bson.types.ObjectId; import de.ozgcloud.common.logging.OzgCloudLogging; import de.ozgcloud.user.common.errorhandling.ResourceNotFoundException; import io.quarkus.mongodb.panache.PanacheMongoRepository; import io.quarkus.panache.common.Parameters; -import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped @OzgCloudLogging @@ -127,6 +128,10 @@ class UserRepository implements PanacheMongoRepository<User> { return find(DELETED_FIELD, true).project(UserIdProjection.class).stream().map(UserIdProjection::getAsString); } + public Stream<User> findAllUsersByOrganisationsEinheitId(String organisationsEinheitId) { + return stream(ORGANISATIONS_EINHEIT_IDS_FIELD, organisationsEinheitId); + } + public void deleteById(String id) { deleteById(new ObjectId(id)); } diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/UserService.java b/user-manager-server/src/main/java/de/ozgcloud/user/UserService.java index 27edabcc..2fd9d63a 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/UserService.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/UserService.java @@ -28,26 +28,28 @@ import java.util.Optional; import java.util.stream.Stream; import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; import org.apache.commons.lang3.StringUtils; import de.ozgcloud.common.logging.OzgCloudLogging; +import de.ozgcloud.user.common.errorhandling.FunctionalException; import de.ozgcloud.user.common.errorhandling.ResourceNotFoundException; import de.ozgcloud.user.common.errorhandling.TechnicalException; import de.ozgcloud.user.keycloak.KeycloakUserRemoteService; import de.ozgcloud.user.settings.UserSettings; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.infrastructure.Infrastructure; +import lombok.RequiredArgsConstructor; @ApplicationScoped @OzgCloudLogging +@RequiredArgsConstructor public class UserService { - @Inject - UserRepository repository; - @Inject - KeycloakUserRemoteService keycloakUserRemoteService; + static final String MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE = "OrganisationsEinheitId ('%s') can not be null or empty"; + + private final UserRepository repository; + private final KeycloakUserRemoteService keycloakUserRemoteService; public User save(User user) { findUser(user).ifPresentOrElse(persistedUser -> repository.updateUser(addIdUser(user, persistedUser)), @@ -146,4 +148,11 @@ public class UserService { throw new TechnicalException(String.format("Deleting active users is not allowed [user id: %s].", user.getId().toHexString())); } } + + public Stream<User> findAllUsersOfOrganisationsEinheit(String organisationsEinheitId) { + if (StringUtils.isEmpty(organisationsEinheitId)) { + throw new FunctionalException(() -> String.format(MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE, organisationsEinheitId)); + } + return repository.findAllUsersByOrganisationsEinheitId(organisationsEinheitId); + } } \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientGrpcService.java b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientGrpcService.java index fa9dc41d..ab0ebdd2 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientGrpcService.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientGrpcService.java @@ -35,6 +35,7 @@ import io.grpc.stub.StreamObserver; import io.quarkus.grpc.GrpcService; @GrpcService +@Deprecated public class RecipientGrpcService extends RecipientServiceImplBase { @Inject diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientMapper.java b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientMapper.java index bea3d985..334c81ea 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientMapper.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientMapper.java @@ -34,6 +34,7 @@ import de.ozgcloud.user.User; unmappedSourcePolicy = ReportingPolicy.WARN, // nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, // collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +@Deprecated interface RecipientMapper { GrpcRecipient toRecipient(User user); diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientRepository.java b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientRepository.java index 17482b93..f076298b 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientRepository.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientRepository.java @@ -15,6 +15,7 @@ import io.quarkus.mongodb.panache.PanacheMongoRepository; @ApplicationScoped @OzgCloudLogging +@Deprecated class RecipientRepository implements PanacheMongoRepository<User> { private static final String SEARCH_RECIPIENT_QUERY = ORGANISATIONS_EINHEIT_IDS_FIELD + " = ?1 and " diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientService.java b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientService.java index b383eceb..c6444739 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientService.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/recipient/RecipientService.java @@ -25,15 +25,16 @@ package de.ozgcloud.user.recipient; import java.util.List; -import de.ozgcloud.user.common.errorhandling.FunctionalException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import com.cronutils.utils.StringUtils; import de.ozgcloud.user.User; +import de.ozgcloud.user.common.errorhandling.FunctionalException; @ApplicationScoped +@Deprecated class RecipientService { static final String MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE = "OrganisationsEinheitId ('%s') can not be null or empty"; diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/settings/UserSettingsMapper.java b/user-manager-server/src/main/java/de/ozgcloud/user/settings/UserSettingsMapper.java new file mode 100644 index 00000000..329078be --- /dev/null +++ b/user-manager-server/src/main/java/de/ozgcloud/user/settings/UserSettingsMapper.java @@ -0,0 +1,25 @@ +package de.ozgcloud.user.settings; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; + +import de.ozgcloud.user.userprofile.GrpcUserSettings; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface UserSettingsMapper { + + @Mapping(target = "mergeFrom", ignore = true) + @Mapping(target = "clearField", ignore = true) + @Mapping(target = "clearOneof", ignore = true) + @Mapping(target = "mergeUnknownFields", ignore = true) + @Mapping(target = "unknownFields", ignore = true) + @Mapping(target = "allFields", ignore = true) + @Mapping(target = "notificationsSendForAll", source = "notificationsSendFor") + GrpcUserSettings toGrpc(UserSettings userSettings); + + default boolean map(NotificationsSendFor sendFor) { + return NotificationsSendFor.ALL.equals(sendFor); + } +} diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileGrpcService.java b/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileGrpcService.java index c9d773be..b41ec61d 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileGrpcService.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileGrpcService.java @@ -25,22 +25,20 @@ package de.ozgcloud.user.userprofile; import java.util.stream.Stream; -import jakarta.inject.Inject; - import de.ozgcloud.user.User; import de.ozgcloud.user.UserService; import de.ozgcloud.user.grpc.userprofile.UserProfileServiceGrpc.UserProfileServiceImplBase; import io.grpc.stub.StreamObserver; import io.quarkus.grpc.GrpcService; +import lombok.RequiredArgsConstructor; @GrpcService +@RequiredArgsConstructor public class UserProfileGrpcService extends UserProfileServiceImplBase { - @Inject - UserService service; + private final UserService service; - @Inject - UserProfileMapper mapper; + private final UserProfileMapper mapper; @Override public void getById(GrpcGetUserProfileRequest request, StreamObserver<GrpcGetUserProfileResponse> responseObserver) { @@ -62,6 +60,22 @@ public class UserProfileGrpcService extends UserProfileServiceImplBase { responseObserver.onCompleted(); } + @Override + public void getAllByOrganisationsEinheitId(GrpcGetAllByOrganisationsEinheitIdRequest request, + StreamObserver<GrpcGetAllByOrganisationsEinheitIdResponse> responseObserver) { + + var userProfiles = service.findAllUsersOfOrganisationsEinheit(request.getOrganisationsEinheitId()); + + responseObserver.onNext(buildGrpcGetAllByOrganisationsEinheitIdResponse(userProfiles)); + responseObserver.onCompleted(); + } + + GrpcGetAllByOrganisationsEinheitIdResponse buildGrpcGetAllByOrganisationsEinheitIdResponse(Stream<User> users) { + return GrpcGetAllByOrganisationsEinheitIdResponse.newBuilder() + .addAllUserProfile(users.map(mapper::mapTo).toList()) + .build(); + } + @Override public void findInactiveUserIds(GrpcFindInactiveUserIdsRequest request, StreamObserver<GrpcFindInactiveUserIdsResponse> responseObserver) { var userIds = service.findAllInactiveUserIds(); diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileMapper.java b/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileMapper.java index c29c5e8d..3807a4bc 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileMapper.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/userprofile/UserProfileMapper.java @@ -30,9 +30,9 @@ import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.ReportingPolicy; import de.ozgcloud.user.User; +import de.ozgcloud.user.settings.UserSettingsMapper; -@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN, // - nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, uses = UserSettingsMapper.class) interface UserProfileMapper { @Mapping(target = "emailBytes", ignore = true) @@ -45,6 +45,7 @@ interface UserProfileMapper { @Mapping(target = "lastNameBytes", ignore = true) @Mapping(target = "unknownFields", ignore = true) @Mapping(target = "allFields", ignore = true) + @Mapping(target = "mergeUserSettings", ignore = true) GrpcUserProfile mapTo(User userProfile); default String toString(ObjectId objectId) { diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryITCase.java b/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryITCase.java index e8cf01e2..c8bec751 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryITCase.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryITCase.java @@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.*; import java.time.Instant; import java.util.Arrays; import java.util.List; +import java.util.UUID; import java.util.stream.Stream; import jakarta.inject.Inject; @@ -51,7 +52,7 @@ import io.quarkus.test.junit.TestProfile; class UserRepositoryITCase { @Inject - UserRepository repository; + private UserRepository repository; @DisplayName("Update unsynced users") @Nested @@ -249,8 +250,7 @@ class UserRepositoryITCase { Arrays.asList( UserTestFactory.createBuilder().id(null).username("user1").fullName("Franz Vogel").build(), UserTestFactory.createBuilder().id(null).username("user2").fullName("Franz von Holzhausen").build(), - UserTestFactory.createBuilder().id(null).username("user3").fullName("Peter Lustig").build() - ).forEach(repository::persist); + UserTestFactory.createBuilder().id(null).username("user3").fullName("Peter Lustig").build()).forEach(repository::persist); var foundUsernames = repository.findUsers(query, 10).map(User::getUsername); @@ -266,8 +266,7 @@ class UserRepositoryITCase { Arguments.of("Franz von", new String[] { "user2" }), Arguments.of("Franz von Holzhausen", new String[] { "user2" }), Arguments.of("Franz L", new String[0]), - Arguments.of("Peter V", new String[0]) - ); + Arguments.of("Peter V", new String[0])); } } @@ -285,8 +284,7 @@ class UserRepositoryITCase { Arrays.asList( UserTestFactory.createBuilder().id(null).username("user1").fullNameReversed("Langbein Franz").build(), UserTestFactory.createBuilder().id(null).username("user2").fullNameReversed("Lustig Peter").build(), - UserTestFactory.createBuilder().id(null).username("user3").fullNameReversed("Ilona Nowak").build() - ).forEach(repository::persist); + UserTestFactory.createBuilder().id(null).username("user3").fullNameReversed("Ilona Nowak").build()).forEach(repository::persist); var foundUsernames = repository.findUsers(query, 10).map(User::getUsername); @@ -297,8 +295,7 @@ class UserRepositoryITCase { return Stream.of( Arguments.of("L", new String[] { "user1", "user2", "user3" }), Arguments.of("Lustig", new String[] { "user2" }), - Arguments.of("Lustig Peter", new String[] { "user2" }) - ); + Arguments.of("Lustig Peter", new String[] { "user2" })); } } @@ -573,6 +570,44 @@ class UserRepositoryITCase { } } + @Nested + class TestFindAllUsersByOrganisationsEinheitId { + + private static final String ORGANISATIONSEINHEIT_ID_1 = UUID.randomUUID().toString(); + private static final String ORGANISATIONSEINHEIT_ID_2 = UUID.randomUUID().toString(); + + private final User user1 = UserTestFactory.createBuilder() + .id(null) + .clearOrganisationsEinheitIds() + .organisationsEinheitId(ORGANISATIONSEINHEIT_ID_1) + .build(); + private final User user2 = UserTestFactory.createBuilder() + .id(null) + .clearOrganisationsEinheitIds() + .organisationsEinheitId(ORGANISATIONSEINHEIT_ID_1) + .build(); + private final User user3 = UserTestFactory.createBuilder() + .id(null) + .clearOrganisationsEinheitIds() + .organisationsEinheitId(ORGANISATIONSEINHEIT_ID_2) + .build(); + + @BeforeEach + void init() { + repository.deleteAll(); + repository.persist(user1); + repository.persist(user2); + repository.persist(user3); + } + + @Test + void shouldFindUsersByOrganisationsEinheitId() { + var users = repository.findAllUsersByOrganisationsEinheitId(ORGANISATIONSEINHEIT_ID_1); + + assertThat(users).usingRecursiveFieldByFieldElementComparator().containsExactlyInAnyOrder(user1, user2); + } + } + @Nested class TestDeleteById { diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryTest.java b/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryTest.java index 98c81190..3ca1e919 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryTest.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/UserRepositoryTest.java @@ -30,6 +30,7 @@ import static org.mockito.Mockito.*; import java.util.Date; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; import org.assertj.core.api.Condition; import org.bson.types.ObjectId; @@ -49,12 +50,12 @@ import io.quarkus.panache.common.Parameters; class UserRepositoryTest { @Spy - UserRepository userRepository; + private UserRepository userRepository; @Mock - PanacheQuery<User> panacheQuery; + private PanacheQuery<User> panacheQuery; - User user = UserTestFactory.create(); + private final User user = UserTestFactory.create(); @DisplayName("Test updating users") @Nested @@ -190,15 +191,42 @@ class UserRepositoryTest { assertThatExceptionOfType(ResourceNotFoundException.class).isThrownBy(() -> userRepository.refresh(UserTestFactory.create())); // NOSONAR } } - + @Nested class TestToRegex { - + @Test - void shouldReturnRegex(){ + void shouldReturnRegex() { var regex = userRepository.toRegex("abc"); assertThat(regex).isEqualTo("/.*abc.*/i"); } } + + @Nested + class TestFindAllUsersByOrganisationsEinheitId { + + @BeforeEach + void mock() { + doReturn(Stream.of(user)).when(userRepository).stream(User.ORGANISATIONS_EINHEIT_IDS_FIELD, UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @Test + void shouldFindUsers() { + callRepository(); + + verify(userRepository).stream(User.ORGANISATIONS_EINHEIT_IDS_FIELD, UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnStreamOfUsers() { + var users = callRepository(); + + assertThat(users).containsExactly(user); + } + + private Stream<User> callRepository() { + return userRepository.findAllUsersByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + } } diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/UserServiceTest.java b/user-manager-server/src/test/java/de/ozgcloud/user/UserServiceTest.java index 434d3555..c9f783ae 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/UserServiceTest.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/UserServiceTest.java @@ -38,10 +38,13 @@ import org.bson.types.ObjectId; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.NullAndEmptySource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; +import de.ozgcloud.user.common.errorhandling.FunctionalException; import de.ozgcloud.user.common.errorhandling.ResourceNotFoundException; import de.ozgcloud.user.common.errorhandling.TechnicalException; import de.ozgcloud.user.keycloak.KeycloakUserRemoteService; @@ -399,4 +402,42 @@ class UserServiceTest { verify(repository).persist(user); } } + + @Nested + class TestFindAllUsersOfOrganisationsEinheit { + + private static final String EXPECTED_EXCEPTION_MESSAGE_TEMPLATE = "Functional error: " + + UserService.MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE; + + @Test + void shouldCallRepository() { + callService(); + + verify(repository).findAllUsersByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnFoundUsers() { + var users = Stream.of(UserTestFactory.create()); + when(repository.findAllUsersByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID)).thenReturn(users); + + var returnedUsers = callService(); + + assertThat(returnedUsers).isEqualTo(users); + } + + private Stream<User> callService() { + return service.findAllUsersOfOrganisationsEinheit(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowFunctionalExceptionOnInvalidOrganisationsId(String organisationsEinheitId) { + var expectedMessage = String.format(EXPECTED_EXCEPTION_MESSAGE_TEMPLATE, organisationsEinheitId); + + assertThatExceptionOfType(FunctionalException.class) + .isThrownBy(() -> service.findAllUsersOfOrganisationsEinheit(organisationsEinheitId)) + .withMessageStartingWith(expectedMessage); + } + } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/UserTestFactory.java b/user-manager-server/src/test/java/de/ozgcloud/user/UserTestFactory.java index fc8e1524..42927031 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/UserTestFactory.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/UserTestFactory.java @@ -27,6 +27,7 @@ import java.util.List; import org.bson.types.ObjectId; +import de.ozgcloud.user.settings.UserSettings; import de.ozgcloud.user.settings.UserSettingsTestFactory; public class UserTestFactory { @@ -45,6 +46,7 @@ public class UserTestFactory { public static final String EXTERNAL_ID = "aec115b5-67be-42c9-a693-36d4d711a87a"; public static final String ORGANISTATIONSEINHEITEN_ID = "0815"; public static final List<String> ROLES = List.of("ROLE_1", "POSTSTELLE"); + public static final UserSettings USER_SETTINGS = UserSettingsTestFactory.create(); public static User create() { return createBuilder().build(); @@ -64,6 +66,6 @@ public class UserTestFactory { .externalId(EXTERNAL_ID) .organisationsEinheitId(ORGANISTATIONSEINHEITEN_ID) .roles(ROLES) - .userSettings(UserSettingsTestFactory.create()); + .userSettings(USER_SETTINGS); } } diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/settings/GrpcUserSettingsTestFactory.java b/user-manager-server/src/test/java/de/ozgcloud/user/settings/GrpcUserSettingsTestFactory.java new file mode 100644 index 00000000..39e625f6 --- /dev/null +++ b/user-manager-server/src/test/java/de/ozgcloud/user/settings/GrpcUserSettingsTestFactory.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den + * Ministerpräsidenten des Landes Schleswig-Holstein + * Staatskanzlei + * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.user.settings; + +import de.ozgcloud.user.userprofile.GrpcUserSettings; + +public class GrpcUserSettingsTestFactory { + + public static final boolean NOTIFICATIONS_SEND_FOR = NotificationsSendFor.ALL == UserSettingsTestFactory.NOTIFICATIONS_SEND_FOR; + public static final boolean VORGANG_CREATED = UserSettingsTestFactory.VORGANG_CREATED; + public static final boolean VORGANG_ASSIGNED_TO_USER = UserSettingsTestFactory.VORGANG_ASSIGNED_TO_USER; + public static final boolean POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER = UserSettingsTestFactory.POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER; + public static final boolean WIEDERVORLAGE_OVERDUE = UserSettingsTestFactory.WIEDERVORLAGE_OVERDUE; + + public static GrpcUserSettings create() { + return createBuilder().build(); + } + + public static GrpcUserSettings.Builder createBuilder() { + return GrpcUserSettings.newBuilder() + .setNotificationsSendForAll(NOTIFICATIONS_SEND_FOR) + .setVorgangCreated(VORGANG_CREATED) + .setVorgangAssignedToUser(VORGANG_ASSIGNED_TO_USER) + .setPostfachNachrichtFromAntragsteller(POSTFACH_NACHRICHT_FROM_ANTRAGSTELLER) + .setWiedervorlageOverdue(WIEDERVORLAGE_OVERDUE); + } +} \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/settings/UserSettingsMapperTest.java b/user-manager-server/src/test/java/de/ozgcloud/user/settings/UserSettingsMapperTest.java new file mode 100644 index 00000000..41c63661 --- /dev/null +++ b/user-manager-server/src/test/java/de/ozgcloud/user/settings/UserSettingsMapperTest.java @@ -0,0 +1,23 @@ +package de.ozgcloud.user.settings; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +class UserSettingsMapperTest { + + private final UserSettingsMapper mapper = Mappers.getMapper(UserSettingsMapper.class); + + @Nested + class TestToGrpc { + + @Test + void shouldMapToGrpc() { + var userSettings = mapper.toGrpc(UserSettingsTestFactory.create()); + + assertThat(userSettings).usingRecursiveComparison().isEqualTo(GrpcUserSettingsTestFactory.create()); + } + } +} diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdRequestTestFactory.java b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdRequestTestFactory.java new file mode 100644 index 00000000..32bbabc5 --- /dev/null +++ b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdRequestTestFactory.java @@ -0,0 +1,19 @@ +package de.ozgcloud.user.userprofile; + +import de.ozgcloud.user.UserTestFactory; +import de.ozgcloud.user.userprofile.GrpcGetAllByOrganisationsEinheitIdRequest.Builder; + +public class GrpcGetAllByOrganisationsEinheitIdRequestTestFactory { + + public static final String ORGANISTATIONSEINHEITEN_ID = UserTestFactory.ORGANISTATIONSEINHEITEN_ID; + + public static GrpcGetAllByOrganisationsEinheitIdRequest create() { + return createBuilder() + .build(); + } + + public static Builder createBuilder() { + return GrpcGetAllByOrganisationsEinheitIdRequest.newBuilder() + .setOrganisationsEinheitId(ORGANISTATIONSEINHEITEN_ID); + } +} diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdResponseTestFactory.java b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdResponseTestFactory.java new file mode 100644 index 00000000..de7b1c0d --- /dev/null +++ b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcGetAllByOrganisationsEinheitIdResponseTestFactory.java @@ -0,0 +1,17 @@ +package de.ozgcloud.user.userprofile; + +import de.ozgcloud.user.userprofile.GrpcGetAllByOrganisationsEinheitIdResponse.Builder; + +public class GrpcGetAllByOrganisationsEinheitIdResponseTestFactory { + + public static final GrpcUserProfile USER_PROFILE = GrpcUserProfileTestFactory.create(); + + public static GrpcGetAllByOrganisationsEinheitIdResponse create() { + return createBuilder().build(); + } + + public static Builder createBuilder() { + return GrpcGetAllByOrganisationsEinheitIdResponse.newBuilder() + .addUserProfile(USER_PROFILE); + } +} diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcUserProfileTestFactory.java b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcUserProfileTestFactory.java index 16fd8ad1..5146952f 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcUserProfileTestFactory.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/GrpcUserProfileTestFactory.java @@ -24,6 +24,7 @@ package de.ozgcloud.user.userprofile; import de.ozgcloud.user.UserTestFactory; +import de.ozgcloud.user.settings.GrpcUserSettingsTestFactory; public class GrpcUserProfileTestFactory { @@ -34,6 +35,7 @@ public class GrpcUserProfileTestFactory { public static GrpcUserProfile.Builder createBuilder() { return GrpcUserProfile.newBuilder() .setFirstName(UserTestFactory.FIRST_NAME) - .setLastName(UserTestFactory.LAST_NAME); + .setLastName(UserTestFactory.LAST_NAME) + .setUserSettings(GrpcUserSettingsTestFactory.create()); } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileGrpcServiceTest.java b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileGrpcServiceTest.java index 3b803854..1dbd5875 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileGrpcServiceTest.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileGrpcServiceTest.java @@ -157,6 +157,86 @@ class UserProfileGrpcServiceTest { } } + @Nested + class TestGetAllByOrganisationsEinheitId { + + @Mock + private StreamObserver<GrpcGetAllByOrganisationsEinheitIdResponse> streamObserver; + + private final Stream<User> users = Stream.of(UserTestFactory.create()); + private final GrpcGetAllByOrganisationsEinheitIdResponse response = GrpcGetAllByOrganisationsEinheitIdResponseTestFactory.create(); + + @BeforeEach + void mock() { + when(userService.findAllUsersOfOrganisationsEinheit(UserTestFactory.ORGANISTATIONSEINHEITEN_ID)).thenReturn(users); + } + + @Test + void shouldCallUserService() { + callService(); + + verify(userService).findAllUsersOfOrganisationsEinheit(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @Test + void shouldBuildGrpcGetAllByOrganisationsEinheitIdResponse() { + callService(); + + verify(grpcService).buildGrpcGetAllByOrganisationsEinheitIdResponse(users); + } + + @Test + void shouldCallOnNext() { + doReturn(response).when(grpcService).buildGrpcGetAllByOrganisationsEinheitIdResponse(users); + + callService(); + + verify(streamObserver).onNext(response); + } + + @Test + void shouldCallOnCompleted() { + callService(); + + verify(streamObserver).onCompleted(); + } + + private void callService() { + grpcService.getAllByOrganisationsEinheitId(GrpcGetAllByOrganisationsEinheitIdRequestTestFactory.create(), streamObserver); + } + } + + @Nested + class TestBuildGrpcGetAllByOrganisationsEinheitIdResponse { + + private final User user = UserTestFactory.create(); + private final Stream<User> users = Stream.of(user); + private GrpcUserProfile grpcUserProfile = GrpcUserProfileTestFactory.create(); + + @BeforeEach + void mock() { + when(mapper.mapTo(user)).thenReturn(grpcUserProfile); + } + + @Test + void shouldMapUser() { + callService(); + + verify(mapper).mapTo(user); + } + + @Test + void shouldMappedUsersInResponse() { + var response = callService(); + + assertThat(response.getUserProfileList()).containsExactly(grpcUserProfile); + } + + private GrpcGetAllByOrganisationsEinheitIdResponse callService() { + return grpcService.buildGrpcGetAllByOrganisationsEinheitIdResponse(users); + } + } + @Nested class TestBuildGrpcGetInactiveUserIdsResponse { diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileMapperTest.java b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileMapperTest.java index fa280033..83452481 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileMapperTest.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/userprofile/UserProfileMapperTest.java @@ -33,6 +33,7 @@ import org.mapstruct.factory.Mappers; import de.ozgcloud.user.User; import de.ozgcloud.user.UserTestFactory; +import de.ozgcloud.user.settings.GrpcUserSettingsTestFactory; class UserProfileMapperTest { @@ -70,6 +71,13 @@ class UserProfileMapperTest { assertThat(userProfile.getId()).isEqualTo(UserTestFactory.ID.toString()); } + @Test + void shouldMapUserSettings() { + var userProfile = map(); + + assertThat(userProfile.getUserSettings()).usingRecursiveComparison().isEqualTo(GrpcUserSettingsTestFactory.create()); + } + private GrpcUserProfile map() { return mapper.mapTo(UserTestFactory.create()); } -- GitLab