diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..94b1bc5594d8e3ba20313df5e6402327e6a3e975 --- /dev/null +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/UserRepositoryTest.java @@ -0,0 +1,183 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.assertj.core.api.Condition; +import org.bson.types.ObjectId; +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.mockito.Mock; +import org.mockito.Spy; + +import de.itvsh.kop.user.common.errorhandling.ResourceNotFoundException; +import io.quarkus.mongodb.panache.PanacheQuery; +import io.quarkus.mongodb.panache.common.PanacheUpdate; + +class UserRepositoryTest { + @Spy + UserRepository userRepository; + + @Mock + PanacheQuery<User> panacheQuery; + + User user = UserTestFactory.create(); + + @DisplayName("Test updating users") + @Nested + class TestUpdate { + + @Test + void shouldCallUpdate() { + doReturn(UserTestFactory.create()).when(userRepository).findById(any(ObjectId.class)); + doNothing().when(userRepository).update(any(User.class)); + + userRepository.updateUser(UserTestFactory.create()); + + verify(userRepository, times(2)).findById(any(ObjectId.class)); + verify(userRepository).update(any(User.class)); + } + + @Test + void shouldMarkUserAsDeleted() { + PanacheUpdate update = mock(PanacheUpdate.class); + doReturn(update).when(userRepository).update(anyString(), anyBoolean()); + long timestamp = new Date().getTime(); + + userRepository.updateUnsyncedUsers(timestamp); + + verify(userRepository).update(User.DELETED_FIELD, true); + verify(update).where("lastSyncTimestamp < ?1", timestamp); + } + } + + @DisplayName("Test loading users") + @Nested + class TestFind { + + @Test + void shouldFindByExternalId() { + doReturn(Optional.of(user)).when(panacheQuery).firstResultOptional(); + doReturn(panacheQuery).when(userRepository).find(anyString(), anyString()); + + var userOpt = userRepository.findByExternalId(UserTestFactory.EXTERNAL_ID); + + assertThat(userOpt).isPresent().get().isEqualTo(user); + } + + @Test + void shouldFindByEmail() { + doReturn(Optional.of(user)).when(panacheQuery).firstResultOptional(); + doReturn(panacheQuery).when(userRepository).find(anyString(), anyString()); + + var userOpt = userRepository.findByEmail(UserTestFactory.EMAIL); + + assertThat(userOpt).isPresent().get().isEqualTo(user); + } + + @Test + void shouldFindById() { + doReturn(Optional.of(user)).when(userRepository).findByIdOptional(UserTestFactory.ID); + + var userOpt = userRepository.findById(UserTestFactory.ID.toHexString()); + + assertThat(userOpt).isPresent().get().isEqualTo(user); + } + + @DisplayName("handle loading list of users") + @Nested + class TestFindUsers { + Condition<User> cond = new Condition<>(value -> value.equals(user), "User expected"); + + @Mock + PanacheQuery<?> rangeQuery; + + @BeforeEach + void init() { + doReturn(List.of(UserTestFactory.create()).stream()).when(rangeQuery).stream(); + doReturn(rangeQuery).when(panacheQuery).range(anyInt(), anyInt()); + } + + @Test + void shouldFindUsers() { + doReturn(panacheQuery).when(userRepository).find(anyString(), anyString()); + + var userStream = userRepository.findUsers(UserTestFactory.USER_NAME, 1); + + assertThat(userStream).areExactly(0, cond); + } + + @Test + void shouldFindDeletedUsers() { + doReturn(panacheQuery).when(userRepository).find(anyString(), anyString(), anyBoolean()); + + var userStream = userRepository.findUsers(UserTestFactory.USER_NAME, true, 1); + + assertThat(userStream).areExactly(0, cond); + } + } + } + + @DisplayName("Test refreshing a user") + @Nested + class TestRefresh { + @Test + void shouldRefreshUserById() { + doReturn(Optional.of(user)).when(userRepository).findByIdOptional(UserTestFactory.ID); + doReturn(Optional.of(user)).when(panacheQuery).firstResultOptional(); + doReturn(panacheQuery).when(userRepository).find(anyString(), anyString()); + + var refreshedUser = userRepository.refresh(user); + + assertThat(refreshedUser).isEqualTo(user); + } + + @Test + void shouldRefreshUserByExternalId() { + doReturn(Optional.empty()).when(userRepository).findByIdOptional(any(ObjectId.class)); + doReturn(Optional.of(user)).when(userRepository).findByExternalId(anyString()); + + var refreshedUser = userRepository.refresh(UserTestFactory.create()); + + assertThat(refreshedUser).isEqualTo(user); + } + + @Test + void shouldThrowResourceNotFound() { + doReturn(Optional.empty()).when(userRepository).findByIdOptional(any(ObjectId.class)); + doReturn(Optional.empty()).when(userRepository).findByExternalId(anyString()); + + assertThatExceptionOfType(ResourceNotFoundException.class).isThrownBy(() -> userRepository.refresh(UserTestFactory.create())); // NOSONAR + } + } +} diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/common/lock/LockRepositoryTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/common/lock/LockRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bd8e0f5c0da7034729eb80ec1e030c76766aff15 --- /dev/null +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/common/lock/LockRepositoryTest.java @@ -0,0 +1,74 @@ +/* + * 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.lock; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.time.Instant; +import java.util.Optional; + +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.mockito.Mock; +import org.mockito.Spy; + +import io.quarkus.mongodb.panache.PanacheQuery; + +class LockRepositoryTest { + @Spy + LockRepository lockRepository; + + @Mock + PanacheQuery<Lock> panacheFindQuery; + + @DisplayName("Test loading sync lock") + @Nested + class TestGetLock { + private static final Lock LOCK = LockTestFactory.create(); + + @BeforeEach + void init() { + doReturn(panacheFindQuery).when(lockRepository).find(anyString(), anyLong()); + doReturn(Optional.of(LOCK)).when(panacheFindQuery).firstResultOptional(); + } + + @Test + void shouldGetOldLock() { + var lockOptional = lockRepository.findLockBefore(Instant.ofEpochMilli(LOCK.getTimestamp())); + + assertThat(lockOptional).isPresent().get().hasFieldOrPropertyWithValue(Lock.TIMESTAMP_FIELD, LOCK.getTimestamp()); + } + + @Test + void shouldGetLock() { + var lockOptional = lockRepository.findLock(Instant.ofEpochMilli(LOCK.getTimestamp())); + + assertThat(lockOptional).isPresent().get().hasFieldOrPropertyWithValue(Lock.TIMESTAMP_FIELD, LOCK.getTimestamp()); + } + } +} diff --git a/user-manager-server/src/test/java/de/itvsh/kop/user/keycloak/KeycloakProviderTest.java b/user-manager-server/src/test/java/de/itvsh/kop/user/keycloak/KeycloakProviderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b12dcbdd5d082eb95c702715ca159fd6f7565a44 --- /dev/null +++ b/user-manager-server/src/test/java/de/itvsh/kop/user/keycloak/KeycloakProviderTest.java @@ -0,0 +1,70 @@ +/* + * 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.keycloak; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.lang.reflect.Field; + +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.mockito.InjectMocks; +import org.mockito.Mock; + +import lombok.SneakyThrows; + +class KeycloakProviderTest { + @InjectMocks + KeycloakProvider keycloakProvider; + @Mock + KeycloakApiProperties properties; + + @DisplayName("Test providing keycloak admin client") + @Nested + class TestProvider { + @BeforeEach + void initProperties() { + setServerUrl(); + when(properties.realm()).thenReturn("realm"); + when(properties.user()).thenReturn("user"); + when(properties.password()).thenReturn("password"); + } + + @SneakyThrows + private void setServerUrl() { + Field url = keycloakProvider.getClass().getDeclaredField("keycloakUrl"); + url.set(keycloakProvider, "url"); + } + + @Test + void shouldCreateRealmResource() { + var resource = keycloakProvider.provide(); + + assertThat(resource).isNotNull(); + } + } +}