Closes #11290: Refactor ToolbarMenu to use browser store

upstream-sync
Christian Sadilek 4 years ago
parent 04736ed878
commit d1345e8f93

@ -160,9 +160,9 @@ class BrowserToolbarView(
val menuToolbar: ToolbarMenu val menuToolbar: ToolbarMenu
if (isCustomTabSession) { if (isCustomTabSession) {
menuToolbar = CustomTabToolbarMenu( menuToolbar = CustomTabToolbarMenu(
this, context = this,
sessionManager, store = components.core.store,
customTabSession?.id, sessionId = customTabSession?.id,
shouldReverseItems = toolbarPosition == ToolbarPosition.TOP, shouldReverseItems = toolbarPosition == ToolbarPosition.TOP,
onItemTapped = { onItemTapped = {
it.performHapticIfNeeded(view) it.performHapticIfNeeded(view)
@ -179,7 +179,6 @@ class BrowserToolbarView(
interactor.onBrowserToolbarMenuItemTapped(it) interactor.onBrowserToolbarMenuItemTapped(it)
}, },
lifecycleOwner = lifecycleOwner, lifecycleOwner = lifecycleOwner,
sessionManager = sessionManager,
store = components.core.store, store = components.core.store,
bookmarksStorage = bookmarkStorage, bookmarksStorage = bookmarkStorage,
isPinningSupported = isPinningSupported isPinningSupported = isPinningSupported

@ -6,10 +6,14 @@ package org.mozilla.fenix.components.toolbar
import android.content.Context import android.content.Context
import androidx.annotation.ColorRes import androidx.annotation.ColorRes
import androidx.annotation.VisibleForTesting
import androidx.core.content.ContextCompat.getColor import androidx.core.content.ContextCompat.getColor
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.components.browser.menu.BrowserMenuHighlight import mozilla.components.browser.menu.BrowserMenuHighlight
import mozilla.components.browser.menu.WebExtensionBrowserMenuBuilder import mozilla.components.browser.menu.WebExtensionBrowserMenuBuilder
@ -19,13 +23,15 @@ import mozilla.components.browser.menu.item.BrowserMenuImageSwitch
import mozilla.components.browser.menu.item.BrowserMenuImageText import mozilla.components.browser.menu.item.BrowserMenuImageText
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
import mozilla.components.browser.menu.item.WebExtensionPlaceholderMenuItem import mozilla.components.browser.menu.item.WebExtensionPlaceholderMenuItem
import mozilla.components.browser.session.Session
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.TabSessionState
import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.storage.BookmarksStorage import mozilla.components.concept.storage.BookmarksStorage
import mozilla.components.feature.webcompat.reporter.WebCompatReporterFeature import mozilla.components.feature.webcompat.reporter.WebCompatReporterFeature
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifAnyChanged
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.browser.browsingmode.BrowsingMode
@ -36,7 +42,7 @@ import org.mozilla.fenix.theme.ThemeManager
/** /**
* Builds the toolbar object used with the 3-dot menu in the browser fragment. * Builds the toolbar object used with the 3-dot menu in the browser fragment.
* @param sessionManager Reference to the session manager that contains all tabs. * @param store reference to the application's [BrowserStore].
* @param hasAccountProblem If true, there was a problem signing into the Firefox account. * @param hasAccountProblem If true, there was a problem signing into the Firefox account.
* @param shouldReverseItems If true, reverse the menu items. * @param shouldReverseItems If true, reverse the menu items.
* @param onItemTapped Called when a menu item is tapped. * @param onItemTapped Called when a menu item is tapped.
@ -44,9 +50,9 @@ import org.mozilla.fenix.theme.ThemeManager
* @param bookmarksStorage Used to check if a page is bookmarked. * @param bookmarksStorage Used to check if a page is bookmarked.
*/ */
@Suppress("LargeClass", "LongParameterList") @Suppress("LargeClass", "LongParameterList")
@ExperimentalCoroutinesApi
class DefaultToolbarMenu( class DefaultToolbarMenu(
private val context: Context, private val context: Context,
private val sessionManager: SessionManager,
private val store: BrowserStore, private val store: BrowserStore,
hasAccountProblem: Boolean = false, hasAccountProblem: Boolean = false,
shouldReverseItems: Boolean, shouldReverseItems: Boolean,
@ -59,8 +65,7 @@ class DefaultToolbarMenu(
private var currentUrlIsBookmarked = false private var currentUrlIsBookmarked = false
private var isBookmarkedJob: Job? = null private var isBookmarkedJob: Job? = null
/** Gets the current browser session */ private val selectedSession: TabSessionState? get() = store.state.selectedTab
private val session: Session? get() = sessionManager.selectedSession
override val menuBuilder by lazy { override val menuBuilder by lazy {
WebExtensionBrowserMenuBuilder( WebExtensionBrowserMenuBuilder(
@ -81,7 +86,7 @@ class DefaultToolbarMenu(
primaryContentDescription = context.getString(R.string.browser_menu_back), primaryContentDescription = context.getString(R.string.browser_menu_back),
primaryImageTintResource = primaryTextColor(), primaryImageTintResource = primaryTextColor(),
isInPrimaryState = { isInPrimaryState = {
session?.canGoBack ?: true selectedSession?.content?.canGoBack ?: true
}, },
secondaryImageTintResource = ThemeManager.resolveAttribute(R.attr.disabled, context), secondaryImageTintResource = ThemeManager.resolveAttribute(R.attr.disabled, context),
disableInSecondaryState = true, disableInSecondaryState = true,
@ -95,7 +100,7 @@ class DefaultToolbarMenu(
primaryContentDescription = context.getString(R.string.browser_menu_forward), primaryContentDescription = context.getString(R.string.browser_menu_forward),
primaryImageTintResource = primaryTextColor(), primaryImageTintResource = primaryTextColor(),
isInPrimaryState = { isInPrimaryState = {
session?.canGoForward ?: true selectedSession?.content?.canGoForward ?: true
}, },
secondaryImageTintResource = ThemeManager.resolveAttribute(R.attr.disabled, context), secondaryImageTintResource = ThemeManager.resolveAttribute(R.attr.disabled, context),
disableInSecondaryState = true, disableInSecondaryState = true,
@ -109,7 +114,7 @@ class DefaultToolbarMenu(
primaryContentDescription = context.getString(R.string.browser_menu_refresh), primaryContentDescription = context.getString(R.string.browser_menu_refresh),
primaryImageTintResource = primaryTextColor(), primaryImageTintResource = primaryTextColor(),
isInPrimaryState = { isInPrimaryState = {
session?.loading == false selectedSession?.content?.loading == false
}, },
secondaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_stop, secondaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_stop,
secondaryContentDescription = context.getString(R.string.browser_menu_stop), secondaryContentDescription = context.getString(R.string.browser_menu_stop),
@ -117,7 +122,7 @@ class DefaultToolbarMenu(
disableInSecondaryState = false, disableInSecondaryState = false,
longClickListener = { onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = true)) } longClickListener = { onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = true)) }
) { ) {
if (session?.loading == true) { if (selectedSession?.content?.loading == true) {
onItemTapped.invoke(ToolbarMenu.Item.Stop) onItemTapped.invoke(ToolbarMenu.Item.Stop)
} else { } else {
onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = false)) onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = false))
@ -157,19 +162,19 @@ class DefaultToolbarMenu(
// Predicates that need to be repeatedly called as the session changes // Predicates that need to be repeatedly called as the session changes
private fun canAddToHomescreen(): Boolean = private fun canAddToHomescreen(): Boolean =
session != null && isPinningSupported && selectedSession != null && isPinningSupported &&
!context.components.useCases.webAppUseCases.isInstallable() !context.components.useCases.webAppUseCases.isInstallable()
private fun canInstall(): Boolean = private fun canInstall(): Boolean =
session != null && isPinningSupported && selectedSession != null && isPinningSupported &&
context.components.useCases.webAppUseCases.isInstallable() context.components.useCases.webAppUseCases.isInstallable()
private fun shouldShowOpenInApp(): Boolean = session?.let { session -> private fun shouldShowOpenInApp(): Boolean = selectedSession?.let { session ->
val appLink = context.components.useCases.appLinksUseCases.appLinkRedirect val appLink = context.components.useCases.appLinksUseCases.appLinkRedirect
appLink(session.url).hasExternalApp() appLink(session.content.url).hasExternalApp()
} ?: false } ?: false
private fun shouldShowReaderAppearance(): Boolean = session?.let { private fun shouldShowReaderAppearance(): Boolean = selectedSession?.let {
store.state.findTab(it.id)?.readerState?.active store.state.findTab(it.id)?.readerState?.active
} ?: false } ?: false
// End of predicates // // End of predicates //
@ -234,7 +239,7 @@ class DefaultToolbarMenu(
imageResource = R.drawable.ic_desktop, imageResource = R.drawable.ic_desktop,
label = context.getString(R.string.browser_menu_desktop_site), label = context.getString(R.string.browser_menu_desktop_site),
initialState = { initialState = {
session?.desktopMode ?: false selectedSession?.content?.desktopMode ?: false
} }
) { checked -> ) { checked ->
onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked))
@ -353,44 +358,28 @@ class DefaultToolbarMenu(
} }
@ColorRes @ColorRes
private fun primaryTextColor() = ThemeManager.resolveAttribute(R.attr.primaryText, context) @VisibleForTesting
internal fun primaryTextColor() = ThemeManager.resolveAttribute(R.attr.primaryText, context)
private var currentSessionObserver: Pair<Session, Session.Observer>? = null
@VisibleForTesting
private fun registerForIsBookmarkedUpdates() { internal fun registerForIsBookmarkedUpdates() {
session?.let { store.flowScoped(lifecycleOwner) { flow ->
registerForUrlChanges(it) flow.mapNotNull { state -> state.selectedTab }
} .ifAnyChanged { tab ->
arrayOf(
val sessionManagerObserver = object : SessionManager.Observer { tab.id,
override fun onSessionSelected(session: Session) { tab.content.url
// Unregister any old session observer before registering a new session observer )
currentSessionObserver?.let { }
it.first.unregister(it.second) .collect {
currentUrlIsBookmarked = false
updateCurrentUrlIsBookmarked(it.content.url)
} }
currentUrlIsBookmarked = false
updateCurrentUrlIsBookmarked(session.url)
registerForUrlChanges(session)
}
}
sessionManager.register(sessionManagerObserver, lifecycleOwner)
}
private fun registerForUrlChanges(session: Session) {
val sessionObserver = object : Session.Observer {
override fun onUrlChanged(session: Session, url: String) {
currentUrlIsBookmarked = false
updateCurrentUrlIsBookmarked(url)
}
} }
currentSessionObserver = Pair(session, sessionObserver)
updateCurrentUrlIsBookmarked(session.url)
session.register(sessionObserver, lifecycleOwner)
} }
private fun updateCurrentUrlIsBookmarked(newUrl: String) { @VisibleForTesting
internal fun updateCurrentUrlIsBookmarked(newUrl: String) {
isBookmarkedJob?.cancel() isBookmarkedJob?.cancel()
isBookmarkedJob = lifecycleOwner.lifecycleScope.launch { isBookmarkedJob = lifecycleOwner.lifecycleScope.launch {
currentUrlIsBookmarked = bookmarksStorage currentUrlIsBookmarked = bookmarksStorage

@ -17,8 +17,9 @@ import mozilla.components.browser.menu.item.BrowserMenuImageSwitch
import mozilla.components.browser.menu.item.BrowserMenuImageText import mozilla.components.browser.menu.item.BrowserMenuImageText
import mozilla.components.browser.menu.item.BrowserMenuItemToolbar import mozilla.components.browser.menu.item.BrowserMenuItemToolbar
import mozilla.components.browser.menu.item.SimpleBrowserMenuItem import mozilla.components.browser.menu.item.SimpleBrowserMenuItem
import mozilla.components.browser.session.Session import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.session.SessionManager import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.browser.state.store.BrowserStore
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.toolbar.ToolbarMenu import org.mozilla.fenix.components.toolbar.ToolbarMenu
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
@ -29,14 +30,14 @@ import java.util.Locale
/** /**
* Builds the toolbar object used with the 3-dot menu in the custom tab browser fragment. * Builds the toolbar object used with the 3-dot menu in the custom tab browser fragment.
* @param sessionManager Reference to the session manager that contains all tabs. * @param store reference to the application's [BrowserStore].
* @param sessionId ID of the open custom tab session. * @param sessionId ID of the open custom tab session.
* @param shouldReverseItems If true, reverse the menu items. * @param shouldReverseItems If true, reverse the menu items.
* @param onItemTapped Called when a menu item is tapped. * @param onItemTapped Called when a menu item is tapped.
*/ */
class CustomTabToolbarMenu( class CustomTabToolbarMenu(
private val context: Context, private val context: Context,
private val sessionManager: SessionManager, private val store: BrowserStore,
private val sessionId: String?, private val sessionId: String?,
private val shouldReverseItems: Boolean, private val shouldReverseItems: Boolean,
private val onItemTapped: (ToolbarMenu.Item) -> Unit = {} private val onItemTapped: (ToolbarMenu.Item) -> Unit = {}
@ -45,7 +46,7 @@ class CustomTabToolbarMenu(
override val menuBuilder by lazy { BrowserMenuBuilder(menuItems) } override val menuBuilder by lazy { BrowserMenuBuilder(menuItems) }
/** Gets the current custom tab session */ /** Gets the current custom tab session */
private val session: Session? get() = sessionId?.let { sessionManager.findSessionById(it) } private val session: TabSessionState? get() = sessionId?.let { store.state.findTab(it) }
private val appName = context.getString(R.string.app_name) private val appName = context.getString(R.string.app_name)
override val menuToolbar by lazy { override val menuToolbar by lazy {
@ -54,7 +55,7 @@ class CustomTabToolbarMenu(
primaryContentDescription = context.getString(R.string.browser_menu_back), primaryContentDescription = context.getString(R.string.browser_menu_back),
primaryImageTintResource = primaryTextColor(), primaryImageTintResource = primaryTextColor(),
isInPrimaryState = { isInPrimaryState = {
session?.canGoBack ?: true session?.content?.canGoBack ?: true
}, },
secondaryImageTintResource = ThemeManager.resolveAttribute( secondaryImageTintResource = ThemeManager.resolveAttribute(
R.attr.disabled, R.attr.disabled,
@ -71,7 +72,7 @@ class CustomTabToolbarMenu(
primaryContentDescription = context.getString(R.string.browser_menu_forward), primaryContentDescription = context.getString(R.string.browser_menu_forward),
primaryImageTintResource = primaryTextColor(), primaryImageTintResource = primaryTextColor(),
isInPrimaryState = { isInPrimaryState = {
session?.canGoForward ?: true session?.content?.canGoForward ?: true
}, },
secondaryImageTintResource = ThemeManager.resolveAttribute( secondaryImageTintResource = ThemeManager.resolveAttribute(
R.attr.disabled, R.attr.disabled,
@ -88,7 +89,7 @@ class CustomTabToolbarMenu(
primaryContentDescription = context.getString(R.string.browser_menu_refresh), primaryContentDescription = context.getString(R.string.browser_menu_refresh),
primaryImageTintResource = primaryTextColor(), primaryImageTintResource = primaryTextColor(),
isInPrimaryState = { isInPrimaryState = {
session?.loading == false session?.content?.loading == false
}, },
secondaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_stop, secondaryImageResource = mozilla.components.ui.icons.R.drawable.mozac_ic_stop,
secondaryContentDescription = context.getString(R.string.browser_menu_stop), secondaryContentDescription = context.getString(R.string.browser_menu_stop),
@ -96,7 +97,7 @@ class CustomTabToolbarMenu(
disableInSecondaryState = false, disableInSecondaryState = false,
longClickListener = { onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = true)) } longClickListener = { onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = true)) }
) { ) {
if (session?.loading == true) { if (session?.content?.loading == true) {
onItemTapped.invoke(ToolbarMenu.Item.Stop) onItemTapped.invoke(ToolbarMenu.Item.Stop)
} else { } else {
onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = false)) onItemTapped.invoke(ToolbarMenu.Item.Reload(bypassCache = false))
@ -108,7 +109,7 @@ class CustomTabToolbarMenu(
private fun shouldShowOpenInApp(): Boolean = session?.let { session -> private fun shouldShowOpenInApp(): Boolean = session?.let { session ->
val appLink = context.components.useCases.appLinksUseCases.appLinkRedirect val appLink = context.components.useCases.appLinksUseCases.appLinkRedirect
appLink(session.url).hasExternalApp() appLink(session.content.url).hasExternalApp()
} ?: false } ?: false
private val menuItems by lazy { private val menuItems by lazy {
@ -132,7 +133,7 @@ class CustomTabToolbarMenu(
private val desktopMode = BrowserMenuImageSwitch( private val desktopMode = BrowserMenuImageSwitch(
imageResource = R.drawable.ic_desktop, imageResource = R.drawable.ic_desktop,
label = context.getString(R.string.browser_menu_desktop_site), label = context.getString(R.string.browser_menu_desktop_site),
initialState = { session?.desktopMode ?: false } initialState = { session?.content?.desktopMode ?: false }
) { checked -> ) { checked ->
onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked)) onItemTapped.invoke(ToolbarMenu.Item.RequestDesktop(checked))
} }

@ -7,6 +7,7 @@ package org.mozilla.fenix.customtabs
import android.app.Activity import android.app.Activity
import androidx.appcompat.content.res.AppCompatResources.getDrawable import androidx.appcompat.content.res.AppCompatResources.getDrawable
import mozilla.components.browser.session.SessionManager import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.toolbar.BrowserToolbar import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.browser.toolbar.display.DisplayToolbar import mozilla.components.browser.toolbar.display.DisplayToolbar
import mozilla.components.feature.customtabs.CustomTabsToolbarFeature import mozilla.components.feature.customtabs.CustomTabsToolbarFeature
@ -18,6 +19,7 @@ import org.mozilla.fenix.ext.settings
class CustomTabsIntegration( class CustomTabsIntegration(
sessionManager: SessionManager, sessionManager: SessionManager,
store: BrowserStore,
toolbar: BrowserToolbar, toolbar: BrowserToolbar,
sessionId: String, sessionId: String,
activity: Activity, activity: Activity,
@ -74,7 +76,7 @@ class CustomTabsIntegration(
private val customTabToolbarMenu by lazy { private val customTabToolbarMenu by lazy {
CustomTabToolbarMenu( CustomTabToolbarMenu(
activity, activity,
sessionManager, store,
sessionId, sessionId,
shouldReverseItems, shouldReverseItems,
onItemTapped = onItemTapped onItemTapped = onItemTapped

@ -65,6 +65,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
customTabsIntegration.set( customTabsIntegration.set(
feature = CustomTabsIntegration( feature = CustomTabsIntegration(
sessionManager = requireComponents.core.sessionManager, sessionManager = requireComponents.core.sessionManager,
store = requireComponents.core.store,
toolbar = toolbar, toolbar = toolbar,
sessionId = customTabSessionId, sessionId = customTabSessionId,
activity = activity, activity = activity,

@ -0,0 +1,115 @@
/* 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.toolbar
import android.content.Context
import android.net.Uri
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.unmockkStatic
import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher
import mozilla.components.browser.state.action.ContentAction
import mozilla.components.browser.state.action.TabListAction
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.createTab
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.concept.storage.BookmarksStorage
import mozilla.components.support.test.ext.joinBlocking
import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.After
import org.junit.Assert.assertNotNull
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.components.toolbar.DefaultToolbarMenu
@ExperimentalCoroutinesApi
class DefaultToolbarMenuTest {
private lateinit var store: BrowserStore
private lateinit var lifecycleOwner: MockedLifecycleOwner
private lateinit var toolbarMenu: DefaultToolbarMenu
private lateinit var context: Context
private lateinit var bookmarksStorage: BookmarksStorage
private val testDispatcher = TestCoroutineDispatcher()
@get:Rule
val coroutinesTestRule = MainCoroutineRule(testDispatcher)
@Before
fun setUp() {
mockkStatic(Uri::class)
every { Uri.parse(any()) } returns mockk(relaxed = true)
context = mockk(relaxed = true)
every { context.theme } returns mockk(relaxed = true)
bookmarksStorage = mockk(relaxed = true)
store = BrowserStore(
BrowserState(
tabs = listOf(
createTab(url = "https://firefox.com", id = "1"),
createTab(url = "https://getpocket.com", id = "2")
), selectedTabId = "1"
)
)
lifecycleOwner = MockedLifecycleOwner(Lifecycle.State.STARTED)
toolbarMenu = spyk(DefaultToolbarMenu(
context = context,
store = store,
hasAccountProblem = false,
shouldReverseItems = false,
onItemTapped = { },
lifecycleOwner = lifecycleOwner,
bookmarksStorage = bookmarksStorage,
isPinningSupported = false
))
every { toolbarMenu.updateCurrentUrlIsBookmarked(any()) } returns Unit
}
@After
fun tearDown() {
unmockkStatic(Uri::class)
}
@Test
fun `WHEN url changes THEN bookmarked state is updated`() {
toolbarMenu.registerForIsBookmarkedUpdates()
val newUrl = "https://mozilla.org"
store.dispatch(ContentAction.UpdateUrlAction("1", newUrl)).joinBlocking()
verify(exactly = 1) { toolbarMenu.updateCurrentUrlIsBookmarked(newUrl) }
}
@Test
fun `WHEN selected tab changes THEN bookmarked state is updated`() {
toolbarMenu.registerForIsBookmarkedUpdates()
val newSelectedTab = store.state.findTab("2")
assertNotNull(newSelectedTab)
store.dispatch(TabListAction.SelectTabAction(newSelectedTab!!.id)).joinBlocking()
verify(exactly = 1) { toolbarMenu.updateCurrentUrlIsBookmarked(newSelectedTab.content.url) }
}
internal class MockedLifecycleOwner(initialState: Lifecycle.State) : LifecycleOwner {
val lifecycleRegistry = LifecycleRegistry(this).apply {
currentState = initialState
}
override fun getLifecycle(): Lifecycle = lifecycleRegistry
}
}
Loading…
Cancel
Save