Skip to content
Snippets Groups Projects
Commit 37e6a2aa authored by OZGCloud's avatar OZGCloud
Browse files

OZG-6867 OZG-7002 ITCase for synchronizing to KC

parent af068eb0
No related branches found
No related tags found
No related merge requests found
......@@ -90,7 +90,8 @@ class SyncService {
}
public void syncAddedOrganisationsEinheiten(long syncTimestamp) {
sortInAdditionOrder(repository.findAllWithoutSyncResult()).forEach(organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
sortInAdditionOrder(repository.findAllWithoutSyncResult()).forEach(
organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
}
Stream<OrganisationsEinheit> sortInAdditionOrder(Stream<OrganisationsEinheit> organisationsEinheiten) {
......@@ -115,24 +116,31 @@ class SyncService {
}
void syncAddedOrganisationsEinheit(long syncTimestamp, OrganisationsEinheit organisationsEinheit) {
var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit, findParentKeycloakId(organisationsEinheit));
var keycloakId = addGroupInKeycloak(addGroupData);
if (keycloakId.isPresent()) {
var parent = findParent(organisationsEinheit);
if (parent.isEmpty() || parent.get().getKeycloakId() != null) {
var parentKeycloakId = parent.map(OrganisationsEinheit::getKeycloakId).orElse(null);
addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId).ifPresent(
addedGroupId -> updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId));
}
}
Optional<OrganisationsEinheit> findParent(OrganisationsEinheit organisationsEinheit) {
return Optional.ofNullable(organisationsEinheit.getParentId()).flatMap(repository::findById);
}
Optional<String> addAsGroupInKeycloak(OrganisationsEinheit organisationsEinheit, String parentKeycloakId) {
var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId);
return addGroupInKeycloak(addGroupData);
}
void updateAfterSuccessfulGroupCreation(OrganisationsEinheit organisationsEinheit, long syncTimestamp, String keycloakId) {
var updatedOrganisationsEinheit = organisationsEinheit.toBuilder()
.keycloakId(keycloakId.get())
.keycloakId(keycloakId)
.syncResult(SyncResult.OK)
.lastSyncTimestamp(syncTimestamp)
.build();
repository.save(updatedOrganisationsEinheit);
}
}
String findParentKeycloakId(OrganisationsEinheit organisationsEinheit) {
if (organisationsEinheit.getParentId() == null) {
return null;
}
return repository.findById(organisationsEinheit.getParentId()).map(OrganisationsEinheit::getKeycloakId).orElse(null);
}
Optional<String> addGroupInKeycloak(AddGroupData addGroupData) {
try {
......
package de.ozgcloud.admin.organisationseinheit;
import static org.assertj.core.api.Assertions.*;
import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.Mockito.*;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.test.context.ContextConfiguration;
import de.ozgcloud.admin.common.KeycloakInitializer;
import de.ozgcloud.admin.keycloak.Group;
import de.ozgcloud.admin.keycloak.KeycloakRemoteService;
import de.ozgcloud.admin.keycloak.ResourceCreationException;
import de.ozgcloud.common.test.DbInitializer;
import de.ozgcloud.common.test.ITCase;
@ITCase
@ContextConfiguration(initializers = { DbInitializer.class, KeycloakInitializer.class })
class SyncAddedOrganisationsEinheitenITCase {
@Autowired
private SyncService service;
@SpyBean
private KeycloakRemoteService keycloakRemoteService;
@Autowired
private MongoOperations operations;
private final long syncTimestamp = Instant.now().toEpochMilli();
@BeforeEach
void clearDatabase() {
operations.dropCollection(OrganisationsEinheit.class);
}
@Test
void shouldSynchronizeAddedTopLevelGroup() {
var topLevel = topLevel("shouldSynchronizeAddedTopLevelGroup");
operations.save(topLevel);
service.syncAddedOrganisationsEinheiten(syncTimestamp);
assertThat(keycloakRemoteService.getGroupsWithOrganisationsEinheitId())
.extracting(Group::getName, Group::getOrganisationsEinheitId, Group::getSubGroups)
.contains(tuple(topLevel.getName(), topLevel.getOrganisationsEinheitId(), List.of()));
}
@Test
void shouldSynchronizeAddedTopLevelGroupWithChild() {
var topLevel = topLevel("shouldSynchronizeAddedTopLevelGroupWithChild");
var childLevel1 = childLevel("shouldSynchronizeAddedTopLevelGroupWithChild", topLevel);
operations.save(topLevel);
operations.save(childLevel1);
service.syncAddedOrganisationsEinheiten(syncTimestamp);
assertThat(findGroupInKeycloak(topLevel.getName())).isPresent().get()
.extracting(Group::getSubGroups).asList().extracting("name")
.containsExactly(childLevel1.getName());
}
@Test
void shouldNotAddChildIfParentWasNotSynchronized() {
var topLevel = topLevel("shouldNotAddChildIfParentWasNotSynchronized");
var childLevel1 = childLevel("shouldNotAddChildIfParentWasNotSynchronized", topLevel);
operations.save(topLevel);
operations.save(childLevel1);
doThrow(new ResourceCreationException("OMG!")).when(keycloakRemoteService)
.addGroup(argThat(addGroupData -> addGroupData.getName().equals(topLevel.getName())));
service.syncAddedOrganisationsEinheiten(syncTimestamp);
assertThat(findGroupInKeycloak(childLevel1.getName())).isEmpty();
}
private static OrganisationsEinheit topLevel(String nameSuffix) {
return OrganisationsEinheitTestFactory.createBuilder()
.id(UUID.randomUUID().toString())
.parentId(null)
.keycloakId(null)
.syncResult(null)
.name("topLevel (%s)".formatted(nameSuffix))
.build();
}
private static OrganisationsEinheit childLevel(String nameSuffix, OrganisationsEinheit parent) {
return OrganisationsEinheitTestFactory.createBuilder()
.id(UUID.randomUUID().toString())
.parentId(parent.getId())
.keycloakId(null)
.syncResult(null)
.name("childLevel1 (%s)".formatted(nameSuffix))
.build();
}
private Optional<Group> findGroupInKeycloak(String groupName) {
return keycloakRemoteService.getGroupsWithOrganisationsEinheitId()
.filter(group -> groupName.equals(group.getName()))
.findFirst();
}
}
......@@ -517,86 +517,109 @@ class SyncServiceTest {
class TestSyncAddedOrganisationsEinheit {
private final long syncTimestamp = Instant.now().toEpochMilli();
private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
private final AddGroupData addGroupData = AddGroupDataTestFactory.create();
private final String keycloakId = GroupTestFactory.ID;
private final String addedGroupId = UUID.randomUUID().toString();
private final String parentKeycloakId = UUID.randomUUID().toString();
@BeforeEach
void setUp() {
doReturn(parentKeycloakId).when(service).findParentKeycloakId(organisationsEinheit);
when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId)).thenReturn(addGroupData);
}
private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
private final OrganisationsEinheit parentWithoutKeycloakId = OrganisationsEinheitTestFactory.createBuilder().keycloakId(null).build();
private final OrganisationsEinheit parentWithKeycloakId = OrganisationsEinheitTestFactory.createBuilder().keycloakId(parentKeycloakId).build();
@Test
void shouldFindParentKeycloakId() {
mockAddGroupInKeycloak();
doReturn(Optional.of(parentWithoutKeycloakId)).when(service).findParent(organisationsEinheit);
callService();
verify(service).findParentKeycloakId(organisationsEinheit);
verify(service).findParent(organisationsEinheit);
}
@Test
void shouldCreateAddGroupData() {
mockAddGroupInKeycloak();
@Nested
class OnParentHasNoKeycloakId {
@BeforeEach
void init() {
doReturn(Optional.of(parentWithoutKeycloakId)).when(service).findParent(organisationsEinheit);
}
@Test
void shouldNotAddAsGroupInKeycloak() {
callService();
verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit, parentKeycloakId);
verify(service, never()).addAsGroupInKeycloak(any(), any());
}
}
@Nested
class OnOrganisationsEinheitIsTopLevel {
@BeforeEach
void init() {
doReturn(Optional.empty()).when(service).findParent(organisationsEinheit);
}
@Test
void shouldAddGroupInKeycloak() {
mockAddGroupInKeycloak();
void shouldAddAsGroupInKeycloakWithNullParent() {
doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, null);
callService();
verify(service).addGroupInKeycloak(addGroupData);
verify(service).addAsGroupInKeycloak(organisationsEinheit, null);
}
@Nested
class OnAddGroupInKeycloakSuccessful {
@Test
void shouldUpdateAfterSuccessfulGroupCreation() {
doReturn(Optional.of(addedGroupId)).when(service).addAsGroupInKeycloak(organisationsEinheit, null);
doNothing().when(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
@Captor
private ArgumentCaptor<OrganisationsEinheit> savedOrganisationsEinheitArgumentCaptor;
callService();
@BeforeEach
void init() {
doReturn(Optional.of(keycloakId)).when(service).addGroupInKeycloak(addGroupData);
verify(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
}
@Test
void shouldSaveIfAddGroupSuccessful() {
void shouldNotUpdate() {
doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, null);
callService();
verify(repository).save(savedOrganisationsEinheitArgumentCaptor.capture());
assertThat(savedOrganisationsEinheitArgumentCaptor.getValue()).extracting(
OrganisationsEinheit::getKeycloakId,
OrganisationsEinheit::getSyncResult,
OrganisationsEinheit::getLastSyncTimestamp
).containsExactly(keycloakId, SyncResult.OK, syncTimestamp);
verify(service, never()).updateAfterSuccessfulGroupCreation(any(), anyLong(), any());
}
}
@Nested
class OnAddGroupInKeycloakFailed {
class OnParentHasKeycloakId {
@BeforeEach
void init() {
doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
doReturn(Optional.of(parentWithKeycloakId)).when(service).findParent(organisationsEinheit);
}
@Test
void shouldNotSaveIfAddGroupFailed() {
void shouldAddAsGroupInKeycloakWithNullParent() {
doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
callService();
verify(repository, never()).save(any());
verify(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
}
@Test
void shouldUpdateAfterSuccessfulGroupCreation() {
doReturn(Optional.of(addedGroupId)).when(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
doNothing().when(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
callService();
verify(service).updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, addedGroupId);
}
private void mockAddGroupInKeycloak() {
doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
@Test
void shouldNotUpdate() {
doReturn(Optional.empty()).when(service).addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
callService();
verify(service, never()).updateAfterSuccessfulGroupCreation(any(), anyLong(), any());
}
}
private void callService() {
......@@ -605,15 +628,15 @@ class SyncServiceTest {
}
@Nested
class TestFindParentKeycloakId {
class TestFindParent {
@Nested
class OnParentIdIsNull {
@Test
void shouldReturnNull() {
var parentKeycloakId = service.findParentKeycloakId(OrganisationsEinheitTestFactory.createBuilder().parentId(null).build());
void shouldReturnEmpty() {
var parent = service.findParent(OrganisationsEinheitTestFactory.createBuilder().parentId(null).build());
assertThat(parentKeycloakId).isNull();
assertThat(parent).isEmpty();
}
}
......@@ -631,20 +654,87 @@ class SyncServiceTest {
@Test
void shouldFindById() {
service.findParentKeycloakId(organisationsEinheit);
callService();
verify(repository).findById(OrganisationsEinheitTestFactory.PARENT_ID);
}
@Test
void shouldReturnParentKeycloakId() {
var parentKeycloakId = service.findParentKeycloakId(organisationsEinheit);
void shouldReturnParent() {
var found = callService();
assertThat(found).isPresent().get().isEqualTo(parent);
}
assertThat(parentKeycloakId).isEqualTo(PARENT_KEYCLOAK_ID);
private Optional<OrganisationsEinheit> callService() {
return service.findParent(organisationsEinheit);
}
}
}
@Nested
class TestAddAsGroupInKeycloak {
private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
private final String parentKeycloakId = UUID.randomUUID().toString();
private final AddGroupData addGroupData = AddGroupDataTestFactory.create();
private final String addedGroupId = UUID.randomUUID().toString();
@BeforeEach
void init() {
when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId)).thenReturn(addGroupData);
doReturn(Optional.of(addedGroupId)).when(service).addGroupInKeycloak(addGroupData);
}
@Test
void shouldCreateAddGroupData() {
callService();
verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit, parentKeycloakId);
}
@Test
void shouldAddGroupInKeycloak() {
callService();
verify(service).addGroupInKeycloak(addGroupData);
}
@Test
void shouldReturnAddedGroupId() {
var returnedGroupId = callService();
assertThat(returnedGroupId).get().isEqualTo(addedGroupId);
}
private Optional<String> callService() {
return service.addAsGroupInKeycloak(organisationsEinheit, parentKeycloakId);
}
}
@Nested
class TestUpdateAfterSuccessfulGroupCreation {
private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.createBuilder()
.keycloakId(null)
.syncResult(null)
.lastSyncTimestamp(null)
.build();
private final long syncTimestamp = Instant.now().toEpochMilli();
private final String keycloakId = UUID.randomUUID().toString();
@Captor
private ArgumentCaptor<OrganisationsEinheit> organisationsEinheitArgumentCaptor;
@Test
void shouldSaveUpdatedOrganisationsEinheit() {
service.updateAfterSuccessfulGroupCreation(organisationsEinheit, syncTimestamp, keycloakId);
verify(repository).save(organisationsEinheitArgumentCaptor.capture());
assertThat(organisationsEinheitArgumentCaptor.getValue())
.extracting(OrganisationsEinheit::getKeycloakId, OrganisationsEinheit::getSyncResult, OrganisationsEinheit::getLastSyncTimestamp)
.containsExactly(keycloakId, SyncResult.OK, syncTimestamp);
}
}
@Nested
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment