diff --git a/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteService.java b/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteService.java index 3e1f31c51a71f937c37c808985e0554f194e4f32..7c3d4c1bf7c6748c85a0df583d46c60faae9356d 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteService.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientRemoteService.java @@ -23,9 +23,6 @@ */ package de.ozgcloud.operator.keycloak.client; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.logging.Level; import org.keycloak.admin.client.CreatedResponseUtil; @@ -33,7 +30,6 @@ import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.representations.idm.ClientRepresentation; -import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -54,44 +50,11 @@ class KeycloakClientRemoteService { public String createClient(ClientRepresentation client, String realm) { log.log(Level.FINE, "Creating client {0} in realm {1}", new String[] { client.getId(), realm }); - - // PoC - client.setProtocolMappers(List.of(buildOrganisationsEinheitIdMapper())); - // - var response = getRealm(realm).clients().create(client); KeycloakResultParser.parseCreatedResponse(response); return CreatedResponseUtil.getCreatedId(response); } - // PoC - ProtocolMapperRepresentation buildOrganisationsEinheitIdMapper() { - log.log(Level.FINE, "Build organisationsEinheitId mapper..."); - var mapper = new ProtocolMapperRepresentation(); - mapper.setName("organisationseinheitIdMapper"); - mapper.setProtocol("openid-connect"); - mapper.setProtocolMapper("oidc-usermodel-attribute-mapper"); - mapper.setConfig(buildOrganisationsEinheitIdMapperConfig()); - - return mapper; - } - - Map<String, String> buildOrganisationsEinheitIdMapperConfig() { - var config = new HashMap<String, String>(); - - config.put("access.token.claim", "true"); - config.put("aggregate.attrs", "true"); - config.put("claim.name", "organisationseinheitId"); - config.put("id.token.claim", "true"); - config.put("jsonType.label", "int"); - config.put("multivalued", "true"); - config.put("user.attribute", "organisationseinheitId"); - config.put("userinfo.token.claim", "true"); - - return config; - } - // - public void updateClientRole(RoleRepresentation role, String clientId, String realm) { getClientResource(realm, clientId).roles().get(role.getName()).update(role); } diff --git a/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientService.java b/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientService.java index a0591951b94840f8c50a09adaa46b3909b6d9fa6..33f5fc1872811de49114b03528820dc91d9bd829 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientService.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/client/KeycloakClientService.java @@ -23,6 +23,8 @@ */ package de.ozgcloud.operator.keycloak.client; +import java.util.List; + import org.keycloak.representations.idm.ClientRepresentation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -38,6 +40,9 @@ class KeycloakClientService { @Autowired private KeycloakGenericRemoteService genericRemoteService; + @Autowired + private ProtocolMapperRepresentationHelper mapperRepresentationBuilder; + @Autowired private KeycloakClientMapper mapper; @@ -48,19 +53,24 @@ class KeycloakClientService { } void updateClient(ClientRepresentation existingClient, OzgKeycloakClientSpec spec, String realm) { - ClientRepresentation clientRepresentation = mapper.update(existingClient, spec); + var clientRepresentation = mapper.update(existingClient, spec); remoteService.updateClient(clientRepresentation, realm); addOrUpdateClientRoles(spec, realm, existingClient.getId()); } void createClient(OzgKeycloakClientSpec spec, String realm) { - ClientRepresentation clientRepresentation = mapper.map(spec); - String realClientId = remoteService.createClient(clientRepresentation, realm); + var clientRepresentation = mapper.map(spec); + setProtocolMapper(clientRepresentation); + var realClientId = remoteService.createClient(clientRepresentation, realm); addOrUpdateClientRoles(spec, realm, realClientId); } + void setProtocolMapper(ClientRepresentation clientRepresentation) { + clientRepresentation.setProtocolMappers(List.of(mapperRepresentationBuilder.createOrganisationsEinheitIdMapper())); + } + void addOrUpdateClientRoles(OzgKeycloakClientSpec spec, String realm, String realClientId) { spec.getClientRoles().forEach( roleSpec -> genericRemoteService.getClientRole(roleSpec.getName(), realClientId, realm) diff --git a/src/main/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationHelper.java b/src/main/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..170da5a14bd1d00145fe5a1b386d68fc64bb0bdc --- /dev/null +++ b/src/main/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationHelper.java @@ -0,0 +1,53 @@ +package de.ozgcloud.operator.keycloak.client; + +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; + +import org.keycloak.representations.idm.ProtocolMapperRepresentation; +import org.springframework.stereotype.Component; + +import lombok.extern.java.Log; + +@Log +@Component +class ProtocolMapperRepresentationHelper { + + static final String OPENID_CONNECT_PROTOCOL = "openid-connect"; + static final String ATTRIBUTE_PROTOCOL_MAPPER = "oidc-usermodel-attribute-mapper"; + + static final String CONFIG_ACCESS_TOKEN_CLAIM_KEY = "access.token.claim"; + static final String CONFIG_AGGREGATE_ATTRS_KEY = "aggregate.attrs"; + static final String CONFIG_CLAIM_NAME_KEY = "claim.name"; + static final String CONFIG_ID_TOKEN_CLAIM_KEY = "id.token.claim"; + static final String CONFIG_JSON_TYPE_LABEL_KEY = "jsonType.label"; + static final String CONFIG_MULTIVALUED_KEY = "multivalued"; + static final String CONFIG_USER_ATTRIBUTE_KEY = "user.attribute"; + static final String CONFIG_USERINFO_TOKEN_CLAIM_KEY = "userinfo.token.claim"; + + static final String ORGANISATIONS_EINHEIT_ID_MAPPER_NAME = "organisationseinheitIdMapper"; + + public ProtocolMapperRepresentation createOrganisationsEinheitIdMapper() { + log.log(Level.FINE, "Build organisationsEinheitId mapper..."); + var mapper = new ProtocolMapperRepresentation(); + mapper.setName(ORGANISATIONS_EINHEIT_ID_MAPPER_NAME); + mapper.setProtocol(OPENID_CONNECT_PROTOCOL); + mapper.setProtocolMapper(ATTRIBUTE_PROTOCOL_MAPPER); + mapper.setConfig(buildOrganisationsEinheitMapperConfig()); + + return mapper; + } + + Map<String, String> buildOrganisationsEinheitMapperConfig() { + var config = new HashMap<String, String>(); + config.put(CONFIG_ACCESS_TOKEN_CLAIM_KEY, "true"); + config.put(CONFIG_AGGREGATE_ATTRS_KEY, "true"); + config.put(CONFIG_CLAIM_NAME_KEY, "organisationseinheitId"); + config.put(CONFIG_ID_TOKEN_CLAIM_KEY, "true"); + config.put(CONFIG_JSON_TYPE_LABEL_KEY, "int"); + config.put(CONFIG_MULTIVALUED_KEY, "true"); + config.put(CONFIG_USER_ATTRIBUTE_KEY, "organisationseinheitId"); + config.put(CONFIG_USERINFO_TOKEN_CLAIM_KEY, "true"); + return config; + } +} \ No newline at end of file diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java index aa80a7419274675aca83b342f1684df3672fd9c3..cee07ecae3203f7fca01296a53d5dd73c97ca250 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java @@ -127,7 +127,8 @@ class KeycloakUserRemoteService { log.log(Level.INFO, "Create secret for user: " + userSpec.getKeycloakUser().getUsername()); var credentialsSecret = createUserSecret(userSpec.getKeycloakUser(), namespace); - kubernetesRemoteService.createSecret(namespace, credentialsSecret); + var secret = getUserSecret(userSpec, namespace); + secret.patch(credentialsSecret); } Secret createUserSecret(KeycloakUserSpecUser userSpec, String namespace) { @@ -142,10 +143,7 @@ class KeycloakUserRemoteService { private ObjectMeta createMetaData(KeycloakUserSpecUser userSpec, String namespace) { var name = buildCredentialSecretName(userSpec); var metadata = new ObjectMeta(); - // TOCHECK welchen Namen brauchen wir? metadata.setName(name); - metadata.setGenerateName(name); - // metadata.setNamespace(namespace); return metadata; } diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java b/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java index 25152788c269579086a747798e4ae0f3b08bebaf..bcce1bb38811ef6cd0016a41e1d5d1e67913d39f 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteService.java @@ -21,10 +21,4 @@ class KubernetesRemoteService { log.log(Level.INFO, "Get " + name + " secret from " + namespace + " namespace."); return kubernetesClient.secrets().inNamespace(namespace).withName(name); } - - public void createSecret(String namespace, Secret secret) { - log.log(Level.INFO, "Create " + secret.getFullResourceName() + " secret in " + namespace + " namespace."); - kubernetesClient.secrets().inNamespace(namespace).create(secret); - log.log(Level.INFO, "Secret successful created."); - } } diff --git a/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientServiceTest.java b/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientServiceTest.java index b6025a31890d6e884425f9a8ed0c98742f92664d..299547392089d0e6823957391255e581fb159567 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientServiceTest.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/client/KeycloakClientServiceTest.java @@ -24,14 +24,18 @@ package de.ozgcloud.operator.keycloak.client; import static de.ozgcloud.operator.keycloak.client.OzgKeycloakClientSpecTestFactory.*; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; 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.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; @@ -55,6 +59,8 @@ class KeycloakClientServiceTest { @Mock private KeycloakGenericRemoteService keycloakGenericRemoteService; + @Mock + private ProtocolMapperRepresentationHelper mapperHelper; @Nested class TestAddClient { @@ -83,42 +89,77 @@ class KeycloakClientServiceTest { } } + @DisplayName("Create client") @Nested class TestCreateClient { - @Test - void shouldCreateClientIfNotExists() { - var clientRepresentation = ClientRepresentationTestFactory.create(); + private final OzgKeycloakClientSpec client = OzgKeycloakClientSpecTestFactory.create(); + private final ClientRepresentation clientRepresentation = ClientRepresentationTestFactory.create(); + + @BeforeEach + void mockMapperHelper() { + doNothing().when(service).setProtocolMapper(any()); + when(mapper.map(any())).thenReturn(clientRepresentation); when(remoteService.createClient(clientRepresentation, TEST_NAMESPACE)).thenReturn(REAL_CLIENT_ID); + } - service.createClient(OzgKeycloakClientSpecTestFactory.create(), TEST_NAMESPACE); + @Test + void shouldCreateClientIfNotExists() { + service.createClient(client, TEST_NAMESPACE); verify(remoteService).createClient(clientRepresentation, TEST_NAMESPACE); } @Test void shouldCallMapper() { - var client = OzgKeycloakClientSpecTestFactory.create(); - service.createClient(client, TEST_NAMESPACE); verify(mapper).map(client); } @Test - void shouldCallAddOrUpdateClientRoles() { - var client = OzgKeycloakClientSpecTestFactory.create(); - var clientRepresentation = ClientRepresentationTestFactory.create(); - when(mapper.map(any())).thenReturn(clientRepresentation); - when(remoteService.createClient(clientRepresentation, TEST_NAMESPACE)).thenReturn(REAL_CLIENT_ID); + void shouldSetProtocolMapper() { + service.createClient(client, TEST_NAMESPACE); + verify(service).setProtocolMapper(clientRepresentation); + } + + @Test + void shouldCallAddOrUpdateClientRoles() { service.createClient(client, TEST_NAMESPACE); verify(service).addOrUpdateClientRoles(client, TEST_NAMESPACE, REAL_CLIENT_ID); } } + @DisplayName("Set protocol mapper") + @Nested + class TestSetProtocolMapper { + + private final ClientRepresentation clientRepresentation = ClientRepresentationTestFactory.create(); + private final ProtocolMapperRepresentation organisationsEinheitIdMapper = ProtocolMapperRepresentationTestFactory.create(); + + @BeforeEach + void mockMapperHelper() { + when(mapperHelper.createOrganisationsEinheitIdMapper()).thenReturn(organisationsEinheitIdMapper); + } + + @Test + void shouldCreateOrganisationsEinheitIdMapper() { + service.setProtocolMapper(clientRepresentation); + + verify(mapperHelper).createOrganisationsEinheitIdMapper(); + } + + @Test + void shouldSetOrganisationsEinheitIdMapper() { + service.setProtocolMapper(clientRepresentation); + + assertThat(clientRepresentation.getProtocolMappers()).contains(organisationsEinheitIdMapper); + } + } + @Nested class TestUpdateClient { diff --git a/src/test/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationHelperTest.java b/src/test/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationHelperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a60e6809a30e238c9c8934bca51dfdd94ccff610 --- /dev/null +++ b/src/test/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationHelperTest.java @@ -0,0 +1,120 @@ +package de.ozgcloud.operator.keycloak.client; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Map; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; +import org.mockito.Spy; + +class ProtocolMapperRepresentationHelperTest { + + @Spy + private final ProtocolMapperRepresentationHelper helper = new ProtocolMapperRepresentationHelper(); + + @DisplayName("Create organisationsEinheitId mapper") + @Nested + class TestCreateOrganisationsEinheitIdMapper { + + @Test + void shouldSetName() { + var mapper = create(); + + assertThat(mapper.getName()).isEqualTo(ProtocolMapperRepresentationHelper.ORGANISATIONS_EINHEIT_ID_MAPPER_NAME); + } + + @Test + void shouldSetProtocol() { + var mapper = create(); + + assertThat(mapper.getProtocol()).isEqualTo(ProtocolMapperRepresentationHelper.OPENID_CONNECT_PROTOCOL); + } + + @Test + void shouldSetProtocolMapper() { + var mapper = create(); + + assertThat(mapper.getProtocolMapper()).isEqualTo(ProtocolMapperRepresentationHelper.ATTRIBUTE_PROTOCOL_MAPPER); + } + + @Test + void shouldBuildConfig() { + create(); + + verify(helper).buildOrganisationsEinheitMapperConfig(); + } + + @DisplayName("build config") + @Nested + class TestBuildOrganisationsEinheitIdConfig { + + @Test + void shouldSetAccessTokenClaim() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_ACCESS_TOKEN_CLAIM_KEY, "true"); + } + + @Test + void shouldSetAggregateAttrs() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_AGGREGATE_ATTRS_KEY, "true"); + } + + @Test + void shouldSetClaimName() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_CLAIM_NAME_KEY, "organisationseinheitId"); + } + + @Test + void shouldSetIdTokenClaim() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_ID_TOKEN_CLAIM_KEY, "true"); + } + + @Test + void shouldSetJsonTypeLabel() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_JSON_TYPE_LABEL_KEY, "int"); + } + + @Test + void shouldSetMultivalued() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_MULTIVALUED_KEY, "true"); + } + + @Test + void shouldSetUserAttribute() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_USER_ATTRIBUTE_KEY, "organisationseinheitId"); + } + + @Test + void shouldSetUserInfoTokenClaim() { + var config = buildConfig(); + + assertThat(config).containsEntry(ProtocolMapperRepresentationHelper.CONFIG_USERINFO_TOKEN_CLAIM_KEY, "true"); + } + + private Map<String, String> buildConfig() { + return helper.buildOrganisationsEinheitMapperConfig(); + } + } + + private ProtocolMapperRepresentation create() { + return helper.createOrganisationsEinheitIdMapper(); + } + } +} diff --git a/src/test/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationTestFactory.java b/src/test/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..f9ab08be894eac228d7db8f1b77f5022d579158d --- /dev/null +++ b/src/test/java/de/ozgcloud/operator/keycloak/client/ProtocolMapperRepresentationTestFactory.java @@ -0,0 +1,10 @@ +package de.ozgcloud.operator.keycloak.client; + +import org.keycloak.representations.idm.ProtocolMapperRepresentation; + +public class ProtocolMapperRepresentationTestFactory { + + public static ProtocolMapperRepresentation create() { + return new ProtocolMapperRepresentation(); + } +} diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java index 2bc3183ce09849316e3a298e0aaea33e504d2ac0..64b3499cfd2e90c5ff8d814d0ed039944acb9b5e 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java @@ -88,8 +88,6 @@ class KeycloakUserRemoteServiceTest { @Mock private UserResource userResource; @Mock - private Response response; - @Mock private ClientsResource clientsResource; @Mock private ClientRepresentation clientRepresentation; @@ -107,6 +105,9 @@ class KeycloakUserRemoteServiceTest { @Nested class TestCreateUser { + @Mock + private Response response; + @BeforeEach void init() { when(keycloak.realm(REALM)).thenReturn(realmResource); @@ -331,7 +332,15 @@ class KeycloakUserRemoteServiceTest { private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create(); @Mock - private Secret createSecret; + private Resource<Secret> secretResource; + @Mock + private Secret secret; + + @BeforeEach + void mock() { + doReturn(secretResource).when(userRemoteService).getUserSecret(any(), any()); + doReturn(secret).when(userRemoteService).createUserSecret(any(), any()); + } @Test void shouldBuildUserSecret() { @@ -341,13 +350,27 @@ class KeycloakUserRemoteServiceTest { } @Test - void shouldCreateSecret() { - doReturn(createSecret).when(userRemoteService).createUserSecret(any(), any()); + void shouldGetSecret() { + userRemoteService.createSecret(userSpec, NAMESPACE); + verify(userRemoteService).getUserSecret(userSpec, NAMESPACE); + } + + @Test + void shouldPatchSecret() { userRemoteService.createSecret(userSpec, NAMESPACE); - verify(kubernetesRemoteService).createSecret(NAMESPACE, createSecret); + verify(secretResource).patch(secret); } + +// @Test +// void shouldCreateSecret() { +// doReturn(secret).when(userRemoteService).createUserSecret(any(), any()); +// +// userRemoteService.createSecret(userSpec, NAMESPACE); +// +// verify(kubernetesRemoteService).createSecret(NAMESPACE, secret); +// } } @DisplayName("Create user secret") @@ -391,13 +414,6 @@ class KeycloakUserRemoteServiceTest { assertThat(secret.getMetadata().getName()).isEqualTo(userSpec.getUsername() + "-credentials"); } - @Test - void shouldHaveGeneratedName() { - var secret = userRemoteService.createUserSecret(userSpec, NAMESPACE); - - assertThat(secret.getMetadata().getGenerateName()).isEqualTo(userSpec.getUsername() + "-credentials"); - } - @Test void shouldHaveNamespace() { var secret = userRemoteService.createUserSecret(userSpec, NAMESPACE); diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteServiceTest.java b/src/test/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteServiceTest.java index 443e458194c181f347e419500d139b69a5c6353a..e2084632dd0c836d66eb8b4efdb3196a0e31481e 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteServiceTest.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/user/KubernetesRemoteServiceTest.java @@ -54,34 +54,4 @@ class KubernetesRemoteServiceTest { verify(secretsMock).withName(SECRET_NAME); } } - - @DisplayName("Create secret") - @Nested - class TestCreateSecret { - - @Mock - private Secret secret; - @Mock - private MixedOperation<Secret, SecretList, Resource<Secret>> secretsMock; - - @BeforeEach - void mock() { - when(kubernetesClient.secrets()).thenReturn(secretsMock); - when(secretsMock.inNamespace(any())).thenReturn(secretsMock); - } - - @Test - void shouldGetFromNamespace() { - service.createSecret(NAMESPACE, secret); - - verify(secretsMock).create(secret); - } - - @Test - void shouldCreateByGivenSecret() { - service.createSecret(NAMESPACE, secret); - - verify(secretsMock).create(any()); - } - } }