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/pom.xml b/pom.xml index 5622af5e1fc40961b954a0e352343f68903daa06..7633d613f0cb38c3ddd1c896a4e6ac1da3ae3f2f 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>de.ozgcloud.user</groupId> <artifactId>user-manager</artifactId> - <version>2.9.0-SNAPSHOT</version> + <version>2.10.0-SNAPSHOT</version> <name>OZG-Cloud User Manager</name> <packaging>pom</packaging> diff --git a/user-manager-interface/pom.xml b/user-manager-interface/pom.xml index b24fa1e2caf62d79e09c292faa5e688ef1f351a3..028aa511a95b6aef5a68c71980f2ad1b69ed62e7 100644 --- a/user-manager-interface/pom.xml +++ b/user-manager-interface/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>de.ozgcloud.user</groupId> <artifactId>user-manager</artifactId> - <version>2.9.0-SNAPSHOT</version> + <version>2.10.0-SNAPSHOT</version> </parent> <artifactId>user-manager-interface</artifactId> 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/pom.xml b/user-manager-server/pom.xml index 9ae6f04364246aeb50383a357bb3b6ced675832b..30b89952f8fd31988a10ecbcf375025b274a45c6 100644 --- a/user-manager-server/pom.xml +++ b/user-manager-server/pom.xml @@ -30,7 +30,7 @@ <parent> <groupId>de.ozgcloud.user</groupId> <artifactId>user-manager</artifactId> - <version>2.9.0-SNAPSHOT</version> + <version>2.10.0-SNAPSHOT</version> </parent> <artifactId>user-manager-server</artifactId> 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 8ec6521d461c0e0111126cc9a0549d0fe44480db..3dcb5399889bfcacf4a4d8ab1511fa38f64344da 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 @@ -54,8 +55,9 @@ class UserRepository implements PanacheMongoRepository<User> { EMAIL_FIELD + " like " + param(PARAM_NAME_SEARCH_BY); private static final String AND_DELETED = " and deleted = " + param(PARAM_NAME_DELETED); - private static final String AND_ORGANISATIONS_EINHEIT_ID_IN = " and " + ORGANISATIONS_EINHEIT_IDS_FIELD + " in " + param( + private static final String ORGANISATIONS_EINHEIT_ID_IN_QUERY = ORGANISATIONS_EINHEIT_IDS_FIELD + " in " + param( PARAM_NAME_ORGANISATIONS_EINHEIT_ID); + private static final String AND_ORGANISATIONS_EINHEIT_ID_IN = " and " + ORGANISATIONS_EINHEIT_ID_IN_QUERY; static final String UPDATE_UNSYNCED_USER_QUERY = LAST_SYNC_TIMESTAMP_FIELD + " < " + param(PARAM_NAME_TIMESTAMP); private static String param(String paramName) { @@ -127,6 +129,13 @@ class UserRepository implements PanacheMongoRepository<User> { return find(DELETED_FIELD, true).project(UserIdProjection.class).stream().map(UserIdProjection::getAsString); } + public Stream<User> findAllActiveByOrganisationsEinheitId(String organisationsEinheitId) { + var params = Parameters.with(PARAM_NAME_ORGANISATIONS_EINHEIT_ID, organisationsEinheitId) + .and(PARAM_NAME_DELETED, false); + + return find(ORGANISATIONS_EINHEIT_ID_IN_QUERY + AND_DELETED, params).stream(); + } + public void deleteById(String id) { deleteById(new ObjectId(id)); } diff --git a/user-manager-server/src/main/java/de/ozgcloud/user/UserResourceMapper.java b/user-manager-server/src/main/java/de/ozgcloud/user/UserResourceMapper.java index 52f53b25185c18d5c163bdb4ff695a0adc353266..f9f2486ea48654c5493876af69f760f9b1367daf 100644 --- a/user-manager-server/src/main/java/de/ozgcloud/user/UserResourceMapper.java +++ b/user-manager-server/src/main/java/de/ozgcloud/user/UserResourceMapper.java @@ -23,18 +23,20 @@ */ package de.ozgcloud.user; +import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; import jakarta.inject.Inject; +import org.apache.commons.lang3.StringUtils; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.representations.idm.ClientMappingsRepresentation; @@ -78,18 +80,27 @@ public abstract class UserResourceMapper { Set<String> mapOrganisationsEinheitIds(UserResource userRes) { var groups = userRes.groups(); - var organisationsEinheitIds = getOrganisationsEinheitIdsFromGroups(groups); - return new HashSet<>(organisationsEinheitIds); + return Stream.concat( + getOrganisationsEinheitIdsFromGroups(groups), + getOrganisationsEinheitIdsFromUser(userRes) + ) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toSet()); } - private List<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) { + private Stream<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) { return groups.stream() .map(this::mapGroup) .filter(Objects::nonNull) .map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey())) - .filter(Objects::nonNull) - .map(attributeValues -> attributeValues.get(0)) - .toList(); + .flatMap(Collection::stream); + } + + private Stream<String> getOrganisationsEinheitIdsFromUser(UserResource userRes) { + return getUserAttributes(userRes) + .map(attributes -> attributes.get(properties.organisationsEinheitIdKey())) + .orElse(Collections.emptyList()) + .stream(); } private Map<String, List<String>> mapGroup(GroupRepresentation group) { @@ -113,7 +124,7 @@ public abstract class UserResourceMapper { return Optional.ofNullable(userRepresentation.getAttributes()) .map(attributes -> attributes.get(properties.ldapIdKey())) - .map(id -> id.get(0)) + .map(List::getFirst) .orElseGet(userRepresentation::getId); } @@ -147,4 +158,8 @@ public abstract class UserResourceMapper { return String.join(" ", Stream.of(userRes.toRepresentation().getLastName(), userRes.toRepresentation().getFirstName()) .filter(Objects::nonNull).toArray(String[]::new)); } + + private Optional<Map<String, List<String>>> getUserAttributes(UserResource userResource) { + return Optional.ofNullable(userResource.toRepresentation().getAttributes()); + } } 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..b3ec71cd83f23369acf075fcb09e087bad98e5f8 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> findAllActiveUsersOfOrganisationsEinheit(String organisationsEinheitId) { + if (StringUtils.isEmpty(organisationsEinheitId)) { + throw new FunctionalException(() -> String.format(MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE, organisationsEinheitId)); + } + return repository.findAllActiveByOrganisationsEinheitId(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..23a0782f7e5dce49a04331efbe233670dd53f440 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.findAllActiveUsersOfOrganisationsEinheit(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/GroupRepresentationTestFactory.java b/user-manager-server/src/test/java/de/ozgcloud/user/GroupRepresentationTestFactory.java index fcc0dd786ad938ab75905d6b23e6efbde16cb725..ef6f392a0ca35993bd50422df19a42ac3a69367b 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/GroupRepresentationTestFactory.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/GroupRepresentationTestFactory.java @@ -35,12 +35,12 @@ class GroupRepresentationTestFactory { return group; } - public static GroupRepresentation createByPathAndOrganisationEinheitId(String groupPath, String organisationEinheitId) { + public static GroupRepresentation createByPathAndOrganisationEinheitIds(String groupPath, String... organisationEinheitIds) { var groupRepresentation = new GroupRepresentation(); groupRepresentation.setName(groupPath); groupRepresentation.setPath(groupPath); groupRepresentation.setAttributes(Map.of(UserResourceMapperTest.ORGANISATIONS_EINHEIT_ID_KEY, - List.of(organisationEinheitId))); + List.of(organisationEinheitIds))); return groupRepresentation; } } 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..f8a02a481fec06ac1a4e0931bd3d54f44e814b64 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,48 @@ class UserRepositoryITCase { } } + @Nested + class TestFindAllActiveByOrganisationsEinheitId { + + 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(); + private final User deletedUser = UserTestFactory.createBuilder() + .id(null) + .clearOrganisationsEinheitIds() + .organisationsEinheitId(ORGANISATIONSEINHEIT_ID_1) + .deleted(true) + .build(); + + @BeforeEach + void init() { + repository.deleteAll(); + repository.persist(user1, user2, user3, deletedUser); + } + + @Test + void shouldFindActiveUsersByOrganisationsEinheitId() { + var users = repository.findAllActiveByOrganisationsEinheitId(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..6a27221abb6084f64343aef9ffdd5d7da2ce8093 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,36 @@ 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 TestFindAllActiveByOrganisationsEinheitId { + + @BeforeEach + void mock() { + doReturn(Stream.of(user)).when(panacheQuery).stream(); + doReturn(panacheQuery).when(userRepository).find(anyString(), any(Parameters.class)); + } + + @Test + void shouldReturnStreamOfUsers() { + var users = callRepository(); + + assertThat(users).containsExactly(user); + } + + private Stream<User> callRepository() { + return userRepository.findAllActiveByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + } } diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceMapperTest.java b/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceMapperTest.java index d50c9ee0fca676dfa08335cc4d7fc16ff3f8c519..effcd75641189d1acd52922498cabd394175d55f 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceMapperTest.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceMapperTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.*; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -36,14 +37,15 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RoleMappingResource; -import org.keycloak.admin.client.resource.RoleScopeResource; import org.keycloak.admin.client.resource.UserResource; import org.keycloak.representations.idm.ClientMappingsRepresentation; +import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.MappingsRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.mapstruct.factory.Mappers; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import de.ozgcloud.user.keycloak.KeycloakApiProperties; @@ -55,9 +57,7 @@ class UserResourceMapperTest { static final String GROUP_1_PATH = "/group1"; static final String GROUP_2_PATH = "/group2"; - static final Map<String, List<String>> ATTRIBUTES_1 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_1)); - static final Map<String, List<String>> ATTRIBUTES_2 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_2)); - + @Spy @InjectMocks UserResourceMapper mapper = Mappers.getMapper(UserResourceMapper.class); @@ -67,6 +67,8 @@ class UserResourceMapperTest { @Mock RealmResource realm; + final Set<String> organisationsEinheitIds = Set.of(ORGANISATIONS_EINHEIT_ID_1); + @DisplayName("To kop user") @Nested class TestToKopUser { @@ -74,13 +76,8 @@ class UserResourceMapperTest { @BeforeEach void init() { when(properties.ldapIdKey()).thenReturn("LDAP_ID"); - when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId"); - when(properties.client()).thenReturn("alfa"); - when(realm.getGroupByPath(GROUP_1_PATH)) - .thenReturn(GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_1_PATH, ORGANISATIONS_EINHEIT_ID_1)); - when(properties.ldapIdKey()).thenReturn("LDAP_ID"); - when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId"); when(properties.client()).thenReturn("alfa"); + doReturn(organisationsEinheitIds).when(mapper).mapOrganisationsEinheitIds(any()); } @Test @@ -139,26 +136,9 @@ class UserResourceMapperTest { @Test void shouldMapOrganisationsEinheitIds() { - var user = toKopUser(); + var result = toKopUser(); - assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().contains(ORGANISATIONS_EINHEIT_ID_1); - } - - @Test - void shouldMapMultipleOrganisationsEinheitIds() { - var groupRepresentation = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_2_PATH, - ORGANISATIONS_EINHEIT_ID_2); - when(realm.getGroupByPath(GROUP_2_PATH)).thenReturn(groupRepresentation); - - var user = toKopUser(buildUserResourceWithGroups()); - - assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().hasSize(2).contains(ORGANISATIONS_EINHEIT_ID_2); - } - - private UserResource buildUserResourceWithGroups() { - return UserResourceTestFactory.createWithGroups(List.of( - GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_1_PATH), - GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_2_PATH))); + assertThat(result.getOrganisationsEinheitIds()).hasSameElementsAs(organisationsEinheitIds); } @Test @@ -198,6 +178,65 @@ class UserResourceMapperTest { } } + @DisplayName("Map organisations einheit ids") + @Nested + class TestMapOrganisationsEinheitIds { + static final String ORGANISATIONS_EINHEIT_ID_3 = "6287"; + private final GroupRepresentation group1 = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitIds( + GROUP_1_PATH, ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_3); + private final GroupRepresentation group2 = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitIds( + GROUP_2_PATH, ORGANISATIONS_EINHEIT_ID_2); + + @BeforeEach + void beforeEach() { + when(properties.organisationsEinheitIdKey()).thenReturn(ORGANISATIONS_EINHEIT_ID_KEY); + } + + @Test + void shouldMapOrganisationsEinheitIdsFromSingleGroup() { + var userResource = UserResourceTestFactory.createWithGroups(group1); + when(realm.getGroupByPath(GROUP_1_PATH)).thenReturn(group1); + + var result = mapper.mapOrganisationsEinheitIds(userResource); + + assertThat(result).containsExactlyInAnyOrder(ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_3); + } + + @Test + void shouldMapOrganisationsEinheitIdsFromGroups() { + var userResource = UserResourceTestFactory.createWithGroups(group1, group2); + when(realm.getGroupByPath(GROUP_1_PATH)).thenReturn(group1); + when(realm.getGroupByPath(GROUP_2_PATH)).thenReturn(group2); + + var result = mapper.mapOrganisationsEinheitIds(userResource); + + assertThat(result).containsExactlyInAnyOrder( + ORGANISATIONS_EINHEIT_ID_1, + ORGANISATIONS_EINHEIT_ID_2, + ORGANISATIONS_EINHEIT_ID_3 + ); + } + + @Test + void shouldMapOrganisationsEinheitIdsFromUser() { + var attributes = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_2)); + var userResource = UserResourceTestFactory.createWithAttributes(attributes); + + var result = mapper.mapOrganisationsEinheitIds(userResource); + + assertThat(result).containsExactlyInAnyOrder(ORGANISATIONS_EINHEIT_ID_1, ORGANISATIONS_EINHEIT_ID_2); + } + + @Test + void shouldReturnEmptyIfNoOrganisationsEinheitIds() { + var userResource = UserResourceTestFactory.create(); + + var result = mapper.mapOrganisationsEinheitIds(userResource); + + assertThat(result).isEmpty(); + } + } + @DisplayName("Get client roles") @Nested class TestGetClientRoles { @@ -208,8 +247,6 @@ class UserResourceMapperTest { @Mock RoleMappingResource roleMappingResource; @Mock - RoleScopeResource roleScopeResource; - @Mock MappingsRepresentation mappingsRepresentation; @Mock Map<String, ClientMappingsRepresentation> clientMappingsRepresentation; diff --git a/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceTestFactory.java b/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceTestFactory.java index 8de656cf0a2c8641d95ee03c699effe298d21937..2f13398abda21539fa80efbe44034aa99447ab38 100644 --- a/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceTestFactory.java +++ b/user-manager-server/src/test/java/de/ozgcloud/user/UserResourceTestFactory.java @@ -39,7 +39,7 @@ public class UserResourceTestFactory { return new UserResourceStub(attributes); } - public static UserResource createWithGroups(List<GroupRepresentation> groups) { - return new UserResourceStub(groups); + public static UserResource createWithGroups(GroupRepresentation... groups) { + return new UserResourceStub(List.of(groups)); } } 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..46c00810022af11bf87e562826c55c9d8b544044 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).findAllActiveByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @Test + void shouldReturnFoundUsers() { + var users = Stream.of(UserTestFactory.create()); + when(repository.findAllActiveByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID)).thenReturn(users); + + var returnedUsers = callService(); + + assertThat(returnedUsers).isEqualTo(users); + } + + private Stream<User> callService() { + return service.findAllActiveUsersOfOrganisationsEinheit(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowFunctionalExceptionOnInvalidOrganisationsId(String organisationsEinheitId) { + var expectedMessage = String.format(EXPECTED_EXCEPTION_MESSAGE_TEMPLATE, organisationsEinheitId); + + assertThatExceptionOfType(FunctionalException.class) + .isThrownBy(() -> service.findAllActiveUsersOfOrganisationsEinheit(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..1ec9cebe168d65bec3d444b61033826752159912 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.findAllActiveUsersOfOrganisationsEinheit(UserTestFactory.ORGANISTATIONSEINHEITEN_ID)).thenReturn(users); + doReturn(response).when(grpcService).buildGrpcGetAllByOrganisationsEinheitIdResponse(users); + } + + @Test + void shouldCallUserService() { + callService(); + + verify(userService).findAllActiveUsersOfOrganisationsEinheit(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