Updated on 2026-08-14
This commit is contained in:
parent
075db99e51
commit
4a7d9143c2
3 changed files with 121 additions and 8 deletions
|
|
@ -43,10 +43,10 @@ import com.tangem.datasource.local.appsflyer.AppsFlyerStore
|
|||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||
import com.tangem.domain.account.status.usecase.GetFeePaidCryptoCurrencyStatusSyncUseCase
|
||||
import com.tangem.domain.account.status.usecase.IsAccountsModeEnabledUseCase
|
||||
import com.tangem.domain.card.IsWalletBackupProblematicUseCase
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
|
||||
import com.tangem.domain.card.IsWalletBackupProblematicUseCase
|
||||
import com.tangem.domain.express.models.ExpressOperationType
|
||||
import com.tangem.domain.express.models.ProviderFilterType
|
||||
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
||||
|
|
@ -541,6 +541,10 @@ internal class SwapModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
),
|
||||
isTransferMode = swapTransferInteractor.shouldTransferInsteadOfSwap(
|
||||
fromSwapCurrency = fromSwapCurrencyStatus?.currency,
|
||||
toSwapCurrency = toSwapCurrencyStatus?.currency,
|
||||
),
|
||||
),
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
|
|
@ -623,6 +627,10 @@ internal class SwapModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
),
|
||||
isTransferMode = swapTransferInteractor.shouldTransferInsteadOfSwap(
|
||||
fromSwapCurrency = newFromSwapCurrencyStatus?.currency,
|
||||
toSwapCurrency = newToSwapCurrencyStatus?.currency,
|
||||
),
|
||||
),
|
||||
fromSwapCurrencyStatus = newFromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = newToSwapCurrencyStatus,
|
||||
|
|
@ -741,6 +749,10 @@ internal class SwapModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
),
|
||||
isTransferMode = swapTransferInteractor.shouldTransferInsteadOfSwap(
|
||||
fromSwapCurrency = fromSwapCurrencyStatus.currency,
|
||||
toSwapCurrency = toSwapCurrencyStatus.currency,
|
||||
),
|
||||
),
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
|
|
|
|||
|
|
@ -153,10 +153,15 @@ internal class StateBuilder(
|
|||
isHoldToConfirm = fromSwapCurrencyStatus?.userWallet?.isHotWallet == true,
|
||||
onClick = { },
|
||||
),
|
||||
shouldShowMaxAmount = shouldShowMaxAmount(fromSwapCurrencyStatus?.currency, toSwapCurrencyStatus?.currency),
|
||||
predefinedButtons = createPredefinedButtons(
|
||||
shouldShowMaxAmount = shouldShowMaxAmount(
|
||||
fromSwapCurrencyStatus?.currency,
|
||||
toSwapCurrencyStatus?.currency,
|
||||
emptyAmountState.isTransferMode,
|
||||
),
|
||||
predefinedButtons = createPredefinedButtons(
|
||||
fromToken = fromSwapCurrencyStatus?.currency,
|
||||
toCurrency = toSwapCurrencyStatus?.currency,
|
||||
isTransferMode = emptyAmountState.isTransferMode,
|
||||
),
|
||||
changeCardsButtonState = ChangeCardsButtonState.ENABLED,
|
||||
providerState = ProviderState.Empty(),
|
||||
|
|
@ -244,6 +249,11 @@ internal class StateBuilder(
|
|||
toSwapCurrencyStatus: SwapCurrencyStatus?,
|
||||
shouldResetAmount: Boolean,
|
||||
): SwapStateHolder {
|
||||
val shouldShowMaxAmount = shouldShowMaxAmount(
|
||||
fromSwapCurrencyStatus?.currency,
|
||||
toSwapCurrencyStatus?.currency,
|
||||
emptyAmountState.isTransferMode,
|
||||
)
|
||||
return uiStateHolder.copy(
|
||||
sendCardData = uiStateHolder.sendCardData.updateCurrencyStatus(
|
||||
swapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
|
|
@ -267,10 +277,11 @@ internal class StateBuilder(
|
|||
isHoldToConfirm = fromSwapCurrencyStatus?.userWallet?.isHotWallet == true,
|
||||
onClick = { },
|
||||
),
|
||||
shouldShowMaxAmount = shouldShowMaxAmount(fromSwapCurrencyStatus?.currency, toSwapCurrencyStatus?.currency),
|
||||
shouldShowMaxAmount = shouldShowMaxAmount,
|
||||
predefinedButtons = createPredefinedButtons(
|
||||
fromSwapCurrencyStatus?.currency,
|
||||
toSwapCurrencyStatus?.currency,
|
||||
fromToken = fromSwapCurrencyStatus?.currency,
|
||||
toCurrency = toSwapCurrencyStatus?.currency,
|
||||
isTransferMode = emptyAmountState.isTransferMode,
|
||||
),
|
||||
changeCardsButtonState = ChangeCardsButtonState.ENABLED,
|
||||
providerState = ProviderState.Empty(),
|
||||
|
|
@ -683,7 +694,12 @@ internal class StateBuilder(
|
|||
)
|
||||
}
|
||||
|
||||
private fun shouldShowMaxAmount(fromToken: CryptoCurrency?, toCurrency: CryptoCurrency?): Boolean {
|
||||
private fun shouldShowMaxAmount(
|
||||
fromToken: CryptoCurrency?,
|
||||
toCurrency: CryptoCurrency?,
|
||||
isTransferMode: Boolean = false,
|
||||
): Boolean {
|
||||
if (isTransferMode) return true
|
||||
return !(fromToken is CryptoCurrency.Coin && fromToken.network.id == toCurrency?.network?.id)
|
||||
}
|
||||
|
||||
|
|
@ -696,9 +712,10 @@ internal class StateBuilder(
|
|||
private fun createPredefinedButtons(
|
||||
fromToken: CryptoCurrency?,
|
||||
toCurrency: CryptoCurrency?,
|
||||
isTransferMode: Boolean = false,
|
||||
): ImmutableList<PredefinedPercentButtonUM> {
|
||||
if (!swapFeatureToggles.isSwapPredefinedButtonsEnabled) return persistentListOf()
|
||||
val shouldShowMaxAmount = shouldShowMaxAmount(fromToken, toCurrency)
|
||||
val shouldShowMaxAmount = shouldShowMaxAmount(fromToken, toCurrency, isTransferMode)
|
||||
return PredefinedPercentAmount.entries
|
||||
.filter { it != PredefinedPercentAmount.MAX || shouldShowMaxAmount }
|
||||
.map { percent ->
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.domain.express.models.ExpressError
|
|||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.swap.models.SwapCurrencyStatus
|
||||
|
|
@ -270,6 +271,50 @@ internal class StateBuilderInitialStateTest {
|
|||
|
||||
assertThat(result.notifications).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN same coin on different wallets in transfer mode WHEN called THEN shouldShowMaxAmount is true`() {
|
||||
// Arrange — same coin (shared network id) moved between two wallets => transfer mode
|
||||
val sharedNetwork = buildSharedNetwork()
|
||||
val walletA: UserWallet.Cold = mockk(relaxed = true) { every { walletId } returns UserWalletId("aabb") }
|
||||
val walletB: UserWallet.Cold = mockk(relaxed = true) { every { walletId } returns UserWalletId("ccdd") }
|
||||
val fromStatus = buildCoinSwapCurrencyStatus(walletA, sharedNetwork)
|
||||
val toStatus = buildCoinSwapCurrencyStatus(walletB, sharedNetwork)
|
||||
val transferState = SwapState.EmptyAmountState(
|
||||
zeroAmountEquivalent = com.tangem.core.ui.extensions.stringReference("$0.00"),
|
||||
isTransferMode = true,
|
||||
)
|
||||
|
||||
// Act
|
||||
val result = sut.createInitialReadyState(
|
||||
uiStateHolder = baseState,
|
||||
emptyAmountState = transferState,
|
||||
fromSwapCurrencyStatus = fromStatus,
|
||||
toSwapCurrencyStatus = toStatus,
|
||||
)
|
||||
|
||||
// Assert
|
||||
assertThat(result.shouldShowMaxAmount).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN same-network coin swap not in transfer mode WHEN called THEN shouldShowMaxAmount is false`() {
|
||||
// Arrange — same network coin pair, regular swap => MAX hidden to keep balance for the fee
|
||||
val sharedNetwork = buildSharedNetwork()
|
||||
val fromStatus = buildCoinSwapCurrencyStatus(userWallet, sharedNetwork)
|
||||
val toStatus = buildCoinSwapCurrencyStatus(userWallet, sharedNetwork)
|
||||
|
||||
// Act
|
||||
val result = sut.createInitialReadyState(
|
||||
uiStateHolder = baseState,
|
||||
emptyAmountState = emptyAmountState,
|
||||
fromSwapCurrencyStatus = fromStatus,
|
||||
toSwapCurrencyStatus = toStatus,
|
||||
)
|
||||
|
||||
// Assert
|
||||
assertThat(result.shouldShowMaxAmount).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
|
@ -574,4 +619,43 @@ internal fun buildSwapCurrencyStatus(
|
|||
status = cryptoCurrencyStatus,
|
||||
account = account,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A single [Network] mock whose [Network.id] resolves to one shared instance, so two currencies built from
|
||||
* it compare equal on `network.id` — the condition that gates [StateBuilder.shouldShowMaxAmount].
|
||||
*/
|
||||
internal fun buildSharedNetwork(): Network = mockk(relaxed = true) {
|
||||
every { id } returns mockk(relaxed = true)
|
||||
every { name } returns "Ethereum"
|
||||
every { currencySymbol } returns "ETH"
|
||||
every { rawId } returns "ethereum"
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a [SwapCurrencyStatus] backed by a [CryptoCurrency.Coin] on the given [network]. Pass the same
|
||||
* [network] instance to two calls to model the "same coin on different wallets" (transfer) case.
|
||||
*/
|
||||
internal fun buildCoinSwapCurrencyStatus(
|
||||
userWallet: UserWallet,
|
||||
network: Network,
|
||||
): SwapCurrencyStatus {
|
||||
val account = Account.CryptoPortfolio.createMainAccount(userWallet.walletId)
|
||||
val currency = mockk<CryptoCurrency.Coin>(relaxed = true) {
|
||||
every { symbol } returns "ETH"
|
||||
every { decimals } returns 18
|
||||
every { name } returns "Ethereum"
|
||||
every { this@mockk.network } returns network
|
||||
}
|
||||
val statusValue: CryptoCurrencyStatus.Value = mockk(relaxed = true) {
|
||||
every { amount } returns java.math.BigDecimal("1.0")
|
||||
every { fiatRate } returns java.math.BigDecimal("2000.00")
|
||||
every { fiatAmount } returns java.math.BigDecimal("2000.00")
|
||||
}
|
||||
val cryptoCurrencyStatus = CryptoCurrencyStatus(currency = currency, value = statusValue)
|
||||
return SwapCurrencyStatus(
|
||||
userWallet = userWallet,
|
||||
status = cryptoCurrencyStatus,
|
||||
account = account,
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue