From 9dff5f7213f7efdfafa3812898d858fc92be0e12 Mon Sep 17 00:00:00 2001 From: OZGCloud <ozgcloud@mgm-tp.com> Date: Wed, 16 Oct 2024 10:20:10 +0200 Subject: [PATCH] OZG-6867 OZG-6895 Map group from representation --- .../de/ozgcloud/admin/keycloak/Group.java | 2 +- .../ozgcloud/admin/keycloak/GroupMapper.java | 26 +++- .../admin/keycloak/GroupMapperTest.java | 130 ++++++++++++++++++ .../GroupRepresentationTestFactory.java | 20 +++ .../admin/keycloak/GroupTestFactory.java | 30 ++++ 5 files changed, 202 insertions(+), 6 deletions(-) create mode 100644 src/test/java/de/ozgcloud/admin/keycloak/GroupMapperTest.java create mode 100644 src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java create mode 100644 src/test/java/de/ozgcloud/admin/keycloak/GroupTestFactory.java diff --git a/src/main/java/de/ozgcloud/admin/keycloak/Group.java b/src/main/java/de/ozgcloud/admin/keycloak/Group.java index 6c8f960a..4234dff3 100644 --- a/src/main/java/de/ozgcloud/admin/keycloak/Group.java +++ b/src/main/java/de/ozgcloud/admin/keycloak/Group.java @@ -11,5 +11,5 @@ public class Group { private String name; private String organisationsEinheitId; - private List<Group> subgroups; + private List<Group> subGroups; } diff --git a/src/main/java/de/ozgcloud/admin/keycloak/GroupMapper.java b/src/main/java/de/ozgcloud/admin/keycloak/GroupMapper.java index a36e5cdb..6a8b4996 100644 --- a/src/main/java/de/ozgcloud/admin/keycloak/GroupMapper.java +++ b/src/main/java/de/ozgcloud/admin/keycloak/GroupMapper.java @@ -8,15 +8,31 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.NullValueCheckStrategy; +import lombok.extern.log4j.Log4j2; + @Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) -interface GroupMapper { +@Log4j2 +abstract class GroupMapper { + + static final String ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE = "organisationseinheitId"; - List<Group> fromGroupRepresentations(List<GroupRepresentation> groupRepresentations); + public abstract List<Group> fromGroupRepresentations(List<GroupRepresentation> groupRepresentations); @Mapping(target = "organisationsEinheitId", source = "attributes") - Group fromGroupRepresentation(GroupRepresentation groupRepresentation); + @Mapping(target = "subGroups", expression = "java(new ArrayList<Group>())") + abstract Group fromGroupRepresentation(GroupRepresentation groupRepresentation); - default String getOrganisationsEinheitId(Map<String, List<String>> attributes) { - return "dummy"; + String getOrganisationsEinheitId(Map<String, List<String>> attributes) { + if (attributes == null) { + return null; + } + var values = attributes.get(ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE); + if (values == null) { + return null; + } + if (values.size() > 1 && values.stream().distinct().count() > 1) { + log.warn("Group contains multiple values for {}. The first one is taken.", ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE); + } + return values.getFirst(); } } diff --git a/src/test/java/de/ozgcloud/admin/keycloak/GroupMapperTest.java b/src/test/java/de/ozgcloud/admin/keycloak/GroupMapperTest.java new file mode 100644 index 00000000..e5389ed1 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/keycloak/GroupMapperTest.java @@ -0,0 +1,130 @@ +package de.ozgcloud.admin.keycloak; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.keycloak.representations.idm.GroupRepresentation; +import org.mapstruct.factory.Mappers; +import org.mockito.Spy; + +class GroupMapperTest { + + @Spy + private final GroupMapper mapper = Mappers.getMapper(GroupMapper.class); + + @Nested + class TestGetOrganisationsEinheitId { + + @Test + void shouldReturnNullIfAttributesAreNull() { + var result = mapper.getOrganisationsEinheitId(null); + + assertThat(result).isNull(); + } + + @Test + void shouldReturnNullIfAttributeIsAbsent() { + var result = mapper.getOrganisationsEinheitId(Map.of("dummy-attribute", List.of("123"))); + + assertThat(result).isNull(); + } + + @Test + void shouldReturnOrganisationsEinheitId() { + var value = GroupRepresentationTestFactory.ORGANISATIONS_EINHEIT_ID; + var result = mapper.getOrganisationsEinheitId(Map.of(GroupMapper.ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE, List.of(value))); + + assertThat(result).isEqualTo(value); + } + + @Test + void shouldReturnFirstValueIfMultipleAreAvailable() { + var value = GroupRepresentationTestFactory.ORGANISATIONS_EINHEIT_ID; + var value2 = UUID.randomUUID().toString(); + + var result = mapper.getOrganisationsEinheitId(Map.of(GroupMapper.ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE, List.of(value, value2))); + + assertThat(result).isEqualTo(value); + } + } + + @Nested + class TestFromGroupRepresentation { + + private final GroupRepresentation groupRepresentation = GroupRepresentationTestFactory.create(); + + @BeforeEach + void init() { + doReturn(GroupRepresentationTestFactory.ORGANISATIONS_EINHEIT_ID).when(mapper).getOrganisationsEinheitId(groupRepresentation.getAttributes()); + } + + @Test + void shouldGetOrganisationsEinheitId() { + callMapper(); + + verify(mapper).getOrganisationsEinheitId(groupRepresentation.getAttributes()); + } + + @Test + void shouldSetOrganisationsEinheitId() { + var group = callMapper(); + + assertThat(group.getOrganisationsEinheitId()).isEqualTo(GroupRepresentationTestFactory.ORGANISATIONS_EINHEIT_ID); + } + + @Test + void shouldSetName() { + var group = callMapper(); + + assertThat(group.getName()).isEqualTo(GroupRepresentationTestFactory.NAME); + } + + @Test + void shouldSetSubGroupsToEmptyList() { + var group = callMapper(); + + assertThat(group.getSubGroups()).isEmpty(); + } + + private Group callMapper() { + return mapper.fromGroupRepresentation(groupRepresentation); + } + } + + @Nested + class TestFromGroupRepresentations { + + private GroupRepresentation groupRepresentation = GroupRepresentationTestFactory.create(); + private Group group = GroupTestFactory.createWithEmptySubGroups(); + + @BeforeEach + void init() { + doReturn(group).when(mapper).fromGroupRepresentation(groupRepresentation); + } + + @Test + void shouldMapFromGroupRepresentation() { + callMapper(); + + verify(mapper).fromGroupRepresentation(groupRepresentation); + } + + @Test + void shouldReturnListWithGroupRepresentation() { + var groups = callMapper(); + + assertThat(groups).containsExactly(group); + } + + private List<Group> callMapper() { + return mapper.fromGroupRepresentations(List.of(groupRepresentation)); + } + } +} diff --git a/src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java b/src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java new file mode 100644 index 00000000..9d9df97a --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/keycloak/GroupRepresentationTestFactory.java @@ -0,0 +1,20 @@ +package de.ozgcloud.admin.keycloak; + +import java.util.UUID; + +import org.keycloak.representations.idm.GroupRepresentation; + +import com.thedeanda.lorem.LoremIpsum; + +class GroupRepresentationTestFactory { + + public static final String NAME = LoremIpsum.getInstance().getName(); + public static final String ORGANISATIONS_EINHEIT_ID = UUID.randomUUID().toString(); + + public static GroupRepresentation create() { + var groupRepresentation = new GroupRepresentation() + .singleAttribute(GroupMapper.ORGANIZATIONS_EINHEIT_ID_ATTRIBUTE, ORGANISATIONS_EINHEIT_ID); + groupRepresentation.setName(NAME); + return groupRepresentation; + } +} diff --git a/src/test/java/de/ozgcloud/admin/keycloak/GroupTestFactory.java b/src/test/java/de/ozgcloud/admin/keycloak/GroupTestFactory.java new file mode 100644 index 00000000..bd8413d0 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/keycloak/GroupTestFactory.java @@ -0,0 +1,30 @@ +package de.ozgcloud.admin.keycloak; + +import java.util.List; +import java.util.UUID; + +import com.thedeanda.lorem.LoremIpsum; + +class GroupTestFactory { + + public static final String NAME = GroupRepresentationTestFactory.NAME; + public static final String ORGANISATIONS_EINHEIT_ID = GroupRepresentationTestFactory.ORGANISATIONS_EINHEIT_ID; + + public static final String SUB_GROUP_NAME = LoremIpsum.getInstance().getName(); + public static final String SUB_GROUP_ORGANISATIONS_EINHEIT_ID = UUID.randomUUID().toString(); + + public static Group create() { + return createBuilder().build(); + } + + public static Group createWithEmptySubGroups() { + return createBuilder().subGroups(List.of()).build(); + } + + public static Group.GroupBuilder createBuilder() { + return new Group.GroupBuilder() + .name(NAME) + .organisationsEinheitId(ORGANISATIONS_EINHEIT_ID) + .subGroups(List.of(Group.builder().name(SUB_GROUP_NAME).organisationsEinheitId(SUB_GROUP_ORGANISATIONS_EINHEIT_ID).build())); + } +} -- GitLab