From f16ffe4788dd48ca457281a776dc24aed7afc440 Mon Sep 17 00:00:00 2001 From: Precious OSSAI Date: Wed, 5 Jun 2024 12:47:20 +0100 Subject: [PATCH] refactor: mock dispatcher --- .../repository/TokenRepositoryImpl.kt | 7 +- .../repository/TokenRepositoryImplTest.kt | 648 +++++++++--------- 2 files changed, 319 insertions(+), 336 deletions(-) diff --git a/checkout/src/main/java/com/checkout/tokenization/repository/TokenRepositoryImpl.kt b/checkout/src/main/java/com/checkout/tokenization/repository/TokenRepositoryImpl.kt index 3a2f8113..6f7f4f2e 100644 --- a/checkout/src/main/java/com/checkout/tokenization/repository/TokenRepositoryImpl.kt +++ b/checkout/src/main/java/com/checkout/tokenization/repository/TokenRepositoryImpl.kt @@ -57,6 +57,9 @@ internal class TokenRepositoryImpl( NonCancellable, ) + @VisibleForTesting + var dispatcher = Dispatchers.IO + @Suppress("TooGenericExceptionCaught") override fun sendCardTokenRequest(cardTokenRequest: CardTokenRequest) { var response: NetworkApiResponse @@ -130,7 +133,7 @@ internal class TokenRepositoryImpl( when (tokenResult) { is TokenResult.Success -> { try { - withContext(Dispatchers.IO) { + withContext(dispatcher) { riskSdkUseCase.execute(TokenResult.Success(tokenResult.result.token)) } } catch (exception: Exception) { @@ -211,7 +214,7 @@ internal class TokenRepositoryImpl( ) { when (tokenResult) { is TokenResult.Success -> try { - withContext(Dispatchers.IO) { + withContext(dispatcher) { riskSdkUseCase.execute(TokenResult.Success(tokenResult.result.token)) } } catch (exception: Exception) { diff --git a/checkout/src/test/java/com/checkout/tokenization/repository/TokenRepositoryImplTest.kt b/checkout/src/test/java/com/checkout/tokenization/repository/TokenRepositoryImplTest.kt index 4c17076e..5ed255d5 100644 --- a/checkout/src/test/java/com/checkout/tokenization/repository/TokenRepositoryImplTest.kt +++ b/checkout/src/test/java/com/checkout/tokenization/repository/TokenRepositoryImplTest.kt @@ -51,36 +51,39 @@ import org.junit.jupiter.api.extension.ExtendWith @ExtendWith(MockKExtension::class) @OptIn(ExperimentalCoroutinesApi::class) internal class TokenRepositoryImplTest { - @RelaxedMockK private lateinit var mockTokenNetworkApiClient: TokenNetworkApiClient + @RelaxedMockK + private lateinit var mockTokenNetworkApiClient: TokenNetworkApiClient @RelaxedMockK private lateinit var mockValidateTokenizationDataUseCase: UseCase> - @RelaxedMockK private lateinit var mockRiskSdkUseCase: RiskSdkUseCase + @RelaxedMockK + private lateinit var mockRiskSdkUseCase: RiskSdkUseCase @RelaxedMockK private lateinit var mockValidateCVVTokenizationDataUseCase: - UseCase> + UseCase> - @RelaxedMockK private lateinit var mockTokenizationLogger: TokenizationLogger + @RelaxedMockK + private lateinit var mockTokenizationLogger: TokenizationLogger private lateinit var tokenRepositoryImpl: TokenRepositoryImpl @BeforeEach fun setUp() { tokenRepositoryImpl = - TokenRepositoryImpl( - networkApiClient = mockTokenNetworkApiClient, - cardToTokenRequestMapper = CardToTokenRequestMapper(), - cvvToTokenNetworkRequestMapper = CVVToTokenNetworkRequestMapper(), - cardTokenizationNetworkDataMapper = CardTokenizationNetworkDataMapper(), - validateTokenizationDataUseCase = mockValidateTokenizationDataUseCase, - validateCVVTokenizationDataUseCase = mockValidateCVVTokenizationDataUseCase, - logger = mockTokenizationLogger, - publicKey = "test_key", - cvvTokenizationNetworkDataMapper = CVVTokenizationNetworkDataMapper(), - riskSdkUseCase = mockRiskSdkUseCase, - ) + TokenRepositoryImpl( + networkApiClient = mockTokenNetworkApiClient, + cardToTokenRequestMapper = CardToTokenRequestMapper(), + cvvToTokenNetworkRequestMapper = CVVToTokenNetworkRequestMapper(), + cardTokenizationNetworkDataMapper = CardTokenizationNetworkDataMapper(), + validateTokenizationDataUseCase = mockValidateTokenizationDataUseCase, + validateCVVTokenizationDataUseCase = mockValidateCVVTokenizationDataUseCase, + logger = mockTokenizationLogger, + publicKey = "test_key", + cvvTokenizationNetworkDataMapper = CVVTokenizationNetworkDataMapper(), + riskSdkUseCase = mockRiskSdkUseCase, + ) } @DisplayName("CardToken Details invocation") @@ -89,38 +92,38 @@ internal class TokenRepositoryImplTest { @Test fun `when sendCardTokenRequest invoked with success response then success handler invoked`() { testCardTokenResultInvocation( - true, - NetworkApiResponse.Success(TokenizationRequestTestData.tokenDetailsResponse()), + true, + NetworkApiResponse.Success(TokenizationRequestTestData.tokenDetailsResponse()), ) } @Test fun `when sendCardTokenRequest invoked with network error response then failure handler invoked`() { testCardTokenResultInvocation( - false, - NetworkApiResponse.NetworkError(NullPointerException()), + false, + NetworkApiResponse.NetworkError(NullPointerException()), ) } @Test fun `when sendCardTokenRequest invoked with server error response then failure handler invoked`() { testCardTokenResultInvocation( - false, - NetworkApiResponse.ServerError(null, 123), + false, + NetworkApiResponse.ServerError(null, 123), ) } @Test fun `when sendCardTokenRequest invoked with internal error response then failure handler invoked`() { testCardTokenResultInvocation( - false, - NetworkApiResponse.InternalError( - TokenizationError( - "dummy code", - "exception.message", - null, - ), + false, + NetworkApiResponse.InternalError( + TokenizationError( + "dummy code", + "exception.message", + null, ), + ), ) } @@ -136,45 +139,45 @@ internal class TokenRepositoryImplTest { @Test fun `when sendCardTokenRequest invoked then send card token request with correct data is invoked`() = - runTest { - // Given - val response = mockk>() - - val testDispatcher = UnconfinedTestDispatcher(testScheduler) - Dispatchers.setMain(testDispatcher) - - tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) - - every { mockValidateTokenizationDataUseCase.execute(any()) } returns - ValidationResult.Success(Unit) - coEvery { mockTokenNetworkApiClient.sendCardTokenRequest(any()) } returns - response - - // When - tokenRepositoryImpl.sendCardTokenRequest( - CardTokenRequest( - TokenizationRequestTestData.card, - onSuccess = {}, - onFailure = {}, - ), - ) + runTest { + // Given + val response = mockk>() + + val testDispatcher = UnconfinedTestDispatcher(testScheduler) + Dispatchers.setMain(testDispatcher) + + tokenRepositoryImpl.networkCoroutineScope = + CoroutineScope(StandardTestDispatcher(testScheduler)) - // Then - launch { - verify(exactly = 1) { - mockTokenizationLogger.logTokenRequestEvent( - TokenizationConstants.CARD, - "test_key", - ) - } + every { mockValidateTokenizationDataUseCase.execute(any()) } returns + ValidationResult.Success(Unit) + coEvery { mockTokenNetworkApiClient.sendCardTokenRequest(any()) } returns + response + + // When + tokenRepositoryImpl.sendCardTokenRequest( + CardTokenRequest( + TokenizationRequestTestData.card, + onSuccess = {}, + onFailure = {}, + ), + ) + + // Then + launch { + verify(exactly = 1) { + mockTokenizationLogger.logTokenRequestEvent( + TokenizationConstants.CARD, + "test_key", + ) } } + } } private fun testCardTokenResultInvocation( - successHandlerInvoked: Boolean, - response: NetworkApiResponse, + successHandlerInvoked: Boolean, + response: NetworkApiResponse, ) = runTest { // Given var isSuccess = false @@ -183,10 +186,10 @@ internal class TokenRepositoryImplTest { Dispatchers.setMain(testDispatcher) tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + CoroutineScope(StandardTestDispatcher(testScheduler)) coEvery { mockValidateTokenizationDataUseCase.execute(any()) } returns - ValidationResult.Success(Unit) + ValidationResult.Success(Unit) coEvery { mockTokenNetworkApiClient.sendCardTokenRequest(any()) } returns response @@ -194,11 +197,11 @@ internal class TokenRepositoryImplTest { // When tokenRepositoryImpl.sendCardTokenRequest( - CardTokenRequest( - TokenizationRequestTestData.card, - onSuccess = { isSuccess = true }, - onFailure = { isSuccess = false }, - ), + CardTokenRequest( + TokenizationRequestTestData.card, + onSuccess = { isSuccess = true }, + onFailure = { isSuccess = false }, + ), ) advanceUntilIdle() // Then @@ -217,29 +220,29 @@ internal class TokenRepositoryImplTest { val serverErrorBody = mockk() val response = - if (isSuccessResponse) { - NetworkApiResponse.Success(successBody) - } else { - NetworkApiResponse.ServerError(serverErrorBody, 501) - } + if (isSuccessResponse) { + NetworkApiResponse.Success(successBody) + } else { + NetworkApiResponse.ServerError(serverErrorBody, 501) + } val testDispatcher = UnconfinedTestDispatcher(testScheduler) Dispatchers.setMain(testDispatcher) tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + CoroutineScope(StandardTestDispatcher(testScheduler)) every { mockValidateTokenizationDataUseCase.execute(any()) } returns - ValidationResult.Success(Unit) + ValidationResult.Success(Unit) coEvery { mockTokenNetworkApiClient.sendCardTokenRequest(any()) } returns response // When tokenRepositoryImpl.sendCardTokenRequest( - CardTokenRequest( - TokenizationRequestTestData.card, - onSuccess = {}, - onFailure = {}, - ), + CardTokenRequest( + TokenizationRequestTestData.card, + onSuccess = {}, + onFailure = {}, + ), ) // Then @@ -247,20 +250,20 @@ internal class TokenRepositoryImplTest { if (isSuccessResponse) { verify(exactly = 1) { mockTokenizationLogger.logTokenResponseEvent( - eq(TokenizationConstants.CARD), - eq("test_key"), - eq(successBody), + eq(TokenizationConstants.CARD), + eq("test_key"), + eq(successBody), ) } } else { verify(exactly = 1) { mockTokenizationLogger.logTokenResponseEvent( - tokenType = eq(TokenizationConstants.CARD), - publicKey = eq("test_key"), - tokenDetails = null, - cvvTokenDetailsResponse = null, - code = 501, - errorResponse = serverErrorBody, + tokenType = eq(TokenizationConstants.CARD), + publicKey = eq("test_key"), + tokenDetails = null, + cvvTokenDetailsResponse = null, + code = 501, + errorResponse = serverErrorBody, ) } } @@ -273,79 +276,53 @@ internal class TokenRepositoryImplTest { @Nested inner class GetGooglePayTokenNetworkRequestDetails { @Test - fun `when sendGooglePayTokenRequest invoked with success response then success handler invoked`() = - runTest { - // Given - val response = - NetworkApiResponse.Success( - TokenizationRequestTestData.tokenDetailsResponse() - ) - var isSuccess = false - - val testDispatcher = UnconfinedTestDispatcher(testScheduler) - Dispatchers.setMain(testDispatcher) - - tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) - - coEvery { mockTokenNetworkApiClient.sendGooglePayTokenRequest(any()) } returns - response - coEvery { mockRiskSdkUseCase.execute(any()) } returns Unit - - // When - tokenRepositoryImpl.sendGooglePayTokenRequest( - GooglePayTokenRequest( - "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", - onSuccess = { isSuccess = true }, - onFailure = { isSuccess = false }, - ), - ) - advanceUntilIdle() - - // Then - launch { assertEquals(isSuccess, true) } - } + fun `when sendGooglePayTokenRequest invoked with success response then success handler invoked`() { + testGooglePayTokenResultInvocation( + true, + NetworkApiResponse.Success(TokenizationRequestTestData.tokenDetailsResponse()), + ) + } @Test fun `when sendGooglePayTokenRequest invoked with network error response then failure handler invoked`() { testGooglePayTokenResultInvocation( - false, - NetworkApiResponse.NetworkError(Exception("Network connection lost")), + false, + NetworkApiResponse.NetworkError(Exception("Network connection lost")), ) } @Test fun `when sendGooglePayTokenRequest invoked with server error response then failure handler invoked`() { testGooglePayTokenResultInvocation( - false, - NetworkApiResponse.ServerError(null, 123), + false, + NetworkApiResponse.ServerError(null, 123), ) } @Test fun `when sendGooglePayTokenRequest invoked with internal error response then failure handler invoked`() { testGooglePayTokenResultInvocation( - false, - NetworkApiResponse.InternalError( - TokenizationError( - TokenizationError.GOOGLE_PAY_REQUEST_PARSING_ERROR, - "exception.message", - null, - ), + false, + NetworkApiResponse.InternalError( + TokenizationError( + TokenizationError.GOOGLE_PAY_REQUEST_PARSING_ERROR, + "exception.message", + null, ), + ), ) } @Test fun `when sendGooglePayTokenRequest error invoked with invalid jsonPayLoad request then throw custom TokenizationError`() { testGooglePayErrorHandlerInvocation( - NetworkApiResponse.InternalError( - TokenizationError( - TokenizationError.GOOGLE_PAY_REQUEST_PARSING_ERROR, - "JSONObject[\"protocolVersion\"] not found.", - null, - ), + NetworkApiResponse.InternalError( + TokenizationError( + TokenizationError.GOOGLE_PAY_REQUEST_PARSING_ERROR, + "JSONObject[\"protocolVersion\"] not found.", + null, ), + ), ) } @@ -361,96 +338,96 @@ internal class TokenRepositoryImplTest { @Test fun `when sendGooglePayTokenRequest invoked internalError then log tokenResponseEvent along with resetSession`() = - runTest { - // Given - val expectedInternalErrorBody = - TokenizationError( - TokenizationError.GOOGLE_PAY_REQUEST_PARSING_ERROR, - "testMessage", - java.lang.NullPointerException(), - ) - val captureError = mutableListOf() - - val testDispatcher = UnconfinedTestDispatcher(testScheduler) - Dispatchers.setMain(testDispatcher) - - tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) - - coEvery { mockTokenNetworkApiClient.sendGooglePayTokenRequest(any()) } throws - (expectedInternalErrorBody) - - // When - tokenRepositoryImpl.sendGooglePayTokenRequest( - GooglePayTokenRequest( - "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", - onSuccess = {}, - onFailure = {}, - ), + runTest { + // Given + val expectedInternalErrorBody = + TokenizationError( + TokenizationError.GOOGLE_PAY_REQUEST_PARSING_ERROR, + "testMessage", + java.lang.NullPointerException(), ) + val captureError = mutableListOf() - // Then - launch { - verify(exactly = 1) { - mockTokenizationLogger.logErrorOnTokenRequestedEvent( - any(), - any(), - captureNullable(captureError), - ) - } - assertEquals( - expectedInternalErrorBody.errorCode, - (captureError.firstOrNull() as? TokenizationError)?.errorCode, - ) - assertEquals( - expectedInternalErrorBody.message, - (captureError.firstOrNull() as? TokenizationError)?.message, - ) - assertEquals( - expectedInternalErrorBody.cause, - (captureError.firstOrNull() as? TokenizationError)?.cause, + val testDispatcher = UnconfinedTestDispatcher(testScheduler) + Dispatchers.setMain(testDispatcher) + + tokenRepositoryImpl.networkCoroutineScope = + CoroutineScope(StandardTestDispatcher(testScheduler)) + + coEvery { mockTokenNetworkApiClient.sendGooglePayTokenRequest(any()) } throws + (expectedInternalErrorBody) + + // When + tokenRepositoryImpl.sendGooglePayTokenRequest( + GooglePayTokenRequest( + "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", + onSuccess = {}, + onFailure = {}, + ), + ) + + // Then + launch { + verify(exactly = 1) { + mockTokenizationLogger.logErrorOnTokenRequestedEvent( + any(), + any(), + captureNullable(captureError), ) } + assertEquals( + expectedInternalErrorBody.errorCode, + (captureError.firstOrNull() as? TokenizationError)?.errorCode, + ) + assertEquals( + expectedInternalErrorBody.message, + (captureError.firstOrNull() as? TokenizationError)?.message, + ) + assertEquals( + expectedInternalErrorBody.cause, + (captureError.firstOrNull() as? TokenizationError)?.cause, + ) } + } @Test fun `when sendGooglePayTokenRequest invoked then send google pay token request with correct data is invoked`() = - runTest { - // Given - val response = mockk>() - - val testDispatcher = UnconfinedTestDispatcher(testScheduler) - Dispatchers.setMain(testDispatcher) - - tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) - - coEvery { mockTokenNetworkApiClient.sendCardTokenRequest(any()) } returns - response - - // When - tokenRepositoryImpl.sendGooglePayTokenRequest( - GooglePayTokenRequest( - "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", - onSuccess = {}, - onFailure = {}, - ), - ) + runTest { + // Given + val response = mockk>() + + val testDispatcher = UnconfinedTestDispatcher(testScheduler) + Dispatchers.setMain(testDispatcher) + + tokenRepositoryImpl.networkCoroutineScope = + CoroutineScope(StandardTestDispatcher(testScheduler)) + + coEvery { mockTokenNetworkApiClient.sendCardTokenRequest(any()) } returns + response - // Then - launch { - verify(exactly = 1) { - mockTokenizationLogger.logTokenRequestEvent( - TokenizationConstants.GOOGLE_PAY, - "test_key" - ) - } + // When + tokenRepositoryImpl.sendGooglePayTokenRequest( + GooglePayTokenRequest( + "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", + onSuccess = {}, + onFailure = {}, + ), + ) + + // Then + launch { + verify(exactly = 1) { + mockTokenizationLogger.logTokenRequestEvent( + TokenizationConstants.GOOGLE_PAY, + "test_key", + ) } } + } private fun testGooglePayTokenResultInvocation( - successHandlerInvoked: Boolean, - response: NetworkApiResponse, + successHandlerInvoked: Boolean, + response: NetworkApiResponse, ) = runTest { // Given var isSuccess: Boolean? = null @@ -459,18 +436,19 @@ internal class TokenRepositoryImplTest { Dispatchers.setMain(testDispatcher) tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + CoroutineScope(StandardTestDispatcher(testScheduler)) + tokenRepositoryImpl.dispatcher = testDispatcher coEvery { mockTokenNetworkApiClient.sendGooglePayTokenRequest(any()) } returns response coEvery { mockRiskSdkUseCase.execute(any()) } returns Unit // When tokenRepositoryImpl.sendGooglePayTokenRequest( - GooglePayTokenRequest( - "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", - onSuccess = { isSuccess = true }, - onFailure = { isSuccess = false }, - ), + GooglePayTokenRequest( + "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", + onSuccess = { isSuccess = true }, + onFailure = { isSuccess = false }, + ), ) advanceUntilIdle() // Then @@ -478,7 +456,7 @@ internal class TokenRepositoryImplTest { } private fun testGooglePayErrorHandlerInvocation( - response: NetworkApiResponse + response: NetworkApiResponse, ) = runTest { // Given var isSuccess: Boolean? = null @@ -489,28 +467,28 @@ internal class TokenRepositoryImplTest { Dispatchers.setMain(testDispatcher) tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + CoroutineScope(StandardTestDispatcher(testScheduler)) coEvery { mockTokenNetworkApiClient.sendGooglePayTokenRequest(any()) } returns response // When tokenRepositoryImpl.sendGooglePayTokenRequest( - GooglePayTokenRequest( - "{test: ECv1,signature: “testSignature”,signedMessage: testSignedMessage}", - onSuccess = { isSuccess = true }, - onFailure = { - isSuccess = false - errorMessage = it - }, - ), + GooglePayTokenRequest( + "{test: ECv1,signature: “testSignature”,signedMessage: testSignedMessage}", + onSuccess = { isSuccess = true }, + onFailure = { + isSuccess = false + errorMessage = it + }, + ), ) // Then launch { assertEquals(isSuccess.toString(), successHandlerInvoked.toString()) assertEquals( - errorMessage, - (response as? NetworkApiResponse.InternalError)?.throwable?.message ?: "_", + errorMessage, + (response as? NetworkApiResponse.InternalError)?.throwable?.message ?: "_", ) } } @@ -521,27 +499,27 @@ internal class TokenRepositoryImplTest { val serverErrorBody = mockk() val response = - if (isSuccessResponse) { - NetworkApiResponse.Success(successBody) - } else { - NetworkApiResponse.ServerError(serverErrorBody, 501) - } + if (isSuccessResponse) { + NetworkApiResponse.Success(successBody) + } else { + NetworkApiResponse.ServerError(serverErrorBody, 501) + } val testDispatcher = UnconfinedTestDispatcher(testScheduler) Dispatchers.setMain(testDispatcher) tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + CoroutineScope(StandardTestDispatcher(testScheduler)) coEvery { mockTokenNetworkApiClient.sendGooglePayTokenRequest(any()) } returns response // When tokenRepositoryImpl.sendGooglePayTokenRequest( - GooglePayTokenRequest( - "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", - onSuccess = {}, - onFailure = {}, - ), + GooglePayTokenRequest( + "{protocolVersion: ECv1,signature: “test”,signedMessage: testSignedMessage}", + onSuccess = {}, + onFailure = {}, + ), ) // Then @@ -549,20 +527,20 @@ internal class TokenRepositoryImplTest { if (isSuccessResponse) { verify(exactly = 1) { mockTokenizationLogger.logTokenResponseEvent( - eq(TokenizationConstants.GOOGLE_PAY), - eq("test_key"), - eq(successBody), + eq(TokenizationConstants.GOOGLE_PAY), + eq("test_key"), + eq(successBody), ) } } else { verify(exactly = 1) { mockTokenizationLogger.logTokenResponseEvent( - tokenType = eq(TokenizationConstants.GOOGLE_PAY), - publicKey = eq("test_key"), - tokenDetails = null, - cvvTokenDetailsResponse = null, - code = 501, - errorResponse = serverErrorBody, + tokenType = eq(TokenizationConstants.GOOGLE_PAY), + publicKey = eq("test_key"), + tokenDetails = null, + cvvTokenDetailsResponse = null, + code = 501, + errorResponse = serverErrorBody, ) } } @@ -577,48 +555,48 @@ internal class TokenRepositoryImplTest { @Test fun `when sendCVVTokenizationRequest invoked with success response then success handler invoked`() { testCVVTokenResultInvocation( - successHandlerInvoked = true, - response = - NetworkApiResponse.Success( - body = - CVVTokenDetailsResponse( - type = "cvv", - token = "test_token", - expiresOn = "2019-08-24T14:15:22Z", - ), - ), + successHandlerInvoked = true, + response = + NetworkApiResponse.Success( + body = + CVVTokenDetailsResponse( + type = "cvv", + token = "test_token", + expiresOn = "2019-08-24T14:15:22Z", + ), + ), ) } @Test fun `when sendCVVTokenizationRequest invoked with network error response then failure handler invoked`() { testCVVTokenResultInvocation( - successHandlerInvoked = false, - response = - NetworkApiResponse.NetworkError(Exception("Network connection lost")), + successHandlerInvoked = false, + response = + NetworkApiResponse.NetworkError(Exception("Network connection lost")), ) } @Test fun `when sendCVVTokenizationRequest invoked with server error response then failure handler invoked`() { testCVVTokenResultInvocation( - successHandlerInvoked = false, - response = NetworkApiResponse.ServerError(body = null, code = 123), + successHandlerInvoked = false, + response = NetworkApiResponse.ServerError(body = null, code = 123), ) } @Test fun `when sendCVVTokenizationRequest invoked with internal error response then failure handler invoked`() { testCVVTokenResultInvocation( - successHandlerInvoked = false, - response = - NetworkApiResponse.InternalError( - TokenizationError( - errorCode = "internal_error", - message = "exception.message", - cause = null, - ), - ), + successHandlerInvoked = false, + response = + NetworkApiResponse.InternalError( + TokenizationError( + errorCode = "internal_error", + message = "exception.message", + cause = null, + ), + ), ) } @@ -634,40 +612,40 @@ internal class TokenRepositoryImplTest { @Test fun `when sendCVVTokenizationRequest invoked then send cvv token request with correct data is invoked`() = - runTest { - // Given - val response = mockk>() + runTest { + // Given + val response = mockk>() - val testDispatcher = UnconfinedTestDispatcher(testScheduler) - Dispatchers.setMain(testDispatcher) + val testDispatcher = UnconfinedTestDispatcher(testScheduler) + Dispatchers.setMain(testDispatcher) - tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + tokenRepositoryImpl.networkCoroutineScope = + CoroutineScope(StandardTestDispatcher(testScheduler)) - every { mockValidateCVVTokenizationDataUseCase.execute(any()) } returns - ValidationResult.Success(Unit) - coEvery { mockTokenNetworkApiClient.sendCVVTokenRequest(any()) } returns - response + every { mockValidateCVVTokenizationDataUseCase.execute(any()) } returns + ValidationResult.Success(Unit) + coEvery { mockTokenNetworkApiClient.sendCVVTokenRequest(any()) } returns + response - // When - tokenRepositoryImpl.sendCVVTokenizationRequest( - cvvTokenizationRequest, - ) + // When + tokenRepositoryImpl.sendCVVTokenizationRequest( + cvvTokenizationRequest, + ) - // Then - launch { - verify(exactly = 1) { - mockTokenizationLogger.logTokenRequestEvent( - TokenizationConstants.CVV, - "test_key", - ) - } + // Then + launch { + verify(exactly = 1) { + mockTokenizationLogger.logTokenRequestEvent( + TokenizationConstants.CVV, + "test_key", + ) } } + } private fun testCVVTokenResultInvocation( - successHandlerInvoked: Boolean, - response: NetworkApiResponse, + successHandlerInvoked: Boolean, + response: NetworkApiResponse, ) = runTest { // Given var isSuccess: Boolean? = null @@ -676,27 +654,29 @@ internal class TokenRepositoryImplTest { Dispatchers.setMain(testDispatcher) tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + CoroutineScope(StandardTestDispatcher(testScheduler)) + + tokenRepositoryImpl.dispatcher = testDispatcher coEvery { mockValidateCVVTokenizationDataUseCase.execute(any()) } returns - ValidationResult.Success(Unit) + ValidationResult.Success(Unit) coEvery { mockTokenNetworkApiClient.sendCVVTokenRequest(any()) } returns response coEvery { mockRiskSdkUseCase.execute(any()) } returns Unit // When tokenRepositoryImpl.sendCVVTokenizationRequest( - CVVTokenizationRequest( - cvv = "123", - cardScheme = CardScheme.VISA, - resultHandler = { result -> - isSuccess = - when (result) { - is CVVTokenizationResultHandler.Success -> true - is CVVTokenizationResultHandler.Failure -> false - } - }, - ), + CVVTokenizationRequest( + cvv = "123", + cardScheme = CardScheme.VISA, + resultHandler = { result -> + isSuccess = + when (result) { + is CVVTokenizationResultHandler.Success -> true + is CVVTokenizationResultHandler.Failure -> false + } + }, + ), ) // Then @@ -709,25 +689,25 @@ internal class TokenRepositoryImplTest { val serverErrorBody = mockk() val response = - if (isSuccessResponse) { - NetworkApiResponse.Success(successBody) - } else { - NetworkApiResponse.ServerError(serverErrorBody, 501) - } + if (isSuccessResponse) { + NetworkApiResponse.Success(successBody) + } else { + NetworkApiResponse.ServerError(serverErrorBody, 501) + } val testDispatcher = UnconfinedTestDispatcher(testScheduler) Dispatchers.setMain(testDispatcher) tokenRepositoryImpl.networkCoroutineScope = - CoroutineScope(StandardTestDispatcher(testScheduler)) + CoroutineScope(StandardTestDispatcher(testScheduler)) every { mockValidateCVVTokenizationDataUseCase.execute(any()) } returns - ValidationResult.Success(Unit) + ValidationResult.Success(Unit) coEvery { mockTokenNetworkApiClient.sendCVVTokenRequest(any()) } returns response // When tokenRepositoryImpl.sendCVVTokenizationRequest( - cvvTokenizationRequest, + cvvTokenizationRequest, ) // Then @@ -735,21 +715,21 @@ internal class TokenRepositoryImplTest { if (isSuccessResponse) { verify(exactly = 1) { mockTokenizationLogger.logTokenResponseEvent( - tokenType = eq(TokenizationConstants.CVV), - publicKey = eq("test_key"), - tokenDetails = null, - cvvTokenDetailsResponse = eq(successBody), + tokenType = eq(TokenizationConstants.CVV), + publicKey = eq("test_key"), + tokenDetails = null, + cvvTokenDetailsResponse = eq(successBody), ) } } else { verify(exactly = 1) { mockTokenizationLogger.logTokenResponseEvent( - tokenType = eq(TokenizationConstants.CVV), - publicKey = eq("test_key"), - tokenDetails = null, - cvvTokenDetailsResponse = null, - code = 501, - errorResponse = serverErrorBody, + tokenType = eq(TokenizationConstants.CVV), + publicKey = eq("test_key"), + tokenDetails = null, + cvvTokenDetailsResponse = null, + code = 501, + errorResponse = serverErrorBody, ) } }