diff --git a/components-core/src/main/java/com/adyen/checkout/components/core/internal/analytics/AnalyticsEvent.kt b/components-core/src/main/java/com/adyen/checkout/components/core/internal/analytics/AnalyticsEvent.kt index 3b927909ff..654a3e2b03 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/core/internal/analytics/AnalyticsEvent.kt +++ b/components-core/src/main/java/com/adyen/checkout/components/core/internal/analytics/AnalyticsEvent.kt @@ -66,6 +66,7 @@ sealed interface AnalyticsEvent { enum class Type(val value: String) { ACTION("action"), SUBMIT("submit"), + CLOSED("closed"), THREEDS2("ThreeDS2"), } } diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/internal/analytics/DropInEvents.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/internal/analytics/DropInEvents.kt new file mode 100644 index 0000000000..0bd6413117 --- /dev/null +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/internal/analytics/DropInEvents.kt @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by ararat on 7/10/2024. + */ + +package com.adyen.checkout.dropin.internal.analytics + +import androidx.annotation.RestrictTo +import com.adyen.checkout.components.core.internal.analytics.AnalyticsEvent +import com.adyen.checkout.components.core.internal.analytics.DirectAnalyticsEventCreation +import com.adyen.checkout.components.core.internal.analytics.GenericEvents + +private const val ANALYTICS_COMPONENT = "dropin" + +@OptIn(DirectAnalyticsEventCreation::class) +@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) +internal object DropInEvents { + + fun rendered( + configData: Map? = null, + ) = GenericEvents.rendered( + component = ANALYTICS_COMPONENT, + configData = configData, + ) + + fun closed( + message: String? = null, + ) = AnalyticsEvent.Log( + component = ANALYTICS_COMPONENT, + type = AnalyticsEvent.Log.Type.CLOSED, + message = message, + ) +} diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/internal/ui/DropInViewModel.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/internal/ui/DropInViewModel.kt index 213eb8fea7..2e22d9d93a 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/internal/ui/DropInViewModel.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/internal/ui/DropInViewModel.kt @@ -25,7 +25,6 @@ import com.adyen.checkout.components.core.PaymentMethodTypes import com.adyen.checkout.components.core.PaymentMethodsApiResponse import com.adyen.checkout.components.core.StoredPaymentMethod import com.adyen.checkout.components.core.internal.analytics.AnalyticsManager -import com.adyen.checkout.components.core.internal.analytics.GenericEvents import com.adyen.checkout.components.core.internal.data.api.OrderStatusRepository import com.adyen.checkout.components.core.internal.ui.model.DropInOverrideParams import com.adyen.checkout.components.core.internal.util.bufferedChannel @@ -35,6 +34,7 @@ import com.adyen.checkout.core.DispatcherProvider import com.adyen.checkout.core.exception.CheckoutException import com.adyen.checkout.core.internal.util.adyenLog import com.adyen.checkout.dropin.R +import com.adyen.checkout.dropin.internal.analytics.DropInEvents import com.adyen.checkout.dropin.internal.ui.model.DropInActivityEvent import com.adyen.checkout.dropin.internal.ui.model.DropInDestination import com.adyen.checkout.dropin.internal.ui.model.DropInOverrideParamsFactory @@ -236,8 +236,7 @@ internal class DropInViewModel( adyenLog(AdyenLogLevel.VERBOSE) { "initializeAnalytics" } analyticsManager.initialize(this, viewModelScope) - val event = GenericEvents.rendered( - component = ANALYTICS_COMPONENT, + val event = DropInEvents.rendered( configData = dropInConfigDataGenerator.generate(configuration = dropInParams), ) analyticsManager.trackEvent(event) @@ -458,6 +457,10 @@ internal class DropInViewModel( fun cancelDropIn() { currentOrder?.let { sendCancelOrderEvent(it, true) } + + val event = DropInEvents.closed() + analyticsManager.trackEvent(event) + sendEvent(DropInActivityEvent.CancelDropIn) } @@ -483,8 +486,6 @@ internal class DropInViewModel( companion object { - private const val ANALYTICS_COMPONENT = "dropin" - // These payment methods are either action only or have no UI. private val SKIP_TO_SINGLE_PM_BLOCK_LIST = listOf( PaymentMethodTypes.DUIT_NOW, diff --git a/drop-in/src/test/java/com/adyen/checkout/dropin/internal/ui/DropInViewModelTest.kt b/drop-in/src/test/java/com/adyen/checkout/dropin/internal/ui/DropInViewModelTest.kt index c7f82d2f3f..ab5f3352cc 100644 --- a/drop-in/src/test/java/com/adyen/checkout/dropin/internal/ui/DropInViewModelTest.kt +++ b/drop-in/src/test/java/com/adyen/checkout/dropin/internal/ui/DropInViewModelTest.kt @@ -5,14 +5,15 @@ import com.adyen.checkout.components.core.PaymentMethod import com.adyen.checkout.components.core.PaymentMethodTypes import com.adyen.checkout.components.core.PaymentMethodsApiResponse import com.adyen.checkout.components.core.StoredPaymentMethod -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.data.api.OrderStatusRepository import com.adyen.checkout.components.core.internal.ui.model.AnalyticsParams import com.adyen.checkout.components.core.internal.ui.model.AnalyticsParamsLevel import com.adyen.checkout.core.Environment +import com.adyen.checkout.dropin.internal.analytics.DropInEvents import com.adyen.checkout.dropin.internal.ui.model.DropInParams import com.adyen.checkout.test.LoggingExtension +import com.adyen.checkout.test.TestDispatcherExtension import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Nested @@ -28,7 +29,7 @@ import org.mockito.kotlin.doReturn import org.mockito.kotlin.whenever import java.util.Locale -@ExtendWith(MockitoExtension::class, LoggingExtension::class) +@ExtendWith(MockitoExtension::class, LoggingExtension::class, TestDispatcherExtension::class) internal class DropInViewModelTest( @Mock private val bundleHandler: DropInSavedStateHandleContainer, @Mock private val orderStatusRepository: OrderStatusRepository, @@ -92,12 +93,21 @@ internal class DropInViewModelTest( viewModel.onCreated(false) - val expected = GenericEvents.rendered( - component = "dropin", + val expected = DropInEvents.rendered( configData = emptyMap(), ) analyticsManager.assertLastEventEquals(expected) } + + @Test + fun `when drop-in is cancelled, then analytics event is tracked`() { + viewModel = createDropInViewModel() + + viewModel.cancelDropIn() + + val expected = DropInEvents.closed() + analyticsManager.assertLastEventEquals(expected) + } } private fun createDropInViewModel(