Bug 1861459 - Remove BrowsingModeManager usages outside of the Home Screen

fenix/123.0
Matthew Tighe 6 months ago committed by mergify[bot]
parent 476e32470b
commit 9f196caa04

@ -97,6 +97,7 @@ import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.appstate.bindings.BrowserStoreBinding
import org.mozilla.fenix.components.metrics.BreadcrumbsRecorder
import org.mozilla.fenix.components.metrics.GrowthDataWorker
import org.mozilla.fenix.components.metrics.fonts.FontEnumerationWorker
@ -221,14 +222,14 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
private val externalSourceIntentProcessors by lazy {
listOf(
HomeDeepLinkIntentProcessor(this),
HomeDeepLinkIntentProcessor(this, components.appStore),
SpeechProcessingIntentProcessor(this, components.core.store),
AssistIntentProcessor(),
StartSearchIntentProcessor(),
OpenBrowserIntentProcessor(this, ::getIntentSessionId),
OpenSpecificTabIntentProcessor(this),
OpenPasswordManagerIntentProcessor(),
ReEngagementIntentProcessor(this, settings()),
ReEngagementIntentProcessor(this, settings(), components.appStore),
)
}
@ -391,6 +392,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
extensionsProcessDisabledPromptObserver,
serviceWorkerSupport,
webExtensionPromptFeature,
BrowserStoreBinding(components.core.store, components.appStore),
)
if (shouldAddToRecentsScreen(intent)) {

@ -24,7 +24,6 @@ import mozilla.components.feature.addons.AddonManager
import mozilla.components.feature.addons.AddonManagerException
import mozilla.components.feature.addons.ui.translateName
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.databinding.FragmentInstalledAddOnDetailsBinding
import org.mozilla.fenix.ext.components
@ -263,7 +262,7 @@ class InstalledAddonDetailsFragment : Fragment() {
private fun bindReportButton() {
binding.reportAddOn.setOnClickListener {
val shouldCreatePrivateSession = (activity as HomeActivity).browsingModeManager.mode.isPrivate
val shouldCreatePrivateSession = it.context.components.appStore.state.mode.isPrivate
it.context.components.useCases.tabsUseCases.selectOrAddTab(
url = "${BuildConfig.AMO_BASE_URL}/android/feedback/addon/${addon.id}/",
@ -286,7 +285,7 @@ class InstalledAddonDetailsFragment : Fragment() {
val directions = if (addon.installedState?.openOptionsPageInTab == true) {
val components = it.context.components
val shouldCreatePrivateSession =
(activity as HomeActivity).browsingModeManager.mode.isPrivate
components.appStore.state.mode.isPrivate
// If the addon settings page is already open in a tab, select that one
components.useCases.tabsUseCases.selectOrAddTab(

@ -361,11 +361,12 @@ abstract class BaseBrowserFragment :
val readerMenuController = DefaultReaderModeController(
readerViewFeature,
binding.readerViewControlsBar,
isPrivate = activity.browsingModeManager.mode.isPrivate,
isPrivate = requireComponents.appStore.state.mode.isPrivate,
onReaderModeChanged = { activity.finishActionMode() },
)
val browserToolbarController = DefaultBrowserToolbarController(
store = store,
appStore = requireComponents.appStore,
tabsUseCases = requireComponents.useCases.tabsUseCases,
activity = activity,
navController = findNavController(),
@ -379,7 +380,7 @@ abstract class BaseBrowserFragment :
findNavController().nav(
R.id.browserFragment,
BrowserFragmentDirections.actionGlobalTabsTrayFragment(
page = when (activity.browsingModeManager.mode) {
page = when (requireComponents.appStore.state.mode) {
BrowsingMode.Normal -> Page.NormalTabs
BrowsingMode.Private -> Page.PrivateTabs
},
@ -1159,7 +1160,6 @@ abstract class BaseBrowserFragment :
@VisibleForTesting
internal fun observeRestoreComplete(store: BrowserStore, navController: NavController) {
val activity = activity as HomeActivity
consumeFlow(store) { flow ->
flow.map { state -> state.restoreComplete }
.distinctUntilChanged()
@ -1168,7 +1168,7 @@ abstract class BaseBrowserFragment :
// Once tab restoration is complete, if there are no tabs to show in the browser, go home
val tabs =
store.state.getNormalOrPrivateTabs(
activity.browsingModeManager.mode.isPrivate,
requireComponents.appStore.state.mode.isPrivate,
)
if (tabs.isEmpty() || store.state.selectedTabId == null) {
navController.popBackStack(R.id.homeFragment, false)
@ -1214,10 +1214,6 @@ abstract class BaseBrowserFragment :
}
private fun handleTabSelected(selectedTab: TabSessionState) {
if (!this.isRemoving) {
updateThemeForSession(selectedTab)
}
if (browserInitialized) {
view?.let {
fullScreenChanged(false)
@ -1408,15 +1404,6 @@ abstract class BaseBrowserFragment :
}
}
/**
* Set the activity normal/private theme to match the current session.
*/
@VisibleForTesting
internal fun updateThemeForSession(session: SessionState) {
val sessionMode = BrowsingMode.fromBoolean(session.content.private)
(activity as HomeActivity).browsingModeManager.mode = sessionMode
}
@VisibleForTesting
internal fun getCurrentTab(): SessionState? {
return requireComponents.core.store.state.findCustomTabOrSelectedTab(customTabSessionId)

@ -34,7 +34,6 @@ import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.GleanMetrics.ReaderMode
import org.mozilla.fenix.GleanMetrics.Shopping
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.TabCollectionStorage
@ -96,7 +95,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
)
}
val isPrivate = (activity as HomeActivity).browsingModeManager.mode.isPrivate
val isPrivate = components.appStore.state.mode.isPrivate
val leadingAction = if (isPrivate && context.settings().feltPrivateBrowsingEnabled) {
BrowserToolbar.Button(
imageDrawable = AppCompatResources.getDrawable(

@ -32,6 +32,15 @@ import org.mozilla.fenix.wallpapers.Wallpaper
* [Action] implementation related to [AppStore].
*/
sealed class AppAction : Action {
/**
* NOTE: This action is not yet functional and will require https://bugzilla.mozilla.org/show_bug.cgi?id=1845409
* to be resolved. This is part of an ongoing lib-state refactor.
* Open a tab in the browser.
*
* @property mode Which [BrowsingMode] the tab should be opened in.
*/
data class OpenTabInBrowser(val mode: BrowsingMode) : AppAction()
data class UpdateInactiveExpanded(val expanded: Boolean) : AppAction()
/**
@ -265,4 +274,24 @@ sealed class AppAction : Action {
val key: ShoppingState.ProductRecommendationImpressionKey,
) : ShoppingAction()
}
/**
* Actions related to the home screen.
*/
sealed class HomeAction : AppAction() {
/**
* App should be opened to the home screen in [mode].
*/
data class OpenToHome(val mode: BrowsingMode) : HomeAction()
}
/**
* Actions related to Intents.
*/
sealed class IntentAction : AppAction() {
/**
* Private browsing mode should be entered.
*/
object EnterPrivateBrowsing : IntentAction()
}
}

@ -13,6 +13,8 @@ import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.shopping.ShoppingStateReducer
import org.mozilla.fenix.ext.filterOutTab
import org.mozilla.fenix.ext.getFilteredStories
import org.mozilla.fenix.home.HomeReducer
import org.mozilla.fenix.home.intent.IntentReducer
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesSelectedCategory
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
@ -25,6 +27,7 @@ import org.mozilla.fenix.messaging.state.MessagingReducer
internal object AppStoreReducer {
@Suppress("LongMethod")
fun reduce(state: AppState, action: AppAction): AppState = when (action) {
is AppAction.OpenTabInBrowser -> state.copy(mode = action.mode)
is AppAction.UpdateInactiveExpanded ->
state.copy(inactiveTabsExpanded = action.expanded)
is AppAction.UpdateFirstFrameDrawn -> {
@ -239,6 +242,8 @@ internal object AppStoreReducer {
)
is AppAction.ShoppingAction -> ShoppingStateReducer.reduce(state, action)
is AppAction.HomeAction -> HomeReducer.reduce(state, action)
is AppAction.IntentAction -> IntentReducer.reduce(state, action)
}
}

@ -2,7 +2,7 @@
* 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.bindings
package org.mozilla.fenix.components.appstate.bindings
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collectLatest

@ -25,6 +25,8 @@ 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.browser.readermode.ReaderModeController
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.toolbar.interactor.BrowserToolbarInteractor
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav
@ -76,6 +78,7 @@ private const val MAX_DISPLAY_NUMBER_SHOPPING_CFR = 3
@Suppress("LongParameterList")
class DefaultBrowserToolbarController(
private val store: BrowserStore,
private val appStore: AppStore,
private val tabsUseCases: TabsUseCases,
private val activity: HomeActivity,
private val navController: NavController,
@ -175,13 +178,13 @@ class DefaultBrowserToolbarController(
}
}
is TabCounterMenu.Item.NewTab -> {
activity.browsingModeManager.mode = BrowsingMode.Normal
appStore.dispatch(AppAction.HomeAction.OpenToHome(BrowsingMode.Normal))
navController.navigate(
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true),
)
}
is TabCounterMenu.Item.NewPrivateTab -> {
activity.browsingModeManager.mode = BrowsingMode.Private
appStore.dispatch(AppAction.HomeAction.OpenToHome(BrowsingMode.Private))
navController.navigate(
BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true),
)

@ -562,9 +562,13 @@ class HomeFragment : Fragment() {
tabCounterView = TabCounterView(
context = requireContext(),
browsingModeManager = browsingModeManager,
navController = findNavController(),
tabCounter = binding.tabButton,
mode = requireComponents.appStore.state.mode,
itemTapped = {
newMode ->
requireComponents.appStore.dispatch(AppAction.HomeAction.OpenToHome(newMode))
},
)
toolbarView?.build()

@ -0,0 +1,21 @@
/* 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.home
import org.mozilla.fenix.components.appstate.AppAction.HomeAction
import org.mozilla.fenix.components.appstate.AppState
/**
* Reducer to handle updating [AppState] with the result of an [HomeAction].
*/
object HomeReducer {
/**
* Reducer to handle updating [AppState] with the result of an [HomeAction].
*/
fun reduce(state: AppState, action: HomeAction): AppState = when (action) {
is HomeAction.OpenToHome -> state.copy(mode = action.mode)
}
}

@ -17,7 +17,6 @@ import org.mozilla.fenix.GleanMetrics.StartOnHome
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.toolbar.FenixTabCounterMenu
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.settings
@ -27,22 +26,24 @@ import org.mozilla.fenix.tabstray.Page
* Helper class for building the [FenixTabCounterMenu].
*
* @param context An Android [Context].
* @param browsingModeManager [BrowsingModeManager] used for fetching the current browsing mode.
* @param navController [NavController] used for navigation.
* @param tabCounter The [TabCounter] that will be setup with event handlers.
* @param mode The current [BrowsingMode].
* @param itemTapped Callback to update the [BrowsingMode].
*/
class TabCounterView(
private val context: Context,
private val browsingModeManager: BrowsingModeManager,
private val navController: NavController,
private val tabCounter: TabCounter,
private val mode: BrowsingMode,
private val itemTapped: (BrowsingMode) -> Unit,
) {
init {
val tabCounterMenu = FenixTabCounterMenu(
context = context,
onItemTapped = ::onItemTapped,
iconColor = if (browsingModeManager.mode == BrowsingMode.Private) {
iconColor = if (mode == BrowsingMode.Private) {
ContextCompat.getColor(context, R.color.fx_mobile_private_text_color_primary)
} else {
null
@ -50,7 +51,7 @@ class TabCounterView(
)
tabCounterMenu.updateMenu(
showOnly = when (browsingModeManager.mode) {
showOnly = when (mode) {
BrowsingMode.Normal -> BrowsingMode.Private
BrowsingMode.Private -> BrowsingMode.Normal
},
@ -67,7 +68,7 @@ class TabCounterView(
navController.nav(
navController.currentDestination?.id,
NavGraphDirections.actionGlobalTabsTrayFragment(
page = when (browsingModeManager.mode) {
page = when (mode) {
BrowsingMode.Normal -> Page.NormalTabs
BrowsingMode.Private -> Page.PrivateTabs
},
@ -83,7 +84,7 @@ class TabCounterView(
* browsing mode.
*/
fun update(browserState: BrowserState) {
val isPrivate = browsingModeManager.mode.isPrivate
val isPrivate = mode.isPrivate
val tabCount = if (isPrivate) {
browserState.privateTabs.size
} else {
@ -102,9 +103,9 @@ class TabCounterView(
*/
internal fun onItemTapped(item: TabCounterMenu.Item) {
if (item is TabCounterMenu.Item.NewTab) {
browsingModeManager.mode = BrowsingMode.Normal
itemTapped(BrowsingMode.Normal)
} else if (item is TabCounterMenu.Item.NewPrivateTab) {
browsingModeManager.mode = BrowsingMode.Private
itemTapped(BrowsingMode.Private)
}
}
}

@ -17,7 +17,8 @@ import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.GlobalDirections
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.ext.alreadyOnDestination
import org.mozilla.fenix.ext.openSetDefaultBrowserOption
@ -26,6 +27,7 @@ import org.mozilla.fenix.ext.openSetDefaultBrowserOption
*/
class HomeDeepLinkIntentProcessor(
private val activity: HomeActivity,
private val appStore: AppStore,
) : HomeIntentProcessor {
private val logger = Logger("DeepLinkIntentProcessor")
@ -76,7 +78,7 @@ class HomeDeepLinkIntentProcessor(
private fun handleDeepLinkSideEffects(deepLink: Uri) {
when (deepLink.host) {
"enable_private_browsing" -> {
activity.browsingModeManager.mode = BrowsingMode.Private
appStore.dispatch(AppAction.IntentAction.EnterPrivateBrowsing)
}
"make_default_browser" -> {
activity.openSetDefaultBrowserOption(

@ -0,0 +1,22 @@
/* 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.home.intent
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.appstate.AppAction.IntentAction
import org.mozilla.fenix.components.appstate.AppState
/**
* Reducer to handle updating [AppState] with the result of an [IntentAction].
*/
object IntentReducer {
/**
* Reducer to handle updating [AppState] with the result of an [IntentAction].
*/
fun reduce(state: AppState, action: IntentAction): AppState = when (action) {
is IntentAction.EnterPrivateBrowsing -> state.copy(mode = BrowsingMode.Private)
}
}

@ -15,6 +15,8 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.onboarding.ReEngagementNotificationWorker
import org.mozilla.fenix.onboarding.ReEngagementNotificationWorker.Companion.isReEngagementNotificationIntent
@ -30,6 +32,7 @@ import org.mozilla.fenix.utils.Settings
class ReEngagementIntentProcessor(
private val activity: HomeActivity,
private val settings: Settings,
private val appStore: AppStore,
) : HomeIntentProcessor {
override fun process(intent: Intent, navController: NavController, out: Intent): Boolean {
@ -46,7 +49,7 @@ class ReEngagementIntentProcessor(
navController.nav(null, directions, options)
}
else -> {
activity.browsingModeManager.mode = BrowsingMode.Private
appStore.dispatch(AppAction.OpenTabInBrowser(BrowsingMode.Private))
activity.openToBrowserAndLoad(
ReEngagementNotificationWorker.NOTIFICATION_TARGET_URL,
newTab = true,

@ -276,7 +276,7 @@ class DefaultSessionControlController(
TopSites.openInPrivateTab.record(NoExtras())
}
with(activity) {
browsingModeManager.mode = BrowsingMode.Private
appStore.dispatch(AppAction.ModeChange(BrowsingMode.Private))
openToBrowserAndLoad(
searchTermOrURL = topSite.url,
newTab = true,
@ -464,7 +464,7 @@ class DefaultSessionControlController(
}
override fun handleShowWallpapersOnboardingDialog(state: WallpaperState): Boolean {
return if (activity.browsingModeManager.mode.isPrivate) {
return if (appStore.state.mode.isPrivate) {
false
} else {
state.availableWallpapers.filter { wallpaper ->
@ -504,7 +504,7 @@ class DefaultSessionControlController(
registerCollectionStorageObserver()
val tabIds = store.state
.getNormalOrPrivateTabs(private = activity.browsingModeManager.mode.isPrivate)
.getNormalOrPrivateTabs(private = appStore.state.mode.isPrivate)
.map { session -> session.id }
.toList()
.toTypedArray()

@ -8,9 +8,7 @@ import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import mozilla.components.support.ktx.android.content.getColorFromAttr
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.setToolbarColors
@ -32,8 +30,6 @@ abstract class LibraryPageFragment<T> : Fragment() {
tabsUseCases.addTab.invoke(url, private = private)
}
}
(activity as HomeActivity).browsingModeManager.mode = BrowsingMode.fromBoolean(private)
}
override fun onDetach() {

@ -24,6 +24,7 @@ import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.ext.bookmarkStorage
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav
@ -77,6 +78,7 @@ class DefaultBookmarkController(
private val clipboardManager: ClipboardManager?,
private val scope: CoroutineScope,
private val store: BookmarkFragmentStore,
private val appStore: AppStore,
private val sharedViewModel: BookmarksSharedViewModel,
private val tabsUseCases: TabsUseCases?,
private val loadBookmarkNode: suspend (String, Boolean) -> BookmarkNode?,
@ -97,13 +99,12 @@ class DefaultBookmarkController(
override fun handleBookmarkTapped(item: BookmarkNode) {
val fromHomeFragment =
navController.previousBackStackEntry?.destination?.id == R.id.homeFragment
val isPrivate = activity.browsingModeManager.mode == BrowsingMode.Private
val isPrivate = appStore.state.mode == BrowsingMode.Private
val flags = EngineSession.LoadUrlFlags.select(EngineSession.LoadUrlFlags.ALLOW_JAVASCRIPT_URL)
openInNewTabAndShow(
item.url!!,
isPrivate || fromHomeFragment,
BrowserDirection.FromBookmarks,
activity.browsingModeManager.mode,
flags,
)
}
@ -195,8 +196,6 @@ class DefaultBookmarkController(
startLoading = load,
)
}
activity.browsingModeManager.mode =
BrowsingMode.fromBoolean(mode == BrowsingMode.Private)
showTabTray(mode.isPrivate)
}
@ -264,20 +263,15 @@ class DefaultBookmarkController(
searchTermOrURL: String,
newTab: Boolean,
from: BrowserDirection,
mode: BrowsingMode,
flags: EngineSession.LoadUrlFlags = EngineSession.LoadUrlFlags.none(),
) {
with(activity) {
browsingModeManager.mode = mode
openToBrowserAndLoad(searchTermOrURL, newTab, from, flags = flags)
}
activity.openToBrowserAndLoad(searchTermOrURL, newTab, from, flags = flags)
}
private fun openInNewTab(
url: String,
mode: BrowsingMode,
) {
activity.browsingModeManager.mode = BrowsingMode.fromBoolean(mode == BrowsingMode.Private)
tabsUseCases?.addTab?.invoke(url, private = (mode == BrowsingMode.Private))
}

@ -99,6 +99,7 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
clipboardManager = requireContext().getSystemService(),
scope = viewLifecycleOwner.lifecycleScope,
store = bookmarkStore,
appStore = requireComponents.appStore,
sharedViewModel = sharedViewModel,
tabsUseCases = activity?.components?.useCases?.tabsUseCases,
loadBookmarkNode = ::loadBookmarkNode,

@ -4,10 +4,11 @@
package org.mozilla.fenix.library.downloads
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
interface DownloadController {
fun handleOpen(item: DownloadItem, mode: BrowsingMode? = null)
/**
* Handle opening a [DownloadItem].
*/
fun handleOpen(item: DownloadItem)
fun handleSelect(item: DownloadItem)
fun handleDeselect(item: DownloadItem)
fun handleBackPressed(): Boolean
@ -17,12 +18,12 @@ interface DownloadController {
class DefaultDownloadController(
private val store: DownloadFragmentStore,
private val openToFileManager: (item: DownloadItem, mode: BrowsingMode?) -> Unit,
private val openToFileManager: (item: DownloadItem) -> Unit,
private val invalidateOptionsMenu: () -> Unit,
private val deleteDownloadItems: (Set<DownloadItem>) -> Unit,
) : DownloadController {
override fun handleOpen(item: DownloadItem, mode: BrowsingMode?) {
openToFileManager(item, mode)
override fun handleOpen(item: DownloadItem) {
openToFileManager(item)
}
override fun handleSelect(item: DownloadItem) {

@ -26,11 +26,10 @@ import mozilla.components.browser.state.state.content.DownloadState
import mozilla.components.feature.downloads.AbstractFetchDownloadService
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.UserInteractionHandler
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.components
import org.mozilla.fenix.databinding.FragmentDownloadsBinding
import org.mozilla.fenix.downloads.DynamicDownloadDialog
import org.mozilla.fenix.ext.components
@ -211,8 +210,7 @@ class DownloadFragment : LibraryPageFragment<DownloadItem>(), UserInteractionHan
return downloadView.onBackPressed()
}
private fun openItem(item: DownloadItem, mode: BrowsingMode? = null) {
mode?.let { (activity as HomeActivity).browsingModeManager.mode = it }
private fun openItem(item: DownloadItem) {
context?.let {
val contentLength = if (item.size.isNotEmpty()) {
item.size.toLong()

@ -317,10 +317,7 @@ class HistoryFragment : LibraryPageFragment<History>(), UserInteractionHandler,
(selectedItem as? History.Regular)?.url ?: (selectedItem as? History.Metadata)?.url
}
(activity as HomeActivity).apply {
browsingModeManager.mode = BrowsingMode.Private
supportActionBar?.hide()
}
(activity as HomeActivity).supportActionBar?.hide()
showTabTray(openInPrivate = true)
historyStore.dispatch(HistoryFragmentAction.ExitEditMode)
@ -388,7 +385,7 @@ class HistoryFragment : LibraryPageFragment<History>(), UserInteractionHandler,
GleanHistory.OpenedItemExtra(
isRemote = item.isRemote,
timeGroup = item.historyTimeGroup.toString(),
isPrivate = (activity as HomeActivity).browsingModeManager.mode == BrowsingMode.Private,
isPrivate = requireComponents.appStore.state.mode == BrowsingMode.Private,
),
)

@ -32,7 +32,6 @@ import mozilla.components.ui.widgets.withCenterAlignedButtons
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.addons.showSnackBar
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.databinding.FragmentHistoryMetadataGroupBinding
import org.mozilla.fenix.ext.components
@ -188,10 +187,7 @@ class HistoryMetadataGroupFragment :
selectedItem.url
}
(activity as HomeActivity).apply {
browsingModeManager.mode = BrowsingMode.Private
supportActionBar?.hide()
}
(activity as HomeActivity).supportActionBar?.hide()
showTabTray(openInPrivate = true)
true

@ -29,6 +29,7 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.databinding.FragmentRecentlyClosedTabsBinding
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.setTextColor
@ -138,7 +139,7 @@ class RecentlyClosedFragment :
}
private fun openItem(url: String, mode: BrowsingMode? = null) {
mode?.let { (activity as HomeActivity).browsingModeManager.mode = it }
mode?.let { requireComponents.appStore.dispatch(AppAction.OpenTabInBrowser(it)) }
(activity as HomeActivity).openToBrowserAndLoad(
searchTermOrURL = url,

@ -25,6 +25,7 @@ import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.GleanMetrics.UnifiedSearch
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.Core
import org.mozilla.fenix.components.metrics.MetricsUtils
import org.mozilla.fenix.crashes.CrashListActivity
@ -64,6 +65,7 @@ interface SearchController {
class SearchDialogController(
private val activity: HomeActivity,
private val store: BrowserStore,
private val appStore: AppStore,
private val tabsUseCases: TabsUseCases,
private val fragmentStore: SearchFragmentStore,
private val navController: NavController,
@ -167,7 +169,7 @@ class SearchDialogController(
fragmentStore.dispatch(
SearchFragmentAction.AllowSearchSuggestionsInPrivateModePrompt(
text.isNotEmpty() &&
activity.browsingModeManager.mode.isPrivate &&
appStore.state.mode.isPrivate &&
settings.shouldShowSearchSuggestions &&
!settings.shouldShowSearchSuggestionsInPrivate &&
!settings.showSearchSuggestionsInPrivateOnboardingFinished,
@ -246,7 +248,7 @@ class SearchDialogController(
fragmentStore.dispatch(
SearchFragmentAction.SearchDefaultEngineSelected(
engine = searchEngine,
browsingMode = activity.browsingModeManager.mode,
browsingMode = appStore.state.mode,
settings = settings,
),
)
@ -255,7 +257,7 @@ class SearchDialogController(
fragmentStore.dispatch(
SearchFragmentAction.SearchShortcutEngineSelected(
engine = searchEngine,
browsingMode = activity.browsingModeManager.mode,
browsingMode = appStore.state.mode,
settings = settings,
),
)

@ -177,7 +177,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
this@SearchDialogFragment.onBackPressed()
}
}.apply {
if ((requireActivity() as HomeActivity).browsingModeManager.mode.isPrivate) {
if (requireComponents.appStore.state.mode.isPrivate) {
this.secure(requireActivity())
}
}
@ -193,11 +193,10 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
val args by navArgs<SearchDialogFragmentArgs>()
_binding = FragmentSearchDialogBinding.inflate(inflater, container, false)
val activity = requireActivity() as HomeActivity
val isPrivate = activity.browsingModeManager.mode.isPrivate
val isPrivate = requireComponents.appStore.state.mode.isPrivate
store = SearchDialogFragmentStore(
createInitialSearchFragmentState(
activity,
requireComponents,
tabId = args.sessionId,
pastedText = args.pastedText,
@ -212,6 +211,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
SearchDialogController(
activity = activity,
store = requireComponents.core.store,
appStore = requireComponents.appStore,
tabsUseCases = requireComponents.useCases.tabsUseCases,
fragmentStore = store,
navController = findNavController(),
@ -904,7 +904,7 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
} else {
val clipboardUrl = context?.components?.clipboardHandler?.extractURL()
if (clipboardUrl != null && !((activity as HomeActivity).browsingModeManager.mode.isPrivate)) {
if (clipboardUrl != null && !(requireComponents.appStore.state.mode.isPrivate)) {
requireComponents.core.engine.speculativeConnect(clipboardUrl)
}
binding.clipboardUrl.text = clipboardUrl

@ -13,7 +13,6 @@ import mozilla.components.browser.state.state.selectedOrDefaultSearchEngine
import mozilla.components.lib.state.Action
import mozilla.components.lib.state.State
import mozilla.components.lib.state.Store
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.components.metrics.MetricsUtils
@ -143,7 +142,6 @@ data class SearchFragmentState(
*/
@Suppress("LongParameterList")
fun createInitialSearchFragmentState(
activity: HomeActivity,
components: Components,
tabId: String?,
pastedText: String?,
@ -167,7 +165,7 @@ fun createInitialSearchFragmentState(
searchEngineSource = searchEngineSource,
defaultEngine = null,
showSearchSuggestions = shouldShowSearchSuggestions(
browsingMode = activity.browsingModeManager.mode,
browsingMode = components.appStore.state.mode,
settings = settings,
),
showSearchSuggestionsHint = false,
@ -184,9 +182,9 @@ fun createInitialSearchFragmentState(
showAllSyncedTabsSuggestions = settings.shouldShowSyncedTabsSuggestions,
showSessionSuggestionsForCurrentEngine = false,
showAllSessionSuggestions = true,
showSponsoredSuggestions = activity.browsingModeManager.mode == BrowsingMode.Normal &&
showSponsoredSuggestions = components.appStore.state.mode == BrowsingMode.Normal &&
settings.enableFxSuggest && settings.showSponsoredSuggestions,
showNonSponsoredSuggestions = activity.browsingModeManager.mode == BrowsingMode.Normal &&
showNonSponsoredSuggestions = components.appStore.state.mode == BrowsingMode.Normal &&
settings.enableFxSuggest && settings.showNonSponsoredSuggestions,
tabId = tabId,
pastedText = pastedText,

@ -117,7 +117,7 @@ class AwesomeBarView(
init {
val primaryTextColor = activity.getColorFromAttr(R.attr.textPrimary)
engineForSpeculativeConnects = when (activity.browsingModeManager.mode) {
engineForSpeculativeConnects = when (components.appStore.state.mode) {
BrowsingMode.Normal -> components.core.engine
BrowsingMode.Private -> null
}
@ -162,7 +162,7 @@ class AwesomeBarView(
showDescription = false,
engine = engineForSpeculativeConnects,
filterExactMatch = true,
private = when (activity.browsingModeManager.mode) {
private = when (components.appStore.state.mode) {
BrowsingMode.Normal -> false
BrowsingMode.Private -> true
},
@ -328,12 +328,12 @@ class AwesomeBarView(
}
}
if (activity.browsingModeManager.mode == BrowsingMode.Normal && state.showAllSessionSuggestions) {
if (components.appStore.state.mode == BrowsingMode.Normal && state.showAllSessionSuggestions) {
// Unlike other providers, we don't exclude sponsored suggestions for open tabs.
providersToAdd.add(getLocalTabsProvider())
}
if (activity.browsingModeManager.mode == BrowsingMode.Normal && state.showSessionSuggestionsForCurrentEngine) {
if (components.appStore.state.mode == BrowsingMode.Normal && state.showSessionSuggestionsForCurrentEngine) {
getFilterForCurrentEngineResults(state)?.let {
providersToAdd.add(getLocalTabsProvider(it))
}
@ -448,7 +448,7 @@ class AwesomeBarView(
colorFilter = createBlendModeColorFilterCompat(primaryTextColor, SRC_IN)
}.toBitmap()
val engineForSpeculativeConnects = when (activity.browsingModeManager.mode) {
val engineForSpeculativeConnects = when (components.appStore.state.mode) {
BrowsingMode.Normal -> components.core.engine
BrowsingMode.Private -> null
}
@ -469,7 +469,7 @@ class AwesomeBarView(
icon = searchBitmap,
engine = engineForSpeculativeConnects,
filterExactMatch = true,
private = when (activity.browsingModeManager.mode) {
private = when (components.appStore.state.mode) {
BrowsingMode.Normal -> false
BrowsingMode.Private -> true
},

@ -9,9 +9,9 @@ import android.view.WindowManager
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.PrivateShortcutCreateManager
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -45,9 +45,7 @@ class PrivateBrowsingFragment : PreferenceFragmentCompat() {
requirePreference<SwitchPreference>(R.string.pref_key_allow_screenshots_in_private_mode).apply {
onPreferenceChangeListener = object : SharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
if ((activity as? HomeActivity)?.browsingModeManager?.mode?.isPrivate == true &&
newValue == false
) {
if (requireComponents.appStore.state.mode.isPrivate && newValue == false) {
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
} else {
activity?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)

@ -23,6 +23,7 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -109,7 +110,9 @@ class WallpaperSettingsFragment : Fragment() {
)
.setText(view.context.getString(R.string.wallpaper_updated_snackbar_message))
.setAction(requireContext().getString(R.string.wallpaper_updated_snackbar_action)) {
(activity as HomeActivity).browsingModeManager.mode = BrowsingMode.Normal
requireComponents.appStore.dispatch(
AppAction.HomeAction.OpenToHome(BrowsingMode.Normal),
)
findNavController().navigate(R.id.homeFragment)
}
.show()

@ -9,7 +9,7 @@ import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.tabs.TabLayout
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.support.base.feature.LifecycleAwareFeature
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.tabstray.TrayPagerAdapter.Companion.POSITION_NORMAL_TABS
import org.mozilla.fenix.tabstray.TrayPagerAdapter.Companion.POSITION_PRIVATE_TABS
import org.mozilla.fenix.tabstray.TrayPagerAdapter.Companion.POSITION_SYNCED_TABS
@ -22,7 +22,7 @@ class TabLayoutMediator(
private val tabLayout: TabLayout,
private val tabPager: ViewPager2,
interactor: TabsTrayInteractor,
private val browsingModeManager: BrowsingModeManager,
private val appStore: AppStore,
private val tabsTrayStore: TabsTrayStore,
) : LifecycleAwareFeature {
@ -45,7 +45,7 @@ class TabLayoutMediator(
internal fun selectActivePage() {
val selectedPagerPosition =
when {
browsingModeManager.mode.isPrivate -> POSITION_PRIVATE_TABS
appStore.state.mode.isPrivate -> POSITION_PRIVATE_TABS
tabsTrayStore.state.selectedPage == Page.SyncedTabs -> POSITION_SYNCED_TABS
else -> POSITION_NORMAL_TABS
}

@ -32,7 +32,6 @@ import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.collections.CollectionsDialog
import org.mozilla.fenix.collections.show
import org.mozilla.fenix.components.AppStore
@ -178,7 +177,6 @@ interface TabsTrayController : SyncedTabsController, InactiveTabsController, Tab
* @param tabsTrayStore [TabsTrayStore] used to read/update the [TabsTrayState].
* @param browserStore [BrowserStore] used to read/update the current [BrowserState].
* @param settings [Settings] used to update any user preferences.
* @param browsingModeManager [BrowsingModeManager] used to read/update the current [BrowsingMode].
* @param navController [NavController] used to navigate away from the tabs tray.
* @param navigateToHomeAndDeleteSession Lambda used to return to the Homescreen and delete the current session.
* @param profiler [Profiler] used to add profiler markers.
@ -203,7 +201,6 @@ class DefaultTabsTrayController(
private val tabsTrayStore: TabsTrayStore,
private val browserStore: BrowserStore,
private val settings: Settings,
private val browsingModeManager: BrowsingModeManager,
private val navController: NavController,
private val navigateToHomeAndDeleteSession: (String) -> Unit,
private val profiler: Profiler?,
@ -245,7 +242,7 @@ class DefaultTabsTrayController(
*/
private fun openNewTab(isPrivate: Boolean) {
val startTime = profiler?.getProfilerTime()
browsingModeManager.mode = BrowsingMode.fromBoolean(isPrivate)
appStore.dispatch(AppAction.HomeAction.OpenToHome(BrowsingMode.fromBoolean(isPrivate)))
navController.navigate(
TabsTrayFragmentDirections.actionGlobalHome(focusOnAddressBar = true),
)
@ -536,7 +533,6 @@ class DefaultTabsTrayController(
selected.isEmpty() && tabsTrayStore.state.mode.isSelect().not() -> {
TabsTray.openedExistingTab.record(TabsTray.OpenedExistingTabExtra(source ?: "unknown"))
tabsUseCases.selectTab(tab.id)
browsingModeManager.mode = BrowsingMode.fromBoolean(tab.content.private)
handleNavigateToBrowser()
}
tab.id in selected.map { it.id } -> handleTabUnselected(tab)

@ -175,7 +175,6 @@ class TabsTrayFragment : AppCompatDialogFragment() {
tabsTrayStore = tabsTrayStore,
browserStore = requireComponents.core.store,
settings = requireContext().settings(),
browsingModeManager = activity.browsingModeManager,
navController = findNavController(),
navigateToHomeAndDeleteSession = ::navigateToHomeAndDeleteSession,
navigationInteractor = navigationInteractor,
@ -410,8 +409,6 @@ class TabsTrayFragment : AppCompatDialogFragment() {
}
if (!requireContext().settings().enableTabsTrayToCompose) {
val activity = activity as HomeActivity
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
fabButtonBinding.newTabButton.accessibilityTraversalAfter =
tabsTrayBinding.tabLayout.id
@ -442,7 +439,7 @@ class TabsTrayFragment : AppCompatDialogFragment() {
tabLayout = tabsTrayBinding.tabLayout,
tabPager = tabsTrayBinding.tabsTray,
interactor = tabsTrayInteractor,
browsingModeManager = activity.browsingModeManager,
appStore = requireComponents.appStore,
tabsTrayStore = tabsTrayStore,
),
owner = this,

@ -8,6 +8,7 @@ import android.app.Activity
import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
import android.net.Uri
import androidx.core.text.isDigitsOnly
import io.mockk.Runs
import io.mockk.coEvery
import io.mockk.coVerify
@ -59,6 +60,7 @@ class IntentReceiverActivityTest {
mockkStatic("org.mozilla.fenix.ext.ContextKt")
settings = mockk()
intentProcessors = mockk()
"".isDigitsOnly()
every { settings.openLinksInAPrivateTab } returns false
every { intentProcessors.intentProcessor } returns mockIntentProcessor()

@ -24,6 +24,7 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.databinding.FragmentInstalledAddOnDetailsBinding
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -158,6 +159,7 @@ class InstalledAddonDetailsFragmentTest {
every { selectOrAddTab.invoke(any(), any(), any(), any(), any()) } returns "some-tab-id"
every { useCases.selectOrAddTab } returns selectOrAddTab
every { testContext.components.useCases.tabsUseCases } returns useCases
every { testContext.components.appStore.state.mode } returns BrowsingMode.Normal
// We create the `binding` instance and bind the UI here because `onCreateView()` checks a late init variable
// and we cannot easily mock it to skip the check.
fragment.setBindingAndBindUI(
@ -192,21 +194,22 @@ class InstalledAddonDetailsFragmentTest {
val addon = mockAddon()
every { fragment.addon } returns addon
val homeActivity = mockk<HomeActivity>(relaxed = true)
every { homeActivity.browsingModeManager.mode.isPrivate } returns true
every { fragment.activity } returns homeActivity
val useCases = mockk<TabsUseCases>()
val selectOrAddTab = mockk<TabsUseCases.SelectOrAddUseCase>()
every { selectOrAddTab.invoke(any(), any(), any(), any(), any()) } returns "some-tab-id"
every { useCases.selectOrAddTab } returns selectOrAddTab
every { testContext.components.useCases.tabsUseCases } returns useCases
every { testContext.components.appStore.state.mode } returns BrowsingMode.Private
// We create the `binding` instance and bind the UI here because `onCreateView()` checks a late init variable
// and we cannot easily mock it to skip the check.
val binding = FragmentInstalledAddOnDetailsBinding.inflate(
LayoutInflater.from(testContext),
mockk(relaxed = true),
false,
)
fragment.setBindingAndBindUI(
FragmentInstalledAddOnDetailsBinding.inflate(
LayoutInflater.from(testContext),
mockk(relaxed = true),
false,
),
binding,
)
val navController = mockk<NavController>(relaxed = true)
Navigation.setViewNavController(fragment.binding.root, navController)

@ -11,11 +11,11 @@ import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.components.appstate.bindings.BrowserStoreBinding
class BrowserStoreBindingTest {

@ -40,6 +40,7 @@ import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.FenixApplication
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.toolbar.BrowserToolbarView
import org.mozilla.fenix.components.toolbar.ToolbarIntegration
import org.mozilla.fenix.ext.application
@ -54,6 +55,7 @@ import org.mozilla.fenix.utils.Settings
class BrowserFragmentTest {
private lateinit var store: BrowserStore
private lateinit var appStore: AppStore
private lateinit var testTab: TabSessionState
private lateinit var browserFragment: BrowserFragment
private lateinit var view: View
@ -95,6 +97,8 @@ class BrowserFragmentTest {
testTab = createTab(url = "https://mozilla.org")
store = BrowserStore()
every { context.components.core.store } returns store
appStore = AppStore()
every { context.components.appStore } returns appStore
mockkObject(FeatureFlags)
}
@ -104,24 +108,6 @@ class BrowserFragmentTest {
unmockkObject(FeatureFlags)
}
@Test
fun `GIVEN fragment is added WHEN selected tab changes THEN theme is updated`() {
browserFragment.observeTabSelection(store)
verify(exactly = 0) { browserFragment.updateThemeForSession(testTab) }
addAndSelectTab(testTab)
verify(exactly = 1) { browserFragment.updateThemeForSession(testTab) }
}
@Test
fun `GIVEN fragment is removing WHEN selected tab changes THEN theme is not updated`() {
every { browserFragment.isRemoving } returns true
browserFragment.observeTabSelection(store)
addAndSelectTab(testTab)
verify(exactly = 0) { browserFragment.updateThemeForSession(testTab) }
}
@Test
fun `GIVEN browser UI is not initialized WHEN selected tab changes THEN browser UI is initialized`() {
browserFragment.observeTabSelection(store)

@ -20,6 +20,7 @@ import mozilla.components.service.pocket.PocketStory
import mozilla.components.service.pocket.PocketStory.PocketRecommendedStory
import mozilla.components.service.pocket.PocketStory.PocketSponsoredStory
import mozilla.components.service.pocket.PocketStory.PocketSponsoredStoryCaps
import mozilla.components.support.test.ext.joinBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertSame
@ -538,4 +539,22 @@ class AppStoreTest {
assertEquals(recentHistory - group2, recentHistory.filterOut("Title2"))
assertEquals(recentHistory - group3, recentHistory.filterOut("title3"))
}
@Test
fun `WHEN new tab clicked THEN mode is updated to normal`() {
appStore = AppStore(AppState(mode = BrowsingMode.Private))
appStore.dispatch(AppAction.HomeAction.OpenToHome(BrowsingMode.Normal)).joinBlocking()
assertEquals(BrowsingMode.Normal, appStore.state.mode)
}
@Test
fun `WHEN new private tab clicked THEN mode is updated to private`() {
appStore = AppStore(AppState(mode = BrowsingMode.Normal))
appStore.dispatch(AppAction.HomeAction.OpenToHome(BrowsingMode.Private)).joinBlocking()
assertEquals(BrowsingMode.Private, appStore.state.mode)
}
}

@ -48,8 +48,9 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.browser.BrowserAnimator
import org.mozilla.fenix.browser.BrowserFragmentDirections
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.SimpleBrowsingModeManager
import org.mozilla.fenix.browser.readermode.ReaderModeController
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -92,6 +93,7 @@ class DefaultBrowserToolbarControllerTest {
@RelaxedMockK
private lateinit var homeViewModel: HomeScreenViewModel
private lateinit var appStore: AppStore
private lateinit var store: BrowserStore
private val captureMiddleware = CaptureActionsMiddleware<BrowserState, BrowserAction>()
@ -126,6 +128,7 @@ class DefaultBrowserToolbarControllerTest {
),
middleware = listOf(captureMiddleware),
)
appStore = AppStore()
}
@After
@ -313,29 +316,31 @@ class DefaultBrowserToolbarControllerTest {
@Test
fun handleToolbarNewTabPress() {
val browsingModeManager = SimpleBrowsingModeManager(BrowsingMode.Private)
appStore = AppStore(AppState(mode = BrowsingMode.Private))
val item = TabCounterMenu.Item.NewTab
every { activity.browsingModeManager } returns browsingModeManager
every { navController.navigate(BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)) } just Runs
val controller = createController()
controller.handleTabCounterItemInteraction(item)
assertEquals(BrowsingMode.Normal, browsingModeManager.mode)
appStore.waitUntilIdle()
assertEquals(BrowsingMode.Normal, appStore.state.mode)
verify { navController.navigate(BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)) }
}
@Test
fun handleToolbarNewPrivateTabPress() {
val browsingModeManager = SimpleBrowsingModeManager(BrowsingMode.Normal)
appStore = AppStore(AppState(mode = BrowsingMode.Normal))
val item = TabCounterMenu.Item.NewPrivateTab
every { activity.browsingModeManager } returns browsingModeManager
every { navController.navigate(BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)) } just Runs
val controller = createController()
controller.handleTabCounterItemInteraction(item)
assertEquals(BrowsingMode.Private, browsingModeManager.mode)
appStore.waitUntilIdle()
assertEquals(BrowsingMode.Private, appStore.state.mode)
verify { navController.navigate(BrowserFragmentDirections.actionGlobalHome(focusOnAddressBar = true)) }
}
@ -460,6 +465,7 @@ class DefaultBrowserToolbarControllerTest {
customTabSessionId: String? = null,
) = DefaultBrowserToolbarController(
store = store,
appStore = appStore,
tabsUseCases = tabsUseCases,
activity = activity,
navController = navController,

@ -63,7 +63,6 @@ class ExternalAppBrowserActivityTest {
every { activity.components.settings.shouldReturnToBrowser } returns true
every { activity.openToBrowser(any(), any()) } returns Unit
activity.browsingModeManager = browsingModeManager
activity.navigateToBrowserOnColdStart()
verify(exactly = 0) { activity.openToBrowser(BrowserDirection.FromGlobal, null) }

@ -1117,15 +1117,11 @@ class DefaultSessionControlControllerTest {
@Test
fun `GIVEN app is in private browsing mode WHEN handling wallpaper dialog THEN the dialog is not shown`() {
every { activity.browsingModeManager } returns mockk {
every { mode } returns mockk {
every { isPrivate } returns true
}
}
every { appStore.state.mode } returns BrowsingMode.Private
val wallpaperState = WallpaperState.default.copy(
availableWallpapers = makeFakeRemoteWallpapers(
THUMBNAILS_SELECTION_COUNT,
true,
false,
),
)

@ -18,6 +18,7 @@ import mozilla.components.service.pocket.PocketStory.PocketRecommendedStory
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.rule.MainCoroutineRule
import mozilla.components.support.test.rule.runTestOnMain
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.components.AppStore
@ -85,6 +86,7 @@ class PocketUpdatesMiddlewareTest {
@Test
@Suppress("UNCHECKED_CAST")
@Ignore("started failing after introduction of InitAction. https://bugzilla.mozilla.org/show_bug.cgi?id=1864986")
fun `WHEN PocketStoriesCategoriesChange is dispatched THEN intercept and dispatch PocketStoriesCategoriesSelectionsChange`() = runTestOnMain {
val persistedSelectedCategory: SelectedPocketStoriesCategory = mockk {
every { name } returns "testCategory"

@ -29,8 +29,6 @@ import org.mozilla.fenix.GleanMetrics.StartOnHome
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager
import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -43,9 +41,7 @@ class TabCounterViewTest {
val gleanTestRule = GleanTestRule(testContext)
private lateinit var navController: NavController
private lateinit var browsingModeManager: BrowsingModeManager
private lateinit var settings: Settings
private lateinit var modeDidChange: (BrowsingMode) -> Unit
private lateinit var tabCounterView: TabCounterView
private lateinit var tabCounter: TabCounter
@ -53,30 +49,16 @@ class TabCounterViewTest {
fun setup() {
navController = mockk(relaxed = true)
settings = mockk(relaxed = true)
modeDidChange = mockk(relaxed = true)
tabCounter = spyk(TabCounter(testContext))
browsingModeManager = DefaultBrowsingModeManager(
_mode = BrowsingMode.Normal,
settings = settings,
modeDidChange = modeDidChange,
)
tabCounterView = TabCounterView(
context = testContext,
browsingModeManager = browsingModeManager,
navController = navController,
tabCounter = tabCounter,
)
}
@Test
fun `WHEN tab counter is clicked THEN navigate to tabs tray and record metrics`() {
every { navController.currentDestination?.id } returns R.id.homeFragment
assertNull(StartOnHome.openTabsTray.testGetValue())
tabCounterView = createTabCounterView()
tabCounter.performClick()
assertNotNull(StartOnHome.openTabsTray.testGetValue())
@ -91,16 +73,26 @@ class TabCounterViewTest {
@Test
fun `WHEN New tab menu item is tapped THEN set browsing mode to normal`() {
var capture: BrowsingMode? = null
tabCounterView = createTabCounterView {
capture = it
}
tabCounterView.onItemTapped(TabCounterMenu.Item.NewTab)
assertEquals(BrowsingMode.Normal, browsingModeManager.mode)
assertEquals(BrowsingMode.Normal, capture)
}
@Test
fun `WHEN New private tab menu item is tapped THEN set browsing mode to private`() {
var capture: BrowsingMode? = null
tabCounterView = createTabCounterView {
capture = it
}
tabCounterView.onItemTapped(TabCounterMenu.Item.NewPrivateTab)
assertEquals(BrowsingMode.Private, browsingModeManager.mode)
assertEquals(BrowsingMode.Private, capture)
}
@Test
@ -115,6 +107,7 @@ class TabCounterViewTest {
),
selectedTabId = "mozilla",
)
tabCounterView = createTabCounterView()
tabCounterView.update(browserState)
@ -122,7 +115,7 @@ class TabCounterViewTest {
tabCounter.setCountWithAnimation(browserState.normalTabs.size)
}
browsingModeManager.mode = BrowsingMode.Private
tabCounterView = createTabCounterView(mode = BrowsingMode.Private)
tabCounterView.update(browserState)
@ -144,10 +137,10 @@ class TabCounterViewTest {
selectedTabId = "mozilla",
)
browsingModeManager.mode = BrowsingMode.Private
tabCounterView = createTabCounterView(mode = BrowsingMode.Private)
tabCounterView.update(browserState)
verifyOrder {
verify {
tabCounter.toggleCounterMask(true)
}
}
@ -165,10 +158,22 @@ class TabCounterViewTest {
selectedTabId = "mozilla",
)
tabCounterView = createTabCounterView()
tabCounterView.update(browserState)
verifyOrder {
tabCounter.toggleCounterMask(false)
}
}
private fun createTabCounterView(
mode: BrowsingMode = BrowsingMode.Normal,
itemTapped: (BrowsingMode) -> Unit = {},
) = TabCounterView(
context = testContext,
navController = navController,
tabCounter = tabCounter,
mode = mode,
itemTapped = itemTapped,
)
}

@ -14,6 +14,7 @@ import io.mockk.Called
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.Job
import mozilla.appservices.places.BookmarkRoot
import mozilla.components.concept.engine.EngineSession
import org.junit.Assert.assertFalse
@ -26,7 +27,9 @@ import org.mozilla.fenix.BuildConfig.DEEP_LINK_SCHEME
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.accounts.FenixFxAEntryPoint
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.settings.SupportUtils
import org.robolectric.annotation.Config
@ -34,6 +37,7 @@ import org.robolectric.annotation.Config
@RunWith(FenixRobolectricTestRunner::class)
class HomeDeepLinkIntentProcessorTest {
private lateinit var activity: HomeActivity
private lateinit var appStore: AppStore
private lateinit var navController: NavController
private lateinit var out: Intent
private lateinit var processorHome: HomeDeepLinkIntentProcessor
@ -41,9 +45,10 @@ class HomeDeepLinkIntentProcessorTest {
@Before
fun setup() {
activity = mockk(relaxed = true)
appStore = mockk(relaxed = true)
navController = mockk(relaxed = true)
out = mockk()
processorHome = HomeDeepLinkIntentProcessor(activity)
processorHome = HomeDeepLinkIntentProcessor(activity, appStore)
}
@Test
@ -191,9 +196,11 @@ class HomeDeepLinkIntentProcessorTest {
@Test
fun `process enable_private_browsing deep link`() {
every { appStore.dispatch(any()) } returns Job()
assertTrue(processorHome.process(testIntent("enable_private_browsing"), navController, out))
verify { activity.browsingModeManager.mode = BrowsingMode.Private }
verify { appStore.dispatch(AppAction.IntentAction.EnterPrivateBrowsing) }
verify { navController.navigate(NavGraphDirections.actionGlobalHome()) }
verify { out wasNot Called }
}
@ -228,7 +235,7 @@ class HomeDeepLinkIntentProcessorTest {
@Test
fun `process invalid open deep link`() {
val invalidProcessor = HomeDeepLinkIntentProcessor(activity)
val invalidProcessor = HomeDeepLinkIntentProcessor(activity, mockk())
assertTrue(invalidProcessor.process(testIntent("open"), navController, out))

@ -10,6 +10,7 @@ import io.mockk.Called
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.Job
import mozilla.components.concept.engine.EngineSession
import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.robolectric.testContext
@ -23,7 +24,9 @@ import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.onboarding.ReEngagementNotificationWorker
import org.mozilla.fenix.utils.Settings
@ -39,7 +42,7 @@ class ReEngagementIntentProcessorTest {
val navController: NavController = mockk()
val out: Intent = mockk()
val settings: Settings = mockk()
val result = ReEngagementIntentProcessor(mockk(), settings)
val result = ReEngagementIntentProcessor(mockk(), settings, mockk())
.process(Intent(), navController, out)
assertFalse(result)
@ -52,19 +55,19 @@ class ReEngagementIntentProcessorTest {
val navController: NavController = mockk(relaxed = true)
val out: Intent = mockk()
val activity: HomeActivity = mockk(relaxed = true)
val browsingModeManager: BrowsingModeManager = mockk(relaxed = true)
val settings: Settings = mockk(relaxed = true)
val appStore: AppStore = mockk(relaxed = true)
val intent = Intent().apply {
putExtra("org.mozilla.fenix.re-engagement.intent", true)
}
every { activity.applicationContext } returns testContext
every { activity.browsingModeManager } returns browsingModeManager
every { settings.reEngagementNotificationType } returns ReEngagementNotificationWorker.NOTIFICATION_TYPE_A
every { appStore.dispatch(any()) } returns Job()
assertNull(Events.reEngagementNotifTapped.testGetValue())
val result = ReEngagementIntentProcessor(activity, settings)
val result = ReEngagementIntentProcessor(activity, settings, appStore)
.process(intent, navController, out)
assert(result)
@ -83,6 +86,7 @@ class ReEngagementIntentProcessorTest {
historyMetadata = null,
)
}
verify { appStore.dispatch(AppAction.OpenTabInBrowser(BrowsingMode.Private)) }
verify { navController wasNot Called }
verify { out wasNot Called }
}
@ -92,19 +96,17 @@ class ReEngagementIntentProcessorTest {
val navController: NavController = mockk(relaxed = true)
val out: Intent = mockk()
val activity: HomeActivity = mockk(relaxed = true)
val browsingModeManager: BrowsingModeManager = mockk(relaxed = true)
val settings: Settings = mockk(relaxed = true)
val intent = Intent().apply {
putExtra("org.mozilla.fenix.re-engagement.intent", true)
}
every { activity.applicationContext } returns testContext
every { activity.browsingModeManager } returns browsingModeManager
every { settings.reEngagementNotificationType } returns ReEngagementNotificationWorker.NOTIFICATION_TYPE_B
assertNull(Events.reEngagementNotifTapped.testGetValue())
val result = ReEngagementIntentProcessor(activity, settings)
val result = ReEngagementIntentProcessor(activity, settings, mockk())
.process(intent, navController, out)
assert(result)

@ -42,7 +42,10 @@ import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.Services
import org.mozilla.fenix.components.appstate.AppAction
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.ext.bookmarkStorage
import org.mozilla.fenix.ext.components
@ -65,6 +68,8 @@ class BookmarkControllerTest {
private val navBackStackEntry: NavBackStackEntry = mockk(relaxed = true)
private val navDestination: NavDestination = mockk(relaxed = true)
private lateinit var appStore: AppStore
private val item =
BookmarkNode(BookmarkNodeType.ITEM, "456", "123", 0u, "Mozilla", "http://mozilla.org", 0, null)
private val subfolder =
@ -122,6 +127,7 @@ class BookmarkControllerTest {
every { bookmarkStore.dispatch(any()) } returns mockk()
every { sharedViewModel.selectedFolder = any() } just runs
every { tabsUseCases.addTab } returns addNewTabUseCase
appStore = AppStore()
}
@Test
@ -170,8 +176,8 @@ class BookmarkControllerTest {
@Test
fun `WHEN handleBookmarkTapped is called with private browsing THEN load the bookmark in new tab`() {
every { homeActivity.browsingModeManager.mode } returns BrowsingMode.Private
val flags = EngineSession.LoadUrlFlags.select(EngineSession.LoadUrlFlags.ALLOW_JAVASCRIPT_URL)
appStore = AppStore(AppState(mode = BrowsingMode.Private))
createController().handleBookmarkTapped(item)
@ -185,22 +191,6 @@ class BookmarkControllerTest {
}
}
@Test
fun `handleBookmarkTapped should respect browsing mode`() {
// if in normal mode, should be in normal mode
every { homeActivity.browsingModeManager.mode } returns BrowsingMode.Normal
val controller = createController()
controller.handleBookmarkTapped(item)
assertEquals(BrowsingMode.Normal, homeActivity.browsingModeManager.mode)
// if in private mode, should be in private mode
every { homeActivity.browsingModeManager.mode } returns BrowsingMode.Private
controller.handleBookmarkTapped(item)
assertEquals(BrowsingMode.Private, homeActivity.browsingModeManager.mode)
}
@Test
fun `handleBookmarkExpand should refresh and change the active bookmark node`() = runTestOnMain {
var loadBookmarkNodeInvoked = false
@ -353,7 +343,7 @@ class BookmarkControllerTest {
assertNotNull(openedToPrivateTabsPage)
assertFalse(openedToPrivateTabsPage!!)
verifyOrder {
homeActivity.browsingModeManager.mode = BrowsingMode.Normal
appStore.dispatch(AppAction.ModeChange(BrowsingMode.Normal))
addNewTabUseCase.invoke(item.url!!, private = false)
}
}
@ -373,7 +363,7 @@ class BookmarkControllerTest {
assertNotNull(openedToPrivateTabsPage)
assertTrue(openedToPrivateTabsPage!!)
verifyOrder {
homeActivity.browsingModeManager.mode = BrowsingMode.Private
appStore.dispatch(AppAction.ModeChange(BrowsingMode.Private))
addNewTabUseCase.invoke(item.url!!, private = true)
}
}
@ -412,7 +402,7 @@ class BookmarkControllerTest {
addNewTabUseCase.invoke(item.url!!, private = false)
addNewTabUseCase.invoke(item.url!!, private = false)
addNewTabUseCase.invoke(childItem.url!!, private = false)
homeActivity.browsingModeManager.mode = BrowsingMode.Normal
appStore.dispatch(AppAction.ModeChange(BrowsingMode.Normal))
}
}
@ -450,7 +440,7 @@ class BookmarkControllerTest {
addNewTabUseCase.invoke(item.url!!, private = true)
addNewTabUseCase.invoke(item.url!!, private = true)
addNewTabUseCase.invoke(childItem.url!!, private = true)
homeActivity.browsingModeManager.mode = BrowsingMode.Private
appStore.dispatch(AppAction.ModeChange(BrowsingMode.Private))
}
}
@ -552,6 +542,7 @@ class BookmarkControllerTest {
clipboardManager = clipboardManager,
scope = scope,
store = bookmarkStore,
appStore = appStore,
sharedViewModel = sharedViewModel,
tabsUseCases = tabsUseCases,
loadBookmarkNode = loadBookmarkNode,

@ -28,12 +28,10 @@ class DownloadControllerTest {
private val store: DownloadFragmentStore = mockk(relaxed = true)
private val state: DownloadFragmentState = mockk(relaxed = true)
private val openToFileManager: (DownloadItem, BrowsingMode?) -> Unit = { item, mode ->
private val openToFileManager: (DownloadItem) -> Unit = { item ->
openToFileManagerCapturedItem = item
openToFileManagerCapturedMode = mode
}
private var openToFileManagerCapturedItem: DownloadItem? = null
private var openToFileManagerCapturedMode: BrowsingMode? = null
private val invalidateOptionsMenu: () -> Unit = { wasInvalidateOptionsMenuCalled = true }
private var wasInvalidateOptionsMenuCalled = false
@ -58,15 +56,13 @@ class DownloadControllerTest {
controller.handleOpen(downloadItem)
assertEquals(downloadItem, openToFileManagerCapturedItem)
assertEquals(null, openToFileManagerCapturedMode)
}
@Test
fun onOpenItemInNormalMode() {
controller.handleOpen(downloadItem, BrowsingMode.Normal)
fun onOpenItem() {
controller.handleOpen(downloadItem)
assertEquals(downloadItem, openToFileManagerCapturedItem)
assertEquals(BrowsingMode.Normal, openToFileManagerCapturedMode)
}
@Test

@ -46,7 +46,9 @@ import org.mozilla.fenix.GleanMetrics.UnifiedSearch
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.Core
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.components.metrics.MetricsUtils
import org.mozilla.fenix.ext.application
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -76,6 +78,7 @@ class SearchDialogControllerTest {
private lateinit var middleware: CaptureActionsMiddleware<BrowserState, BrowserAction>
private lateinit var browserStore: BrowserStore
private lateinit var appStore: AppStore
@get:Rule
val gleanTestRule = GleanTestRule(testContext)
@ -88,6 +91,7 @@ class SearchDialogControllerTest {
browserStore = BrowserStore(
middleware = listOf(middleware),
)
appStore = AppStore()
every { store.state.tabId } returns "test-tab-id"
every { store.state.searchEngineSource.searchEngine } returns searchEngine
every { searchEngine.name } returns ""
@ -510,7 +514,7 @@ class SearchDialogControllerTest {
fun handleSearchShortcutEngineSelected() {
val searchEngine: SearchEngine = mockk(relaxed = true)
val browsingMode = BrowsingMode.Private
every { activity.browsingModeManager.mode } returns browsingMode
appStore = AppStore(AppState(mode = browsingMode))
var focusToolbarInvoked = false
createController(
@ -707,6 +711,7 @@ class SearchDialogControllerTest {
return SearchDialogController(
activity = activity,
store = browserStore,
appStore = appStore,
tabsUseCases = TabsUseCases(browserStore),
fragmentStore = store,
navController = navController,

@ -29,6 +29,9 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -36,11 +39,13 @@ import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
internal class SearchDialogFragmentTest {
private val navController: NavController = mockk()
private val fragment = SearchDialogFragment()
private var appStore: AppStore = AppStore()
@Before
fun setup() {
mockkStatic("androidx.navigation.fragment.FragmentKt")
every { any<Fragment>().findNavController() } returns navController
every { testContext.components.appStore } returns appStore
}
@After
@ -156,17 +161,18 @@ internal class SearchDialogFragmentTest {
@Test
fun `GIVEN app is in private mode WHEN search dialog is created THEN the dialog is secure`() {
appStore = AppStore(AppState(mode = BrowsingMode.Private))
val activity: HomeActivity = mockk(relaxed = true)
val fragment = spyk(SearchDialogFragment())
val layoutParams = LayoutParams()
layoutParams.flags = LayoutParams.FLAG_SECURE
every { activity.browsingModeManager.mode.isPrivate } returns true
every { activity.window } returns mockk(relaxed = true) {
every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE }
}
every { fragment.requireActivity() } returns activity
every { fragment.requireContext() } returns testContext
every { testContext.components.appStore } returns appStore
val dialog = fragment.onCreateDialog(null)
@ -176,11 +182,11 @@ internal class SearchDialogFragmentTest {
@Test
fun `GIVEN app is in normal mode WHEN search dialog is created THEN the dialog is not secure`() {
val activity: HomeActivity = mockk(relaxed = true)
appStore = AppStore(AppState(mode = BrowsingMode.Normal))
val fragment = spyk(SearchDialogFragment())
val layoutParams = LayoutParams()
layoutParams.flags = LayoutParams.FLAG_SECURE
every { activity.browsingModeManager.mode.isPrivate } returns false
every { activity.window } returns mockk(relaxed = true) {
every { attributes } returns LayoutParams().apply { flags = LayoutParams.FLAG_SECURE }
}

@ -27,10 +27,10 @@ import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.components.metrics.MetricsUtils
import org.mozilla.fenix.utils.Settings
@ -38,8 +38,6 @@ class SearchFragmentStoreTest {
@MockK private lateinit var searchEngine: SearchEngine
@MockK private lateinit var activity: HomeActivity
@MockK(relaxed = true)
private lateinit var components: Components
@ -49,15 +47,12 @@ class SearchFragmentStoreTest {
@Before
fun setup() {
MockKAnnotations.init(this)
every { activity.browsingModeManager } returns object : BrowsingModeManager {
override var mode: BrowsingMode = BrowsingMode.Normal
}
every { components.settings } returns settings
every { components.appStore } returns AppStore()
}
@Test
fun `createInitialSearchFragmentState with no tab in normal browsing mode`() {
activity.browsingModeManager.mode = BrowsingMode.Normal
every { components.core.store.state } returns BrowserState()
every { settings.shouldShowSearchShortcuts } returns true
every { settings.showUnifiedSearchFeature } returns true
@ -100,7 +95,6 @@ class SearchFragmentStoreTest {
assertEquals(
expected,
createInitialSearchFragmentState(
activity,
components,
tabId = null,
pastedText = "pastedText",
@ -110,7 +104,6 @@ class SearchFragmentStoreTest {
assertEquals(
expected.copy(tabId = "tabId"),
createInitialSearchFragmentState(
activity,
components,
tabId = "tabId",
pastedText = "pastedText",
@ -124,8 +117,8 @@ class SearchFragmentStoreTest {
@Test
fun `createInitialSearchFragmentState with no tab in private browsing mode`() {
activity.browsingModeManager.mode = BrowsingMode.Private
every { components.core.store.state } returns BrowserState()
every { components.appStore } returns AppStore(AppState(mode = BrowsingMode.Private))
every { settings.shouldShowSearchShortcuts } returns true
every { settings.showUnifiedSearchFeature } returns true
every { settings.shouldShowHistorySuggestions } returns true
@ -166,7 +159,6 @@ class SearchFragmentStoreTest {
assertEquals(
expected,
createInitialSearchFragmentState(
activity,
components,
tabId = null,
pastedText = "pastedText",
@ -177,7 +169,6 @@ class SearchFragmentStoreTest {
@Test
fun `createInitialSearchFragmentState with tab`() {
activity.browsingModeManager.mode = BrowsingMode.Private
every { components.core.store.state } returns BrowserState(
tabs = listOf(
TabSessionState(
@ -219,7 +210,6 @@ class SearchFragmentStoreTest {
searchAccessPoint = MetricsUtils.Source.SHORTCUT,
),
createInitialSearchFragmentState(
activity,
components,
tabId = "tabId",
pastedText = "",
@ -230,14 +220,13 @@ class SearchFragmentStoreTest {
@Test
fun `GIVEN sponsored and non-sponsored suggestions are enabled and Firefox Suggest is disabled WHEN the initial state is created THEN neither are displayed`() {
activity.browsingModeManager.mode = BrowsingMode.Normal
every { components.appStore } returns AppStore()
every { components.core.store.state } returns BrowserState()
every { settings.enableFxSuggest } returns false
every { settings.showSponsoredSuggestions } returns true
every { settings.showNonSponsoredSuggestions } returns true
val initialState = createInitialSearchFragmentState(
activity,
components,
tabId = null,
pastedText = "pastedText",

@ -38,7 +38,9 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.Core.Companion
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@ -49,6 +51,7 @@ import org.mozilla.fenix.utils.Settings
@RunWith(FenixRobolectricTestRunner::class)
class AwesomeBarViewTest {
private var activity: HomeActivity = mockk(relaxed = true)
private var appStore = AppStore()
private lateinit var awesomeBarView: AwesomeBarView
@Before
@ -65,6 +68,7 @@ class AwesomeBarViewTest {
every { any<Activity>().components.core.client } returns mockk()
every { any<Activity>().components.backgroundServices.syncedTabsStorage } returns mockk()
every { any<Activity>().components.core.store.state.search } returns mockk(relaxed = true)
every { any<Activity>().components.appStore } returns appStore
every { any<Activity>().getColorFromAttr(any()) } returns 0
every { AwesomeBarView.Companion.getDrawable(any(), any()) } returns mockk<VectorDrawable>(relaxed = true) {
every { intrinsicWidth } returns 10
@ -769,7 +773,6 @@ class AwesomeBarViewTest {
val settings: Settings = mockk(relaxed = true)
val url = Uri.parse("https://www.test.com")
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
showSessionSuggestionsForCurrentEngine = false,
searchEngineSource = SearchEngineSource.Shortcut(
@ -815,7 +818,6 @@ class AwesomeBarViewTest {
val settings: Settings = mockk(relaxed = true)
val url = Uri.parse("https://www.test.com")
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
showAllSessionSuggestions = false,
searchEngineSource = SearchEngineSource.Shortcut(
@ -834,9 +836,10 @@ class AwesomeBarViewTest {
@Test
fun `GIVEN private browsing mode and needing to show tabs suggestions WHEN configuring providers THEN don't add the tabs provider`() {
val appStore = AppStore(AppState(mode = BrowsingMode.Private))
val settings: Settings = mockk(relaxed = true)
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Private
every { any<Activity>().components.appStore } returns appStore
val state = getSearchProviderState(
searchEngineSource = SearchEngineSource.Shortcut(mockk(relaxed = true)),
)
@ -851,7 +854,6 @@ class AwesomeBarViewTest {
val settings: Settings = mockk(relaxed = true)
val url = Uri.parse("https://www.test.com")
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
showSyncedTabsSuggestionsForCurrentEngine = false,
searchEngineSource = SearchEngineSource.Shortcut(
@ -874,7 +876,6 @@ class AwesomeBarViewTest {
val settings: Settings = mockk(relaxed = true)
val url = Uri.parse("https://www.test.com")
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
showAllSyncedTabsSuggestions = false,
searchEngineSource = SearchEngineSource.Shortcut(
@ -920,7 +921,6 @@ class AwesomeBarViewTest {
val settings: Settings = mockk(relaxed = true)
val url = Uri.parse("https://www.test.com")
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
showBookmarksSuggestionsForCurrentEngine = false,
searchEngineSource = SearchEngineSource.Shortcut(
@ -966,7 +966,6 @@ class AwesomeBarViewTest {
val settings: Settings = mockk(relaxed = true)
val url = Uri.parse("https://www.test.com")
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
showAllBookmarkSuggestions = false,
searchEngineSource = SearchEngineSource.Shortcut(
@ -1001,7 +1000,6 @@ class AwesomeBarViewTest {
val settings: Settings = mockk(relaxed = true)
val url = Uri.parse("https://www.test.com")
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
searchEngineSource = SearchEngineSource.Default(
mockk(relaxed = true) {
@ -1076,7 +1074,6 @@ class AwesomeBarViewTest {
fun `GIVEN a search from the default engine with no suggestions asked WHEN configuring providers THEN add only search engine suggestion provider`() {
val settings: Settings = mockk(relaxed = true)
every { activity.settings() } returns settings
every { activity.browsingModeManager.mode } returns BrowsingMode.Normal
val state = getSearchProviderState(
showHistorySuggestionsForCurrentEngine = false,
showSearchShortcuts = false,

@ -57,12 +57,11 @@ import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.browser.browsingmode.DefaultBrowsingModeManager
import org.mozilla.fenix.collections.CollectionsDialog
import org.mozilla.fenix.collections.show
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.components.TabCollectionStorage
import org.mozilla.fenix.components.appstate.AppState
import org.mozilla.fenix.components.bookmarks.BookmarksUseCase
import org.mozilla.fenix.ext.maxActiveTime
import org.mozilla.fenix.ext.potentialInactiveTabs
@ -80,9 +79,6 @@ class DefaultTabsTrayControllerTest {
@MockK(relaxed = true)
private lateinit var browserStore: BrowserStore
@MockK(relaxed = true)
private lateinit var browsingModeManager: BrowsingModeManager
@MockK(relaxed = true)
private lateinit var navController: NavController
@ -98,7 +94,7 @@ class DefaultTabsTrayControllerTest {
@MockK(relaxed = true)
private lateinit var activity: HomeActivity
private val appStore: AppStore = mockk(relaxed = true)
private lateinit var appStore: AppStore
private val settings: Settings = mockk(relaxed = true)
private val bookmarksUseCase: BookmarksUseCase = mockk(relaxed = true)
@ -117,6 +113,7 @@ class DefaultTabsTrayControllerTest {
@Before
fun setup() {
MockKAnnotations.init(this)
appStore = AppStore()
}
@Test
@ -142,6 +139,7 @@ class DefaultTabsTrayControllerTest {
Double.MAX_VALUE,
)
}
assertEquals(BrowsingMode.Private, appStore.state.mode)
}
@Test
@ -149,6 +147,7 @@ class DefaultTabsTrayControllerTest {
profiler = spyk(profiler) {
every { getProfilerTime() } returns Double.MAX_VALUE
}
appStore = AppStore(AppState(mode = BrowsingMode.Private))
createController().handleNormalTabsFabClick()
@ -942,13 +941,6 @@ class DefaultTabsTrayControllerTest {
tabs = listOf(normalTab, privateTab),
),
)
browsingModeManager = spyk(
DefaultBrowsingModeManager(
_mode = BrowsingMode.Private,
settings = settings,
modeDidChange = mockk(relaxed = true),
),
)
val controller = spyk(createController())
try {
@ -957,14 +949,13 @@ class DefaultTabsTrayControllerTest {
controller.handleTabSelected(privateTab, null)
assertEquals(privateTab.id, browserStore.state.selectedTabId)
assertEquals(true, browsingModeManager.mode.isPrivate)
controller.handleTabDeletion("privateTab")
browserStore.dispatch(TabListAction.SelectTabAction(normalTab.id)).joinBlocking()
controller.handleTabSelected(normalTab, null)
assertEquals(normalTab.id, browserStore.state.selectedTabId)
assertEquals(false, browsingModeManager.mode.isPrivate)
assertEquals(false, appStore.state.mode.isPrivate)
} finally {
unmockkStatic("mozilla.components.browser.state.selector.SelectorsKt")
}
@ -1143,7 +1134,6 @@ class DefaultTabsTrayControllerTest {
tabsTrayStore = trayStore,
browserStore = browserStore,
settings = settings,
browsingModeManager = browsingModeManager,
navController = navController,
navigateToHomeAndDeleteSession = navigateToHomeAndDeleteSession,
profiler = profiler,

@ -11,14 +11,14 @@ import io.mockk.mockk
import io.mockk.verify
import org.junit.Test
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
import org.mozilla.fenix.components.AppStore
import org.mozilla.fenix.tabstray.TrayPagerAdapter.Companion.POSITION_NORMAL_TABS
import org.mozilla.fenix.tabstray.TrayPagerAdapter.Companion.POSITION_PRIVATE_TABS
import org.mozilla.fenix.tabstray.TrayPagerAdapter.Companion.POSITION_SYNCED_TABS
class TabLayoutMediatorTest {
private val modeManager: BrowsingModeManager = mockk(relaxed = true)
private val tabsTrayStore: TabsTrayStore = mockk(relaxed = true)
private val appStore: AppStore = mockk(relaxed = true)
private val interactor: TabsTrayInteractor = mockk(relaxed = true)
private val tabLayout: TabLayout = mockk(relaxed = true)
private val tab: TabLayout.Tab = mockk(relaxed = true)
@ -26,10 +26,10 @@ class TabLayoutMediatorTest {
@Test
fun `page to normal tab position when mode is also normal`() {
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, modeManager, tabsTrayStore)
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, appStore, tabsTrayStore)
val mockState: TabsTrayState = mockk()
every { modeManager.mode }.answers { BrowsingMode.Normal }
every { appStore.state } returns mockk { every { mode } returns BrowsingMode.Normal }
every { tabLayout.getTabAt(POSITION_NORMAL_TABS) }.answers { tab }
every { tabsTrayStore.state } returns mockState
every { mockState.selectedPage } returns Page.NormalTabs
@ -43,9 +43,9 @@ class TabLayoutMediatorTest {
@Test
fun `page to private tab position when mode is also private`() {
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, modeManager, tabsTrayStore)
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, appStore, tabsTrayStore)
every { modeManager.mode }.answers { BrowsingMode.Private }
every { appStore.state } returns mockk { every { mode } returns BrowsingMode.Private }
every { tabLayout.getTabAt(POSITION_PRIVATE_TABS) }.answers { tab }
mediator.selectActivePage()
@ -56,10 +56,10 @@ class TabLayoutMediatorTest {
@Test
fun `page to synced tabs when selected page is also synced tabs`() {
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, modeManager, tabsTrayStore)
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, appStore, tabsTrayStore)
val mockState: TabsTrayState = mockk()
every { modeManager.mode }.answers { BrowsingMode.Normal }
every { appStore.state } returns mockk { every { mode } returns BrowsingMode.Normal }
every { tabsTrayStore.state } returns mockState
every { mockState.selectedPage } returns Page.SyncedTabs
@ -70,7 +70,7 @@ class TabLayoutMediatorTest {
@Test
fun `selectTabAtPosition will dispatch the correct TabsTrayStore action`() {
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, modeManager, tabsTrayStore)
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, appStore, tabsTrayStore)
every { tabLayout.getTabAt(POSITION_NORMAL_TABS) }.answers { tab }
every { tabLayout.getTabAt(POSITION_PRIVATE_TABS) }.answers { tab }
@ -91,9 +91,9 @@ class TabLayoutMediatorTest {
@Test
fun `lifecycle methods adds and removes observer`() {
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, modeManager, tabsTrayStore)
val mediator = TabLayoutMediator(tabLayout, viewPager, interactor, appStore, tabsTrayStore)
every { modeManager.mode }.answers { BrowsingMode.Private }
every { appStore.state } returns mockk { every { mode } returns BrowsingMode.Private }
mediator.start()

Loading…
Cancel
Save