2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-19 09:25:34 +00:00

Bug 1837504 - Display undo snackbar when compose top site is removed

This patch aims to reimplement the previous behavior upon removing
a pinned top site when a snackbar was shown giving the option to undo
the removal.
This commit is contained in:
DreVla 2023-06-15 17:42:03 +03:00 committed by mergify[bot]
parent 2fd034664b
commit af3b8d4be8
4 changed files with 109 additions and 0 deletions

View File

@ -52,6 +52,7 @@ import mozilla.components.concept.sync.AccountObserver
import mozilla.components.concept.sync.AuthType import mozilla.components.concept.sync.AuthType
import mozilla.components.concept.sync.OAuthAccount import mozilla.components.concept.sync.OAuthAccount
import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.top.sites.TopSite
import mozilla.components.feature.top.sites.TopSitesConfig import mozilla.components.feature.top.sites.TopSitesConfig
import mozilla.components.feature.top.sites.TopSitesFeature import mozilla.components.feature.top.sites.TopSitesFeature
import mozilla.components.feature.top.sites.TopSitesFrecencyConfig import mozilla.components.feature.top.sites.TopSitesFrecencyConfig
@ -351,6 +352,7 @@ class HomeFragment : Fragment() {
viewLifecycleScope = viewLifecycleOwner.lifecycleScope, viewLifecycleScope = viewLifecycleOwner.lifecycleScope,
registerCollectionStorageObserver = ::registerCollectionStorageObserver, registerCollectionStorageObserver = ::registerCollectionStorageObserver,
removeCollectionWithUndo = ::removeCollectionWithUndo, removeCollectionWithUndo = ::removeCollectionWithUndo,
showUndoSnackbarForTopSite = ::showUndoSnackbarForTopSite,
showTabTray = ::openTabsTray, showTabTray = ::openTabsTray,
), ),
recentTabController = DefaultRecentTabsController( recentTabController = DefaultRecentTabsController(
@ -461,6 +463,24 @@ class HomeFragment : Fragment() {
) )
} }
@VisibleForTesting
internal fun showUndoSnackbarForTopSite(topSite: TopSite) {
lifecycleScope.allowUndo(
view = requireView(),
message = getString(R.string.snackbar_top_site_removed),
undoActionTitle = getString(R.string.snackbar_deleted_undo),
onCancel = {
requireComponents.useCases.topSitesUseCase.addPinnedSites(
topSite.title.toString(),
topSite.url,
)
},
operation = { },
elevation = TOAST_ELEVATION,
paddedForBottomToolbar = true,
)
}
/** /**
* The [SessionControlView] is forced to update with our current state when we call * The [SessionControlView] is forced to update with our current state when we call
* [HomeFragment.onCreateView] in order to be able to draw everything at once with the current * [HomeFragment.onCreateView] in order to be able to draw everything at once with the current

View File

@ -193,6 +193,7 @@ class DefaultSessionControlController(
private val viewLifecycleScope: CoroutineScope, private val viewLifecycleScope: CoroutineScope,
private val registerCollectionStorageObserver: () -> Unit, private val registerCollectionStorageObserver: () -> Unit,
private val removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit, private val removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit,
private val showUndoSnackbarForTopSite: (topSite: TopSite) -> Unit,
private val showTabTray: () -> Unit, private val showTabTray: () -> Unit,
) : SessionControlController { ) : SessionControlController {
@ -332,6 +333,8 @@ class DefaultSessionControlController(
removeTopSites(topSite) removeTopSites(topSite)
} }
} }
showUndoSnackbarForTopSite(topSite)
} }
override fun handleRenameCollectionTapped(collection: TabCollection) { override fun handleRenameCollectionTapped(collection: TabCollection) {

View File

@ -867,6 +867,28 @@ class DefaultSessionControlControllerTest {
assertNull(TopSites.remove.testGetValue()!!.single().extra) assertNull(TopSites.remove.testGetValue()!!.single().extra)
} }
@Test
fun `WHEN top site is removed THEN the undo snackbar is called`() {
val mozillaTopSite = TopSite.Default(
id = 1L,
title = "Mozilla",
url = "https://mozilla.org",
null,
)
var undoSnackbarCalled = false
var undoSnackbarShownFor = "TopSiteName"
createController(
showUndoSnackbarForTopSite = { topSite ->
undoSnackbarCalled = true
undoSnackbarShownFor = topSite.title.toString()
},
).handleRemoveTopSiteClicked(mozillaTopSite)
assertEquals(true, undoSnackbarCalled)
assertEquals("Mozilla", undoSnackbarShownFor)
}
@Test @Test
fun `GIVEN exactly the required amount of downloaded thumbnails with no errors WHEN handling wallpaper dialog THEN dialog is shown`() { fun `GIVEN exactly the required amount of downloaded thumbnails with no errors WHEN handling wallpaper dialog THEN dialog is shown`() {
val wallpaperState = WallpaperState.default.copy( val wallpaperState = WallpaperState.default.copy(
@ -1142,6 +1164,7 @@ class DefaultSessionControlControllerTest {
registerCollectionStorageObserver: () -> Unit = { }, registerCollectionStorageObserver: () -> Unit = { },
showTabTray: () -> Unit = { }, showTabTray: () -> Unit = { },
removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit = { }, removeCollectionWithUndo: (tabCollection: TabCollection) -> Unit = { },
showUndoSnackbarForTopSite: (topSite: TopSite) -> Unit = { },
): DefaultSessionControlController { ): DefaultSessionControlController {
return DefaultSessionControlController( return DefaultSessionControlController(
activity = activity, activity = activity,
@ -1159,6 +1182,7 @@ class DefaultSessionControlControllerTest {
viewLifecycleScope = scope, viewLifecycleScope = scope,
registerCollectionStorageObserver = registerCollectionStorageObserver, registerCollectionStorageObserver = registerCollectionStorageObserver,
removeCollectionWithUndo = removeCollectionWithUndo, removeCollectionWithUndo = removeCollectionWithUndo,
showUndoSnackbarForTopSite = showUndoSnackbarForTopSite,
showTabTray = showTabTray, showTabTray = showTabTray,
) )
} }

View File

@ -5,10 +5,19 @@
package org.mozilla.fenix.home package org.mozilla.fenix.home
import android.content.Context import android.content.Context
import android.view.ViewGroup
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import io.mockk.Runs
import io.mockk.every import io.mockk.every
import io.mockk.just
import io.mockk.mockk import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.spyk import io.mockk.spyk
import io.mockk.unmockkStatic
import io.mockk.verify import io.mockk.verify
import kotlinx.coroutines.CoroutineScope
import mozilla.components.browser.state.search.SearchEngine import mozilla.components.browser.state.search.SearchEngine
import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.SearchState import mozilla.components.browser.state.state.SearchState
@ -22,12 +31,15 @@ import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.FenixApplication import org.mozilla.fenix.FenixApplication
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.Core import org.mozilla.fenix.components.Core
import org.mozilla.fenix.ext.application import org.mozilla.fenix.ext.application
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.home.HomeFragment.Companion.AMAZON_SPONSORED_TITLE import org.mozilla.fenix.home.HomeFragment.Companion.AMAZON_SPONSORED_TITLE
import org.mozilla.fenix.home.HomeFragment.Companion.EBAY_SPONSORED_TITLE import org.mozilla.fenix.home.HomeFragment.Companion.EBAY_SPONSORED_TITLE
import org.mozilla.fenix.home.HomeFragment.Companion.TOAST_ELEVATION
import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.utils.allowUndo
class HomeFragmentTest { class HomeFragmentTest {
@ -127,4 +139,54 @@ class HomeFragmentTest {
assertFalse(homeFragment.shouldEnableWallpaper()) assertFalse(homeFragment.shouldEnableWallpaper())
} }
@Test
fun `WHEN a pinned top is removed THEN show the undo snackbar`() {
try {
val topSite = TopSite.Default(
id = 1L,
title = "Mozilla",
url = "https://mozilla.org",
null,
)
mockkStatic("org.mozilla.fenix.utils.UndoKt")
mockkStatic("androidx.lifecycle.LifecycleOwnerKt")
val view: ViewGroup = mockk(relaxed = true)
val lifecycleScope: LifecycleCoroutineScope = mockk(relaxed = true)
every { any<LifecycleOwner>().lifecycleScope } returns lifecycleScope
every { homeFragment.getString(R.string.snackbar_top_site_removed) } returns "Mocked Removed Top Site"
every { homeFragment.getString(R.string.snackbar_deleted_undo) } returns "Mocked Undo Removal"
every {
any<CoroutineScope>().allowUndo(
any(),
any(),
any(),
any(),
any(),
any(),
any(),
any(),
)
} just Runs
every { homeFragment.requireView() } returns view
homeFragment.showUndoSnackbarForTopSite(topSite)
verify {
lifecycleScope.allowUndo(
view,
"Mocked Removed Top Site",
"Mocked Undo Removal",
any(),
any(),
any(),
TOAST_ELEVATION,
true,
)
}
} finally {
unmockkStatic("org.mozilla.fenix.utils.UndoKt")
unmockkStatic("androidx.lifecycle.LifecycleOwnerKt")
}
}
} }