diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt index bc033e7215d..37c35a5eae9 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsScreen.kt @@ -1,5 +1,6 @@ package com.woocommerce.android.ui.woopos.home.totals +import androidx.compose.animation.AnimatedContent import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibilityScope import androidx.compose.animation.fadeIn @@ -52,6 +53,7 @@ import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosErrorS import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosOutlinedButton import com.woocommerce.android.ui.woopos.common.composeui.component.WooPosShimmerBox import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding +import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.Totals import com.woocommerce.android.ui.woopos.home.totals.payment.failed.WooPosPaymentFailedScreen import com.woocommerce.android.ui.woopos.home.totals.payment.inprogress.WooPosPaymentInProgressScreen import com.woocommerce.android.ui.woopos.home.totals.payment.success.WooPosPaymentSuccessScreen @@ -74,8 +76,8 @@ private fun WooPosTotalsScreen( onUIEvent: (WooPosTotalsUIEvent) -> Unit, ) { Box(modifier = modifier) { - StateChangeAnimated(visible = state is WooPosTotalsViewState.Totals) { - if (state is WooPosTotalsViewState.Totals) { + StateChangeAnimated(visible = state is WooPosTotalsViewState.Checkout) { + if (state is WooPosTotalsViewState.Checkout) { TotalsLoaded( state = state, onUIEvent = onUIEvent, @@ -140,7 +142,7 @@ private fun StateChangeAnimated( @Composable private fun TotalsLoaded( - state: WooPosTotalsViewState.Totals, + state: WooPosTotalsViewState.Checkout, onUIEvent: (WooPosTotalsUIEvent) -> Unit, ) { Column( @@ -176,26 +178,36 @@ private fun TotalsLoaded( } } } - Column( - modifier = Modifier - .fillMaxWidth() - .padding( - horizontal = 40.dp.toAdaptivePadding(), - vertical = 16.dp.toAdaptivePadding() - ) - .weight(.9f), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - TotalsGrid(state = state) - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) - WooPosOutlinedButton( - text = stringResource(R.string.woopos_payment_take_cash_payment_label), - onClick = { onUIEvent(WooPosTotalsUIEvent.OnCashPaymentClicked) }, - ) - Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) + AnimatedContent( + targetState = state.totals, + label = "totals_grid_animation", + ) { state -> + when (state) { + is Totals.Hidden -> Unit + is Totals.Visible -> { + Column( + modifier = Modifier + .fillMaxWidth() + .padding( + horizontal = 40.dp.toAdaptivePadding(), + vertical = 16.dp.toAdaptivePadding() + ) + .weight(.9f), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + TotalsGrid(totals = state) + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) + WooPosOutlinedButton( + text = stringResource(R.string.woopos_payment_take_cash_payment_label), + onClick = { onUIEvent(WooPosTotalsUIEvent.OnCashPaymentClicked) }, + ) + Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) + } + } + } } } } @@ -287,7 +299,7 @@ private fun ReaderDisconnected( } @Composable -private fun TotalsGrid(state: WooPosTotalsViewState.Totals) { +private fun TotalsGrid(totals: Totals.Visible) { Column( modifier = Modifier .padding(24.dp.toAdaptivePadding()) @@ -297,14 +309,14 @@ private fun TotalsGrid(state: WooPosTotalsViewState.Totals) { ) { TotalsGridRow( textOne = stringResource(R.string.woopos_payment_subtotal_label), - textTwo = state.orderSubtotalText, + textTwo = totals.orderSubtotalText, ) Spacer(modifier = Modifier.height(8.dp.toAdaptivePadding())) TotalsGridRow( textOne = stringResource(R.string.woopos_payment_tax_label), - textTwo = state.orderTaxText, + textTwo = totals.orderTaxText, ) Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) @@ -315,7 +327,7 @@ private fun TotalsGrid(state: WooPosTotalsViewState.Totals) { TotalsGridRow( textOne = stringResource(R.string.woopos_payment_total_label), - textTwo = state.orderTotalText, + textTwo = totals.orderTotalText, styleOne = MaterialTheme.typography.h4, styleTwo = MaterialTheme.typography.h4, fontWeightOne = FontWeight.Medium, @@ -412,10 +424,12 @@ fun WooPosTotalsScreenPreview(modifier: Modifier = Modifier) { WooPosTheme { WooPosTotalsScreen( modifier = modifier, - state = WooPosTotalsViewState.Totals( - orderSubtotalText = "$420.00", - orderTotalText = "$462.00", - orderTaxText = "$42.00", + state = WooPosTotalsViewState.Checkout( + totals = Totals.Visible( + orderSubtotalText = "$420.00", + orderTotalText = "$462.00", + orderTaxText = "$42.00", + ), readerStatus = WooPosTotalsViewState.ReaderStatus.ReadyForPayment( title = "Ready for payment", subtitle = "Tap, swipe or insert card" @@ -433,10 +447,12 @@ fun WooPosTotalsScreenPreviewReaderNotConnected(modifier: Modifier = Modifier) { WooPosTheme { WooPosTotalsScreen( modifier = modifier, - state = WooPosTotalsViewState.Totals( - orderSubtotalText = "$420.00", - orderTotalText = "$462.00", - orderTaxText = "$42.00", + state = WooPosTotalsViewState.Checkout( + totals = Totals.Visible( + orderSubtotalText = "$420.00", + orderTotalText = "$462.00", + orderTaxText = "$42.00", + ), readerStatus = WooPosTotalsViewState.ReaderStatus.Disconnected( title = "Reader not connected", subtitle = "To process this payment, please connect your reader.", @@ -455,10 +471,12 @@ fun WooPosTotalsScreenPreviewWithCashPaymentAvailable() { WooPosTheme { WooPosTotalsScreen( modifier = Modifier, - state = WooPosTotalsViewState.Totals( - orderSubtotalText = "$420.00", - orderTotalText = "$462.00", - orderTaxText = "$42.00", + state = WooPosTotalsViewState.Checkout( + totals = Totals.Visible( + orderSubtotalText = "$420.00", + orderTotalText = "$462.00", + orderTaxText = "$42.00", + ), readerStatus = WooPosTotalsViewState.ReaderStatus.Disconnected( title = "Reader not connected", subtitle = "To process this payment, please connect your reader.", @@ -477,10 +495,12 @@ fun WooPosTotalsScreenPreviewForFreeOrders() { WooPosTheme { WooPosTotalsScreen( modifier = Modifier, - state = WooPosTotalsViewState.Totals( - orderSubtotalText = "$420.00", - orderTotalText = "$462.00", - orderTaxText = "$42.00", + state = WooPosTotalsViewState.Checkout( + totals = Totals.Visible( + orderSubtotalText = "$420.00", + orderTotalText = "$462.00", + orderTaxText = "$42.00", + ), readerStatus = WooPosTotalsViewState.ReaderStatus.Disconnected( title = "Reader not connected", subtitle = "To process this payment, please connect your reader.", diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt index 40434049352..0d83e71d441 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModel.kt @@ -31,6 +31,7 @@ import com.woocommerce.android.ui.woopos.home.WooPosParentToChildrenEventReceive import com.woocommerce.android.ui.woopos.home.items.WooPosItemsViewModel import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.PaymentFailed import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.PaymentInProgress +import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState.Totals import com.woocommerce.android.ui.woopos.util.WooPosNetworkStatus import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsEvent import com.woocommerce.android.ui.woopos.util.analytics.WooPosAnalyticsTracker @@ -44,6 +45,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine @@ -119,14 +121,14 @@ class WooPosTotalsViewModel @Inject constructor( when (status) { is NotConnected, is Connecting -> { val state = uiState.value - if (state !is WooPosTotalsViewState.Totals) return@collect + if (state !is WooPosTotalsViewState.Checkout) return@collect uiState.value = state.copy(readerStatus = buildTotalsReaderNotConnectedError()) cancelPaymentAction() } is Connected -> { val state = uiState.value - if (state !is WooPosTotalsViewState.Totals) return@collect + if (state !is WooPosTotalsViewState.Checkout) return@collect uiState.value = state.copy(readerStatus = buildPreparingReaderStatusState()) if (data.orderId != EMPTY_ORDER_ID) { collectPayment() @@ -260,8 +262,8 @@ class WooPosTotalsViewModel @Inject constructor( dataState.value.orderTotal?.compareTo(BigDecimal.ZERO) == 1 ) { val state = uiState.value - check(state is WooPosTotalsViewState.Totals) - check(uiState.value is WooPosTotalsViewState.Totals) + check(state is WooPosTotalsViewState.Checkout) + check(uiState.value is WooPosTotalsViewState.Checkout) createCardReaderPaymentController(dataState.value.orderId) cardReaderPaymentController?.start() listenToPaymentState() @@ -307,6 +309,14 @@ class WooPosTotalsViewModel @Inject constructor( is CardReaderPaymentState.ProcessingPayment, is CardReaderPaymentState.PaymentCapturing -> { + val state = uiState.value + if (state is WooPosTotalsViewState.Checkout) { + uiState.value = state.copy(totals = Totals.Hidden) + // allow the UI to show "shrinking" exit animation of totals grid before showing + // the "payment in progress" state. + @Suppress("MagicNumber") + delay(384) + } uiState.value = buildPaymentInProgressState() childrenToParentEventSender.sendToParent(ChildToParentEvent.PaymentInProgress) childrenToParentEventSender.sendToParent( @@ -338,7 +348,7 @@ class WooPosTotalsViewModel @Inject constructor( private suspend fun handleCollectingPaymentState(paymentState: CardReaderPaymentState.CollectingPayment) { val totalsState = uiState.value - if (totalsState is WooPosTotalsViewState.Totals) { + if (totalsState is WooPosTotalsViewState.Checkout) { uiState.value = totalsState.copy( readerStatus = WooPosTotalsViewState.ReaderStatus.ReadyForPayment( title = resourceProvider.getString(R.string.woopos_totals_reader_ready_for_payment_title), @@ -357,7 +367,7 @@ class WooPosTotalsViewModel @Inject constructor( private suspend fun handleReaderLoadingPaymentState() { val totalsState = uiState.value - if (totalsState is WooPosTotalsViewState.Totals) { + if (totalsState is WooPosTotalsViewState.Checkout) { uiState.value = totalsState.copy( readerStatus = WooPosTotalsViewState.ReaderStatus.Preparing( @@ -455,7 +465,7 @@ class WooPosTotalsViewModel @Inject constructor( } } - private suspend fun buildWooPosTotalsViewState(order: Order): WooPosTotalsViewState.Totals { + private suspend fun buildWooPosTotalsViewState(order: Order): WooPosTotalsViewState.Checkout { val subtotalAmount = order.productsTotal val taxAmount = order.totalTax val totalAmount = order.total @@ -463,10 +473,12 @@ class WooPosTotalsViewModel @Inject constructor( is Connected -> buildPreparingReaderStatusState() else -> buildTotalsReaderNotConnectedError() } - return WooPosTotalsViewState.Totals( - orderSubtotalText = priceFormat(subtotalAmount), - orderTaxText = priceFormat(taxAmount), - orderTotalText = priceFormat(totalAmount), + return WooPosTotalsViewState.Checkout( + totals = Totals.Visible( + orderSubtotalText = priceFormat(subtotalAmount), + orderTaxText = priceFormat(taxAmount), + orderTotalText = priceFormat(totalAmount), + ), readerStatus = readerStatus, isFreeOrder = totalAmount.compareTo(BigDecimal.ZERO) == 0 ) diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt index 67634f6bfde..30f37d1c20c 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewState.kt @@ -7,14 +7,24 @@ import kotlinx.parcelize.Parcelize sealed class WooPosTotalsViewState : Parcelable { data object Loading : WooPosTotalsViewState() - data class Totals( - val orderSubtotalText: String, - val orderTaxText: String, - val orderTotalText: String, + data class Checkout( + val totals: Totals, val readerStatus: ReaderStatus, val isFreeOrder: Boolean, ) : WooPosTotalsViewState() + sealed class Totals : Parcelable { + @Parcelize + data object Hidden : Totals() + + @Parcelize + data class Visible( + val orderSubtotalText: String, + val orderTaxText: String, + val orderTotalText: String, + ) : Totals() + } + data class PaymentSuccess(val orderTotalText: String) : WooPosTotalsViewState() sealed class ReaderStatus( diff --git a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/inprogress/WooPosTotalsPaymentInProgressScreen.kt b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/inprogress/WooPosTotalsPaymentInProgressScreen.kt index 2add10026b3..f1098e436e5 100644 --- a/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/inprogress/WooPosTotalsPaymentInProgressScreen.kt +++ b/WooCommerce/src/main/kotlin/com/woocommerce/android/ui/woopos/home/totals/payment/inprogress/WooPosTotalsPaymentInProgressScreen.kt @@ -1,8 +1,6 @@ package com.woocommerce.android.ui.woopos.home.totals.payment.inprogress import androidx.activity.compose.BackHandler -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.animateDpAsState import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -14,11 +12,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -34,7 +28,6 @@ import com.woocommerce.android.ui.woopos.common.composeui.WooPosTheme import com.woocommerce.android.ui.woopos.common.composeui.toAdaptivePadding import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsUIEvent import com.woocommerce.android.ui.woopos.home.totals.WooPosTotalsViewState -import kotlinx.coroutines.delay @Composable fun WooPosPaymentInProgressScreen( @@ -44,11 +37,6 @@ fun WooPosPaymentInProgressScreen( BackHandler { onUIEvent(WooPosTotalsUIEvent.OnBackClicked) } - var enterAnimationStarted by remember { mutableStateOf(false) } - LaunchedEffect(Unit) { - delay(50) - enterAnimationStarted = true - } Box( modifier = Modifier .background(color = WooPosTheme.colors.paymentProcessingBackground) @@ -69,29 +57,24 @@ fun WooPosPaymentInProgressScreen( clipToCompositionBounds = false, clipSpec = LottieClipSpec.Markers("payment_processing_start", "payment_processing_end") ) - val marginBetweenAnimatedIconAndText by animateDpAsState( - targetValue = if (enterAnimationStarted) 0.dp else 256.dp, - ) - Spacer(modifier = Modifier.height(marginBetweenAnimatedIconAndText.toAdaptivePadding())) - AnimatedVisibility(visible = enterAnimationStarted) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Text( - text = state.title, - color = WooPosTheme.colors.paymentProcessingText, - style = MaterialTheme.typography.h6, - fontWeight = FontWeight.Normal, - ) - Spacer(modifier = Modifier.height(8.dp.toAdaptivePadding())) - Text( - text = state.subtitle, - color = WooPosTheme.colors.paymentProcessingText, - style = MaterialTheme.typography.h4, - fontWeight = FontWeight.Bold, - ) - } - } Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = state.title, + color = WooPosTheme.colors.paymentProcessingText, + style = MaterialTheme.typography.h6, + fontWeight = FontWeight.Normal, + ) + Spacer(modifier = Modifier.height(8.dp.toAdaptivePadding())) + Text( + text = state.subtitle, + color = WooPosTheme.colors.paymentProcessingText, + style = MaterialTheme.typography.h4, + fontWeight = FontWeight.Bold, + ) + } } + Spacer(modifier = Modifier.height(16.dp.toAdaptivePadding())) } } diff --git a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt index 14165485a9d..ebb6d9674b1 100644 --- a/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt +++ b/WooCommerce/src/test/kotlin/com/woocommerce/android/ui/woopos/home/totals/WooPosTotalsViewModelTest.kt @@ -52,6 +52,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import org.assertj.core.api.Assertions.assertThat import org.junit.Before @@ -242,10 +243,12 @@ class WooPosTotalsViewModelTest { ) // THEN - val state = viewModel.state.value as WooPosTotalsViewState.Totals - assertThat(state.orderTotalText).isEqualTo("$5.00") - assertThat(state.orderTaxText).isEqualTo("$2.00") - assertThat(state.orderSubtotalText).isEqualTo("$3.00") + val state = viewModel.state.value as WooPosTotalsViewState.Checkout + assert(state.totals is WooPosTotalsViewState.Totals.Visible) + state.totals as WooPosTotalsViewState.Totals.Visible + assertThat(state.totals.orderTotalText).isEqualTo("$5.00") + assertThat(state.totals.orderTaxText).isEqualTo("$2.00") + assertThat(state.totals.orderSubtotalText).isEqualTo("$3.00") verify(totalsRepository).createOrderWithProducts(itemClickedData) } @@ -304,10 +307,11 @@ class WooPosTotalsViewModelTest { ) // THEN - val totals = viewModel.state.value as WooPosTotalsViewState.Totals - assertThat(totals.orderTotalText).isEqualTo("5.00$") - assertThat(totals.orderTaxText).isEqualTo("2.00$") - assertThat(totals.orderSubtotalText).isEqualTo("3.00$") + val state = viewModel.state.value as WooPosTotalsViewState.Checkout + state.totals as WooPosTotalsViewState.Totals.Visible + assertThat(state.totals.orderTotalText).isEqualTo("5.00$") + assertThat(state.totals.orderTaxText).isEqualTo("2.00$") + assertThat(state.totals.orderSubtotalText).isEqualTo("3.00$") } @Test @@ -441,10 +445,11 @@ class WooPosTotalsViewModelTest { viewModel.onUIEvent(WooPosTotalsUIEvent.RetryOrderCreationClicked) // Ensure the view model state transitions to the success state with correct totals - val state = viewModel.state.value as WooPosTotalsViewState.Totals - assertThat(state.orderTotalText).isEqualTo("$5.00") - assertThat(state.orderTaxText).isEqualTo("$2.00") - assertThat(state.orderSubtotalText).isEqualTo("$3.00") + val state = viewModel.state.value as WooPosTotalsViewState.Checkout + state.totals as WooPosTotalsViewState.Totals.Visible + assertThat(state.totals.orderTotalText).isEqualTo("$5.00") + assertThat(state.totals.orderTaxText).isEqualTo("$2.00") + assertThat(state.totals.orderSubtotalText).isEqualTo("$3.00") } @Test @@ -503,10 +508,11 @@ class WooPosTotalsViewModelTest { ) // THEN - val state = viewModel.state.value as WooPosTotalsViewState.Totals - assertThat(state.orderSubtotalText).isEqualTo("3.00$") - assertThat(state.orderTaxText).isEqualTo("2.00$") - assertThat(state.orderTotalText).isEqualTo("5.00$") + val state = viewModel.state.value as WooPosTotalsViewState.Checkout + state.totals as WooPosTotalsViewState.Totals.Visible + assertThat(state.totals.orderSubtotalText).isEqualTo("3.00$") + assertThat(state.totals.orderTaxText).isEqualTo("2.00$") + assertThat(state.totals.orderTotalText).isEqualTo("5.00$") verify(totalsRepository).createOrderWithProducts(itemClickedData) } @@ -579,7 +585,7 @@ class WooPosTotalsViewModelTest { ) // THEN - val state = viewModel.state.value as WooPosTotalsViewState.Totals + val state = viewModel.state.value as WooPosTotalsViewState.Checkout assertThat(state.readerStatus).isInstanceOf(WooPosTotalsViewState.ReaderStatus.Preparing::class.java) } @@ -652,8 +658,8 @@ class WooPosTotalsViewModelTest { val viewModel = createViewModelAndSetupForSuccessfulOrderCreation() // THEN - assertThat(viewModel.state.value).isInstanceOf(WooPosTotalsViewState.Totals::class.java) - val state = viewModel.state.value as WooPosTotalsViewState.Totals + assertThat(viewModel.state.value).isInstanceOf(WooPosTotalsViewState.Checkout::class.java) + val state = viewModel.state.value as WooPosTotalsViewState.Checkout assertThat(state.readerStatus).isNotNull() with(state.readerStatus as WooPosTotalsViewState.ReaderStatus.Disconnected) { assertThat(title).isEqualTo("Reader not connected") @@ -668,8 +674,8 @@ class WooPosTotalsViewModelTest { val viewModel = createViewModelAndSetupForSuccessfulOrderCreation() // THEN - assertThat(viewModel.state.value).isInstanceOf(WooPosTotalsViewState.Totals::class.java) - val state = viewModel.state.value as WooPosTotalsViewState.Totals + assertThat(viewModel.state.value).isInstanceOf(WooPosTotalsViewState.Checkout::class.java) + val state = viewModel.state.value as WooPosTotalsViewState.Checkout assertThat(state.readerStatus).isInstanceOf(WooPosTotalsViewState.ReaderStatus.Preparing::class.java) } @@ -683,7 +689,7 @@ class WooPosTotalsViewModelTest { // WHEN val viewModel = createViewModelAndSetupForSuccessfulOrderCreation() - assertThat(viewModel.state.value).isInstanceOf(WooPosTotalsViewState.Totals::class.java) + assertThat(viewModel.state.value).isInstanceOf(WooPosTotalsViewState.Checkout::class.java) viewModel.onUIEvent(WooPosTotalsUIEvent.ConnectReaderClicked) // THEN @@ -757,6 +763,7 @@ class WooPosTotalsViewModelTest { // WHEN paymentState.value = CardReaderPaymentState.ProcessingPayment.ExternalReaderProcessingPayment("") {} + advanceUntilIdle() // THEN assertThat(vm.state.value).isInstanceOf(WooPosTotalsViewState.PaymentInProgress::class.java) @@ -792,7 +799,7 @@ class WooPosTotalsViewModelTest { val vm = createViewModelAndSetupForSuccessfulOrderCreation(controllerFactory = factory) // THEN - val totalState = vm.state.value as WooPosTotalsViewState.Totals + val totalState = vm.state.value as WooPosTotalsViewState.Checkout assertThat(totalState.readerStatus).isInstanceOf( WooPosTotalsViewState.ReaderStatus.ReadyForPayment::class.java ) @@ -827,6 +834,7 @@ class WooPosTotalsViewModelTest { // WHEN val vm = createViewModelAndSetupForSuccessfulOrderCreation(controllerFactory = factory) paymentState.value = CardReaderPaymentState.PaymentCapturing.ExternalReaderPaymentCapturing("") + advanceUntilIdle() // THEN val processingState = vm.state.value as WooPosTotalsViewState.PaymentInProgress @@ -856,6 +864,7 @@ class WooPosTotalsViewModelTest { // WHEN val vm = createViewModelAndSetupForSuccessfulOrderCreation(controllerFactory = factory) paymentState.value = CardReaderPaymentState.ProcessingPayment.ExternalReaderProcessingPayment("") {} + advanceUntilIdle() // THEN val processingState = vm.state.value as WooPosTotalsViewState.PaymentInProgress @@ -897,6 +906,7 @@ class WooPosTotalsViewModelTest { paymentState.value = CardReaderPaymentState.PaymentFailed.ExternalReaderFailedPayment.NonCancelable( errorType = PaymentFlowError.NoNetwork, failedPaymentRetryAction ) + advanceUntilIdle() assertThat(vm.state.value).isInstanceOf(WooPosTotalsViewState.PaymentFailed::class.java) assertTrue( (paymentState.value as CardReaderPaymentState.PaymentFailed.ExternalReaderFailedPayment).onRetry != null @@ -938,6 +948,7 @@ class WooPosTotalsViewModelTest { paymentState.value = CardReaderPaymentState.PaymentFailed.ExternalReaderFailedPayment.Cancelable( errorType = PaymentFlowError.NoNetwork, onRetry = null, onCancel = {}, amountWithCurrencyLabel = "" ) + advanceUntilIdle() assertThat(vm.state.value).isInstanceOf(WooPosTotalsViewState.PaymentFailed::class.java) assertTrue( (paymentState.value as CardReaderPaymentState.PaymentFailed.ExternalReaderFailedPayment).onRetry == null @@ -981,6 +992,8 @@ class WooPosTotalsViewModelTest { paymentState.value = CardReaderPaymentState.PaymentFailed.ExternalReaderFailedPayment.Cancelable( errorType = PaymentFlowError.NoNetwork, onRetry = null, onCancel = {}, amountWithCurrencyLabel = "" ) + advanceUntilIdle() + assertThat(vm.state.value).isInstanceOf(WooPosTotalsViewState.PaymentFailed::class.java) assertTrue( (paymentState.value as CardReaderPaymentState.PaymentFailed.ExternalReaderFailedPayment).onRetry == null @@ -988,6 +1001,7 @@ class WooPosTotalsViewModelTest { // WHEN vm.onUIEvent(WooPosTotalsUIEvent.RetryFailedTransactionClicked) + advanceUntilIdle() // THEN verify(childrenToParentEventSender).sendToParent(ChildToParentEvent.ReturnedFromCardReaderPaymentToCheckout) @@ -1019,6 +1033,7 @@ class WooPosTotalsViewModelTest { paymentState.value = CardReaderPaymentState.PaymentFailed.ExternalReaderFailedPayment.NonCancelable( errorType = PaymentFlowError.NoNetwork, {} ) + advanceUntilIdle() assertThat(vm.state.value).isInstanceOf(WooPosTotalsViewState.PaymentFailed::class.java) // WHEN @@ -1179,8 +1194,8 @@ class WooPosTotalsViewModelTest { ) // THEN - val totals = viewModel.state.value as WooPosTotalsViewState.Totals - assertTrue(totals.isFreeOrder) + val checkout = viewModel.state.value as WooPosTotalsViewState.Checkout + assertTrue(checkout.isFreeOrder) } @Test @@ -1238,8 +1253,8 @@ class WooPosTotalsViewModelTest { ) // THEN - val totals = viewModel.state.value as WooPosTotalsViewState.Totals - assertFalse(totals.isFreeOrder) + val checkout = viewModel.state.value as WooPosTotalsViewState.Checkout + assertFalse(checkout.isFreeOrder) } private fun createNonEmptyOrder() = Order.getEmptyOrder(