Skip to content

Commit

Permalink
Migrate PayPalWebClient Analytics Logic Into PayPalWebAnalytics Class (
Browse files Browse the repository at this point in the history
…#300)

* Extract all analytics tracking from PayPalWebClient into PayPalWebAnalytics.

* Update broken unit test.

* Remove unused imports.

* Fix analytics typo.
  • Loading branch information
sshropshire authored Dec 2, 2024
1 parent 6ac1752 commit afda478
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package com.paypal.android.cardpayments
import com.paypal.android.corepayments.analytics.AnalyticsService

@Suppress("TooManyFunctions")
class CardAnalytics(
private val analyticsService: AnalyticsService
) {
internal class CardAnalytics(private val analyticsService: AnalyticsService) {

// region Approve Order
fun notifyApproveOrderStarted(orderId: String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.paypal.android.paypalwebpayments

import com.paypal.android.corepayments.analytics.AnalyticsService

@Suppress("TooManyFunctions")
internal class PayPalWebAnalytics(private val analyticsService: AnalyticsService) {

fun notifyCheckoutStarted(orderId: String) {
val eventName = "paypal-web-payments:checkout:started"
analyticsService.sendAnalyticsEvent(eventName, orderId)
}

fun notifyCheckoutAuthChallengeStarted(orderId: String) {
val eventName = "paypal-web-payments:checkout:auth-challenge-started"
analyticsService.sendAnalyticsEvent(eventName, orderId)
}

fun notifyCheckoutAuthChallengeSucceeded(orderId: String?) {
val eventName = "paypal-web-payments:checkout:auth-challenge-succeeded"
analyticsService.sendAnalyticsEvent(eventName, orderId)
}

fun notifyCheckoutAuthChallengeFailed(orderId: String?) {
val eventName = "paypal-web-payments:checkout:auth-challenge-failed"
analyticsService.sendAnalyticsEvent(eventName, orderId)
}

fun notifyCheckoutAuthChallengeCanceled(orderId: String?) {
val eventName = "paypal-web-payments:checkout:auth-challenge-canceled"
analyticsService.sendAnalyticsEvent(eventName, orderId)
}

fun notifyVaultStarted(setupTokenId: String) {
val eventName = "paypal-web-payments:vault:started"
analyticsService.sendAnalyticsEvent(eventName, setupTokenId)
}

fun notifyVaultAuthChallengeStarted(setupTokenId: String) {
val eventName = "paypal-web-payments:vault:auth-challenge-started"
analyticsService.sendAnalyticsEvent(eventName, setupTokenId)
}

fun notifyVaultAuthChallengeSucceeded(setupTokenId: String?) {
val eventName = "paypal-web-payments:vault:auth-challenge-succeeded"
analyticsService.sendAnalyticsEvent(eventName, setupTokenId)
}

fun notifyVaultAuthChallengeFailed(setupTokenId: String?) {
val eventName = "paypal-web-payments:vault:auth-challenge-failed"
analyticsService.sendAnalyticsEvent(eventName, setupTokenId)
}

fun notifyVaultAuthChallengeCanceled(setupTokenId: String?) {
val eventName = "paypal-web-payments:vault:auth-challenge-canceled"
analyticsService.sendAnalyticsEvent(eventName, setupTokenId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.content.Intent
import android.util.Log
import androidx.activity.ComponentActivity
import com.paypal.android.corepayments.CoreConfig
import com.paypal.android.corepayments.PayPalSDKError
import com.paypal.android.corepayments.analytics.AnalyticsService

// NEXT MAJOR VERSION: consider renaming this module to PayPalWebClient since
Expand All @@ -15,7 +14,7 @@ import com.paypal.android.corepayments.analytics.AnalyticsService
* Use this client to approve an order with a [PayPalWebCheckoutRequest].
*/
class PayPalWebCheckoutClient internal constructor(
private val analyticsService: AnalyticsService,
private val analytics: PayPalWebAnalytics,
private val payPalWebLauncher: PayPalWebLauncher
) {

Expand All @@ -27,7 +26,7 @@ class PayPalWebCheckoutClient internal constructor(
* @param urlScheme the custom URl scheme used to return to your app from a browser switch flow
*/
constructor(context: Context, configuration: CoreConfig, urlScheme: String) : this(
AnalyticsService(context.applicationContext, configuration),
PayPalWebAnalytics(AnalyticsService(context.applicationContext, configuration)),
PayPalWebLauncher(urlScheme, configuration),
)

Expand All @@ -50,16 +49,16 @@ class PayPalWebCheckoutClient internal constructor(
activity: ComponentActivity,
request: PayPalWebCheckoutRequest
): PayPalPresentAuthChallengeResult {
analyticsService.sendAnalyticsEvent("paypal-web-payments:started", request.orderId)
analytics.notifyCheckoutStarted(request.orderId)
val result = payPalWebLauncher.launchPayPalWebCheckout(activity, request)
when (result) {
is PayPalPresentAuthChallengeResult.Failure -> {
notifyWebCheckoutFailure(result.error, request.orderId)
analytics.notifyCheckoutAuthChallengeFailed(request.orderId)
listener?.onPayPalWebFailure(result.error)
}

is PayPalPresentAuthChallengeResult.Success -> {
// TODO: track success with analytics
}
is PayPalPresentAuthChallengeResult.Success ->
analytics.notifyCheckoutAuthChallengeStarted(request.orderId)
}
return result
}
Expand All @@ -73,72 +72,64 @@ class PayPalWebCheckoutClient internal constructor(
activity: ComponentActivity,
request: PayPalWebVaultRequest
): PayPalPresentAuthChallengeResult {
analyticsService.sendAnalyticsEvent("paypal-web-payments:vault-wo-purchase:started")
analytics.notifyVaultStarted(request.setupTokenId)
val result = payPalWebLauncher.launchPayPalWebVault(activity, request)
when (result) {
is PayPalPresentAuthChallengeResult.Failure -> {
notifyVaultFailure(result.error)
analytics.notifyVaultAuthChallengeFailed(request.setupTokenId)
vaultListener?.onPayPalWebVaultFailure(result.error)
}

is PayPalPresentAuthChallengeResult.Success -> {
// TODO: track success with analytics
}
is PayPalPresentAuthChallengeResult.Success ->
analytics.notifyVaultAuthChallengeStarted(request.setupTokenId)
}
return result
}

fun completeAuthChallenge(intent: Intent, authState: String): PayPalWebStatus {
val status = payPalWebLauncher.completeAuthRequest(intent, authState)
when (status) {
is PayPalWebStatus.CheckoutSuccess -> notifyWebCheckoutSuccess(status.result)
is PayPalWebStatus.CheckoutError -> status.run {
notifyWebCheckoutFailure(error, orderId)
is PayPalWebStatus.CheckoutSuccess -> {
analytics.notifyCheckoutAuthChallengeSucceeded(status.result.orderId)
listener?.onPayPalWebSuccess(status.result)
}

is PayPalWebStatus.CheckoutError -> {
analytics.notifyCheckoutAuthChallengeFailed(status.orderId)
listener?.onPayPalWebFailure(status.error)
}

is PayPalWebStatus.CheckoutCanceled -> {
analytics.notifyCheckoutAuthChallengeCanceled(status.orderId)
listener?.onPayPalWebCanceled()
}

is PayPalWebStatus.CheckoutCanceled -> notifyWebCheckoutCancelation(status.orderId)
is PayPalWebStatus.VaultSuccess -> notifyVaultSuccess(status.result)
is PayPalWebStatus.VaultError -> notifyVaultFailure(status.error)
PayPalWebStatus.VaultCanceled -> notifyVaultCancelation()
is PayPalWebStatus.VaultSuccess -> {
// TODO: see if we can get setup token id from somewhere
analytics.notifyVaultAuthChallengeSucceeded(null)
vaultListener?.onPayPalWebVaultSuccess(status.result)
}
is PayPalWebStatus.VaultError -> {
// TODO: see if we can get setup token id from somewhere
analytics.notifyVaultAuthChallengeFailed(null)
vaultListener?.onPayPalWebVaultFailure(status.error)
}
PayPalWebStatus.VaultCanceled -> {
// TODO: see if we can get setup token id from somewhere
analytics.notifyVaultAuthChallengeCanceled(null)
vaultListener?.onPayPalWebVaultCanceled()
}
is PayPalWebStatus.UnknownError -> {
Log.d("PayPalSDK", "An unknown error occurred: ${status.error.message}")
}

PayPalWebStatus.NoResult -> {
// ignore
}
}
return status
}

private fun notifyWebCheckoutSuccess(result: PayPalWebCheckoutResult) {
analyticsService.sendAnalyticsEvent("paypal-web-payments:succeeded", result.orderId)
listener?.onPayPalWebSuccess(result)
}

private fun notifyWebCheckoutFailure(error: PayPalSDKError, orderId: String?) {
analyticsService.sendAnalyticsEvent("paypal-web-payments:failed", orderId)
listener?.onPayPalWebFailure(error)
}

private fun notifyWebCheckoutCancelation(orderId: String?) {
analyticsService.sendAnalyticsEvent("paypal-web-payments:browser-login:canceled", orderId)
listener?.onPayPalWebCanceled()
}

private fun notifyVaultSuccess(result: PayPalWebVaultResult) {
analyticsService.sendAnalyticsEvent("paypal-web-payments:vault-wo-purchase:succeeded")
vaultListener?.onPayPalWebVaultSuccess(result)
}

private fun notifyVaultFailure(error: PayPalSDKError) {
analyticsService.sendAnalyticsEvent("paypal-web-payments:vault-wo-purchase:failed")
vaultListener?.onPayPalWebVaultFailure(error)
}

private fun notifyVaultCancelation() {
analyticsService.sendAnalyticsEvent("paypal-web-payments:vault-wo-purchase:canceled")
vaultListener?.onPayPalWebVaultCanceled()
}

/**
* Call this method at the end of the web checkout flow to clear out all observers and listeners
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.paypal.android.paypalwebpayments
import android.content.Intent
import androidx.fragment.app.FragmentActivity
import com.paypal.android.corepayments.PayPalSDKError
import com.paypal.android.corepayments.analytics.AnalyticsService
import io.mockk.Called
import io.mockk.every
import io.mockk.mockk
Expand All @@ -21,7 +20,7 @@ import org.robolectric.RobolectricTestRunner
class PayPalWebCheckoutClientUnitTest {

private val activity: FragmentActivity = mockk(relaxed = true)
private val analyticsService = mockk<AnalyticsService>(relaxed = true)
private val analytics = mockk<PayPalWebAnalytics>(relaxed = true)

private val checkoutListener = mockk<PayPalWebCheckoutListener>(relaxed = true)
private val vaultListener = mockk<PayPalWebVaultListener>(relaxed = true)
Expand All @@ -34,7 +33,7 @@ class PayPalWebCheckoutClientUnitTest {
@Before
fun beforeEach() {
payPalWebLauncher = mockk(relaxed = true)
sut = PayPalWebCheckoutClient(analyticsService, payPalWebLauncher)
sut = PayPalWebCheckoutClient(analytics, payPalWebLauncher)
}

@Test
Expand Down

0 comments on commit afda478

Please sign in to comment.