diff --git a/src/main/java/biz/nynja/account/components/AccountServiceHelper.java b/src/main/java/biz/nynja/account/components/AccountServiceHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..c47fa789bc087d4b2cb4b4839c5007de28c3ad57 --- /dev/null +++ b/src/main/java/biz/nynja/account/components/AccountServiceHelper.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2018 Nynja Inc. All rights reserved. + */ +package biz.nynja.account.components; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import biz.nynja.account.models.Account; +import biz.nynja.account.models.AccountByAuthenticationProvider; +import biz.nynja.account.repositories.AccountByAuthenticationProviderRepository; + +@Service +public class AccountServiceHelper { + @Autowired + private AccountByAuthenticationProviderRepository accountByAuthenticationProviderRepository; + + public Account getAccountByAuthenticationProviderHelper(String authenticationIdentifier, + String type) { + + List accounts = accountByAuthenticationProviderRepository + .findAllByAuthenticationProvider(authenticationIdentifier); + + if (accounts.isEmpty()) { + return null; + } + + // We retrieve accounts by authentication provider identifier from DB where both authentication provider + // identifier and type uniquely identify an account. + // For this reason we need to filter results by authentication provider type. + for (AccountByAuthenticationProvider account : accounts) { + if (account.getAuthenticationProviderType().equals(type)) { + return account.toAccount(); + } + } + + return null; + } +} diff --git a/src/main/java/biz/nynja/account/components/Validator.java b/src/main/java/biz/nynja/account/components/Validator.java index 64c0873b29b3675de727102f8f256bbf1555aad0..769307bbb72ddc5cab152613b6cf2d42d4423c40 100644 --- a/src/main/java/biz/nynja/account/components/Validator.java +++ b/src/main/java/biz/nynja/account/components/Validator.java @@ -26,6 +26,7 @@ import biz.nynja.account.grpc.AuthProviderDetails; import biz.nynja.account.grpc.AuthenticationType; import biz.nynja.account.grpc.CompletePendingAccountCreationRequest; import biz.nynja.account.grpc.CreatePendingAccountRequest; +import biz.nynja.account.grpc.DeleteAuthenticationProviderRequest; import biz.nynja.account.grpc.ErrorResponse.Cause; import biz.nynja.account.grpc.UpdateAccountRequest; import biz.nynja.account.grpc.UpdateProfileRequest; @@ -308,4 +309,16 @@ public class Validator { return validateAuthProvider(request.getAuthenticationProvider().getAuthenticationType(), request.getAuthenticationProvider().getAuthenticationProvider()); } + + public Cause validateDeleteAuthenticationProviderRequest(DeleteAuthenticationProviderRequest request) { + if (!isValidUuid(request.getProfileId())) { + return Cause.INVALID_PROFILE_ID; + } + Cause cause = validateAuthProvider(request.getAuthenticationProvider().getAuthenticationType(), + request.getAuthenticationProvider().getAuthenticationProvider()); + if (cause != null) { + return cause; + } + return null; + } } diff --git a/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java b/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java index 7ef1245a020391e54ccc1692652f82704596fd73..498059d87e0f32acae9ead6f8a1ea73982b4bddf 100644 --- a/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java +++ b/src/main/java/biz/nynja/account/models/AccountByAuthenticationProvider.java @@ -319,4 +319,23 @@ public class AccountByAuthenticationProvider { } + public Account toAccount() { + Account account = new Account(); + account.setAccountId(this.accountId); + account.setProfileId(this.profileId); + account.setAccountMark(this.accountMark); + account.setAuthenticationProvider(this.authenticationProvider); + account.setAuthenticationProviderType(this.authenticationProviderType); + account.setFirstName(this.firstName); + account.setLastName(this.lastName); + account.setAvatar(this.avatar); + account.setAccountName(this.accountName); + account.setUsername(this.username); + account.setAccountStatus(this.accountStatus); + account.setCreationTimestamp(this.creationTimestamp); + account.setLastUpdateTimestamp(this.lastUpdateTimestamp); + account.setCommunicationProviders(this.communicationProviders); + account.setQrCode(this.qrCode); + return account; + } } diff --git a/src/main/java/biz/nynja/account/models/Profile.java b/src/main/java/biz/nynja/account/models/Profile.java index 86071a31b0f2367bb50735e8320d398084355429..63e09dc76e4c9473e3d1042e90961583f7e2ca27 100644 --- a/src/main/java/biz/nynja/account/models/Profile.java +++ b/src/main/java/biz/nynja/account/models/Profile.java @@ -173,4 +173,7 @@ public class Profile { return builder.build(); } + public boolean removeAuthenticationProvider(AuthenticationProvider ap) { + return authenticationProviders.remove(ap); + } } diff --git a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java index d0fdd3676321ed515d33e5cf9d4b0056dc873677..e7628f96465048734bfbf2d4f488e3e86035e403 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java +++ b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditional.java @@ -35,4 +35,6 @@ public interface AccountRepositoryAdditional { boolean authenticationProviderAlreadyUsedInAccount(AuthenticationProvider authProvider); boolean addAuthenticationProvider(UUID profileId, AuthenticationProvider authProvider); + + boolean deleteAuthenticationProvider(Profile profile, AuthenticationProvider authProvider); } diff --git a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java index 6baf5ba879d28f3728be30b43ea8e9ea03310f7f..b8868094eae5643bb00e67c3a00b2a34c0858b6b 100644 --- a/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java +++ b/src/main/java/biz/nynja/account/repositories/AccountRepositoryAdditionalImpl.java @@ -24,6 +24,8 @@ import com.datastax.driver.core.Session; import com.datastax.driver.core.SimpleStatement; import com.datastax.driver.core.Statement; +import biz.nynja.account.components.AccountServiceHelper; +import biz.nynja.account.grpc.AccountDetails; import biz.nynja.account.grpc.AuthProviderDetails; import biz.nynja.account.grpc.CompletePendingAccountCreationRequest; import biz.nynja.account.grpc.UpdateAccountRequest; @@ -74,6 +76,9 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio @Autowired private PendingAccountRepository pendingAccountRepository; + @Autowired + private AccountServiceHelper accountServiceHelper; + @Autowired private Session session; @@ -691,4 +696,55 @@ public class AccountRepositoryAdditionalImpl implements AccountRepositoryAdditio } return false; } + + @Override + public boolean deleteAuthenticationProvider(Profile profile, + AuthenticationProvider authProvider) { + + BatchStatement batch = new BatchStatement(); + ResultSet rs = null; + + // Remove authentication provider form list of authentication providers in profile + Statement st1 = new SimpleStatement("UPDATE profile SET authenticationproviders = authenticationproviders - {('" + + authProvider.getType() + "', '" + authProvider.getValue() + + "')} WHERE profileid = " + profile.getProfileId().toString()); + batch.add(st1); + + // Remove record for profile by this authentication provider + Statement st2 = new SimpleStatement( + "DELETE FROM profilebyauthenticationprovider where authenticationprovider = '" + + authProvider.getValue() + "' and authenticationprovidertype = '" + + authProvider.getType() + "';"); + batch.add(st2); + + // The requested authentication provider is set as a backup provider. We have to delete the reference. + if (profile.getBackupAuthenticationProvider() != null + && profile.getBackupAuthenticationProvider().equals(authProvider)) { + Statement st3 = new SimpleStatement("DELETE backupauthenticationprovider FROM profile WHERE profileid = " + + profile.getProfileId().toString()); + batch.add(st3); + } + + // Check if there is an account, created using this authentication provider + Account account = accountServiceHelper.getAccountByAuthenticationProviderHelper( + authProvider.getValue(), authProvider.getType()); + + + // Delete authentication provider from account + if (account != null) { + Statement st4 = new SimpleStatement( + "DELETE authenticationprovidertype, authenticationprovider FROM account WHERE accountid = " + + account.getAccountId().toString()); + batch.add(st4); + } + + rs = session.execute(batch); + if (rs != null) { + boolean applied = rs.wasApplied(); + if (applied) { + return true; + } + } + return false; + } } diff --git a/src/main/java/biz/nynja/account/services/AccountServiceImpl.java b/src/main/java/biz/nynja/account/services/AccountServiceImpl.java index 617cc28708ac52dd5c571c4a5455c2f4876ad892..437066074ec60cb48b576d808bd0dbab3bdfa37f 100644 --- a/src/main/java/biz/nynja/account/services/AccountServiceImpl.java +++ b/src/main/java/biz/nynja/account/services/AccountServiceImpl.java @@ -13,6 +13,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import biz.nynja.account.components.AccountServiceHelper; import biz.nynja.account.components.Validator; import biz.nynja.account.grpc.AccountByAccountIdRequest; import biz.nynja.account.grpc.AccountByAuthenticationProviderRequest; @@ -28,13 +29,12 @@ import biz.nynja.account.grpc.CreateAccountRequest; import biz.nynja.account.grpc.CreatePendingAccountRequest; import biz.nynja.account.grpc.CreatePendingAccountResponse; import biz.nynja.account.grpc.DeleteAccountRequest; +import biz.nynja.account.grpc.DeleteAuthenticationProviderRequest; import biz.nynja.account.grpc.StatusResponse; import biz.nynja.account.grpc.DeleteProfileRequest; import biz.nynja.account.grpc.ErrorResponse; import biz.nynja.account.grpc.ErrorResponse.Cause; -import biz.nynja.account.grpc.StatusResponse; import biz.nynja.account.models.Account; -import biz.nynja.account.models.AccountByAuthenticationProvider; import biz.nynja.account.models.AccountByProfileId; import biz.nynja.account.models.AuthenticationProvider; import biz.nynja.account.models.PendingAccount; @@ -49,7 +49,6 @@ import biz.nynja.account.repositories.PendingAccountByAuthenticationProviderRepo import biz.nynja.account.repositories.PendingAccountRepository; import biz.nynja.account.repositories.ProfileByAuthenticationProviderRepository; import biz.nynja.account.repositories.ProfileRepository; -import biz.nynja.account.grpc.AccountsResponse; import biz.nynja.account.grpc.UpdateAccountRequest; import biz.nynja.account.grpc.UpdateProfileRequest; import biz.nynja.account.grpc.UpdateProfileResponse; @@ -93,6 +92,9 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas @Autowired private Validator validator; + @Autowired + private AccountServiceHelper accountServiceHelper; + @Override public void createAccount(CreateAccountRequest request, StreamObserver responseObserver) { @@ -118,12 +120,9 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas return; } - AccountDetails accountDetails = null; - - List accounts = accountByAuthenticationProviderRepository - .findAllByAuthenticationProvider(request.getAuthenticationIdentifier()); - - if (accounts.isEmpty()) { + Account account = accountServiceHelper.getAccountByAuthenticationProviderHelper( + request.getAuthenticationIdentifier(), request.getAuthenticationType().toString()); + if (account == null) { logger.debug("No matching accounts found for authetntication provider {}: {}", request.getAuthenticationType(), request.getAuthenticationIdentifier()); responseObserver.onNext(AccountResponse.newBuilder() @@ -132,25 +131,7 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas return; } - // We retrieve accounts by authentication provider identifier from DB where both authentication provider - // identifier and type uniquely identify an account. - // For this reason we need to filter results by authentication provider type. - for (AccountByAuthenticationProvider account : accounts) { - if (account.getAuthenticationProviderType().equals(request.getAuthenticationType().name())) { - accountDetails = account.toProto(); - break; - } - } - if (accountDetails == null) { - logger.debug("No matching accounts found for authetntication provider {}: {}", - request.getAuthenticationType(), request.getAuthenticationIdentifier()); - responseObserver.onNext(AccountResponse.newBuilder() - .setError(ErrorResponse.newBuilder().setCause(Cause.ACCOUNT_NOT_FOUND)).build()); - responseObserver.onCompleted(); - return; - } - - AccountResponse response = AccountResponse.newBuilder().setAccountDetails(accountDetails).build(); + AccountResponse response = AccountResponse.newBuilder().setAccountDetails(account.toProto()).build(); logger.debug("Found result for account by authentication provider {}: {}: \"{}\"", request.getAuthenticationType(), request.getAuthenticationIdentifier(), response); responseObserver.onNext(response); @@ -551,4 +532,81 @@ public class AccountServiceImpl extends AccountServiceGrpc.AccountServiceImplBas responseObserver.onCompleted(); return; } + + @Override + public void deleteAuthenticationProviderFromProfile(DeleteAuthenticationProviderRequest request, + StreamObserver responseObserver) { + logger.info("Deleting Authentication Provider from profile: {}", request); + + if ((request.getProfileId() == null) || (request.getProfileId().isEmpty())) { + responseObserver.onNext(StatusResponse.newBuilder() + .setError(ErrorResponse.newBuilder().setCause(Cause.MISSING_PROFILE_ID)).build()); + responseObserver.onCompleted(); + return; + } + if (request.getAuthenticationProvider().getAuthenticationTypeValue() == 0) { + responseObserver.onNext(StatusResponse.newBuilder() + .setError(ErrorResponse.newBuilder().setCause(Cause.MISSING_AUTH_PROVIDER_TYPE)).build()); + responseObserver.onCompleted(); + return; + } + if (request.getAuthenticationProvider().getAuthenticationProvider() == null + || request.getAuthenticationProvider().getAuthenticationProvider().isEmpty()) { + responseObserver.onNext(StatusResponse.newBuilder() + .setError(ErrorResponse.newBuilder().setCause(Cause.MISSING_AUTH_PROVIDER_IDENTIFIER)).build()); + responseObserver.onCompleted(); + return; + } + + Cause cause = validator.validateDeleteAuthenticationProviderRequest(request); + if (cause != null) { + responseObserver + .onNext(StatusResponse.newBuilder().setError(ErrorResponse.newBuilder().setCause(cause)).build()); + responseObserver.onCompleted(); + return; + } + + // Make sure that the requested profile id for update exists in DB. + Profile profile = profileRepository.findByProfileId(UUID.fromString(request.getProfileId())); + if (profile == null) { + logger.error("Profile id {} missing in DB.", request.getProfileId()); + responseObserver.onNext(StatusResponse.newBuilder() + .setError(ErrorResponse.newBuilder().setCause(Cause.PROFILE_NOT_FOUND)).build()); + responseObserver.onCompleted(); + return; + } + + AuthenticationProvider authenticationProviderToDelete = AuthenticationProvider + .createAuthenticationProviderFromProto(request.getAuthenticationProvider()); + profile.removeAuthenticationProvider(authenticationProviderToDelete); + + if (profile.getAuthenticationProviders().size() < MIN_NUMBER_OF_AUTH_PROVIDERS_IN_PROFILE) { + logger.error( + "Error deleting authentication provider {} from profile with id {}. Check the number of authentication providers.", + request.getAuthenticationProvider(), request.getProfileId()); + responseObserver.onNext(StatusResponse.newBuilder() + .setError(ErrorResponse.newBuilder().setCause(Cause.ERROR_DELETING_AUTH_PROVIDER)).build()); + responseObserver.onCompleted(); + return; + } + + boolean result = accountRepositoryAdditional.deleteAuthenticationProvider(profile, + authenticationProviderToDelete); + + if (result) { + logger.info("Authentication provider {}:{} successfuly deleted from profile id {}.", + request.getAuthenticationProvider().getAuthenticationType().name(), + request.getAuthenticationProvider().getAuthenticationProvider(), request.getProfileId()); + responseObserver.onNext(StatusResponse.newBuilder().setStatus("SUCCESS").build()); + responseObserver.onCompleted(); + return; + } + logger.error("Authentication provider {}:{} was not successfuly deleted from profile id {}.", + request.getAuthenticationProvider().getAuthenticationType().name(), + request.getAuthenticationProvider().getAuthenticationProvider(), request.getProfileId()); + responseObserver.onNext(StatusResponse.newBuilder() + .setError(ErrorResponse.newBuilder().setCause(Cause.INTERNAL_SERVER_ERROR)).build()); + responseObserver.onCompleted(); + return; + } } \ No newline at end of file diff --git a/src/test/java/biz/nynja/account/components/AccountServiceHelperTests.java b/src/test/java/biz/nynja/account/components/AccountServiceHelperTests.java new file mode 100644 index 0000000000000000000000000000000000000000..fcfcb5dd1d79159c8b95e4f0fbc651efb23ad8b8 --- /dev/null +++ b/src/test/java/biz/nynja/account/components/AccountServiceHelperTests.java @@ -0,0 +1,87 @@ +package biz.nynja.account.components; + +import static org.junit.Assert.*; +import static org.mockito.BDDMockito.given; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import biz.nynja.account.components.AccountServiceHelper; +import biz.nynja.account.configurations.CassandraTestsConfig; +import biz.nynja.account.models.Account; +import biz.nynja.account.models.AccountByAuthenticationProvider; +import biz.nynja.account.repositories.AccountByAuthenticationProviderRepository; +import biz.nynja.account.utils.Util; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = { Util.class, CassandraTestsConfig.class }, + webEnvironment = WebEnvironment.RANDOM_PORT, + properties = { + "spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration", + "spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration" }) +@ActiveProfiles("dev") +public class AccountServiceHelperTests { + @MockBean + private AccountByAuthenticationProviderRepository accountByAuthenticationProviderRepository; + + @Autowired + private AccountServiceHelper helper; + + @Autowired + @Qualifier("accountByPhone") + private AccountByAuthenticationProvider accountByPhone; + + @Autowired + @Qualifier("accountByEmail") + private AccountByAuthenticationProvider accountByEmail; + + @Autowired + @Qualifier("accountByFacebook") + private AccountByAuthenticationProvider accountByFacebook; + + @Test + public void testGetAccountByAuthenticationProviderHelperMultipleRecords() { + List accList = new ArrayList<>(); + accList.add(accountByEmail); + accList.add(accountByFacebook); + given(accountByAuthenticationProviderRepository.findAllByAuthenticationProvider(Util.EMAIL)) + .willReturn(accList); + + Account account = helper.getAccountByAuthenticationProviderHelper(Util.EMAIL, "EMAIL"); + assertEquals(Util.EMAIL, account.getAuthenticationProvider()); + } + + @Test + public void testGetAccountByAuthProviderPhoneByPhoneOK() { + List accList = new ArrayList<>(); + accList.add(accountByPhone); + given(accountByAuthenticationProviderRepository.findAllByAuthenticationProvider(Util.PHONE_NUMBER)) + .willReturn(accList); + + Account account = helper.getAccountByAuthenticationProviderHelper(Util.PHONE_NUMBER, "PHONE"); + assertEquals(Util.PHONE_NUMBER, account.getAuthenticationProvider()); + } + + @Test + public void testGetAccountByAuthenticationProviderHelperAccountNotFound() { + List accList = new ArrayList<>(); + accList.add(accountByFacebook); + accList.add(accountByPhone); + given(accountByAuthenticationProviderRepository.findAllByAuthenticationProvider(Util.EMAIL)) + .willReturn(new ArrayList()); + + Account account = helper.getAccountByAuthenticationProviderHelper(Util.EMAIL, "EMAIL"); + assertNull(account); + } + +} diff --git a/src/test/java/biz/nynja/account/services/AccountServiceTests.java b/src/test/java/biz/nynja/account/services/AccountServiceTests.java index 1038ebf2653efbed5b298f5605ec739beace6876..60eab8d4c0237c338ef21d3b0a9fda36d032f85a 100644 --- a/src/test/java/biz/nynja/account/services/AccountServiceTests.java +++ b/src/test/java/biz/nynja/account/services/AccountServiceTests.java @@ -9,8 +9,10 @@ import static org.junit.Assert.assertTrue; import static org.mockito.BDDMockito.given; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -25,6 +27,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; +import biz.nynja.account.components.AccountServiceHelper; import biz.nynja.account.configurations.CassandraTestsConfig; import biz.nynja.account.grpc.AccountByAuthenticationProviderRequest; @@ -41,6 +44,7 @@ import biz.nynja.account.grpc.CreatePendingAccountRequest; import biz.nynja.account.grpc.CreatePendingAccountResponse; import biz.nynja.account.grpc.DeleteAccountRequest; import biz.nynja.account.grpc.DeleteProfileRequest; +import biz.nynja.account.grpc.DeleteAuthenticationProviderRequest; import biz.nynja.account.grpc.ErrorResponse.Cause; import biz.nynja.account.grpc.StatusResponse; import biz.nynja.account.grpc.UpdateAccountRequest; @@ -158,6 +162,8 @@ public class AccountServiceTests extends GrpcServerTestBase { @MockBean private ProfileByAuthenticationProviderRepository profileByAutheticationProviderRepository; + @MockBean + private AccountServiceHelper util; @Test public void testGetAccountByAccountId() throws ExecutionException, InterruptedException { @@ -269,12 +275,15 @@ public class AccountServiceTests extends GrpcServerTestBase { @Test public void testGetAccountByAuthProviderPhone() { final AccountByAuthenticationProviderRequest request = AccountByAuthenticationProviderRequest.newBuilder() - .setAuthenticationIdentifier(Util.PHONE_NUMBER).setAuthenticationType(AuthenticationType.PHONE).build(); + .setAuthenticationIdentifier(Util.PHONE_PROVIDER).setAuthenticationType(AuthenticationType.PHONE) + .build(); List accList = new ArrayList<>(); accList.add(accountByPhone); - given(accountByAuthenticationProviderRepository.findAllByAuthenticationProvider(Util.PHONE_NUMBER)) + + given(accountByAuthenticationProviderRepository.findAllByAuthenticationProvider(Util.PHONE_PROVIDER)) .willReturn(accList); + given(util.getAccountByAuthenticationProviderHelper(Util.PHONE_PROVIDER, "PHONE")).willReturn(phoneAccount); final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); @@ -283,34 +292,11 @@ public class AccountServiceTests extends GrpcServerTestBase { assertTrue( String.format("Reply should contain authentication provider '%s'", request.getAuthenticationIdentifier()), - reply.getAccountDetails().getAuthenticationIdentifier().equals(Util.PHONE_NUMBER)); + reply.getAccountDetails().getAuthenticationIdentifier().equals(Util.PHONE_PROVIDER)); assertTrue(String.format("Reply should contain authentication type '%s'", AuthenticationType.PHONE.name()), reply.getAccountDetails().getAuthenticationType().equals(AuthenticationType.PHONE.name())); } - @Test - public void testGetAccountByAuthProviderMultipleRecords() { - final AccountByAuthenticationProviderRequest request = AccountByAuthenticationProviderRequest.newBuilder() - .setAuthenticationIdentifier(Util.EMAIL).setAuthenticationType(AuthenticationType.EMAIL).build(); - - List accList = new ArrayList<>(); - accList.add(accountByEmail); - accList.add(accountByFacebook); - given(accountByAuthenticationProviderRepository.findAllByAuthenticationProvider(Util.EMAIL)) - .willReturn(accList); - - final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc - .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); - final AccountResponse reply = accountServiceBlockingStub.getAccountByAuthenticationProvider(request); - assertNotNull("Reply should not be null", reply); - assertTrue( - String.format("Reply should contain authentication provider '%s'", - request.getAuthenticationIdentifier()), - reply.getAccountDetails().getAuthenticationIdentifier().equals(Util.EMAIL)); - assertTrue(String.format("Reply should contain authentication type '%s'", AuthenticationType.EMAIL.name()), - reply.getAccountDetails().getAuthenticationType().equals(AuthenticationType.EMAIL.name())); - } - @Test public void testGetAccountByAuthProviderMissingType() { final AccountByAuthenticationProviderRequest request = AccountByAuthenticationProviderRequest.newBuilder() @@ -420,10 +406,10 @@ public class AccountServiceTests extends GrpcServerTestBase { public void testCreatePendingAccountAuthProviderAlreadyUsedInPendingAccount() { final CreatePendingAccountRequest request = CreatePendingAccountRequest.newBuilder() .setAuthenticationType(AuthenticationType.EMAIL).setAuthenticationProvider(Util.EMAIL).build(); - given(accountRepositoryAdditional - .findSameAuthenticationProviderInPendingAccount( - AuthenticationProvider.createAuthenticationProviderFromStrings( - request.getAuthenticationType().name(), request.getAuthenticationProvider()))).willReturn(existingPendingAccountByAuthenticationProvider); + given(accountRepositoryAdditional.findSameAuthenticationProviderInPendingAccount( + AuthenticationProvider.createAuthenticationProviderFromStrings(request.getAuthenticationType().name(), + request.getAuthenticationProvider()))) + .willReturn(existingPendingAccountByAuthenticationProvider); given(pendingAccountRepository.save(Mockito.any(PendingAccount.class))).willReturn(existingPendingAccount); final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); @@ -437,10 +423,9 @@ public class AccountServiceTests extends GrpcServerTestBase { public void testCreatePendingAccountAuthProviderAlreadyUsedInAccount() { final CreatePendingAccountRequest request = CreatePendingAccountRequest.newBuilder() .setAuthenticationType(AuthenticationType.EMAIL).setAuthenticationProvider(Util.EMAIL).build(); - given(accountRepositoryAdditional - .authenticationProviderAlreadyUsedInAccount( - AuthenticationProvider.createAuthenticationProviderFromStrings( - request.getAuthenticationType().name(), request.getAuthenticationProvider()))).willReturn(true); + given(accountRepositoryAdditional.authenticationProviderAlreadyUsedInAccount( + AuthenticationProvider.createAuthenticationProviderFromStrings(request.getAuthenticationType().name(), + request.getAuthenticationProvider()))).willReturn(true); final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); final CreatePendingAccountResponse reply = accountServiceBlockingStub.createPendingAccount(request); @@ -452,9 +437,9 @@ public class AccountServiceTests extends GrpcServerTestBase { @Test public void testUpdateProfileAddBackupAuthProvider() throws ExecutionException, InterruptedException { final UpdateProfileRequest request = UpdateProfileRequest.newBuilder().setProfileId(Util.PROFILE_ID.toString()) - .addAuthProviders(AuthProviderDetails.newBuilder().setAuthenticationProvider(Util.PHONE_NUMBER) + .addAuthProviders(AuthProviderDetails.newBuilder().setAuthenticationProvider(Util.PHONE_PROVIDER) .setAuthenticationType(AuthenticationType.PHONE).build()) - .setBackupAuthProvider(AuthProviderDetails.newBuilder().setAuthenticationProvider(Util.PHONE_NUMBER) + .setBackupAuthProvider(AuthProviderDetails.newBuilder().setAuthenticationProvider(Util.PHONE_PROVIDER) .setAuthenticationType(AuthenticationType.PHONE).build()) .build(); given(accountRepositoryAdditional.updateProfile(request)).willReturn(updatedProfile); @@ -890,4 +875,78 @@ public class AccountServiceTests extends GrpcServerTestBase { reply.getError().getCause().equals(Cause.PROFILE_NOT_FOUND)); } + @Test + public void testDeleteAuthenticationProviderFromProfileOK() { + final DeleteAuthenticationProviderRequest request = DeleteAuthenticationProviderRequest.newBuilder() + .setProfileId(Util.PROFILE_ID.toString()) + .setAuthenticationProvider(AuthProviderDetails.newBuilder() + .setAuthenticationProvider(Util.PHONE_PROVIDER).setAuthenticationType(AuthenticationType.PHONE)) + .build(); + + given(accountRepositoryAdditional.deleteAuthenticationProvider(Mockito.any(Profile.class), + Mockito.any(AuthenticationProvider.class))).willReturn(true); + + given(profileRepository.findByProfileId(Util.PROFILE_ID)).willReturn(profile2AuthProviders); + + final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc + .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); + + final StatusResponse reply = accountServiceBlockingStub.deleteAuthenticationProviderFromProfile(request); + assertNotNull("Reply should not be null", reply); + assertEquals("SUCCESS", reply.getStatus()); + + } + + @Test + public void testDeleteAuthenticationProviderFromProfileMissingProfileId() { + final DeleteAuthenticationProviderRequest request = DeleteAuthenticationProviderRequest.newBuilder() + .setAuthenticationProvider(AuthProviderDetails.newBuilder() + .setAuthenticationProvider(Util.PHONE_PROVIDER).setAuthenticationType(AuthenticationType.PHONE)) + .build(); + + final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc + .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); + + final StatusResponse reply = accountServiceBlockingStub.deleteAuthenticationProviderFromProfile(request); + assertNotNull("Reply should not be null", reply); + assertTrue(String.format("Reply should contain cause '%s'", Cause.MISSING_PROFILE_ID), + reply.getError().getCause().equals(Cause.MISSING_PROFILE_ID)); + } + + @Test + public void testDeleteAuthenticationProviderFromProfileProfileNotFound() { + final DeleteAuthenticationProviderRequest request = DeleteAuthenticationProviderRequest.newBuilder() + .setProfileId(Util.PROFILE_ID.toString()) + .setAuthenticationProvider(AuthProviderDetails.newBuilder() + .setAuthenticationProvider(Util.PHONE_PROVIDER).setAuthenticationType(AuthenticationType.PHONE)) + .build(); + given(profileRepository.findByProfileId(Util.PROFILE_ID)).willReturn(null); + + final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc + .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); + + final StatusResponse reply = accountServiceBlockingStub.deleteAuthenticationProviderFromProfile(request); + assertNotNull("Reply should not be null", reply); + assertTrue(String.format("Reply should contain cause '%s'", Cause.PROFILE_NOT_FOUND), + reply.getError().getCause().equals(Cause.PROFILE_NOT_FOUND)); + } + + @Test + public void testDeleteAuthenticationProviderFromProfileMinNumberOfAuthProviders() { + final DeleteAuthenticationProviderRequest request = DeleteAuthenticationProviderRequest.newBuilder() + .setProfileId(Util.PROFILE_ID.toString()) + .setAuthenticationProvider(AuthProviderDetails.newBuilder() + .setAuthenticationProvider(Util.PHONE_PROVIDER).setAuthenticationType(AuthenticationType.PHONE)) + .build(); + + given(profileRepository.findByProfileId(Util.PROFILE_ID)).willReturn(profile1AuthProvider); + + final AccountServiceGrpc.AccountServiceBlockingStub accountServiceBlockingStub = AccountServiceGrpc + .newBlockingStub(Optional.ofNullable(channel).orElse(inProcChannel)); + + final StatusResponse reply = accountServiceBlockingStub.deleteAuthenticationProviderFromProfile(request); + assertTrue(String.format("Reply should contain cause '%s'", Cause.ERROR_DELETING_AUTH_PROVIDER), + reply.getError().getCause().equals(Cause.ERROR_DELETING_AUTH_PROVIDER)); + } + } diff --git a/src/test/java/biz/nynja/account/utils/Util.java b/src/test/java/biz/nynja/account/utils/Util.java index 64557c1b06333a0e9aa7b7759734f5ee03c54cf8..90086fa491eddabd6a24549d313ee2ae88f0f952 100644 --- a/src/test/java/biz/nynja/account/utils/Util.java +++ b/src/test/java/biz/nynja/account/utils/Util.java @@ -51,8 +51,8 @@ public class Util { public static final String FIRST_NAME = "John"; public static final String LAST_NAME = "Doe"; public static final String MIDDLE_NAME = "Kass"; - public static final String PHONE_NUMBER = "+359887434646"; - public static final String PHONE_PROVIDER = "BG:+359887434646"; + public static final String PHONE_NUMBER = "+359887123456"; + public static final String PHONE_PROVIDER = "BG:+359887123456"; public static final String PHONE_TYPE = "PHONE"; public static final String EMAIL_TYPE = "EMAIL"; public static final String FACBOOK_TYPE = "FACEBOOK"; @@ -177,7 +177,8 @@ public class Util { Set authProviders = new HashSet(); authProviders.add(AuthenticationProvider.createAuthenticationProviderFromStrings(PHONE_TYPE, PHONE_NUMBER)); profile.setAuthenticationProviders(authProviders); - profile.setBackupAuthenticationProvider(AuthenticationProvider.createAuthenticationProviderFromStrings(PHONE_TYPE, PHONE_NUMBER)); + profile.setBackupAuthenticationProvider( + AuthenticationProvider.createAuthenticationProviderFromStrings(PHONE_TYPE, PHONE_NUMBER)); return profile; }