From 4c2c27d82a6d87f80ded9229ed11a2a526307652 Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Fri, 22 Jan 2021 14:23:46 -0500 Subject: [PATCH] [fenix] For https://github.com/mozilla-mobile/fenix/issues/17304 - Implement top site search engine attribution (https://github.com/mozilla-mobile/fenix/pull/17580) --- .../SessionControlController.kt | 22 ++- .../mozilla/fenix/settings/SupportUtils.kt | 2 + .../DefaultSessionControlControllerTest.kt | 127 +++++++++++++++++- 3 files changed, 146 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt index 23188a3b81..1b39222a3b 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt @@ -363,7 +363,9 @@ class DefaultSessionControlController( override fun handleSelectTopSite(url: String, type: TopSite.Type) { dismissSearchDialogIfDisplayed() + metrics.track(Event.TopSiteOpenInNewTab) + when (type) { TopSite.Type.DEFAULT -> metrics.track(Event.TopSiteOpenDefault) TopSite.Type.FRECENT -> metrics.track(Event.TopSiteOpenFrecent) @@ -373,14 +375,32 @@ class DefaultSessionControlController( if (url == SupportUtils.POCKET_TRENDING_URL) { metrics.track(Event.PocketTopSiteClicked) } + addTabUseCase.invoke( - url = url, + url = appendSearchAttributionToUrlIfNeeded(url), selectTab = true, startLoading = true ) activity.openToBrowser(BrowserDirection.FromHome) } + /** + * Append a search attribution query to any provided search engine URL based on the + * user's current region. + */ + private fun appendSearchAttributionToUrlIfNeeded(url: String): String { + if (url == SupportUtils.GOOGLE_URL) { + store.state.search.region?.let { region -> + return when (region.current) { + "US" -> SupportUtils.GOOGLE_US_URL + else -> SupportUtils.GOOGLE_XX_URL + } + } + } + + return url + } + private fun dismissSearchDialogIfDisplayed() { if (navController.currentDestination?.id == R.id.searchDialogFragment) { navController.navigateUp() diff --git a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt index aabccd1bc5..4068a5f652 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/SupportUtils.kt @@ -31,6 +31,8 @@ object SupportUtils { "?e=&p=AyIGZRprFDJWWA1FBCVbV0IUWVALHFRBEwQAQB1AWQkFVUVXfFkAF14lRFRbJXstVWR3WQ1rJ08AZnhS" + "HDJBYh4LZR9eEAMUBlccWCUBEQZRGFoXCxc3ZRteJUl8BmUZWhQ" + "AEwdRGF0cMhIAVB5ZFAETBVAaXRwyFQdcKydLSUpaCEtYFAIXN2UrWCUyIgdVK1slXVZaCCtZFAMWDg%3D%3D" + const val GOOGLE_US_URL = "https://www.google.com/webhp?client=firefox-b-1-m&channel=ts" + const val GOOGLE_XX_URL = "https://www.google.com/webhp?client=firefox-b-m&channel=ts" enum class SumoTopic(internal val topicStr: String) { FENIX_MOVING("sync-delist"), diff --git a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt index 9c28d2eb4b..23c0d1a850 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -14,6 +14,8 @@ import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.TestCoroutineScope import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager +import mozilla.components.browser.state.action.SearchAction +import mozilla.components.browser.state.search.RegionState import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.ReaderState @@ -25,6 +27,7 @@ import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.top.sites.TopSite +import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.rule.MainCoroutineRule import org.junit.After import org.junit.Before @@ -89,11 +92,13 @@ class DefaultSessionControlControllerTest { @Before fun setup() { - store = BrowserStore(BrowserState( - search = SearchState( - regionSearchEngines = listOf(searchEngine) + store = BrowserStore( + BrowserState( + search = SearchState( + regionSearchEngines = listOf(searchEngine) + ) ) - )) + ) every { fragmentStore.state } returns HomeFragmentState( collections = emptyList(), @@ -357,6 +362,120 @@ class DefaultSessionControlControllerTest { verify { activity.openToBrowser(BrowserDirection.FromHome) } } + @Test + fun handleSelectGoogleDefaultTopSiteUS() { + val topSiteUrl = SupportUtils.GOOGLE_URL + + store.dispatch(SearchAction.SetRegionAction(RegionState("US", "US"))).joinBlocking() + + controller.handleSelectTopSite(topSiteUrl, TopSite.Type.DEFAULT) + verify { metrics.track(Event.TopSiteOpenInNewTab) } + verify { metrics.track(Event.TopSiteOpenDefault) } + verify { + tabsUseCases.addTab.invoke( + url = SupportUtils.GOOGLE_US_URL, + selectTab = true, + startLoading = true + ) + } + verify { activity.openToBrowser(BrowserDirection.FromHome) } + } + + @Test + fun handleSelectGoogleDefaultTopSiteXX() { + val topSiteUrl = SupportUtils.GOOGLE_URL + + store.dispatch(SearchAction.SetRegionAction(RegionState("DE", "FR"))).joinBlocking() + + controller.handleSelectTopSite(topSiteUrl, TopSite.Type.DEFAULT) + verify { metrics.track(Event.TopSiteOpenInNewTab) } + verify { metrics.track(Event.TopSiteOpenDefault) } + verify { + tabsUseCases.addTab.invoke( + SupportUtils.GOOGLE_XX_URL, + selectTab = true, + startLoading = true + ) + } + verify { activity.openToBrowser(BrowserDirection.FromHome) } + } + + @Test + fun handleSelectGooglePinnedTopSiteUS() { + val topSiteUrl = SupportUtils.GOOGLE_URL + + store.dispatch(SearchAction.SetRegionAction(RegionState("US", "US"))).joinBlocking() + + controller.handleSelectTopSite(topSiteUrl, TopSite.Type.PINNED) + verify { metrics.track(Event.TopSiteOpenInNewTab) } + verify { metrics.track(Event.TopSiteOpenPinned) } + verify { + tabsUseCases.addTab.invoke( + SupportUtils.GOOGLE_US_URL, + selectTab = true, + startLoading = true + ) + } + verify { activity.openToBrowser(BrowserDirection.FromHome) } + } + + @Test + fun handleSelectGooglePinnedTopSiteXX() { + val topSiteUrl = SupportUtils.GOOGLE_URL + + store.dispatch(SearchAction.SetRegionAction(RegionState("DE", "FR"))).joinBlocking() + + controller.handleSelectTopSite(topSiteUrl, TopSite.Type.PINNED) + verify { metrics.track(Event.TopSiteOpenInNewTab) } + verify { metrics.track(Event.TopSiteOpenPinned) } + verify { + tabsUseCases.addTab.invoke( + SupportUtils.GOOGLE_XX_URL, + selectTab = true, + startLoading = true + ) + } + verify { activity.openToBrowser(BrowserDirection.FromHome) } + } + + @Test + fun handleSelectGoogleFrecentTopSiteUS() { + val topSiteUrl = SupportUtils.GOOGLE_URL + + store.dispatch(SearchAction.SetRegionAction(RegionState("US", "US"))).joinBlocking() + + controller.handleSelectTopSite(topSiteUrl, TopSite.Type.FRECENT) + verify { metrics.track(Event.TopSiteOpenInNewTab) } + verify { metrics.track(Event.TopSiteOpenFrecent) } + verify { + tabsUseCases.addTab.invoke( + SupportUtils.GOOGLE_US_URL, + selectTab = true, + startLoading = true + ) + } + verify { activity.openToBrowser(BrowserDirection.FromHome) } + } + + @Test + fun handleSelectGoogleFrecentTopSiteXX() { + val topSiteUrl = SupportUtils.GOOGLE_URL + + store.dispatch(SearchAction.SetRegionAction(RegionState("DE", "FR"))).joinBlocking() + + controller.handleSelectTopSite(topSiteUrl, TopSite.Type.FRECENT) + verify { metrics.track(Event.TopSiteOpenInNewTab) } + verify { metrics.track(Event.TopSiteOpenFrecent) } + verify { + tabsUseCases.addTab.invoke( + SupportUtils.GOOGLE_XX_URL, + selectTab = true, + startLoading = true + ) + } + verify { activity.openToBrowser(BrowserDirection.FromHome) } + } + @Test fun handleStartBrowsingClicked() { controller.handleStartBrowsingClicked()