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

Shopper Insights - Merchant analytics #869

Merged
merged 5 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ShopperInsights/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ android {
dependencies {
implementation deps.coreKtx

api project(':BraintreeCore')

testImplementation deps.jsonAssert
testImplementation deps.kotlinTest
testImplementation deps.mockk
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.braintreepayments.api

internal object ShopperInsightsAnalytics {
const val PAYPAL_PRESENTED = "shopper-insights:paypal-presented"
const val PAYPAL_SELECTED = "shopper-insights:paypal-selected"
const val VENMO_PRESENTED = "shopper-insights:venmo-presented"
const val VENMO_SELECTED = "shopper-insights:venmo-selected"
saperi22 marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.braintreepayments.api

import androidx.annotation.VisibleForTesting
import com.braintreepayments.api.ShopperInsightsAnalytics.PAYPAL_PRESENTED
Copy link
Contributor

Choose a reason for hiding this comment

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

This may be my lack of Android knowledge but can we just do import com.braintreepayments.api.ShopperInsightsAnalytics or do we need to import each event individually?

Copy link
Contributor

Choose a reason for hiding this comment

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

In other modules we have been fully qualifying the events when used (ex: on line 61 braintreeClient.sendAnalyticsEvent(ShopperInsightsAnalytics.PAYPAL_PRESENTED)) that being said, either way is fine with me

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep, we could use a wildcard import here import com.braintreepayments.api.ShopperInsightsAnalytics.*, but Google is opinionated about import statements. https://developer.android.com/kotlin/style-guide#import_statements

I think there are pros and cons to both ways, but Android Studio is pretty good at formatting imports and auto imports.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice, thanks for sending over that doc!

Copy link
Contributor Author

@saperi22 saperi22 Dec 21, 2023

Choose a reason for hiding this comment

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

Some of the cons of using wildcard imports might no longer apply to kotlin, as it gives us a way to use import alias as shown below, but the tools and practices are slower to catch up to the capabilities of the newer languages, so we just go with whatever the tools suggest :D

But yeah, no reason not to use wild card imports in this current scenario.

Example of import alias.

import org.example.Message // Message is accessible
import org.test.Message as TestMessage // TestMessage stands for 'org.test.Message'

See: https://kotlinlang.org/docs/packages.html#imports

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you are interested, here's how things could go wrong using wildcard imports.
https://www.javadude.com/posts/20040522-import-on-demand-is-evil/

Copy link
Contributor

Choose a reason for hiding this comment

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

There's a way to turn off autogen of import * in Android Studio in preferences, I forget exactly where.

import com.braintreepayments.api.ShopperInsightsAnalytics.PAYPAL_SELECTED
import com.braintreepayments.api.ShopperInsightsAnalytics.VENMO_PRESENTED
import com.braintreepayments.api.ShopperInsightsAnalytics.VENMO_SELECTED

/**
* Use [ShopperInsightsClient] to optimize your checkout experience
Expand All @@ -11,7 +15,8 @@ import androidx.annotation.VisibleForTesting
* Note: **This feature is in beta. It's public API may change in future releases.**
*/
class ShopperInsightsClient @VisibleForTesting internal constructor(
private val paymentReadyAPI: PaymentReadyApi
private val paymentReadyAPI: PaymentReadyApi,
private val braintreeClient: BraintreeClient
) {
/**
* Retrieves recommended payment methods based on the provided shopper insights request.
Expand Down Expand Up @@ -47,4 +52,36 @@ class ShopperInsightsClient @VisibleForTesting internal constructor(
)
)
}

/**
* Call this method when the PayPal button has been successfully displayed to the buyer.
* This method sends analytics to help improve the Shopper Insights feature experience.
*/
fun sendPayPalPresentedEvent() {
tdchow marked this conversation as resolved.
Show resolved Hide resolved
braintreeClient.sendAnalyticsEvent(PAYPAL_PRESENTED)
}

/**
* Call this method when the PayPal button has been selected/tapped by the buyer.
* This method sends analytics to help improve the Shopper Insights feature experience.
*/
fun sendPayPalSelectedEvent() {
braintreeClient.sendAnalyticsEvent(PAYPAL_SELECTED)
}

/**
* Call this method when the Venmo button has been successfully displayed to the buyer.
* This method sends analytics to help improve the Shopper Insights feature experience.
*/
fun sendVenmoPresentedEvent() {
braintreeClient.sendAnalyticsEvent(VENMO_PRESENTED)
}

/**
* Call this method when the Venmo button has been selected/tapped by the buyer.
* This method sends analytics to help improve the Shopper Insights feature experience.
*/
fun sendVenmoSelectedEvent() {
braintreeClient.sendAnalyticsEvent(VENMO_SELECTED)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.braintreepayments.api

import io.mockk.mockk
import io.mockk.verify
import kotlin.test.assertEquals
import kotlin.test.assertIs
import org.junit.Assert.assertNotNull
Expand All @@ -18,11 +19,13 @@ class ShopperInsightsClientUnitTest {

private lateinit var sut: ShopperInsightsClient
private lateinit var paymentApi: PaymentReadyApi
private lateinit var braintreeClient: BraintreeClient

@Before
fun beforeEach() {
paymentApi = mockk(relaxed = true)
sut = ShopperInsightsClient(paymentApi)
braintreeClient = mockk(relaxed = true)
sut = ShopperInsightsClient(paymentApi, braintreeClient)
}

/**
Expand Down Expand Up @@ -54,4 +57,28 @@ class ShopperInsightsClientUnitTest {
)
}
}

@Test
fun `test paypal presented analytics event`() {
sut.sendPayPalPresentedEvent()
verify { braintreeClient.sendAnalyticsEvent("shopper-insights:paypal-presented") }
}

@Test
fun `test paypal selected analytics event`() {
sut.sendPayPalSelectedEvent()
verify { braintreeClient.sendAnalyticsEvent("shopper-insights:paypal-selected") }
}

@Test
fun `test venmo presented analytics event`() {
sut.sendVenmoPresentedEvent()
verify { braintreeClient.sendAnalyticsEvent("shopper-insights:venmo-presented") }
}

@Test
fun `test venmo selected analytics event`() {
sut.sendVenmoSelectedEvent()
verify { braintreeClient.sendAnalyticsEvent("shopper-insights:venmo-selected") }
}
}
Loading