diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt index a31d8ce19a..4d4f8b4b19 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAdapter.kt @@ -41,7 +41,6 @@ class InactiveTabsAdapter( ) : Adapter(DiffCallback), TabsTray, FeatureNameHolder { internal lateinit var inactiveTabsInteractor: InactiveTabsInteractor - internal lateinit var inactiveTabsAutoCloseDialogInteractor: InactiveTabsAutoCloseDialogInteractor internal var inActiveTabsCount: Int = 0 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InactiveTabViewHolder { @@ -49,7 +48,7 @@ class InactiveTabsAdapter( .inflate(viewType, parent, false) return when (viewType) { - AutoCloseDialogHolder.LAYOUT_ID -> AutoCloseDialogHolder(view, inactiveTabsAutoCloseDialogInteractor) + AutoCloseDialogHolder.LAYOUT_ID -> AutoCloseDialogHolder(view, inactiveTabsInteractor) HeaderHolder.LAYOUT_ID -> HeaderHolder(view, inactiveTabsInteractor, tabsTrayInteractor) TabViewHolder.LAYOUT_ID -> TabViewHolder(view, browserTrayInteractor, featureName) FooterHolder.LAYOUT_ID -> FooterHolder(view) diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogController.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogController.kt index ca140022ec..2f675f2694 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogController.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogController.kt @@ -24,7 +24,7 @@ class InactiveTabsAutoCloseDialogController( */ fun close() { markDialogAsShown() - refeshInactiveTabsSecion() + refreshInactiveTabsSection() metrics.track(Event.TabsTrayAutoCloseDialogDismissed) } @@ -37,7 +37,7 @@ class InactiveTabsAutoCloseDialogController( settings.closeTabsAfterOneWeek = false settings.closeTabsAfterOneDay = false settings.manuallyCloseTabs = false - refeshInactiveTabsSecion() + refreshInactiveTabsSection() metrics.track(Event.TabsTrayAutoCloseDialogTurnOnClicked) } @@ -49,7 +49,7 @@ class InactiveTabsAutoCloseDialogController( } @VisibleForTesting - internal fun refeshInactiveTabsSecion() { + internal fun refreshInactiveTabsSection() { val tabs = browserStore.state.tabs.filter(tabFilter) tray.updateTabs(tabs, browserStore.state.selectedTabId) } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogInteractor.kt deleted file mode 100644 index ec3d930d99..0000000000 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogInteractor.kt +++ /dev/null @@ -1,22 +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.browser - -interface InactiveTabsAutoCloseDialogInteractor { - fun onCloseClicked() - fun onEnabledAutoCloseClicked() -} - -class DefaultInactiveTabsAutoCloseDialogInteractor( - private val controller: InactiveTabsAutoCloseDialogController -) : InactiveTabsAutoCloseDialogInteractor { - override fun onCloseClicked() { - controller.close() - } - - override fun onEnabledAutoCloseClicked() { - controller.enableAutoClosed() - } -} diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt index 64778a6311..d79c274270 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsController.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.tabstray.browser +import androidx.annotation.VisibleForTesting import mozilla.components.browser.state.state.TabSessionState import mozilla.components.browser.state.store.BrowserStore import mozilla.components.browser.tabstray.TabsTray @@ -11,13 +12,15 @@ import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.Event +import org.mozilla.fenix.utils.Settings class InactiveTabsController( private val browserStore: BrowserStore, private val appStore: AppStore, private val tabFilter: (TabSessionState) -> Boolean, private val tray: TabsTray, - private val metrics: MetricController + private val metrics: MetricController, + private val settings: Settings ) { /** * Updates the inactive card to be expanded to display all the tabs, or collapsed with only @@ -33,6 +36,40 @@ class InactiveTabsController( } ) + refreshInactiveTabsSection() + } + + /** + * Dismiss the auto-close dialog. + */ + fun close() { + markDialogAsShown() + refreshInactiveTabsSection() + metrics.track(Event.TabsTrayAutoCloseDialogDismissed) + } + + /** + * Enable the auto-close feature with the after a month setting. + */ + fun enableAutoClosed() { + markDialogAsShown() + settings.closeTabsAfterOneMonth = true + settings.closeTabsAfterOneWeek = false + settings.closeTabsAfterOneDay = false + settings.manuallyCloseTabs = false + refreshInactiveTabsSection() + metrics.track(Event.TabsTrayAutoCloseDialogTurnOnClicked) + } + + /** + * Marks the dialog as shown and to not be displayed again. + */ + private fun markDialogAsShown() { + settings.hasInactiveTabsAutoCloseDialogBeenDismissed = true + } + + @VisibleForTesting + internal fun refreshInactiveTabsSection() { val tabs = browserStore.state.tabs.filter(tabFilter) tray.updateTabs(tabs, browserStore.state.selectedTabId) } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt index c331a79202..27bcde07dc 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/InactiveTabsInteractor.kt @@ -4,14 +4,56 @@ package org.mozilla.fenix.tabstray.browser -interface InactiveTabsInteractor { +/** + * Interactor for all things related to inactive tabs in the tabs tray. + */ +interface InactiveTabsInteractor : InactiveTabsAutoCloseDialogInteractor { + /** + * Invoked when the header is tapped on. + * + * @param activated true when the tap should expand the inactive section. + */ fun onHeaderClicked(activated: Boolean) } +/** + * Interactor for the auto-close dialog in the inactive tabs section. + */ +interface InactiveTabsAutoCloseDialogInteractor { + + /** + * Invoked when the close button is clicked. + */ + fun onCloseClicked() + + /** + * Invoked when the dialog is clicked. + */ + fun onEnabledAutoCloseClicked() +} + class DefaultInactiveTabsInteractor( private val controller: InactiveTabsController ) : InactiveTabsInteractor { + + /** + * See [InactiveTabsInteractor.onHeaderClicked]. + */ override fun onHeaderClicked(activated: Boolean) { controller.updateCardExpansion(activated) } + + /** + * See [InactiveTabsAutoCloseDialogInteractor.onCloseClicked]. + */ + override fun onCloseClicked() { + controller.close() + } + + /** + * See [InactiveTabsAutoCloseDialogInteractor.onEnabledAutoCloseClicked]. + */ + override fun onEnabledAutoCloseClicked() { + controller.enableAutoClosed() + } } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/NormalBrowserTrayList.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/NormalBrowserTrayList.kt index 640e22f21a..79c9d94d62 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/NormalBrowserTrayList.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/NormalBrowserTrayList.kt @@ -55,19 +55,8 @@ class NormalBrowserTrayList @JvmOverloads constructor( context.components.appStore, inactiveTabsFilter, concatAdapter.inactiveTabsAdapter, - context.components.analytics.metrics - ) - ) - } - - private val inactiveTabsAutoCloseInteractor by lazy { - DefaultInactiveTabsAutoCloseDialogInteractor( - InactiveTabsAutoCloseDialogController( - context.components.core.store, - context.settings(), - inactiveTabsFilter, - concatAdapter.inactiveTabsAdapter, - context.components.analytics.metrics + context.components.analytics.metrics, + context.settings() ) ) } @@ -76,8 +65,7 @@ class NormalBrowserTrayList @JvmOverloads constructor( TabsFeature( tabSorter, context.components.core.store, - { !it.content.private }, - ) + ) { !it.content.private } } private val touchHelper by lazy { @@ -95,7 +83,6 @@ class NormalBrowserTrayList @JvmOverloads constructor( super.onAttachedToWindow() concatAdapter.inactiveTabsAdapter.inactiveTabsInteractor = inactiveTabsInteractor - concatAdapter.inactiveTabsAdapter.inactiveTabsAutoCloseDialogInteractor = inactiveTabsAutoCloseInteractor tabsFeature.start() diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsAutoCloseDialogInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsAutoCloseDialogInteractorTest.kt deleted file mode 100644 index 110987efef..0000000000 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsAutoCloseDialogInteractorTest.kt +++ /dev/null @@ -1,32 +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.browser - -import io.mockk.mockk -import io.mockk.verify -import org.junit.Test - -class DefaultInactiveTabsAutoCloseDialogInteractorTest { - - @Test - fun `WHEN onCloseClicked THEN close`() { - val controller: InactiveTabsAutoCloseDialogController = mockk(relaxed = true) - val interactor = DefaultInactiveTabsAutoCloseDialogInteractor(controller) - - interactor.onCloseClicked() - - verify { controller.close() } - } - - @Test - fun `WHEN onEnabledAutoCloseClicked THEN enableAutoClosed`() { - val controller: InactiveTabsAutoCloseDialogController = mockk(relaxed = true) - val interactor = DefaultInactiveTabsAutoCloseDialogInteractor(controller) - - interactor.onEnabledAutoCloseClicked() - - verify { controller.enableAutoClosed() } - } -} diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt index 36c27520b8..f3f2ddc3de 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/browser/DefaultInactiveTabsInteractorTest.kt @@ -19,4 +19,24 @@ class DefaultInactiveTabsInteractorTest { verify { controller.updateCardExpansion(true) } } + + @Test + fun `WHEN onCloseClicked THEN close`() { + val controller: InactiveTabsController = mockk(relaxed = true) + val interactor = DefaultInactiveTabsInteractor(controller) + + interactor.onCloseClicked() + + verify { controller.close() } + } + + @Test + fun `WHEN onEnabledAutoCloseClicked THEN enableAutoClosed`() { + val controller: InactiveTabsController = mockk(relaxed = true) + val interactor = DefaultInactiveTabsInteractor(controller) + + interactor.onEnabledAutoCloseClicked() + + verify { controller.enableAutoClosed() } + } } diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogControllerTest.kt deleted file mode 100644 index e43c213a6b..0000000000 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/InactiveTabsAutoCloseDialogControllerTest.kt +++ /dev/null @@ -1,61 +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.browser - -import io.mockk.Runs -import io.mockk.every -import io.mockk.just -import io.mockk.mockk -import io.mockk.spyk -import io.mockk.verify -import mozilla.components.browser.state.state.TabSessionState -import mozilla.components.browser.state.store.BrowserStore -import mozilla.components.browser.tabstray.TabsTray -import org.junit.Test -import org.mozilla.fenix.components.metrics.Event -import org.mozilla.fenix.components.metrics.MetricController -import org.mozilla.fenix.utils.Settings - -class InactiveTabsAutoCloseDialogControllerTest { - - val metrics: MetricController = mockk(relaxed = true) - - @Test - fun `WHEN close THEN update settings and refresh`() { - val filter: (TabSessionState) -> Boolean = { !it.content.private } - val store = BrowserStore() - val settings: Settings = mockk(relaxed = true) - val tray: TabsTray = mockk(relaxed = true) - val controller = spyk(InactiveTabsAutoCloseDialogController(store, settings, filter, tray, metrics)) - - every { controller.refeshInactiveTabsSecion() } just Runs - - controller.close() - - verify { metrics.track(Event.TabsTrayAutoCloseDialogDismissed) } - verify { settings.hasInactiveTabsAutoCloseDialogBeenDismissed = true } - verify { controller.refeshInactiveTabsSecion() } - } - - @Test - fun `WHEN enableAutoClosed THEN update closeTabsAfterOneMonth settings and refresh`() { - val filter: (TabSessionState) -> Boolean = { !it.content.private } - val store = BrowserStore() - val settings: Settings = mockk(relaxed = true) - val tray: TabsTray = mockk(relaxed = true) - val controller = spyk(InactiveTabsAutoCloseDialogController(store, settings, filter, tray, metrics)) - - every { controller.refeshInactiveTabsSecion() } just Runs - - controller.enableAutoClosed() - - verify { metrics.track(Event.TabsTrayAutoCloseDialogTurnOnClicked) } - verify { settings.closeTabsAfterOneMonth = true } - verify { settings.closeTabsAfterOneWeek = false } - verify { settings.closeTabsAfterOneDay = false } - verify { settings.manuallyCloseTabs = false } - verify { controller.refeshInactiveTabsSecion() } - } -} diff --git a/app/src/test/java/org/mozilla/fenix/tabstray/browser/InactiveTabsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/tabstray/browser/InactiveTabsControllerTest.kt index 54d6c39165..11a17ccc54 100644 --- a/app/src/test/java/org/mozilla/fenix/tabstray/browser/InactiveTabsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/tabstray/browser/InactiveTabsControllerTest.kt @@ -4,8 +4,12 @@ package org.mozilla.fenix.tabstray.browser +import io.mockk.Runs +import io.mockk.every +import io.mockk.just import io.mockk.mockk import io.mockk.slot +import io.mockk.spyk import io.mockk.verify import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState @@ -17,9 +21,12 @@ import org.junit.Test import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController +import org.mozilla.fenix.utils.Settings class InactiveTabsControllerTest { + private val metrics: MetricController = mockk(relaxed = true) + private val settings: Settings = mockk(relaxed = true) private val appStore = AppStore() @Test @@ -36,7 +43,8 @@ class InactiveTabsControllerTest { ) val tray: TabsTray = mockk(relaxed = true) val tabsSlot = slot>() - val controller = InactiveTabsController(store, appStore, filter, tray, mockk(relaxed = true)) + val controller = + InactiveTabsController(store, appStore, filter, tray, mockk(relaxed = true), settings) controller.updateCardExpansion(true) @@ -48,10 +56,9 @@ class InactiveTabsControllerTest { @Test fun `WHEN expanded THEN track telemetry event`() { - val metrics: MetricController = mockk(relaxed = true) val store = BrowserStore(BrowserState()) val controller = InactiveTabsController( - store, appStore, mockk(relaxed = true), mockk(relaxed = true), metrics + store, appStore, mockk(relaxed = true), mockk(relaxed = true), metrics, settings ) controller.updateCardExpansion(true) @@ -61,14 +68,51 @@ class InactiveTabsControllerTest { @Test fun `WHEN collapsed THEN track telemetry event`() { - val metrics: MetricController = mockk(relaxed = true) val store = BrowserStore(BrowserState()) val controller = InactiveTabsController( - store, appStore, mockk(relaxed = true), mockk(relaxed = true), metrics + store, appStore, mockk(relaxed = true), mockk(relaxed = true), metrics, settings ) controller.updateCardExpansion(false) verify { metrics.track(Event.TabsTrayInactiveTabsCollapsed) } } + + @Test + fun `WHEN close THEN update settings and refresh`() { + val store = BrowserStore() + val controller = spyk( + InactiveTabsController( + store, appStore, mockk(relaxed = true), mockk(relaxed = true), metrics, settings + ) + ) + + every { controller.refreshInactiveTabsSection() } just Runs + + controller.close() + + verify { metrics.track(Event.TabsTrayAutoCloseDialogDismissed) } + verify { settings.hasInactiveTabsAutoCloseDialogBeenDismissed = true } + verify { controller.refreshInactiveTabsSection() } + } + + @Test + fun `WHEN enableAutoClosed THEN update closeTabsAfterOneMonth settings and refresh`() { + val filter: (TabSessionState) -> Boolean = { !it.content.private } + val store = BrowserStore() + val tray: TabsTray = mockk(relaxed = true) + val controller = + spyk(InactiveTabsAutoCloseDialogController(store, settings, filter, tray, metrics)) + + every { controller.refreshInactiveTabsSection() } just Runs + + controller.enableAutoClosed() + + verify { metrics.track(Event.TabsTrayAutoCloseDialogTurnOnClicked) } + verify { settings.closeTabsAfterOneMonth = true } + verify { settings.closeTabsAfterOneWeek = false } + verify { settings.closeTabsAfterOneDay = false } + verify { settings.manuallyCloseTabs = false } + verify { controller.refreshInactiveTabsSection() } + } }