Skip to content

Commit

Permalink
Paypal analytics (#1231)
Browse files Browse the repository at this point in the history
* Add constants

* Add analytics around app switch return to app

* remove analytics captured in the wrong place
  • Loading branch information
saperi22 authored Dec 10, 2024
1 parent e12b985 commit caf65bd
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ internal object PayPalAnalytics {

// Additional Conversion events
const val HANDLE_RETURN_STARTED = "paypal:tokenize:handle-return:started"
const val HANDLE_RETURN_SUCCEEDED = "paypal:tokenize:handle-return:succeeded"
const val HANDLE_RETURN_FAILED = "paypal:tokenize:handle-return:failed"
const val HANDLE_RETURN_NO_RESULT = "paypal:tokenize:handle-return:no-result"

// App Switch events
const val APP_SWITCH_STARTED = "paypal:tokenize:app-switch:started"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,6 @@ class PayPalClient internal constructor(

if (isAppSwitchFlow) {
appSwitchUrlString = approvalUrl
braintreeClient.sendAnalyticsEvent(
PayPalAnalytics.HANDLE_RETURN_STARTED,
analyticsParams
)
}

approvalUrl?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@ import com.braintreepayments.api.BrowserSwitchClient
import com.braintreepayments.api.BrowserSwitchException
import com.braintreepayments.api.BrowserSwitchFinalResult
import com.braintreepayments.api.BrowserSwitchStartResult
import com.braintreepayments.api.core.AnalyticsClient
import com.braintreepayments.api.core.BraintreeException

/**
* Responsible for launching PayPal user authentication in a web browser
*/
class PayPalLauncher internal constructor(private val browserSwitchClient: BrowserSwitchClient) {
class PayPalLauncher internal constructor(
private val browserSwitchClient: BrowserSwitchClient,
lazyAnalyticsClient: Lazy<AnalyticsClient>
) {
/**
* Used to launch the PayPal flow in a web browser and deliver results to your Activity
*/
constructor() : this(BrowserSwitchClient())
constructor() : this(
browserSwitchClient = BrowserSwitchClient(),
lazyAnalyticsClient = AnalyticsClient.lazyInstance
)

private val analyticsClient: AnalyticsClient by lazyAnalyticsClient

/**
* Launches the PayPal flow by switching to a web browser for user authentication
Expand Down Expand Up @@ -73,17 +82,27 @@ class PayPalLauncher internal constructor(private val browserSwitchClient: Brows
pendingRequest: PayPalPendingRequest.Started,
intent: Intent
): PayPalPaymentAuthResult {
analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_STARTED)
return when (val browserSwitchResult =
browserSwitchClient.completeRequest(intent, pendingRequest.pendingRequestString)) {
is BrowserSwitchFinalResult.Success -> PayPalPaymentAuthResult.Success(
browserSwitchResult
)
is BrowserSwitchFinalResult.Success -> {
analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_SUCCEEDED)
PayPalPaymentAuthResult.Success(
browserSwitchResult
)
}

is BrowserSwitchFinalResult.Failure -> PayPalPaymentAuthResult.Failure(
browserSwitchResult.error
)
is BrowserSwitchFinalResult.Failure -> {
analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_FAILED)
PayPalPaymentAuthResult.Failure(
browserSwitchResult.error
)
}

is BrowserSwitchFinalResult.NoResult -> PayPalPaymentAuthResult.NoResult
is BrowserSwitchFinalResult.NoResult -> {
analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_NO_RESULT)
PayPalPaymentAuthResult.NoResult
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,6 @@ public void tokenize_whenPayPalInternalClientTokenizeResult_sendsAppSwitchSuccee
assertEquals(payPalAccountNonce, ((PayPalResult.Success) result).getNonce());

AnalyticsEventParams params = new AnalyticsEventParams();
verify(braintreeClient).sendAnalyticsEvent(PayPalAnalytics.HANDLE_RETURN_STARTED, params);
params.setPayPalContextId("EC-HERMES-SANDBOX-EC-TOKEN");
verify(braintreeClient).sendAnalyticsEvent(PayPalAnalytics.TOKENIZATION_SUCCEEDED, params);
AnalyticsEventParams appSwitchParams = new AnalyticsEventParams(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import com.braintreepayments.api.BrowserSwitchException
import com.braintreepayments.api.BrowserSwitchFinalResult
import com.braintreepayments.api.BrowserSwitchOptions
import com.braintreepayments.api.BrowserSwitchStartResult
import com.braintreepayments.api.core.AnalyticsClient
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.json.JSONException
import org.junit.Assert.assertEquals
import org.junit.Assert.assertSame
Expand All @@ -26,13 +28,14 @@ class PayPalLauncherUnitTest {
private val intent: Intent = mockk(relaxed = true)
private val options: BrowserSwitchOptions = mockk(relaxed = true)
private val pendingRequestString = "pending_request_string"
private val analyticsClient: AnalyticsClient = mockk(relaxed = true)

private lateinit var sut: PayPalLauncher

@Before
fun setup() {
every { paymentAuthRequestParams.browserSwitchOptions } returns options
sut = PayPalLauncher(browserSwitchClient)
sut = PayPalLauncher(browserSwitchClient, lazy { analyticsClient })
}

@Test
Expand Down Expand Up @@ -90,6 +93,16 @@ class PayPalLauncherUnitTest {
)
}

@Test
@Throws(JSONException::class)
fun `handleReturnToApp sends started event`() {
sut.handleReturnToApp(
PayPalPendingRequest.Started(pendingRequestString),
intent
)
verify { analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_STARTED) }
}

@Test
@Throws(JSONException::class)
fun `handleReturnToApp when result exists returns result`() {
Expand All @@ -102,14 +115,40 @@ class PayPalLauncherUnitTest {
} returns browserSwitchFinalResult

val paymentAuthResult = sut.handleReturnToApp(
PayPalPendingRequest.Started(pendingRequestString), intent
PayPalPendingRequest.Started(pendingRequestString),
intent
)

assertTrue(paymentAuthResult is PayPalPaymentAuthResult.Success)
assertSame(
browserSwitchFinalResult,
(paymentAuthResult as PayPalPaymentAuthResult.Success).browserSwitchSuccess
)
verify { analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_SUCCEEDED) }
}

@Test
@Throws(JSONException::class)
fun `handleReturnToApp when result fails returns failed result`() {
val browserSwitchFinalResult = mockk<BrowserSwitchFinalResult.Failure>()
every {
browserSwitchClient.completeRequest(intent, pendingRequestString)
} returns browserSwitchFinalResult

val exception = BrowserSwitchException("BrowserSwitchException")
every { browserSwitchFinalResult.error } returns exception

val paymentAuthResult = sut.handleReturnToApp(
PayPalPendingRequest.Started(pendingRequestString),
intent
)

assertTrue(paymentAuthResult is PayPalPaymentAuthResult.Failure)
assertSame(
exception,
(paymentAuthResult as PayPalPaymentAuthResult.Failure).error
)
verify { analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_FAILED) }
}

@Test
Expand All @@ -120,9 +159,11 @@ class PayPalLauncherUnitTest {
} returns BrowserSwitchFinalResult.NoResult

val paymentAuthResult = sut.handleReturnToApp(
PayPalPendingRequest.Started(pendingRequestString), intent
PayPalPendingRequest.Started(pendingRequestString),
intent
)

assertTrue(paymentAuthResult is PayPalPaymentAuthResult.NoResult)
verify { analyticsClient.sendEvent(PayPalAnalytics.HANDLE_RETURN_NO_RESULT) }
}
}

0 comments on commit caf65bd

Please sign in to comment.