package de.itvsh.kop.user; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; import java.util.Collections; import java.util.List; import java.util.Map; 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.keycloak.admin.client.resource.RealmResource; 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; import org.mockito.InjectMocks; 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"; static final String GROUP_1_PATH = "/group1"; static final String GROUP_2_PATH = "/group2"; static final Map<String, List<String>> ATTRIBUTES_1 = Map.of(ORGANISATIONS_EINHEIT_ID_KEY, List.of(ORGANISATIONS_EINHEIT_ID_1)); 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); @Mock private KeycloakApiProperties properties; @Mock private RealmResource realm; @Nested class TestMapping { @BeforeEach void init() { when(properties.ldapIdKey()).thenReturn("LDAP_ID"); when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId"); when(properties.client()).thenReturn("sh-kiel-dev-goofy"); when(realm.getGroupByPath(GROUP_1_PATH)) .thenReturn(GroupRepresentationTestFactory.createByPathAndOrganisationEinheitId(GROUP_1_PATH, ORGANISATIONS_EINHEIT_ID_1)); when(properties.ldapIdKey()).thenReturn("LDAP_ID"); when(properties.organisationsEinheitIdKey()).thenReturn("organisationseinheitId"); when(properties.client()).thenReturn("sh-kiel-dev-goofy"); } @Test void shouldMapToUser() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user).isNotNull(); } @Test void shouldMapEmail() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user.getEmail()).isEqualTo(UserRepresentationTestFactory.EMAIL); } @Test void shouldMapExternalId() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID); } @Test void shouldMapExternalIdFallback() { User user = mapper.toKopUser(UserResourceTestFactory.createWithAttributes(Map.of())); assertThat(user.getExternalId()).isEqualTo(UserRepresentationTestFactory.EXTERNAL_ID_FALLBACK); } @Test void shouldMapFirstName() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user.getFirstName()).isEqualTo(UserRepresentationTestFactory.FIRST_NAME); } @Test void shouldMapLastName() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user.getLastName()).isEqualTo(UserRepresentationTestFactory.LAST_NAME); } @Test void shouldMapUserName() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user.getUsername()).isEqualTo(UserRepresentationTestFactory.USER_NAME); } @Test void shouldMapOrganisationsEinheitIds() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().contains(ORGANISATIONS_EINHEIT_ID_1); } @Test void shouldMapMultipleOrganisationsEinheitIds() { GroupRepresentation 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)))); assertThat(user.getOrganisationsEinheitIds()).isNotEmpty().hasSize(2).contains(ORGANISATIONS_EINHEIT_ID_2); } @Test void shouldMapRoles() { User user = mapper.toKopUser(UserResourceTestFactory.create()); assertThat(user.getRoles()).isNotEmpty().contains(UserRepresentationTestFactory.ROLE_NAME); } } @DisplayName("Get client roles") @Nested class TestGetClientRoles { @Mock private UserResource userResource; @Mock private RoleMappingResource roleMappingResource; @Mock private RoleScopeResource roleScopeResource; @Mock private MappingsRepresentation mappingsRepresentation; @Mock private Map<String, ClientMappingsRepresentation> clientMappingsRepresentation; @Mock private ClientMappingsRepresentation clientMappingRepresentation; @BeforeEach void init() { when(userResource.roles()).thenReturn(roleMappingResource); when(roleMappingResource.getAll()).thenReturn(mappingsRepresentation); } @DisplayName("on existing roles") @Nested class TestOnAssignedRoles { @BeforeEach void init() { when(properties.client()).thenReturn(UserRepresentationTestFactory.CLIENT_KEY); when(mappingsRepresentation.getClientMappings()).thenReturn(clientMappingsRepresentation); when(clientMappingsRepresentation.containsKey(UserRepresentationTestFactory.CLIENT_KEY)).thenReturn(true); when(clientMappingsRepresentation.get(UserRepresentationTestFactory.CLIENT_KEY)).thenReturn(clientMappingRepresentation); when(clientMappingRepresentation.getMappings()).thenReturn(List.of(createRoleRepresentation())); } private RoleRepresentation createRoleRepresentation() { var roleRepresentation = new RoleRepresentation(); roleRepresentation.setName(UserRepresentationTestFactory.ROLE_NAME); return roleRepresentation; } @Test void shouldReturnRolesIfExists() { var roles = mapper.mapRoles(userResource); assertThat(roles).isNotEmpty(); assertThat(roles.get(0)).isEqualTo(UserRepresentationTestFactory.ROLE_NAME); } } @Nested class TestOnNonExistingClient { @BeforeEach void init() { when(properties.client()).thenReturn(UserRepresentationTestFactory.CLIENT_KEY); when(mappingsRepresentation.getClientMappings()).thenReturn(Collections.emptyMap()); } @Test void shouldReturnEmptyListIfNoRolesAttached() { var roles = mapper.mapRoles(userResource); assertThat(roles).isEmpty(); } } @Nested class TestNullClientMappings { @BeforeEach void init() { when(mappingsRepresentation.getClientMappings()).thenReturn(null); } @Test void shouldReturnEmptyListIfNoRolesAttached() { var roles = mapper.mapRoles(userResource); assertThat(roles).isEmpty(); } } } }