Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Paypal analytics #1231

Merged
merged 12 commits into from
Dec 10, 2024
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 @@ -212,13 +212,6 @@ class PayPalClient internal constructor(
val switchInitiatedTime = Uri.parse(approvalUrl).getQueryParameter("switch_initiated_time")
val isAppSwitchFlow = !switchInitiatedTime.isNullOrEmpty()

if (isAppSwitchFlow) {
Copy link
Contributor Author

@saperi22 saperi22 Dec 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why HANDLE_RETURN_STARTED was tied to app switch flow, but I'm NOT copying that logic into PayPalLauncher.

braintreeClient.sendAnalyticsEvent(
PayPalAnalytics.HANDLE_RETURN_STARTED,
analyticsParams
)
}

approvalUrl?.let {
val pairingId = Uri.parse(approvalUrl).getQueryParameter(tokenKey)
if (!pairingId.isNullOrEmpty()) {
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 @@ -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 @@ -102,14 +105,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 +149,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) }
}
}
Loading