Updated on 2026-08-14
This commit is contained in:
parent
3f56f32dd6
commit
60911ceb8c
5 changed files with 18 additions and 157 deletions
|
|
@ -120,7 +120,6 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
|
||||
private val refreshStateJobHolder = JobHolder()
|
||||
private val addToWalletBannerJobHolder = JobHolder()
|
||||
private val frozenStateJobHolder = JobHolder()
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
|
||||
|
||||
|
|
@ -141,9 +140,6 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
fetchAddToWalletBanner()
|
||||
uiState.update { stateFactory.getLoadedState(state) }
|
||||
uiState.update(DetailsBalanceTransformer(state.balance.fiatBalance))
|
||||
state.cards.firstOrNull()?.let { card ->
|
||||
subscribeToCardFrozenState(card.id)
|
||||
}
|
||||
}
|
||||
else -> uiState.update { stateFactory.getLoadingState() }
|
||||
}
|
||||
|
|
@ -165,22 +161,6 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
|
||||
fun isRedesignEnabled(): Boolean = tangemPayFeatureToggles.isRedesignEnabled
|
||||
|
||||
private fun subscribeToCardFrozenState(cardId: String) {
|
||||
frozenStateJobHolder.cancel()
|
||||
cardDetailsRepository
|
||||
.cardFrozenState(cardId)
|
||||
.onEach { frozenState ->
|
||||
uiState.update(
|
||||
TangemPayFreezeUnfreezeStateTransformer(
|
||||
cardFrozenState = frozenState,
|
||||
isDataFresh = currentStatus.value.ifLoadedOrNull { it.isFresh } == true,
|
||||
),
|
||||
)
|
||||
}
|
||||
.launchIn(modelScope)
|
||||
.saveIn(frozenStateJobHolder)
|
||||
}
|
||||
|
||||
override fun onClickAddFunds() {
|
||||
analytics.send(TangemPayAnalyticsEvents.AddFundsClicked())
|
||||
val balance = currentStatus.value.balanceOrNull()
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.tangem.domain.models.pay.TangemPayCardFrozenState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
|
||||
import com.tangem.utils.transformer.Transformer
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
internal class TangemPayFreezeUnfreezeStateTransformer(
|
||||
private val cardFrozenState: TangemPayCardFrozenState,
|
||||
private val isDataFresh: Boolean,
|
||||
) : Transformer<TangemPayDetailsUM> {
|
||||
|
||||
override fun transform(prevState: TangemPayDetailsUM): TangemPayDetailsUM {
|
||||
val balanceBlockState = if (prevState.balanceBlockState is TangemPayDetailsBalanceBlockState.Content) {
|
||||
val isEnabled = isDataFresh && cardFrozenState == TangemPayCardFrozenState.Unfrozen
|
||||
val actionButtons = prevState.balanceBlockState.actionButtons.map {
|
||||
it.copy(isEnabled = isEnabled)
|
||||
}
|
||||
prevState.balanceBlockState.copy(actionButtons = actionButtons.toPersistentList())
|
||||
} else {
|
||||
prevState.balanceBlockState
|
||||
}
|
||||
return prevState.copy(balanceBlockState = balanceBlockState)
|
||||
}
|
||||
}
|
||||
|
|
@ -22,14 +22,12 @@ internal val AccountStatus.Payment.isDeactivated: Boolean
|
|||
get() = value is PaymentAccountStatusValue.Deactivated
|
||||
|
||||
internal val PaymentAccountStatusValue.Loaded.isFresh: Boolean
|
||||
get() = source == StatusSource.ACTUAL && error == null
|
||||
get() = source.isActual() && error == null
|
||||
|
||||
internal fun AccountStatus.Payment.requireLoaded(): PaymentAccountStatusValue.Loaded =
|
||||
value as? PaymentAccountStatusValue.Loaded
|
||||
?: error("Card-detail subflow requires Loaded status, got ${value::class.simpleName}")
|
||||
|
||||
internal fun AccountStatus.Payment.firstCard(): TangemPayCard = requireLoaded().cards.first()
|
||||
|
||||
internal inline fun <T> AccountStatus.Payment.ifLoadedOrNull(call: (PaymentAccountStatusValue.Loaded) -> T): T? {
|
||||
val value = value
|
||||
return if (value is PaymentAccountStatusValue.Loaded) {
|
||||
|
|
|
|||
|
|
@ -96,6 +96,23 @@ internal class TangemPayDetailsStateFactoryTest {
|
|||
assertThat(state.balanceBlockState.cardsBlockState?.isAddCardEnabled).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN actual status with frozen first card but unfrozen second card WHEN getLoadedState THEN action buttons enabled`() {
|
||||
val factory = createFactory()
|
||||
val frozenFirstCard = activeUnfrozenCard.copy(id = "card_frozen", frozenState = TangemPayCardFrozenState.Frozen)
|
||||
val status = loadedStatus(
|
||||
statusSource = StatusSource.ACTUAL,
|
||||
statusError = null,
|
||||
statusCards = listOf(frozenFirstCard, activeUnfrozenCard),
|
||||
)
|
||||
|
||||
// Act
|
||||
val state = factory.getLoadedState(status)
|
||||
|
||||
// Assert
|
||||
assertThat(state.balanceBlockState.actionButtons.map { it.isEnabled }).containsExactly(true, true)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN actual status with issuing card WHEN getLoadedState THEN add card disabled`() {
|
||||
// Arrange
|
||||
|
|
|
|||
|
|
@ -1,108 +0,0 @@
|
|||
package com.tangem.features.tangempay.model.transformers
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
|
||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.domain.models.pay.TangemPayCardFrozenState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsTopBarConfig
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
|
||||
internal class TangemPayFreezeUnfreezeStateTransformerTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideCases")
|
||||
fun `GIVEN content state WHEN transform THEN buttons enabled only when fresh and unfrozen`(case: Case) {
|
||||
// Arrange
|
||||
val state = contentState(actionButtonsEnabled = true)
|
||||
|
||||
// Act
|
||||
val result = TangemPayFreezeUnfreezeStateTransformer(
|
||||
cardFrozenState = case.frozenState,
|
||||
isDataFresh = case.isDataFresh,
|
||||
).transform(state)
|
||||
|
||||
// Assert
|
||||
val enabled = result.balanceBlockState.actionButtons.map { it.isEnabled }
|
||||
assertThat(enabled).containsExactly(case.expectedEnabled, case.expectedEnabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN non-content state WHEN transform THEN state is unchanged`() {
|
||||
// Arrange
|
||||
val state = loadingState()
|
||||
|
||||
// Act
|
||||
val result = TangemPayFreezeUnfreezeStateTransformer(
|
||||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
isDataFresh = true,
|
||||
).transform(state)
|
||||
|
||||
// Assert
|
||||
assertThat(result).isEqualTo(state)
|
||||
}
|
||||
|
||||
private fun contentState(actionButtonsEnabled: Boolean): TangemPayDetailsUM = baseState(
|
||||
balanceBlockState = TangemPayDetailsBalanceBlockState.Content(
|
||||
actionButtons = persistentListOf(
|
||||
actionButton(isEnabled = actionButtonsEnabled),
|
||||
actionButton(isEnabled = actionButtonsEnabled),
|
||||
),
|
||||
cardsBlockState = null,
|
||||
fiatBalance = TextReference.EMPTY,
|
||||
isBalanceFlickering = false,
|
||||
),
|
||||
)
|
||||
|
||||
private fun loadingState(): TangemPayDetailsUM = baseState(
|
||||
balanceBlockState = TangemPayDetailsBalanceBlockState.Loading(
|
||||
actionButtons = persistentListOf(actionButton(isEnabled = true)),
|
||||
cardsBlockState = null,
|
||||
),
|
||||
)
|
||||
|
||||
private fun baseState(balanceBlockState: TangemPayDetailsBalanceBlockState) = TangemPayDetailsUM(
|
||||
topBarConfig = TangemPayDetailsTopBarConfig(
|
||||
onBackClick = {},
|
||||
onOpenMenu = {},
|
||||
items = persistentListOf(),
|
||||
itemsV2 = persistentListOf(),
|
||||
),
|
||||
pullToRefreshConfig = PullToRefreshConfig(isRefreshing = false, onRefresh = {}),
|
||||
balanceBlockState = balanceBlockState,
|
||||
addToWalletBlockState = null,
|
||||
isBalanceHidden = false,
|
||||
errorNotificationConfig = null,
|
||||
accountDeactivatedNotificationConfig = null,
|
||||
)
|
||||
|
||||
private fun actionButton(isEnabled: Boolean) = ActionButtonConfig(
|
||||
text = TextReference.EMPTY,
|
||||
iconResId = 0,
|
||||
onClick = {},
|
||||
isEnabled = isEnabled,
|
||||
)
|
||||
|
||||
internal data class Case(
|
||||
val frozenState: TangemPayCardFrozenState,
|
||||
val isDataFresh: Boolean,
|
||||
val expectedEnabled: Boolean,
|
||||
)
|
||||
|
||||
private companion object {
|
||||
@JvmStatic
|
||||
fun provideCases() = listOf(
|
||||
Case(frozenState = TangemPayCardFrozenState.Unfrozen, isDataFresh = true, expectedEnabled = true),
|
||||
Case(frozenState = TangemPayCardFrozenState.Unfrozen, isDataFresh = false, expectedEnabled = false),
|
||||
Case(frozenState = TangemPayCardFrozenState.Frozen, isDataFresh = true, expectedEnabled = false),
|
||||
Case(frozenState = TangemPayCardFrozenState.Pending, isDataFresh = true, expectedEnabled = false),
|
||||
Case(frozenState = TangemPayCardFrozenState.Frozen, isDataFresh = false, expectedEnabled = false),
|
||||
Case(frozenState = TangemPayCardFrozenState.Pending, isDataFresh = false, expectedEnabled = false),
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue