For #26227 - Remove search term tab groups from Jump Back In
This commit is contained in:
parent
aa992263d6
commit
8656fd48eb
|
@ -93,7 +93,6 @@ import org.mozilla.fenix.perf.StrictModeManager
|
|||
import org.mozilla.fenix.perf.lazyMonitored
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
import org.mozilla.fenix.settings.advanced.getSelectedLocale
|
||||
import org.mozilla.fenix.tabstray.SearchTermTabGroupMiddleware
|
||||
import org.mozilla.fenix.telemetry.TelemetryMiddleware
|
||||
import org.mozilla.fenix.utils.getUndoDelay
|
||||
import org.mozilla.geckoview.GeckoRuntime
|
||||
|
@ -247,7 +246,6 @@ class Core(
|
|||
AdsTelemetryMiddleware(adsTelemetry),
|
||||
LastMediaAccessMiddleware(),
|
||||
HistoryMetadataMiddleware(historyMetadataService),
|
||||
SearchTermTabGroupMiddleware()
|
||||
) + if (tabsPrioritizationEnable) {
|
||||
listOf(SessionPrioritizationMiddleware())
|
||||
} else {
|
||||
|
|
|
@ -11,12 +11,10 @@ import mozilla.components.service.pocket.ext.recordNewImpression
|
|||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.ext.filterOutTab
|
||||
import org.mozilla.fenix.ext.getFilteredStories
|
||||
import org.mozilla.fenix.ext.recentSearchGroup
|
||||
import org.mozilla.fenix.gleanplumb.state.MessagingReducer
|
||||
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesSelectedCategory
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem
|
||||
import org.mozilla.fenix.home.recentvisits.RecentlyVisitedItem.RecentHistoryGroup
|
||||
import org.mozilla.fenix.gleanplumb.state.MessagingReducer
|
||||
|
||||
/**
|
||||
* Reducer for [AppStore].
|
||||
|
@ -44,12 +42,7 @@ internal object AppStoreReducer {
|
|||
topSites = action.topSites,
|
||||
recentBookmarks = action.recentBookmarks,
|
||||
recentTabs = action.recentTabs,
|
||||
recentHistory = if (action.recentHistory.isNotEmpty() && action.recentTabs.isNotEmpty()) {
|
||||
val recentSearchGroup = action.recentTabs.find { it is RecentTab.SearchGroup } as RecentTab.SearchGroup?
|
||||
action.recentHistory.filterOut(recentSearchGroup?.searchTerm)
|
||||
} else {
|
||||
action.recentHistory
|
||||
}
|
||||
recentHistory = action.recentHistory,
|
||||
)
|
||||
is AppAction.CollectionExpanded -> {
|
||||
val newExpandedCollection = state.expandedCollections.toMutableSet()
|
||||
|
@ -69,10 +62,9 @@ internal object AppStoreReducer {
|
|||
state.copy(showCollectionPlaceholder = false)
|
||||
}
|
||||
is AppAction.RecentTabsChange -> {
|
||||
val recentSearchGroup = action.recentTabs.find { it is RecentTab.SearchGroup } as RecentTab.SearchGroup?
|
||||
state.copy(
|
||||
recentTabs = action.recentTabs,
|
||||
recentHistory = state.recentHistory.filterOut(recentSearchGroup?.searchTerm)
|
||||
recentHistory = state.recentHistory,
|
||||
)
|
||||
}
|
||||
is AppAction.RemoveRecentTab -> {
|
||||
|
@ -90,7 +82,7 @@ internal object AppStoreReducer {
|
|||
state.copy(recentBookmarks = state.recentBookmarks.filterNot { it.url == action.recentBookmark.url })
|
||||
}
|
||||
is AppAction.RecentHistoryChange -> state.copy(
|
||||
recentHistory = action.recentHistory.filterOut(state.recentSearchGroup?.searchTerm)
|
||||
recentHistory = action.recentHistory
|
||||
)
|
||||
is AppAction.RemoveRecentHistoryHighlight -> state.copy(
|
||||
recentHistory = state.recentHistory.filterNot {
|
||||
|
@ -99,10 +91,7 @@ internal object AppStoreReducer {
|
|||
)
|
||||
is AppAction.DisbandSearchGroupAction -> state.copy(
|
||||
recentHistory = state.recentHistory.filterNot {
|
||||
it is RecentHistoryGroup && (
|
||||
it.title.equals(action.searchTerm, true) ||
|
||||
it.title.equals(state.recentSearchGroup?.searchTerm, true)
|
||||
)
|
||||
it is RecentHistoryGroup && it.title.equals(action.searchTerm, true)
|
||||
}
|
||||
)
|
||||
is AppAction.SelectPocketStoriesCategory -> {
|
||||
|
|
|
@ -16,7 +16,6 @@ import org.mozilla.fenix.home.pocket.POCKET_STORIES_DEFAULT_CATEGORY_NAME
|
|||
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
|
||||
import org.mozilla.fenix.home.pocket.PocketStory
|
||||
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab.SearchGroup
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
|
@ -162,13 +161,6 @@ internal fun getFilteredSponsoredStories(
|
|||
.toList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the [SearchGroup] shown in the "Jump back in" section.
|
||||
* May be null if no search group is shown.
|
||||
*/
|
||||
internal val AppState.recentSearchGroup: SearchGroup?
|
||||
get() = recentTabs.find { it is SearchGroup } as SearchGroup?
|
||||
|
||||
/**
|
||||
* Filter a [AppState] by the blocklist.
|
||||
*
|
||||
|
|
|
@ -4,16 +4,12 @@
|
|||
|
||||
package org.mozilla.fenix.ext
|
||||
|
||||
import mozilla.components.browser.state.selector.findTab
|
||||
import mozilla.components.browser.state.selector.normalTabs
|
||||
import mozilla.components.browser.state.selector.selectedNormalTab
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.TabGroup
|
||||
import mozilla.components.browser.state.state.TabSessionState
|
||||
import mozilla.components.feature.tabs.ext.hasMediaPlayed
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
import org.mozilla.fenix.tabstray.SEARCH_TERM_TAB_GROUPS
|
||||
import org.mozilla.fenix.tabstray.SEARCH_TERM_TAB_GROUPS_MIN_SIZE
|
||||
import org.mozilla.fenix.tabstray.ext.isNormalTabInactive
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -29,26 +25,15 @@ const val DEFAULT_ACTIVE_DAYS = 14L
|
|||
val maxActiveTime = TimeUnit.DAYS.toMillis(DEFAULT_ACTIVE_DAYS)
|
||||
|
||||
/**
|
||||
* Get the last opened normal tab, last tab with in progress media and last search term group, if available.
|
||||
* Get the last opened normal tab or last tab with in progress media.
|
||||
*
|
||||
* @return A list of the last opened tab not part of the last active search group and
|
||||
* the last active search group if these are available or an empty list.
|
||||
* @return A list of the last opened tab or an empty list.
|
||||
*/
|
||||
fun BrowserState.asRecentTabs(): List<RecentTab> {
|
||||
return mutableListOf<RecentTab>().apply {
|
||||
val mostRecentTabsGroup = lastSearchGroup
|
||||
val mostRecentTabNotInGroup = if (mostRecentTabsGroup == null) {
|
||||
lastOpenedNormalTab
|
||||
} else {
|
||||
listOf(selectedNormalTab)
|
||||
.plus(normalTabs.sortedByDescending { it.lastAccess })
|
||||
.filterNot { lastTabGroup?.tabIds?.contains(it?.id) ?: false }
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
mostRecentTabNotInGroup?.let { add(RecentTab.Tab(it)) }
|
||||
|
||||
mostRecentTabsGroup?.let { add(it) }
|
||||
return if (lastOpenedNormalTab == null) {
|
||||
mutableListOf()
|
||||
} else {
|
||||
mutableListOf(RecentTab.Tab(lastOpenedNormalTab!!))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,32 +61,6 @@ val BrowserState.inProgressMediaTab: TabSessionState?
|
|||
.filter { it.hasMediaPlayed() }
|
||||
.maxByOrNull { it.lastMediaAccessState.lastMediaAccess }
|
||||
|
||||
/**
|
||||
* Get the most recently accessed [TabGroup].
|
||||
* Result will be `null` if the currently open normal tabs are not part of a search group.
|
||||
*/
|
||||
val BrowserState.lastTabGroup: TabGroup?
|
||||
get() = tabPartitions[SEARCH_TERM_TAB_GROUPS]?.tabGroups
|
||||
?.lastOrNull { it.tabIds.size >= SEARCH_TERM_TAB_GROUPS_MIN_SIZE }
|
||||
|
||||
/**
|
||||
* Get the most recent search term group.
|
||||
*/
|
||||
val BrowserState.lastSearchGroup: RecentTab.SearchGroup?
|
||||
get() {
|
||||
val tabGroup = lastTabGroup ?: return null
|
||||
val firstTabId = tabGroup.tabIds.firstOrNull() ?: return null
|
||||
val firstTab = findTab(firstTabId) ?: return null
|
||||
|
||||
return RecentTab.SearchGroup(
|
||||
tabGroup.id,
|
||||
firstTabId,
|
||||
firstTab.content.url,
|
||||
firstTab.content.thumbnail,
|
||||
tabGroup.tabIds.size
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* List of all inactive tabs based on [maxActiveTime].
|
||||
* The user may have disabled the feature so for user interactions consider using the [actualInactiveTabs] method
|
||||
|
|
|
@ -8,7 +8,7 @@ import androidx.annotation.VisibleForTesting
|
|||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
|
||||
/**
|
||||
* Removes a [RecentTab.Tab] from a list of [RecentTab]. [RecentTab.SearchGroup]s will not be filtered.
|
||||
* Removes a [RecentTab.Tab] from a list of [RecentTab].
|
||||
*
|
||||
* @param tab [RecentTab] to remove from the list
|
||||
*/
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
|
||||
package org.mozilla.fenix.home.recenttabs
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.map
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.TabSessionState
|
||||
|
@ -29,8 +27,7 @@ class RecentTabsListFeature(
|
|||
) : AbstractBinding<BrowserState>(browserStore) {
|
||||
|
||||
override suspend fun onState(flow: Flow<BrowserState>) {
|
||||
// Listen for changes regarding the currently selected tab, in progress media tab
|
||||
// and search term groups.
|
||||
// Listen for changes regarding the currently selected tab and in progress media tab.
|
||||
flow
|
||||
.map { it.asRecentTabs() }
|
||||
.ifChanged()
|
||||
|
@ -47,21 +44,4 @@ sealed class RecentTab {
|
|||
* @param state Recently viewed [TabSessionState]
|
||||
*/
|
||||
data class Tab(val state: TabSessionState) : RecentTab()
|
||||
|
||||
/**
|
||||
* A search term group that was recently viewed
|
||||
*
|
||||
* @param searchTerm The search term that was recently viewed. Forced to start with uppercase.
|
||||
* @param tabId The id of the tab that was recently viewed
|
||||
* @param url The url that was recently viewed
|
||||
* @param thumbnail The thumbnail of the search term that was recently viewed
|
||||
* @param count The number of tabs in the search term group
|
||||
*/
|
||||
data class SearchGroup(
|
||||
val searchTerm: String,
|
||||
val tabId: String,
|
||||
val url: String,
|
||||
val thumbnail: Bitmap?,
|
||||
val count: Int
|
||||
) : RecentTab()
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import androidx.navigation.NavController
|
|||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.feature.tabs.TabsUseCases.SelectTabUseCase
|
||||
import mozilla.components.service.glean.private.NoExtras
|
||||
import org.mozilla.fenix.GleanMetrics.SearchTerms
|
||||
import org.mozilla.fenix.GleanMetrics.RecentTabs
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.components.appstate.AppAction
|
||||
|
@ -18,7 +18,6 @@ import org.mozilla.fenix.ext.inProgressMediaTab
|
|||
import org.mozilla.fenix.home.HomeFragmentDirections
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
import org.mozilla.fenix.home.recenttabs.interactor.RecentTabInteractor
|
||||
import org.mozilla.fenix.GleanMetrics.RecentTabs as RecentTabs
|
||||
|
||||
/**
|
||||
* An interface that handles the view manipulation of the recent tabs in the Home screen.
|
||||
|
@ -30,11 +29,6 @@ interface RecentTabController {
|
|||
*/
|
||||
fun handleRecentTabClicked(tabId: String)
|
||||
|
||||
/**
|
||||
* @see [RecentTabInteractor.onRecentSearchGroupClicked]
|
||||
*/
|
||||
fun handleRecentSearchGroupClicked(tabId: String)
|
||||
|
||||
/**
|
||||
* @see [RecentTabInteractor.onRecentTabShowAllClicked]
|
||||
*/
|
||||
|
@ -76,15 +70,6 @@ class DefaultRecentTabsController(
|
|||
navController.navigate(HomeFragmentDirections.actionGlobalTabsTrayFragment())
|
||||
}
|
||||
|
||||
override fun handleRecentSearchGroupClicked(tabId: String) {
|
||||
SearchTerms.jumpBackInGroupTapped.record(NoExtras())
|
||||
navController.navigate(
|
||||
HomeFragmentDirections.actionGlobalTabsTrayFragment(
|
||||
focusGroupTabId = tabId
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun handleRecentTabRemoved(tab: RecentTab.Tab) {
|
||||
appStore.dispatch(AppAction.RemoveRecentTab(tab))
|
||||
}
|
||||
|
|
|
@ -17,13 +17,6 @@ interface RecentTabInteractor {
|
|||
*/
|
||||
fun onRecentTabClicked(tabId: String)
|
||||
|
||||
/**
|
||||
* Opens the tabs tray and scroll to the search group. Called when a user clicks on a search group.
|
||||
*
|
||||
* @param tabId The ID of the tab to open.
|
||||
*/
|
||||
fun onRecentSearchGroupClicked(tabId: String)
|
||||
|
||||
/**
|
||||
* Show the tabs tray. Called when a user clicks on the "Show all" button besides the recent
|
||||
* tabs.
|
||||
|
|
|
@ -58,7 +58,6 @@ class RecentTabViewHolder(
|
|||
RecentTabs(
|
||||
recentTabs = recentTabs.value ?: emptyList(),
|
||||
onRecentTabClick = { recentTabInteractor.onRecentTabClicked(it) },
|
||||
onRecentSearchGroupClick = { recentTabInteractor.onRecentSearchGroupClicked(it) },
|
||||
menuItems = listOf(
|
||||
RecentTabMenuItem(
|
||||
title = stringResource(id = R.string.recent_tab_menu_item_remove),
|
||||
|
|
|
@ -10,7 +10,6 @@ import android.graphics.Bitmap
|
|||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
@ -29,7 +28,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
|
@ -44,8 +42,6 @@ import androidx.compose.ui.graphics.asImageBitmap
|
|||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
@ -53,7 +49,6 @@ import mozilla.components.browser.icons.compose.Loader
|
|||
import mozilla.components.browser.icons.compose.Placeholder
|
||||
import mozilla.components.browser.icons.compose.WithIcon
|
||||
import mozilla.components.ui.colors.PhotonColors
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.components
|
||||
import org.mozilla.fenix.compose.Image
|
||||
import org.mozilla.fenix.compose.ThumbnailCard
|
||||
|
@ -66,14 +61,12 @@ import org.mozilla.fenix.theme.FirefoxTheme
|
|||
* @param recentTabs List of [RecentTab] to display.
|
||||
* @param menuItems List of [RecentTabMenuItem] shown long clicking a [RecentTab].
|
||||
* @param onRecentTabClick Invoked when the user clicks on a recent tab.
|
||||
* @param onRecentSearchGroupClick Invoked when the user clicks on a recent search group.
|
||||
*/
|
||||
@Composable
|
||||
fun RecentTabs(
|
||||
recentTabs: List<RecentTab>,
|
||||
menuItems: List<RecentTabMenuItem>,
|
||||
onRecentTabClick: (String) -> Unit = {},
|
||||
onRecentSearchGroupClick: (String) -> Unit = {},
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
@ -88,16 +81,6 @@ fun RecentTabs(
|
|||
onRecentTabClick = onRecentTabClick
|
||||
)
|
||||
}
|
||||
is RecentTab.SearchGroup -> {
|
||||
if (components.settings.searchTermTabGroupsAreEnabled) {
|
||||
RecentSearchGroupItem(
|
||||
searchTerm = tab.searchTerm,
|
||||
tabId = tab.tabId,
|
||||
count = tab.count,
|
||||
onSearchGroupClick = onRecentSearchGroupClick
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,81 +168,6 @@ private fun RecentTabItem(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A recent search group item.
|
||||
*
|
||||
* @param searchTerm The search term for the group.
|
||||
* @param tabId The id of the last accessed tab in the group.
|
||||
* @param count Count of how many tabs belongs to the group.
|
||||
* @param onSearchGroupClick Invoked when the user clicks on a group.
|
||||
*/
|
||||
@Composable
|
||||
private fun RecentSearchGroupItem(
|
||||
searchTerm: String,
|
||||
tabId: String,
|
||||
count: Int,
|
||||
onSearchGroupClick: (String) -> Unit = {}
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(112.dp)
|
||||
.clickable { onSearchGroupClick(tabId) },
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
backgroundColor = FirefoxTheme.colors.layer2,
|
||||
elevation = 6.dp
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.ic_search_group_thumbnail),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(108.dp, 80.dp),
|
||||
contentScale = ContentScale.FillWidth,
|
||||
alignment = Alignment.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.recent_tabs_search_term, searchTerm),
|
||||
color = FirefoxTheme.colors.textPrimary,
|
||||
fontSize = 14.sp,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 2,
|
||||
)
|
||||
|
||||
Row {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_all_tabs),
|
||||
modifier = Modifier.size(18.dp),
|
||||
contentDescription = null,
|
||||
tint = when (isSystemInDarkTheme()) {
|
||||
true -> FirefoxTheme.colors.textPrimary
|
||||
false -> FirefoxTheme.colors.textSecondary
|
||||
}
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.recent_tabs_search_term_count_2, count),
|
||||
color = FirefoxTheme.colors.textSecondary,
|
||||
fontSize = 12.sp,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A recent tab image.
|
||||
*
|
||||
|
|
|
@ -372,10 +372,6 @@ class SessionControlInteractor(
|
|||
recentTabController.handleRecentTabClicked(tabId)
|
||||
}
|
||||
|
||||
override fun onRecentSearchGroupClicked(tabId: String) {
|
||||
recentTabController.handleRecentSearchGroupClicked(tabId)
|
||||
}
|
||||
|
||||
override fun onRecentTabShowAllClicked() {
|
||||
recentTabController.handleRecentTabShowAllClicked()
|
||||
}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
/* 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.tabstray
|
||||
|
||||
import mozilla.components.browser.state.action.BrowserAction
|
||||
import mozilla.components.browser.state.action.HistoryMetadataAction
|
||||
import mozilla.components.browser.state.action.TabGroupAction
|
||||
import mozilla.components.browser.state.action.TabListAction
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.getGroupByName
|
||||
import mozilla.components.lib.state.Middleware
|
||||
import mozilla.components.lib.state.MiddlewareContext
|
||||
|
||||
const val SEARCH_TERM_TAB_GROUPS = "searchTermTabGroups"
|
||||
const val SEARCH_TERM_TAB_GROUPS_MIN_SIZE = 2
|
||||
|
||||
/**
|
||||
* This [Middleware] manages tab groups for search terms.
|
||||
*/
|
||||
class SearchTermTabGroupMiddleware : Middleware<BrowserState, BrowserAction> {
|
||||
|
||||
override fun invoke(
|
||||
context: MiddlewareContext<BrowserState, BrowserAction>,
|
||||
next: (BrowserAction) -> Unit,
|
||||
action: BrowserAction
|
||||
) {
|
||||
|
||||
next(action)
|
||||
|
||||
when (action) {
|
||||
is HistoryMetadataAction.SetHistoryMetadataKeyAction -> {
|
||||
action.historyMetadataKey.searchTerm?.let { searchTerm ->
|
||||
context.dispatch(
|
||||
TabGroupAction.AddTabAction(SEARCH_TERM_TAB_GROUPS, searchTerm, action.tabId)
|
||||
)
|
||||
}
|
||||
}
|
||||
is HistoryMetadataAction.DisbandSearchGroupAction -> {
|
||||
val group = context.state.tabPartitions[SEARCH_TERM_TAB_GROUPS]?.getGroupByName(action.searchTerm)
|
||||
group?.let {
|
||||
context.dispatch(TabGroupAction.RemoveTabGroupAction(SEARCH_TERM_TAB_GROUPS, it.id))
|
||||
}
|
||||
}
|
||||
is TabListAction.RestoreAction -> {
|
||||
action.tabs.forEach { tab ->
|
||||
tab.state.historyMetadata?.searchTerm?.let { searchTerm ->
|
||||
context.dispatch(
|
||||
TabGroupAction.AddTabAction(SEARCH_TERM_TAB_GROUPS, searchTerm, tab.state.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -153,7 +153,6 @@ class TabsTrayFragment : AppCompatDialogFragment() {
|
|||
initialState = TabsTrayState(
|
||||
selectedPage = initialPage,
|
||||
mode = initialMode,
|
||||
focusGroupTabId = args.focusGroupTabId
|
||||
),
|
||||
middlewares = listOf(
|
||||
TabsTrayMiddleware()
|
||||
|
|
|
@ -19,10 +19,9 @@ import org.mozilla.fenix.tabstray.syncedtabs.SyncedTabsListItem
|
|||
* @property mode Whether the browser tab list is in multi-select mode or not with the set of
|
||||
* currently selected tabs.
|
||||
* @property inactiveTabs The list of tabs are considered inactive.
|
||||
* @property normalTabs The list of normal tabs that do not fall under [inactiveTabs] or search term groups.
|
||||
* @property normalTabs The list of normal tabs that do not fall under [inactiveTabs].
|
||||
* @property privateTabs The list of tabs that are [ContentState.private].
|
||||
* @property syncing Whether the Synced Tabs feature should fetch the latest tabs from paired devices.
|
||||
* @property focusGroupTabId The search group tab id to focus. Defaults to null.
|
||||
*/
|
||||
data class TabsTrayState(
|
||||
val selectedPage: Page = Page.NormalTabs,
|
||||
|
@ -32,7 +31,6 @@ data class TabsTrayState(
|
|||
val privateTabs: List<TabSessionState> = emptyList(),
|
||||
val syncedTabs: List<SyncedTabsListItem> = emptyList(),
|
||||
val syncing: Boolean = false,
|
||||
val focusGroupTabId: String? = null
|
||||
) : State {
|
||||
|
||||
/**
|
||||
|
@ -130,11 +128,6 @@ sealed class TabsTrayAction : Action {
|
|||
*/
|
||||
object SyncCompleted : TabsTrayAction()
|
||||
|
||||
/**
|
||||
* Removes the [TabsTrayState.focusGroupTabId] of the [TabsTrayState].
|
||||
*/
|
||||
object ConsumeFocusGroupTabId : TabsTrayAction()
|
||||
|
||||
/**
|
||||
* Updates the list of tabs in [TabsTrayState.inactiveTabs].
|
||||
*/
|
||||
|
@ -184,8 +177,6 @@ internal object TabsTrayReducer {
|
|||
state.copy(syncing = true)
|
||||
is TabsTrayAction.SyncCompleted ->
|
||||
state.copy(syncing = false)
|
||||
is TabsTrayAction.ConsumeFocusGroupTabId ->
|
||||
state.copy(focusGroupTabId = null)
|
||||
is TabsTrayAction.UpdateInactiveTabs ->
|
||||
state.copy(inactiveTabs = action.tabs)
|
||||
is TabsTrayAction.UpdateNormalTabs ->
|
||||
|
|
|
@ -84,10 +84,6 @@ class NormalBrowserPageViewHolder(
|
|||
val inactiveTabsAreEnabled = containerView.context.settings().inactiveTabsAreEnabled
|
||||
|
||||
val selectedTab = browserStore.state.selectedNormalTab ?: return
|
||||
// It's safe to read the state directly (i.e. won't cause bugs because of the store actions
|
||||
// processed on a separate thread) instead of observing it because this value is only set during
|
||||
// the initialState of the TabsTrayStore being created.
|
||||
val focusGroupTabId = tabsTrayStore.state.focusGroupTabId
|
||||
|
||||
// Update tabs into the inactive adapter.
|
||||
if (inactiveTabsAreEnabled && selectedTab.isNormalTabInactive(maxActiveTime)) {
|
||||
|
@ -105,9 +101,7 @@ class NormalBrowserPageViewHolder(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (focusGroupTabId.isNullOrEmpty()) {
|
||||
} else {
|
||||
// Updates tabs into the normal browser tabs adapter.
|
||||
browserAdapter.observeFirstInsert {
|
||||
val activeTabsList = browserStore.state.getNormalTrayTabs(inactiveTabsAreEnabled)
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="18dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="18"
|
||||
android:viewportHeight="18">
|
||||
<path
|
||||
android:pathData="M0,2.5C0,1.119 1.119,0 2.5,0H15.5C16.881,0 18,1.119 18,2.5V10.5C18,11.881 16.881,13 15.5,13H2.5C1.119,13 0,11.881 0,10.5V2.5ZM15.7,11.5L16.5,10.7V2.3L15.7,1.5H2.3L1.5,2.3V10.7L2.3,11.5H15.7ZM1.5,15.7L2.3,16.5H15.7L16.5,15.7V14.75C16.5,14.336 16.836,14 17.25,14C17.664,14 18,14.336 18,14.75V15.5C18,16.881 16.881,18 15.5,18H2.5C1.119,18 0,16.881 0,15.5V14.75C0,14.336 0.336,14 0.75,14C1.164,14 1.5,14.336 1.5,14.75V15.7Z"
|
||||
android:fillColor="?attr/textSecondary"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -1,49 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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/. -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="80dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="80">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M8,0L100,0A8,8 0,0 1,108 8L108,72A8,8 0,0 1,100 80L8,80A8,8 0,0 1,0 72L0,8A8,8 0,0 1,8 0z"/>
|
||||
<path
|
||||
android:pathData="M8,0L100,0A8,8 0,0 1,108 8L108,72A8,8 0,0 1,100 80L8,80A8,8 0,0 1,0 72L0,8A8,8 0,0 1,8 0z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startY="0"
|
||||
android:startX="108"
|
||||
android:endY="103.313"
|
||||
android:endX="31.4721"
|
||||
android:type="linear">
|
||||
<item android:offset="0" android:color="#FF9059FF"/>
|
||||
<item android:offset="1" android:color="#FF0250BB"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M100,80L8,80A8,8 0,0 1,0 72L0,8A8,8 0,0 1,8 0L100,0A8,8 0,0 1,108 8L108,72A8,8 0,0 1,100 80z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillAlpha="0.5">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:startY="80"
|
||||
android:startX="54"
|
||||
android:endY="0"
|
||||
android:endX="54"
|
||||
android:type="linear">
|
||||
<item android:offset="0.0104167" android:color="#FF000000"/>
|
||||
<item android:offset="0.567708" android:color="#FF81535C"/>
|
||||
<item android:offset="1" android:color="#00C4C4C4"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:pathData="M60.55,43.687C62.019,41.645 62.888,39.145 62.888,36.444C62.888,29.584 57.306,24 50.444,24C43.582,24 38,29.584 38,36.444C38,43.305 43.582,48.889 50.444,48.889C53.155,48.889 55.663,48.014 57.709,46.535L58.641,46.524L67.725,55.609C67.985,55.868 68.326,56 68.667,56C69.008,56 69.35,55.87 69.609,55.609C70.13,55.088 70.13,54.244 69.609,53.723L60.532,44.644L60.55,43.687ZM50.444,46.222C45.052,46.222 40.667,41.835 40.667,36.444C40.667,31.054 45.052,26.667 50.444,26.667C55.836,26.667 60.221,31.054 60.221,36.444C60.221,41.835 55.836,46.222 50.444,46.222Z"
|
||||
android:fillColor="#F9F9FB"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -161,11 +161,6 @@
|
|||
android:name="enterMultiselect"
|
||||
android:defaultValue="false"
|
||||
app:argType="boolean" />
|
||||
<argument
|
||||
android:name="focusGroupTabId"
|
||||
app:nullable="true"
|
||||
android:defaultValue="@null"
|
||||
app:argType="string" />
|
||||
<argument
|
||||
android:name="page"
|
||||
android:defaultValue="NormalTabs"
|
||||
|
|
|
@ -120,10 +120,10 @@
|
|||
<string name="recent_tabs_show_all_content_description_2">Show all recent tabs button</string>
|
||||
<!-- Title for showing a group item in the 'Jump back in' section of the new tab
|
||||
The first parameter is the search term that the user used. (for example: your search for "cat")-->
|
||||
<string name="recent_tabs_search_term">Your search for \"%1$s\"</string>
|
||||
<string name="recent_tabs_search_term" moz:RemovedIn="105" tools:ignore="UnusedResources">Your search for \"%1$s\"</string>
|
||||
<!-- Text for the number of tabs in a group in the 'Jump back in' section of the new tab
|
||||
%d is a placeholder for the number of sites in the group. This number will always be more than one. -->
|
||||
<string name="recent_tabs_search_term_count_2">%d sites</string>
|
||||
<string name="recent_tabs_search_term_count_2" moz:RemovedIn="105" tools:ignore="UnusedResources">%d sites</string>
|
||||
<!-- Text for button in synced tab card that opens synced tabs tray -->
|
||||
<string name="recent_tabs_see_all_synced_tabs_button_text">See all synced tabs</string>
|
||||
<!-- Accessibility description for device icon used for recent synced tab -->
|
||||
|
|
|
@ -145,14 +145,12 @@ class AppStoreTest {
|
|||
assertEquals(0, appStore.state.recentTabs.size)
|
||||
|
||||
// Add 2 RecentTabs to the AppStore
|
||||
// A new SearchGroup already shown in history should hide the HistoryGroup.
|
||||
val recentTab1: RecentTab.Tab = mockk()
|
||||
val recentTab2 = RecentTab.SearchGroup(group2.title, "tabId", "url", null, 2)
|
||||
val recentTabs: List<RecentTab> = listOf(recentTab1, recentTab2)
|
||||
val recentTabs: List<RecentTab> = listOf(recentTab1)
|
||||
appStore.dispatch(AppAction.RecentTabsChange(recentTabs)).join()
|
||||
|
||||
assertEquals(recentTabs, appStore.state.recentTabs)
|
||||
assertEquals(listOf(group1, group3, highlight), appStore.state.recentHistory)
|
||||
assertEquals(listOf(group1, group2, group3, highlight), appStore.state.recentHistory)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -256,13 +254,12 @@ class AppStoreTest {
|
|||
assertEquals(0, appStore.state.recentHistory.size)
|
||||
assertEquals(Mode.Normal, appStore.state.mode)
|
||||
|
||||
val recentGroup = RecentTab.SearchGroup("testSearchTerm", "id", "url", null, 3)
|
||||
val collections: List<TabCollection> = listOf(mockk())
|
||||
val topSites: List<TopSite> = listOf(mockk(), mockk())
|
||||
val recentTabs: List<RecentTab> = listOf(mockk(), recentGroup, mockk())
|
||||
val recentTabs: List<RecentTab> = listOf(mockk(), mockk())
|
||||
val recentBookmarks: List<RecentBookmark> = listOf(mockk(), mockk())
|
||||
val group1 = RecentHistoryGroup(title = "test One")
|
||||
val group2 = RecentHistoryGroup(title = recentGroup.searchTerm.lowercase())
|
||||
val group2 = RecentHistoryGroup(title = "testSearchTerm")
|
||||
val group3 = RecentHistoryGroup(title = "test two")
|
||||
val highlight = RecentHistoryHighlight(group2.title, "")
|
||||
val recentHistory: List<RecentlyVisitedItem> = listOf(group1, group2, group3, highlight)
|
||||
|
@ -283,7 +280,7 @@ class AppStoreTest {
|
|||
assertEquals(topSites, appStore.state.topSites)
|
||||
assertEquals(recentTabs, appStore.state.recentTabs)
|
||||
assertEquals(recentBookmarks, appStore.state.recentBookmarks)
|
||||
assertEquals(listOf(group1, group3, highlight), appStore.state.recentHistory)
|
||||
assertEquals(listOf(group1, group2, group3, highlight), appStore.state.recentHistory)
|
||||
assertEquals(Mode.Private, appStore.state.mode)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import org.mozilla.fenix.home.pocket.POCKET_STORIES_DEFAULT_CATEGORY_NAME
|
|||
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesCategory
|
||||
import org.mozilla.fenix.home.pocket.PocketRecommendedStoriesSelectedCategory
|
||||
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTabState
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.random.Random
|
||||
|
@ -498,24 +497,6 @@ class AppStateTest {
|
|||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN recentTabs contains a SearchGroup WHEN recentSearchGroup is called THEN return the group`() {
|
||||
val searchGroup: RecentTab.SearchGroup = mockk()
|
||||
val normalTab: RecentTab.Tab = mockk()
|
||||
val state = AppState(recentTabs = listOf(normalTab, searchGroup))
|
||||
|
||||
assertEquals(searchGroup, state.recentSearchGroup)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN recentTabs does not contains SearchGroup WHEN recentSearchGroup is called THEN return null`() {
|
||||
val normalTab1: RecentTab.Tab = mockk()
|
||||
val normalTab2: RecentTab.Tab = mockk()
|
||||
val state = AppState(recentTabs = listOf(normalTab1, normalTab2))
|
||||
|
||||
assertNull(state.recentSearchGroup)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN recent tabs disabled in settings WHEN checking to show tabs THEN section should not be shown`() {
|
||||
val settings = mockk<Settings> {
|
||||
|
|
|
@ -8,8 +8,6 @@ import io.mockk.every
|
|||
import io.mockk.mockk
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.LastMediaAccessState
|
||||
import mozilla.components.browser.state.state.TabGroup
|
||||
import mozilla.components.browser.state.state.TabPartition
|
||||
import mozilla.components.browser.state.state.createTab
|
||||
import mozilla.components.concept.storage.HistoryMetadataKey
|
||||
import org.junit.Assert.assertEquals
|
||||
|
@ -17,7 +15,6 @@ import org.junit.Assert.assertNull
|
|||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
import org.mozilla.fenix.tabstray.SEARCH_TERM_TAB_GROUPS
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
class BrowserStateTest {
|
||||
|
@ -160,74 +157,6 @@ class BrowserStateTest {
|
|||
assertEquals(searchGroupTab, (result[0] as RecentTab.Tab).state)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN only normal tabs from a search group are open WHEN recentTabs is called THEN return only the tab group`() {
|
||||
val searchGroupTab1 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "1",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "Test",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val searchGroupTab2 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "2",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "Test",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val tabGroup = listOf(TabGroup("Test", "", listOf(searchGroupTab1.id, searchGroupTab2.id)))
|
||||
val browserState = BrowserState(
|
||||
tabs = listOf(searchGroupTab1, searchGroupTab2),
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, tabGroup))),
|
||||
selectedTabId = searchGroupTab1.id
|
||||
)
|
||||
|
||||
val result = browserState.asRecentTabs()
|
||||
|
||||
assertEquals(1, result.size)
|
||||
assert(result[0] is RecentTab.SearchGroup)
|
||||
assertEquals(searchGroupTab1.historyMetadata?.searchTerm, (result[0] as RecentTab.SearchGroup).searchTerm)
|
||||
assertEquals(searchGroupTab1.id, (result[0] as RecentTab.SearchGroup).tabId)
|
||||
assertEquals(searchGroupTab1.content.url, (result[0] as RecentTab.SearchGroup).url)
|
||||
assertEquals(searchGroupTab1.content.thumbnail, (result[0] as RecentTab.SearchGroup).thumbnail)
|
||||
assertEquals(2, (result[0] as RecentTab.SearchGroup).count)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN tabs with different search terms are opened WHEN recentTabs is called THEN return the most recent tab and tab group`() {
|
||||
val searchGroupTab = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "1",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "Test",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val otherTab = createTab(url = "https://www.mozilla.org/firefox", id = "2")
|
||||
val browserState = BrowserState(
|
||||
tabs = listOf(searchGroupTab, otherTab, searchGroupTab),
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, listOf(TabGroup("Test", "", listOf("1", "3")))))),
|
||||
selectedTabId = searchGroupTab.id
|
||||
)
|
||||
|
||||
val result = browserState.asRecentTabs()
|
||||
|
||||
assertEquals(2, result.size)
|
||||
assertEquals(otherTab, (result[0] as RecentTab.Tab).state)
|
||||
assert(result[1] is RecentTab.SearchGroup)
|
||||
assertEquals("Test", (result[1] as RecentTab.SearchGroup).searchTerm)
|
||||
assertEquals(searchGroupTab.id, (result[1] as RecentTab.SearchGroup).tabId)
|
||||
assertEquals(searchGroupTab.content.url, (result[1] as RecentTab.SearchGroup).url)
|
||||
assertEquals(searchGroupTab.content.thumbnail, (result[1] as RecentTab.SearchGroup).thumbnail)
|
||||
assertEquals(2, (result[1] as RecentTab.SearchGroup).count)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN the selected tab is a normal tab and tab group with one tab exists WHEN asRecentTabs is called THEN return only the normal tab`() {
|
||||
val selectedTab = createTab(url = "url", id = "3")
|
||||
|
@ -260,46 +189,6 @@ class BrowserStateTest {
|
|||
assertEquals(selectedTab, (result[0] as RecentTab.Tab).state)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN the selected tab is a normal tab and tab group with two tabs exists WHEN asRecentTabs is called THEN return a list of these tabs`() {
|
||||
val selectedTab = createTab(url = "url", id = "3")
|
||||
val searchGroupTab1 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "4",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "Test",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val searchGroupTab2 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "5",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "Test",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val tabGroup = listOf(TabGroup("Test", "", listOf(searchGroupTab1.id, searchGroupTab2.id)))
|
||||
val browserState = BrowserState(
|
||||
tabs = listOf(mockk(relaxed = true), selectedTab, searchGroupTab1, searchGroupTab1),
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, tabGroup))),
|
||||
selectedTabId = selectedTab.id
|
||||
)
|
||||
|
||||
val result = browserState.asRecentTabs()
|
||||
|
||||
assertEquals(2, result.size)
|
||||
assertEquals(selectedTab, (result[0] as RecentTab.Tab).state)
|
||||
assert(result[1] is RecentTab.SearchGroup)
|
||||
assertEquals(searchGroupTab1.historyMetadata?.searchTerm, (result[1] as RecentTab.SearchGroup).searchTerm)
|
||||
assertEquals(searchGroupTab1.id, (result[1] as RecentTab.SearchGroup).tabId)
|
||||
assertEquals(searchGroupTab1.content.url, (result[1] as RecentTab.SearchGroup).url)
|
||||
assertEquals(searchGroupTab1.content.thumbnail, (result[1] as RecentTab.SearchGroup).thumbnail)
|
||||
assertEquals(2, (result[1] as RecentTab.SearchGroup).count)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN only private tabs and a private one selected WHEN lastOpenedNormalTab is called THEN return null`() {
|
||||
val selectedPrivateTab = createTab(url = "url", id = "1", private = true)
|
||||
|
@ -467,38 +356,4 @@ class BrowserStateTest {
|
|||
assertEquals(2, result.size)
|
||||
assertTrue(result.containsAll(listOf(normalTab1, normalTab3)))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN tabs exist with search terms WHEN lastTabGroup is called THEN return the last accessed TabGroup`() {
|
||||
val tab1 = createTab(url = "url1", id = "id1", searchTerms = "test1", lastAccess = 10)
|
||||
val tab2 = createTab(url = "url2", id = "id2", searchTerms = "test1", lastAccess = 11)
|
||||
val tab3 = createTab(url = "url3", id = "id3", searchTerms = "test3", lastAccess = 100)
|
||||
val tab4 = createTab(url = "url4", id = "id4", searchTerms = "test3", lastAccess = 111)
|
||||
val tab5 = createTab(url = "url5", id = "id5", searchTerms = "test5", lastAccess = 1000)
|
||||
val tab6 = createTab(url = "url6", id = "id6", searchTerms = "test5", lastAccess = 1111)
|
||||
val tabGroup1 = TabGroup("test1", "", listOf(tab1.id, tab2.id))
|
||||
val tabGroup2 = TabGroup("test3", "", listOf(tab3.id, tab4.id))
|
||||
val tabGroup3 = TabGroup("test5", "", listOf(tab5.id, tab6.id))
|
||||
|
||||
val browserState = BrowserState(
|
||||
tabs = listOf(tab1, tab2, tab3, tab4, tab5, tab6),
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, listOf(tabGroup1, tabGroup2, tabGroup3))))
|
||||
)
|
||||
val expected = TabGroup("test5", "", listOf(tab5.id, tab6.id))
|
||||
|
||||
val result = browserState.lastTabGroup
|
||||
|
||||
assertEquals(expected, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN no tabs exist with search terms WHEN lastTabGroup is called THEN return the last accessed TabGroup`() {
|
||||
val tab1 = createTab(url = "url1", id = "id1", lastAccess = 10)
|
||||
val tab2 = createTab(url = "url2", id = "id2", lastAccess = 11)
|
||||
val browserState = BrowserState(tabs = listOf(tab1, tab2))
|
||||
|
||||
val result = browserState.lastTabGroup
|
||||
|
||||
assertNull(result)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/* 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.ext
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import mozilla.components.browser.state.state.TabSessionState
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
|
||||
class RecentTabsTest {
|
||||
@Test
|
||||
fun `Test filtering out tab`() {
|
||||
val filteredId = "id"
|
||||
val mockSessionState: TabSessionState = mockk()
|
||||
every { mockSessionState.id } returns filteredId
|
||||
val tab = RecentTab.Tab(mockSessionState)
|
||||
val searchGroup = RecentTab.SearchGroup(
|
||||
tabId = filteredId,
|
||||
searchTerm = "",
|
||||
url = "",
|
||||
thumbnail = null,
|
||||
count = 0
|
||||
)
|
||||
|
||||
val recentTabs = listOf(tab, searchGroup)
|
||||
val result = recentTabs.filterOutTab(tab)
|
||||
|
||||
assertEquals(listOf(searchGroup), result)
|
||||
}
|
||||
}
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
package org.mozilla.fenix.home
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import mozilla.components.browser.state.action.ContentAction.UpdateIconAction
|
||||
|
@ -13,12 +12,9 @@ import mozilla.components.browser.state.action.MediaSessionAction
|
|||
import mozilla.components.browser.state.action.TabListAction
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.LastMediaAccessState
|
||||
import mozilla.components.browser.state.state.TabGroup
|
||||
import mozilla.components.browser.state.state.TabPartition
|
||||
import mozilla.components.browser.state.state.createTab
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.concept.engine.mediasession.MediaSession
|
||||
import mozilla.components.concept.storage.HistoryMetadataKey
|
||||
import mozilla.components.feature.media.middleware.LastMediaAccessMiddleware
|
||||
import mozilla.components.support.test.ext.joinBlocking
|
||||
import mozilla.components.support.test.libstate.ext.waitUntilIdle
|
||||
|
@ -38,7 +34,6 @@ import org.mozilla.fenix.components.appstate.AppAction
|
|||
import org.mozilla.fenix.components.appstate.AppState
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTab
|
||||
import org.mozilla.fenix.home.recenttabs.RecentTabsListFeature
|
||||
import org.mozilla.fenix.tabstray.SEARCH_TERM_TAB_GROUPS
|
||||
|
||||
class RecentTabsListFeatureTest {
|
||||
|
||||
|
@ -388,245 +383,4 @@ class RecentTabsListFeatureTest {
|
|||
assertTrue(appStore.state.recentTabs[0] is RecentTab.Tab)
|
||||
assertEquals(selectedTab, (appStore.state.recentTabs[0] as RecentTab.Tab).state)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN only tabs from a search group WHEN the feature starts THEN dispatch the selected tab group as a recent tab list`() {
|
||||
val tab1 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "1",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
|
||||
val tab2 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "2",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val tabs = listOf(tab1, tab2)
|
||||
val tabGroup = TabGroup("Test search term", "", listOf(tab1.id, tab2.id))
|
||||
val browserStore = BrowserStore(
|
||||
BrowserState(
|
||||
tabs = tabs,
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, listOf(tabGroup)))),
|
||||
selectedTabId = "1"
|
||||
)
|
||||
)
|
||||
val feature = RecentTabsListFeature(
|
||||
browserStore = browserStore,
|
||||
appStore = appStore
|
||||
)
|
||||
|
||||
feature.start()
|
||||
|
||||
appStore.waitUntilIdle()
|
||||
|
||||
assertEquals(1, appStore.state.recentTabs.size)
|
||||
val searchGroup = (appStore.state.recentTabs[0] as RecentTab.SearchGroup)
|
||||
assertEquals(searchGroup.searchTerm, "Test search term")
|
||||
assertEquals(searchGroup.tabId, "1")
|
||||
assertEquals(searchGroup.url, "https://www.mozilla.org")
|
||||
assertEquals(searchGroup.thumbnail, null)
|
||||
assertEquals(searchGroup.count, 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN tabs with different search terms are opened WHEN the feature starts THEN dispatch the last active tab and last active search group as recent tabs list`() {
|
||||
val tab1 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "1",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "Test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
|
||||
val tab2 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "2",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "Test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val tab3 = createTab(url = "https://www.mozilla.org/firefox", id = "3")
|
||||
val tabs = listOf(tab1, tab2, tab3)
|
||||
val tabGroup = TabGroup("Test search term", "", listOf(tab1.id, tab2.id))
|
||||
val browserStore = BrowserStore(
|
||||
BrowserState(
|
||||
tabs = tabs,
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, listOf(tabGroup)))),
|
||||
selectedTabId = "1"
|
||||
)
|
||||
)
|
||||
val feature = RecentTabsListFeature(
|
||||
browserStore = browserStore,
|
||||
appStore = appStore
|
||||
)
|
||||
|
||||
feature.start()
|
||||
|
||||
appStore.waitUntilIdle()
|
||||
|
||||
assertEquals(2, appStore.state.recentTabs.size)
|
||||
assertTrue(appStore.state.recentTabs[0] is RecentTab.Tab)
|
||||
assertEquals(tab3, (appStore.state.recentTabs[0] as RecentTab.Tab).state)
|
||||
val searchGroup = (appStore.state.recentTabs[1] as RecentTab.SearchGroup)
|
||||
assertEquals(searchGroup.searchTerm, "Test search term")
|
||||
assertEquals(searchGroup.tabId, "1")
|
||||
assertEquals(searchGroup.url, "https://www.mozilla.org")
|
||||
assertEquals(searchGroup.thumbnail, null)
|
||||
assertEquals(searchGroup.count, 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN a tab group with one tab and a selected tab WHEN the feature starts THEN dispatch selected tab as a recent tab list`() {
|
||||
val tab1 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "1"
|
||||
)
|
||||
val tab2 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "2",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val tabs = listOf(tab1, tab2)
|
||||
val browserStore = BrowserStore(
|
||||
BrowserState(
|
||||
tabs = tabs,
|
||||
selectedTabId = "1"
|
||||
)
|
||||
)
|
||||
val feature = RecentTabsListFeature(
|
||||
browserStore = browserStore,
|
||||
appStore = appStore
|
||||
)
|
||||
|
||||
feature.start()
|
||||
|
||||
appStore.waitUntilIdle()
|
||||
|
||||
assertEquals(1, appStore.state.recentTabs.size)
|
||||
assertTrue(appStore.state.recentTabs[0] is RecentTab.Tab)
|
||||
assertEquals(tab1, (appStore.state.recentTabs[0] as RecentTab.Tab).state)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN a tab group with two tabs and a selected tab WHEN the feature starts THEN dispatch both the selected tab and the selected tab group as a recent tab list`() {
|
||||
val tab1 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "1"
|
||||
)
|
||||
val tab2 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "2",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
|
||||
val tab3 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "3",
|
||||
historyMetadata = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
)
|
||||
val tabs = listOf(tab1, tab2, tab3)
|
||||
val tabGroup = TabGroup("test search term", "", listOf(tab2.id, tab3.id))
|
||||
val browserStore = BrowserStore(
|
||||
BrowserState(
|
||||
tabs = tabs,
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, listOf(tabGroup)))),
|
||||
selectedTabId = "1"
|
||||
)
|
||||
)
|
||||
val feature = RecentTabsListFeature(
|
||||
browserStore = browserStore,
|
||||
appStore = appStore
|
||||
)
|
||||
|
||||
feature.start()
|
||||
|
||||
appStore.waitUntilIdle()
|
||||
|
||||
assertEquals(2, appStore.state.recentTabs.size)
|
||||
assertTrue(appStore.state.recentTabs[0] is RecentTab.Tab)
|
||||
assertEquals(tab1, (appStore.state.recentTabs[0] as RecentTab.Tab).state)
|
||||
val searchGroup = (appStore.state.recentTabs[1] as RecentTab.SearchGroup)
|
||||
assertEquals(searchGroup.searchTerm, "test search term")
|
||||
assertEquals(searchGroup.tabId, "2")
|
||||
assertEquals(searchGroup.url, "https://www.mozilla.org")
|
||||
assertEquals(searchGroup.thumbnail, null)
|
||||
assertEquals(searchGroup.count, 2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN a valid inProgressMediaTabId, selected tab and tab group exists WHEN the feature starts THEN dispatch all as as a recent tabs list`() {
|
||||
val mediaTab = createTab(
|
||||
url = "https://mozilla.com", id = "42",
|
||||
lastMediaAccessState = LastMediaAccessState("https://mozilla.com", 123)
|
||||
)
|
||||
val selectedTab = createTab("https://mozilla.com", id = "43")
|
||||
val historyMetadataKey = HistoryMetadataKey(
|
||||
url = "https://www.mozilla.org",
|
||||
searchTerm = "test search term",
|
||||
referrerUrl = "https://www.mozilla.org"
|
||||
)
|
||||
val thumbnail = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888)
|
||||
val searchTermTab1 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "44",
|
||||
thumbnail = thumbnail,
|
||||
historyMetadata = historyMetadataKey
|
||||
)
|
||||
val searchTermTab2 = createTab(
|
||||
url = "https://www.mozilla.org",
|
||||
id = "45",
|
||||
thumbnail = thumbnail,
|
||||
historyMetadata = historyMetadataKey
|
||||
)
|
||||
val searchTermTabGroup = TabGroup(historyMetadataKey.searchTerm!!, "", listOf(searchTermTab1.id, searchTermTab2.id))
|
||||
val browserStore = BrowserStore(
|
||||
BrowserState(
|
||||
tabs = listOf(mediaTab, selectedTab, searchTermTab1, searchTermTab2),
|
||||
tabPartitions = mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, listOf(searchTermTabGroup)))),
|
||||
selectedTabId = "43"
|
||||
)
|
||||
)
|
||||
val feature = RecentTabsListFeature(
|
||||
browserStore = browserStore,
|
||||
appStore = appStore
|
||||
)
|
||||
|
||||
feature.start()
|
||||
appStore.waitUntilIdle()
|
||||
|
||||
assertEquals(2, appStore.state.recentTabs.size)
|
||||
assertTrue(appStore.state.recentTabs[0] is RecentTab.Tab)
|
||||
assertEquals(selectedTab, (appStore.state.recentTabs[0] as RecentTab.Tab).state)
|
||||
val searchGroup = (appStore.state.recentTabs[1] as RecentTab.SearchGroup)
|
||||
assertEquals(searchGroup.searchTerm, "test search term")
|
||||
assertEquals(searchGroup.tabId, "44")
|
||||
assertEquals(searchGroup.url, "https://www.mozilla.org")
|
||||
assertEquals(searchGroup.thumbnail, thumbnail)
|
||||
assertEquals(searchGroup.count, 2)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,13 +162,6 @@ class SessionControlInteractorTest {
|
|||
verify { recentTabController.handleRecentTabClicked(tabId) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onRecentSearchGroupClicked() {
|
||||
val tabId = "tabId"
|
||||
interactor.onRecentSearchGroupClicked(tabId)
|
||||
verify { recentTabController.handleRecentSearchGroupClicked(tabId) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onRecentTabShowAllClicked() {
|
||||
interactor.onRecentTabShowAllClicked()
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.junit.Rule
|
|||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.GleanMetrics.RecentTabs
|
||||
import org.mozilla.fenix.GleanMetrics.SearchTerms
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.AppStore
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
|
@ -163,21 +162,4 @@ class RecentTabControllerTest {
|
|||
|
||||
assertNotNull(RecentTabs.showAllClicked.testGetValue())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN handleRecentSearchGroupClicked is called THEN navigate to the tabsTrayFragment and record the correct metric`() {
|
||||
assertNull(SearchTerms.jumpBackInGroupTapped.testGetValue())
|
||||
|
||||
controller.handleRecentSearchGroupClicked("1")
|
||||
|
||||
verify {
|
||||
navController.navigate(
|
||||
match<NavDirections> {
|
||||
it.actionId == R.id.action_global_tabsTrayFragment &&
|
||||
it.arguments["focusGroupTabId"] == "1"
|
||||
}
|
||||
)
|
||||
}
|
||||
assertNotNull(SearchTerms.jumpBackInGroupTapped.testGetValue())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
/* 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.tabstray
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import mozilla.components.browser.state.action.BrowserAction
|
||||
import mozilla.components.browser.state.action.HistoryMetadataAction
|
||||
import mozilla.components.browser.state.action.TabGroupAction
|
||||
import mozilla.components.browser.state.action.TabListAction
|
||||
import mozilla.components.browser.state.engine.EngineMiddleware
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.state.TabGroup
|
||||
import mozilla.components.browser.state.state.TabPartition
|
||||
import mozilla.components.browser.state.state.recover.RecoverableTab
|
||||
import mozilla.components.browser.state.state.recover.TabState
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.concept.storage.HistoryMetadataKey
|
||||
import mozilla.components.lib.state.MiddlewareContext
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class SearchTermTabGroupMiddlewareTest {
|
||||
|
||||
private lateinit var store: BrowserStore
|
||||
private lateinit var searchTermTabGroupMiddleware: SearchTermTabGroupMiddleware
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
searchTermTabGroupMiddleware = SearchTermTabGroupMiddleware()
|
||||
store = BrowserStore(
|
||||
middleware = listOf(searchTermTabGroupMiddleware) + EngineMiddleware.create(engine = mockk()),
|
||||
initialState = BrowserState()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN invoking with set history metadata key action THEN dispatch add tab action`() {
|
||||
val context: MiddlewareContext<BrowserState, BrowserAction> = mockk()
|
||||
val next: (BrowserAction) -> Unit = {}
|
||||
|
||||
every { context.dispatch(any()) } returns Unit
|
||||
|
||||
searchTermTabGroupMiddleware.invoke(
|
||||
context,
|
||||
next,
|
||||
HistoryMetadataAction.SetHistoryMetadataKeyAction("tabId", HistoryMetadataKey("url", "search term", "url"))
|
||||
)
|
||||
|
||||
verify { context.dispatch(TabGroupAction.AddTabAction(SEARCH_TERM_TAB_GROUPS, "search term", "tabId")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN invoking with disband search group action THEN dispatch remove tab group action`() {
|
||||
val context: MiddlewareContext<BrowserState, BrowserAction> = mockk()
|
||||
val next: (BrowserAction) -> Unit = {}
|
||||
val state: BrowserState = mockk()
|
||||
val tabPartitions =
|
||||
mapOf(Pair(SEARCH_TERM_TAB_GROUPS, TabPartition(SEARCH_TERM_TAB_GROUPS, listOf(TabGroup("testId", "search term", listOf("tab1"))))))
|
||||
|
||||
every { context.dispatch(any()) } returns Unit
|
||||
every { context.state } returns state
|
||||
every { state.tabPartitions } returns tabPartitions
|
||||
|
||||
searchTermTabGroupMiddleware.invoke(
|
||||
context,
|
||||
next,
|
||||
HistoryMetadataAction.DisbandSearchGroupAction("search term")
|
||||
)
|
||||
|
||||
verify { context.dispatch(TabGroupAction.RemoveTabGroupAction(SEARCH_TERM_TAB_GROUPS, "testId")) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN invoking with restore action THEN dispatch add tab action`() {
|
||||
val context: MiddlewareContext<BrowserState, BrowserAction> = mockk()
|
||||
val next: (BrowserAction) -> Unit = {}
|
||||
|
||||
every { context.dispatch(any()) } returns Unit
|
||||
|
||||
searchTermTabGroupMiddleware.invoke(
|
||||
context,
|
||||
next,
|
||||
TabListAction.RestoreAction(
|
||||
listOf(
|
||||
RecoverableTab(
|
||||
engineSessionState = null,
|
||||
state = TabState(
|
||||
id = "testId",
|
||||
url = "url",
|
||||
historyMetadata = HistoryMetadataKey("url", "search term", "url")
|
||||
)
|
||||
)
|
||||
),
|
||||
restoreLocation = TabListAction.RestoreAction.RestoreLocation.BEGINNING
|
||||
)
|
||||
)
|
||||
|
||||
verify { context.dispatch(TabGroupAction.AddTabAction(SEARCH_TERM_TAB_GROUPS, "search term", "testId")) }
|
||||
}
|
||||
}
|
|
@ -10,18 +10,6 @@ import org.junit.Test
|
|||
import org.mozilla.fenix.tabstray.syncedtabs.getFakeSyncedTabList
|
||||
|
||||
class TabsTrayStoreReducerTest {
|
||||
@Test
|
||||
fun `GIVEN focusGroupTabId WHEN ConsumeFocusGroupTabIdAction THEN focusGroupTabId must be consumed`() {
|
||||
val initialState = TabsTrayState(focusGroupTabId = "id")
|
||||
val expectedState = initialState.copy(focusGroupTabId = null)
|
||||
|
||||
val resultState = TabsTrayReducer.reduce(
|
||||
initialState,
|
||||
TabsTrayAction.ConsumeFocusGroupTabId
|
||||
)
|
||||
|
||||
assertEquals(expectedState, resultState)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN UpdateInactiveTabs THEN inactive tabs are added`() {
|
||||
|
|
Loading…
Reference in New Issue