From a980e5a9c8cfec23583907cbb3f05b794a44462b Mon Sep 17 00:00:00 2001 From: DreVla Date: Mon, 27 Nov 2023 11:21:51 +0200 Subject: [PATCH] Bug 1865854 - Product recommendations telemetry Add missing product recommendations telemetry. (cherry picked from commit 860348cde7567993ddbab8b09bebebaa42ee7596) --- app/metrics.yaml | 78 +++++++++++++++++++ .../org/mozilla/fenix/FenixApplication.kt | 1 + .../ReviewQualityCheckTelemetryMiddleware.kt | 30 +++++++ .../store/ReviewQualityCheckAction.kt | 6 +- ...viewQualityCheckTelemetryMiddlewareTest.kt | 54 +++++++++++++ 5 files changed, 166 insertions(+), 3 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 595135984..3b0faa3d6 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -10863,6 +10863,66 @@ shopping: metadata: tags: - Shopping + surface_ads_impression: + type: event + description: | + The user viewed an ad in review checker for at least 1.5 seconds. + send_in_pings: + - events + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1865854 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4604#issuecomment-1827890623 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: never + metadata: + tags: + - Shopping + surface_ads_clicked: + type: event + description: | + The user clicked an ad in review checker. + send_in_pings: + - events + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1865854 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4604#issuecomment-1827890623 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: never + metadata: + tags: + - Shopping + surface_ads_setting_toggled: + type: event + description: | + The user toggled the ads display setting. + send_in_pings: + - events + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1865854 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4604#issuecomment-1827890623 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: never + extra_keys: + action: + type: string + description: | + Whether the toggle was used to enable or disable ads. Possible values + are `enabled` and `disabled`. + metadata: + tags: + - Shopping shopping.settings: component_opted_out: @@ -10922,6 +10982,24 @@ shopping.settings: metadata: tags: - Shopping + disabled_ads: + type: boolean + description: | + Indicates if the user has disabled ads. + send_in_pings: + - metrics + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1865854 + data_reviews: + - https://github.com/mozilla-mobile/firefox-android/pull/4604#issuecomment-1827890623 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: never + metadata: + tags: + - Shopping fx_suggest: ping_type: type: string diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 72552bd3d..d2a44797e 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -863,6 +863,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider { componentOptedOut.set(!settings.isReviewQualityCheckEnabled) nimbusDisabledShopping.set(!FxNimbus.features.shoppingExperience.value().enabled) userHasOnboarded.set(settings.reviewQualityCheckOptInTimeInMillis != 0L) + disabledAds.set(!settings.isReviewQualityCheckProductRecommendationsEnabled) } } diff --git a/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddleware.kt b/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddleware.kt index 495568be3..8e0268d24 100644 --- a/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddleware.kt +++ b/app/src/main/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddleware.kt @@ -16,6 +16,9 @@ import org.mozilla.fenix.shopping.store.ReviewQualityCheckMiddleware import org.mozilla.fenix.shopping.store.ReviewQualityCheckState import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.AnalysisStatus +private const val ACTION_ENABLED = "enabled" +private const val ACTION_DISABLED = "disabled" + /** * Middleware that captures telemetry events for the review quality check feature. */ @@ -39,6 +42,7 @@ class ReviewQualityCheckTelemetryMiddleware( } } + @Suppress("LongMethod") private fun processAction( store: Store, action: ReviewQualityCheckAction.TelemetryAction, @@ -130,6 +134,32 @@ class ReviewQualityCheckTelemetryMiddleware( is ReviewQualityCheckAction.OpenPoweredByLink -> { Shopping.surfacePoweredByFakespotLinkClicked.record() } + + is ReviewQualityCheckAction.RecommendedProductImpression -> { + Shopping.surfaceAdsImpression.record() + } + + is ReviewQualityCheckAction.RecommendedProductClick -> { + Shopping.surfaceAdsClicked.record() + } + + ReviewQualityCheckAction.ToggleProductRecommendation -> { + val state = store.state + if (state is ReviewQualityCheckState.OptedIn && + state.productRecommendationsPreference != null + ) { + val toggleAction = if (state.productRecommendationsPreference) { + ACTION_ENABLED + } else { + ACTION_DISABLED + } + Shopping.surfaceAdsSettingToggled.record( + Shopping.SurfaceAdsSettingToggledExtra( + action = toggleAction, + ), + ) + } + } } } diff --git a/app/src/main/java/org/mozilla/fenix/shopping/store/ReviewQualityCheckAction.kt b/app/src/main/java/org/mozilla/fenix/shopping/store/ReviewQualityCheckAction.kt index 0ea528aa5..4798ebfea 100644 --- a/app/src/main/java/org/mozilla/fenix/shopping/store/ReviewQualityCheckAction.kt +++ b/app/src/main/java/org/mozilla/fenix/shopping/store/ReviewQualityCheckAction.kt @@ -56,7 +56,7 @@ sealed interface ReviewQualityCheckAction : Action { /** * Triggered when the user has enabled or disabled product recommendations. */ - object ToggleProductRecommendation : PreferencesMiddlewareAction, UpdateAction + object ToggleProductRecommendation : PreferencesMiddlewareAction, UpdateAction, TelemetryAction /** * Triggered as a result of a [OptIn] or [Init] whe user has opted in for shopping experience. @@ -132,7 +132,7 @@ sealed interface ReviewQualityCheckAction : Action { data class RecommendedProductClick( val productAid: String, val productUrl: String, - ) : NavigationMiddlewareAction, NetworkAction + ) : NavigationMiddlewareAction, NetworkAction, TelemetryAction /** * Triggered when the user views the recommended product. @@ -141,7 +141,7 @@ sealed interface ReviewQualityCheckAction : Action { */ data class RecommendedProductImpression( val productAid: String, - ) : NetworkAction + ) : NetworkAction, TelemetryAction /** * Triggered when the user clicks on learn more link on the explainer card. diff --git a/app/src/test/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddlewareTest.kt b/app/src/test/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddlewareTest.kt index ca20e8947..5495d8af2 100644 --- a/app/src/test/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddlewareTest.kt +++ b/app/src/test/java/org/mozilla/fenix/shopping/middleware/ReviewQualityCheckTelemetryMiddlewareTest.kt @@ -333,4 +333,58 @@ class ReviewQualityCheckTelemetryMiddlewareTest { assertNull(Shopping.surfaceStaleAnalysisShown.testGetValue()) } + + @Test + fun `WHEN a product recommendation is visible for more than one and a half seconds THEN ad impression telemetry probe is sent`() { + store.dispatch(ReviewQualityCheckAction.RecommendedProductImpression("")).joinBlocking() + store.waitUntilIdle() + + assertNotNull(Shopping.surfaceAdsImpression.testGetValue()) + } + + @Test + fun `WHEN a product recommendation is clicked THEN the ad clicked telemetry probe is sent`() { + store.dispatch(ReviewQualityCheckAction.RecommendedProductClick("", "")).joinBlocking() + store.waitUntilIdle() + + assertNotNull(Shopping.surfaceAdsClicked.testGetValue()) + } + + @Test + fun `GIVEN the user has opted in WHEN the user switches product recommendations on THEN send enabled product recommendations toggled telemetry probe`() { + val tested = ReviewQualityCheckStore( + initialState = ReviewQualityCheckState.OptedIn( + productRecommendationsPreference = false, + productVendor = ReviewQualityCheckState.ProductVendor.AMAZON, + isHighlightsExpanded = false, + ), + middleware = listOf( + ReviewQualityCheckTelemetryMiddleware(browserStore, appStore), + ), + ) + tested.waitUntilIdle() + tested.dispatch(ReviewQualityCheckAction.ToggleProductRecommendation).joinBlocking() + tested.waitUntilIdle() + + assertNotNull(Shopping.SurfaceAdsSettingToggledExtra("enabled")) + } + + @Test + fun `GIVEN the user has opted in WHEN the user switches product recommendations off THEN send disabled product recommendations toggled telemetry probe`() { + val tested = ReviewQualityCheckStore( + initialState = ReviewQualityCheckState.OptedIn( + productRecommendationsPreference = true, + productVendor = ReviewQualityCheckState.ProductVendor.AMAZON, + isHighlightsExpanded = false, + ), + middleware = listOf( + ReviewQualityCheckTelemetryMiddleware(browserStore, appStore), + ), + ) + tested.waitUntilIdle() + tested.dispatch(ReviewQualityCheckAction.ToggleProductRecommendation).joinBlocking() + tested.waitUntilIdle() + + assertNotNull(Shopping.SurfaceAdsSettingToggledExtra("disabled")) + } }