Commit 2192b68c authored by Sebastian Kaspari's avatar Sebastian Kaspari
Browse files

Issue #3557: Add TabListAction.RestoreAction for restoring a list of tabs and the selection.

parent 3becaa52
......@@ -16,7 +16,6 @@ import mozilla.components.lib.state.Action
* [Action] implementation related to [BrowserState].
*/
sealed class BrowserAction : Action
/**
* [BrowserAction] implementations related to updating the list of [TabSessionState] inside [BrowserState].
*/
......@@ -35,6 +34,11 @@ sealed class TabListAction : BrowserAction() {
* Removes the [TabSessionState] with the given [tabId] from the list of sessions.
*/
data class RemoveTabAction(val tabId: String) : TabListAction()
/**
* Restores state from a (partial) previous state.
*/
data class RestoreAction(val tabs: List<TabSessionState>, val selectedTabId: String? = null) : TabListAction()
}
/**
......
......@@ -51,6 +51,23 @@ internal object TabListReducer {
)
}
}
is TabListAction.RestoreAction -> {
// We are adding the restored tabs first and then the already existing tabs. Since restore can or should
// happen asynchronously we may already have a tab at this point (e.g. from an `Intent` and so we
// pretend we restored the list of tabs before any tab was added.
state.copy(
tabs = action.tabs + state.tabs,
selectedTabId = if (action.selectedTabId != null && state.selectedTabId == null) {
// We only want to update the selected tab if none has been already selected. Otherwise we may
// switch to a restored tab even though the user is already looking at an existing tab (e.g.
// a tab that came from an intent).
action.selectedTabId
} else {
state.selectedTabId
}
)
}
}
}
}
......
......@@ -258,4 +258,110 @@ class TabListActionTest {
store.dispatch(TabListAction.RemoveTabAction("a")).joinBlocking()
assertNull(store.state.selectedTabId)
}
@Test
fun `RestoreAction - Adds restored tabs and updates selected tab`() {
val store = BrowserStore(BrowserState())
assertEquals(0, store.state.tabs.size)
store.dispatch(TabListAction.RestoreAction(
tabs = listOf(
createTab(id = "a", url = "https://www.mozilla.org", private = false),
createTab(id = "b", url = "https://www.firefox.com", private = true),
createTab(id = "c", url = "https://www.example.org", private = true),
createTab(id = "d", url = "https://getpocket.com", private = false)
),
selectedTabId = "d"
)).joinBlocking()
assertEquals(4, store.state.tabs.size)
assertEquals("a", store.state.tabs[0].id)
assertEquals("b", store.state.tabs[1].id)
assertEquals("c", store.state.tabs[2].id)
assertEquals("d", store.state.tabs[3].id)
assertEquals("d", store.state.selectedTabId)
}
@Test
fun `RestoreAction - Adds restored tabs to existing tabs without updating selection`() {
val store = BrowserStore(BrowserState(
tabs = listOf(
createTab(id = "a", url = "https://www.mozilla.org", private = false),
createTab(id = "b", url = "https://www.firefox.com", private = true)
),
selectedTabId = "a"
))
assertEquals(2, store.state.tabs.size)
store.dispatch(TabListAction.RestoreAction(
tabs = listOf(
createTab(id = "c", url = "https://www.example.org", private = true),
createTab(id = "d", url = "https://getpocket.com", private = false)
),
selectedTabId = "d"
)).joinBlocking()
assertEquals(4, store.state.tabs.size)
assertEquals("c", store.state.tabs[0].id)
assertEquals("d", store.state.tabs[1].id)
assertEquals("a", store.state.tabs[2].id)
assertEquals("b", store.state.tabs[3].id)
assertEquals("a", store.state.selectedTabId)
}
@Test
fun `RestoreAction - Adds restored tabs to existing tabs with updating selection`() {
val store = BrowserStore(BrowserState(
tabs = listOf(
createTab(id = "a", url = "https://www.mozilla.org", private = false),
createTab(id = "b", url = "https://www.firefox.com", private = true)
)
))
assertEquals(2, store.state.tabs.size)
store.dispatch(TabListAction.RestoreAction(
tabs = listOf(
createTab(id = "c", url = "https://www.example.org", private = true),
createTab(id = "d", url = "https://getpocket.com", private = false)
),
selectedTabId = "d"
)).joinBlocking()
assertEquals(4, store.state.tabs.size)
assertEquals("c", store.state.tabs[0].id)
assertEquals("d", store.state.tabs[1].id)
assertEquals("a", store.state.tabs[2].id)
assertEquals("b", store.state.tabs[3].id)
assertEquals("d", store.state.selectedTabId)
}
@Test
fun `RestoreAction - Does not update selection if none was provided`() {
val store = BrowserStore(BrowserState(
tabs = listOf(
createTab(id = "a", url = "https://www.mozilla.org", private = false),
createTab(id = "b", url = "https://www.firefox.com", private = true)
)
))
assertEquals(2, store.state.tabs.size)
store.dispatch(TabListAction.RestoreAction(
tabs = listOf(
createTab(id = "c", url = "https://www.example.org", private = true),
createTab(id = "d", url = "https://getpocket.com", private = false)
),
selectedTabId = null
)).joinBlocking()
assertEquals(4, store.state.tabs.size)
assertEquals("c", store.state.tabs[0].id)
assertEquals("d", store.state.tabs[1].id)
assertEquals("a", store.state.tabs[2].id)
assertEquals("b", store.state.tabs[3].id)
assertNull(store.state.selectedTabId)
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment