diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index eebff5f978..26cfc9a8a8 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -256,8 +256,8 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { reviewQualityCheckAvailable = it safeInvalidateBrowserToolbarView() }, - onBottomSheetCollapsed = { - reviewQualityCheck.setSelected(selected = false, notifyListener = false) + onBottomSheetStateChange = { + reviewQualityCheck.setSelected(selected = it, notifyListener = false) }, ), owner = this, diff --git a/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt b/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt index cb5274a11d..6cde1b5199 100644 --- a/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt +++ b/app/src/main/java/org/mozilla/fenix/components/appstate/AppState.kt @@ -77,5 +77,5 @@ data class AppState( val pendingDeletionHistoryItems: Set = emptySet(), val wallpaperState: WallpaperState = WallpaperState.default, val standardSnackbarError: StandardSnackbarError? = null, - val shoppingSheetExpanded: Boolean = false, + val shoppingSheetExpanded: Boolean? = null, ) : State diff --git a/app/src/main/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeature.kt b/app/src/main/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeature.kt index 80907b834e..4a0353b965 100644 --- a/app/src/main/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeature.kt +++ b/app/src/main/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeature.kt @@ -7,8 +7,6 @@ package org.mozilla.fenix.shopping import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.drop -import kotlinx.coroutines.flow.filterNot import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull import mozilla.components.browser.state.selector.selectedTab @@ -26,14 +24,14 @@ import org.mozilla.fenix.components.AppStore * @property shoppingExperienceFeature Reference to the [ShoppingExperienceFeature]. * @property onAvailabilityChange Invoked when availability of this feature changes based on feature * flag and when the loaded page is a supported product page. - * @property onBottomSheetCollapsed Invoked when the bottom sheet is collapsed. + * @property onBottomSheetStateChange Invoked when the bottom sheet is collapsed or expanded. */ class ReviewQualityCheckFeature( private val appStore: AppStore, private val browserStore: BrowserStore, private val shoppingExperienceFeature: ShoppingExperienceFeature, private val onAvailabilityChange: (isAvailable: Boolean) -> Unit, - private val onBottomSheetCollapsed: () -> Unit, + private val onBottomSheetStateChange: (isExpanded: Boolean) -> Unit, ) : LifecycleAwareFeature { private var scope: CoroutineScope? = null private var appStoreScope: CoroutineScope? = null @@ -54,11 +52,7 @@ class ReviewQualityCheckFeature( appStoreScope = appStore.flowScoped { flow -> flow.mapNotNull { it.shoppingSheetExpanded } .distinctUntilChanged() - .drop(1) // Needed to ignore the initial emission from the Store setup - .filterNot { it } - .collect { - onBottomSheetCollapsed() - } + .collect(onBottomSheetStateChange) } } diff --git a/app/src/test/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeatureTest.kt b/app/src/test/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeatureTest.kt index 473b8f0869..0d6c26161c 100644 --- a/app/src/test/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeatureTest.kt +++ b/app/src/test/java/org/mozilla/fenix/shopping/ReviewQualityCheckFeatureTest.kt @@ -19,6 +19,7 @@ import org.junit.Test import org.mozilla.fenix.components.AppStore import org.mozilla.fenix.components.appstate.AppAction import org.mozilla.fenix.components.appstate.AppState +import org.mozilla.fenix.shopping.fake.FakeShoppingExperienceFeature class ReviewQualityCheckFeatureTest { @@ -35,7 +36,7 @@ class ReviewQualityCheckFeatureTest { onAvailabilityChange = { availability = it }, - onBottomSheetCollapsed = {}, + onBottomSheetStateChange = {}, ) tested.start() @@ -65,7 +66,7 @@ class ReviewQualityCheckFeatureTest { onAvailabilityChange = { availability = it }, - onBottomSheetCollapsed = {}, + onBottomSheetStateChange = {}, ) tested.start() @@ -95,7 +96,7 @@ class ReviewQualityCheckFeatureTest { onAvailabilityChange = { availability = it }, - onBottomSheetCollapsed = {}, + onBottomSheetStateChange = {}, ) tested.start() @@ -130,7 +131,7 @@ class ReviewQualityCheckFeatureTest { onAvailabilityChange = { availability = it }, - onBottomSheetCollapsed = {}, + onBottomSheetStateChange = {}, ) tested.start() @@ -168,7 +169,7 @@ class ReviewQualityCheckFeatureTest { onAvailabilityChange = { availability = it }, - onBottomSheetCollapsed = {}, + onBottomSheetStateChange = {}, ) tested.start() @@ -209,7 +210,7 @@ class ReviewQualityCheckFeatureTest { availability = it availabilityCount++ }, - onBottomSheetCollapsed = {}, + onBottomSheetStateChange = {}, ) tested.start() @@ -222,20 +223,20 @@ class ReviewQualityCheckFeatureTest { } @Test - fun `WHEN the shopping sheet is collapsed THEN the collapsed callback is called`() { + fun `WHEN the shopping sheet is collapsed THEN the callback is called with false`() { val appStore = AppStore( initialState = AppState( shoppingSheetExpanded = true, ), ) - var callbackCalled = false + var isExpanded: Boolean? = null val tested = ReviewQualityCheckFeature( appStore = appStore, browserStore = BrowserStore(), shoppingExperienceFeature = FakeShoppingExperienceFeature(), onAvailabilityChange = {}, - onBottomSheetCollapsed = { - callbackCalled = true + onBottomSheetStateChange = { + isExpanded = it }, ) @@ -243,24 +244,24 @@ class ReviewQualityCheckFeatureTest { appStore.dispatch(AppAction.ShoppingSheetStateUpdated(expanded = false)).joinBlocking() - assertTrue(callbackCalled) + assertFalse(isExpanded!!) } @Test - fun `WHEN the shopping sheet is expanded THEN the collapsed callback is not called`() { + fun `WHEN the shopping sheet is expanded THEN the collapsed callback is called with true`() { val appStore = AppStore( initialState = AppState( shoppingSheetExpanded = false, ), ) - var callbackCalled = false + var isExpanded: Boolean? = null val tested = ReviewQualityCheckFeature( appStore = appStore, browserStore = BrowserStore(), shoppingExperienceFeature = FakeShoppingExperienceFeature(), onAvailabilityChange = {}, - onBottomSheetCollapsed = { - callbackCalled = true + onBottomSheetStateChange = { + isExpanded = it }, ) @@ -268,14 +269,34 @@ class ReviewQualityCheckFeatureTest { appStore.dispatch(AppAction.ShoppingSheetStateUpdated(expanded = true)).joinBlocking() - assertFalse(callbackCalled) + assertTrue(isExpanded!!) + } + + @Test + fun `WHEN the feature is restarted THEN first emission is collected to set the tint`() { + val appStore = AppStore( + initialState = AppState( + shoppingSheetExpanded = false, + ), + ) + var isExpanded: Boolean? = null + val tested = ReviewQualityCheckFeature( + appStore = appStore, + browserStore = BrowserStore(), + shoppingExperienceFeature = FakeShoppingExperienceFeature(), + onAvailabilityChange = {}, + onBottomSheetStateChange = { + isExpanded = it + }, + ) + + tested.start() + tested.stop() + + // emulate emission + appStore.dispatch(AppAction.ShoppingSheetStateUpdated(expanded = false)).joinBlocking() + + tested.start() + assertFalse(isExpanded!!) } } - -class FakeShoppingExperienceFeature( - private val enabled: Boolean = true, -) : ShoppingExperienceFeature { - - override val isEnabled: Boolean - get() = enabled -} diff --git a/app/src/test/java/org/mozilla/fenix/shopping/fake/FakeShoppingExperienceFeature.kt b/app/src/test/java/org/mozilla/fenix/shopping/fake/FakeShoppingExperienceFeature.kt new file mode 100644 index 0000000000..613cbd1570 --- /dev/null +++ b/app/src/test/java/org/mozilla/fenix/shopping/fake/FakeShoppingExperienceFeature.kt @@ -0,0 +1,15 @@ +/* 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.shopping.fake + +import org.mozilla.fenix.shopping.ShoppingExperienceFeature + +class FakeShoppingExperienceFeature( + private val enabled: Boolean = true, +) : ShoppingExperienceFeature { + + override val isEnabled: Boolean + get() = enabled +}