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 b3c23a7a89fe854d85f6b34f4c1dc7079169ccd3..fbb73dadca282faa7e218288efb312d963b357d0 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteService.java @@ -29,6 +29,8 @@ import java.util.Objects; import java.util.Optional; import java.util.logging.Level; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; import org.keycloak.admin.client.CreatedResponseUtil; import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.resource.RealmResource; @@ -41,6 +43,7 @@ import org.springframework.stereotype.Component; import de.ozgcloud.operator.keycloak.KeycloakException; import de.ozgcloud.operator.keycloak.KeycloakGenericRemoteService; import de.ozgcloud.operator.keycloak.KeycloakResultParser; +import de.ozgcloud.operator.keycloak.user.OzgKeycloakUserSpec.KeycloakUserSpecUser; import io.fabric8.kubernetes.api.model.ObjectMeta; import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.api.model.SecretBuilder; @@ -52,8 +55,9 @@ import lombok.extern.java.Log; @Component class KeycloakUserRemoteService { - private static final String SECRET_PASSWORD_FIELD = "password"; - private static final String SECRET_NAME_FIELD = "name"; + private static final String SECRET_TYPE = "Opaque"; + static final String SECRET_PASSWORD_FIELD = "password"; + static final String SECRET_NAME_FIELD = "name"; @Autowired private Keycloak keycloak; @@ -115,57 +119,75 @@ class KeycloakUserRemoteService { realmResource.users().get(userId).roles().clientLevel(appClient.getId()).add(Arrays.asList(clientRole)); } - // PoC - public String createSecret(OzgKeycloakUserSpec userSpec, String createdNamespace) { - log.log(Level.INFO, "Create secret for user: " + userSpec.getKeycloakUser().getUsername()); - var secretName = userSpec.getKeycloakUser().getUsername().toLowerCase() + "-credentials"; + public boolean existSecret(OzgKeycloakUserSpec userSpec, String namespace) { + var secret = getUserSecret(userSpec, namespace); + + return Objects.nonNull(secret.get()); + } -// var namespace = "keycloak"; - var namespace = createdNamespace; - var secret = getSecret(secretName, namespace); - if (Objects.isNull(secret.get())) { - log.log(Level.INFO, "...secret does not exist, create one..."); + public void createSecret(OzgKeycloakUserSpec userSpec, String createdNamespace) { + log.log(Level.INFO, "Create secret for user: " + userSpec.getKeycloakUser().getUsername()); + var namespace = "keycloak";// TODO durch den namespace ersetzen, wenn die Helm Charts passen - var credentialsSecret = buildSecret(secretName, userSpec.getKeycloakUser().getPassword()); - kubernetesClient.secrets().inNamespace(namespace).create(credentialsSecret); + var credentialsSecret = createUserSecret(userSpec.getKeycloakUser(), namespace); - log.log(Level.INFO, "...secret created '" + secretName + "' in " + namespace + " for user " + userSpec.getKeycloakUser().getUsername()); - var newPassword = getPassword(getSecret(secretName, namespace)); - log.log(Level.INFO, "return password from created secret:" + newPassword); - return newPassword; - } - var password = getPassword(secret); - log.log(Level.INFO, "secret exists, return with password:" + password); - return password; + kubernetesClient.secrets().inNamespace(namespace).create(credentialsSecret); + log.log(Level.INFO, "Secret successful created in namespace: " + namespace); } - private Resource<Secret> getSecret(String secretName, String namespace) { - return kubernetesClient.secrets().inNamespace(namespace).withName(secretName); + Secret createUserSecret(KeycloakUserSpecUser userSpec, String namespace) { + return new SecretBuilder() + .withType(SECRET_TYPE) + .withMetadata(createMetaData(userSpec, namespace)) + .addToStringData(SECRET_NAME_FIELD, userSpec.getUsername()) + .addToStringData(SECRET_PASSWORD_FIELD, getPassword(userSpec.getPassword())) + .build(); } - Secret buildSecret(String name, String password) { + 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("keycloak"); + // + metadata.setNamespace(namespace); + return metadata; + } - return new SecretBuilder() - .withType("Opaque") - .withMetadata(metadata) - .addToStringData(SECRET_PASSWORD_FIELD, password) - .addToStringData(SECRET_NAME_FIELD, name) - .build(); + String getPassword(String userPassword) { + return StringUtils.isEmpty(userPassword) ? generateRandomPasswordForKeycloak() : userPassword; + } + + private String generateRandomPasswordForKeycloak() { + var upperCaseCharacter = RandomStringUtils.random(1).toUpperCase(); + var randomString = RandomStringUtils.random(7); + return upperCaseCharacter + randomString; + } + + public String getPasswordFromSecret(OzgKeycloakUserSpec userSpec, String namespace) { + var secret = getUserSecret(userSpec, namespace); + return getPasswordFromSecret(secret); + } + + public Resource<Secret> getUserSecret(OzgKeycloakUserSpec userSpec, String namespace) { + var secretName = buildCredentialSecretName(userSpec.getKeycloakUser()); + return getUserSecret(secretName, namespace); + } + + private String buildCredentialSecretName(KeycloakUserSpecUser userSpec) { + return userSpec.getUsername().toLowerCase() + "-credentials"; + } + + private Resource<Secret> getUserSecret(String secretName, String namespace) { + return kubernetesClient.secrets().inNamespace(namespace).withName(secretName); } - private String getPassword(Resource<Secret> secret) { - return decodeBase64(secret.get().getData().get(SECRET_PASSWORD_FIELD)); + private String getPasswordFromSecret(Resource<Secret> secret) { + return decodeBase64(secret.get().getStringData().get(SECRET_PASSWORD_FIELD)); } - String decodeBase64(String base64String) { - log.log(Level.INFO, "base64String to decode: " + base64String); - var decoded = Base64.getDecoder().decode(base64String); - log.log(Level.INFO, "decoded string: " + decoded); - return new String(decoded); + private String decodeBase64(String base64String) { + return new String(Base64.getDecoder().decode(base64String)); } - // } \ No newline at end of file diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java index 4493b8c1f47d3f17fc0864c3c564ad6d8056db5c..a25b97be1464c5115090349d4cfd40483aa6e795 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserService.java @@ -42,17 +42,16 @@ class KeycloakUserService { private KeycloakUserMapper userMapper; public void createOrUpdateUser(OzgKeycloakUserSpec userSpec, String namespace) { - // PoC -// if (!StringUtils.hasLength(userSpec.getKeycloakUser().getPassword())) { - log.log(Level.INFO, "createOrUpdateUser createSecret for credentials..."); - log.log(Level.INFO, "Old password: " + userSpec.getKeycloakUser().getPassword()); -// log.log(Level.INFO, "User has no password, create secret..."); - var password = remoteService.createSecret(userSpec, namespace); - log.log(Level.INFO, "New password: " + password); + log.log(Level.INFO, "createOrUpdateUser"); + + if (!remoteService.existSecret(userSpec, namespace)) { + log.log(Level.INFO, "Secret not exists -> create one"); + remoteService.createSecret(userSpec, namespace); + } + var password = remoteService.getPasswordFromSecret(userSpec, namespace); + log.log(Level.INFO, "Update password to: " + password); userSpec.getKeycloakUser().setPassword(password); -// } - log.log(Level.INFO, "proceed"); - // + remoteService.getUserByName(userSpec.getKeycloakUser().getUsername(), namespace) .ifPresentOrElse(existingUser -> remoteService.updateUser(userMapper.update(existingUser, userSpec), namespace), () -> remoteService.createUser(userMapper.map(userSpec), namespace)); 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 698c7d742c543a16415820d6f1c7068a40e14a0a..8f44e5328c246c08e5313062865effcbdc40e359 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserRemoteServiceTest.java @@ -28,12 +28,14 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; +import java.util.Base64; import java.util.Collections; import java.util.List; import java.util.Optional; import javax.ws.rs.core.Response; +import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -54,7 +56,13 @@ import org.mockito.Spy; import de.ozgcloud.operator.keycloak.KeycloakException; import de.ozgcloud.operator.keycloak.KeycloakGenericRemoteService; +import de.ozgcloud.operator.keycloak.user.OzgKeycloakUserSpec.KeycloakUserSpecUser; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.api.model.SecretBuilder; +import io.fabric8.kubernetes.api.model.SecretList; import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.dsl.MixedOperation; +import io.fabric8.kubernetes.client.dsl.Resource; class KeycloakUserRemoteServiceTest { @@ -272,4 +280,191 @@ class KeycloakUserRemoteServiceTest { verify(usersResource).delete(USERID); } } + + @DisplayName("Exists secret") + @Nested + class TestExistsSecret { + + private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create(); + + @Mock + private Resource<Secret> resourceMock; + + @BeforeEach + void mock() { + doReturn(resourceMock).when(userRemoteService).getUserSecret(any(), any()); + } + + @Test + void shouldReturnTrueIfExists() { + when(resourceMock.get()).thenReturn(new Secret()); + + var exists = userRemoteService.existSecret(userSpec, REALM); + + assertThat(exists).isTrue(); + } + + @Test + void shouldReturnFalseIfNotExists() { + when(resourceMock.get()).thenReturn(null); + + var exists = userRemoteService.existSecret(userSpec, REALM); + + assertThat(exists).isFalse(); + } + } + + @DisplayName("Create Secret") + @Nested + class TestCreateSecret { + + private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create(); + + @Mock + private Secret credentialSecret; + + @Mock + private MixedOperation<Secret, SecretList, Resource<Secret>> secretsMock; + + @BeforeEach + void mock() { + when(kubernetesClient.secrets()).thenReturn(secretsMock); + when(secretsMock.inNamespace(any())).thenReturn(secretsMock); + } + + @Test + void shouldBuildUserSecret() { + userRemoteService.createSecret(userSpec, REALM); + + verify(userRemoteService).createUserSecret(eq(userSpec.getKeycloakUser()), any()); + } + + @Test + void shouldCreateSecret() { + userRemoteService.createSecret(userSpec, REALM); + + verify(secretsMock).create(any()); + } + } + + @DisplayName("Create user secret") + @Nested + class TestCreateUserSecret { + + private final KeycloakUserSpecUser userSpec = KeycloakUserSpecUserTestFactory.create(); + + @Test + void shouldHaveType() { + var secret = userRemoteService.createUserSecret(userSpec, REALM); + + assertThat(secret.getType()).isEqualTo("Opaque"); + } + + @Test + void shouldHaveUserName() { + var secret = userRemoteService.createUserSecret(userSpec, REALM); + + assertThat(secret.getStringData()).containsEntry(KeycloakUserRemoteService.SECRET_NAME_FIELD, KeycloakUserSpecUserTestFactory.USERNAME); + } + + @Test + void shouldHavePassword() { + doReturn(KeycloakUserSpecUserTestFactory.PASSWORD).when(userRemoteService).getPassword(any()); + + var secret = userRemoteService.createUserSecret(userSpec, REALM); + + assertThat(secret.getStringData()).containsEntry(KeycloakUserRemoteService.SECRET_PASSWORD_FIELD, + KeycloakUserSpecUserTestFactory.PASSWORD); + } + + @DisplayName("metadata") + @Nested + class TestMetaData { + + @Test + void shouldHaveName() { + var secret = userRemoteService.createUserSecret(userSpec, REALM); + + assertThat(secret.getMetadata().getName()).isEqualTo(userSpec.getUsername() + "-credentials"); + } + + @Test + void shouldHaveGeneratedName() { + var secret = userRemoteService.createUserSecret(userSpec, REALM); + + assertThat(secret.getMetadata().getGenerateName()).isEqualTo(userSpec.getUsername() + "-credentials"); + } + + @Test + void shouldHaveNamespace() { + var secret = userRemoteService.createUserSecret(userSpec, REALM); + + assertThat(secret.getMetadata().getNamespace()).isEqualTo(REALM); + } + } + } + + @DisplayName("Get password") + @Nested + class TestGetPassword { + + @Test + void shouldReturnPasswordIfExists() { + var password = userRemoteService.getPassword(KeycloakUserSpecUserTestFactory.PASSWORD); + + assertThat(password).isEqualTo(KeycloakUserSpecUserTestFactory.PASSWORD); + } + + @Test + void shouldGeneratePasswordIfNotExists() { + var password = userRemoteService.getPassword(StringUtils.EMPTY); + + assertThat(password).isNotEmpty(); + assertThat(StringUtils.substring(password, 0, 1)).isUpperCase(); + } + } + + @DisplayName("Get user secret") + @Nested + class TestGetUserSecret { + + @Mock + private MixedOperation<Secret, SecretList, Resource<Secret>> secretsMock; + + @BeforeEach + void mock() { + when(kubernetesClient.secrets()).thenReturn(secretsMock); + when(secretsMock.inNamespace(any())).thenReturn(secretsMock); + + } + + @Test + void shouldGetWithName() { + userRemoteService.getUserSecret(OzgKeycloakUserSpecTestFactory.create(), REALM); + + verify(secretsMock).withName(KeycloakUserSpecUserTestFactory.USERNAME + "-credentials"); + } + } + + @DisplayName("Get password from secret") + @Nested + class TestGetPasswordFromSecret { + + @Mock + private Resource<Secret> resource; + private OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create(); + private Secret secret = new SecretBuilder() + .addToStringData(KeycloakUserRemoteService.SECRET_PASSWORD_FIELD, Base64.getEncoder().encodeToString("dummyPassword".getBytes())) + .build(); + + @Test + void shouldReturnDecodedPassword() { + doReturn(resource).when(userRemoteService).getUserSecret(any(), any()); + when(resource.get()).thenReturn(secret); + + var password = userRemoteService.getPasswordFromSecret(userSpec, REALM); + + assertThat(password).isEqualTo("dummyPassword"); + } + } } \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java index 3d3d0a6167d2054c42b6125843ddfdcd68c3529e..a574e8b07b9dd9a84b3891a2ce35dd8fac8e560a 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserServiceTest.java @@ -23,88 +23,131 @@ */ package de.ozgcloud.operator.keycloak.user; +import static org.assertj.core.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.Optional; import org.apache.commons.lang3.StringUtils; +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.UserRepresentation; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Mockito; import org.mockito.Spy; +import io.fabric8.kubernetes.api.model.Secret; +import io.fabric8.kubernetes.client.dsl.Resource; + class KeycloakUserServiceTest { private static final String TEST_NAMESPACE = "TestNamespace"; private static final String TEST_USERID = "TestUserId"; + private static final String PASSWORD = "CreatedDummyPassword"; @Spy @InjectMocks - private KeycloakUserService userService; + private KeycloakUserService service; @Mock - private KeycloakUserRemoteService userRemoteService; + private KeycloakUserRemoteService remoteService; @Mock private KeycloakUserMapper userMapper; + @DisplayName("Create or Update") @Nested - class TestAddUser { + class TestCreateOrUpdate { - @Test - void shouldCallUserMapper() { - var testUser = OzgKeycloakUserSpecTestFactory.create(); + @Mock + private Resource<Secret> resource; + @Captor + private ArgumentCaptor<OzgKeycloakUserSpec> ozgKeycloakUserSpecCaptor; - userService.createOrUpdateUser(testUser, TEST_NAMESPACE); + private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.create(); - verify(userMapper).map(testUser); + @BeforeEach + void mock() { + when(remoteService.getPasswordFromSecret(any(), any())).thenReturn(PASSWORD); } @Test - void shouldCallUserRemoteServiceGetUserByName() { - var userRepresentation = UserRepresentationTestFactory.create(); + void shouldVerifiySecretExists() { + service.createOrUpdateUser(userSpec, TEST_NAMESPACE); - userService.createOrUpdateUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); + verify(remoteService).existSecret(userSpec, TEST_NAMESPACE); + } + + @Test + void shouldCreateSecretIfNotExists() { + when(remoteService.existSecret(any(), any())).thenReturn(false); - verify(userRemoteService).getUserByName(eq(userRepresentation.getUsername()), eq(TEST_NAMESPACE)); + service.createOrUpdateUser(userSpec, TEST_NAMESPACE); + + verify(remoteService).createSecret(userSpec, TEST_NAMESPACE); } @Test - void shouldCreateSecretIfPasswordIsNotSet() { - when(userRemoteService.createSecret(any(), any())).thenReturn("TestPassword"); + void shouldGetPasswordFromSecret() { + service.createOrUpdateUser(userSpec, TEST_NAMESPACE); + + verify(remoteService).getPasswordFromSecret(userSpec, TEST_NAMESPACE); + } - var testUser = OzgKeycloakUserSpecTestFactory.createBuilder() + @Test + void shouldSetPasswortFromSecret() { + var userWithoutPassword = OzgKeycloakUserSpecTestFactory.createBuilder() .keycloakUser(KeycloakUserSpecUserTestFactory.createBuiler().password(StringUtils.EMPTY).build()).build(); - userService.createOrUpdateUser(testUser, TEST_NAMESPACE); + service.createOrUpdateUser(userWithoutPassword, TEST_NAMESPACE); + + verify(userMapper).map(ozgKeycloakUserSpecCaptor.capture()); + assertThat(ozgKeycloakUserSpecCaptor.getValue().getKeycloakUser().getPassword()).isEqualTo(PASSWORD); + } + + @Test + void shouldCallUserMapper() { + service.createOrUpdateUser(userSpec, TEST_NAMESPACE); + + verify(userMapper).map(userSpec); + } + + @Test + void shouldCallUserRemoteServiceGetUserByName() { + var userRepresentation = UserRepresentationTestFactory.create(); + + service.createOrUpdateUser(userSpec, TEST_NAMESPACE); - verify(userRemoteService).createSecret(testUser, TEST_NAMESPACE); + verify(remoteService).getUserByName(userRepresentation.getUsername(), TEST_NAMESPACE); } @Test void shouldCreateUserIfNotExists() { - when(userRemoteService.getUserByName(OzgKeycloakUserSpecTestFactory.KEYCLOAK_USER.getUsername(), TEST_NAMESPACE)) + when(remoteService.getUserByName(OzgKeycloakUserSpecTestFactory.KEYCLOAK_USER.getUsername(), TEST_NAMESPACE)) .thenReturn(Optional.empty()); - when(userMapper.map(any())).thenReturn(mock(UserRepresentation.class)); + when(userMapper.map(any())).thenReturn(Mockito.mock(UserRepresentation.class)); - userService.createOrUpdateUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); + service.createOrUpdateUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); - verify(userRemoteService).createUser(any(UserRepresentation.class), eq(TEST_NAMESPACE)); + verify(remoteService).createUser(any(UserRepresentation.class), eq(TEST_NAMESPACE)); } @Test void shouldUpdateUserIfExists() { - var userRepresentation = mock(UserRepresentation.class); - when(userRemoteService.getUserByName(OzgKeycloakUserSpecTestFactory.KEYCLOAK_USER.getUsername(), TEST_NAMESPACE)) + var userRepresentation = Mockito.mock(UserRepresentation.class); + when(remoteService.getUserByName(OzgKeycloakUserSpecTestFactory.KEYCLOAK_USER.getUsername(), TEST_NAMESPACE)) .thenReturn(Optional.of(userRepresentation)); when(userMapper.update(eq(userRepresentation), any())).thenReturn(userRepresentation); - userService.createOrUpdateUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); + service.createOrUpdateUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); - verify(userRemoteService).updateUser(eq(userRepresentation), eq(TEST_NAMESPACE)); + verify(remoteService).updateUser(userRepresentation, TEST_NAMESPACE); } } @@ -116,7 +159,7 @@ class KeycloakUserServiceTest { var testUser = OzgKeycloakUserSpecTestFactory.create(); - userService.deleteUser(testUser, TEST_NAMESPACE); + service.deleteUser(testUser, TEST_NAMESPACE); verify(userMapper).map(testUser); } @@ -127,9 +170,9 @@ class KeycloakUserServiceTest { var userRepresentation = UserRepresentationTestFactory.create(); when(userMapper.map(any())).thenReturn(userRepresentation); - userService.deleteUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); + service.deleteUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); - verify(userRemoteService).getUserByName(eq(userRepresentation.getUsername()), eq(TEST_NAMESPACE)); + verify(remoteService).getUserByName(userRepresentation.getUsername(), TEST_NAMESPACE); } @Test @@ -137,12 +180,12 @@ class KeycloakUserServiceTest { var userRepresentation = UserRepresentationTestFactory.create(); when(userMapper.map(any())).thenReturn(userRepresentation); - when(userRemoteService.getUserByName(UserRepresentationTestFactory.USERNAME, TEST_NAMESPACE)).thenReturn(Optional.of(userRepresentation)); + when(remoteService.getUserByName(UserRepresentationTestFactory.USERNAME, TEST_NAMESPACE)).thenReturn(Optional.of(userRepresentation)); userRepresentation.setId(TEST_USERID); - userService.deleteUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); + service.deleteUser(OzgKeycloakUserSpecTestFactory.create(), TEST_NAMESPACE); - verify(userRemoteService).deleteUser(eq(TEST_USERID), eq(TEST_NAMESPACE)); + verify(remoteService).deleteUser(TEST_USERID, TEST_NAMESPACE); } } }