From 9fc6a8769748b87e2f2c948cdcc7eafa0a37f85b Mon Sep 17 00:00:00 2001 From: Elise Richards Date: Thu, 29 Apr 2021 19:15:56 -0500 Subject: [PATCH] No issue: uplift three dot menu redesign for beta. (#19312) * For #19005: new tab three-dot menu sync sign in (#19037) * Show synced tabs or sync account in new tab menu * Sync sign in item navigates to account settings * Check account auth and get sync item title * Look for sync sign in item on home menu for UI test * Sync sign in menu item UI test * For #19114: check state of sync account when navigating from sync sign in menu item (#19118) * For #18591 - Make the navbar sticky in the new menu * Turn on feature flag for three-dot menu redesign for beta. (#19111) * For #18591 - Update tests Some tests trying to "Add to top sites" may fail because of the sticky navbar now covering that menu item -> scroll the menu up a little. Some tests that previously were trying to scroll to the bottom of the menu to interact with navbar options now don't have to. Them trying to interact with navbar option with the menu opened as collapsed is a good test for the navbar stickyness. Co-authored-by: Mugurell --- .../java/org/mozilla/fenix/ui/SmokeTest.kt | 23 ++-- .../mozilla/fenix/ui/ThreeDotMenuMainTest.kt | 7 +- .../java/org/mozilla/fenix/ui/TopSitesTest.kt | 5 + .../fenix/ui/robots/SyncSignInRobot.kt | 52 +++++++++ .../fenix/ui/robots/ThreeDotMenuMainRobot.kt | 30 +++--- .../java/org/mozilla/fenix/FeatureFlags.kt | 2 +- .../accounts/FenixAccountManager.kt | 33 ++++++ .../toolbar/BrowserToolbarMenuController.kt | 7 +- .../components/toolbar/DefaultToolbarMenu.kt | 14 +-- .../fenix/components/toolbar/ToolbarMenu.kt | 2 +- .../org/mozilla/fenix/home/HomeFragment.kt | 13 +++ .../java/org/mozilla/fenix/home/HomeMenu.kt | 48 +++++---- .../accounts/FenixAccountManagerTest.kt | 101 ++++++++++++++++++ ...DefaultBrowserToolbarMenuControllerTest.kt | 22 ++++ 14 files changed, 303 insertions(+), 56 deletions(-) create mode 100644 app/src/androidTest/java/org/mozilla/fenix/ui/robots/SyncSignInRobot.kt create mode 100644 app/src/main/java/org/mozilla/fenix/components/accounts/FenixAccountManager.kt create mode 100644 app/src/test/java/org/mozilla/fenix/components/accounts/FenixAccountManagerTest.kt diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt index bdb2e31bb..a5ddedb66 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/SmokeTest.kt @@ -17,6 +17,7 @@ import org.junit.Before import org.junit.Ignore import org.junit.Rule import org.junit.Test +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.R import org.mozilla.fenix.ext.settings import org.mozilla.fenix.helpers.AndroidAssetDispatcher @@ -226,12 +227,21 @@ class SmokeTest { } @Test - // Verifies the Synced tabs menu opens from a tab's 3 dot menu - fun openMainMenuSyncedTabsItemTest() { - homeScreen { - }.openThreeDotMenu { - }.openSyncedTabs { - verifySyncedTabsMenuHeader() + // Verifies the Synced tabs menu or Sync Sign In menu opens from a tab's 3 dot menu. + // The test is assuming we are NOT signed in. + fun openMainMenuSyncItemTest() { + if (FeatureFlags.tabsTrayRewrite) { + homeScreen { + }.openThreeDotMenu { + }.openSyncSignIn { + verifySyncSignInMenuHeader() + } + } else { + homeScreen { + }.openThreeDotMenu { + }.openSyncedTabs { + verifySyncedTabsMenuHeader() + } } } @@ -311,7 +321,6 @@ class SmokeTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { - expandMenu() }.openSaveToCollection { verifyCollectionNameTextField() } diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt index f4814f2ee..69b2f294a 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/ThreeDotMenuMainTest.kt @@ -9,6 +9,7 @@ import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test +import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.helpers.AndroidAssetDispatcher import org.mozilla.fenix.helpers.HomeActivityTestRule import org.mozilla.fenix.ui.robots.homeScreen @@ -48,7 +49,11 @@ class ThreeDotMenuMainTest { verifyHistoryButton() verifyDownloadsButton() verifyAddOnsButton() - verifySyncedTabsButton() + if (FeatureFlags.tabsTrayRewrite) { + verifySyncSignInButton() + } else { + verifySyncedTabsButton() + } verifyDesktopSite() verifyWhatsNewButton() verifyHelpButton() diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt index 1b692a619..96eac6ace 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/TopSitesTest.kt @@ -54,6 +54,7 @@ class TopSitesTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { + expandMenu() verifyAddToTopSitesButton() }.addToFirefoxHome { verifySnackBarText("Added to top sites!") @@ -73,6 +74,7 @@ class TopSitesTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { + expandMenu() verifyAddToTopSitesButton() }.addToFirefoxHome { verifySnackBarText("Added to top sites!") @@ -104,6 +106,7 @@ class TopSitesTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { + expandMenu() verifyAddToTopSitesButton() }.addToFirefoxHome { verifySnackBarText("Added to top sites!") @@ -128,6 +131,7 @@ class TopSitesTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { + expandMenu() verifyAddToTopSitesButton() }.addToFirefoxHome { verifySnackBarText("Added to top sites!") @@ -152,6 +156,7 @@ class TopSitesTest { navigationToolbar { }.enterURLAndEnterToBrowser(defaultWebPage.url) { }.openThreeDotMenu { + expandMenu() verifyAddToTopSitesButton() }.addToFirefoxHome { verifySnackBarText("Added to top sites!") diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SyncSignInRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SyncSignInRobot.kt new file mode 100644 index 000000000..ac7132ea7 --- /dev/null +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/SyncSignInRobot.kt @@ -0,0 +1,52 @@ +/* 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.ui.robots + +import androidx.test.espresso.Espresso.onView +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.ViewMatchers.withContentDescription +import androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility +import androidx.test.espresso.matcher.ViewMatchers.withText +import androidx.test.espresso.matcher.ViewMatchers.Visibility +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.uiautomator.UiDevice +import org.hamcrest.CoreMatchers.allOf +import org.mozilla.fenix.R +import org.mozilla.fenix.helpers.click + +/** + * Implementation of Robot Pattern for Sync Sign In sub menu. + */ +class SyncSignInRobot { + + fun verifyAccountSettingsMenuHeader() = assertAccountSettingsMenuHeader() + fun verifySyncSignInMenuHeader() = assertSyncSignInMenuHeader() + + class Transition { + val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())!! + + fun goBack(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { + goBackButton().click() + + BrowserRobot().interact() + return BrowserRobot.Transition() + } + } +} + +private fun goBackButton() = + onView(allOf(withContentDescription("Navigate up"))) + +private fun assertAccountSettingsMenuHeader() { + // Replaced with the new string here, the test is assuming we are NOT signed in + // Sync tests in SettingsSyncTest are still TO-DO, so I'm not sure that we have a test for signing into Sync + onView(withText(R.string.preferences_account_settings)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) +} + +private fun assertSyncSignInMenuHeader() { + onView(withText(R.string.sign_in_with_camera)) + .check((matches(withEffectiveVisibility(Visibility.VISIBLE)))) +} diff --git a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt index fcfaac7e4..9db6eef94 100644 --- a/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt +++ b/app/src/androidTest/java/org/mozilla/fenix/ui/robots/ThreeDotMenuMainRobot.kt @@ -51,6 +51,7 @@ class ThreeDotMenuMainRobot { fun verifyHistoryButton() = assertHistoryButton() fun verifyBookmarksButton() = assertBookmarksButton() fun verifySyncedTabsButton() = assertSyncedTabsButton() + fun verifySyncSignInButton() = assertSignInToSyncButton() fun verifyHelpButton() = assertHelpButton() fun verifyThreeDotMenuExists() = threeDotMenuRecyclerViewExists() fun verifyForwardButton() = assertForwardButton() @@ -164,6 +165,15 @@ class ThreeDotMenuMainRobot { return SyncedTabsRobot.Transition() } + fun openSyncSignIn(interact: SyncSignInRobot.() -> Unit): SyncSignInRobot.Transition { + onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(swipeDown()) + mDevice.waitNotNull(Until.findObject(By.text("Sign in to sync")), waitingTime) + signInToSyncButton().click() + + SyncSignInRobot().interact() + return SyncSignInRobot.Transition() + } + fun openBookmarks(interact: BookmarksRobot.() -> Unit): BookmarksRobot.Transition { onView(withId(R.id.mozac_browser_menu_recyclerView)).perform(swipeDown()) mDevice.waitNotNull(Until.findObject(By.text("Bookmarks")), waitingTime) @@ -193,11 +203,6 @@ class ThreeDotMenuMainRobot { } fun sharePage(interact: LibrarySubMenusMultipleSelectionToolbarRobot.() -> Unit): LibrarySubMenusMultipleSelectionToolbarRobot.Transition { - var maxSwipes = 3 - while (!shareButton().exists() && maxSwipes != 0) { - threeDotMenuRecyclerView().perform(swipeUp()) - maxSwipes-- - } shareButton().click() LibrarySubMenusMultipleSelectionToolbarRobot().interact() return LibrarySubMenusMultipleSelectionToolbarRobot.Transition() @@ -212,11 +217,6 @@ class ThreeDotMenuMainRobot { } fun goForward(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - var maxSwipes = 3 - while (!forwardButton().exists() && maxSwipes != 0) { - threeDotMenuRecyclerView().perform(swipeUp()) - maxSwipes-- - } forwardButton().click() BrowserRobot().interact() @@ -250,11 +250,6 @@ class ThreeDotMenuMainRobot { } fun refreshPage(interact: BrowserRobot.() -> Unit): BrowserRobot.Transition { - var maxSwipes = 3 - while (!refreshButton().exists() && maxSwipes != 0) { - threeDotMenuRecyclerView().perform(swipeUp()) - maxSwipes-- - } assertRefreshButton() refreshButton().click() @@ -369,6 +364,11 @@ class ThreeDotMenuMainRobot { } fun openSaveToCollection(interact: ThreeDotMenuMainRobot.() -> Unit): ThreeDotMenuMainRobot.Transition { + // Ensure the menu is expanded and fully scrolled to the bottom. + for (i in 0..3) { + threeDotMenuRecyclerView().perform(swipeUp()) + } + mDevice.waitNotNull(Until.findObject(By.text("Save to collection")), waitingTime) saveCollectionButton().click() ThreeDotMenuMainRobot().interact() diff --git a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt index eaf3489f9..205761689 100644 --- a/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt +++ b/app/src/main/java/org/mozilla/fenix/FeatureFlags.kt @@ -37,7 +37,7 @@ object FeatureFlags { /** * Shows new three-dot toolbar menu design. */ - val toolbarMenuFeature = Config.channel.isNightlyOrDebug + const val toolbarMenuFeature = true /** * Enables the tabs tray re-write with Synced Tabs. diff --git a/app/src/main/java/org/mozilla/fenix/components/accounts/FenixAccountManager.kt b/app/src/main/java/org/mozilla/fenix/components/accounts/FenixAccountManager.kt new file mode 100644 index 000000000..fe5397bd1 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/components/accounts/FenixAccountManager.kt @@ -0,0 +1,33 @@ +/* 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.components.accounts + +import android.content.Context +import mozilla.components.service.fxa.manager.FxaAccountManager +import org.mozilla.fenix.ext.components + +/** + * Component which holds a reference to [FxaAccountManager]. Manages account authentication, + * profiles, and profile state observers. + */ +open class FenixAccountManager(context: Context) { + val accountManager = context.components.backgroundServices.accountManager + + val authenticatedAccount + get() = accountManager.authenticatedAccount() != null + + val accountProfileEmail + get() = accountManager.accountProfile()?.email + + /** + * Check if the current account is signed in and authenticated. + */ + fun signedInToFxa(): Boolean { + val account = accountManager.authenticatedAccount() + val needsReauth = accountManager.accountNeedsReauth() + + return account != null && !needsReauth + } +} diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt index fee10c378..8f7fdd0f0 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/BrowserToolbarMenuController.kt @@ -226,10 +226,15 @@ class DefaultBrowserToolbarMenuController( ) } is ToolbarMenu.Item.SyncAccount -> { + val directions = if (item.signedIn) { + BrowserFragmentDirections.actionGlobalAccountSettingsFragment() + } else { + BrowserFragmentDirections.actionGlobalTurnOnSync() + } browserAnimator.captureEngineViewAndDrawStatically { navController.nav( R.id.browserFragment, - BrowserFragmentDirections.actionGlobalAccountSettingsFragment() + directions ) } } diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt index 21ab04666..985644685 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/DefaultToolbarMenu.kt @@ -39,6 +39,7 @@ import org.mozilla.fenix.FeatureFlags.tabsTrayRewrite import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.browsingmode.BrowsingMode +import org.mozilla.fenix.components.accounts.FenixAccountManager import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.Experiments import org.mozilla.fenix.ext.asActivity @@ -74,12 +75,11 @@ open class DefaultToolbarMenu( private val shouldDeleteDataOnQuit = context.settings().shouldDeleteBrowsingDataOnQuit private val shouldUseBottomToolbar = context.settings().shouldUseBottomToolbar + private val accountManager = FenixAccountManager(context) private val selectedSession: TabSessionState? get() = store.state.selectedTab - private val accountManager = context.components.backgroundServices.accountManager - override val menuBuilder by lazy { WebExtensionBrowserMenuBuilder( items = @@ -161,7 +161,7 @@ open class DefaultToolbarMenu( registerForIsBookmarkedUpdates() if (FeatureFlags.toolbarMenuFeature) { - BrowserMenuItemToolbar(listOf(back, forward, share, refresh)) + BrowserMenuItemToolbar(listOf(back, forward, share, refresh), isSticky = true) } else { val bookmark = BrowserMenuItemToolbar.TwoStateButton( primaryImageResource = R.drawable.ic_bookmark_filled, @@ -534,10 +534,10 @@ open class DefaultToolbarMenu( } private fun getSyncItemTitle(): String { - val authenticatedAccount = accountManager.authenticatedAccount() != null - val email = accountManager.accountProfile()?.email + val authenticatedAccount = accountManager.authenticatedAccount + val email = accountManager.accountProfileEmail - return if (authenticatedAccount && email != null) { + return if (authenticatedAccount && !email.isNullOrEmpty()) { email } else { context.getString(R.string.sync_menu_sign_in) @@ -549,7 +549,7 @@ open class DefaultToolbarMenu( R.drawable.ic_synced_tabs, primaryTextColor() ) { - onItemTapped.invoke(ToolbarMenu.Item.SyncAccount) + onItemTapped.invoke(ToolbarMenu.Item.SyncAccount(accountManager.signedInToFxa())) } @VisibleForTesting(otherwise = PRIVATE) diff --git a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt index 7b547e7fe..ec384c188 100644 --- a/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/components/toolbar/ToolbarMenu.kt @@ -23,7 +23,7 @@ interface ToolbarMenu { object InstallPwaToHomeScreen : Item() object AddToHomeScreen : Item() object SyncedTabs : Item() - object SyncAccount : Item() + data class SyncAccount(val signedIn: Boolean) : Item() object AddonsManager : Item() object Quit : Item() object OpenInApp : Item() 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 693c14444..a43261f41 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -89,6 +89,7 @@ import org.mozilla.fenix.GleanMetrics.PerfStartup import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.browser.BrowserAnimator.Companion.getToolbarNavOptions +import org.mozilla.fenix.browser.BrowserFragmentDirections import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.PrivateShortcutCreateManager @@ -792,6 +793,18 @@ class HomeFragment : Fragment() { HomeFragmentDirections.actionGlobalSyncedTabsFragment() ) } + is HomeMenu.Item.SyncAccount -> { + hideOnboardingIfNeeded() + val directions = if (it.signedIn) { + BrowserFragmentDirections.actionGlobalAccountSettingsFragment() + } else { + BrowserFragmentDirections.actionGlobalTurnOnSync() + } + nav( + R.id.homeFragment, + directions + ) + } HomeMenu.Item.Bookmarks -> { hideOnboardingIfNeeded() nav( diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt b/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt index 6d2f6f877..4c22f21d8 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeMenu.kt @@ -24,7 +24,9 @@ import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.OAuthAccount import mozilla.components.support.ktx.android.content.getColorFromAttr import org.mozilla.fenix.FeatureFlags +import org.mozilla.fenix.FeatureFlags.tabsTrayRewrite import org.mozilla.fenix.R +import org.mozilla.fenix.components.accounts.FenixAccountManager import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.Experiments import org.mozilla.fenix.ext.components @@ -47,6 +49,7 @@ class HomeMenu( object Downloads : Item() object Extensions : Item() object SyncTabs : Item() + data class SyncAccount(val signedIn: Boolean) : Item() object WhatsNew : Item() object Help : Item() object Settings : Item() @@ -55,15 +58,14 @@ class HomeMenu( data class DesktopMode(val checked: Boolean) : Item() } - private val primaryTextColor = - ThemeManager.resolveAttribute(R.attr.primaryText, context) + private val primaryTextColor = ThemeManager.resolveAttribute(R.attr.primaryText, context) private val syncDisconnectedColor = ThemeManager.resolveAttribute(R.attr.syncDisconnected, context) private val syncDisconnectedBackgroundColor = context.getColorFromAttr(R.attr.syncDisconnectedBackground) private val shouldUseBottomToolbar = context.settings().shouldUseBottomToolbar - private val accountManager = context.components.backgroundServices.accountManager + private val accountManager = FenixAccountManager(context) // 'Reconnect' and 'Quit' items aren't needed most of the time, so we'll only create the if necessary. private val reconnectToSyncItem by lazy { @@ -92,17 +94,33 @@ class HomeMenu( } } + val syncedTabsItem = BrowserMenuImageText( + context.getString(R.string.synced_tabs), + R.drawable.ic_synced_tabs, + primaryTextColor + ) { + onItemTapped.invoke(Item.SyncTabs) + } + private fun getSyncItemTitle(): String { - val authenticatedAccount = accountManager.authenticatedAccount() != null - val email = accountManager.accountProfile()?.email + val authenticatedAccount = accountManager.authenticatedAccount + val email = accountManager.accountProfileEmail - return if (authenticatedAccount && email != null) { + return if (authenticatedAccount && !email.isNullOrEmpty()) { email } else { context.getString(R.string.sync_menu_sign_in) } } + val syncSignInMenuItem = BrowserMenuImageText( + getSyncItemTitle(), + R.drawable.ic_synced_tabs, + primaryTextColor + ) { + onItemTapped.invoke(Item.SyncAccount(accountManager.signedInToFxa())) + } + private val oldCoreMenuItems by lazy { val whatsNewItem = BrowserMenuHighlightableItem( context.getString(R.string.browser_menu_whats_new), @@ -169,14 +187,6 @@ class HomeMenu( onItemTapped.invoke(Item.Settings) } - val syncedTabsItem = BrowserMenuImageText( - getSyncItemTitle(), - R.drawable.ic_synced_tabs, - primaryTextColor - ) { - onItemTapped.invoke(Item.SyncTabs) - } - val helpItem = BrowserMenuImageText( context.getString(R.string.browser_menu_help), R.drawable.ic_help, @@ -293,14 +303,6 @@ class HomeMenu( onItemTapped.invoke(Item.Extensions) } - val syncSignInItem = BrowserMenuImageText( - context.getString(R.string.library_synced_tabs), - R.drawable.ic_synced_tabs, - primaryTextColor - ) { - onItemTapped.invoke(Item.SyncTabs) - } - val whatsNewItem = BrowserMenuHighlightableItem( context.getString(R.string.browser_menu_whats_new), R.drawable.ic_whats_new, @@ -344,7 +346,7 @@ class HomeMenu( historyItem, downloadsItem, extensionsItem, - syncSignInItem, + if (tabsTrayRewrite) syncSignInMenuItem else syncedTabsItem, accountAuthItem, BrowserMenuDivider(), desktopItem, diff --git a/app/src/test/java/org/mozilla/fenix/components/accounts/FenixAccountManagerTest.kt b/app/src/test/java/org/mozilla/fenix/components/accounts/FenixAccountManagerTest.kt new file mode 100644 index 000000000..d93616bc5 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/components/accounts/FenixAccountManagerTest.kt @@ -0,0 +1,101 @@ +/* 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.components.accounts + +import android.content.Context +import io.mockk.every +import io.mockk.mockk +import mozilla.components.concept.sync.OAuthAccount +import mozilla.components.concept.sync.Profile +import mozilla.components.service.fxa.manager.FxaAccountManager +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mozilla.fenix.ext.components +import org.mozilla.fenix.helpers.FenixRobolectricTestRunner + +@RunWith(FenixRobolectricTestRunner::class) +class FenixAccountManagerTest { + + private lateinit var fenixFxaManager: FenixAccountManager + private lateinit var accountManagerComponent: FxaAccountManager + private lateinit var context: Context + private lateinit var account: OAuthAccount + private lateinit var profile: Profile + + @Before + fun setUp() { + context = mockk(relaxed = true) + account = mockk(relaxed = true) + profile = mockk(relaxed = true) + accountManagerComponent = mockk(relaxed = true) + } + + @Test + fun `GIVEN an account exists THEN fetch the associated email address`() { + every { accountManagerComponent.authenticatedAccount() } returns account + every { accountManagerComponent.accountProfile() } returns profile + every { context.components.backgroundServices.accountManager } returns accountManagerComponent + + fenixFxaManager = FenixAccountManager(context) + + val emailAddress = "firefoxIsFun@test.com" + every { accountManagerComponent.accountProfile()?.email } returns emailAddress + + val result = fenixFxaManager.accountProfileEmail + assertEquals(emailAddress, result) + } + + @Test + fun `GIVEN an account does not exist THEN return null when fetching the associated email address`() { + every { accountManagerComponent.authenticatedAccount() } returns null + every { accountManagerComponent.accountProfile() } returns null + every { context.components.backgroundServices.accountManager } returns accountManagerComponent + + fenixFxaManager = FenixAccountManager(context) + + val result = fenixFxaManager.accountProfileEmail + assertEquals(null, result) + } + + @Test + fun `GIVEN an account is signed in and authenticated THEN check returns true`() { + every { accountManagerComponent.authenticatedAccount() } returns account + every { accountManagerComponent.accountNeedsReauth() } returns false + every { context.components.backgroundServices.accountManager } returns accountManagerComponent + + fenixFxaManager = FenixAccountManager(context) + + val signedIn = fenixFxaManager.signedInToFxa() + assertTrue(signedIn) + } + + @Test + fun `GIVEN an account is signed in and NOT authenticated THEN check returns false`() { + every { accountManagerComponent.authenticatedAccount() } returns account + every { accountManagerComponent.accountNeedsReauth() } returns true + every { context.components.backgroundServices.accountManager } returns accountManagerComponent + + fenixFxaManager = FenixAccountManager(context) + + val signedIn = fenixFxaManager.signedInToFxa() + assertFalse(signedIn) + } + + @Test + fun `GIVEN an account is not signed in THEN check returns false`() { + every { accountManagerComponent.authenticatedAccount() } returns null + every { accountManagerComponent.accountNeedsReauth() } returns true + every { context.components.backgroundServices.accountManager } returns accountManagerComponent + + fenixFxaManager = FenixAccountManager(context) + + val signedIn = fenixFxaManager.signedInToFxa() + assertFalse(signedIn) + } +} diff --git a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt index 118043de8..a60977431 100644 --- a/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/toolbar/DefaultBrowserToolbarMenuControllerTest.kt @@ -572,6 +572,28 @@ class DefaultBrowserToolbarMenuControllerTest { } } + @Test + fun `WHEN sync sign in menu item is pressed AND account is signed out THEN navigate to sync sign in`() = runBlockingTest { + val item = ToolbarMenu.Item.SyncAccount(false) + val directions = BrowserFragmentDirections.actionGlobalTurnOnSync() + + val controller = createController(scope = this, store = browserStore) + controller.handleToolbarItemInteraction(item) + + verify { navController.navigate(directions, null) } + } + + @Test + fun `WHEN sync sign in menu item is pressed AND account is signed in THEN navigate to sync sign in`() = runBlockingTest { + val item = ToolbarMenu.Item.SyncAccount(true) + val directions = BrowserFragmentDirections.actionGlobalAccountSettingsFragment() + + val controller = createController(scope = this, store = browserStore) + controller.handleToolbarItemInteraction(item) + + verify { navController.navigate(directions, null) } + } + private fun createController( scope: CoroutineScope, store: BrowserStore,