diff --git a/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt b/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt index f9e7df531..0869cdd11 100644 --- a/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt @@ -14,6 +14,7 @@ import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import mozilla.components.browser.state.state.MediaState import mozilla.components.feature.tab.collections.TabCollection +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Before @@ -52,6 +53,11 @@ class DefaultCollectionCreationControllerTest { ) } + @After + fun cleanUp() { + testCoroutineScope.cleanupTestCoroutines() + } + @Test fun `GIVEN tab list WHEN saveCollectionName is called THEN collection should be created`() { val session = mockSession(sessionId = "session-1") diff --git a/app/src/test/java/org/mozilla/fenix/exceptions/login/LoginExceptionsInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/exceptions/login/LoginExceptionsInteractorTest.kt index b36f147e9..92fc23bce 100644 --- a/app/src/test/java/org/mozilla/fenix/exceptions/login/LoginExceptionsInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/exceptions/login/LoginExceptionsInteractorTest.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.test.TestCoroutineScope import kotlinx.coroutines.test.runBlockingTest import mozilla.components.feature.logins.exceptions.LoginException import mozilla.components.feature.logins.exceptions.LoginExceptionStorage +import org.junit.After import org.junit.Before import org.junit.Test @@ -27,6 +28,11 @@ class LoginExceptionsInteractorTest { interactor = DefaultLoginExceptionsInteractor(scope, loginExceptionStorage) } + @After + fun cleanUp() { + scope.cleanupTestCoroutines() + } + @Test fun onDeleteAll() = scope.runBlockingTest { interactor.onDeleteAll() diff --git a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt index 4ae80cffa..260c81308 100644 --- a/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/home/DefaultSessionControlControllerTest.kt @@ -20,6 +20,7 @@ import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.top.sites.TopSite import mozilla.components.support.test.rule.MainCoroutineRule +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -42,8 +43,10 @@ import mozilla.components.feature.tab.collections.Tab as ComponentTab @OptIn(ExperimentalCoroutinesApi::class) class DefaultSessionControlControllerTest { + private val testDispatcher = TestCoroutineDispatcher() + @get:Rule - val coroutinesTestRule = MainCoroutineRule(TestCoroutineDispatcher()) + val coroutinesTestRule = MainCoroutineRule(testDispatcher) private val activity: HomeActivity = mockk(relaxed = true) private val fragmentStore: HomeFragmentStore = mockk(relaxed = true) @@ -68,6 +71,7 @@ class DefaultSessionControlControllerTest { private val searchEngineManager = mockk(relaxed = true) private val settings: Settings = mockk(relaxed = true) private val analytics: Analytics = mockk(relaxed = true) + private val scope = TestCoroutineScope() private lateinit var controller: DefaultSessionControlController @@ -103,7 +107,7 @@ class DefaultSessionControlControllerTest { addTabUseCase = tabsUseCases.addTab, fragmentStore = fragmentStore, navController = navController, - viewLifecycleScope = TestCoroutineScope(), + viewLifecycleScope = scope, hideOnboarding = hideOnboarding, registerCollectionStorageObserver = registerCollectionStorageObserver, showDeleteCollectionPrompt = showDeleteCollectionPrompt, @@ -112,6 +116,12 @@ class DefaultSessionControlControllerTest { ) } + @After + fun cleanUp() { + scope.cleanupTestCoroutines() + testDispatcher.cleanupTestCoroutines() + } + @Test fun handleCollectionAddTabTapped() { val collection = mockk { diff --git a/app/src/test/java/org/mozilla/fenix/library/downloads/DownloadControllerTest.kt b/app/src/test/java/org/mozilla/fenix/library/downloads/DownloadControllerTest.kt index 75d3d7418..66109bf55 100644 --- a/app/src/test/java/org/mozilla/fenix/library/downloads/DownloadControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/downloads/DownloadControllerTest.kt @@ -7,10 +7,10 @@ package org.mozilla.fenix.library.downloads import io.mockk.every import io.mockk.mockk import io.mockk.verify -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineScope import mozilla.components.browser.state.state.content.DownloadState +import org.junit.After import org.junit.Assert.assertFalse import org.junit.Before import org.junit.Test @@ -22,11 +22,10 @@ import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @RunWith(FenixRobolectricTestRunner::class) class DownloadControllerTest { private val downloadItem = DownloadItem("0", "title", "url", "77", "jpg", DownloadState.Status.COMPLETED) - private val scope: CoroutineScope = TestCoroutineScope() + private val scope = TestCoroutineScope() private val store: DownloadFragmentStore = mockk(relaxed = true) private val state: DownloadFragmentState = mockk(relaxed = true) private val openToFileManager: (DownloadItem, BrowsingMode?) -> Unit = mockk(relaxed = true) - private val invalidateOptionsMenu: () -> Unit = mockk(relaxed = true) private val controller = DefaultDownloadController( store, openToFileManager @@ -37,6 +36,11 @@ class DownloadControllerTest { every { store.state } returns state } + @After + fun cleanUp() { + scope.cleanupTestCoroutines() + } + @Test fun onPressDownloadItemInNormalMode() { controller.handleOpen(downloadItem) diff --git a/app/src/test/java/org/mozilla/fenix/library/history/HistoryControllerTest.kt b/app/src/test/java/org/mozilla/fenix/library/history/HistoryControllerTest.kt index aeb3a7738..ea6f427cf 100644 --- a/app/src/test/java/org/mozilla/fenix/library/history/HistoryControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/library/history/HistoryControllerTest.kt @@ -13,10 +13,10 @@ import io.mockk.every import io.mockk.mockk import io.mockk.slot import io.mockk.verify -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineScope import mozilla.components.concept.engine.prompt.ShareData +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue @@ -33,7 +33,7 @@ import org.mozilla.fenix.helpers.FenixRobolectricTestRunner @RunWith(FenixRobolectricTestRunner::class) class HistoryControllerTest { private val historyItem = HistoryItem(0, "title", "url", 0.toLong()) - private val scope: CoroutineScope = TestCoroutineScope() + private val scope = TestCoroutineScope() private val store: HistoryFragmentStore = mockk(relaxed = true) private val state: HistoryFragmentState = mockk(relaxed = true) private val navController: NavController = mockk(relaxed = true) @@ -64,6 +64,11 @@ class HistoryControllerTest { every { store.state } returns state } + @After + fun cleanUp() { + scope.cleanupTestCoroutines() + } + @Test fun onPressHistoryItemInNormalMode() { controller.handleOpen(historyItem) diff --git a/app/src/test/java/org/mozilla/fenix/migration/MigrationTelemetryListenerTest.kt b/app/src/test/java/org/mozilla/fenix/migration/MigrationTelemetryListenerTest.kt index 1c6c65a13..5bee4e175 100644 --- a/app/src/test/java/org/mozilla/fenix/migration/MigrationTelemetryListenerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/migration/MigrationTelemetryListenerTest.kt @@ -16,6 +16,7 @@ import mozilla.components.support.migration.state.MigrationAction import mozilla.components.support.migration.state.MigrationStore import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.rule.MainCoroutineRule +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -46,6 +47,11 @@ class MigrationTelemetryListenerTest { ) } + @After + fun cleanUp() { + testDispatcher.cleanupTestCoroutines() + } + @Test fun `progress state is logged`() = testDispatcher.runBlockingTest { listener.start() diff --git a/app/src/test/java/org/mozilla/fenix/push/WebPushEngineIntegrationTest.kt b/app/src/test/java/org/mozilla/fenix/push/WebPushEngineIntegrationTest.kt index 08354def9..a66baa183 100644 --- a/app/src/test/java/org/mozilla/fenix/push/WebPushEngineIntegrationTest.kt +++ b/app/src/test/java/org/mozilla/fenix/push/WebPushEngineIntegrationTest.kt @@ -57,6 +57,7 @@ class WebPushEngineIntegrationTest { @After fun teardown() { unmockkStatic(Base64::class) + scope.cleanupTestCoroutines() } @Test diff --git a/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt b/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt index fb6500a76..8de7ca2b6 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/SettingsFragmentTest.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineDispatcher import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.rule.MainCoroutineRule +import org.junit.After import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue @@ -49,6 +50,11 @@ class SettingsFragmentTest { every { Config.channel } returns ReleaseChannel.Nightly } + @After + fun cleanUp() { + testDispatcher.cleanupTestCoroutines() + } + @Test fun `Add-on collection override pref is visible if debug menu active`() { val settingsFragment = SettingsFragment() diff --git a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt index 605a81492..414c8dfd4 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt @@ -19,6 +19,7 @@ import mozilla.components.concept.engine.Engine import mozilla.components.concept.storage.HistoryStorage import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.support.test.rule.MainCoroutineRule +import org.junit.After import org.junit.Before import org.junit.Rule import org.junit.Test @@ -27,8 +28,10 @@ import org.mozilla.fenix.components.PermissionStorage @OptIn(ExperimentalCoroutinesApi::class) class DefaultDeleteBrowsingDataControllerTest { + val testDispatcher = TestCoroutineDispatcher() + @get:Rule - val coroutinesTestRule = MainCoroutineRule(TestCoroutineDispatcher()) + val coroutinesTestRule = MainCoroutineRule(testDispatcher) private var removeAllTabs: TabsUseCases.RemoveAllTabsUseCase = mockk(relaxed = true) private var historyStorage: HistoryStorage = mockk(relaxed = true) @@ -51,6 +54,11 @@ class DefaultDeleteBrowsingDataControllerTest { ) } + @After + fun cleanUp() { + testDispatcher.cleanupTestCoroutines() + } + @Test fun deleteTabs() = runBlockingTest { diff --git a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt index 314015612..6164cf932 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt @@ -18,6 +18,7 @@ import mozilla.components.browser.storage.sync.PlacesHistoryStorage import mozilla.components.concept.engine.Engine import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.support.test.rule.MainCoroutineRule +import org.junit.After import org.junit.Before import org.junit.Ignore import org.junit.Rule @@ -34,8 +35,10 @@ import org.mozilla.fenix.utils.Settings @RunWith(FenixRobolectricTestRunner::class) class DeleteAndQuitTest { + val testDispatcher = TestCoroutineDispatcher() + @get:Rule - val coroutinesTestRule = MainCoroutineRule(TestCoroutineDispatcher()) + val coroutinesTestRule = MainCoroutineRule(testDispatcher) private val activity: HomeActivity = mockk(relaxed = true) private val settings: Settings = mockk(relaxed = true) @@ -58,6 +61,11 @@ class DeleteAndQuitTest { every { activity.components.core.icons } returns iconsStorage } + @After + fun cleanUp() { + testDispatcher.cleanupTestCoroutines() + } + @Test fun `delete only tabs and quit`() = runBlockingTest { // When diff --git a/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsStorageControllerTest.kt b/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsStorageControllerTest.kt index e06dc6641..aa46116e5 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsStorageControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/logins/SavedLoginsStorageControllerTest.kt @@ -33,8 +33,9 @@ import org.mozilla.fenix.settings.logins.fragment.EditLoginFragmentDirections @ExperimentalCoroutinesApi @RunWith(FenixRobolectricTestRunner::class) class SavedLoginsStorageControllerTest { + val testDispatcher = TestCoroutineDispatcher() @get:Rule - val coroutinesTestRule = MainCoroutineRule(TestCoroutineDispatcher()) + val coroutinesTestRule = MainCoroutineRule(testDispatcher) private val passwordsStorage: SyncableLoginsStorage = mockk(relaxed = true) private lateinit var controller: SavedLoginsStorageController @@ -65,6 +66,7 @@ class SavedLoginsStorageControllerTest { fun cleanUp() { scope.cleanupTestCoroutines() ioDispatcher.cleanupTestCoroutines() + testDispatcher.cleanupTestCoroutines() } @Test diff --git a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt index f0df1e6b8..a8bedf56d 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt @@ -22,6 +22,7 @@ import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissions.Status.NO_DECISION import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.support.test.robolectric.testContext +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertSame import org.junit.Test @@ -66,6 +67,11 @@ class DefaultQuickSettingsControllerTest { dismiss = dismiss )) + @After + fun cleanUp() { + coroutinesScope.cleanupTestCoroutines() + } + @Test fun `handlePermissionsShown should delegate to an injected parameter`() { controller.handlePermissionsShown() diff --git a/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt b/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt index 90540b24c..a0f9e833d 100644 --- a/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/share/ShareControllerTest.kt @@ -28,6 +28,7 @@ import mozilla.components.concept.sync.TabData import mozilla.components.feature.accounts.push.SendTabUseCases import mozilla.components.feature.share.RecentAppsStorage import mozilla.components.support.test.robolectric.testContext +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Assert.assertTrue @@ -54,6 +55,7 @@ class ShareControllerTest { ShareData(url = "url0", title = "title0"), ShareData(url = "url1", title = "title1") ) + // Navigation between app fragments uses ShareTab as arguments. SendTabUseCases uses TabData. private val tabsData = listOf( TabData("title0", "url0"), @@ -76,6 +78,11 @@ class ShareControllerTest { every { context.metrics } returns metrics } + @After + fun cleanUp() { + testCoroutineScope.cleanupTestCoroutines() + } + @Test fun `handleShareClosed should call a passed in delegate to close this`() { controller.handleShareClosed() @@ -93,8 +100,10 @@ class ShareControllerTest { // needed for capturing the actual Intent used the `slot` one doesn't have this flag so we // need to use an Activity Context. val activityContext: Context = mockk() - val testController = DefaultShareController(activityContext, shareSubject, shareData, mockk(), - mockk(), mockk(), recentAppStorage, testCoroutineScope, dismiss) + val testController = DefaultShareController( + activityContext, shareSubject, shareData, mockk(), + mockk(), mockk(), recentAppStorage, testCoroutineScope, dismiss + ) every { activityContext.startActivity(capture(shareIntent)) } just Runs every { recentAppStorage.updateRecentApp(appShareOption.activityName) } just Runs @@ -127,8 +136,11 @@ class ShareControllerTest { // needed for capturing the actual Intent used the `slot` one doesn't have this flag so we // need to use an Activity Context. val activityContext: Context = mockk() - val testController = DefaultShareController(activityContext, shareSubject, shareData, mockk(), - snackbar, mockk(), mockk(), testCoroutineScope, dismiss) + val testController = DefaultShareController( + activityContext, shareSubject, shareData, mockk(), + snackbar, mockk(), recentAppStorage, testCoroutineScope, dismiss + ) + every { recentAppStorage.updateRecentApp(appShareOption.activityName) } just Runs every { activityContext.startActivity(capture(shareIntent)) } throws SecurityException() every { activityContext.getString(R.string.share_error_snackbar) } returns "Cannot share to this app" @@ -152,8 +164,11 @@ class ShareControllerTest { // needed for capturing the actual Intent used the `slot` one doesn't have this flag so we // need to use an Activity Context. val activityContext: Context = mockk() - val testController = DefaultShareController(activityContext, shareSubject, shareData, mockk(), - snackbar, mockk(), mockk(), testCoroutineScope, dismiss) + val testController = DefaultShareController( + activityContext, shareSubject, shareData, mockk(), + snackbar, mockk(), recentAppStorage, testCoroutineScope, dismiss + ) + every { recentAppStorage.updateRecentApp(appShareOption.activityName) } just Runs every { activityContext.startActivity(capture(shareIntent)) } throws ActivityNotFoundException() every { activityContext.getString(R.string.share_error_snackbar) } returns "Cannot share to this app" @@ -171,7 +186,8 @@ class ShareControllerTest { @Suppress("DeferredResultUnused") fun `handleShareToDevice should share to account device, inform callbacks and dismiss`() { val deviceToShareTo = Device( - "deviceId", "deviceName", DeviceType.UNKNOWN, false, 0L, emptyList(), false, null) + "deviceId", "deviceName", DeviceType.UNKNOWN, false, 0L, emptyList(), false, null + ) val deviceId = slot() val tabsShared = slot>() @@ -194,8 +210,26 @@ class ShareControllerTest { @Suppress("DeferredResultUnused") fun `handleShareToAllDevices calls handleShareToDevice multiple times`() { val devicesToShareTo = listOf( - Device("deviceId0", "deviceName0", DeviceType.UNKNOWN, false, 0L, emptyList(), false, null), - Device("deviceId1", "deviceName1", DeviceType.UNKNOWN, true, 1L, emptyList(), false, null) + Device( + "deviceId0", + "deviceName0", + DeviceType.UNKNOWN, + false, + 0L, + emptyList(), + false, + null + ), + Device( + "deviceId1", + "deviceName1", + DeviceType.UNKNOWN, + true, + 1L, + emptyList(), + false, + null + ) ) val tabsShared = slot>() diff --git a/app/src/test/java/org/mozilla/fenix/share/ShareViewModelTest.kt b/app/src/test/java/org/mozilla/fenix/share/ShareViewModelTest.kt index 17502d251..9aa817e65 100644 --- a/app/src/test/java/org/mozilla/fenix/share/ShareViewModelTest.kt +++ b/app/src/test/java/org/mozilla/fenix/share/ShareViewModelTest.kt @@ -27,6 +27,7 @@ import mozilla.components.feature.share.RecentApp import mozilla.components.feature.share.RecentAppsStorage import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.support.test.robolectric.testContext +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test @@ -71,6 +72,11 @@ class ShareViewModelTest { viewModel.ioDispatcher = testIoDispatcher } + @After + fun cleanUp() { + testIoDispatcher.cleanupTestCoroutines() + } + @Test fun `liveData should be initialized as empty list`() { assertEquals(emptyList(), viewModel.devicesList.value) diff --git a/app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt index 6ff967c84..768681f70 100644 --- a/app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabtray/SyncedTabsControllerTest.kt @@ -18,6 +18,7 @@ import mozilla.components.feature.syncedtabs.view.SyncedTabsView.ErrorType import mozilla.components.support.test.ext.joinBlocking import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.test.rule.MainCoroutineRule +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule @@ -68,6 +69,11 @@ class SyncedTabsControllerTest { SyncedTabsController(lifecycleOwner, view, store, concatAdapter, coroutineContext) } + @After + fun cleanUp() { + testDispatcher.cleanupTestCoroutines() + } + @Test fun `display synced tabs in reverse`() { val tabs = listOf(