diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/list/ProductListRepository.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/list/ProductListRepository.kt index 849600ce064..7608665bfc9 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/list/ProductListRepository.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/list/ProductListRepository.kt @@ -96,7 +96,8 @@ class ProductListRepository @Inject constructor( offset = offset, sortType = sortType ?: productSortingChoice, filterOptions = productFilterOptions, - excludedProductIds = excludedProductIds.orEmpty() + excludedProductIds = excludedProductIds.orEmpty(), + includeTypes = emptyList() ).let { result -> if (result.isError) { AnalyticsTracker.track( diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandler.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandler.kt index 27baf37a7dd..74f112e73f5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandler.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandler.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.update import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import org.wordpress.android.fluxc.store.WCProductStore import org.wordpress.android.fluxc.store.WCProductStore.ProductFilterOption import org.wordpress.android.fluxc.store.WCProductStore.SkuSearchOptions import java.util.concurrent.atomic.AtomicBoolean @@ -48,6 +49,7 @@ class ProductListHandler @Inject constructor(private val repository: ProductSele searchQuery: String = "", filters: Map = emptyMap(), searchType: SearchType, + includeType: List = emptyList(), ): Result = mutex.withLock { offset.value = 0 searchResults.value = emptyList() @@ -68,7 +70,7 @@ class ProductListHandler @Inject constructor(private val repository: ProductSele } } } else { - fetchProducts(forceRefresh) + fetchProducts(forceRefresh, includeType) } } @@ -84,8 +86,17 @@ class ProductListHandler @Inject constructor(private val repository: ProductSele } } - private suspend fun fetchProducts(forceRefresh: Boolean = false): Result { - return repository.fetchProducts(forceRefresh, offset.value, PAGE_SIZE, productFilters.value).onSuccess { + private suspend fun fetchProducts( + forceRefresh: Boolean = false, + includeTypes: List = emptyList(), + ): Result { + return repository.fetchProducts( + forceRefresh, + offset.value, + PAGE_SIZE, + productFilters.value, + includeTypes + ).onSuccess { canLoadMore.set(it) offset.value += PAGE_SIZE }.map { } diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductSelectorRepository.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductSelectorRepository.kt index 69607c17116..1de7f40520b 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductSelectorRepository.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/products/selector/ProductSelectorRepository.kt @@ -75,13 +75,15 @@ class ProductSelectorRepository @Inject constructor( forceRefresh: Boolean = false, offset: Int, pageSize: Int, - filterOptions: Map + filterOptions: Map, + includeType: List, ): Result { return productStore.fetchProducts( site = selectedSite.get(), offset = offset, pageSize = pageSize, filterOptions = filterOptions, + includeTypes = includeType, forceRefresh = forceRefresh, ) .let { result -> diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/featureflags/IsNonSimpleProductTypesEnabled.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/featureflags/IsNonSimpleProductTypesEnabled.kt deleted file mode 100644 index f64330e77ae..00000000000 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/featureflags/IsNonSimpleProductTypesEnabled.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.woocommerce.android.ui.woopos.featureflags - -import com.woocommerce.android.util.FeatureFlag -import javax.inject.Inject - -class IsNonSimpleProductTypesEnabled @Inject constructor() { - operator fun invoke(): Boolean { - return FeatureFlag.POS_NON_SIMPLE_PRODUCT_TYPES.isEnabled() - } -} diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsDataSource.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsDataSource.kt index 0ce38ef5a56..df06b734a1b 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsDataSource.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsDataSource.kt @@ -2,9 +2,7 @@ package com.woocommerce.android.ui.woopos.home.items.products import com.woocommerce.android.model.Product import com.woocommerce.android.ui.products.ProductStatus -import com.woocommerce.android.ui.products.ProductType import com.woocommerce.android.ui.products.selector.ProductListHandler -import com.woocommerce.android.ui.woopos.featureflags.IsNonSimpleProductTypesEnabled import com.woocommerce.android.util.WooLog import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow @@ -22,7 +20,6 @@ import javax.inject.Singleton @Singleton class WooPosProductsDataSource @Inject constructor( private val handler: ProductListHandler, - private val isNonSimpleProductTypesEnabled: IsNonSimpleProductTypesEnabled, ) { private var productCache: List = emptyList() private val cacheMutex = Mutex() @@ -40,15 +37,8 @@ class WooPosProductsDataSource @Inject constructor( val result = handler.loadFromCacheAndFetch( forceRefresh = forceRefreshProducts, searchType = ProductListHandler.SearchType.DEFAULT, - filters = - if (isNonSimpleProductTypesEnabled()) { - mapOf(WCProductStore.ProductFilterOption.STATUS to ProductStatus.PUBLISH.value) - } else { - mapOf( - WCProductStore.ProductFilterOption.TYPE to ProductType.SIMPLE.value, - WCProductStore.ProductFilterOption.STATUS to ProductStatus.PUBLISH.value - ) - } + includeType = listOf(WCProductStore.IncludeType.Simple), + filters = mapOf(WCProductStore.ProductFilterOption.STATUS to ProductStatus.PUBLISH.value) ) if (result.isSuccess) { diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt index ec0dc7a598b..796e3dfc23b 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/util/FeatureFlag.kt @@ -14,7 +14,6 @@ enum class FeatureFlag { ENDLESS_CAMPAIGNS_SUPPORT, REVAMP_WOO_SHIPPING, OBJECTIVE_SECTION, - POS_NON_SIMPLE_PRODUCT_TYPES, POS_CASH_PAYMENTS, POS_RECEIPTS, PRODUCT_GLOBAL_UNIQUE_IDENTIFIER_SUPPORT; @@ -29,7 +28,6 @@ enum class FeatureFlag { BETTER_CUSTOMER_SEARCH_M2, ORDER_CREATION_AUTO_TAX_RATE, REVAMP_WOO_SHIPPING, - POS_NON_SIMPLE_PRODUCT_TYPES, POS_CASH_PAYMENTS, POS_RECEIPTS, PRODUCT_GLOBAL_UNIQUE_IDENTIFIER_SUPPORT -> PackageUtils.isDebugBuild() diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandlerTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandlerTest.kt index 43301ed6a1c..1581a20d94f 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandlerTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/products/selector/ProductListHandlerTest.kt @@ -22,7 +22,7 @@ internal class ProductListHandlerTest : BaseUnitTest() { on(it.observeProducts(any())) doReturn flow { emit(generateSampleProducts()) } onBlocking { - (it.fetchProducts(any(), any(), any(), any())) + (it.fetchProducts(any(), any(), any(), any(), any())) } doReturn Result.success(true) } @@ -34,7 +34,7 @@ internal class ProductListHandlerTest : BaseUnitTest() { @Test fun `when load invoked, then emits first 25 products from db`() = testBlocking { - whenever(repo.fetchProducts(any(), any(), any(), any())).doReturn(Result.success(true)) + whenever(repo.fetchProducts(any(), any(), any(), any(), any())).doReturn(Result.success(true)) val handler = ProductListHandler(repo) handler.loadFromCacheAndFetch(searchType = SearchType.DEFAULT) @@ -51,17 +51,23 @@ internal class ProductListHandlerTest : BaseUnitTest() { fun `when load invoked, then side fetches first 25 products from backend`() = testBlocking { val handler = ProductListHandler(repo) handler.loadFromCacheAndFetch(searchType = SearchType.DEFAULT) - verify(repo).fetchProducts(false, 0, 25, emptyMap()) + verify(repo).fetchProducts(false, 0, 25, emptyMap(), emptyList()) } @Test fun `when load more invoked, then fetches next 25 products`() = testBlocking { val handler = ProductListHandler(repo) - handler.loadFromCacheAndFetch(searchType = SearchType.DEFAULT) + handler.loadFromCacheAndFetch( + false, + "", + emptyMap(), + searchType = SearchType.DEFAULT, + emptyList() + ) handler.loadMore() - verify(repo).fetchProducts(false, 25, 25, emptyMap()) + verify(repo).fetchProducts(false, 25, 25, emptyMap(), emptyList()) handler.productsFlow.test { val products = awaitItem() diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/WooPosProductsDataSourceTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/WooPosProductsDataSourceTest.kt index 51896e70ca7..fea6ddb911c 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/WooPosProductsDataSourceTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/WooPosProductsDataSourceTest.kt @@ -1,10 +1,7 @@ package com.woocommerce.android.ui.woopos.home.items -import com.woocommerce.android.ui.products.ProductStatus import com.woocommerce.android.ui.products.ProductTestUtils -import com.woocommerce.android.ui.products.ProductType import com.woocommerce.android.ui.products.selector.ProductListHandler -import com.woocommerce.android.ui.woopos.featureflags.IsNonSimpleProductTypesEnabled import com.woocommerce.android.ui.woopos.home.items.products.WooPosProductsDataSource import com.woocommerce.android.ui.woopos.util.WooPosCoroutineTestRule import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -16,9 +13,7 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Rule import org.mockito.kotlin.any import org.mockito.kotlin.mock -import org.mockito.kotlin.verify import org.mockito.kotlin.whenever -import org.wordpress.android.fluxc.store.WCProductStore import java.util.concurrent.atomic.AtomicBoolean import kotlin.test.Test import kotlin.test.assertFalse @@ -71,14 +66,13 @@ class WooPosProductsDataSourceTest { ) private val handler: ProductListHandler = mock() - private val isNonSimpleProductTypesEnabled: IsNonSimpleProductTypesEnabled = mock() @Test fun `given force refresh, when loadSimpleProducts called, then should clear cache`() = runTest { // GIVEN whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) whenever(handler.productsFlow).thenReturn(flowOf(sampleProducts)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + val sut = WooPosProductsDataSource(handler) // Pre-populate the cache sut.loadSimpleProducts(forceRefreshProducts = false).first() @@ -102,8 +96,8 @@ class WooPosProductsDataSourceTest { // GIVEN whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) whenever(handler.productsFlow).thenReturn(flowOf(sampleProducts)) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN sut.loadSimpleProducts(forceRefreshProducts = false).first() @@ -121,8 +115,8 @@ class WooPosProductsDataSourceTest { // GIVEN whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) whenever(handler.productsFlow).thenReturn(flowOf(sampleProducts)) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN sut.loadSimpleProducts(forceRefreshProducts = false).first() @@ -144,14 +138,16 @@ class WooPosProductsDataSourceTest { whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) whenever(handler.productsFlow).thenReturn(flowOf(sampleProducts)) val exception = Exception("Remote load failed") - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + val sut = WooPosProductsDataSource(handler) // Prepopulate the cache by calling loadSimpleProducts once sut.loadSimpleProducts(forceRefreshProducts = false).first() - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.failure(exception)) + whenever( + handler.loadFromCacheAndFetch(any(), any(), any(), any(), any()) + ).thenReturn(Result.failure(exception)) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = false).toList() @@ -175,7 +171,7 @@ class WooPosProductsDataSourceTest { flowOf(sampleProducts + additionalProducts) ) whenever(handler.loadMore()).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + val sut = WooPosProductsDataSource(handler) sut.loadSimpleProducts(forceRefreshProducts = false).first() @@ -200,7 +196,7 @@ class WooPosProductsDataSourceTest { whenever(handler.productsFlow).thenReturn(flowOf(sampleProducts)) val exception = Exception("Load more failed") whenever(handler.loadMore()).thenReturn(Result.failure(exception)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + val sut = WooPosProductsDataSource(handler) sut.loadSimpleProducts(forceRefreshProducts = false).first() @@ -224,9 +220,11 @@ class WooPosProductsDataSourceTest { whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) whenever(handler.productsFlow).thenReturn(flowOf(emptyList())) val exception = Exception("Remote load failed") - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.failure(exception)) + whenever( + handler.loadFromCacheAndFetch(any(), any(), any(), any(), any()) + ).thenReturn(Result.failure(exception)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = false).toList() @@ -246,8 +244,8 @@ class WooPosProductsDataSourceTest { // GIVEN whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) whenever(handler.productsFlow).thenReturn(flowOf(emptyList())) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = false).toList() @@ -286,8 +284,8 @@ class WooPosProductsDataSourceTest { ) ) ) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = false).toList() @@ -323,8 +321,8 @@ class WooPosProductsDataSourceTest { ) ) ) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = true).toList() @@ -361,8 +359,8 @@ class WooPosProductsDataSourceTest { ) ) ) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = false).toList() @@ -400,8 +398,8 @@ class WooPosProductsDataSourceTest { ) ) ) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = true).toList() @@ -437,8 +435,8 @@ class WooPosProductsDataSourceTest { ) ) ) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = false).toList() @@ -475,8 +473,8 @@ class WooPosProductsDataSourceTest { ) ) ) - whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any())).thenReturn(Result.success(Unit)) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) + whenever(handler.loadFromCacheAndFetch(any(), any(), any(), any(), any())).thenReturn(Result.success(Unit)) + val sut = WooPosProductsDataSource(handler) // WHEN val flow = sut.loadSimpleProducts(forceRefreshProducts = true).toList() @@ -485,47 +483,4 @@ class WooPosProductsDataSourceTest { val remoteResult = flow[1] as WooPosProductsDataSource.ProductsResult.Remote assertThat(remoteResult.productsResult.getOrNull()?.any { it.remoteId == 1L }).isFalse() } - - @Test - fun `given non-simple product types feature disabled, when loadSimpleProducts called, then add filter to display only simple products`() = runTest { - // GIVEN - whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) - whenever(handler.productsFlow).thenReturn(flowOf(sampleProducts)) - whenever(isNonSimpleProductTypesEnabled.invoke()).thenReturn(false) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) - - // WHEN - sut.loadSimpleProducts(forceRefreshProducts = true).first() - - // THEN - verify(handler).loadFromCacheAndFetch( - forceRefresh = true, - searchType = ProductListHandler.SearchType.DEFAULT, - filters = mapOf( - WCProductStore.ProductFilterOption.TYPE to ProductType.SIMPLE.value, - WCProductStore.ProductFilterOption.STATUS to ProductStatus.PUBLISH.value - ) - ) - } - - @Test - fun `given non-simple product types feature enabled, when loadSimpleProducts called, then do not add filter to display only simple products`() = runTest { - // GIVEN - whenever(handler.canLoadMore).thenReturn(AtomicBoolean(true)) - whenever(handler.productsFlow).thenReturn(flowOf(sampleProducts)) - whenever(isNonSimpleProductTypesEnabled.invoke()).thenReturn(true) - val sut = WooPosProductsDataSource(handler, isNonSimpleProductTypesEnabled) - - // WHEN - sut.loadSimpleProducts(forceRefreshProducts = true).first() - - // THEN - verify(handler).loadFromCacheAndFetch( - forceRefresh = true, - searchType = ProductListHandler.SearchType.DEFAULT, - filters = mapOf( - WCProductStore.ProductFilterOption.STATUS to ProductStatus.PUBLISH.value - ) - ) - } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d335874f5c4..0be0a12c2cd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -85,7 +85,7 @@ stripe-terminal = '3.7.1' tinder-statemachine = '0.2.0' wiremock = '2.26.3' wordpress-aztec = 'v2.1.4' -wordpress-fluxc = 'trunk-d9a3dcb6ea775cb2822aaecfa52e49d6d4b00e9b' +wordpress-fluxc = 'trunk-7cb493915ef7e0ee6eff1a4ca3b9872e178ee73e' wordpress-login = '1.19.0' wordpress-libaddressinput = '0.0.2' wordpress-mediapicker = '0.3.1'