From 88eb056af5244487677b4dbd9ed6b1d85092f0f0 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 8 Jun 2022 17:29:34 +0400 Subject: [PATCH 1/5] Show more information about refunds: fees and shipping --- .../adapter/OrderDetailRefundsAdapter.kt | 28 +++++++++++++++++++ WooCommerce/src/main/res/values/strings.xml | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt index 037e92ee3d1f..280eda149ae6 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt @@ -1,5 +1,6 @@ package com.woocommerce.android.ui.orders.details.adapter +import android.content.Context import android.text.format.DateFormat import android.view.LayoutInflater import android.view.ViewGroup @@ -10,6 +11,7 @@ import com.woocommerce.android.R import com.woocommerce.android.databinding.OrderDetailRefundPaymentItemBinding import com.woocommerce.android.extensions.isEqualTo import com.woocommerce.android.model.Refund +import com.woocommerce.android.util.StringUtils import java.math.BigDecimal class OrderDetailRefundsAdapter( @@ -58,6 +60,11 @@ class OrderDetailRefundsAdapter( ) { fun bind(refund: Refund) { val context = viewBinding.root.context + + viewBinding.refundsListLblRefund.text = context.getString( + R.string.orderdetail_refunded, + buildRefundLine(context, refund) + ) viewBinding.refundsListRefundAmount.text = context.getString( R.string.orderdetail_refund_amount, formatCurrency(refund.amount) @@ -76,6 +83,27 @@ class OrderDetailRefundsAdapter( // TODO: open refund detail screen } } + + private fun buildRefundLine(context: Context, refund: Refund): String { + val tokens = mutableListOf() + if (refund.items.isNotEmpty()) { + val quantity = refund.items.sumOf { it.quantity } + val productString = StringUtils.getQuantityString( + context = context, + quantity = quantity, + default = R.string.orderdetail_product_multiple, + one = R.string.orderdetail_product + ) + tokens.add("$quantity $productString") + } + if (refund.shippingLines.isNotEmpty()) { + tokens.add(context.getString(R.string.product_shipping)) + } + if (refund.feeLines.isNotEmpty()) { + tokens.add(context.getString(R.string.orderdetail_payment_fees)) + } + return tokens.joinToString(separator = ", ") { it.lowercase() } + } } class RefundModelDiffCallback( diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index f3c07e397c67..459696459729 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -438,7 +438,7 @@ %1$s via %2$s Awaiting payment via %s Paid - Refunded + Refunded: %s Refunded products %1$s via %2$s Net Payment From 9ff93a7e0dd7ca7d07b8b43649d3f6ca15d2b2dc Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 9 Jun 2022 12:57:08 +0400 Subject: [PATCH 2/5] Extracted logic to a separate class so I can test it --- .../adapter/OrderDetailRefundsAdapter.kt | 32 +--- .../adapter/OrderDetailRefundsLineBuilder.kt | 30 +++ .../views/OrderDetailPaymentInfoView.kt | 13 +- .../android/viewmodel/ResourceProvider.kt | 20 +- WooCommerce/src/main/res/values/strings.xml | 2 +- .../OrderDetailRefundsLineBuilderTest.kt | 175 ++++++++++++++++++ 6 files changed, 242 insertions(+), 30 deletions(-) create mode 100644 WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilder.kt create mode 100644 WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt index 280eda149ae6..edd6f43ad7ec 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt @@ -1,6 +1,5 @@ package com.woocommerce.android.ui.orders.details.adapter -import android.content.Context import android.text.format.DateFormat import android.view.LayoutInflater import android.view.ViewGroup @@ -11,12 +10,12 @@ import com.woocommerce.android.R import com.woocommerce.android.databinding.OrderDetailRefundPaymentItemBinding import com.woocommerce.android.extensions.isEqualTo import com.woocommerce.android.model.Refund -import com.woocommerce.android.util.StringUtils import java.math.BigDecimal class OrderDetailRefundsAdapter( private val isCashPayment: Boolean, private val paymentMethodTitle: String, + private val orderDetailRefundsLineBuilder: OrderDetailRefundsLineBuilder, private val formatCurrency: (BigDecimal) -> String ) : RecyclerView.Adapter() { var refundList: List = ArrayList() @@ -40,6 +39,7 @@ class OrderDetailRefundsAdapter( ), isCashPayment, paymentMethodTitle, + orderDetailRefundsLineBuilder, formatCurrency ) } @@ -54,6 +54,7 @@ class OrderDetailRefundsAdapter( private val viewBinding: OrderDetailRefundPaymentItemBinding, private val isCashPayment: Boolean, private val paymentMethodTitle: String, + private val orderDetailRefundsLineBuilder: OrderDetailRefundsLineBuilder, private val formatCurrency: (BigDecimal) -> String ) : RecyclerView.ViewHolder( viewBinding.root @@ -61,10 +62,8 @@ class OrderDetailRefundsAdapter( fun bind(refund: Refund) { val context = viewBinding.root.context - viewBinding.refundsListLblRefund.text = context.getString( - R.string.orderdetail_refunded, - buildRefundLine(context, refund) - ) + val refundLine = orderDetailRefundsLineBuilder.buildRefundLine(refund) + viewBinding.refundsListLblRefund.text = context.getString(R.string.orderdetail_refunded, refundLine) viewBinding.refundsListRefundAmount.text = context.getString( R.string.orderdetail_refund_amount, formatCurrency(refund.amount) @@ -83,27 +82,6 @@ class OrderDetailRefundsAdapter( // TODO: open refund detail screen } } - - private fun buildRefundLine(context: Context, refund: Refund): String { - val tokens = mutableListOf() - if (refund.items.isNotEmpty()) { - val quantity = refund.items.sumOf { it.quantity } - val productString = StringUtils.getQuantityString( - context = context, - quantity = quantity, - default = R.string.orderdetail_product_multiple, - one = R.string.orderdetail_product - ) - tokens.add("$quantity $productString") - } - if (refund.shippingLines.isNotEmpty()) { - tokens.add(context.getString(R.string.product_shipping)) - } - if (refund.feeLines.isNotEmpty()) { - tokens.add(context.getString(R.string.orderdetail_payment_fees)) - } - return tokens.joinToString(separator = ", ") { it.lowercase() } - } } class RefundModelDiffCallback( diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilder.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilder.kt new file mode 100644 index 000000000000..942149d994f2 --- /dev/null +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilder.kt @@ -0,0 +1,30 @@ +package com.woocommerce.android.ui.orders.details.adapter + +import com.woocommerce.android.R +import com.woocommerce.android.model.Refund +import com.woocommerce.android.viewmodel.ResourceProvider +import javax.inject.Inject + +class OrderDetailRefundsLineBuilder @Inject constructor( + private val resourceProvider: ResourceProvider, +) { + fun buildRefundLine(refund: Refund): String { + val tokens = mutableListOf() + if (refund.items.isNotEmpty()) { + val quantity = refund.items.sumOf { it.quantity } + val productString = resourceProvider.getQuantityString( + quantity = quantity, + default = R.string.orderdetail_product_multiple, + one = R.string.orderdetail_product + ) + tokens.add("$quantity $productString") + } + if (refund.shippingLines.isNotEmpty()) { + tokens.add(resourceProvider.getString(R.string.product_shipping)) + } + if (refund.feeLines.isNotEmpty()) { + tokens.add(resourceProvider.getString(R.string.orderdetail_payment_fees)) + } + return tokens.joinToString(separator = ", ") { it.lowercase() } + } +} diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/views/OrderDetailPaymentInfoView.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/views/OrderDetailPaymentInfoView.kt index 602bc1c48fd6..3f97435f1cf2 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/views/OrderDetailPaymentInfoView.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/views/OrderDetailPaymentInfoView.kt @@ -16,13 +16,19 @@ import com.woocommerce.android.extensions.show import com.woocommerce.android.model.Order import com.woocommerce.android.model.Refund import com.woocommerce.android.ui.orders.details.adapter.OrderDetailRefundsAdapter +import com.woocommerce.android.ui.orders.details.adapter.OrderDetailRefundsLineBuilder +import dagger.hilt.android.AndroidEntryPoint import java.math.BigDecimal +import javax.inject.Inject +@AndroidEntryPoint class OrderDetailPaymentInfoView @JvmOverloads constructor( ctx: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : MaterialCardView(ctx, attrs, defStyleAttr) { + @Inject lateinit var orderDetailRefundsLineBuilder: OrderDetailRefundsLineBuilder + private val binding = OrderDetailPaymentInfoBinding.inflate(LayoutInflater.from(ctx), this) @Suppress("LongParameterList") @@ -174,7 +180,12 @@ class OrderDetailPaymentInfoView @JvmOverloads constructor( formatCurrencyForDisplay: (BigDecimal) -> String ) { val adapter = binding.paymentInfoRefunds.adapter as? OrderDetailRefundsAdapter - ?: OrderDetailRefundsAdapter(order.isCashPayment, order.paymentMethodTitle, formatCurrencyForDisplay) + ?: OrderDetailRefundsAdapter( + order.isCashPayment, + order.paymentMethodTitle, + orderDetailRefundsLineBuilder, + formatCurrencyForDisplay, + ) binding.paymentInfoRefunds.adapter = adapter adapter.refundList = refunds diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/viewmodel/ResourceProvider.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/viewmodel/ResourceProvider.kt index 388044847cf2..6da7c0724c4c 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/viewmodel/ResourceProvider.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/viewmodel/ResourceProvider.kt @@ -1,8 +1,13 @@ package com.woocommerce.android.viewmodel import android.content.Context -import androidx.annotation.* +import androidx.annotation.ArrayRes +import androidx.annotation.ColorRes +import androidx.annotation.DimenRes +import androidx.annotation.RawRes +import androidx.annotation.StringRes import androidx.core.content.ContextCompat +import com.woocommerce.android.util.StringUtils import java.io.InputStream import javax.inject.Inject @@ -32,4 +37,17 @@ class ResourceProvider @Inject constructor(private val context: Context) { val resources = context.resources return resources.openRawResource(rawId) } + + fun getQuantityString( + quantity: Int, + @StringRes default: Int, + @StringRes zero: Int? = null, + @StringRes one: Int? = null + ) = StringUtils.getQuantityString( + context, + quantity, + default, + zero, + one, + ) } diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index 459696459729..f526d6023fef 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -438,7 +438,7 @@ %1$s via %2$s Awaiting payment via %s Paid - Refunded: %s + Refunded: %1$s Refunded products %1$s via %2$s Net Payment diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt new file mode 100644 index 000000000000..b55f3ce55dbe --- /dev/null +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt @@ -0,0 +1,175 @@ +package com.woocommerce.android.ui.orders.details.adapter + +import com.woocommerce.android.R +import com.woocommerce.android.model.Refund +import com.woocommerce.android.model.Refund.Item +import com.woocommerce.android.viewmodel.BaseUnitTest +import com.woocommerce.android.viewmodel.ResourceProvider +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +class OrderDetailRefundsLineBuilderTest : BaseUnitTest() { + private val resourceProvider: ResourceProvider = mock { + on { + getQuantityString( + quantity = 1, + default = R.string.orderdetail_product_multiple, + one = R.string.orderdetail_product + ) + }.thenReturn("Product") + on { + getQuantityString( + quantity = 2, + default = R.string.orderdetail_product_multiple, + one = R.string.orderdetail_product + ) + }.thenReturn("Products") + on { getString(R.string.product_shipping) }.thenReturn("Shipping") + on { getString(R.string.orderdetail_payment_fees) }.thenReturn("Fees") + } + + private val refund = mock { + on { items }.thenReturn(emptyList()) + on { shippingLines }.thenReturn(emptyList()) + on { feeLines }.thenReturn(emptyList()) + } + + private val builder = OrderDetailRefundsLineBuilder(resourceProvider) + + @Test + fun `given refund with product, when building line, then product returned`() { + // GIVEN + val item = mock { + on { quantity }.thenReturn(1) + } + whenever(refund.items).thenReturn( + listOf(item) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("1 product") + } + + @Test + fun `given refund with products, when building line, then products returned`() { + // GIVEN + val itemOne = mock { + on { quantity }.thenReturn(3) + } + val itemTwo = mock { + on { quantity }.thenReturn(4) + } + val itemThree = mock { + on { quantity }.thenReturn(5) + } + whenever(refund.items).thenReturn( + listOf(itemOne, itemTwo, itemThree) + ) + whenever( + resourceProvider.getQuantityString( + quantity = 12, + default = R.string.orderdetail_product_multiple, + one = R.string.orderdetail_product + ) + ).thenReturn("Products") + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("12 products") + } + + @Test + fun `given refund with fee, when building line, then fees returned`() { + // GIVEN + whenever(refund.feeLines).thenReturn( + listOf(mock()) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("fees") + } + + @Test + fun `given refund with shipping, when building line, then shipping returned`() { + // GIVEN + whenever(refund.shippingLines).thenReturn( + listOf(mock()) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("shipping") + } + + @Test + fun `given refund with product and shipping, when building line, then product and shipping returned`() { + // GIVEN + val item = mock { + on { quantity }.thenReturn(1) + } + whenever(refund.items).thenReturn( + listOf(item) + ) + whenever(refund.shippingLines).thenReturn( + listOf(mock()) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("1 product, shipping") + } + + @Test + fun `given refund with shipping and fee, when building line, then shipping and fee returned`() { + // GIVEN + whenever(refund.shippingLines).thenReturn( + listOf(mock()) + ) + whenever(refund.feeLines).thenReturn( + listOf(mock()) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("shipping, fees") + } + + @Test + fun `given refund with product, shipping and fee, when building line, then product shipping and fee returned`() { + // GIVEN + val item = mock { + on { quantity }.thenReturn(1) + } + whenever(refund.items).thenReturn( + listOf(item) + ) + whenever(refund.shippingLines).thenReturn( + listOf(mock()) + ) + whenever(refund.feeLines).thenReturn( + listOf(mock()) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("1 product, shipping, fees") + } +} From 7b2f6cefad3061c2a0c988898d40c63c79541264 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 9 Jun 2022 13:03:23 +0400 Subject: [PATCH 3/5] Added one missing test --- .../OrderDetailRefundsLineBuilderTest.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt index b55f3ce55dbe..bb7725d30335 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt @@ -172,4 +172,24 @@ class OrderDetailRefundsLineBuilderTest : BaseUnitTest() { // THEN assertThat(result).isEqualTo("1 product, shipping, fees") } + + @Test + fun `given refund with product and fees, when building line, then product and fees returned`() { + // GIVEN + val item = mock { + on { quantity }.thenReturn(1) + } + whenever(refund.items).thenReturn( + listOf(item) + ) + whenever(refund.feeLines).thenReturn( + listOf(mock()) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("1 product, fees") + } } From 673bcef408d04141bdc71f6c5ecc60b0086d7c5f Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 9 Jun 2022 15:33:05 +0400 Subject: [PATCH 4/5] Fixed lint complains --- .../ui/orders/details/adapter/OrderDetailRefundsAdapter.kt | 5 ++++- .../src/main/res/layout/order_detail_refund_payment_item.xml | 2 +- WooCommerce/src/main/res/values/strings.xml | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt index edd6f43ad7ec..77776d565cdd 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsAdapter.kt @@ -63,7 +63,10 @@ class OrderDetailRefundsAdapter( val context = viewBinding.root.context val refundLine = orderDetailRefundsLineBuilder.buildRefundLine(refund) - viewBinding.refundsListLblRefund.text = context.getString(R.string.orderdetail_refunded, refundLine) + viewBinding.refundsListLblRefund.text = context.getString( + R.string.orderdetail_refunded_line_with_info, + refundLine + ) viewBinding.refundsListRefundAmount.text = context.getString( R.string.orderdetail_refund_amount, formatCurrency(refund.amount) diff --git a/WooCommerce/src/main/res/layout/order_detail_refund_payment_item.xml b/WooCommerce/src/main/res/layout/order_detail_refund_payment_item.xml index 748e88bcb750..b2d3fc507d50 100644 --- a/WooCommerce/src/main/res/layout/order_detail_refund_payment_item.xml +++ b/WooCommerce/src/main/res/layout/order_detail_refund_payment_item.xml @@ -26,7 +26,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginTop="@dimen/major_75" - android:text="@string/orderdetail_refunded" + android:text="@string/orderdetail_refunded_line_with_info" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@id/refundsList_refundDivider" /> diff --git a/WooCommerce/src/main/res/values/strings.xml b/WooCommerce/src/main/res/values/strings.xml index f526d6023fef..fd9aebb971dd 100644 --- a/WooCommerce/src/main/res/values/strings.xml +++ b/WooCommerce/src/main/res/values/strings.xml @@ -438,7 +438,8 @@ %1$s via %2$s Awaiting payment via %s Paid - Refunded: %1$s + Refunded + Refunded: %1$s Refunded products %1$s via %2$s Net Payment From 767754993b7a87ac2563fb338585938e7ecacc08 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 15 Jun 2022 11:57:57 +0400 Subject: [PATCH 5/5] Added more tests --- .../OrderDetailRefundsLineBuilderTest.kt | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt index bb7725d30335..04d22f3c5049 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/orders/details/adapter/OrderDetailRefundsLineBuilderTest.kt @@ -192,4 +192,81 @@ class OrderDetailRefundsLineBuilderTest : BaseUnitTest() { // THEN assertThat(result).isEqualTo("1 product, fees") } + + @Test + fun `given refund with 2 products and fees, when building line, then 2 products and fees returned`() { + // GIVEN + val item = mock { + on { quantity }.thenReturn(2) + } + whenever(refund.items).thenReturn( + listOf(item) + ) + whenever(refund.feeLines).thenReturn( + listOf(mock()) + ) + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("2 products, fees") + } + + @Test + fun `given refund with 5 products and shipping, when building line, then 5 products and shipping returned`() { + // GIVEN + val item = mock { + on { quantity }.thenReturn(5) + } + whenever(refund.items).thenReturn( + listOf(item) + ) + whenever(refund.shippingLines).thenReturn( + listOf(mock()) + ) + whenever( + resourceProvider.getQuantityString( + quantity = 5, + default = R.string.orderdetail_product_multiple, + one = R.string.orderdetail_product + ) + ).thenReturn("Products") + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("5 products, shipping") + } + + @Test + fun `given refund with 10 products ship fees, when building line, then 10 products, ship and fees returned`() { + // GIVEN + val item = mock { + on { quantity }.thenReturn(10) + } + whenever(refund.items).thenReturn( + listOf(item) + ) + whenever(refund.shippingLines).thenReturn( + listOf(mock()) + ) + whenever(refund.feeLines).thenReturn( + listOf(mock()) + ) + whenever( + resourceProvider.getQuantityString( + quantity = 10, + default = R.string.orderdetail_product_multiple, + one = R.string.orderdetail_product + ) + ).thenReturn("Products") + + // WHEN + val result = builder.buildRefundLine(refund) + + // THEN + assertThat(result).isEqualTo("10 products, shipping, fees") + } }