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

Merge branch 'OZG-6867-organisationseinheit-management-sync' into OZG-6720-signatur-bearbeiten

parents 519b2f3f 0f53316e
No related branches found
No related tags found
No related merge requests found
Showing
with 315 additions and 49 deletions
...@@ -20,11 +20,17 @@ class KeycloakApiService { ...@@ -20,11 +20,17 @@ class KeycloakApiService {
} }
public String addGroup(GroupRepresentation groupRepresentation) { public String addGroup(GroupRepresentation groupRepresentation) {
try (var response = groupsResource.add(groupRepresentation)) { try (var response = addParentOrChildGroup(groupRepresentation)) {
return getAddedResourceIdFromResponse(response); return getAddedResourceIdFromResponse(response);
} }
} }
Response addParentOrChildGroup(GroupRepresentation groupRepresentation) {
return groupRepresentation.getParentId() == null ?
groupsResource.add(groupRepresentation) :
groupsResource.group(groupRepresentation.getParentId()).subGroup(groupRepresentation);
}
String getAddedResourceIdFromResponse(Response response) { String getAddedResourceIdFromResponse(Response response) {
if (response.getStatus() == Response.Status.CREATED.getStatusCode()) { if (response.getStatus() == Response.Status.CREATED.getStatusCode()) {
return extractResourceIdFromLocationHeader(response.getHeaderString("Location")); return extractResourceIdFromLocationHeader(response.getHeaderString("Location"));
......
...@@ -31,7 +31,7 @@ public class OrganisationsEinheit { ...@@ -31,7 +31,7 @@ public class OrganisationsEinheit {
@JsonIgnore @JsonIgnore
private String zufiId; private String zufiId;
@JsonIgnore @JsonIgnore
private long lastSyncTimestamp; private Long lastSyncTimestamp;
@JsonIgnore @JsonIgnore
private String parentId; private String parentId;
@JsonIgnore @JsonIgnore
......
...@@ -13,5 +13,6 @@ interface OrganisationsEinheitMapper { ...@@ -13,5 +13,6 @@ interface OrganisationsEinheitMapper {
@Mapping(target = "zufiId", source = "id") @Mapping(target = "zufiId", source = "id")
OrganisationsEinheit fromGrpc(GrpcOrganisationsEinheit grpcOrganisationsEinheit); OrganisationsEinheit fromGrpc(GrpcOrganisationsEinheit grpcOrganisationsEinheit);
AddGroupData toAddGroupData(OrganisationsEinheit organisationsEinheit); @Mapping(target = "parentId", source = "parentKeycloakId")
AddGroupData toAddGroupData(OrganisationsEinheit organisationsEinheit, String parentKeycloakId);
} }
...@@ -14,9 +14,11 @@ class SyncScheduler { ...@@ -14,9 +14,11 @@ class SyncScheduler {
private final SyncService syncService; private final SyncService syncService;
@SchedulerLock(name = "SyncScheduler_syncOrganisationsEinheitenFromKeycloak", lockAtLeastFor = "PT5M", lockAtMostFor = "PT23H") @SchedulerLock(name = "SyncScheduler_syncOrganisationsEinheitenWithKeycloak", lockAtLeastFor = "PT5M", lockAtMostFor = "PT23H")
@Scheduled(cron = "${ozgcloud.administration.sync.organisationseinheiten.cron}") @Scheduled(cron = "${ozgcloud.administration.sync.organisationseinheiten.cron}")
public void syncOrganisationsEinheitenFromKeycloak() { public void syncOrganisationsEinheitenWithKeycloak() {
syncService.syncOrganisationsEinheitenFromKeycloak(Instant.now().toEpochMilli()); var syncTimestamp = Instant.now().toEpochMilli();
syncService.syncOrganisationsEinheitenFromKeycloak(syncTimestamp);
syncService.syncAddedOrganisationsEinheiten(syncTimestamp);
} }
} }
...@@ -2,6 +2,7 @@ package de.ozgcloud.admin.organisationseinheit; ...@@ -2,6 +2,7 @@ package de.ozgcloud.admin.organisationseinheit;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Stream;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -89,11 +90,32 @@ class SyncService { ...@@ -89,11 +90,32 @@ class SyncService {
} }
public void syncAddedOrganisationsEinheiten(long syncTimestamp) { public void syncAddedOrganisationsEinheiten(long syncTimestamp) {
repository.findAllWithoutSyncResult().forEach(organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit)); sortInAdditionOrder(repository.findAllWithoutSyncResult()).forEach(organisationsEinheit -> syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
}
Stream<OrganisationsEinheit> sortInAdditionOrder(Stream<OrganisationsEinheit> organisationsEinheiten) {
return organisationsEinheiten.sorted((org1, org2) -> {
if (org1.getParentId() == null && org2.getParentId() == null) {
return 0;
}
if (org1.getParentId() == null) {
return -1;
}
if (org2.getParentId() == null) {
return 1;
}
if (org1.getId().equals(org2.getParentId())) {
return -1;
}
if (org1.getParentId().equals(org2.getId())) {
return 1;
}
return 0;
});
} }
void syncAddedOrganisationsEinheit(long syncTimestamp, OrganisationsEinheit organisationsEinheit) { void syncAddedOrganisationsEinheit(long syncTimestamp, OrganisationsEinheit organisationsEinheit) {
var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit); var addGroupData = organisationsEinheitMapper.toAddGroupData(organisationsEinheit, findParentKeycloakId(organisationsEinheit));
var keycloakId = addGroupInKeycloak(addGroupData); var keycloakId = addGroupInKeycloak(addGroupData);
if (keycloakId.isPresent()) { if (keycloakId.isPresent()) {
var updatedOrganisationsEinheit = organisationsEinheit.toBuilder() var updatedOrganisationsEinheit = organisationsEinheit.toBuilder()
...@@ -105,6 +127,13 @@ class SyncService { ...@@ -105,6 +127,13 @@ class SyncService {
} }
} }
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) { Optional<String> addGroupInKeycloak(AddGroupData addGroupData) {
try { try {
return Optional.of(keycloakRemoteService.addGroup(addGroupData)); return Optional.of(keycloakRemoteService.addGroup(addGroupData));
......
...@@ -13,6 +13,7 @@ class GroupRepresentationTestFactory { ...@@ -13,6 +13,7 @@ class GroupRepresentationTestFactory {
public static final String ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE = "organisationseinheitId"; public static final String ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE = "organisationseinheitId";
public static final String ID = UUID.randomUUID().toString(); public static final String ID = UUID.randomUUID().toString();
public static final String PARENT_ID = UUID.randomUUID().toString();
public static final String NAME = LoremIpsum.getInstance().getName(); public static final String NAME = LoremIpsum.getInstance().getName();
public static final String ORGANISATIONS_EINHEIT_ID = UUID.randomUUID().toString(); public static final String ORGANISATIONS_EINHEIT_ID = UUID.randomUUID().toString();
public static final Map<String, List<String>> ATTRIBUTES = Map.of(ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE, List.of(ORGANISATIONS_EINHEIT_ID)); public static final Map<String, List<String>> ATTRIBUTES = Map.of(ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE, List.of(ORGANISATIONS_EINHEIT_ID));
...@@ -43,6 +44,7 @@ class GroupRepresentationTestFactory { ...@@ -43,6 +44,7 @@ class GroupRepresentationTestFactory {
if (withId) { if (withId) {
groupRepresentation.setId(ID); groupRepresentation.setId(ID);
} }
groupRepresentation.setParentId(PARENT_ID);
groupRepresentation.setName(NAME); groupRepresentation.setName(NAME);
groupRepresentation.setAttributes(ATTRIBUTES); groupRepresentation.setAttributes(ATTRIBUTES);
groupRepresentation.setSubGroups(List.of(createSubGroup(withId))); groupRepresentation.setSubGroups(List.of(createSubGroup(withId)));
...@@ -54,6 +56,7 @@ class GroupRepresentationTestFactory { ...@@ -54,6 +56,7 @@ class GroupRepresentationTestFactory {
if (withId) { if (withId) {
groupRepresentation.setId(SUB_GROUP_ID); groupRepresentation.setId(SUB_GROUP_ID);
} }
groupRepresentation.setParentId(ID);
groupRepresentation.setName(SUB_GROUP_NAME); groupRepresentation.setName(SUB_GROUP_NAME);
groupRepresentation.setAttributes(SUB_GROUP_ATTRIBUTES); groupRepresentation.setAttributes(SUB_GROUP_ATTRIBUTES);
return groupRepresentation; return groupRepresentation;
......
...@@ -8,6 +8,7 @@ import java.util.Optional; ...@@ -8,6 +8,7 @@ import java.util.Optional;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.resource.GroupsResource;
import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.GroupRepresentation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
...@@ -25,6 +26,8 @@ class KeycloakApiServiceITCase { ...@@ -25,6 +26,8 @@ class KeycloakApiServiceITCase {
private KeycloakApiService service; private KeycloakApiService service;
@Autowired @Autowired
private KeycloakApiProperties properties; private KeycloakApiProperties properties;
@Autowired
private GroupsResource groupsResource;
@Nested @Nested
class TestGetAllGroups { class TestGetAllGroups {
...@@ -146,7 +149,7 @@ class KeycloakApiServiceITCase { ...@@ -146,7 +149,7 @@ class KeycloakApiServiceITCase {
} }
@Test @Test
void shouldNotAddSubgroups() { void shouldNotAddSubgroupsOfAddedGroup() {
var groupToAdd = createUniqueGroupRepresentation("shouldNotAddSubgroups"); var groupToAdd = createUniqueGroupRepresentation("shouldNotAddSubgroups");
var groupId = service.addGroup(groupToAdd); var groupId = service.addGroup(groupToAdd);
...@@ -155,10 +158,26 @@ class KeycloakApiServiceITCase { ...@@ -155,10 +158,26 @@ class KeycloakApiServiceITCase {
.asList().isEmpty(); .asList().isEmpty();
} }
private GroupRepresentation createUniqueGroupRepresentation(String suffix) { @Test
void shouldAddSubgroupToParent() {
var parentToAdd = createUniqueGroupRepresentation("shouldAddSubgroupToParent-parent");
var parentId = service.addGroup(parentToAdd);
var childToAdd = createUniqueGroupRepresentation("shouldAddSubgroupToParent-child");
childToAdd.setParentId(parentId);
var childId = service.addGroup(childToAdd);
var subgroupsInKc = groupsResource.group(parentId).getSubGroups(0, Integer.MAX_VALUE, true);
assertThat(subgroupsInKc).hasSize(1).first().extracting(GroupRepresentation::getId, GroupRepresentation::getParentId)
.contains(childId, parentId);
}
private GroupRepresentation createUniqueGroupRepresentation(String nameSuffix) {
// LoremIpsum does not guarantee unique results when called repeatedly // LoremIpsum does not guarantee unique results when called repeatedly
var groupName = "%s (%s)".formatted(LoremIpsum.getInstance().getName(), suffix); var groupName = "%s (%s)".formatted(LoremIpsum.getInstance().getName(), nameSuffix);
return GroupRepresentationTestFactory.createWithoutId(groupName); var group = GroupRepresentationTestFactory.createWithoutId(groupName);
group.setParentId(null);
return group;
} }
private Optional<GroupRepresentation> findGroupInKeycloak(String groupId) { private Optional<GroupRepresentation> findGroupInKeycloak(String groupId) {
......
...@@ -6,6 +6,7 @@ import static org.mockito.Mockito.*; ...@@ -6,6 +6,7 @@ import static org.mockito.Mockito.*;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.keycloak.admin.client.resource.GroupResource;
import org.keycloak.admin.client.resource.GroupsResource; import org.keycloak.admin.client.resource.GroupsResource;
import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.GroupRepresentation;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
...@@ -34,15 +35,15 @@ class KeycloakApiServiceTest { ...@@ -34,15 +35,15 @@ class KeycloakApiServiceTest {
@BeforeEach @BeforeEach
void init() { void init() {
when(groupsResource.add(groupRepresentation)).thenReturn(response); doReturn(response).when(service).addParentOrChildGroup(groupRepresentation);
doReturn(RESOURCE_ID).when(service).getAddedResourceIdFromResponse(response); doReturn(RESOURCE_ID).when(service).getAddedResourceIdFromResponse(response);
} }
@Test @Test
void shouldCallGroupsResource() { void shouldAddParentOrChildGroup() {
callService(); callService();
verify(groupsResource).add(groupRepresentation); verify(service).addParentOrChildGroup(groupRepresentation);
} }
@Test @Test
...@@ -64,6 +65,69 @@ class KeycloakApiServiceTest { ...@@ -64,6 +65,69 @@ class KeycloakApiServiceTest {
} }
} }
@Nested
class TestAddParentOrChildGroup {
private GroupRepresentation groupRepresentation;
@Nested
class OnParentGroup {
@BeforeEach
void init() {
groupRepresentation = GroupRepresentationTestFactory.create();
groupRepresentation.setParentId(null);
when(groupsResource.add(groupRepresentation)).thenReturn(response);
}
@Test
void shouldCallGroupsResource() {
callService();
verify(groupsResource).add(groupRepresentation);
}
@Test
void shouldReturnResponse() {
var serviceResponse = callService();
assertThat(serviceResponse).isEqualTo(response);
}
}
@Nested
class OnChildGroup {
@Mock
private GroupResource groupResource;
@BeforeEach
void init() {
groupRepresentation = GroupRepresentationTestFactory.create();
when(groupsResource.group(GroupRepresentationTestFactory.PARENT_ID)).thenReturn(groupResource);
when(groupResource.subGroup(groupRepresentation)).thenReturn(response);
}
@Test
void shouldCallGroupResource() {
callService();
verify(groupResource).subGroup(groupRepresentation);
}
@Test
void shouldReturnResponse() {
var serviceResponse = callService();
assertThat(serviceResponse).isEqualTo(response);
}
}
private Response callService() {
return service.addParentOrChildGroup(groupRepresentation);
}
}
@Nested @Nested
class TestGetAddedResourceIdFromResponse { class TestGetAddedResourceIdFromResponse {
......
...@@ -3,6 +3,7 @@ package de.ozgcloud.admin.organisationseinheit; ...@@ -3,6 +3,7 @@ package de.ozgcloud.admin.organisationseinheit;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import java.util.Collections; import java.util.Collections;
import java.util.UUID;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
...@@ -44,16 +45,18 @@ class OrganisationsEinheitMapperTest { ...@@ -44,16 +45,18 @@ class OrganisationsEinheitMapperTest {
@Nested @Nested
class TestToAddGroupData { class TestToAddGroupData {
public static final String PARENT_KEYCLOAK_ID = UUID.randomUUID().toString();
@Test @Test
void shouldMap() { void shouldMap() {
var mapped = mapper.toAddGroupData(OrganisationsEinheitTestFactory.create()); var mapped = mapper.toAddGroupData(OrganisationsEinheitTestFactory.create(), PARENT_KEYCLOAK_ID);
assertThat(mapped).extracting( assertThat(mapped).extracting(
AddGroupData::getParentId, AddGroupData::getParentId,
AddGroupData::getName, AddGroupData::getName,
AddGroupData::getOrganisationsEinheitId AddGroupData::getOrganisationsEinheitId
).containsExactly( ).containsExactly(
OrganisationsEinheitTestFactory.PARENT_ID, PARENT_KEYCLOAK_ID,
OrganisationsEinheitTestFactory.NAME, OrganisationsEinheitTestFactory.NAME,
OrganisationsEinheitTestFactory.ORGANISATIONS_EINHEIT_ID OrganisationsEinheitTestFactory.ORGANISATIONS_EINHEIT_ID
); );
......
...@@ -5,7 +5,7 @@ import static org.mockito.Mockito.*; ...@@ -5,7 +5,7 @@ import static org.mockito.Mockito.*;
import java.time.Instant; import java.time.Instant;
import org.assertj.core.data.Offset; import org.assertj.core.data.*;
import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
...@@ -22,18 +22,34 @@ class SyncSchedulerTest { ...@@ -22,18 +22,34 @@ class SyncSchedulerTest {
private SyncService syncService; private SyncService syncService;
@Nested @Nested
class TestSyncOrganisationsEinheitenFromKeycloak { class TestSyncOrganisationsEinheitenWithKeycloak {
@Captor @Captor
private ArgumentCaptor<Long> syncTimestampArgumentCaptor; private ArgumentCaptor<Long> syncTimestampArgumentCaptor;
@Test @Test
void shouldCallService() { void shouldSyncOrganisationsEinheitenFromKeycloak() {
scheduler.syncOrganisationsEinheitenFromKeycloak(); callService();
verify(syncService).syncOrganisationsEinheitenFromKeycloak(syncTimestampArgumentCaptor.capture()); verify(syncService).syncOrganisationsEinheitenFromKeycloak(syncTimestampArgumentCaptor.capture());
assertThatSyncTimestampIsCloseToNow();
}
@Test
void shouldSyncAddedOrganisationsEinheiten() {
callService();
verify(syncService).syncAddedOrganisationsEinheiten(syncTimestampArgumentCaptor.capture());
assertThatSyncTimestampIsCloseToNow();
}
private void assertThatSyncTimestampIsCloseToNow() {
assertThat(syncTimestampArgumentCaptor.getValue()).isCloseTo(Instant.now().toEpochMilli(), Offset.offset(5000L)); assertThat(syncTimestampArgumentCaptor.getValue()).isCloseTo(Instant.now().toEpochMilli(), Offset.offset(5000L));
} }
private void callService() {
scheduler.syncOrganisationsEinheitenWithKeycloak();
}
} }
} }
\ No newline at end of file
...@@ -5,6 +5,7 @@ import static org.mockito.ArgumentMatchers.*; ...@@ -5,6 +5,7 @@ import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*; import static org.mockito.Mockito.*;
import java.time.Instant; import java.time.Instant;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
...@@ -416,15 +417,21 @@ class SyncServiceTest { ...@@ -416,15 +417,21 @@ class SyncServiceTest {
} }
@Nested @Nested
class TestsyncAddedOrganisationsEinheiten { class TestSyncAddedOrganisationsEinheiten {
private final long syncTimestamp = Instant.now().toEpochMilli(); private final long syncTimestamp = Instant.now().toEpochMilli();
private final OrganisationsEinheit withoutSyncResult1 = OrganisationsEinheitTestFactory.createBuilder().id("A").build(); private final OrganisationsEinheit withoutSyncResult1 = OrganisationsEinheitTestFactory.createBuilder().id("A").build();
private final OrganisationsEinheit withoutSyncResult2 = OrganisationsEinheitTestFactory.createBuilder().id("B").build(); private final OrganisationsEinheit withoutSyncResult2 = OrganisationsEinheitTestFactory.createBuilder().id("B").build();
private final OrganisationsEinheit[] unsortedOrganisationsEinheiten = new OrganisationsEinheit[]{withoutSyncResult2, withoutSyncResult1};
private final OrganisationsEinheit[] sortedOrganisationsEinheiten = new OrganisationsEinheit[]{withoutSyncResult1, withoutSyncResult2};
@Captor
private ArgumentCaptor<Stream<OrganisationsEinheit>> streamArgumentCaptor;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
when(repository.findAllWithoutSyncResult()).thenReturn(Stream.of(withoutSyncResult1, withoutSyncResult2)); when(repository.findAllWithoutSyncResult()).thenReturn(Stream.of(unsortedOrganisationsEinheiten));
doReturn(Stream.of(sortedOrganisationsEinheiten)).when(service).sortInAdditionOrder(any());
doNothing().when(service).syncAddedOrganisationsEinheit(anyLong(), any()); doNothing().when(service).syncAddedOrganisationsEinheit(anyLong(), any());
} }
...@@ -435,6 +442,14 @@ class SyncServiceTest { ...@@ -435,6 +442,14 @@ class SyncServiceTest {
verify(repository).findAllWithoutSyncResult(); verify(repository).findAllWithoutSyncResult();
} }
@Test
void shouldSortInAdditionOrder() {
callService();
verify(service).sortInAdditionOrder(streamArgumentCaptor.capture());
assertThat(streamArgumentCaptor.getValue()).containsExactly(unsortedOrganisationsEinheiten);
}
@Test @Test
void shouldSynchronizeFirstOrganisationsEinheit() { void shouldSynchronizeFirstOrganisationsEinheit() {
callService(); callService();
...@@ -449,11 +464,55 @@ class SyncServiceTest { ...@@ -449,11 +464,55 @@ class SyncServiceTest {
verify(service).syncAddedOrganisationsEinheit(syncTimestamp, withoutSyncResult2); verify(service).syncAddedOrganisationsEinheit(syncTimestamp, withoutSyncResult2);
} }
@Test
void shouldSynchronizeInOrder() {
var inOrder = inOrder(service);
callService();
Arrays.stream(sortedOrganisationsEinheiten).forEach(organisationsEinheit ->
inOrder.verify(service).syncAddedOrganisationsEinheit(syncTimestamp, organisationsEinheit));
}
private void callService() { private void callService() {
service.syncAddedOrganisationsEinheiten(syncTimestamp); service.syncAddedOrganisationsEinheiten(syncTimestamp);
} }
} }
@Nested
class TestSortInAdditionOrder {
@Test
void shouldTopLevelOrgComeFirst() {
var orgWithParent = OrganisationsEinheitTestFactory.create();
var orgWithoutParent = OrganisationsEinheitTestFactory.createBuilder().parentId(null).build();
var sorted = service.sortInAdditionOrder(Stream.of(orgWithParent, orgWithoutParent));
assertThat(sorted).containsExactly(orgWithoutParent, orgWithParent);
}
@Test
void shouldParentComeBeforeChild() {
var parent = OrganisationsEinheitTestFactory.create();
var child = OrganisationsEinheitTestFactory.createBuilder().parentId(parent.getId()).build();
var sorted = service.sortInAdditionOrder(Stream.of(child, parent));
assertThat(sorted).containsExactly(parent, child);
}
@Test
void shouldPreserveOrderForTopLevelGroups() {
var orgWithoutParent1 = OrganisationsEinheitTestFactory.createBuilder().parentId(null).build();
var orgWithoutParent2 = OrganisationsEinheitTestFactory.createBuilder().parentId(null).build();
var sorted = service.sortInAdditionOrder(Stream.of(orgWithoutParent1, orgWithoutParent2));
assertThat(sorted).containsExactly(orgWithoutParent1, orgWithoutParent2);
}
}
@Nested @Nested
class TestSyncAddedOrganisationsEinheit { class TestSyncAddedOrganisationsEinheit {
...@@ -461,37 +520,54 @@ class SyncServiceTest { ...@@ -461,37 +520,54 @@ class SyncServiceTest {
private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create(); private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
private final AddGroupData addGroupData = AddGroupDataTestFactory.create(); private final AddGroupData addGroupData = AddGroupDataTestFactory.create();
private final String keycloakId = GroupTestFactory.ID; private final String keycloakId = GroupTestFactory.ID;
private final String parentKeycloakId = UUID.randomUUID().toString();
@Captor
private ArgumentCaptor<OrganisationsEinheit> savedOrganisationsEinheitArgumentCaptor;
@BeforeEach @BeforeEach
void setUp() { void setUp() {
when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit)).thenReturn(addGroupData); doReturn(parentKeycloakId).when(service).findParentKeycloakId(organisationsEinheit);
when(organisationsEinheitMapper.toAddGroupData(organisationsEinheit, parentKeycloakId)).thenReturn(addGroupData);
}
@Test
void shouldFindParentKeycloakId() {
mockAddGroupInKeycloak();
callService();
verify(service).findParentKeycloakId(organisationsEinheit);
} }
@Test @Test
void shouldCreateAddGroupData() { void shouldCreateAddGroupData() {
givenAddGroupInKeycloakSuccessful(); mockAddGroupInKeycloak();
callService(); callService();
verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit); verify(organisationsEinheitMapper).toAddGroupData(organisationsEinheit, parentKeycloakId);
} }
@Test @Test
void shouldAddGroupInKeycloak() { void shouldAddGroupInKeycloak() {
givenAddGroupInKeycloakSuccessful(); mockAddGroupInKeycloak();
callService(); callService();
verify(service).addGroupInKeycloak(addGroupData); verify(service).addGroupInKeycloak(addGroupData);
} }
@Nested
class OnAddGroupInKeycloakSuccessful {
@Captor
private ArgumentCaptor<OrganisationsEinheit> savedOrganisationsEinheitArgumentCaptor;
@BeforeEach
void init() {
doReturn(Optional.of(keycloakId)).when(service).addGroupInKeycloak(addGroupData);
}
@Test @Test
void shouldSaveIfAddGroupSuccessful() { void shouldSaveIfAddGroupSuccessful() {
givenAddGroupInKeycloakSuccessful();
callService(); callService();
verify(repository).save(savedOrganisationsEinheitArgumentCaptor.capture()); verify(repository).save(savedOrganisationsEinheitArgumentCaptor.capture());
...@@ -501,21 +577,25 @@ class SyncServiceTest { ...@@ -501,21 +577,25 @@ class SyncServiceTest {
OrganisationsEinheit::getLastSyncTimestamp OrganisationsEinheit::getLastSyncTimestamp
).containsExactly(keycloakId, SyncResult.OK, syncTimestamp); ).containsExactly(keycloakId, SyncResult.OK, syncTimestamp);
} }
}
@Nested
class OnAddGroupInKeycloakFailed {
@BeforeEach
void init() {
doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
}
@Test @Test
void shouldNotSaveIfAddGroupFailed() { void shouldNotSaveIfAddGroupFailed() {
givenAddGroupInKeycloakFailed();
callService(); callService();
verifyNoInteractions(repository); verify(repository, never()).save(any());
} }
private void givenAddGroupInKeycloakSuccessful() {
doReturn(Optional.of(keycloakId)).when(service).addGroupInKeycloak(addGroupData);
} }
private void givenAddGroupInKeycloakFailed() { private void mockAddGroupInKeycloak() {
doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData); doReturn(Optional.empty()).when(service).addGroupInKeycloak(addGroupData);
} }
...@@ -524,6 +604,49 @@ class SyncServiceTest { ...@@ -524,6 +604,49 @@ class SyncServiceTest {
} }
} }
@Nested
class TestFindParentKeycloakId {
@Nested
class OnParentIdIsNull {
@Test
void shouldReturnNull() {
var parentKeycloakId = service.findParentKeycloakId(OrganisationsEinheitTestFactory.createBuilder().parentId(null).build());
assertThat(parentKeycloakId).isNull();
}
}
@Nested
class OnParentIdIsNotNull {
private final String PARENT_KEYCLOAK_ID = UUID.randomUUID().toString();
private final OrganisationsEinheit organisationsEinheit = OrganisationsEinheitTestFactory.create();
private final OrganisationsEinheit parent = OrganisationsEinheitTestFactory.createBuilder().keycloakId(PARENT_KEYCLOAK_ID).build();
@BeforeEach
void init() {
when(repository.findById(OrganisationsEinheitTestFactory.PARENT_ID)).thenReturn(Optional.of(parent));
}
@Test
void shouldFindById() {
service.findParentKeycloakId(organisationsEinheit);
verify(repository).findById(OrganisationsEinheitTestFactory.PARENT_ID);
}
@Test
void shouldReturnParentKeycloakId() {
var parentKeycloakId = service.findParentKeycloakId(organisationsEinheit);
assertThat(parentKeycloakId).isEqualTo(PARENT_KEYCLOAK_ID);
}
}
}
@Nested @Nested
class TestAddGroupInKeycloak { class TestAddGroupInKeycloak {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment