From f884503a348fa6483eebead46a2aa1dc3250a06e Mon Sep 17 00:00:00 2001 From: Gabriel Luong Date: Thu, 9 Mar 2023 00:59:57 -0500 Subject: [PATCH] Bug 1822446 - Add OnboardingController for handling onboarding functionality --- .../org/mozilla/fenix/home/HomeFragment.kt | 6 +- .../SessionControlController.kt | 25 -------- .../SessionControlInteractor.kt | 8 ++- .../controller/OnboardingController.kt | 46 +++++++++++++++ .../DefaultSessionControlControllerTest.kt | 33 ----------- .../home/SessionControlInteractorTest.kt | 11 +++- .../interactor/RecentVisitsInteractorTest.kt | 3 + .../DefaultOnboardingControllerTest.kt | 58 +++++++++++++++++++ 8 files changed, 127 insertions(+), 63 deletions(-) create mode 100644 app/src/main/java/org/mozilla/fenix/onboarding/controller/OnboardingController.kt create mode 100644 app/src/test/java/org/mozilla/fenix/onboarding/DefaultOnboardingControllerTest.kt diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index bd92d6f86c..41716f5e39 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -124,6 +124,7 @@ import org.mozilla.fenix.home.sessioncontrol.viewholders.CollectionHeaderViewHol import org.mozilla.fenix.home.topsites.DefaultTopSitesView import org.mozilla.fenix.nimbus.FxNimbus import org.mozilla.fenix.onboarding.FenixOnboarding +import org.mozilla.fenix.onboarding.controller.DefaultOnboardingController import org.mozilla.fenix.perf.MarkersFragmentLifecycleCallbacks import org.mozilla.fenix.perf.runBlockingIncrement import org.mozilla.fenix.search.toolbar.SearchSelectorMenu @@ -390,7 +391,6 @@ class HomeFragment : Fragment() { appStore = components.appStore, navController = findNavController(), viewLifecycleScope = viewLifecycleOwner.lifecycleScope, - hideOnboarding = ::hideOnboardingAndOpenSearch, registerCollectionStorageObserver = ::registerCollectionStorageObserver, removeCollectionWithUndo = ::removeCollectionWithUndo, showTabTray = ::openTabsTray, @@ -423,6 +423,10 @@ class HomeFragment : Fragment() { homeActivity = activity, appStore = components.appStore, ), + onboardingController = DefaultOnboardingController( + activity = activity, + hideOnboarding = ::hideOnboardingAndOpenSearch, + ), ) updateLayout(binding.root) 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 93d56829d1..ad30bb5883 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 @@ -143,16 +143,6 @@ interface SessionControlController { */ fun handleSponsorPrivacyClicked() - /** - * @see [OnboardingInteractor.onStartBrowsingClicked] - */ - fun handleStartBrowsingClicked() - - /** - * @see [OnboardingInteractor.onReadPrivacyNoticeClicked] - */ - fun handleReadPrivacyNoticeClicked() - /** * @see [CollectionInteractor.onToggleCollectionExpanded] */ @@ -229,7 +219,6 @@ class DefaultSessionControlController( private val appStore: AppStore, private val navController: NavController, private val viewLifecycleScope: CoroutineScope, - private val hideOnboarding: () -> Unit, private val registerCollectionStorageObserver: () -> Unit, private val removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit, private val showTabTray: () -> Unit, @@ -486,10 +475,6 @@ class DefaultSessionControlController( return url } - override fun handleStartBrowsingClicked() { - hideOnboarding() - } - override fun handleCustomizeHomeTapped() { val directions = HomeFragmentDirections.actionGlobalHomeSettingsFragment() navController.nav(navController.currentDestination?.id, directions) @@ -515,16 +500,6 @@ class DefaultSessionControlController( } } } - - override fun handleReadPrivacyNoticeClicked() { - activity.startActivity( - SupportUtils.createCustomTabIntent( - activity, - SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE), - ), - ) - } - override fun handleToggleCollectionExpanded(collection: TabCollection, expand: Boolean) { appStore.dispatch(AppAction.CollectionExpanded(collection, expand)) } diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt index 85650cfd94..1b8d03ffda 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlInteractor.kt @@ -27,6 +27,7 @@ import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryGrou import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryHighlight import org.mozilla.fenix.home.recentvisits.controller.RecentVisitsController import org.mozilla.fenix.home.recentvisits.interactor.RecentVisitsInteractor +import org.mozilla.fenix.onboarding.controller.OnboardingController import org.mozilla.fenix.onboarding.interactor.OnboardingInteractor import org.mozilla.fenix.search.toolbar.SearchSelectorInteractor import org.mozilla.fenix.search.toolbar.SearchSelectorMenu @@ -234,7 +235,7 @@ interface WallpaperInteractor { * ExperimentCardInteractor, RecentTabInteractor, RecentBookmarksInteractor * and others. */ -@SuppressWarnings("TooManyFunctions") +@SuppressWarnings("TooManyFunctions", "LongParameterList") class SessionControlInteractor( private val controller: SessionControlController, private val recentTabController: RecentTabController, @@ -242,6 +243,7 @@ class SessionControlInteractor( private val recentBookmarksController: RecentBookmarksController, private val recentVisitsController: RecentVisitsController, private val pocketStoriesController: PocketStoriesController, + private val onboardingController: OnboardingController, ) : CollectionInteractor, OnboardingInteractor, TopSiteInteractor, @@ -310,11 +312,11 @@ class SessionControlInteractor( } override fun onStartBrowsingClicked() { - controller.handleStartBrowsingClicked() + onboardingController.handleStartBrowsingClicked() } override fun onReadPrivacyNoticeClicked() { - controller.handleReadPrivacyNoticeClicked() + onboardingController.handleReadPrivacyNoticeClicked() } override fun showWallpapersOnboardingDialog(state: WallpaperState): Boolean { diff --git a/app/src/main/java/org/mozilla/fenix/onboarding/controller/OnboardingController.kt b/app/src/main/java/org/mozilla/fenix/onboarding/controller/OnboardingController.kt new file mode 100644 index 0000000000..e8f0b0eeb8 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/onboarding/controller/OnboardingController.kt @@ -0,0 +1,46 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.onboarding.controller + +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.onboarding.interactor.OnboardingInteractor +import org.mozilla.fenix.settings.SupportUtils + +/** + * An interface that handles the view manipulation of the first run onboarding. + */ +interface OnboardingController { + /** + * @see [OnboardingInteractor.onStartBrowsingClicked] + */ + fun handleStartBrowsingClicked() + + /** + * @see [OnboardingInteractor.onReadPrivacyNoticeClicked] + */ + fun handleReadPrivacyNoticeClicked() +} + +/** + * The default implementation of [OnboardingController]. + */ +class DefaultOnboardingController( + private val activity: HomeActivity, + private val hideOnboarding: () -> Unit, +) : OnboardingController { + + override fun handleStartBrowsingClicked() { + hideOnboarding() + } + + override fun handleReadPrivacyNoticeClicked() { + activity.startActivity( + SupportUtils.createCustomTabIntent( + activity, + SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE), + ), + ) + } +} 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 5e1904ba0f..67b8eab50c 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -11,11 +11,8 @@ import io.mockk.Runs import io.mockk.every import io.mockk.just import io.mockk.mockk -import io.mockk.mockkObject import io.mockk.mockkStatic -import io.mockk.slot import io.mockk.spyk -import io.mockk.unmockkObject import io.mockk.unmockkStatic import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -957,34 +954,6 @@ class DefaultSessionControlControllerTest { assertFalse(createController().handleShowWallpapersOnboardingDialog(wallpaperState)) } - @Test - fun handleStartBrowsingClicked() { - var hideOnboardingInvoked = false - createController(hideOnboarding = { hideOnboardingInvoked = true }).handleStartBrowsingClicked() - - assertTrue(hideOnboardingInvoked) - } - - @Test - fun handleReadPrivacyNoticeClicked() { - mockkObject(SupportUtils) - val urlCaptor = slot() - every { SupportUtils.createCustomTabIntent(any(), capture(urlCaptor)) } returns mockk() - - createController().handleReadPrivacyNoticeClicked() - - verify { - activity.startActivity( - any(), - ) - } - assertEquals( - SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE), - urlCaptor.captured, - ) - unmockkObject(SupportUtils) - } - @Test fun handleToggleCollectionExpanded() { val collection = mockk() @@ -1323,7 +1292,6 @@ class DefaultSessionControlControllerTest { } private fun createController( - hideOnboarding: () -> Unit = { }, registerCollectionStorageObserver: () -> Unit = { }, showTabTray: () -> Unit = { }, removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit = { }, @@ -1342,7 +1310,6 @@ class DefaultSessionControlControllerTest { appStore = appStore, navController = navController, viewLifecycleScope = scope, - hideOnboarding = hideOnboarding, registerCollectionStorageObserver = registerCollectionStorageObserver, removeCollectionWithUndo = removeCollectionWithUndo, showTabTray = showTabTray, diff --git a/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt index d5c6fe14b9..6762cfead5 100644 --- a/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/SessionControlInteractorTest.kt @@ -24,6 +24,7 @@ import org.mozilla.fenix.home.recenttabs.controller.RecentTabController import org.mozilla.fenix.home.recentvisits.controller.RecentVisitsController import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor +import org.mozilla.fenix.onboarding.controller.OnboardingController class SessionControlInteractorTest { @@ -32,6 +33,7 @@ class SessionControlInteractorTest { private val recentSyncedTabController: RecentSyncedTabController = mockk(relaxed = true) private val recentBookmarksController: RecentBookmarksController = mockk(relaxed = true) private val pocketStoriesController: PocketStoriesController = mockk(relaxed = true) + private val onboardingController: OnboardingController = mockk(relaxed = true) // Note: the recent visits tests are handled in [RecentVisitsInteractorTest] and [RecentVisitsControllerTest] private val recentVisitsController: RecentVisitsController = mockk(relaxed = true) @@ -47,6 +49,7 @@ class SessionControlInteractorTest { recentBookmarksController, recentVisitsController, pocketStoriesController, + onboardingController, ) } @@ -109,7 +112,13 @@ class SessionControlInteractorTest { @Test fun onStartBrowsingClicked() { interactor.onStartBrowsingClicked() - verify { controller.handleStartBrowsingClicked() } + verify { onboardingController.handleStartBrowsingClicked() } + } + + @Test + fun onReadPrivacyNoticeClicked() { + interactor.onReadPrivacyNoticeClicked() + verify { onboardingController.handleReadPrivacyNoticeClicked() } } @Test diff --git a/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt index 6522bcdeed..5ecbaaec5b 100644 --- a/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/recentvisits/interactor/RecentVisitsInteractorTest.kt @@ -20,6 +20,7 @@ import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryHigh import org.mozilla.fenix.home.recentvisits.controller.RecentVisitsController import org.mozilla.fenix.home.sessioncontrol.DefaultSessionControlController import org.mozilla.fenix.home.sessioncontrol.SessionControlInteractor +import org.mozilla.fenix.onboarding.controller.OnboardingController class RecentVisitsInteractorTest { private val defaultSessionControlController: DefaultSessionControlController = @@ -29,6 +30,7 @@ class RecentVisitsInteractorTest { private val recentBookmarksController: RecentBookmarksController = mockk(relaxed = true) private val pocketStoriesController: PocketStoriesController = mockk(relaxed = true) private val recentVisitsController: RecentVisitsController = mockk(relaxed = true) + private val onboardingController: OnboardingController = mockk(relaxed = true) private lateinit var interactor: SessionControlInteractor @@ -41,6 +43,7 @@ class RecentVisitsInteractorTest { recentBookmarksController, recentVisitsController, pocketStoriesController, + onboardingController, ) } diff --git a/app/src/test/java/org/mozilla/fenix/onboarding/DefaultOnboardingControllerTest.kt b/app/src/test/java/org/mozilla/fenix/onboarding/DefaultOnboardingControllerTest.kt new file mode 100644 index 0000000000..8e967b5f43 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/onboarding/DefaultOnboardingControllerTest.kt @@ -0,0 +1,58 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.fenix.onboarding + +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkObject +import io.mockk.slot +import io.mockk.unmockkObject +import io.mockk.verify +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.mozilla.fenix.HomeActivity +import org.mozilla.fenix.onboarding.controller.DefaultOnboardingController +import org.mozilla.fenix.settings.SupportUtils + +class DefaultOnboardingControllerTest { + + private val activity: HomeActivity = mockk(relaxed = true) + + @Test + fun handleStartBrowsingClicked() { + var hideOnboardingInvoked = false + createController(hideOnboarding = { hideOnboardingInvoked = true }).handleStartBrowsingClicked() + + assertTrue(hideOnboardingInvoked) + } + + @Test + fun handleReadPrivacyNoticeClicked() { + mockkObject(SupportUtils) + val urlCaptor = slot() + every { SupportUtils.createCustomTabIntent(any(), capture(urlCaptor)) } returns mockk() + + createController().handleReadPrivacyNoticeClicked() + + verify { + activity.startActivity( + any(), + ) + } + assertEquals( + SupportUtils.getMozillaPageUrl(SupportUtils.MozillaPage.PRIVATE_NOTICE), + urlCaptor.captured, + ) + unmockkObject(SupportUtils) + } + + private fun createController( + hideOnboarding: () -> Unit = {}, + ) = DefaultOnboardingController( + activity = activity, + hideOnboarding = hideOnboarding, + ) +}