From db8a9b4b976460ae1d7fe38ed63f036e3c5886bb Mon Sep 17 00:00:00 2001 From: samiuelson Date: Tue, 14 May 2024 16:57:31 +0200 Subject: [PATCH 01/19] Update conditions for showing POS entry point --- .../android/ui/moremenu/MoreMenuViewModel.kt | 3 +- .../android/ui/woopos/IsWooPosEnabled.kt | 31 ++++- .../com/woocommerce/android/util/UiHelpers.kt | 4 + .../ui/moremenu/MoreMenuViewModelTests.kt | 2 +- .../android/ui/woopos/IsWooPosEnabledTest.kt | 110 ++++++++++++++++++ 5 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt index 81b54b2e4ce..d22b59a94bd 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt @@ -29,6 +29,7 @@ import com.woocommerce.android.ui.payments.taptopay.isAvailable import com.woocommerce.android.ui.plans.domain.SitePlan import com.woocommerce.android.ui.plans.repository.SitePlanRepository import com.woocommerce.android.ui.woopos.IsWooPosEnabled +import com.woocommerce.android.util.FeatureFlag import com.woocommerce.android.viewmodel.MultiLiveEvent import com.woocommerce.android.viewmodel.ResourceProvider import com.woocommerce.android.viewmodel.ScopedViewModel @@ -140,7 +141,7 @@ class MoreMenuViewModel @Inject constructor( title = R.string.more_menu_button_woo_pos, description = R.string.more_menu_button_woo_pos_description, icon = R.drawable.ic_more_menu_payments, - isEnabled = isWooPosEnabled(), + isEnabled = isWooPosEnabled() && FeatureFlag.WOO_POS.isEnabled(), onClick = { triggerEvent(MoreMenuEvent.NavigateToWooPosEvent) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 9e7ef857473..a306bca0f76 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -1,8 +1,33 @@ package com.woocommerce.android.ui.woopos -import com.woocommerce.android.util.FeatureFlag +import com.woocommerce.android.tools.SelectedSite +import com.woocommerce.android.ui.payments.GetActivePaymentsPlugin +import com.woocommerce.android.util.IsWindowClassExpandedAndBigger +import org.wordpress.android.fluxc.model.payments.inperson.WCPaymentAccountResult +import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore +import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore.InPersonPaymentsPluginType.WOOCOMMERCE_PAYMENTS import javax.inject.Inject -class IsWooPosEnabled @Inject constructor() { - operator fun invoke() = FeatureFlag.WOO_POS.isEnabled() +class IsWooPosEnabled @Inject constructor( + private val selectedSite: SelectedSite, + private val ippStore: WCInPersonPaymentsStore, + private val getActivePaymentsPlugin: GetActivePaymentsPlugin, + private val isWindowSizeExpandedAndBigger: IsWindowClassExpandedAndBigger, +) { + @Suppress("ReturnCount") + suspend operator fun invoke(): Boolean { + val ippPlugin = getActivePaymentsPlugin() ?: return false + val selectedSite = selectedSite.getOrNull() ?: return false + val paymentAccount = ippStore.loadAccount(ippPlugin, selectedSite).model ?: return false + val countryCode = paymentAccount.country + + return countryCode.lowercase() == "us" && + ippPlugin == WOOCOMMERCE_PAYMENTS && + paymentAccount.storeCurrencies.default.lowercase() == "usd" && + isPluginSetupCompleted(paymentAccount) && + isWindowSizeExpandedAndBigger() + } + + private fun isPluginSetupCompleted(paymentAccount: WCPaymentAccountResult): Boolean = + paymentAccount.status != WCPaymentAccountResult.WCPaymentAccountStatus.NO_ACCOUNT } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/UiHelpers.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/UiHelpers.kt index 28f051b2bba..78e23ad6d92 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/UiHelpers.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/UiHelpers.kt @@ -89,3 +89,7 @@ object UiHelpers { class IsWindowClassLargeThanCompact @Inject constructor(val context: Context) { operator fun invoke() = context.windowSizeClass != WindowSizeClass.Compact } + +class IsWindowClassExpandedAndBigger @Inject constructor(val context: Context) { + operator fun invoke() = context.windowSizeClass == WindowSizeClass.ExpandedAndBigger +} diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt index e92b4c183bc..d98c86d078e 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModelTests.kt @@ -74,7 +74,7 @@ class MoreMenuViewModelTests : BaseUnitTest() { onBlocking { invoke() } doReturn true } private val isWooPosEnabled: IsWooPosEnabled = mock { - on { invoke() } doReturn true + onBlocking { invoke() } doReturn true } private val blazeCampaignsStore: BlazeCampaignsStore = mock() diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt new file mode 100644 index 00000000000..5c6f5e10354 --- /dev/null +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt @@ -0,0 +1,110 @@ +package com.woocommerce.android.ui.woopos + +import com.woocommerce.android.tools.SelectedSite +import com.woocommerce.android.ui.payments.GetActivePaymentsPlugin +import com.woocommerce.android.util.IsWindowClassExpandedAndBigger +import com.woocommerce.android.viewmodel.BaseUnitTest +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Before +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.model.payments.inperson.WCPaymentAccountResult +import org.wordpress.android.fluxc.model.payments.inperson.WCPaymentAccountResult.WCPaymentAccountStatus.COMPLETE +import org.wordpress.android.fluxc.model.payments.inperson.WCPaymentAccountResult.WCPaymentAccountStatus.StoreCurrencies +import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult +import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore +import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore.InPersonPaymentsPluginType.STRIPE +import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore.InPersonPaymentsPluginType.WOOCOMMERCE_PAYMENTS +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +@OptIn(ExperimentalCoroutinesApi::class) +class IsWooPosEnabledTest : BaseUnitTest() { + private val selectedSite: SelectedSite = mock() + private val ippStore: WCInPersonPaymentsStore = mock() + private val getActivePaymentsPlugin: GetActivePaymentsPlugin = mock() + private val isWindowSizeExpandedAndBigger: IsWindowClassExpandedAndBigger = mock() + + private lateinit var sut: IsWooPosEnabled + + @Before + fun setup() = testBlocking { + whenever(selectedSite.getOrNull()).thenReturn(SiteModel()) + whenever(getActivePaymentsPlugin()).thenReturn(WOOCOMMERCE_PAYMENTS) + whenever(isWindowSizeExpandedAndBigger()).thenReturn(true) + + sut = IsWooPosEnabled( + selectedSite = selectedSite, + ippStore = ippStore, + getActivePaymentsPlugin = getActivePaymentsPlugin, + isWindowSizeExpandedAndBigger = isWindowSizeExpandedAndBigger + ) + } + + @Test + fun `given store not in the US, then return false`() = testBlocking { + val result = buildPaymentAccountResult(countryCode = "CA") + whenever(ippStore.loadAccount(any(), any())).thenReturn(result) + assertFalse(sut()) + } + + @Test + fun `given not big enough screen, then return false`() = testBlocking { + whenever(isWindowSizeExpandedAndBigger()).thenReturn(false) + assertFalse(sut()) + } + + @Test + fun `given currency is not USD, then return false`() = testBlocking { + val result = buildPaymentAccountResult(defaultCurrency = "CAD") + whenever(ippStore.loadAccount(any(), any())).thenReturn(result) + assertFalse(sut()) + } + + @Test + fun `given ipp plugin is not enabled, then return false`() = testBlocking { + whenever(getActivePaymentsPlugin()).thenReturn(null) + assertFalse(sut()) + } + + @Test + fun `given ipp plugin is not woo payments, then return false`() = testBlocking { + whenever(getActivePaymentsPlugin()).thenReturn(STRIPE) + assertFalse(sut()) + } + + @Test + fun `given woo payments setup not completed, then return false`() = testBlocking { + val result = buildPaymentAccountResult(status = WCPaymentAccountResult.WCPaymentAccountStatus.NO_ACCOUNT) + whenever(ippStore.loadAccount(any(), any())).thenReturn(result) + assertFalse(sut()) + } + + @Test + fun `given big enough screen, woo payments enabled, USD currency and store in the US, then return true`() = testBlocking { + val result = buildPaymentAccountResult(defaultCurrency = "USD", countryCode = "US", status = COMPLETE) + whenever(ippStore.loadAccount(any(), any())).thenReturn(result) + assertTrue(sut()) + } + + private fun buildPaymentAccountResult( + status: WCPaymentAccountResult.WCPaymentAccountStatus = COMPLETE, + countryCode: String = "US", + defaultCurrency: String = "USD" + ) = WooResult( + WCPaymentAccountResult( + status, + hasPendingRequirements = false, + hasOverdueRequirements = false, + currentDeadline = null, + statementDescriptor = "", + storeCurrencies = StoreCurrencies(defaultCurrency, listOf(defaultCurrency)), + country = countryCode, + isLive = true, + testMode = false, + ) + ) +} From 55d6a279edd623c14d82fb883ba0e95fa0e14ac0 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Tue, 14 May 2024 18:18:12 +0200 Subject: [PATCH 02/19] Fix mocks --- .../com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt index 5c6f5e10354..3cf281c9233 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt @@ -35,6 +35,7 @@ class IsWooPosEnabledTest : BaseUnitTest() { whenever(selectedSite.getOrNull()).thenReturn(SiteModel()) whenever(getActivePaymentsPlugin()).thenReturn(WOOCOMMERCE_PAYMENTS) whenever(isWindowSizeExpandedAndBigger()).thenReturn(true) + whenever(ippStore.loadAccount(any(), any())).thenReturn(buildPaymentAccountResult()) sut = IsWooPosEnabled( selectedSite = selectedSite, From 8cb5f81905c2b600bba5c1959168e087a79059af Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 10:08:21 +0200 Subject: [PATCH 03/19] Wrap FF into class to make it testable --- .../android/ui/moremenu/MoreMenuViewModel.kt | 2 +- .../woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 4 +++- .../woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt | 10 ++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt index d22b59a94bd..60edf4be6bf 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt @@ -141,7 +141,7 @@ class MoreMenuViewModel @Inject constructor( title = R.string.more_menu_button_woo_pos, description = R.string.more_menu_button_woo_pos_description, icon = R.drawable.ic_more_menu_payments, - isEnabled = isWooPosEnabled() && FeatureFlag.WOO_POS.isEnabled(), + isEnabled = isWooPosEnabled(), onClick = { triggerEvent(MoreMenuEvent.NavigateToWooPosEvent) } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index a306bca0f76..b2490aa6c9c 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -13,6 +13,7 @@ class IsWooPosEnabled @Inject constructor( private val ippStore: WCInPersonPaymentsStore, private val getActivePaymentsPlugin: GetActivePaymentsPlugin, private val isWindowSizeExpandedAndBigger: IsWindowClassExpandedAndBigger, + private val isWooPosFFEnabled: IsWooPosFFEnabled, ) { @Suppress("ReturnCount") suspend operator fun invoke(): Boolean { @@ -25,7 +26,8 @@ class IsWooPosEnabled @Inject constructor( ippPlugin == WOOCOMMERCE_PAYMENTS && paymentAccount.storeCurrencies.default.lowercase() == "usd" && isPluginSetupCompleted(paymentAccount) && - isWindowSizeExpandedAndBigger() + isWindowSizeExpandedAndBigger() && + isWooPosFFEnabled() } private fun isPluginSetupCompleted(paymentAccount: WCPaymentAccountResult): Boolean = diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt new file mode 100644 index 00000000000..ff1f887cf93 --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt @@ -0,0 +1,10 @@ +package com.woocommerce.android.ui.woopos + +import com.woocommerce.android.util.FeatureFlag +import javax.inject.Inject + +class IsWooPosFFEnabled @Inject constructor() { + operator fun invoke(): Boolean { + return FeatureFlag.WOO_POS.isEnabled() + } +} \ No newline at end of file From faa680d5e8d8926fb33357f0a79d697ffc8dd7d7 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 10:25:22 +0200 Subject: [PATCH 04/19] Fix detekt issues --- .../com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt | 1 - .../com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt index 60edf4be6bf..81b54b2e4ce 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/moremenu/MoreMenuViewModel.kt @@ -29,7 +29,6 @@ import com.woocommerce.android.ui.payments.taptopay.isAvailable import com.woocommerce.android.ui.plans.domain.SitePlan import com.woocommerce.android.ui.plans.repository.SitePlanRepository import com.woocommerce.android.ui.woopos.IsWooPosEnabled -import com.woocommerce.android.util.FeatureFlag import com.woocommerce.android.viewmodel.MultiLiveEvent import com.woocommerce.android.viewmodel.ResourceProvider import com.woocommerce.android.viewmodel.ScopedViewModel diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt index ff1f887cf93..1fae746cc87 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosFFEnabled.kt @@ -7,4 +7,4 @@ class IsWooPosFFEnabled @Inject constructor() { operator fun invoke(): Boolean { return FeatureFlag.WOO_POS.isEnabled() } -} \ No newline at end of file +} From 73e5780e9611d04b2aa0fa42f1c5fd71f113eeeb Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 10:27:45 +0200 Subject: [PATCH 05/19] Update unit tests --- .../android/ui/woopos/IsWooPosEnabledTest.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt index 3cf281c9233..c24d8f4ae5b 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt @@ -27,6 +27,7 @@ class IsWooPosEnabledTest : BaseUnitTest() { private val ippStore: WCInPersonPaymentsStore = mock() private val getActivePaymentsPlugin: GetActivePaymentsPlugin = mock() private val isWindowSizeExpandedAndBigger: IsWindowClassExpandedAndBigger = mock() + private val isWooPosFFEnabled: IsWooPosFFEnabled = mock() private lateinit var sut: IsWooPosEnabled @@ -36,12 +37,14 @@ class IsWooPosEnabledTest : BaseUnitTest() { whenever(getActivePaymentsPlugin()).thenReturn(WOOCOMMERCE_PAYMENTS) whenever(isWindowSizeExpandedAndBigger()).thenReturn(true) whenever(ippStore.loadAccount(any(), any())).thenReturn(buildPaymentAccountResult()) + whenever(isWooPosFFEnabled()).thenReturn(true) sut = IsWooPosEnabled( selectedSite = selectedSite, ippStore = ippStore, getActivePaymentsPlugin = getActivePaymentsPlugin, - isWindowSizeExpandedAndBigger = isWindowSizeExpandedAndBigger + isWindowSizeExpandedAndBigger = isWindowSizeExpandedAndBigger, + isWooPosFFEnabled = isWooPosFFEnabled, ) } @@ -84,6 +87,12 @@ class IsWooPosEnabledTest : BaseUnitTest() { assertFalse(sut()) } + @Test + fun `given feature flag disabled, then return false`() = testBlocking { + whenever(isWooPosFFEnabled.invoke()).thenReturn(false) + assertFalse(sut()) + } + @Test fun `given big enough screen, woo payments enabled, USD currency and store in the US, then return true`() = testBlocking { val result = buildPaymentAccountResult(defaultCurrency = "USD", countryCode = "US", status = COMPLETE) From 23c62d4f1794d1e72e8c484270e853e26254a972 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 10:28:12 +0200 Subject: [PATCH 06/19] Make isPluginSetupCompleted condition more strict --- .../kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index b2490aa6c9c..0acff90bade 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -31,5 +31,5 @@ class IsWooPosEnabled @Inject constructor( } private fun isPluginSetupCompleted(paymentAccount: WCPaymentAccountResult): Boolean = - paymentAccount.status != WCPaymentAccountResult.WCPaymentAccountStatus.NO_ACCOUNT + paymentAccount.status == WCPaymentAccountResult.WCPaymentAccountStatus.COMPLETE } From 2cc87193a96d6d5b44b1283cf6e78839337b9eed Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 10:35:00 +0200 Subject: [PATCH 07/19] Check FF first --- .../com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 0acff90bade..0acda0da40a 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -17,6 +17,8 @@ class IsWooPosEnabled @Inject constructor( ) { @Suppress("ReturnCount") suspend operator fun invoke(): Boolean { + if (!isWooPosFFEnabled()) return false + val ippPlugin = getActivePaymentsPlugin() ?: return false val selectedSite = selectedSite.getOrNull() ?: return false val paymentAccount = ippStore.loadAccount(ippPlugin, selectedSite).model ?: return false @@ -26,8 +28,7 @@ class IsWooPosEnabled @Inject constructor( ippPlugin == WOOCOMMERCE_PAYMENTS && paymentAccount.storeCurrencies.default.lowercase() == "usd" && isPluginSetupCompleted(paymentAccount) && - isWindowSizeExpandedAndBigger() && - isWooPosFFEnabled() + isWindowSizeExpandedAndBigger() } private fun isPluginSetupCompleted(paymentAccount: WCPaymentAccountResult): Boolean = From 32a4e39698c577aded79e2d333a17525b37b2694 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 10:53:28 +0200 Subject: [PATCH 08/19] Cache IsWooPosEnabled in-memory --- .../android/ui/main/MainActivityViewModel.kt | 7 +++++++ .../android/ui/woopos/IsWooPosEnabled.kt | 16 +++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt index da101692c21..378b3e12c94 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt @@ -28,12 +28,14 @@ import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState import com.woocommerce.android.ui.prefs.PrivacySettingsRepository import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue import com.woocommerce.android.ui.whatsnew.FeatureAnnouncementRepository +import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.util.BuildConfigWrapper import com.woocommerce.android.util.WooLog import com.woocommerce.android.util.WooLog.T import com.woocommerce.android.viewmodel.MultiLiveEvent.Event import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update @@ -57,11 +59,16 @@ class MainActivityViewModel @Inject constructor( moreMenuNewFeatureHandler: MoreMenuNewFeatureHandler, unseenReviewsCountHandler: UnseenReviewsCountHandler, determineTrialStatusBarState: DetermineTrialStatusBarState, + isWooPosEnabled: IsWooPosEnabled, ) : ScopedViewModel(savedState) { init { launch { featureAnnouncementRepository.getFeatureAnnouncements(fromCache = false) } + launch(IO) { + // Cache the condition for WooPOS feature being enabled + isWooPosEnabled() + } } val startDestination = if (selectedSite.exists()) R.id.dashboard else R.id.nav_graph_site_picker diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 0acda0da40a..4115e3c4a6d 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -7,7 +7,9 @@ import org.wordpress.android.fluxc.model.payments.inperson.WCPaymentAccountResul import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore.InPersonPaymentsPluginType.WOOCOMMERCE_PAYMENTS import javax.inject.Inject +import javax.inject.Singleton +@Singleton class IsWooPosEnabled @Inject constructor( private val selectedSite: SelectedSite, private val ippStore: WCInPersonPaymentsStore, @@ -15,8 +17,12 @@ class IsWooPosEnabled @Inject constructor( private val isWindowSizeExpandedAndBigger: IsWindowClassExpandedAndBigger, private val isWooPosFFEnabled: IsWooPosFFEnabled, ) { + private var cachedResult : Boolean? = null + @Suppress("ReturnCount") suspend operator fun invoke(): Boolean { + cachedResult?.let { return it } + if (!isWooPosFFEnabled()) return false val ippPlugin = getActivePaymentsPlugin() ?: return false @@ -24,11 +30,11 @@ class IsWooPosEnabled @Inject constructor( val paymentAccount = ippStore.loadAccount(ippPlugin, selectedSite).model ?: return false val countryCode = paymentAccount.country - return countryCode.lowercase() == "us" && - ippPlugin == WOOCOMMERCE_PAYMENTS && - paymentAccount.storeCurrencies.default.lowercase() == "usd" && - isPluginSetupCompleted(paymentAccount) && - isWindowSizeExpandedAndBigger() + return (countryCode.lowercase() == "us" && + ippPlugin == WOOCOMMERCE_PAYMENTS && + paymentAccount.storeCurrencies.default.lowercase() == "usd" && + isPluginSetupCompleted(paymentAccount) && + isWindowSizeExpandedAndBigger()).also { cachedResult = it } } private fun isPluginSetupCompleted(paymentAccount: WCPaymentAccountResult): Boolean = From b11439b2ab81edb257c7db413bfb73acf2894e74 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 11:03:28 +0200 Subject: [PATCH 09/19] Fix detekt issues --- .../com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 4115e3c4a6d..96a5b1f48a3 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -17,7 +17,7 @@ class IsWooPosEnabled @Inject constructor( private val isWindowSizeExpandedAndBigger: IsWindowClassExpandedAndBigger, private val isWooPosFFEnabled: IsWooPosFFEnabled, ) { - private var cachedResult : Boolean? = null + private var cachedResult: Boolean? = null @Suppress("ReturnCount") suspend operator fun invoke(): Boolean { @@ -30,11 +30,13 @@ class IsWooPosEnabled @Inject constructor( val paymentAccount = ippStore.loadAccount(ippPlugin, selectedSite).model ?: return false val countryCode = paymentAccount.country - return (countryCode.lowercase() == "us" && + return ( + countryCode.lowercase() == "us" && ippPlugin == WOOCOMMERCE_PAYMENTS && paymentAccount.storeCurrencies.default.lowercase() == "usd" && isPluginSetupCompleted(paymentAccount) && - isWindowSizeExpandedAndBigger()).also { cachedResult = it } + isWindowSizeExpandedAndBigger() + ).also { cachedResult = it } } private fun isPluginSetupCompleted(paymentAccount: WCPaymentAccountResult): Boolean = From c70865289cc8f910a1557d94b408171a3cf62fa0 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Wed, 15 May 2024 11:09:18 +0200 Subject: [PATCH 10/19] Update unit tests --- .../woocommerce/android/ui/main/MainActivityViewModelTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt index 1c2e3c8b60f..e032aa8e1d5 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt @@ -583,7 +583,8 @@ class MainActivityViewModelTest : BaseUnitTest() { unseenReviewsCountHandler = unseenReviewsCountHandler, determineTrialStatusBarState = mock { onBlocking { invoke(any()) } doReturn emptyFlow() - } + }, + mock() ) ) } From 78a4290bab8caa3596d1a670ca8a537ebd86bb61 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 09:18:25 +0200 Subject: [PATCH 11/19] Remove isPluginSetupCompleted condition --- .../com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 5 ----- .../woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt | 7 ------- 2 files changed, 12 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 96a5b1f48a3..15b91a5e6d5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -3,7 +3,6 @@ package com.woocommerce.android.ui.woopos import com.woocommerce.android.tools.SelectedSite import com.woocommerce.android.ui.payments.GetActivePaymentsPlugin import com.woocommerce.android.util.IsWindowClassExpandedAndBigger -import org.wordpress.android.fluxc.model.payments.inperson.WCPaymentAccountResult import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore import org.wordpress.android.fluxc.store.WCInPersonPaymentsStore.InPersonPaymentsPluginType.WOOCOMMERCE_PAYMENTS import javax.inject.Inject @@ -34,11 +33,7 @@ class IsWooPosEnabled @Inject constructor( countryCode.lowercase() == "us" && ippPlugin == WOOCOMMERCE_PAYMENTS && paymentAccount.storeCurrencies.default.lowercase() == "usd" && - isPluginSetupCompleted(paymentAccount) && isWindowSizeExpandedAndBigger() ).also { cachedResult = it } } - - private fun isPluginSetupCompleted(paymentAccount: WCPaymentAccountResult): Boolean = - paymentAccount.status == WCPaymentAccountResult.WCPaymentAccountStatus.COMPLETE } diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt index c24d8f4ae5b..684827174f8 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabledTest.kt @@ -80,13 +80,6 @@ class IsWooPosEnabledTest : BaseUnitTest() { assertFalse(sut()) } - @Test - fun `given woo payments setup not completed, then return false`() = testBlocking { - val result = buildPaymentAccountResult(status = WCPaymentAccountResult.WCPaymentAccountStatus.NO_ACCOUNT) - whenever(ippStore.loadAccount(any(), any())).thenReturn(result) - assertFalse(sut()) - } - @Test fun `given feature flag disabled, then return false`() = testBlocking { whenever(isWooPosFFEnabled.invoke()).thenReturn(false) From 84b21afd267debf431781c839bb1298d26091965 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 09:19:01 +0200 Subject: [PATCH 12/19] Move isWooPosEnabled() async request to dashboard vm --- .../android/ui/dashboard/DashboardViewModel.kt | 12 ++++++++++-- .../android/ui/main/MainActivityViewModel.kt | 7 ------- .../android/ui/dashboard/DashboardViewModelTest.kt | 3 ++- .../android/ui/main/MainActivityViewModelTest.kt | 1 - 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt index 1241bb7bd9a..a3a4ba6aaba 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt @@ -27,10 +27,12 @@ import com.woocommerce.android.ui.analytics.ranges.StatsTimeRangeSelection.Selec import com.woocommerce.android.ui.dashboard.DashboardViewModel.DashboardEvent.OpenEditWidgets import com.woocommerce.android.ui.dashboard.data.DashboardRepository import com.woocommerce.android.ui.prefs.privacy.banner.domain.ShouldShowPrivacyBanner +import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.viewmodel.MultiLiveEvent import com.woocommerce.android.viewmodel.ResourceProvider import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow @@ -61,8 +63,9 @@ class DashboardViewModel @Inject constructor( dashboardTransactionLauncher: DashboardTransactionLauncher, shouldShowPrivacyBanner: ShouldShowPrivacyBanner, dashboardRepository: DashboardRepository, - private val feedbackPrefs: FeedbackPrefs -) : ScopedViewModel(savedState) { + private val feedbackPrefs: FeedbackPrefs, + isWooPosEnabled: IsWooPosEnabled, + ) : ScopedViewModel(savedState) { companion object { private const val DAYS_TO_REDISPLAY_JP_BENEFITS_BANNER = 5 val SUPPORTED_RANGES_ON_MY_STORE_TAB = listOf( @@ -123,6 +126,11 @@ class DashboardViewModel @Inject constructor( } updateShareStoreButtonVisibility() + + launch(Dispatchers.IO) { + // Cache the condition for WooPOS feature being enabled + isWooPosEnabled() + } } private fun updateShareStoreButtonVisibility() { diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt index 378b3e12c94..da101692c21 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt @@ -28,14 +28,12 @@ import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState import com.woocommerce.android.ui.prefs.PrivacySettingsRepository import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue import com.woocommerce.android.ui.whatsnew.FeatureAnnouncementRepository -import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.util.BuildConfigWrapper import com.woocommerce.android.util.WooLog import com.woocommerce.android.util.WooLog.T import com.woocommerce.android.viewmodel.MultiLiveEvent.Event import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update @@ -59,16 +57,11 @@ class MainActivityViewModel @Inject constructor( moreMenuNewFeatureHandler: MoreMenuNewFeatureHandler, unseenReviewsCountHandler: UnseenReviewsCountHandler, determineTrialStatusBarState: DetermineTrialStatusBarState, - isWooPosEnabled: IsWooPosEnabled, ) : ScopedViewModel(savedState) { init { launch { featureAnnouncementRepository.getFeatureAnnouncements(fromCache = false) } - launch(IO) { - // Cache the condition for WooPOS feature being enabled - isWooPosEnabled() - } } val startDestination = if (selectedSite.exists()) R.id.dashboard else R.id.nav_graph_site_picker diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt index b9291ec633e..8e640f16699 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt @@ -71,7 +71,8 @@ class DashboardViewModelTest : BaseUnitTest() { selectedSite = selectedSite, shouldShowPrivacyBanner = shouldShowPrivacyBanner, dashboardRepository = dashboardRepository, - feedbackPrefs = feedbackPrefs + feedbackPrefs = feedbackPrefs, + isWooPosEnabled = mock(), ) } diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt index e032aa8e1d5..c2788807046 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt @@ -584,7 +584,6 @@ class MainActivityViewModelTest : BaseUnitTest() { determineTrialStatusBarState = mock { onBlocking { invoke(any()) } doReturn emptyFlow() }, - mock() ) ) } From 65e5751bf162407f328102191815bd7c5593c31a Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 09:22:15 +0200 Subject: [PATCH 13/19] Fix detekt issues --- .../com/woocommerce/android/ui/dashboard/DashboardViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt index a3a4ba6aaba..5181573087f 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt @@ -65,7 +65,7 @@ class DashboardViewModel @Inject constructor( dashboardRepository: DashboardRepository, private val feedbackPrefs: FeedbackPrefs, isWooPosEnabled: IsWooPosEnabled, - ) : ScopedViewModel(savedState) { +) : ScopedViewModel(savedState) { companion object { private const val DAYS_TO_REDISPLAY_JP_BENEFITS_BANNER = 5 val SUPPORTED_RANGES_ON_MY_STORE_TAB = listOf( From c6b929bda7d87f2d5458619b3ec7d0ff732ca6ed Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 12:20:22 +0200 Subject: [PATCH 14/19] Remove isWooPosEnabled requests from dashboard vm --- .../android/ui/dashboard/DashboardViewModel.kt | 8 -------- .../android/ui/dashboard/DashboardViewModelTest.kt | 1 - 2 files changed, 9 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt index 5181573087f..2515e6e2047 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModel.kt @@ -27,12 +27,10 @@ import com.woocommerce.android.ui.analytics.ranges.StatsTimeRangeSelection.Selec import com.woocommerce.android.ui.dashboard.DashboardViewModel.DashboardEvent.OpenEditWidgets import com.woocommerce.android.ui.dashboard.data.DashboardRepository import com.woocommerce.android.ui.prefs.privacy.banner.domain.ShouldShowPrivacyBanner -import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.viewmodel.MultiLiveEvent import com.woocommerce.android.viewmodel.ResourceProvider import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow @@ -64,7 +62,6 @@ class DashboardViewModel @Inject constructor( shouldShowPrivacyBanner: ShouldShowPrivacyBanner, dashboardRepository: DashboardRepository, private val feedbackPrefs: FeedbackPrefs, - isWooPosEnabled: IsWooPosEnabled, ) : ScopedViewModel(savedState) { companion object { private const val DAYS_TO_REDISPLAY_JP_BENEFITS_BANNER = 5 @@ -126,11 +123,6 @@ class DashboardViewModel @Inject constructor( } updateShareStoreButtonVisibility() - - launch(Dispatchers.IO) { - // Cache the condition for WooPOS feature being enabled - isWooPosEnabled() - } } private fun updateShareStoreButtonVisibility() { diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt index 8e640f16699..e95e118cd4b 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/dashboard/DashboardViewModelTest.kt @@ -72,7 +72,6 @@ class DashboardViewModelTest : BaseUnitTest() { shouldShowPrivacyBanner = shouldShowPrivacyBanner, dashboardRepository = dashboardRepository, feedbackPrefs = feedbackPrefs, - isWooPosEnabled = mock(), ) } From 7806925dd5fb30030eee5325c0fbcaeb21a012d0 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 13:03:30 +0200 Subject: [PATCH 15/19] Fetch IsWooPosEnabled in MainActivityViewModel --- .../woocommerce/android/ui/main/MainActivityViewModel.kt | 7 +++++++ .../com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 2 +- .../android/ui/main/MainActivityViewModelTest.kt | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt index da101692c21..793085833be 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt @@ -28,12 +28,14 @@ import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState import com.woocommerce.android.ui.prefs.PrivacySettingsRepository import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue import com.woocommerce.android.ui.whatsnew.FeatureAnnouncementRepository +import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.util.BuildConfigWrapper import com.woocommerce.android.util.WooLog import com.woocommerce.android.util.WooLog.T import com.woocommerce.android.viewmodel.MultiLiveEvent.Event import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update @@ -57,11 +59,16 @@ class MainActivityViewModel @Inject constructor( moreMenuNewFeatureHandler: MoreMenuNewFeatureHandler, unseenReviewsCountHandler: UnseenReviewsCountHandler, determineTrialStatusBarState: DetermineTrialStatusBarState, + isWooPosEnabled: IsWooPosEnabled, ) : ScopedViewModel(savedState) { init { launch { featureAnnouncementRepository.getFeatureAnnouncements(fromCache = false) } + launch(IO) { + // cache Woo POS eligibility result as soon as possible so that it doesn't block UI + isWooPosEnabled() + } } val startDestination = if (selectedSite.exists()) R.id.dashboard else R.id.nav_graph_site_picker diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 15b91a5e6d5..3bac3fd3135 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -24,8 +24,8 @@ class IsWooPosEnabled @Inject constructor( if (!isWooPosFFEnabled()) return false - val ippPlugin = getActivePaymentsPlugin() ?: return false val selectedSite = selectedSite.getOrNull() ?: return false + val ippPlugin = getActivePaymentsPlugin() ?: return false val paymentAccount = ippStore.loadAccount(ippPlugin, selectedSite).model ?: return false val countryCode = paymentAccount.country diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt index c2788807046..f9abcd02f52 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt @@ -584,6 +584,7 @@ class MainActivityViewModelTest : BaseUnitTest() { determineTrialStatusBarState = mock { onBlocking { invoke(any()) } doReturn emptyFlow() }, + isWooPosEnabled = mock(), ) ) } From 65c009854e7e47c155a000c2653561cef6f8ecec Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 13:48:43 +0200 Subject: [PATCH 16/19] Revert "Fetch IsWooPosEnabled in MainActivityViewModel" This reverts commit 7806925dd5fb30030eee5325c0fbcaeb21a012d0. --- .../woocommerce/android/ui/main/MainActivityViewModel.kt | 7 ------- .../com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 2 +- .../android/ui/main/MainActivityViewModelTest.kt | 1 - 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt index 793085833be..da101692c21 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt @@ -28,14 +28,12 @@ import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState import com.woocommerce.android.ui.prefs.PrivacySettingsRepository import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue import com.woocommerce.android.ui.whatsnew.FeatureAnnouncementRepository -import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.util.BuildConfigWrapper import com.woocommerce.android.util.WooLog import com.woocommerce.android.util.WooLog.T import com.woocommerce.android.viewmodel.MultiLiveEvent.Event import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update @@ -59,16 +57,11 @@ class MainActivityViewModel @Inject constructor( moreMenuNewFeatureHandler: MoreMenuNewFeatureHandler, unseenReviewsCountHandler: UnseenReviewsCountHandler, determineTrialStatusBarState: DetermineTrialStatusBarState, - isWooPosEnabled: IsWooPosEnabled, ) : ScopedViewModel(savedState) { init { launch { featureAnnouncementRepository.getFeatureAnnouncements(fromCache = false) } - launch(IO) { - // cache Woo POS eligibility result as soon as possible so that it doesn't block UI - isWooPosEnabled() - } } val startDestination = if (selectedSite.exists()) R.id.dashboard else R.id.nav_graph_site_picker diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 3bac3fd3135..15b91a5e6d5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -24,8 +24,8 @@ class IsWooPosEnabled @Inject constructor( if (!isWooPosFFEnabled()) return false - val selectedSite = selectedSite.getOrNull() ?: return false val ippPlugin = getActivePaymentsPlugin() ?: return false + val selectedSite = selectedSite.getOrNull() ?: return false val paymentAccount = ippStore.loadAccount(ippPlugin, selectedSite).model ?: return false val countryCode = paymentAccount.country diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt index f9abcd02f52..c2788807046 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt @@ -584,7 +584,6 @@ class MainActivityViewModelTest : BaseUnitTest() { determineTrialStatusBarState = mock { onBlocking { invoke(any()) } doReturn emptyFlow() }, - isWooPosEnabled = mock(), ) ) } From 682491d0eaa50e272581366d698fa752d0f63c09 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 15:27:08 +0200 Subject: [PATCH 17/19] Add missing wiremock stub maps --- .../mocks/mappings/woopos/settings.json | 28 +++++++++++++++++++ .../mocks/mappings/woopos/stripe_account.json | 28 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 WooCommerce/src/androidTest/assets/mocks/mappings/woopos/settings.json create mode 100644 WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json diff --git a/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/settings.json b/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/settings.json new file mode 100644 index 00000000000..ecba4978ab4 --- /dev/null +++ b/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/settings.json @@ -0,0 +1,28 @@ +{ + "request": { + "method": "GET", + "urlPathPattern": "/rest/v1.1/jetpack-blogs/161477129/rest-api/", + "queryParameters": { + "path": { + "equalTo": "/wc/v3/settings/products/&_method=get" + }, + "json": { + "equalTo": "true" + }, + "locale": { + "matches": "(.*)" + } + } + }, + "response": { + "status": 200, + "jsonBody": { + "data": { + } + }, + "headers": { + "Content-Type": "application/json", + "Connection": "keep-alive" + } + } +} diff --git a/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json b/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json new file mode 100644 index 00000000000..e1243ab8b0d --- /dev/null +++ b/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json @@ -0,0 +1,28 @@ +{ + "request": { + "method": "GET", + "urlPathPattern": "/rest/v1.1/jetpack-blogs/161477129/rest-api/", + "queryParameters": { + "path": { + "equalTo": "/wc/v3/wc_stripe/account/summary/&_method=get" + }, + "json": { + "equalTo": "true" + }, + "locale": { + "matches": "(.*)" + } + } + }, + "response": { + "status": 200, + "jsonBody": { + "data": { + } + }, + "headers": { + "Content-Type": "application/json", + "Connection": "keep-alive" + } + } +} From cfa9d6bf97fe2684ca5a3f2292a5d0c6d91f8b3c Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 16:01:59 +0200 Subject: [PATCH 18/19] Update wiremock mapping response --- .../assets/mocks/mappings/woopos/stripe_account.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json b/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json index e1243ab8b0d..ffaafe992ea 100644 --- a/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json +++ b/WooCommerce/src/androidTest/assets/mocks/mappings/woopos/stripe_account.json @@ -18,6 +18,10 @@ "status": 200, "jsonBody": { "data": { + "country": "US", + "storeCurrencies": { + "default": "USD" + } } }, "headers": { From 535d1844d4a08aa53caf9876579e4661d2503801 Mon Sep 17 00:00:00 2001 From: samiuelson Date: Thu, 16 May 2024 16:28:16 +0200 Subject: [PATCH 19/19] Revert "Revert "Fetch IsWooPosEnabled in MainActivityViewModel"" This reverts commit 65c009854e7e47c155a000c2653561cef6f8ecec. --- .../woocommerce/android/ui/main/MainActivityViewModel.kt | 7 +++++++ .../com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt | 2 +- .../android/ui/main/MainActivityViewModelTest.kt | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt index da101692c21..793085833be 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/main/MainActivityViewModel.kt @@ -28,12 +28,14 @@ import com.woocommerce.android.ui.plans.trial.DetermineTrialStatusBarState import com.woocommerce.android.ui.prefs.PrivacySettingsRepository import com.woocommerce.android.ui.prefs.RequestedAnalyticsValue import com.woocommerce.android.ui.whatsnew.FeatureAnnouncementRepository +import com.woocommerce.android.ui.woopos.IsWooPosEnabled import com.woocommerce.android.util.BuildConfigWrapper import com.woocommerce.android.util.WooLog import com.woocommerce.android.util.WooLog.T import com.woocommerce.android.viewmodel.MultiLiveEvent.Event import com.woocommerce.android.viewmodel.ScopedViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update @@ -57,11 +59,16 @@ class MainActivityViewModel @Inject constructor( moreMenuNewFeatureHandler: MoreMenuNewFeatureHandler, unseenReviewsCountHandler: UnseenReviewsCountHandler, determineTrialStatusBarState: DetermineTrialStatusBarState, + isWooPosEnabled: IsWooPosEnabled, ) : ScopedViewModel(savedState) { init { launch { featureAnnouncementRepository.getFeatureAnnouncements(fromCache = false) } + launch(IO) { + // cache Woo POS eligibility result as soon as possible so that it doesn't block UI + isWooPosEnabled() + } } val startDestination = if (selectedSite.exists()) R.id.dashboard else R.id.nav_graph_site_picker diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt index 15b91a5e6d5..3bac3fd3135 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/IsWooPosEnabled.kt @@ -24,8 +24,8 @@ class IsWooPosEnabled @Inject constructor( if (!isWooPosFFEnabled()) return false - val ippPlugin = getActivePaymentsPlugin() ?: return false val selectedSite = selectedSite.getOrNull() ?: return false + val ippPlugin = getActivePaymentsPlugin() ?: return false val paymentAccount = ippStore.loadAccount(ippPlugin, selectedSite).model ?: return false val countryCode = paymentAccount.country diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt index c2788807046..f9abcd02f52 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/main/MainActivityViewModelTest.kt @@ -584,6 +584,7 @@ class MainActivityViewModelTest : BaseUnitTest() { determineTrialStatusBarState = mock { onBlocking { invoke(any()) } doReturn emptyFlow() }, + isWooPosEnabled = mock(), ) ) }