No issue: refactor tabs tray to use interactor/controller, add tests
parent
0ba1d266b3
commit
635c30510d
|
@ -0,0 +1,124 @@
|
||||||
|
/* 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.tabtray
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import mozilla.components.browser.session.Session
|
||||||
|
import mozilla.components.browser.session.SessionManager
|
||||||
|
import mozilla.components.concept.engine.prompt.ShareData
|
||||||
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
|
import org.mozilla.fenix.collections.SaveCollectionStep
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.sessionsOfType
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [TabTrayDialogFragment] controller.
|
||||||
|
*
|
||||||
|
* Delegated by View Interactors, handles container business logic and operates changes on it.
|
||||||
|
*/
|
||||||
|
interface TabTrayController {
|
||||||
|
fun onNewTabTapped(private: Boolean)
|
||||||
|
fun onTabTrayDismissed()
|
||||||
|
fun onShareTabsClicked(private: Boolean)
|
||||||
|
fun onSaveToCollectionClicked()
|
||||||
|
fun onCloseAllTabsClicked(private: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("TooManyFunctions")
|
||||||
|
class DefaultTabTrayController(
|
||||||
|
private val activity: HomeActivity,
|
||||||
|
private val navController: NavController,
|
||||||
|
private val dismissTabTray: () -> Unit,
|
||||||
|
private val showUndoSnackbar: (String, SessionManager.Snapshot) -> Unit,
|
||||||
|
private val registerCollectionStorageObserver: () -> Unit
|
||||||
|
) : TabTrayController {
|
||||||
|
override fun onNewTabTapped(private: Boolean) {
|
||||||
|
activity.browsingModeManager.mode = BrowsingMode.fromBoolean(private)
|
||||||
|
navController.navigate(TabTrayDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true))
|
||||||
|
dismissTabTray()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabTrayDismissed() {
|
||||||
|
dismissTabTray()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveToCollectionClicked() {
|
||||||
|
val tabs = getListOfSessions(false)
|
||||||
|
val tabIds = tabs.map { it.id }.toList().toTypedArray()
|
||||||
|
val tabCollectionStorage = activity.components.core.tabCollectionStorage
|
||||||
|
|
||||||
|
val step = when {
|
||||||
|
// Show the SelectTabs fragment if there are multiple opened tabs to select which tabs
|
||||||
|
// you want to save to a collection.
|
||||||
|
tabs.size > 1 -> SaveCollectionStep.SelectTabs
|
||||||
|
// If there is an existing tab collection, show the SelectCollection fragment to save
|
||||||
|
// the selected tab to a collection of your choice.
|
||||||
|
tabCollectionStorage.cachedTabCollections.isNotEmpty() -> SaveCollectionStep.SelectCollection
|
||||||
|
// Show the NameCollection fragment to create a new collection for the selected tab.
|
||||||
|
else -> SaveCollectionStep.NameCollection
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navController.currentDestination?.id == R.id.collectionCreationFragment) return
|
||||||
|
|
||||||
|
// Only register the observer right before moving to collection creation
|
||||||
|
registerCollectionStorageObserver()
|
||||||
|
|
||||||
|
val directions = TabTrayDialogFragmentDirections.actionGlobalCollectionCreationFragment(
|
||||||
|
tabIds = tabIds,
|
||||||
|
saveCollectionStep = step,
|
||||||
|
selectedTabIds = tabIds
|
||||||
|
)
|
||||||
|
navController.navigate(directions)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShareTabsClicked(private: Boolean) {
|
||||||
|
val tabs = getListOfSessions(private)
|
||||||
|
val data = tabs.map {
|
||||||
|
ShareData(url = it.url, title = it.title)
|
||||||
|
}
|
||||||
|
val directions = TabTrayDialogFragmentDirections.actionGlobalShareFragment(
|
||||||
|
data = data.toTypedArray()
|
||||||
|
)
|
||||||
|
navController.navigate(directions)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCloseAllTabsClicked(private: Boolean) {
|
||||||
|
val sessionManager = activity.components.core.sessionManager
|
||||||
|
val tabs = getListOfSessions(private)
|
||||||
|
|
||||||
|
val selectedIndex = sessionManager
|
||||||
|
.selectedSession?.let { sessionManager.sessions.indexOf(it) } ?: 0
|
||||||
|
|
||||||
|
val snapshot = tabs
|
||||||
|
.map(sessionManager::createSessionSnapshot)
|
||||||
|
.map {
|
||||||
|
it.copy(
|
||||||
|
engineSession = null,
|
||||||
|
engineSessionState = it.engineSession?.saveState()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.let { SessionManager.Snapshot(it, selectedIndex) }
|
||||||
|
|
||||||
|
tabs.forEach {
|
||||||
|
sessionManager.remove(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
val snackbarMessage = if (private) {
|
||||||
|
activity.getString(R.string.snackbar_private_tabs_closed)
|
||||||
|
} else {
|
||||||
|
activity.getString(R.string.snackbar_tabs_closed)
|
||||||
|
}
|
||||||
|
|
||||||
|
showUndoSnackbar(snackbarMessage, snapshot)
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||||
|
private fun getListOfSessions(private: Boolean): List<Session> {
|
||||||
|
return activity.components.core.sessionManager.sessionsOfType(private = private).toList()
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,25 +22,21 @@ import mozilla.components.browser.session.SessionManager
|
||||||
import mozilla.components.browser.state.selector.normalTabs
|
import mozilla.components.browser.state.selector.normalTabs
|
||||||
import mozilla.components.browser.state.selector.privateTabs
|
import mozilla.components.browser.state.selector.privateTabs
|
||||||
import mozilla.components.browser.state.state.BrowserState
|
import mozilla.components.browser.state.state.BrowserState
|
||||||
import mozilla.components.concept.engine.prompt.ShareData
|
|
||||||
import mozilla.components.feature.tabs.tabstray.TabsFeature
|
|
||||||
import mozilla.components.feature.tab.collections.TabCollection
|
import mozilla.components.feature.tab.collections.TabCollection
|
||||||
import mozilla.components.feature.tabs.TabsUseCases
|
import mozilla.components.feature.tabs.TabsUseCases
|
||||||
|
import mozilla.components.feature.tabs.tabstray.TabsFeature
|
||||||
import mozilla.components.lib.state.ext.consumeFrom
|
import mozilla.components.lib.state.ext.consumeFrom
|
||||||
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
|
||||||
import org.mozilla.fenix.HomeActivity
|
import org.mozilla.fenix.HomeActivity
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
|
||||||
import org.mozilla.fenix.collections.SaveCollectionStep
|
|
||||||
import org.mozilla.fenix.components.FenixSnackbar
|
import org.mozilla.fenix.components.FenixSnackbar
|
||||||
|
import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.sessionsOfType
|
|
||||||
import org.mozilla.fenix.utils.allowUndo
|
import org.mozilla.fenix.utils.allowUndo
|
||||||
import org.mozilla.fenix.components.TabCollectionStorage
|
|
||||||
|
|
||||||
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
@SuppressWarnings("TooManyFunctions", "LargeClass")
|
||||||
class TabTrayDialogFragment : AppCompatDialogFragment(), TabTrayInteractor {
|
class TabTrayDialogFragment : AppCompatDialogFragment() {
|
||||||
private val tabsFeature = ViewBoundFeatureWrapper<TabsFeature>()
|
private val tabsFeature = ViewBoundFeatureWrapper<TabsFeature>()
|
||||||
private var _tabTrayView: TabTrayView? = null
|
private var _tabTrayView: TabTrayView? = null
|
||||||
private val tabTrayView: TabTrayView
|
private val tabTrayView: TabTrayView
|
||||||
|
@ -108,10 +104,19 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), TabTrayInteractor {
|
||||||
|
|
||||||
_tabTrayView = TabTrayView(
|
_tabTrayView = TabTrayView(
|
||||||
view.tabLayout,
|
view.tabLayout,
|
||||||
this,
|
interactor = TabTrayFragmentInteractor(
|
||||||
isPrivate,
|
DefaultTabTrayController(
|
||||||
requireContext().resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE,
|
activity = (activity as HomeActivity),
|
||||||
viewLifecycleOwner.lifecycleScope
|
navController = findNavController(),
|
||||||
|
dismissTabTray = ::dismissAllowingStateLoss,
|
||||||
|
showUndoSnackbar = ::showUndoSnackbar,
|
||||||
|
registerCollectionStorageObserver = ::registerCollectionStorageObserver
|
||||||
|
)
|
||||||
|
),
|
||||||
|
isPrivate = isPrivate,
|
||||||
|
startingInLandscape = requireContext().resources.configuration.orientation ==
|
||||||
|
Configuration.ORIENTATION_LANDSCAPE,
|
||||||
|
lifecycleScope = viewLifecycleOwner.lifecycleScope
|
||||||
) { tabsFeature.get()?.filterTabs(it) }
|
) { tabsFeature.get()?.filterTabs(it) }
|
||||||
|
|
||||||
tabsFeature.set(
|
tabsFeature.set(
|
||||||
|
@ -195,96 +200,6 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), TabTrayInteractor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewTabTapped(private: Boolean) {
|
|
||||||
(activity as HomeActivity).browsingModeManager.mode = BrowsingMode.fromBoolean(private)
|
|
||||||
findNavController().navigate(TabTrayDialogFragmentDirections.actionGlobalHome(focusOnAddressBar = true))
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onTabTrayDismissed() {
|
|
||||||
dismissAllowingStateLoss()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onSaveToCollectionClicked() {
|
|
||||||
val tabs = getListOfSessions(false)
|
|
||||||
val tabIds = tabs.map { it.id }.toList().toTypedArray()
|
|
||||||
val tabCollectionStorage = (activity as HomeActivity).components.core.tabCollectionStorage
|
|
||||||
val navController = findNavController()
|
|
||||||
|
|
||||||
val step = when {
|
|
||||||
// Show the SelectTabs fragment if there are multiple opened tabs to select which tabs
|
|
||||||
// you want to save to a collection.
|
|
||||||
tabs.size > 1 -> SaveCollectionStep.SelectTabs
|
|
||||||
// If there is an existing tab collection, show the SelectCollection fragment to save
|
|
||||||
// the selected tab to a collection of your choice.
|
|
||||||
tabCollectionStorage.cachedTabCollections.isNotEmpty() -> SaveCollectionStep.SelectCollection
|
|
||||||
// Show the NameCollection fragment to create a new collection for the selected tab.
|
|
||||||
else -> SaveCollectionStep.NameCollection
|
|
||||||
}
|
|
||||||
|
|
||||||
if (navController.currentDestination?.id == R.id.collectionCreationFragment) return
|
|
||||||
|
|
||||||
// Only register the observer right before moving to collection creation
|
|
||||||
registerCollectionStorageObserver()
|
|
||||||
|
|
||||||
val directions = TabTrayDialogFragmentDirections.actionGlobalCollectionCreationFragment(
|
|
||||||
tabIds = tabIds,
|
|
||||||
saveCollectionStep = step,
|
|
||||||
selectedTabIds = tabIds
|
|
||||||
)
|
|
||||||
navController.navigate(directions)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onShareTabsClicked(private: Boolean) {
|
|
||||||
val tabs = getListOfSessions(private)
|
|
||||||
val data = tabs.map {
|
|
||||||
ShareData(url = it.url, title = it.title)
|
|
||||||
}
|
|
||||||
val directions = TabTrayDialogFragmentDirections.actionGlobalShareFragment(
|
|
||||||
data = data.toTypedArray()
|
|
||||||
)
|
|
||||||
findNavController().navigate(directions)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCloseAllTabsClicked(private: Boolean) {
|
|
||||||
val sessionManager = requireContext().components.core.sessionManager
|
|
||||||
val tabs = getListOfSessions(private)
|
|
||||||
|
|
||||||
val selectedIndex = sessionManager
|
|
||||||
.selectedSession?.let { sessionManager.sessions.indexOf(it) } ?: 0
|
|
||||||
|
|
||||||
val snapshot = tabs
|
|
||||||
.map(sessionManager::createSessionSnapshot)
|
|
||||||
.map { it.copy(engineSession = null, engineSessionState = it.engineSession?.saveState()) }
|
|
||||||
.let { SessionManager.Snapshot(it, selectedIndex) }
|
|
||||||
|
|
||||||
tabs.forEach {
|
|
||||||
sessionManager.remove(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
val snackbarMessage = if (tabTrayView.isPrivateModeSelected) {
|
|
||||||
getString(R.string.snackbar_private_tabs_closed)
|
|
||||||
} else {
|
|
||||||
getString(R.string.snackbar_tabs_closed)
|
|
||||||
}
|
|
||||||
|
|
||||||
viewLifecycleOwner.lifecycleScope.allowUndo(
|
|
||||||
requireView(),
|
|
||||||
snackbarMessage,
|
|
||||||
getString(R.string.snackbar_deleted_undo),
|
|
||||||
{
|
|
||||||
sessionManager.restore(snapshot)
|
|
||||||
},
|
|
||||||
operation = { },
|
|
||||||
elevation = ELEVATION
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getListOfSessions(private: Boolean): List<Session> {
|
|
||||||
return requireContext().components.core.sessionManager.sessionsOfType(private = private)
|
|
||||||
.toList()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun navigateHomeIfNeeded(state: BrowserState) {
|
private fun navigateHomeIfNeeded(state: BrowserState) {
|
||||||
val shouldPop = if (tabTrayView.isPrivateModeSelected) {
|
val shouldPop = if (tabTrayView.isPrivateModeSelected) {
|
||||||
state.privateTabs.isEmpty()
|
state.privateTabs.isEmpty()
|
||||||
|
@ -301,6 +216,21 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), TabTrayInteractor {
|
||||||
requireComponents.core.tabCollectionStorage.register(collectionStorageObserver, this)
|
requireComponents.core.tabCollectionStorage.register(collectionStorageObserver, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showUndoSnackbar(snackbarMessage: String, snapshot: SessionManager.Snapshot) {
|
||||||
|
view?.let {
|
||||||
|
viewLifecycleOwner.lifecycleScope.allowUndo(
|
||||||
|
it,
|
||||||
|
snackbarMessage,
|
||||||
|
getString(R.string.snackbar_deleted_undo),
|
||||||
|
{
|
||||||
|
context?.components?.core?.sessionManager?.restore(snapshot)
|
||||||
|
},
|
||||||
|
operation = { },
|
||||||
|
elevation = ELEVATION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun showCollectionSnackbar() {
|
private fun showCollectionSnackbar() {
|
||||||
view.let {
|
view.let {
|
||||||
val snackbar = FenixSnackbar
|
val snackbar = FenixSnackbar
|
||||||
|
@ -328,7 +258,9 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), TabTrayInteractor {
|
||||||
|
|
||||||
fun show(fragmentManager: FragmentManager) {
|
fun show(fragmentManager: FragmentManager) {
|
||||||
// If we've killed the fragmentManager. Let's not try to show the tabs tray.
|
// If we've killed the fragmentManager. Let's not try to show the tabs tray.
|
||||||
if (fragmentManager.isDestroyed) { return }
|
if (fragmentManager.isDestroyed) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// We want to make sure we don't accidentally show the dialog twice if
|
// We want to make sure we don't accidentally show the dialog twice if
|
||||||
// a user somehow manages to trigger `show()` twice before we present the dialog.
|
// a user somehow manages to trigger `show()` twice before we present the dialog.
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* 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.tabtray
|
||||||
|
|
||||||
|
interface TabTrayInteractor {
|
||||||
|
fun onNewTabTapped(private: Boolean)
|
||||||
|
fun onTabTrayDismissed()
|
||||||
|
fun onShareTabsClicked(private: Boolean)
|
||||||
|
fun onSaveToCollectionClicked()
|
||||||
|
fun onCloseAllTabsClicked(private: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interactor for the tab tray fragment.
|
||||||
|
*/
|
||||||
|
class TabTrayFragmentInteractor(private val controller: TabTrayController) : TabTrayInteractor {
|
||||||
|
override fun onNewTabTapped(private: Boolean) {
|
||||||
|
controller.onNewTabTapped(private)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabTrayDismissed() {
|
||||||
|
controller.onTabTrayDismissed()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShareTabsClicked(private: Boolean) {
|
||||||
|
controller.onShareTabsClicked(private)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSaveToCollectionClicked() {
|
||||||
|
controller.onSaveToCollectionClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCloseAllTabsClicked(private: Boolean) {
|
||||||
|
controller.onCloseAllTabsClicked(private)
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,13 +32,6 @@ import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.ext.components
|
import org.mozilla.fenix.ext.components
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
|
|
||||||
interface TabTrayInteractor {
|
|
||||||
fun onNewTabTapped(private: Boolean)
|
|
||||||
fun onTabTrayDismissed()
|
|
||||||
fun onShareTabsClicked(private: Boolean)
|
|
||||||
fun onSaveToCollectionClicked()
|
|
||||||
fun onCloseAllTabsClicked(private: Boolean)
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* View that contains and configures the BrowserAwesomeBar
|
* View that contains and configures the BrowserAwesomeBar
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
/* 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.tabtray
|
||||||
|
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavDestination
|
||||||
|
import androidx.navigation.NavDirections
|
||||||
|
import io.mockk.Runs
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.just
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.slot
|
||||||
|
import io.mockk.verify
|
||||||
|
import io.mockk.verifyOrder
|
||||||
|
import mozilla.components.browser.session.Session
|
||||||
|
import mozilla.components.browser.session.SessionManager
|
||||||
|
import mozilla.components.feature.tab.collections.TabCollection
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertTrue
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.HomeActivity
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||||
|
import org.mozilla.fenix.components.TabCollectionStorage
|
||||||
|
import org.mozilla.fenix.ext.components
|
||||||
|
import org.mozilla.fenix.ext.sessionsOfType
|
||||||
|
|
||||||
|
class DefaultTabTrayControllerTest {
|
||||||
|
|
||||||
|
private val activity: HomeActivity = mockk(relaxed = true)
|
||||||
|
private val navController: NavController = mockk()
|
||||||
|
private val sessionManager: SessionManager = mockk(relaxed = true)
|
||||||
|
private val dismissTabTray: (() -> Unit) = mockk(relaxed = true)
|
||||||
|
private val showUndoSnackbar: ((String, SessionManager.Snapshot) -> Unit) =
|
||||||
|
mockk(relaxed = true)
|
||||||
|
private val registerCollectionStorageObserver: (() -> Unit) = mockk(relaxed = true)
|
||||||
|
private val tabCollectionStorage: TabCollectionStorage = mockk(relaxed = true)
|
||||||
|
private val tabCollection: TabCollection = mockk()
|
||||||
|
private val cachedTabCollections: List<TabCollection> = listOf(tabCollection)
|
||||||
|
private val currentDestination: NavDestination = mockk(relaxed = true)
|
||||||
|
|
||||||
|
private lateinit var controller: DefaultTabTrayController
|
||||||
|
|
||||||
|
private val session = Session(
|
||||||
|
"mozilla.org",
|
||||||
|
true
|
||||||
|
)
|
||||||
|
|
||||||
|
private val nonPrivateSession = Session(
|
||||||
|
"mozilla.org",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
mockkStatic("org.mozilla.fenix.ext.SessionManagerKt")
|
||||||
|
|
||||||
|
every { activity.components.core.sessionManager } returns sessionManager
|
||||||
|
every { activity.components.core.tabCollectionStorage } returns tabCollectionStorage
|
||||||
|
every { sessionManager.sessionsOfType(private = true) } returns listOf(session).asSequence()
|
||||||
|
every { sessionManager.sessionsOfType(private = false) } returns listOf(nonPrivateSession).asSequence()
|
||||||
|
every { sessionManager.createSessionSnapshot(any()) } returns SessionManager.Snapshot.Item(
|
||||||
|
session
|
||||||
|
)
|
||||||
|
every { sessionManager.remove(any()) } just Runs
|
||||||
|
every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollections
|
||||||
|
every { sessionManager.selectedSession } returns nonPrivateSession
|
||||||
|
every { navController.navigate(any<NavDirections>()) } just Runs
|
||||||
|
every { navController.currentDestination } returns currentDestination
|
||||||
|
every { currentDestination.id } returns R.id.browserFragment
|
||||||
|
|
||||||
|
controller = DefaultTabTrayController(
|
||||||
|
activity = activity,
|
||||||
|
navController = navController,
|
||||||
|
dismissTabTray = dismissTabTray,
|
||||||
|
showUndoSnackbar = showUndoSnackbar,
|
||||||
|
registerCollectionStorageObserver = registerCollectionStorageObserver
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onNewTabTapped() {
|
||||||
|
controller.onNewTabTapped(private = false)
|
||||||
|
|
||||||
|
verifyOrder {
|
||||||
|
activity.browsingModeManager.mode = BrowsingMode.fromBoolean(false)
|
||||||
|
navController.navigate(
|
||||||
|
TabTrayDialogFragmentDirections.actionGlobalHome(
|
||||||
|
focusOnAddressBar = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
dismissTabTray()
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.onNewTabTapped(private = true)
|
||||||
|
|
||||||
|
verifyOrder {
|
||||||
|
activity.browsingModeManager.mode = BrowsingMode.fromBoolean(true)
|
||||||
|
navController.navigate(
|
||||||
|
TabTrayDialogFragmentDirections.actionGlobalHome(
|
||||||
|
focusOnAddressBar = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
dismissTabTray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTabTrayDismissed() {
|
||||||
|
controller.onTabTrayDismissed()
|
||||||
|
|
||||||
|
verify {
|
||||||
|
dismissTabTray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onSaveToCollectionClicked() {
|
||||||
|
val navDirectionsSlot = slot<NavDirections>()
|
||||||
|
every { navController.navigate(capture(navDirectionsSlot)) } just Runs
|
||||||
|
|
||||||
|
controller.onSaveToCollectionClicked()
|
||||||
|
verify {
|
||||||
|
registerCollectionStorageObserver()
|
||||||
|
navController.navigate(capture(navDirectionsSlot))
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(navDirectionsSlot.isCaptured)
|
||||||
|
assertEquals(
|
||||||
|
R.id.action_global_collectionCreationFragment,
|
||||||
|
navDirectionsSlot.captured.actionId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onShareTabsClicked() {
|
||||||
|
val navDirectionsSlot = slot<NavDirections>()
|
||||||
|
every { navController.navigate(capture(navDirectionsSlot)) } just Runs
|
||||||
|
|
||||||
|
controller.onShareTabsClicked(private = false)
|
||||||
|
|
||||||
|
verify {
|
||||||
|
navController.navigate(capture(navDirectionsSlot))
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTrue(navDirectionsSlot.isCaptured)
|
||||||
|
assertEquals(R.id.action_global_shareFragment, navDirectionsSlot.captured.actionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onCloseAllTabsClicked() {
|
||||||
|
controller.onCloseAllTabsClicked(private = false)
|
||||||
|
val snackbarMessage = activity.getString(R.string.snackbar_tabs_closed)
|
||||||
|
|
||||||
|
verify {
|
||||||
|
sessionManager.createSessionSnapshot(nonPrivateSession)
|
||||||
|
sessionManager.remove(nonPrivateSession)
|
||||||
|
showUndoSnackbar(snackbarMessage, any())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* 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.tabtray
|
||||||
|
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class TabTrayFragmentInteractorTest {
|
||||||
|
private val controller = mockk<TabTrayController>(relaxed = true)
|
||||||
|
private val interactor = TabTrayFragmentInteractor(controller)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onNewTabTapped() {
|
||||||
|
interactor.onNewTabTapped(private = true)
|
||||||
|
verify { controller.onNewTabTapped(true) }
|
||||||
|
|
||||||
|
interactor.onNewTabTapped(private = false)
|
||||||
|
verify { controller.onNewTabTapped(false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onTabTrayDismissed() {
|
||||||
|
interactor.onTabTrayDismissed()
|
||||||
|
verify { controller.onTabTrayDismissed() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onShareTabsClicked() {
|
||||||
|
interactor.onShareTabsClicked(private = true)
|
||||||
|
verify { controller.onShareTabsClicked(true) }
|
||||||
|
|
||||||
|
interactor.onShareTabsClicked(private = false)
|
||||||
|
verify { controller.onShareTabsClicked(false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onSaveToCollectionClicked() {
|
||||||
|
interactor.onSaveToCollectionClicked()
|
||||||
|
verify { controller.onSaveToCollectionClicked() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun onCloseAllTabsClicked() {
|
||||||
|
interactor.onCloseAllTabsClicked(private = false)
|
||||||
|
verify { controller.onCloseAllTabsClicked(false) }
|
||||||
|
|
||||||
|
interactor.onCloseAllTabsClicked(private = true)
|
||||||
|
verify { controller.onCloseAllTabsClicked(true) }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue