From d113e8b5eee4966b02e0498751cd9a8509dc0ada Mon Sep 17 00:00:00 2001 From: Ararat Mnatsakanyan Date: Wed, 20 Nov 2024 13:26:22 +0100 Subject: [PATCH] Track third party error event for Google Pay COAND-1009 --- .../internal/ui/DefaultGooglePayDelegate.kt | 16 +++++++++ .../ui/DefaultGooglePayDelegateTest.kt | 36 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegate.kt b/googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegate.kt index 9a80f18319..093fab3c6d 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegate.kt +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegate.kt @@ -19,6 +19,7 @@ import com.adyen.checkout.components.core.PaymentMethodTypes import com.adyen.checkout.components.core.internal.PaymentComponentEvent import com.adyen.checkout.components.core.internal.PaymentObserverRepository import com.adyen.checkout.components.core.internal.analytics.AnalyticsManager +import com.adyen.checkout.components.core.internal.analytics.ErrorEvent import com.adyen.checkout.components.core.internal.analytics.GenericEvents import com.adyen.checkout.components.core.internal.util.bufferedChannel import com.adyen.checkout.core.AdyenLogLevel @@ -230,16 +231,19 @@ internal class DefaultGooglePayDelegate( AutoResolveHelper.RESULT_ERROR -> { val statusMessage: String = paymentDataTaskResult.status.statusMessage?.let { ": $it" }.orEmpty() adyenLog(AdyenLogLevel.ERROR) { "GooglePay encountered an error$statusMessage" } + trackThirdPartyErrorEvent() exceptionChannel.trySend(ComponentException("GooglePay encountered an error$statusMessage")) } CommonStatusCodes.INTERNAL_ERROR -> { adyenLog(AdyenLogLevel.ERROR) { "GooglePay encountered an internal error" } + trackThirdPartyErrorEvent() exceptionChannel.trySend(ComponentException("GooglePay encountered an internal error")) } else -> { adyenLog(AdyenLogLevel.ERROR) { "GooglePay encountered an unexpected error, statusCode: $statusCode" } + trackThirdPartyErrorEvent() exceptionChannel.trySend(ComponentException("GooglePay encountered an unexpected error")) } } @@ -250,6 +254,7 @@ internal class DefaultGooglePayDelegate( when (resultCode) { Activity.RESULT_OK -> { if (data == null) { + trackThirdPartyErrorEvent() exceptionChannel.trySend(ComponentException("Result data is null")) return } @@ -261,6 +266,8 @@ internal class DefaultGooglePayDelegate( } AutoResolveHelper.RESULT_ERROR -> { + trackThirdPartyErrorEvent() + val status = AutoResolveHelper.getStatusFromIntent(data) val statusMessage: String = status?.let { ": ${it.statusMessage}" }.orEmpty() exceptionChannel.trySend(ComponentException("GooglePay returned an error$statusMessage")) @@ -271,6 +278,7 @@ internal class DefaultGooglePayDelegate( private fun initiatePayment(paymentData: PaymentData?) { if (paymentData == null) { adyenLog(AdyenLogLevel.ERROR) { "Payment data is null" } + trackThirdPartyErrorEvent() exceptionChannel.trySend(ComponentException("GooglePay encountered an unexpected error")) return } @@ -283,6 +291,14 @@ internal class DefaultGooglePayDelegate( submitHandler.onSubmit(_componentStateFlow.value) } + private fun trackThirdPartyErrorEvent() { + val event = GenericEvents.error( + component = getPaymentMethodType(), + event = ErrorEvent.THIRD_PARTY, + ) + analyticsManager.trackEvent(event) + } + override fun getGooglePayButtonParameters(): GooglePayButtonParameters { val allowedPaymentMethodsList = GooglePayUtils.getAllowedPaymentMethods(componentParams) val allowedPaymentMethods = ModelUtils.serializeOptList( diff --git a/googlepay/src/test/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegateTest.kt b/googlepay/src/test/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegateTest.kt index 1604aba502..cf00f955bc 100644 --- a/googlepay/src/test/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegateTest.kt +++ b/googlepay/src/test/java/com/adyen/checkout/googlepay/internal/ui/DefaultGooglePayDelegateTest.kt @@ -8,6 +8,7 @@ package com.adyen.checkout.googlepay.internal.ui +import android.app.Activity import app.cash.turbine.test import com.adyen.checkout.components.core.Amount import com.adyen.checkout.components.core.CheckoutConfiguration @@ -16,6 +17,7 @@ import com.adyen.checkout.components.core.Configuration import com.adyen.checkout.components.core.OrderRequest import com.adyen.checkout.components.core.PaymentMethod import com.adyen.checkout.components.core.internal.PaymentObserverRepository +import com.adyen.checkout.components.core.internal.analytics.ErrorEvent import com.adyen.checkout.components.core.internal.analytics.GenericEvents import com.adyen.checkout.components.core.internal.analytics.TestAnalyticsManager import com.adyen.checkout.components.core.internal.ui.model.CommonComponentParamsMapper @@ -287,6 +289,31 @@ internal class DefaultGooglePayDelegateTest( analyticsManager.assertIsCleared() } + + @ParameterizedTest + @MethodSource("com.adyen.checkout.googlepay.internal.ui.DefaultGooglePayDelegateTest#paymentResultErrorSource") + fun `when handling payment result is error, then error event is tracked`( + result: ApiTaskResult + ) { + delegate.handlePaymentResult(result) + + val expectedEvent = GenericEvents.error( + component = TEST_PAYMENT_METHOD_TYPE, + event = ErrorEvent.THIRD_PARTY, + ) + analyticsManager.assertLastEventEquals(expectedEvent) + } + + @Test + fun `when activity result is OK and data is null, then error event is tracked`() { + delegate.handleActivityResult(Activity.RESULT_OK, data = null) + + val expectedEvent = GenericEvents.error( + component = TEST_PAYMENT_METHOD_TYPE, + event = ErrorEvent.THIRD_PARTY, + ) + analyticsManager.assertLastEventEquals(expectedEvent) + } } @ParameterizedTest @@ -413,5 +440,14 @@ internal class DefaultGooglePayDelegateTest( arguments(true, false, false, GooglePayUnavailableException()), arguments(true, true, true, null), ) + + @JvmStatic + fun paymentResultErrorSource() = listOf( + // result + arguments(ApiTaskResult(null, Status.RESULT_SUCCESS)), + arguments(ApiTaskResult(null, Status.RESULT_INTERNAL_ERROR)), + arguments(ApiTaskResult(null, Status.RESULT_INTERRUPTED)), + arguments(ApiTaskResult(null, Status(AutoResolveHelper.RESULT_ERROR))), + ) } }