diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt index a6f2bf6fc9..ff2e371af8 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/NavigationInteractor.kt @@ -7,7 +7,6 @@ package org.mozilla.fenix.tabstray import android.content.Context import androidx.navigation.NavController import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.launch import mozilla.components.browser.state.selector.getNormalOrPrivateTabs @@ -25,6 +24,7 @@ import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.ext.navigateBlockingForAsyncNavGraph import org.mozilla.fenix.home.HomeFragment import org.mozilla.fenix.tabstray.ext.getTabSessionState +import kotlin.coroutines.CoroutineContext /** * An interactor that helps with navigating to different parts of the app from the tabs tray. @@ -91,7 +91,8 @@ class DefaultNavigationInteractor( private val bookmarksUseCase: BookmarksUseCase, private val tabsTrayStore: TabsTrayStore, private val collectionStorage: TabCollectionStorage, - private val accountManager: FxaAccountManager + private val accountManager: FxaAccountManager, + private val ioDispatcher: CoroutineContext ) : NavigationInteractor { override fun onTabTrayDismissed() { @@ -181,8 +182,9 @@ class DefaultNavigationInteractor( override fun onSaveToBookmarks(tabs: Collection) { tabs.forEach { tab -> // We don't combine the context with lifecycleScope so that our jobs are not cancelled - // if we leave the fragment, i.e. we still want the bookmarks to be added. - CoroutineScope(Dispatchers.IO).launch { + // if we leave the fragment, i.e. we still want the bookmarks to be added if the + // tabs tray closes before the job is done. + CoroutineScope(ioDispatcher).launch { bookmarksUseCase.addBookmark(tab.url, tab.title) } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt index f15754ecc9..f71f16bd8c 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/TabsTrayFragment.kt @@ -119,7 +119,8 @@ class TabsTrayFragment : AppCompatDialogFragment(), TabsTrayInteractor { dismissTabTrayAndNavigateHome = ::dismissTabsTrayAndNavigateHome, bookmarksUseCase = requireComponents.useCases.bookmarksUseCases, collectionStorage = requireComponents.core.tabCollectionStorage, - accountManager = requireComponents.backgroundServices.accountManager + accountManager = requireComponents.backgroundServices.accountManager, + ioDispatcher = Dispatchers.IO ) tabsTrayController = DefaultTabsTrayController( diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt index 3afb3b5793..69ae45dadb 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/NavigationInteractorTest.kt @@ -14,6 +14,7 @@ import io.mockk.verify import io.mockk.mockkStatic import io.mockk.unmockkStatic import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.runBlockingTest import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState @@ -21,6 +22,7 @@ import mozilla.components.browser.state.state.createTab as createStateTab import mozilla.components.browser.state.store.BrowserStore import mozilla.components.concept.tabstray.Tab import mozilla.components.service.fxa.manager.FxaAccountManager +import mozilla.components.support.test.rule.MainCoroutineRule import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule @@ -34,6 +36,7 @@ import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.tabstray.browser.createTab as createTrayTab +@ExperimentalCoroutinesApi class NavigationInteractorTest { private lateinit var store: BrowserStore private lateinit var tabsTrayStore: TabsTrayStore @@ -48,9 +51,14 @@ class NavigationInteractorTest { private val collectionStorage: TabCollectionStorage = mockk(relaxed = true) private val accountManager: FxaAccountManager = mockk(relaxed = true) + private val testDispatcher = TestCoroutineDispatcher() + @get:Rule val disableNavGraphProviderAssertionRule = DisableNavGraphProviderAssertionRule() + @get:Rule + val coroutinesTestRule = MainCoroutineRule(testDispatcher) + @Before fun setup() { store = BrowserStore(initialState = BrowserState(tabs = listOf(testTab))) @@ -65,7 +73,8 @@ class NavigationInteractorTest { bookmarksUseCase, tabsTrayStore, collectionStorage, - accountManager + accountManager, + testDispatcher ) } @@ -206,9 +215,21 @@ class NavigationInteractorTest { unmockkStatic("org.mozilla.fenix.collections.CollectionsDialogKt") } - @OptIn(ExperimentalCoroutinesApi::class) @Test fun `onBookmarkTabs calls navigation on DefaultNavigationInteractor`() = runBlockingTest { + navigationInteractor = DefaultNavigationInteractor( + context, + store, + navController, + metrics, + dismissTabTray, + dismissTabTrayAndNavigateHome, + bookmarksUseCase, + tabsTrayStore, + collectionStorage, + accountManager, + coroutineContext + ) navigationInteractor.onSaveToBookmarks(listOf(createTrayTab())) coVerify(exactly = 1) { bookmarksUseCase.addBookmark(any(), any(), any()) } }