Commit a8983a8d authored by Sebastian Kaspari's avatar Sebastian Kaspari
Browse files

Issue #3432: Add method to SessionManager to add multiple Sessions at once.

parent 42198274
......@@ -196,6 +196,31 @@ class LegacySessionManager(
}
}
/**
* Adds multiple sessions.
*
* Note that for performance reasons this method will invoke
* [SessionManager.Observer.onSessionsRestored] and not [SessionManager.Observer.onSessionAdded]
* for every added [Session].
*/
fun add(sessions: List<Session>) = synchronized(values) {
if (sessions.isEmpty()) {
return
}
sessions.forEach {
addInternal(
session = it,
viaRestore = true
)
}
if (selectedIndex == NO_SELECTION) {
// If there is no selection yet then select first non-private session
sessions.find { !it.private }?.let { select(it) }
}
}
/**
* Restores sessions from the provided [Snapshot].
*
......
......@@ -15,6 +15,7 @@ import mozilla.components.concept.engine.Engine
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.EngineSessionState
import mozilla.components.support.base.observer.Observable
import java.lang.IllegalArgumentException
/**
* This class provides access to a centralized registry of all active sessions.
......@@ -109,6 +110,31 @@ class SessionManager(
}
}
/**
* Adds multiple sessions.
*
* Note that for performance reasons this method will invoke
* [SessionManager.Observer.onSessionsRestored] and not [SessionManager.Observer.onSessionAdded]
* for every added [Session].
*/
fun add(sessions: List<Session>) {
// We disallow bulk adding custom tabs or sessions with a parent. At the moment this is not
// needed and it makes the browser-state migration logic easier.
sessions.find { it.isCustomTabSession() }?.let {
throw IllegalArgumentException("Bulk adding of custom tab sessions is not supported.")
}
sessions.find { it.parentId != null }?.let {
throw IllegalArgumentException("Bulk adding of ")
}
// Add store to each Session so that it can dispatch actions whenever it changes.
sessions.forEach { it.store = store }
delegate.add(sessions)
}
/**
* Restores sessions from the provided [Snapshot].
*
......
......@@ -17,7 +17,7 @@ import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.mock
......@@ -217,7 +217,7 @@ class SessionManagerTest {
fun `createSnapshot ignores CustomTab sessions`() {
val manager = SessionManager(mock())
val session = Session("http://mozilla.org")
session.customTabConfig = Mockito.mock(CustomTabConfig::class.java)
session.customTabConfig = mock(CustomTabConfig::class.java)
manager.add(session)
assertTrue(manager.createSnapshot().isEmpty())
......@@ -227,7 +227,7 @@ class SessionManagerTest {
fun `createSnapshot ignores private CustomTab sessions`() {
val manager = SessionManager(mock())
val session = Session("http://mozilla.org", true)
session.customTabConfig = Mockito.mock(CustomTabConfig::class.java)
session.customTabConfig = mock(CustomTabConfig::class.java)
manager.add(session)
assertTrue(manager.createSnapshot().isEmpty())
......@@ -387,10 +387,10 @@ class SessionManagerTest {
fun `createSnapshot produces a correct snapshot of sessions`() {
val manager = SessionManager(mock())
val customTabSession = Session("http://mozilla.org")
customTabSession.customTabConfig = Mockito.mock(CustomTabConfig::class.java)
customTabSession.customTabConfig = mock(CustomTabConfig::class.java)
val privateSession = Session("http://www.secret.com", true)
val privateCustomTabSession = Session("http://very.secret.com", true)
privateCustomTabSession.customTabConfig = Mockito.mock(CustomTabConfig::class.java)
privateCustomTabSession.customTabConfig = mock(CustomTabConfig::class.java)
val regularSession = Session("http://www.firefox.com")
val engineSessionState: EngineSessionState = mock()
......@@ -524,7 +524,7 @@ class SessionManagerTest {
val session2 = Session("https://www.firefox.com")
val session3 = Session("https://wiki.mozilla.org")
val session4 = Session("https://github.com/mozilla-mobile/android-components")
session4.customTabConfig = Mockito.mock(CustomTabConfig::class.java)
session4.customTabConfig = mock(CustomTabConfig::class.java)
manager.add(session1)
manager.add(session2)
......@@ -641,7 +641,7 @@ class SessionManagerTest {
val session1 = Session("https://www.mozilla.org")
val session2 = Session("https://getPocket.com")
val session3 = Session("https://www.firefox.com")
session2.customTabConfig = Mockito.mock(CustomTabConfig::class.java)
session2.customTabConfig = mock(CustomTabConfig::class.java)
manager.add(session1)
manager.add(session2)
......@@ -701,7 +701,7 @@ class SessionManagerTest {
@Test
fun `custom tab session will not be selected if it is the first session`() {
val session = Session("about:blank")
session.customTabConfig = Mockito.mock(CustomTabConfig::class.java)
session.customTabConfig = mock(CustomTabConfig::class.java)
val manager = SessionManager(mock())
manager.add(session)
......@@ -1116,4 +1116,113 @@ class SessionManagerTest {
manager.restore(snapshot)
}
@Test
fun `WHEN adding multiple sessions THEN sessions get added and selection gets updated`() {
val manager = SessionManager(engine = mock())
val sessions = listOf(
Session("https://www.mozilla.org"),
Session("https://www.example.org"),
Session("https://www.firefox.com", private = true)
)
assertEquals(0, manager.sessions.size)
assertNull(manager.selectedSession)
manager.add(sessions)
assertEquals(3, manager.sessions.size)
assertEquals("https://www.mozilla.org", manager.selectedSessionOrThrow.url)
}
@Test(expected = java.lang.IllegalArgumentException::class)
fun `WHEN adding multiple session containing custom tab THEN adding fails`() {
val manager = SessionManager(engine = mock())
val sessions = listOf(
Session("https://www.mozilla.org"),
Session("https://www.example.org").apply {
customTabConfig = mock()
},
Session("https://www.firefox.com", private = true)
)
manager.add(sessions)
}
@Test(expected = java.lang.IllegalArgumentException::class)
fun `WHEN adding multiple session AND parent id THEN adding fails`() {
val manager = SessionManager(engine = mock())
val sessions = listOf(
Session("https://www.mozilla.org"),
Session("https://www.example.org").apply {
parentId = "some-parent"
},
Session("https://www.firefox.com", private = true)
)
manager.add(sessions)
}
@Test
fun `When adding multiple sessions then non-private session will get selected`() {
val manager = SessionManager(engine = mock())
val sessions = listOf(
Session("https://www.mozilla.org", private = true),
Session("https://www.example.org", private = true),
Session("https://getpocket.com"),
Session("https://www.firefox.com", private = true)
)
assertEquals(0, manager.sessions.size)
assertNull(manager.selectedSession)
manager.add(sessions)
assertEquals(4, manager.sessions.size)
assertEquals("https://getpocket.com", manager.selectedSessionOrThrow.url)
}
@Test
fun `WHEN adding multiple private sessions THEN none is selected`() {
val manager = SessionManager(engine = mock())
val sessions = listOf(
Session("https://www.mozilla.org", private = true),
Session("https://www.example.org", private = true),
Session("https://www.firefox.com", private = true)
)
assertEquals(0, manager.sessions.size)
assertNull(manager.selectedSession)
manager.add(sessions)
assertEquals(3, manager.sessions.size)
assertNull(manager.selectedSession)
}
@Test
fun `WHEN adding multiple sessions AND selection already exist THEN selection is not updated`() {
val manager = SessionManager(engine = mock())
manager.add(Session("https://www.mozilla.org"))
manager.add(Session("https://www.example.org"))
val sessions = listOf(
Session("htttps://getpocket.com"),
Session("https://www.firefox.com", private = true)
)
assertEquals(2, manager.sessions.size)
assertEquals("https://www.mozilla.org", manager.selectedSessionOrThrow.url)
manager.add(sessions)
assertEquals(4, manager.sessions.size)
assertEquals("https://www.mozilla.org", manager.selectedSessionOrThrow.url)
}
}
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