Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.woocommerce.android.ui.woopos.common.data

import com.woocommerce.android.model.Order
import com.woocommerce.android.model.Refund
import com.woocommerce.android.model.toAppModel
import com.woocommerce.android.tools.SelectedSite
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.wordpress.android.fluxc.store.WCRefundStore
import java.math.BigDecimal
import javax.inject.Inject

/**
* Use case that retrieves all refunds for the given [Order].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np: I’m not sure how much value this comment currently adds, as it simply translates to the English code below. However, if the implementation changes in the future, the comment is likely not to be updated and may actually confuse the code reader rather than clarify it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, let's remove it. I wanted to add information that it's not explicitly stated in the API, but the code is indeed sufficiently clear to obtain that info from there. Done in d6b20cd

*
* - First attempts to load refunds from the local store.
* - If none are found, fetches them from the remote source.
* - If the order's [Order.refundTotal] is zero, returns an empty list without querying any source.
*
* This optimization prevents unnecessary store or network access for non-refunded orders.
*/
class WooPosRetrieveOrderRefunds @Inject constructor(
private val refundStore: WCRefundStore,
private val selectedSite: SelectedSite
) {
suspend operator fun invoke(order: Order): List<Refund> =
withContext(Dispatchers.IO) {
if (order.refundTotal.compareTo(BigDecimal.ZERO) == 0) {
return@withContext emptyList()
}

val site = selectedSite.get()

var refundModels = refundStore.getAllRefunds(site, order.id)
if (refundModels.isEmpty()) {
refundModels = refundStore.fetchAllRefunds(site, order.id).model ?: emptyList()
}

refundModels.map { it.toAppModel() }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import com.woocommerce.android.R
import com.woocommerce.android.model.Order
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosSearchInputState
import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosSearchUIEvent
import com.woocommerce.android.ui.woopos.common.data.WooPosGetOrderRefundsByOrderId
import com.woocommerce.android.ui.woopos.common.data.WooPosGetProductById
import com.woocommerce.android.ui.woopos.common.data.WooPosRetrieveOrderRefunds
import com.woocommerce.android.ui.woopos.home.ChildToParentEvent.NavigationEvent.ToEmailReceipt
import com.woocommerce.android.ui.woopos.home.WooPosChildrenToParentEventSender
import com.woocommerce.android.ui.woopos.home.items.WooPosPaginationState
Expand Down Expand Up @@ -42,7 +42,7 @@ class WooPosOrdersViewModel @Inject constructor(
private val getProductById: WooPosGetProductById,
private val childrenToParentEventSender: WooPosChildrenToParentEventSender,
private val formatPrice: WooPosFormatPrice,
private val getOrderRefunds: WooPosGetOrderRefundsByOrderId,
private val retrieveOrderRefunds: WooPosRetrieveOrderRefunds,
private val ordersAnalyticsTracker: WooPosOrdersAnalyticsTracker
) : ViewModel() {

Expand Down Expand Up @@ -542,7 +542,7 @@ class WooPosOrdersViewModel @Inject constructor(

val discountCode = order.couponLines.firstOrNull()?.code

val refundsDeferred = async { getOrderRefunds(order.id) }
val refundsDeferred = async { retrieveOrderRefunds(order) }

val lineItems = lineItemsDeferred.awaitAll()
val refunds = refundsDeferred.await()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ object OrderTestUtils {
return result
}

fun generateTestOrder(orderId: Long = 1): Order {
fun generateTestOrder(orderId: Long = 1, refundTotal: BigDecimal = -BigDecimal.TEN): Order {
return Order.getEmptyOrder(Date(), Date()).copy(
id = orderId,
customer = Order.Customer(
Expand All @@ -198,7 +198,7 @@ object OrderTestUtils {
status = Order.Status.Pending,
total = BigDecimal("106.00"),
items = generateTestOrderItems(productId = 15),
refundTotal = -BigDecimal.TEN,
refundTotal = refundTotal,
)
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.woocommerce.android.ui.woopos.common.data

import com.woocommerce.android.tools.SelectedSite
import com.woocommerce.android.ui.orders.OrderTestUtils
import kotlinx.coroutines.test.runTest
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
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.model.SiteModel
import org.wordpress.android.fluxc.model.refunds.WCRefundModel
import org.wordpress.android.fluxc.network.rest.wpcom.wc.WooResult
import org.wordpress.android.fluxc.store.WCRefundStore
import java.math.BigDecimal
import java.util.Date

class WooPosRetrieveOrderRefundsTest {
private lateinit var refundStore: WCRefundStore
private lateinit var selectedSite: SelectedSite
private lateinit var sut: WooPosRetrieveOrderRefunds
private lateinit var site: SiteModel

@Before
fun setup() {
refundStore = mock()
selectedSite = mock()
site = mock()

whenever(selectedSite.get()).thenReturn(site)

sut = WooPosRetrieveOrderRefunds(
refundStore = refundStore,
selectedSite = selectedSite
)
}

@Test
fun `given refunds exist locally, when invoke called, then returns mapped refunds`() = runTest {
// GIVEN
val order = OrderTestUtils.generateTestOrder(orderId = 123L)

val fluxCRefunds = listOf(
WCRefundModel(
id = 1L,
dateCreated = Date(),
amount = BigDecimal.TEN,
reason = "Test refund",
automaticGatewayRefund = true,
items = emptyList(),
shippingLineItems = emptyList(),
feeLineItems = emptyList()
),
WCRefundModel(
id = 2L,
dateCreated = Date(),
amount = BigDecimal.valueOf(5),
reason = "Another refund",
automaticGatewayRefund = false,
items = emptyList(),
shippingLineItems = emptyList(),
feeLineItems = emptyList()
)
)
whenever(refundStore.getAllRefunds(site, order.id)).thenReturn(fluxCRefunds)

// WHEN
val result = sut.invoke(order)

// THEN
assertThat(result).hasSize(2)
assertThat(result[0].id).isEqualTo(1L)
assertThat(result[0].amount).isEqualTo(BigDecimal.TEN)
assertThat(result[1].id).isEqualTo(2L)
assertThat(result[1].amount).isEqualTo(BigDecimal.valueOf(5))
}

@Test
fun `given no refunds exist locally, when invoke called, then fetches and returns mapped refunds`() = runTest {
// GIVEN
val order = OrderTestUtils.generateTestOrder(orderId = 123L)

whenever(refundStore.getAllRefunds(site, order.id)).thenReturn(emptyList())

val remoteRefunds = listOf(
WCRefundModel(
id = 10L,
dateCreated = Date(),
amount = BigDecimal.ONE,
reason = "Remote refund",
automaticGatewayRefund = false,
items = emptyList(),
shippingLineItems = emptyList(),
feeLineItems = emptyList()
)
)
whenever(refundStore.fetchAllRefunds(site, order.id)).thenReturn(
WooResult(model = remoteRefunds)
)

// WHEN
val result = sut.invoke(order)

// THEN
assertThat(result).hasSize(1)
assertThat(result[0].id).isEqualTo(10L)
assertThat(result[0].amount).isEqualTo(BigDecimal.ONE)
verify(refundStore).getAllRefunds(site, order.id)
verify(refundStore).fetchAllRefunds(site, order.id)
}

@Test
fun `given order refundTotal is zero, when invoke called, then returns empty list and does not hit store`() = runTest {
// GIVEN
val order = OrderTestUtils.generateTestOrder(orderId = 999L, refundTotal = BigDecimal.ZERO)

// WHEN
val result = sut.invoke(order)

// THEN
assertThat(result).isEmpty()
verify(refundStore, org.mockito.kotlin.never()).getAllRefunds(any(), any())
}

@Test
fun `given order provided, when invoke called, then passes correct orderId to store`() = runTest {
// GIVEN
val order = OrderTestUtils.generateTestOrder(orderId = 456L, refundTotal = BigDecimal.ONE)
whenever(refundStore.getAllRefunds(any(), any())).thenReturn(emptyList())
whenever(refundStore.fetchAllRefunds(any(), any(), any(), any())).thenReturn(
WooResult(emptyList())
)

// WHEN
sut.invoke(order)

// THEN
verify(refundStore).getAllRefunds(site, order.id)
}
}
Loading
Loading