diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..9bd06c2e74db50ec5d22d49cf0108e70d1da3271 --- /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 5c286982bd5d030560df4ada71454fefcec937b8..5f07b59ff2567fabdad01b05038d9b9211127b30 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 bbaae80c221116bf348bba49aa67a1da12c6f02e..8c3d9b273c584960c3e3f647e5ffe09db2209b6e 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 0a5db4334318f844dca9c0bf1c96dcc07b4d405c..633775e1e224e6cbbc7e05bee02fbb838c285d02 100644 --- a/user-manager-interface/src/main/protobuf/userprofile.model.proto +++ b/user-manager-interface/src/main/protobuf/userprofile.model.proto @@ -34,8 +34,16 @@ 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 wiedervorlageDueToday = 5; +} message GrpcGetUserProfileRequest { string userId = 1; @@ -45,6 +53,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 ab445da50c1b7fa166a7d7baae574042f70bddd7..0b22ea5141227ef49ace738890da5d42f882a9d6 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 56f1b35b720162cdefd35edec85cc220787990de..7c6767505343751dc8d1bb4b9b106a08ab2bace5 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> findAllByOrganisationsEinheitId(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 27edabcc7dc9d0d1e2be4c549065298f1c4eca3e..b795174f565cc05876638619dabe7b2578fcbc49 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.findAllByOrganisationsEinheitId(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 fa9dc41d0d2f2079ac017b8cfc7b3335e0ab105b..ab0ebdd2f7d0f324171121fd234639f72750ed1b 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 bea3d98566fca973601f0139516bdcb3c0d5503c..334c81ea9051bc009b43c80fd000b8f99a4bca84 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 17482b933b614b1c6f36c61b58b064846937b907..f076298b30f0c1b47d6a2635de33f7957c13da63 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 b383eceb28d300bae59c83f8c692d05d7cf1e776..c64447393969054c2ada13c40ce2c5066207de60 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/UserSettings.java b/user-manager-server/src/main/java/de/ozgcloud/user/settings/UserSettings.java index f951133352e78f346a2c1c7fa8003f7acdb298ad..cc159625c8d1530fecf4e0c94f9238d262fc99d4 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/settings/UserSettings.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/settings/UserSettings.java @@ -36,6 +36,7 @@ public class UserSettings { public static final String NOTIFICATIONS_SEND_FOR_FIELD = "notificationsSendFor"; + @Deprecated private NotificationsSendFor notificationsSendFor; private boolean vorgangCreated; private boolean vorgangAssignedToUser; 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 0000000000000000000000000000000000000000..329078be5d3c381226adcbc66b0d36d30b8597fc --- /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 c9d773bed326d3465751c780baf122d39c7c7005..b41ec61d533b1a085fd738d96497588ba2147d93 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 c29c5e8d949d498714bc39c1fa38623b2c16f7fd..3807a4bca7807bafefd6a371a5b69227292281dc 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 e8cf01e27b347d8c4d93912f4fdcc6f27be59c30..b8bcd5e53438f537497048b95bfda7e07bcb95c4 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 TestFindAllByOrganisationsEinheitId { + + 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.findAllByOrganisationsEinheitId(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 98c81190f771301e7d9452acb42277da982c0cd8..635aaf22ff03e8245854c6bd3e6c2efb57049a2b 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 TestFindAllByOrganisationsEinheitId { + + @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.findAllByOrganisationsEinheitId(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 434d355536c0ccc3b261ad8557e9aeab7eda031d..447bd4c95368619cd26a69609d7feea5dd91d400 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).findAllByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnFoundUsers() { + var users = Stream.of(UserTestFactory.create()); + when(repository.findAllByOrganisationsEinheitId(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 fc8e1524b13bd267a2734f224601751bdd19aea9..4292703149d8a5fc94e41c06d55aecc6743d18fa 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 0000000000000000000000000000000000000000..461a1b3f28f68a648be47d666a9b09d4e94952cf --- /dev/null +++ b/user-manager-server/src/test/java/de/ozgcloud/user/settings/GrpcUserSettingsTestFactory.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2024 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_DUE_TODAY = UserSettingsTestFactory.WIEDERVORLAGE_DUE_TODAY; + + 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) + .setWiedervorlageDueToday(WIEDERVORLAGE_DUE_TODAY); + } +} \ 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 0000000000000000000000000000000000000000..41c6366177f29902c61485d2372dc26051260639 --- /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 0000000000000000000000000000000000000000..32bbabc55e0d05124a2e112e52e683fe3fc8c295 --- /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 0000000000000000000000000000000000000000..de7b1c0dcd975d189a58f6a2d47a123ba866325e --- /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 16fd8ad1742ccc8f91bfe9d037c9f481f9776126..5146952f18f7371d5fda9b2ad620410323c5851d 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 3b8038541b8de00c0392014cc886cb611710598a..330f65ac02198bc54e67fe32f8dcad60969a51ce 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,85 @@ 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); + doReturn(response).when(grpcService).buildGrpcGetAllByOrganisationsEinheitIdResponse(users); + } + + @Test + void shouldCallUserService() { + callService(); + + verify(userService).findAllUsersOfOrganisationsEinheit(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @Test + void shouldBuildGrpcGetAllByOrganisationsEinheitIdResponse() { + callService(); + + verify(grpcService).buildGrpcGetAllByOrganisationsEinheitIdResponse(users); + } + + @Test + void shouldCallOnNext() { + 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 fa280033555979187ac89125d3b219b44ff82429..625f7408c1083ce8a7527b76cf862d94c0d70f1a 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 @@ -24,59 +24,91 @@ package de.ozgcloud.user.userprofile; import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; +import org.mockito.InjectMocks; +import org.mockito.Mock; import de.ozgcloud.user.User; import de.ozgcloud.user.UserTestFactory; +import de.ozgcloud.user.settings.GrpcUserSettingsTestFactory; +import de.ozgcloud.user.settings.UserSettingsMapper; class UserProfileMapperTest { + @InjectMocks private UserProfileMapper mapper = Mappers.getMapper(UserProfileMapper.class); + @Mock + private UserSettingsMapper userSettingsMapper; + @DisplayName("Map to") @Nested class TestMapTo { - @Test - void shouldMapFirstName() { - var userProfile = map(); + @Nested + class OnValidArgument { - assertThat(userProfile.getFirstName()).isEqualTo(UserTestFactory.FIRST_NAME); - } + private GrpcUserSettings grpcUserSettings = GrpcUserSettingsTestFactory.create(); - @Test - void shouldMapLastName() { - var userProfile = map(); + @BeforeEach + void mockUserSettingsMapper() { + when(userSettingsMapper.toGrpc(UserTestFactory.USER_SETTINGS)).thenReturn(grpcUserSettings); + } - assertThat(userProfile.getLastName()).isEqualTo(UserTestFactory.LAST_NAME); - } + @Test + void shouldMapFirstName() { + var userProfile = map(); - @Test - void shouldMapEMail() { - var userProfile = map(); + assertThat(userProfile.getFirstName()).isEqualTo(UserTestFactory.FIRST_NAME); + } - assertThat(userProfile.getEmail()).isEqualTo(UserTestFactory.EMAIL); - } + @Test + void shouldMapLastName() { + var userProfile = map(); - @Test - void shouldMapId() { - var userProfile = map(); + assertThat(userProfile.getLastName()).isEqualTo(UserTestFactory.LAST_NAME); + } - assertThat(userProfile.getId()).isEqualTo(UserTestFactory.ID.toString()); - } + @Test + void shouldMapEMail() { + var userProfile = map(); + + assertThat(userProfile.getEmail()).isEqualTo(UserTestFactory.EMAIL); + } - private GrpcUserProfile map() { - return mapper.mapTo(UserTestFactory.create()); + @Test + void shouldMapId() { + var userProfile = map(); + + assertThat(userProfile.getId()).isEqualTo(UserTestFactory.ID.toString()); + } + + @Test + void shouldMapUserSettings() { + var userProfile = map(); + + assertThat(userProfile.getUserSettings()).isEqualTo(grpcUserSettings); + } + + private GrpcUserProfile map() { + return mapper.mapTo(UserTestFactory.create()); + } } - @Test - void shouldProceedWithNull() { - Assertions.assertDoesNotThrow(() -> mapper.mapTo(User.builder().build())); + @Nested + class OnEmptyUser { + + @Test + void shouldProceedWithNull() { + Assertions.assertDoesNotThrow(() -> mapper.mapTo(User.builder().build())); + } } } } \ No newline at end of file