diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/User.java b/user-manager-server/src/main/java/de/itvsh/kop/user/User.java index 99c8a9722443fb8bed03ef8caf47b372e895ff05..145d92dbf79f662eed14dd0b2adbbb3f65594e92 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/User.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/User.java @@ -57,8 +57,8 @@ public class User { public static final String LASTNAME_FIELD = "lastName"; public static final String FIRSTNAME_FIELD = "firstName"; public static final String USERNAME_FIELD = "username"; - static final String ORGANISATIONS_EINHEIT_IDS_FIELD = "organisationsEinheitIds"; - static final String NOTIFICATION_SEND_FOR_FIELD = "userSettings.notificationsSendFor"; + public static final String ORGANISATIONS_EINHEIT_IDS_FIELD = "organisationsEinheitIds"; + public static final String NOTIFICATION_SEND_FOR_FIELD = "userSettings.notificationsSendFor"; @JsonIgnore @BsonId diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java b/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java index 79533852c5d7b1ed85fbe753dac372140b2bf9d7..2ee4018ddbc6dd46ce6bf0a85033d3d68a782473 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/UserRepository.java @@ -25,7 +25,6 @@ package de.itvsh.kop.user; import static de.itvsh.kop.user.User.*; -import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -35,7 +34,6 @@ import org.bson.types.ObjectId; import de.itvsh.kop.common.logging.KopLogging; import de.itvsh.kop.user.common.errorhandling.ResourceNotFoundException; -import de.itvsh.kop.user.settings.NotificationsSendFor; import io.quarkus.mongodb.panache.PanacheMongoRepository; @ApplicationScoped @@ -48,8 +46,6 @@ class UserRepository implements PanacheMongoRepository<User> { EMAIL_FIELD + " like ?1"; private static final String AND_DELETED = " and deleted = ?2"; - - private static final String SEARCH_RECIPIENT_QUERY = ORGANISATIONS_EINHEIT_IDS_FIELD + " = ?1 and " + NOTIFICATION_SEND_FOR_FIELD + " = ?2"; private static final String UPDATE_UNSYNCED_USER_QUERY = LAST_SYNC_TIMESTAMP_FIELD + " < ?1"; public User updateUser(User userToUpdate) { @@ -80,10 +76,6 @@ class UserRepository implements PanacheMongoRepository<User> { return find(SEARCH_QUERY + AND_DELETED, "/.*" + query + "*/i", deleted).range(0, limit - 1).stream(); } - public List<User> findRecipientByOrganisationsEinheitId(String organisationseinheitId) { - return find(SEARCH_RECIPIENT_QUERY, organisationseinheitId, NotificationsSendFor.ALL.name()).list(); - } - public long updateUnsyncedUsers(long lastSyncTimestamp) { return update(DELETED_FIELD, true).where(UPDATE_UNSYNCED_USER_QUERY, lastSyncTimestamp); } @@ -92,4 +84,4 @@ class UserRepository implements PanacheMongoRepository<User> { return findByIdOptional(user.getId()) .orElse(findByExternalId(user.getExternalId()).orElseThrow(() -> new ResourceNotFoundException(User.class, user.getExternalId()))); } -} +} \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/UserResourceMapper.java b/user-manager-server/src/main/java/de/itvsh/kop/user/UserResourceMapper.java index 930db5ccedf04d288dcfcf0f95523abae28e7c7d..8759f9450f75518b28395204f18d9721386a3c3e 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/UserResourceMapper.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/UserResourceMapper.java @@ -27,6 +27,7 @@ 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; @@ -68,7 +69,7 @@ public abstract class UserResourceMapper { Date mapCreatedAt(UserResource userRes) { var createdAt = userRes.toRepresentation().getCreatedTimestamp(); - return createdAt != null ? new Date(createdAt) : new Date(); + return Optional.ofNullable(createdAt).map(Date::new).orElse(new Date()); } Set<String> mapOrganisationsEinheitIds(UserResource userRes) { @@ -79,10 +80,7 @@ public abstract class UserResourceMapper { private List<String> getOrganisationsEinheitIdsFromGroups(List<GroupRepresentation> groups) { return groups.stream() - .map(group -> { - var groupFromRealm = realm.getGroupByPath(group.getPath()); - return groupFromRealm != null ? groupFromRealm.getAttributes() : null; - }) + .map(this::mapGroup) .filter(Objects::nonNull) .map(attributeMap -> attributeMap.get(properties.organisationsEinheitIdKey())) .filter(Objects::nonNull) @@ -90,6 +88,12 @@ public abstract class UserResourceMapper { .toList(); } + private Map<String, List<String>> mapGroup(GroupRepresentation group) { + var groupFromRealm = realm.getGroupByPath(group.getPath()); + + return Optional.ofNullable(groupFromRealm).map(GroupRepresentation::getAttributes).orElse(null); + } + List<String> mapRoles(UserResource userRes) { var roleRepresentation = Optional.ofNullable(userRes.roles().getAll().getClientMappings()) .filter(Objects::nonNull) diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java index 5306416e269989e160ee6df9204209e59bf17fbd..29faba06212925767f2281d5a45d33a7c7ef245a 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/UserService.java @@ -23,7 +23,6 @@ */ package de.itvsh.kop.user; -import java.util.List; import java.util.Optional; import java.util.stream.Stream; @@ -81,14 +80,10 @@ public class UserService { repository.updateUnsyncedUsers(lastSyncTimestamp); } - public List<User> findRecipientByOrganisationsEinheitId(String organisationsEinheitId) { - return repository.findRecipientByOrganisationsEinheitId(organisationsEinheitId); - } - public User getById(String id) { if (id.contains(UUID_PATTERN)) { // TODO wenn user migriert wurden wieder entfernen. - return repository.findByExternalId(id).orElseThrow(() -> new ResourceNotFoundException(User.class, id)); + return findByExternalId(id); } return repository.findById(id).orElseThrow(() -> new ResourceNotFoundException(User.class, id)); diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/common/callcontext/GrpcUtil.java b/user-manager-server/src/main/java/de/itvsh/kop/user/common/callcontext/GrpcUtil.java index be21f7a6b4cc6a48b9651c77b4dca899b51020b9..07b3cfb40c353e8b94b6034103d22ad2f971a1ad 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/common/callcontext/GrpcUtil.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/common/callcontext/GrpcUtil.java @@ -10,7 +10,7 @@ import io.grpc.Metadata; import io.grpc.Metadata.Key; // TODO move to a grpcUtil class in common -public class GrpcUtil { +class GrpcUtil { public static Optional<String> getFromHeaders(String key, Metadata headers) { return Optional.ofNullable(headers.get(createKeyOf(key))) diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakClientException.java b/user-manager-server/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakClientException.java deleted file mode 100644 index 36ac5c5f33c54ad7c6b6bade0f67477ff6858028..0000000000000000000000000000000000000000 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/common/errorhandling/KeycloakClientException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.itvsh.kop.user.common.errorhandling; - -public class KeycloakClientException extends TechnicalException { - - private static final long serialVersionUID = 1L; - - private static final String MESSAGE_TEMPLATE = "Access Denied for admin user: %s, realm: %s, url: %s"; - - public KeycloakClientException(String user, String realm, String url, Throwable cause) { - super(String.format(MESSAGE_TEMPLATE, user, realm, url), cause); - } -} \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/common/errorhandling/UserNotFoundException.java b/user-manager-server/src/main/java/de/itvsh/kop/user/common/errorhandling/UserNotFoundException.java deleted file mode 100644 index d869f78bebfad4fdd2475985416f239f5b3dc757..0000000000000000000000000000000000000000 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/common/errorhandling/UserNotFoundException.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.itvsh.kop.user.common.errorhandling; - -public class UserNotFoundException extends TechnicalException { - - private static final long serialVersionUID = 1L; - - private static final String MESSAGE_WITH_EXTERNALID_TEMPLATE = "User not found for keycloak id %s"; - private static final String MESSAGE_WITH_ID_TEMPLATE = "User not found for id %s"; - - public UserNotFoundException(String id) { - super(String.format(MESSAGE_WITH_ID_TEMPLATE, id)); - } - - public UserNotFoundException(String externalId, Throwable cause) { - super(String.format(MESSAGE_WITH_EXTERNALID_TEMPLATE, externalId), cause); - } -} \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiService.java index 403fc8bd1e2076239aa5bedbd7a89bad908643b2..c0bdac2070c68ccc89045b1ae1e21a6a84b7834a 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiService.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/keycloak/KeycloakApiService.java @@ -33,11 +33,11 @@ import javax.inject.Inject; import javax.ws.rs.ClientErrorException; import javax.ws.rs.ProcessingException; -import de.itvsh.kop.common.logging.KopLogging; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.representations.idm.UserRepresentation; +import de.itvsh.kop.common.logging.KopLogging; import de.itvsh.kop.user.RemoteUserIterator; import de.itvsh.kop.user.User; import de.itvsh.kop.user.UserResourceMapper; @@ -74,7 +74,7 @@ class KeycloakApiService { return mapper.toKopUser(realmResource.users().get(userRepresentation.getId())); } - private <T> T handlingKeycloakException(Supplier<T> runnable) { + <T> T handlingKeycloakException(Supplier<T> runnable) { try { return runnable.get(); } catch (ClientErrorException | ProcessingException | IllegalStateException e) { diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientGrpcService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientGrpcService.java index b66c0bdac1aebc48cf10e7a4c25838bab79ec45b..585511220ac067c02248c7f0246776ef6540770a 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientGrpcService.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientGrpcService.java @@ -24,7 +24,6 @@ package de.itvsh.kop.user.recipient; import java.util.Collection; -import java.util.List; import javax.inject.Inject; @@ -45,14 +44,13 @@ public class RecipientGrpcService extends RecipientServiceImplBase { @Override public void findRecipientByOrganisationsEinheitId(GrpcFindRecipientRequest request, StreamObserver<GrpcFindRecipientResponse> responseObserver) { - List<User> recipients = recipientService.findRecipientByOrganisationsEinheitId(request.getOrganisationsEinheitId()); + var recipients = recipientService.findByOrganisationsEinheitId(request.getOrganisationsEinheitId()); - responseObserver.onNext(buildSearchReponse(recipients.stream().map(recipientMapper::toRecipient).toList())); + responseObserver.onNext(buildSearchReponse(recipients)); responseObserver.onCompleted(); } - private GrpcFindRecipientResponse buildSearchReponse(Collection<GrpcRecipient> recipients) { - return GrpcFindRecipientResponse.newBuilder().addAllRecipient(recipients).build(); - + private GrpcFindRecipientResponse buildSearchReponse(Collection<User> recipients) { + return GrpcFindRecipientResponse.newBuilder().addAllRecipient(recipients.stream().map(recipientMapper::toRecipient).toList()).build(); } -} +} \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientRepository.java b/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..dcebbee5daec02dca277310951821a20b29cda5d --- /dev/null +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientRepository.java @@ -0,0 +1,23 @@ +package de.itvsh.kop.user.recipient; + +import static de.itvsh.kop.user.User.*; + +import java.util.List; + +import javax.enterprise.context.ApplicationScoped; + +import de.itvsh.kop.common.logging.KopLogging; +import de.itvsh.kop.user.User; +import de.itvsh.kop.user.settings.NotificationsSendFor; +import io.quarkus.mongodb.panache.PanacheMongoRepository; + +@ApplicationScoped +@KopLogging +class RecipientRepository implements PanacheMongoRepository<User> { + + private static final String SEARCH_RECIPIENT_QUERY = ORGANISATIONS_EINHEIT_IDS_FIELD + " = ?1 and " + NOTIFICATION_SEND_FOR_FIELD + " = ?2"; + + public List<User> findByOrganisationsEinheitId(String organisationseinheitId) { + return find(SEARCH_RECIPIENT_QUERY, organisationseinheitId, NotificationsSendFor.ALL.name()).list(); + } +} \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientService.java index 922ee3eff17ec3302808852d6a0ac9c4d2d93e30..1f65e76a32008a7bf7030202633f76bce9f23545 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientService.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/recipient/RecipientService.java @@ -31,7 +31,6 @@ import javax.inject.Inject; import com.cronutils.utils.StringUtils; import de.itvsh.kop.user.User; -import de.itvsh.kop.user.UserService; import de.itvsh.kop.user.common.errorhandling.FunctionalException; @ApplicationScoped @@ -40,12 +39,12 @@ class RecipientService { static final String MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE = "OrganisationsEinheitId ('%s') can not be null or empty"; @Inject - UserService userService; + RecipientRepository repository; - public List<User> findRecipientByOrganisationsEinheitId(String organisationsEinheitId) { + public List<User> findByOrganisationsEinheitId(String organisationsEinheitId) { if (StringUtils.isEmpty(organisationsEinheitId)) { throw new FunctionalException(() -> String.format(MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE, organisationsEinheitId)); } - return userService.findRecipientByOrganisationsEinheitId(organisationsEinheitId); + return repository.findByOrganisationsEinheitId(organisationsEinheitId); } } \ No newline at end of file diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/settings/UserSettingsService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/settings/UserSettingsService.java index db61a750a743c31fb4605c0146ab1e5a8eb237a2..a22acb22fc7091f2425d6f72ef0029546c368293 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/settings/UserSettingsService.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/settings/UserSettingsService.java @@ -31,7 +31,7 @@ import javax.inject.Inject; import de.itvsh.kop.user.UserService; @ApplicationScoped -public class UserSettingsService { +class UserSettingsService { @Inject UserService userService; @@ -43,10 +43,6 @@ public class UserSettingsService { return repository.updateByUserId(userId, userSettings); } - public UserSettings findByUserId(String userId) { - return userService.getById(userId).getUserSettings(); - } - public UserSettings getByUserId(String userId) { var user = userService.getById(userId); diff --git a/user-manager-server/src/main/java/de/itvsh/kop/user/userprofile/UserProfileGrpcService.java b/user-manager-server/src/main/java/de/itvsh/kop/user/userprofile/UserProfileGrpcService.java index 2561d97f954e711e72316d8b16efc8a929f1fdd4..38d8c517a48733610171badb402e683c6903071b 100644 --- a/user-manager-server/src/main/java/de/itvsh/kop/user/userprofile/UserProfileGrpcService.java +++ b/user-manager-server/src/main/java/de/itvsh/kop/user/userprofile/UserProfileGrpcService.java @@ -25,6 +25,7 @@ package de.itvsh.kop.user.userprofile; import javax.inject.Inject; +import de.itvsh.kop.user.User; import de.itvsh.kop.user.UserService; import de.itvsh.kop.user.grpc.userprofile.GrpcGetUserProfileRequest; import de.itvsh.kop.user.grpc.userprofile.GrpcGetUserProfileResponse; @@ -44,7 +45,11 @@ public class UserProfileGrpcService extends UserProfileServiceImplBase { public void getById(GrpcGetUserProfileRequest request, StreamObserver<GrpcGetUserProfileResponse> responseObserver) { var userProfile = service.getById(request.getUserId()); - responseObserver.onNext(GrpcGetUserProfileResponse.newBuilder().setUserProfile(mapper.mapTo(userProfile)).build()); + responseObserver.onNext(buildResponse(userProfile)); responseObserver.onCompleted(); } + + private GrpcGetUserProfileResponse buildResponse(User userProfile) { + return GrpcGetUserProfileResponse.newBuilder().setUserProfile(mapper.mapTo(userProfile)).build(); + } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java index 6e56fcccbb75eef637f9af8ed91f8f362d3c22ab..431a32167c76082aa3d6fc9faabf799c15633ccc 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryITCase.java @@ -23,7 +23,6 @@ */ package de.itvsh.kop.user; -import static de.itvsh.kop.user.settings.NotificationsSendFor.*; import static java.util.function.Predicate.not; import static org.assertj.core.api.Assertions.*; @@ -40,7 +39,6 @@ import org.junit.jupiter.api.Test; import com.thedeanda.lorem.LoremIpsum; import de.itvsh.kop.user.common.MongoDbTestProfile; -import de.itvsh.kop.user.settings.UserSettings; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.TestProfile; @@ -246,18 +244,6 @@ class UserRepositoryITCase { assertThat(startWithMax.stream().filter(not(User::isDeleted)).count()).isEqualTo(1); } - @Test - void shouldFindByOrganisationeinheitIdAndNotificatinoActivated() { - var recipientUser = UserTestFactory.createBuilder().userSettings(new UserSettings(ALL)).build(); - var notRecipientUser = UserTestFactory.createBuilder().organisationsEinheitIds(List.of("a")).build(); - repository.persist(List.of(notRecipientUser, recipientUser)); - - var users = repository.findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); - - assertThat(users).hasSize(1); - assertThat(users.get(0).getOrganisationsEinheitIds()).contains(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); - } - @Test void shouldUseLimit() { repository.persist(UserTestFactory.create()); @@ -284,30 +270,4 @@ class UserRepositoryITCase { assertThat(user).isNotNull().hasFieldOrPropertyWithValue("id", user1.getId()); } } - - @DisplayName("Test for empty result list ") - @Nested - class TestReturnEmptyList { - @Test - void whenIdNotFound() { - var recipientUser = UserTestFactory.createBuilder().userSettings(new UserSettings(ALL)).build(); - repository.persist(recipientUser); - var users = repository.findRecipientByOrganisationsEinheitId("some_id"); - assertThat(users).isEmpty(); - } - - @Test - void whenNotificationDeactivated() { - - var users = repository.findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); - assertThat(users).isEmpty(); - } - - @Test - void shouldReturnEmptyListNotificationDeactivated() { - var users = repository.findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); - - assertThat(users).isEmpty(); - } - } -} +} \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/UserResourceMapperTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/UserResourceMapperTest.java index b863d0bf77774efe7e1c6cb8d82ea85543d7b921..0b03b88eccc01b2390f7fab1669b5397bbf3d48f 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/UserResourceMapperTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/UserResourceMapperTest.java @@ -39,7 +39,6 @@ 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; @@ -49,6 +48,7 @@ import org.mockito.Mock; import de.itvsh.kop.user.keycloak.KeycloakApiProperties; class UserResourceMapperTest { + static final String ORGANISATIONS_EINHEIT_ID_KEY = "organisationseinheitId"; static final String ORGANISATIONS_EINHEIT_ID_1 = "0815"; static final String ORGANISATIONS_EINHEIT_ID_2 = "4711"; @@ -59,16 +59,17 @@ class UserResourceMapperTest { static final Map<String, List<String>> ATTRIBUTES_2 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_2)); @InjectMocks - private UserResourceMapper mapper = Mappers.getMapper(UserResourceMapper.class); + UserResourceMapper mapper = Mappers.getMapper(UserResourceMapper.class); @Mock - private KeycloakApiProperties properties; + KeycloakApiProperties properties; @Mock - private RealmResource realm; + RealmResource realm; + @DisplayName("To kop user") @Nested - class TestMapping { + class TestToKopUser { @BeforeEach void init() { @@ -84,80 +85,96 @@ class UserResourceMapperTest { @Test void shouldMapToUser() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + var user = toKopUser(); assertThat(user).isNotNull(); } @Test void shouldMapEmail() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + var user = toKopUser(); assertThat(user.getEmail()).isEqualTo(UserRepresentationTestFactory.EMAIL); } - @Test - void shouldMapExternalId() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + @DisplayName("externalId") + @Nested + class TestMapExternalId { - assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID); - } + @Test + void shouldMap() { + var user = toKopUser(); - @Test - void shouldMapExternalIdFallback() { - User user = mapper.toKopUser(UserResourceTestFactory.createWithAttributes(Map.of())); + assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID); + } + + @Test + void shouldMapFallbackOnEmptyAttributes() { + var user = toKopUser(UserResourceTestFactory.createWithAttributes(Collections.emptyMap())); - assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID_FALLBACK); + assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID_FALLBACK); + } } @Test void shouldMapFirstName() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + var user = toKopUser(); assertThat(user.getFirstName()).isEqualTo(UserRepresentationTestFactory.FIRST_NAME); } @Test void shouldMapLastName() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + var user = toKopUser(); assertThat(user.getLastName()).isEqualTo(UserRepresentationTestFactory.LAST_NAME); } @Test void shouldMapUserName() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + var user = toKopUser(); assertThat(user.getUsername()).isEqualTo(UserRepresentationTestFactory.USER_NAME); } @Test void shouldMapOrganisationsEinheitIds() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + var user = toKopUser(); assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().contains(ORGANISATIONS_EINHEIT_ID_1); } @Test void shouldMapMultipleOrganisationsEinheitIds() { - GroupRepresentation groupRepresentation = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_2_PATH, + var groupRepresentation = GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_2_PATH, ORGANISATIONS_EINHEIT_ID_2); - when(realm.getGroupByPath(GROUP_2_PATH)).thenReturn(groupRepresentation); - User user = mapper.toKopUser( - UserResourceTestFactory.createWithGroups(List.of(GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_1_PATH), - GroupRepresentationTestFactory.createGroup(UserResourceMapperTest.GROUP_2_PATH)))); + 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))); + } + @Test void shouldMapRoles() { - User user = mapper.toKopUser(UserResourceTestFactory.create()); + var user = toKopUser(); assertThat(user.getRoles()).isNotEmpty().contains(UserRepresentationTestFactory.ROLE_NAME); } + + private User toKopUser() { + return toKopUser(UserResourceTestFactory.create()); + } + + private User toKopUser(UserResource userResource) { + return mapper.toKopUser(userResource); + } } @DisplayName("Get client roles") @@ -165,18 +182,18 @@ class UserResourceMapperTest { class TestGetClientRoles { @Mock - private UserResource userResource; + UserResource userResource; @Mock - private RoleMappingResource roleMappingResource; + RoleMappingResource roleMappingResource; @Mock - private RoleScopeResource roleScopeResource; + RoleScopeResource roleScopeResource; @Mock - private MappingsRepresentation mappingsRepresentation; + MappingsRepresentation mappingsRepresentation; @Mock - private Map<String, ClientMappingsRepresentation> clientMappingsRepresentation; + Map<String, ClientMappingsRepresentation> clientMappingsRepresentation; @Mock - private ClientMappingsRepresentation clientMappingRepresentation; + ClientMappingsRepresentation clientMappingRepresentation; @BeforeEach void init() { diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java index 7bf81cd55b2ab07e26b19473a2fd192a87c41a8e..10db77a921a4d539eb9303877608a2f2ba79786d 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/UserServiceTest.java @@ -23,6 +23,7 @@ */ package de.itvsh.kop.user; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -39,6 +40,7 @@ import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import de.itvsh.kop.user.common.errorhandling.ResourceNotFoundException; import de.itvsh.kop.user.keycloak.KeycloakUserRemoteService; class UserServiceTest { @@ -50,26 +52,64 @@ class UserServiceTest { @Mock KeycloakUserRemoteService keycloakRemoteService; - @DisplayName("Find by id") + @DisplayName("Get by id") @Nested - class TestFindById { + class TestGetById { - @Test - void shouldFindByIdOnInternalId() { - when(repository.findById(anyString())).thenReturn(Optional.of(UserTestFactory.create())); + @DisplayName("on UUID pattern") + @Nested + class TestByUUID { + + private final static String ID = UUID.randomUUID().toString(); + + @BeforeEach + void mockRepository() { + when(repository.findByExternalId(any())).thenReturn(Optional.of(UserTestFactory.create())); + } + + @Test + void shouldCallRepository() { + service.getById(ID); + + verify(repository).findByExternalId(anyString()); + } - service.getById("xxx"); + @Test + void shouldThrowExceptionIfNotExists() { + when(repository.findByExternalId(anyString())).thenReturn(Optional.empty()); - verify(repository).findById(anyString()); + assertThatThrownBy(() -> service.getById(ID)) + .isInstanceOf(ResourceNotFoundException.class) + .extracting(e -> ((ResourceNotFoundException) e).getId()).isEqualTo(ID); + } } - @Test - void shouldFindByExternalIdOnUUID() { - when(repository.findByExternalId(any())).thenReturn(Optional.of(UserTestFactory.create())); + @DisplayName("on other") + @Nested + class TestByOther { + + private final static String ID = "xxx"; + + @BeforeEach + void mockRepository() { + when(repository.findById(anyString())).thenReturn(Optional.of(UserTestFactory.create())); + } + + @Test + void shouldCallRepository() { + service.getById(ID); - service.getById(UUID.randomUUID().toString()); + verify(repository).findById(anyString()); + } - verify(repository).findByExternalId(anyString()); + @Test + void shouldThrowExceptionIfNotExists() { + when(repository.findById(anyString())).thenReturn(Optional.empty()); + + assertThatThrownBy(() -> service.getById(ID)) + .isInstanceOf(ResourceNotFoundException.class) + .extracting(e -> ((ResourceNotFoundException) e).getId()).isEqualTo(ID); + } } } @@ -136,18 +176,6 @@ class UserServiceTest { } } - @DisplayName("Find recipient by organisationsEinheitId") - @Nested - class TestFindRecipientByOrganisationsEinheitId { - - @Test - void shouldCallRepository() { - service.findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); - - verify(repository).findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); - } - } - @DisplayName("Search users") @Nested class TestUserSearch { diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/common/errorhandling/ApiErrorUtilTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/common/errorhandling/ApiErrorUtilTest.java index 0f3583495f45be250f719bab29375e174d020cd7..b6a67a5f36cb1d329da467d7301d2c93ae0089c5 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/common/errorhandling/ApiErrorUtilTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/common/errorhandling/ApiErrorUtilTest.java @@ -201,4 +201,11 @@ class ApiErrorUtilTest { return util.buildFromKeycloakUnavailableException(exception); } } + + @Test + void shouldCreateExceptionId() { + var exceptionId = util.createExceptionId(); + + assertThat(exceptionId).isNotNull(); + } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceTest.java index 4003592a8dd8560feb97c96ae1455fff115ea184..152a2fe30d3bec4e423dbe12aaa155dc1edd9192 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/keycloak/KeycloakApiServiceTest.java @@ -23,11 +23,16 @@ */ package de.itvsh.kop.user.keycloak; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.function.Supplier; import java.util.stream.Stream; +import javax.ws.rs.ClientErrorException; +import javax.ws.rs.ProcessingException; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -45,6 +50,7 @@ import de.itvsh.kop.user.User; import de.itvsh.kop.user.UserRepresentationTestFactory; import de.itvsh.kop.user.UserResourceMapper; import de.itvsh.kop.user.UserTestFactory; +import de.itvsh.kop.user.common.errorhandling.KeycloakUnavailableException; class KeycloakApiServiceTest { @@ -98,4 +104,34 @@ class KeycloakApiServiceTest { verify(userResourceMapper).toKopUser(any(UserResource.class)); } } + + @DisplayName("handling keycloak exception") + @Nested + class TestHandlingKeycloakException { + + @Test + void shouldThrowOnClientErrorException() { + assertThatThrownBy(() -> handlingKeyCloakException(() -> { + throw new ClientErrorException(403); + })).isInstanceOf(KeycloakUnavailableException.class); + } + + @Test + void shouldThrowOnProcessingException() { + assertThatThrownBy(() -> handlingKeyCloakException(() -> { + throw new ProcessingException(new RuntimeException()); + })).isInstanceOf(KeycloakUnavailableException.class); + } + + @Test + void shouldThrowIllegalStateException() { + assertThatThrownBy(() -> handlingKeyCloakException(() -> { + throw new IllegalStateException(new RuntimeException()); + })).isInstanceOf(KeycloakUnavailableException.class); + } + + private <T> T handlingKeyCloakException(Supplier<T> runnable) { + return service.handlingKeycloakException(runnable); + } + } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientGrpcServiceTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientGrpcServiceTest.java index 360abd0df1e5cc822478891d557517d42205975c..ed3567f9d1be37e8d8990febdec4be4d0700acc9 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientGrpcServiceTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientGrpcServiceTest.java @@ -62,11 +62,11 @@ class RecipientGrpcServiceTest { @Test void shouldGetUsersFromRepository() { - when(recipientService.findRecipientByOrganisationsEinheitId(any())).thenReturn(List.of(UserTestFactory.create())); + when(recipientService.findByOrganisationsEinheitId(any())).thenReturn(List.of(UserTestFactory.create())); recipientGrpcService.findRecipientByOrganisationsEinheitId(RecipientTestFactory.FIND_REQUEST, streamObserver); - verify(recipientService).findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + verify(recipientService).findByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); } } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientMapperTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientMapperTest.java index 721c12a4f697c95b9dbaa14a5ee10dc9253d8bba..c360d315f56294fe98d1b74da17d6a1ede222719 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientMapperTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientMapperTest.java @@ -26,6 +26,7 @@ package de.itvsh.kop.user.recipient; import static org.assertj.core.api.Assertions.*; import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -68,5 +69,10 @@ class RecipientMapperTest { assertThat(recipient.getEmail()).isEqualTo(StringUtils.EMPTY); } + + @Test + void shouldNotThrowExceptionOnNull() { + Assertions.assertDoesNotThrow(() -> mapper.toRecipient(null)); + } } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientRepositoryITCase.java b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientRepositoryITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..34f8f13b572b828b4de160898f6d9757d72785b8 --- /dev/null +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientRepositoryITCase.java @@ -0,0 +1,104 @@ +package de.itvsh.kop.user.recipient; + +import static de.itvsh.kop.user.settings.NotificationsSendFor.*; +import static org.assertj.core.api.Assertions.*; + +import javax.inject.Inject; + +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.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.EnumSource.Mode; + +import de.itvsh.kop.user.User; +import de.itvsh.kop.user.UserTestFactory; +import de.itvsh.kop.user.common.MongoDbTestProfile; +import de.itvsh.kop.user.settings.NotificationsSendFor; +import de.itvsh.kop.user.settings.UserSettingsTestFactory; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.TestProfile; + +@QuarkusTest +@TestProfile(MongoDbTestProfile.class) +class RecipientRepositoryITCase { + + @Inject + RecipientRepository repository; + + @DisplayName("Find by organisationsEinheitId") + @Nested + class TestFindByOrganisationsEinheitId { + + @BeforeEach + void clearDb() { + repository.deleteAll(); + } + + @DisplayName("with given organisationsEinheitId") + @Nested + class TestWithGivenOrganisationsEinheitId { + + private static final User USER_NOTIFICATION_SEND_FOR_ALL = UserTestFactory.createBuilder().userSettings( + UserSettingsTestFactory.createBuilder().notificationsSendFor(ALL).build()) + .build(); + + @Test + void shouldReturnOnMatch() { + persist(USER_NOTIFICATION_SEND_FOR_ALL); + + var userList = repository.findByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + + assertThat(userList).hasSize(1); + assertThat(userList.get(0)).usingRecursiveComparison().isEqualTo(USER_NOTIFICATION_SEND_FOR_ALL); + } + + @Test + void shouldReturnEmptyListOnNonMatch() { + persist(USER_NOTIFICATION_SEND_FOR_ALL); + + var userList = repository.findByOrganisationsEinheitId("nonMatch"); + + assertThat(userList).isEmpty(); + } + } + + @DisplayName("by notificationSendFor") + @Nested + class TestByNotificationSendFor { + + private static final User USER_NOTIFICATION_SEND_FOR_ALL = UserTestFactory.createBuilder().userSettings( + UserSettingsTestFactory.createBuilder().notificationsSendFor(ALL).build()) + .build(); + + @Test + void shouldReturnOnAll() { + persist(USER_NOTIFICATION_SEND_FOR_ALL); + + var userList = repository.findByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + + assertThat(userList).hasSize(1); + assertThat(userList.get(0)).usingRecursiveComparison().isEqualTo(USER_NOTIFICATION_SEND_FOR_ALL); + } + + @ParameterizedTest + @EnumSource(mode = Mode.EXCLUDE, names = { "ALL" }) + void shouldNotReturnOn(NotificationsSendFor sendFor) { + var user = UserTestFactory.createBuilder().userSettings( + UserSettingsTestFactory.createBuilder().notificationsSendFor(sendFor).build()) + .build(); + persist(user); + + var userList = repository.findByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + + assertThat(userList).isEmpty(); + } + } + + private void persist(User user) { + repository.persist(user); + } + } +} \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientServiceTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientServiceTest.java index e5a37bbed38e58de0d59d7ec4dc976d22b496d0c..dc816a3b4eb510e57a12fbaa8447b13d580718a9 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientServiceTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/recipient/RecipientServiceTest.java @@ -34,7 +34,6 @@ import org.mockito.Mock; import com.cronutils.utils.StringUtils; -import de.itvsh.kop.user.UserService; import de.itvsh.kop.user.UserTestFactory; import de.itvsh.kop.user.common.errorhandling.FunctionalException; @@ -43,11 +42,11 @@ class RecipientServiceTest { @InjectMocks RecipientService service; @Mock - UserService userService; + RecipientRepository repository; - @DisplayName("Find recipient by organisationsEinheitId") + @DisplayName("Find by organisationsEinheitId") @Nested - class TestFindRecipientByOrganisationsEinheitId { + class TestFindByOrganisationsEinheitId { private static final String EXPECTED_EXCEPTION_MESSAGE_TEMPLATE = "Functional error: " + RecipientService.MISSING_ORGANISATIONS_EINHEIT_ID_MESSAGE_TEMPLATE; @@ -57,7 +56,7 @@ class RecipientServiceTest { var expectedMessage = String.format(EXPECTED_EXCEPTION_MESSAGE_TEMPLATE, "null"); assertThatExceptionOfType(FunctionalException.class) - .isThrownBy(() -> service.findRecipientByOrganisationsEinheitId(null)) + .isThrownBy(() -> service.findByOrganisationsEinheitId(null)) .withMessageStartingWith(expectedMessage); } @@ -66,15 +65,15 @@ class RecipientServiceTest { var expectedMessage = String.format(EXPECTED_EXCEPTION_MESSAGE_TEMPLATE, StringUtils.EMPTY); assertThatExceptionOfType(FunctionalException.class) - .isThrownBy(() -> service.findRecipientByOrganisationsEinheitId(StringUtils.EMPTY)) + .isThrownBy(() -> service.findByOrganisationsEinheitId(StringUtils.EMPTY)) .withMessageStartingWith(expectedMessage); } @Test - void shouldCallUserService() { - service.findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + void shouldCallRepository() { + service.findByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); - verify(userService).findRecipientByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); + verify(repository).findByOrganisationsEinheitId(UserTestFactory.ORGANISTATIONSEINHEITEN_ID); } } } \ No newline at end of file diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/settings/UserSettingsServiceTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/settings/UserSettingsServiceTest.java index 48a873ab8f6aa326de0ae92648e450a15af2f687..7c7e7c2b1dfdaee7997f9aaeec56fd2176900727 100644 --- a/user-manager-server/src/test/java/de/itvsh/kop/user/settings/UserSettingsServiceTest.java +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/settings/UserSettingsServiceTest.java @@ -103,7 +103,7 @@ class UserSettingsServiceTest { @BeforeEach void mockUserService() { when(userService.getById(anyString())) - .thenReturn(UserTestFactory.createBuilder().userSettings(UserSettingsTestFactory.create()).build()); + .thenReturn(UserTestFactory.createBuilder().userSettings(null).build()); } @Test