From c45bddc7bd15b9667437fc90c914778bf295d9a2 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 5 Sep 2025 07:48:08 +0200 Subject: [PATCH 1/6] Migrate WooPosProductsViewModel and Test --- .../items/products/WooPosProductsViewModel.kt | 19 ++++---- .../products/WooPosProductsViewModelTest.kt | 43 ++++++++++--------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModel.kt index 6bda043dd244..f7e045203e9b 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModel.kt @@ -2,8 +2,7 @@ package com.woocommerce.android.ui.woopos.home.items.products import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.woocommerce.android.model.Product -import com.woocommerce.android.ui.products.ProductType +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2 import com.woocommerce.android.ui.woopos.home.ChildToParentEvent import com.woocommerce.android.ui.woopos.home.ParentToChildrenEvent import com.woocommerce.android.ui.woopos.home.WooPosChildrenToParentEventSender @@ -229,7 +228,7 @@ class WooPosProductsViewModel @Inject constructor( is WooPosProductsViewState.Empty -> state.copy(pullToRefreshState = WooPosPullToRefreshState.Refreshing) } - private suspend fun List.toContentState( + private suspend fun List.toContentState( paginationState: WooPosPaginationState = WooPosPaginationState.None ) = WooPosProductsViewState.Content( items = map { it.toItemSelectionViewState() }, @@ -237,21 +236,21 @@ class WooPosProductsViewModel @Inject constructor( pullToRefreshState = WooPosPullToRefreshState.Enabled, ) - private suspend fun Product.toItemSelectionViewState(): WooPosItemSelectionViewState { + private suspend fun WooPosProductModelVersion2.toItemSelectionViewState(): WooPosItemSelectionViewState { return if (this.isVariable()) { WooPosItemSelectionViewState.Product.Variable( id = this.remoteId, name = this.name, - price = priceFormat(this.price), + price = priceFormat(this.pricing.displayPrice), imageUrl = this.firstImageUrl, - numOfVariations = this.numVariations, + numOfVariations = this.variationIds.size, variationIds = this.variationIds ) } else { WooPosItemSelectionViewState.Product.Simple( id = this.remoteId, name = this.name, - price = priceFormat(this.price), + price = priceFormat(this.pricing.displayPrice), imageUrl = this.firstImageUrl, ) } @@ -316,7 +315,7 @@ class WooPosProductsViewModel @Inject constructor( viewModelScope.launch { fromChildToParentEventSender.sendToParent(event) } } - private fun Product.isVariable() = - productType == ProductType.VARIABLE || - productType == ProductType.VARIATION + private fun WooPosProductModelVersion2.isVariable() = + type == WooPosProductModelVersion2.WooPosProductType.VARIABLE || + type == WooPosProductModelVersion2.WooPosProductType.VARIATION } diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt index 3b03118d44e5..4e8ea4cc40e0 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt @@ -1,7 +1,7 @@ package com.woocommerce.android.ui.woopos.home.items.products import app.cash.turbine.test -import com.woocommerce.android.ui.products.ProductTestUtils +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2 import com.woocommerce.android.ui.woopos.home.ChildToParentEvent import com.woocommerce.android.ui.woopos.home.ParentToChildrenEvent import com.woocommerce.android.ui.woopos.home.WooPosChildrenToParentEventSender @@ -16,6 +16,7 @@ import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsEvent import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsEventConstant import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsTracker import com.woocommerce.android.ui.woopos.util.format.WooPosFormatPrice +import com.woocommerce.android.ui.woopos.util.generateWooPosProduct import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.flow @@ -54,11 +55,11 @@ class WooPosProductsViewModelTest { @Before fun setup() { val products = listOf( - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 1, productName = "Product 1", amount = "10.0", - productType = "simple", + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE, isDownloadable = false, ), ) @@ -77,20 +78,21 @@ class WooPosProductsViewModelTest { fun `given products from data source, when view model created, then view state updated correctly`() = runTest { // WHEN val products = listOf( - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 1, productName = "Product 1", amount = "10.0", - productType = "simple", + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE, isDownloadable = false, ), - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 2, productName = "Product 2", amount = "20.0", - productType = "simple", + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE, isDownloadable = false, - ).copy(firstImageUrl = "https://test.com") + images = listOf(WooPosProductModelVersion2.WooPosProductImage(0, "https://test.com", "","")) + ) ) whenever(productsDataSource.loadProducts(any())).thenReturn( @@ -325,21 +327,22 @@ class WooPosProductsViewModelTest { runTest { // GIVEN val products = listOf( - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 1, productName = "Product 1", amount = "10.0", - productType = "simple", + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE, isDownloadable = false, ), - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 2, productName = "Product 2", amount = "20.0", - productType = "variable", + productType = WooPosProductModelVersion2.WooPosProductType.VARIABLE, isDownloadable = false, - isVariable = true - ).copy(firstImageUrl = "https://test.com") + images = listOf(WooPosProductModelVersion2 + .WooPosProductImage(0, "https://test.com", "", "")), + ) ) whenever(productsDataSource.loadProducts(any())).thenReturn( @@ -371,11 +374,11 @@ class WooPosProductsViewModelTest { whenever(productsDataSource.loadMore()).thenReturn( Result.success( listOf( - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 2, productName = "Product 2", amount = "20.0", - productType = "simple" + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE ) ) ) @@ -386,11 +389,11 @@ class WooPosProductsViewModelTest { WooPosProductsDataSource.ProductsResult.Remote( Result.success( listOf( - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 1, productName = "Product 1", amount = "10.0", - productType = "simple" + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE ) ) ) @@ -501,11 +504,11 @@ class WooPosProductsViewModelTest { whenever(productsDataSource.loadMore()).thenReturn( Result.success( listOf( - ProductTestUtils.generateProduct( + generateWooPosProduct( productId = 2, productName = "Product 2", amount = "20.0", - productType = "simple" + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE, ) ) ) From f7b5f98535581d7195a7060d068ad8cfadbcd7b8 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 5 Sep 2025 07:48:20 +0200 Subject: [PATCH 2/6] Introduce WooPosProductUtils --- .../ui/woopos/util/WooPosProductUtils.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt new file mode 100644 index 000000000000..18d2691573f5 --- /dev/null +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt @@ -0,0 +1,30 @@ +package com.woocommerce.android.ui.woopos.util + +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2 +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2.WooPosPricing +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2.WooPosProductImage +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2.WooPosProductStatus +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2.WooPosProductType + +fun generateWooPosProduct( + productId: Long = 1, + productName: String = "Product 1", + amount: String = "10.0", + productType: WooPosProductType = WooPosProductType.SIMPLE, + isDownloadable: Boolean = false, + images: List = emptyList() +) = WooPosProductModelVersion2( + remoteId = productId, + name = productName, + pricing = WooPosPricing.RegularPricing(amount.toBigDecimal()), + type = productType, + isDownloadable = isDownloadable, + parentId = null, + sku = "", + globalUniqueId = "", + status = WooPosProductStatus.PUBLISH, + description = "", + shortDescription = "", + lastModified = "", + images = images, +) From 51976580a396c86f50591403454355c4a6f3d8ab Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 5 Sep 2025 07:48:56 +0200 Subject: [PATCH 3/6] Migrate WooPosSearchByIdentifier ProductGetOrFetch and test --- ...oPosSearchByIdentifierProductGetOrFetch.kt | 9 ++- ...SearchByIdentifierProductGetOrFetchTest.kt | 60 +++++++++++-------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetch.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetch.kt index 00741b4a28ac..4e079796b1c0 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetch.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetch.kt @@ -1,8 +1,8 @@ package com.woocommerce.android.ui.woopos.common.data.searchbyidentifier -import com.woocommerce.android.model.toAppModel import com.woocommerce.android.tools.SelectedSite import com.woocommerce.android.ui.woopos.common.data.WooPosProductsCache +import com.woocommerce.android.ui.woopos.common.data.models.WCProductToWooPosProductModelMapper import org.wordpress.android.fluxc.store.WCProductStore import javax.inject.Inject @@ -10,7 +10,8 @@ class WooPosSearchByIdentifierProductGetOrFetch @Inject constructor( private val selectedSite: SelectedSite, private val productStore: WCProductStore, private val productsCache: WooPosProductsCache, - private val errorMapper: WooPosSearchByIdentifierProductErrorMapper + private val errorMapper: WooPosSearchByIdentifierProductErrorMapper, + private val posProductMapper: WCProductToWooPosProductModelMapper, ) { suspend operator fun invoke(productId: Long): WooPosSearchByIdentifierResult { productsCache.getProductById(productId)?.let { cachedProduct -> @@ -28,7 +29,9 @@ class WooPosSearchByIdentifierProductGetOrFetch @Inject constructor( result.isError -> WooPosSearchByIdentifierResult.Failure(errorMapper(result.error)) else -> { - val product = productStore.getProduct(selectedSite.get(), productId)?.toAppModel() + val product = productStore.getProduct(selectedSite.get(), productId)?.let { + posProductMapper.map(it) + } if (product != null) { productsCache.addAll(listOf(product)) WooPosSearchByIdentifierResult.Success(product) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetchTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetchTest.kt index 49dda235a93f..9d6a8bd43ef7 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetchTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierProductGetOrFetchTest.kt @@ -4,6 +4,8 @@ import com.woocommerce.android.model.toAppModel import com.woocommerce.android.tools.SelectedSite import com.woocommerce.android.ui.products.ProductTestUtils import com.woocommerce.android.ui.woopos.common.data.WooPosProductsCache +import com.woocommerce.android.ui.woopos.common.data.models.WCProductToWooPosProductModelMapper +import com.woocommerce.android.ui.woopos.util.generateWooPosProduct import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -24,11 +26,18 @@ class WooPosSearchByIdentifierProductGetOrFetchTest { private val productStore: WCProductStore = mock() private val productsCache: WooPosProductsCache = mock() private val site: SiteModel = mock() + private val posProductMapper: WCProductToWooPosProductModelMapper = mock() private val errorMapper: WooPosSearchByIdentifierProductErrorMapper = WooPosSearchByIdentifierProductErrorMapper() @Before fun setup() { - sut = WooPosSearchByIdentifierProductGetOrFetch(selectedSite, productStore, productsCache, errorMapper) + sut = WooPosSearchByIdentifierProductGetOrFetch( + selectedSite, + productStore, + productsCache, + errorMapper, + posProductMapper + ) whenever(selectedSite.get()).thenReturn(site) } @@ -62,7 +71,7 @@ class WooPosSearchByIdentifierProductGetOrFetchTest { fun `given product found in cache, when invoke called, then return cached product without fetching`() = runTest { // GIVEN val productId = 123L - val cachedProduct = ProductTestUtils.generateProduct(productId) + val cachedProduct = generateWooPosProduct(productId) whenever(productsCache.getProductById(productId)).thenReturn(cachedProduct) // WHEN @@ -75,31 +84,32 @@ class WooPosSearchByIdentifierProductGetOrFetchTest { } @Test - fun `given successful fetch but product not found in store, when invoke called, then return failure with unknown error`() = runTest { - // GIVEN - val productId = 123L - val result: WCProductStore.OnProductChanged = mock { - on { isError }.thenReturn(false) + fun `given successful fetch but product not found in store, when invoke called, then return failure with unknown error`() = + runTest { + // GIVEN + val productId = 123L + val result: WCProductStore.OnProductChanged = mock { + on { isError }.thenReturn(false) + } + + whenever( + productStore.fetchSingleProduct(any()) + ).thenReturn(result) + + whenever(productStore.getProduct(site, productId)).thenReturn(null) + + // WHEN + val actualResult = sut(productId) + + // THEN + assertEquals( + WooPosSearchByIdentifierResult.Failure( + WooPosSearchByIdentifierResult.Error.UnknownError("Product not found for ID: $productId") + ), + actualResult + ) } - whenever( - productStore.fetchSingleProduct(any()) - ).thenReturn(result) - - whenever(productStore.getProduct(site, productId)).thenReturn(null) - - // WHEN - val actualResult = sut(productId) - - // THEN - assertEquals( - WooPosSearchByIdentifierResult.Failure( - WooPosSearchByIdentifierResult.Error.UnknownError("Product not found for ID: $productId") - ), - actualResult - ) - } - @Test fun `given fetch error, when invoke called, then return failure with mapped error`() = runTest { // GIVEN From 324847d63f611bc994f275589ae8ac2244c46b6d Mon Sep 17 00:00:00 2001 From: malinajirka Date: Fri, 5 Sep 2025 07:52:27 +0200 Subject: [PATCH 4/6] Migrate WooPosSearchByIdentifier and test --- .../WooPosSearchByIdentifierResult.kt | 6 +- .../WooPosSearchByIdentifierTest.kt | 103 ++---------------- .../ui/woopos/util/WooPosProductUtils.kt | 3 +- 3 files changed, 16 insertions(+), 96 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierResult.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierResult.kt index 7d93cdf49b85..1d40f3ad2faf 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierResult.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierResult.kt @@ -1,11 +1,11 @@ package com.woocommerce.android.ui.woopos.common.data.searchbyidentifier -import com.woocommerce.android.model.Product import com.woocommerce.android.model.ProductVariation +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2 sealed class WooPosSearchByIdentifierResult { - data class Success(val product: Product) : WooPosSearchByIdentifierResult() - data class VariationSuccess(val variation: ProductVariation, val parentProduct: Product) : + data class Success(val product: WooPosProductModelVersion2) : WooPosSearchByIdentifierResult() + data class VariationSuccess(val variation: ProductVariation, val parentProduct: WooPosProductModelVersion2) : WooPosSearchByIdentifierResult() data class Failure(val error: Error) : WooPosSearchByIdentifierResult() diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierTest.kt index 5322dfdd5bb4..1a2733006283 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierTest.kt @@ -1,15 +1,10 @@ package com.woocommerce.android.ui.woopos.common.data.searchbyidentifier -import com.woocommerce.android.model.Product -import com.woocommerce.android.ui.products.ProductBackorderStatus -import com.woocommerce.android.ui.products.ProductStatus -import com.woocommerce.android.ui.products.ProductStockStatus -import com.woocommerce.android.ui.products.ProductTaxStatus -import com.woocommerce.android.ui.products.ProductType -import com.woocommerce.android.ui.products.settings.ProductCatalogVisibility import com.woocommerce.android.ui.woopos.common.data.WooPosProductsTypesFilterConfig import com.woocommerce.android.ui.woopos.common.data.WooPosVariationsTypesFilterConfig +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2 import com.woocommerce.android.ui.woopos.common.util.WooPosLogWrapper +import com.woocommerce.android.ui.woopos.util.generateWooPosProduct import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -19,8 +14,6 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.never import org.mockito.kotlin.verify import org.mockito.kotlin.whenever -import java.math.BigDecimal -import java.util.Date class WooPosSearchByIdentifierTest { @@ -47,7 +40,7 @@ class WooPosSearchByIdentifierTest { runTest { // GIVEN val identifier = "123456" - val localProduct = createProduct() + val localProduct = generateWooPosProduct() val localResult = WooPosSearchByIdentifierResult.Success(localProduct) whenever(localSearcher(identifier)).thenReturn(localResult) @@ -64,7 +57,7 @@ class WooPosSearchByIdentifierTest { fun `given product not found locally, when search called, then search remotely`() = runTest { // GIVEN val identifier = "123456" - val remoteProduct = createProduct() + val remoteProduct = generateWooPosProduct() whenever(localSearcher(identifier)).thenReturn( WooPosSearchByIdentifierResult.Failure(WooPosSearchByIdentifierResult.Error.NotFound) ) @@ -126,7 +119,10 @@ class WooPosSearchByIdentifierTest { fun `given product meets filter criteria, when search called, then return product`() = runTest { // GIVEN val identifier = "123456" - val product = createProduct(type = ProductType.SIMPLE.value, status = ProductStatus.PUBLISH) + val product = generateWooPosProduct( + productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE, + status = WooPosProductModelVersion2.WooPosProductStatus.PUBLISH + ) whenever(localSearcher(identifier)) .thenReturn(WooPosSearchByIdentifierResult.Success(product)) @@ -143,7 +139,7 @@ class WooPosSearchByIdentifierTest { fun `given product has invalid status, when search called, then return product not supported`() = runTest { // GIVEN val identifier = "123456" - val product = createProduct(status = ProductStatus.DRAFT) + val product = generateWooPosProduct(status = WooPosProductModelVersion2.WooPosProductStatus.DRAFT) whenever(localSearcher(identifier)) .thenReturn(WooPosSearchByIdentifierResult.Success(product)) @@ -163,7 +159,7 @@ class WooPosSearchByIdentifierTest { fun `given product is downloadable, when search called, then return product not supported`() = runTest { // GIVEN val identifier = "123456" - val product = createProduct(isDownloadable = true) + val product = generateWooPosProduct(isDownloadable = true) whenever(localSearcher(identifier)) .thenReturn(WooPosSearchByIdentifierResult.Success(product)) @@ -183,7 +179,7 @@ class WooPosSearchByIdentifierTest { fun `given variable product, when search called, then return product not supported`() = runTest { // GIVEN val identifier = "123456" - val product = createProduct(type = ProductType.VARIABLE.value) + val product = generateWooPosProduct(productType = WooPosProductModelVersion2.WooPosProductType.VARIABLE) whenever(localSearcher(identifier)) .thenReturn(WooPosSearchByIdentifierResult.Success(product)) @@ -198,81 +194,4 @@ class WooPosSearchByIdentifierTest { (result as WooPosSearchByIdentifierResult.Failure).error ) } - - @Suppress("LongMethod") - private fun createProduct( - remoteId: Long = 1, - name: String = "Test Product", - type: String = ProductType.SIMPLE.value, - status: ProductStatus = ProductStatus.PUBLISH, - isDownloadable: Boolean = false - ) = Product( - remoteId = remoteId, - parentId = 0, - name = name, - description = "", - shortDescription = "", - slug = "", - type = type, - status = status, - catalogVisibility = ProductCatalogVisibility.VISIBLE, - isFeatured = false, - stockStatus = ProductStockStatus.InStock, - backorderStatus = ProductBackorderStatus.No, - dateCreated = Date(), - firstImageUrl = null, - totalSales = 0, - reviewsAllowed = true, - isVirtual = false, - ratingCount = 0, - averageRating = 0f, - permalink = "", - externalUrl = "", - buttonText = "", - price = BigDecimal.TEN, - salePrice = null, - regularPrice = BigDecimal.TEN, - taxClass = Product.TAX_CLASS_DEFAULT, - isStockManaged = false, - stockQuantity = 0.0, - sku = "", - globalUniqueId = "", - shippingClass = "", - shippingClassId = 0, - isDownloadable = isDownloadable, - downloads = emptyList(), - downloadLimit = 0, - downloadExpiry = 0, - purchaseNote = "", - numVariations = 0, - images = emptyList(), - attributes = emptyList(), - saleEndDateGmt = null, - saleStartDateGmt = null, - isSoldIndividually = false, - taxStatus = ProductTaxStatus.Taxable, - isSaleScheduled = false, - isPurchasable = true, - menuOrder = 0, - categories = emptyList(), - tags = emptyList(), - groupedProductIds = emptyList(), - crossSellProductIds = emptyList(), - upsellProductIds = emptyList(), - variationIds = emptyList(), - length = 0f, - width = 0f, - height = 0f, - weight = 0f, - isSampleProduct = false, - specialStockStatus = null, - isConfigurable = false, - minAllowedQuantity = null, - maxAllowedQuantity = null, - bundleMinSize = null, - bundleMaxSize = null, - groupOfQuantity = null, - combineVariationQuantities = null, - password = null - ) } diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt index 18d2691573f5..96fbd43cacac 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/util/WooPosProductUtils.kt @@ -9,6 +9,7 @@ import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVe fun generateWooPosProduct( productId: Long = 1, productName: String = "Product 1", + status: WooPosProductStatus = WooPosProductStatus.PUBLISH, amount: String = "10.0", productType: WooPosProductType = WooPosProductType.SIMPLE, isDownloadable: Boolean = false, @@ -22,7 +23,7 @@ fun generateWooPosProduct( parentId = null, sku = "", globalUniqueId = "", - status = WooPosProductStatus.PUBLISH, + status = status, description = "", shortDescription = "", lastModified = "", From 4622e04b603296953661861d6e8bc16acfa415ce Mon Sep 17 00:00:00 2001 From: malinajirka Date: Mon, 8 Sep 2025 08:22:03 +0200 Subject: [PATCH 5/6] Migrate WooPosSearchByIdentifier to WooPosProductModel --- .../data/models/WooPosProductModelVersion2.kt | 37 ++++++++++--------- .../WooPosSearchByIdentifier.kt | 8 ++-- ...PosSearchByIdentifierGlobalUniqueSearch.kt | 5 ++- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt index 0d7894366006..a838f6404685 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt @@ -2,6 +2,7 @@ package com.woocommerce.android.ui.woopos.common.data.models import android.os.Parcelable import kotlinx.parcelize.Parcelize +import org.wordpress.android.fluxc.network.rest.wpcom.wc.product.CoreProductStatus import java.math.BigDecimal /** @@ -61,26 +62,26 @@ data class WooPosProductModelVersion2( get() = displayPrice?.toPlainString() ?: "" } - enum class WooPosProductType { - SIMPLE, - VARIABLE, - GROUPED, - EXTERNAL, - VARIATION, - SUBSCRIPTION, - VARIABLE_SUBSCRIPTION, - CUSTOM, - BUNDLE, - COMPOSITE + enum class WooPosProductType(val value: String) { + SIMPLE("simple"), + VARIABLE("variable"), + GROUPED("grouped"), + EXTERNAL("external"), + VARIATION("variation"), + SUBSCRIPTION("subscription"), + VARIABLE_SUBSCRIPTION("variable-subscription"), + CUSTOM("custom"), + BUNDLE("bundle"), + COMPOSITE("composite"), } - enum class WooPosProductStatus { - PUBLISH, - DRAFT, - PENDING, - PRIVATE, - TRASH, - UNKNOWN + enum class WooPosProductStatus(val value: String) { + PUBLISH(CoreProductStatus.PUBLISH.value), + DRAFT(CoreProductStatus.DRAFT.value), + PENDING(CoreProductStatus.PENDING.value), + PRIVATE(CoreProductStatus.PRIVATE.value), + TRASH(CoreProductStatus.TRASH.value), + UNKNOWN("unknown"); } @Parcelize diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifier.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifier.kt index 215c35242b9b..ca066be86db5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifier.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifier.kt @@ -1,9 +1,9 @@ package com.woocommerce.android.ui.woopos.common.data.searchbyidentifier -import com.woocommerce.android.model.Product import com.woocommerce.android.model.ProductVariation import com.woocommerce.android.ui.woopos.common.data.WooPosProductsTypesFilterConfig import com.woocommerce.android.ui.woopos.common.data.WooPosVariationsTypesFilterConfig +import com.woocommerce.android.ui.woopos.common.data.models.WooPosProductModelVersion2 import com.woocommerce.android.ui.woopos.common.util.WooPosLogWrapper import org.wordpress.android.fluxc.store.WCProductStore import org.wordpress.android.fluxc.store.WCProductStore.DownloadableOptions @@ -52,15 +52,15 @@ class WooPosSearchByIdentifier @Inject constructor( } } - private fun meetsFilterRequirements(product: Product): Boolean { - val hasValidStatus = product.status?.value == filterConfig.filters[ProductFilterOption.STATUS] + private fun meetsFilterRequirements(product: WooPosProductModelVersion2): Boolean { + val hasValidStatus = product.status.value == filterConfig.filters[ProductFilterOption.STATUS] val meetsDownloadableRequirement = !product.isDownloadable || filterConfig.filters[ProductFilterOption.DOWNLOADABLE] != DownloadableOptions.FALSE.toString() val hasValidType = filterConfig.includeTypes .filterNot { it == WCProductStore.IncludeType.Variable } - .any { it.toString().equals(product.type, ignoreCase = true) } + .any { it.value.equals(product.type.value, ignoreCase = true) } return (hasValidStatus && meetsDownloadableRequirement && hasValidType) .also { meetsRequirements -> diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierGlobalUniqueSearch.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierGlobalUniqueSearch.kt index 6ea906efdba9..7022bad32d4c 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierGlobalUniqueSearch.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/searchbyidentifier/WooPosSearchByIdentifierGlobalUniqueSearch.kt @@ -1,7 +1,7 @@ package com.woocommerce.android.ui.woopos.common.data.searchbyidentifier -import com.woocommerce.android.model.toAppModel import com.woocommerce.android.tools.SelectedSite +import com.woocommerce.android.ui.woopos.common.data.models.WCProductToWooPosProductModelMapper import com.woocommerce.android.ui.woopos.common.util.WooPosLogWrapper import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooError import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooErrorType.API_ERROR @@ -23,6 +23,7 @@ class WooPosSearchByIdentifierGlobalUniqueSearch @Inject constructor( private val selectedSite: SelectedSite, private val productStore: WCProductStore, private val wooPosLogWrapper: WooPosLogWrapper, + private val posProductMapper: WCProductToWooPosProductModelMapper, ) { suspend operator fun invoke(globalUniqueId: String): WooPosSearchByIdentifierResult { val result = productStore.searchProducts( @@ -39,7 +40,7 @@ class WooPosSearchByIdentifierGlobalUniqueSearch @Inject constructor( result.model != null -> { val productSearchResult = result.model!! - val products = productSearchResult.products.map { it.toAppModel() } + val products = productSearchResult.products.map { posProductMapper.map(it) } if (products.isEmpty()) { WooPosSearchByIdentifierResult.Failure( WooPosSearchByIdentifierResult.Error.NotFound From f6ad62417fabf57ffdb10a5f8b9a5c1595a4f33a Mon Sep 17 00:00:00 2001 From: malinajirka Date: Mon, 8 Sep 2025 08:23:09 +0200 Subject: [PATCH 6/6] Fix detekt --- .../common/data/models/WooPosProductModelVersion2.kt | 2 +- .../woopos/common/data/WooPosProductsInMemoryCacheTest.kt | 1 - .../home/items/products/WooPosProductsViewModelTest.kt | 8 +++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt index a838f6404685..c04879aa9e99 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/common/data/models/WooPosProductModelVersion2.kt @@ -81,7 +81,7 @@ data class WooPosProductModelVersion2( PENDING(CoreProductStatus.PENDING.value), PRIVATE(CoreProductStatus.PRIVATE.value), TRASH(CoreProductStatus.TRASH.value), - UNKNOWN("unknown"); + UNKNOWN("unknown") } @Parcelize diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/WooPosProductsInMemoryCacheTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/WooPosProductsInMemoryCacheTest.kt index dbe0755ae3fb..0db1e367ed24 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/WooPosProductsInMemoryCacheTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/common/data/WooPosProductsInMemoryCacheTest.kt @@ -9,7 +9,6 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import java.math.BigDecimal -import java.util.Date @ExperimentalCoroutinesApi class WooPosProductsInMemoryCacheTest { diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt index 4e8ea4cc40e0..00d37ea4a218 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/items/products/WooPosProductsViewModelTest.kt @@ -91,7 +91,7 @@ class WooPosProductsViewModelTest { amount = "20.0", productType = WooPosProductModelVersion2.WooPosProductType.SIMPLE, isDownloadable = false, - images = listOf(WooPosProductModelVersion2.WooPosProductImage(0, "https://test.com", "","")) + images = listOf(WooPosProductModelVersion2.WooPosProductImage(0, "https://test.com", "", "")) ) ) @@ -340,8 +340,10 @@ class WooPosProductsViewModelTest { amount = "20.0", productType = WooPosProductModelVersion2.WooPosProductType.VARIABLE, isDownloadable = false, - images = listOf(WooPosProductModelVersion2 - .WooPosProductImage(0, "https://test.com", "", "")), + images = listOf( + WooPosProductModelVersion2 + .WooPosProductImage(0, "https://test.com", "", "") + ), ) )