Refactor BrowserToolbarMenuController to use browser store

upstream-sync
Christian Sadilek 3 years ago
parent b6ac5079b2
commit c9b8f57f96

@ -318,17 +318,17 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
} }
) )
val browserToolbarMenuController = DefaultBrowserToolbarMenuController( val browserToolbarMenuController = DefaultBrowserToolbarMenuController(
store = store,
activity = activity, activity = activity,
navController = findNavController(), navController = findNavController(),
metrics = requireComponents.analytics.metrics, metrics = requireComponents.analytics.metrics,
settings = context.settings(), settings = context.settings(),
readerModeController = readerMenuController, readerModeController = readerMenuController,
sessionManager = requireComponents.core.sessionManager,
sessionFeature = sessionFeature, sessionFeature = sessionFeature,
findInPageLauncher = { findInPageIntegration.withFeature { it.launch() } }, findInPageLauncher = { findInPageIntegration.withFeature { it.launch() } },
swipeRefresh = swipeRefresh, swipeRefresh = swipeRefresh,
browserAnimator = browserAnimator, browserAnimator = browserAnimator,
customTabSession = customTabSessionId?.let { sessionManager.findSessionById(it) }, customTabSessionId = customTabSessionId,
openInFenixIntent = openInFenixIntent, openInFenixIntent = openInFenixIntent,
bookmarkTapped = { url: String, title: String -> bookmarkTapped = { url: String, title: String ->
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.lifecycleScope.launch {

@ -15,9 +15,10 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.appservices.places.BookmarkRoot import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.session.Session import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.state.SessionState
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.EngineSession.LoadUrlFlags import mozilla.components.concept.engine.EngineSession.LoadUrlFlags
import mozilla.components.concept.engine.prompt.ShareData import mozilla.components.concept.engine.prompt.ShareData
@ -53,17 +54,17 @@ interface BrowserToolbarMenuController {
@Suppress("LargeClass", "ForbiddenComment") @Suppress("LargeClass", "ForbiddenComment")
class DefaultBrowserToolbarMenuController( class DefaultBrowserToolbarMenuController(
private val store: BrowserStore,
private val activity: HomeActivity, private val activity: HomeActivity,
private val navController: NavController, private val navController: NavController,
private val metrics: MetricController, private val metrics: MetricController,
private val settings: Settings, private val settings: Settings,
private val readerModeController: ReaderModeController, private val readerModeController: ReaderModeController,
private val sessionFeature: ViewBoundFeatureWrapper<SessionFeature>, private val sessionFeature: ViewBoundFeatureWrapper<SessionFeature>,
private val sessionManager: SessionManager,
private val findInPageLauncher: () -> Unit, private val findInPageLauncher: () -> Unit,
private val browserAnimator: BrowserAnimator, private val browserAnimator: BrowserAnimator,
private val swipeRefresh: SwipeRefreshLayout, private val swipeRefresh: SwipeRefreshLayout,
private val customTabSession: Session?, private val customTabSessionId: String?,
private val openInFenixIntent: Intent, private val openInFenixIntent: Intent,
private val bookmarkTapped: (String, String) -> Unit, private val bookmarkTapped: (String, String) -> Unit,
private val scope: CoroutineScope, private val scope: CoroutineScope,
@ -73,7 +74,7 @@ class DefaultBrowserToolbarMenuController(
) : BrowserToolbarMenuController { ) : BrowserToolbarMenuController {
private val currentSession private val currentSession
get() = customTabSession ?: sessionManager.selectedSession get() = store.state.findCustomTabOrSelectedTab(customTabSessionId)
// We hold onto a reference of the inner scope so that we can override this with the // We hold onto a reference of the inner scope so that we can override this with the
// TestCoroutineScope to ensure sequential execution. If we didn't have this, our tests // TestCoroutineScope to ensure sequential execution. If we didn't have this, our tests
@ -84,6 +85,7 @@ class DefaultBrowserToolbarMenuController(
@Suppress("ComplexMethod", "LongMethod") @Suppress("ComplexMethod", "LongMethod")
override fun handleToolbarItemInteraction(item: ToolbarMenu.Item) { override fun handleToolbarItemInteraction(item: ToolbarMenu.Item) {
val sessionUseCases = activity.components.useCases.sessionUseCases val sessionUseCases = activity.components.useCases.sessionUseCases
val customTabUseCases = activity.components.useCases.customTabsUseCases
trackToolbarItemInteraction(item) trackToolbarItemInteraction(item)
Do exhaustive when (item) { Do exhaustive when (item) {
@ -104,26 +106,27 @@ class DefaultBrowserToolbarMenuController(
} }
} }
is ToolbarMenu.Item.OpenInFenix -> { is ToolbarMenu.Item.OpenInFenix -> {
// Stop the SessionFeature from updating the EngineView and let it release the session customTabSessionId?.let {
// from the EngineView so that it can immediately be rendered by a different view once // Stop the SessionFeature from updating the EngineView and let it release the session
// we switch to the actual browser. // from the EngineView so that it can immediately be rendered by a different view once
sessionFeature.get()?.release() // we switch to the actual browser.
sessionFeature.get()?.release()
// Strip the CustomTabConfig to turn this Session into a regular tab and then select it // Turn this Session into a regular tab and then select it
customTabSession!!.customTabConfig = null customTabUseCases.migrate(customTabSessionId, select = true)
sessionManager.select(customTabSession)
// Switch to the actual browser which should now display our new selected session // Switch to the actual browser which should now display our new selected session
activity.startActivity(openInFenixIntent.apply { activity.startActivity(openInFenixIntent.apply {
// We never want to launch the browser in the same task as the external app // We never want to launch the browser in the same task as the external app
// activity. So we force a new task here. IntentReceiverActivity will do the // activity. So we force a new task here. IntentReceiverActivity will do the
// right thing and take care of routing to an already existing browser and avoid // right thing and take care of routing to an already existing browser and avoid
// cloning a new one. // cloning a new one.
flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK
}) })
// Close this activity (and the task) since it is no longer displaying any session // Close this activity (and the task) since it is no longer displaying any session
activity.finishAndRemoveTask() activity.finishAndRemoveTask()
}
} }
is ToolbarMenu.Item.Quit -> { is ToolbarMenu.Item.Quit -> {
// We need to show the snackbar while the browsing data is deleting (if "Delete // We need to show the snackbar while the browsing data is deleting (if "Delete
@ -150,7 +153,7 @@ class DefaultBrowserToolbarMenuController(
val appLinksUseCases = activity.components.useCases.appLinksUseCases val appLinksUseCases = activity.components.useCases.appLinksUseCases
val getRedirect = appLinksUseCases.appLinkRedirect val getRedirect = appLinksUseCases.appLinkRedirect
currentSession?.let { currentSession?.let {
val redirect = getRedirect.invoke(it.url) val redirect = getRedirect.invoke(it.content.url)
redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK redirect.appIntent?.flags = Intent.FLAG_ACTIVITY_NEW_TASK
appLinksUseCases.openAppLink.invoke(redirect.appIntent) appLinksUseCases.openAppLink.invoke(redirect.appIntent)
} }
@ -161,22 +164,26 @@ class DefaultBrowserToolbarMenuController(
if (item.viewHistory) { if (item.viewHistory) {
navController.navigate( navController.navigate(
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment( BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSession?.id activeSessionId = customTabSessionId
) )
) )
} else { } else {
sessionUseCases.goBack.invoke(currentSession) currentSession?.let {
sessionUseCases.goBack.invoke(it.id)
}
} }
} }
is ToolbarMenu.Item.Forward -> { is ToolbarMenu.Item.Forward -> {
if (item.viewHistory) { if (item.viewHistory) {
navController.navigate( navController.navigate(
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment( BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSession?.id activeSessionId = customTabSessionId
) )
) )
} else { } else {
sessionUseCases.goForward.invoke(currentSession) currentSession?.let {
sessionUseCases.goForward.invoke(it.id)
}
} }
} }
is ToolbarMenu.Item.Reload -> { is ToolbarMenu.Item.Reload -> {
@ -186,15 +193,21 @@ class DefaultBrowserToolbarMenuController(
LoadUrlFlags.none() LoadUrlFlags.none()
} }
sessionUseCases.reload.invoke(currentSession, flags = flags) currentSession?.let {
sessionUseCases.reload.invoke(it.id, flags = flags)
}
}
is ToolbarMenu.Item.Stop -> {
currentSession?.let {
sessionUseCases.stopLoading.invoke(it.id)
}
} }
is ToolbarMenu.Item.Stop -> sessionUseCases.stopLoading.invoke(currentSession)
is ToolbarMenu.Item.Share -> { is ToolbarMenu.Item.Share -> {
val directions = NavGraphDirections.actionGlobalShareFragment( val directions = NavGraphDirections.actionGlobalShareFragment(
data = arrayOf( data = arrayOf(
ShareData( ShareData(
url = getProperUrl(currentSession), url = getProperUrl(currentSession),
title = currentSession?.title title = currentSession?.content?.title
) )
), ),
showPage = true showPage = true
@ -211,10 +224,14 @@ class DefaultBrowserToolbarMenuController(
BrowserFragmentDirections.actionBrowserFragmentToSyncedTabsFragment() BrowserFragmentDirections.actionBrowserFragmentToSyncedTabsFragment()
) )
} }
is ToolbarMenu.Item.RequestDesktop -> sessionUseCases.requestDesktopSite.invoke( is ToolbarMenu.Item.RequestDesktop -> {
item.isChecked, currentSession?.let {
currentSession sessionUseCases.requestDesktopSite.invoke(
) item.isChecked,
it.id
)
}
}
is ToolbarMenu.Item.AddToTopSites -> { is ToolbarMenu.Item.AddToTopSites -> {
scope.launch { scope.launch {
val context = swipeRefresh.context val context = swipeRefresh.context
@ -234,7 +251,7 @@ class DefaultBrowserToolbarMenuController(
ioScope.launch { ioScope.launch {
currentSession?.let { currentSession?.let {
with(activity.components.useCases.topSitesUseCase) { with(activity.components.useCases.topSitesUseCase) {
addPinnedSites(it.title, it.url) addPinnedSites(it.content.title, it.content.url)
} }
} }
}.join() }.join()
@ -294,8 +311,8 @@ class DefaultBrowserToolbarMenuController(
} }
} }
is ToolbarMenu.Item.Bookmark -> { is ToolbarMenu.Item.Bookmark -> {
sessionManager.selectedSession?.let { store.state.selectedTab?.let {
getProperUrl(it)?.let { url -> bookmarkTapped(url, it.title) } getProperUrl(it)?.let { url -> bookmarkTapped(url, it.content.title) }
} }
} }
is ToolbarMenu.Item.Bookmarks -> browserAnimator.captureEngineViewAndDrawStatically { is ToolbarMenu.Item.Bookmarks -> browserAnimator.captureEngineViewAndDrawStatically {
@ -325,13 +342,13 @@ class DefaultBrowserToolbarMenuController(
} }
} }
private fun getProperUrl(currentSession: Session?): String? { private fun getProperUrl(currentSession: SessionState?): String? {
return currentSession?.id?.let { return currentSession?.id?.let {
val currentTab = browserStore.state.findTab(it) val currentTab = browserStore.state.findTab(it)
if (currentTab?.readerState?.active == true) { if (currentTab?.readerState?.active == true) {
currentTab.readerState.activeUrl currentTab.readerState.activeUrl
} else { } else {
currentSession.url currentSession.content.url
} }
} }
} }

@ -24,10 +24,11 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runBlockingTest
import mozilla.appservices.places.BookmarkRoot import mozilla.appservices.places.BookmarkRoot
import mozilla.components.browser.session.Session import mozilla.components.browser.state.action.CustomTabListAction
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.ReaderState import mozilla.components.browser.state.state.ReaderState
import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.state.createCustomTab
import mozilla.components.browser.state.state.createTab import mozilla.components.browser.state.state.createTab
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.engine.EngineSession import mozilla.components.concept.engine.EngineSession
@ -36,9 +37,11 @@ import mozilla.components.feature.search.SearchUseCases
import mozilla.components.feature.session.SessionFeature import mozilla.components.feature.session.SessionFeature
import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.tabs.CustomTabsUseCases
import mozilla.components.feature.top.sites.DefaultTopSitesStorage import mozilla.components.feature.top.sites.DefaultTopSitesStorage
import mozilla.components.feature.top.sites.TopSitesUseCases import mozilla.components.feature.top.sites.TopSitesUseCases
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.rule.MainCoroutineRule import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -76,13 +79,12 @@ class DefaultBrowserToolbarMenuControllerTest {
@RelaxedMockK private lateinit var navController: NavController @RelaxedMockK private lateinit var navController: NavController
@RelaxedMockK private lateinit var findInPageLauncher: () -> Unit @RelaxedMockK private lateinit var findInPageLauncher: () -> Unit
@RelaxedMockK private lateinit var bookmarkTapped: (String, String) -> Unit @RelaxedMockK private lateinit var bookmarkTapped: (String, String) -> Unit
@RelaxedMockK private lateinit var sessionManager: SessionManager
@RelaxedMockK private lateinit var currentSession: Session
@RelaxedMockK private lateinit var openInFenixIntent: Intent @RelaxedMockK private lateinit var openInFenixIntent: Intent
@RelaxedMockK private lateinit var metrics: MetricController @RelaxedMockK private lateinit var metrics: MetricController
@RelaxedMockK private lateinit var settings: Settings @RelaxedMockK private lateinit var settings: Settings
@RelaxedMockK private lateinit var searchUseCases: SearchUseCases @RelaxedMockK private lateinit var searchUseCases: SearchUseCases
@RelaxedMockK private lateinit var sessionUseCases: SessionUseCases @RelaxedMockK private lateinit var sessionUseCases: SessionUseCases
@RelaxedMockK private lateinit var customTabUseCases: CustomTabsUseCases
@RelaxedMockK private lateinit var browserAnimator: BrowserAnimator @RelaxedMockK private lateinit var browserAnimator: BrowserAnimator
@RelaxedMockK private lateinit var snackbar: FenixSnackbar @RelaxedMockK private lateinit var snackbar: FenixSnackbar
@RelaxedMockK private lateinit var tabCollectionStorage: TabCollectionStorage @RelaxedMockK private lateinit var tabCollectionStorage: TabCollectionStorage
@ -91,7 +93,9 @@ class DefaultBrowserToolbarMenuControllerTest {
@MockK private lateinit var sessionFeatureWrapper: ViewBoundFeatureWrapper<SessionFeature> @MockK private lateinit var sessionFeatureWrapper: ViewBoundFeatureWrapper<SessionFeature>
@RelaxedMockK private lateinit var sessionFeature: SessionFeature @RelaxedMockK private lateinit var sessionFeature: SessionFeature
@RelaxedMockK private lateinit var topSitesStorage: DefaultTopSitesStorage @RelaxedMockK private lateinit var topSitesStorage: DefaultTopSitesStorage
@RelaxedMockK private lateinit var browserStore: BrowserStore
private lateinit var browserStore: BrowserStore
private lateinit var selectedTab: TabSessionState
@Before @Before
fun setUp() { fun setUp() {
@ -106,18 +110,25 @@ class DefaultBrowserToolbarMenuControllerTest {
every { FenixSnackbar.make(any(), any(), any(), any()) } returns snackbar every { FenixSnackbar.make(any(), any(), any(), any()) } returns snackbar
every { activity.components.useCases.sessionUseCases } returns sessionUseCases every { activity.components.useCases.sessionUseCases } returns sessionUseCases
every { activity.components.useCases.customTabsUseCases } returns customTabUseCases
every { activity.components.useCases.searchUseCases } returns searchUseCases every { activity.components.useCases.searchUseCases } returns searchUseCases
every { activity.components.useCases.topSitesUseCase } returns topSitesUseCase every { activity.components.useCases.topSitesUseCase } returns topSitesUseCase
every { sessionManager.selectedSession } returns currentSession
every { sessionFeatureWrapper.get() } returns sessionFeature every { sessionFeatureWrapper.get() } returns sessionFeature
every { navController.currentDestination } returns mockk { every { navController.currentDestination } returns mockk {
every { id } returns R.id.browserFragment every { id } returns R.id.browserFragment
} }
every { currentSession.id } returns "1"
every { settings.topSitesMaxLimit } returns 16 every { settings.topSitesMaxLimit } returns 16
val onComplete = slot<() -> Unit>() val onComplete = slot<() -> Unit>()
every { browserAnimator.captureEngineViewAndDrawStatically(capture(onComplete)) } answers { onComplete.captured.invoke() } every { browserAnimator.captureEngineViewAndDrawStatically(capture(onComplete)) } answers { onComplete.captured.invoke() }
selectedTab = createTab("https://www.mozilla.org", id = "1")
browserStore = BrowserStore(
initialState = BrowserState(
tabs = listOf(selectedTab),
selectedTabId = selectedTab.id
)
)
} }
@After @After
@ -134,23 +145,20 @@ class DefaultBrowserToolbarMenuControllerTest {
val item = ToolbarMenu.Item.Bookmark val item = ToolbarMenu.Item.Bookmark
val title = "Mozilla" val title = "Mozilla"
val readerUrl = "moz-extension://1234" val url = "https://mozilla.org"
val readerTab = createTab( val regularTab = createTab(
url = readerUrl, url = url,
readerState = ReaderState(active = false, activeUrl = "https://1234.org"), readerState = ReaderState(active = false, activeUrl = "https://1234.org"),
title = title title = title
) )
browserStore = val store =
BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) BrowserStore(BrowserState(tabs = listOf(regularTab), selectedTabId = regularTab.id))
every { currentSession.id } returns readerTab.id
every { currentSession.title } returns title
every { currentSession.url } returns "https://mozilla.org"
val controller = createController(scope = this) val controller = createController(scope = this, store = store)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) }
verify { bookmarkTapped("https://mozilla.org", title) } verify { bookmarkTapped(url, title) }
} }
} }
@ -167,11 +175,8 @@ class DefaultBrowserToolbarMenuControllerTest {
) )
browserStore = browserStore =
BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id))
every { currentSession.id } returns readerTab.id
every { currentSession.title } returns title
every { currentSession.url } returns readerUrl
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BOOKMARK)) }
@ -182,18 +187,22 @@ class DefaultBrowserToolbarMenuControllerTest {
@Test @Test
fun `WHEN open in Fenix menu item is pressed THEN menu item is handled correctly`() = runBlockingTest { fun `WHEN open in Fenix menu item is pressed THEN menu item is handled correctly`() = runBlockingTest {
if (!FeatureFlags.toolbarMenuFeature) { if (!FeatureFlags.toolbarMenuFeature) {
val controller = createController(scope = this, customTabSession = currentSession)
val customTab = createCustomTab("https://mozilla.org")
browserStore.dispatch(CustomTabListAction.AddCustomTabAction(customTab)).joinBlocking()
val controller = createController(
scope = this,
store = browserStore,
customTabSessionId = customTab.id
)
val item = ToolbarMenu.Item.OpenInFenix val item = ToolbarMenu.Item.OpenInFenix
every { currentSession.customTabConfig } returns mockk()
every { activity.startActivity(any()) } just Runs every { activity.startActivity(any()) } just Runs
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { sessionFeature.release() } verify { sessionFeature.release() }
verify { currentSession.customTabConfig = null } verify { customTabUseCases.migrate(customTab.id, true) }
verify { sessionManager.select(currentSession) }
verify { activity.startActivity(openInFenixIntent) } verify { activity.startActivity(openInFenixIntent) }
verify { activity.finishAndRemoveTask() } verify { activity.finishAndRemoveTask() }
} }
@ -205,7 +214,7 @@ class DefaultBrowserToolbarMenuControllerTest {
val item = ToolbarMenu.Item.Quit val item = ToolbarMenu.Item.Quit
val testScope = this val testScope = this
val controller = createController(scope = testScope) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
@ -218,7 +227,7 @@ class DefaultBrowserToolbarMenuControllerTest {
if (!FeatureFlags.toolbarMenuFeature) { if (!FeatureFlags.toolbarMenuFeature) {
val item = ToolbarMenu.Item.OpenInApp val item = ToolbarMenu.Item.OpenInApp
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
@ -230,7 +239,7 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN reader mode menu item is pressed THEN handle appearance change`() = runBlockingTest { fun `WHEN reader mode menu item is pressed THEN handle appearance change`() = runBlockingTest {
val item = ToolbarMenu.Item.ReaderModeAppearance val item = ToolbarMenu.Item.ReaderModeAppearance
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
@ -243,18 +252,18 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN backwards nav menu item is pressed THEN the session navigates back with active session`() = runBlockingTest { fun `WHEN backwards nav menu item is pressed THEN the session navigates back with active session`() = runBlockingTest {
val item = ToolbarMenu.Item.Back(false) val item = ToolbarMenu.Item.Back(false)
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BACK)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.BACK)) }
verify { sessionUseCases.goBack(currentSession) } verify { sessionUseCases.goBack(browserStore.state.selectedTabId!!) }
} }
@Test @Test
fun `WHEN backwards nav menu item is long pressed THEN the session navigates back with no active session`() = runBlockingTest { fun `WHEN backwards nav menu item is long pressed THEN the session navigates back with no active session`() = runBlockingTest {
val item = ToolbarMenu.Item.Back(true) val item = ToolbarMenu.Item.Back(true)
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
val directions = BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(null) val directions = BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(null)
@ -267,18 +276,18 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN forward nav menu item is pressed THEN the session navigates forward to active session`() = runBlockingTest { fun `WHEN forward nav menu item is pressed THEN the session navigates forward to active session`() = runBlockingTest {
val item = ToolbarMenu.Item.Forward(false) val item = ToolbarMenu.Item.Forward(false)
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.FORWARD)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.FORWARD)) }
verify { sessionUseCases.goForward(currentSession) } verify { sessionUseCases.goForward(selectedTab.id) }
} }
@Test @Test
fun `WHEN forward nav menu item is long pressed THEN the browser navigates forward with no active session`() = runBlockingTest { fun `WHEN forward nav menu item is long pressed THEN the browser navigates forward with no active session`() = runBlockingTest {
val item = ToolbarMenu.Item.Forward(true) val item = ToolbarMenu.Item.Forward(true)
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
val directions = BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(null) val directions = BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(null)
@ -291,24 +300,24 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN reload nav menu item is pressed THEN the session reloads from cache`() = runBlockingTest { fun `WHEN reload nav menu item is pressed THEN the session reloads from cache`() = runBlockingTest {
val item = ToolbarMenu.Item.Reload(false) val item = ToolbarMenu.Item.Reload(false)
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.RELOAD)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.RELOAD)) }
verify { sessionUseCases.reload(currentSession) } verify { sessionUseCases.reload(selectedTab.id) }
} }
@Test @Test
fun `WHEN reload nav menu item is long pressed THEN the session reloads with no cache`() = runBlockingTest { fun `WHEN reload nav menu item is long pressed THEN the session reloads with no cache`() = runBlockingTest {
val item = ToolbarMenu.Item.Reload(true) val item = ToolbarMenu.Item.Reload(true)
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.RELOAD)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.RELOAD)) }
verify { verify {
sessionUseCases.reload( sessionUseCases.reload(
currentSession, selectedTab.id,
EngineSession.LoadUrlFlags.select(EngineSession.LoadUrlFlags.BYPASS_CACHE) EngineSession.LoadUrlFlags.select(EngineSession.LoadUrlFlags.BYPASS_CACHE)
) )
} }
@ -318,18 +327,18 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN stop nav menu item is pressed THEN the session stops loading`() = runBlockingTest { fun `WHEN stop nav menu item is pressed THEN the session stops loading`() = runBlockingTest {
val item = ToolbarMenu.Item.Stop val item = ToolbarMenu.Item.Stop
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.STOP)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.STOP)) }
verify { sessionUseCases.stopLoading(currentSession) } verify { sessionUseCases.stopLoading(selectedTab.id) }
} }
@Test @Test
fun `WHEN settings menu item is pressed THEN menu item is handled`() = runBlockingTest { fun `WHEN settings menu item is pressed THEN menu item is handled`() = runBlockingTest {
val item = ToolbarMenu.Item.Settings val item = ToolbarMenu.Item.Settings
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment() val directions = BrowserFragmentDirections.actionBrowserFragmentToSettingsFragment()
@ -342,7 +351,7 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN bookmark menu item is pressed THEN navigate to bookmarks page`() = runBlockingTest { fun `WHEN bookmark menu item is pressed THEN navigate to bookmarks page`() = runBlockingTest {
val item = ToolbarMenu.Item.Bookmarks val item = ToolbarMenu.Item.Bookmarks
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
val directions = BrowserFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id) val directions = BrowserFragmentDirections.actionGlobalBookmarkFragment(BookmarkRoot.Mobile.id)
@ -355,7 +364,7 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN history menu item is pressed THEN navigate to history page`() = runBlockingTest { fun `WHEN history menu item is pressed THEN navigate to history page`() = runBlockingTest {
val item = ToolbarMenu.Item.History val item = ToolbarMenu.Item.History
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
val directions = BrowserFragmentDirections.actionGlobalHistoryFragment() val directions = BrowserFragmentDirections.actionGlobalHistoryFragment()
@ -372,14 +381,14 @@ class DefaultBrowserToolbarMenuControllerTest {
every { sessionUseCases.requestDesktopSite } returns requestDesktopSiteUseCase every { sessionUseCases.requestDesktopSite } returns requestDesktopSiteUseCase
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_ON)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_ON)) }
verify { verify {
requestDesktopSiteUseCase.invoke( requestDesktopSiteUseCase.invoke(
true, true,
currentSession selectedTab.id
) )
} }
} }
@ -392,14 +401,14 @@ class DefaultBrowserToolbarMenuControllerTest {
every { sessionUseCases.requestDesktopSite } returns requestDesktopSiteUseCase every { sessionUseCases.requestDesktopSite } returns requestDesktopSiteUseCase
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_OFF)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.DESKTOP_VIEW_OFF)) }
verify { verify {
requestDesktopSiteUseCase.invoke( requestDesktopSiteUseCase.invoke(
false, false,
currentSession selectedTab.id
) )
} }
} }
@ -414,10 +423,10 @@ class DefaultBrowserToolbarMenuControllerTest {
swipeRefreshLayout.context.getString(R.string.snackbar_added_to_top_sites) swipeRefreshLayout.context.getString(R.string.snackbar_added_to_top_sites)
} returns "Added to top sites!" } returns "Added to top sites!"
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { addPinnedSiteUseCase.invoke(currentSession.title, currentSession.url) } verify { addPinnedSiteUseCase.invoke(selectedTab.content.title, selectedTab.content.url) }
verify { snackbar.setText("Added to top sites!") } verify { snackbar.setText("Added to top sites!") }
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADD_TO_TOP_SITES)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADD_TO_TOP_SITES)) }
} }
@ -426,7 +435,7 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN addon extensions menu item is pressed THEN navigate to addons manager`() = runBlockingTest { fun `WHEN addon extensions menu item is pressed THEN navigate to addons manager`() = runBlockingTest {
val item = ToolbarMenu.Item.AddonsManager val item = ToolbarMenu.Item.AddonsManager
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADDONS_MANAGER)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADDONS_MANAGER)) }
@ -436,7 +445,7 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN Add To Home Screen menu item is pressed THEN add site`() = runBlockingTest { fun `WHEN Add To Home Screen menu item is pressed THEN add site`() = runBlockingTest {
val item = ToolbarMenu.Item.AddToHomeScreen val item = ToolbarMenu.Item.AddToHomeScreen
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.ADD_TO_HOMESCREEN)) }
@ -446,18 +455,14 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `IF reader mode is inactive WHEN share menu item is pressed THEN navigate to share screen`() = runBlockingTest { fun `IF reader mode is inactive WHEN share menu item is pressed THEN navigate to share screen`() = runBlockingTest {
val item = ToolbarMenu.Item.Share val item = ToolbarMenu.Item.Share
val title = "Mozilla" val title = "Mozilla"
val readerUrl = "moz-extension://1234" val url = "https://mozilla.org"
val readerTab = createTab( val regularTab = createTab(
url = readerUrl, url = url,
readerState = ReaderState(active = false, activeUrl = "https://1234.org"), readerState = ReaderState(active = false, activeUrl = "https://1234.org"),
title = title title = title
) )
browserStore = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) browserStore = BrowserStore(BrowserState(tabs = listOf(regularTab), selectedTabId = regularTab.id))
every { currentSession.id } returns readerTab.id val controller = createController(scope = this, store = browserStore)
every { currentSession.title } returns title
every { currentSession.url } returns "https://mozilla.org"
val controller = createController(scope = this)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SHARE)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SHARE)) }
@ -484,11 +489,7 @@ class DefaultBrowserToolbarMenuControllerTest {
title = title title = title
) )
browserStore = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id)) browserStore = BrowserStore(BrowserState(tabs = listOf(readerTab), selectedTabId = readerTab.id))
every { currentSession.id } returns readerTab.id val controller = createController(scope = this, store = browserStore)
every { currentSession.title } returns title
every { currentSession.url } returns readerUrl
val controller = createController(scope = this)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SHARE)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SHARE)) }
@ -508,7 +509,7 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN Find In Page menu item is pressed THEN launch finder`() = runBlockingTest { fun `WHEN Find In Page menu item is pressed THEN launch finder`() = runBlockingTest {
val item = ToolbarMenu.Item.FindInPage val item = ToolbarMenu.Item.FindInPage
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { findInPageLauncher() } verify { findInPageLauncher() }
@ -521,7 +522,7 @@ class DefaultBrowserToolbarMenuControllerTest {
val cachedTabCollections: List<TabCollection> = mockk(relaxed = true) val cachedTabCollections: List<TabCollection> = mockk(relaxed = true)
every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollections every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollections
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { verify {
@ -537,8 +538,8 @@ class DefaultBrowserToolbarMenuControllerTest {
val directions = BrowserFragmentDirections.actionGlobalCollectionCreationFragment( val directions = BrowserFragmentDirections.actionGlobalCollectionCreationFragment(
saveCollectionStep = SaveCollectionStep.SelectCollection, saveCollectionStep = SaveCollectionStep.SelectCollection,
tabIds = arrayOf(currentSession.id), tabIds = arrayOf(selectedTab.id),
selectedTabIds = arrayOf(currentSession.id) selectedTabIds = arrayOf(selectedTab.id)
) )
verify { navController.navigate(directionsEq(directions), null) } verify { navController.navigate(directionsEq(directions), null) }
} }
@ -549,7 +550,7 @@ class DefaultBrowserToolbarMenuControllerTest {
val cachedTabCollectionsEmpty: List<TabCollection> = emptyList() val cachedTabCollectionsEmpty: List<TabCollection> = emptyList()
every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollectionsEmpty every { tabCollectionStorage.cachedTabCollections } returns cachedTabCollectionsEmpty
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION)) } verify { metrics.track(Event.BrowserMenuItemTapped(Event.BrowserMenuItemTapped.Item.SAVE_TO_COLLECTION)) }
@ -562,8 +563,8 @@ class DefaultBrowserToolbarMenuControllerTest {
} }
val directions = BrowserFragmentDirections.actionGlobalCollectionCreationFragment( val directions = BrowserFragmentDirections.actionGlobalCollectionCreationFragment(
saveCollectionStep = SaveCollectionStep.NameCollection, saveCollectionStep = SaveCollectionStep.NameCollection,
tabIds = arrayOf(currentSession.id), tabIds = arrayOf(selectedTab.id),
selectedTabIds = arrayOf(currentSession.id) selectedTabIds = arrayOf(selectedTab.id)
) )
verify { navController.navigate(directionsEq(directions), null) } verify { navController.navigate(directionsEq(directions), null) }
} }
@ -572,7 +573,7 @@ class DefaultBrowserToolbarMenuControllerTest {
fun `WHEN New Tab menu item is pressed THEN navigate to a new tab home`() = runBlockingTest { fun `WHEN New Tab menu item is pressed THEN navigate to a new tab home`() = runBlockingTest {
val item = ToolbarMenu.Item.NewTab val item = ToolbarMenu.Item.NewTab
val controller = createController(scope = this) val controller = createController(scope = this, store = browserStore)
controller.handleToolbarItemInteraction(item) controller.handleToolbarItemInteraction(item)
@ -589,23 +590,24 @@ class DefaultBrowserToolbarMenuControllerTest {
private fun createController( private fun createController(
scope: CoroutineScope, scope: CoroutineScope,
store: BrowserStore,
activity: HomeActivity = this.activity, activity: HomeActivity = this.activity,
customTabSession: Session? = null customTabSessionId: String? = null
) = DefaultBrowserToolbarMenuController( ) = DefaultBrowserToolbarMenuController(
store = store,
activity = activity, activity = activity,
navController = navController, navController = navController,
metrics = metrics, metrics = metrics,
settings = settings, settings = settings,
findInPageLauncher = findInPageLauncher, findInPageLauncher = findInPageLauncher,
browserAnimator = browserAnimator, browserAnimator = browserAnimator,
customTabSession = customTabSession, customTabSessionId = customTabSessionId,
openInFenixIntent = openInFenixIntent, openInFenixIntent = openInFenixIntent,
scope = scope, scope = scope,
swipeRefresh = swipeRefreshLayout, swipeRefresh = swipeRefreshLayout,
tabCollectionStorage = tabCollectionStorage, tabCollectionStorage = tabCollectionStorage,
bookmarkTapped = bookmarkTapped, bookmarkTapped = bookmarkTapped,
readerModeController = readerModeController, readerModeController = readerModeController,
sessionManager = sessionManager,
sessionFeature = sessionFeatureWrapper, sessionFeature = sessionFeatureWrapper,
topSitesStorage = topSitesStorage, topSitesStorage = topSitesStorage,
browserStore = browserStore browserStore = browserStore

Loading…
Cancel
Save