Updated on 2026-08-14
This commit is contained in:
parent
01b7433542
commit
e338fb8fdc
18 changed files with 351 additions and 68 deletions
|
|
@ -47,6 +47,7 @@ dependencies {
|
|||
implementation(projects.domain.visa.models)
|
||||
implementation(projects.domain.balanceHiding)
|
||||
implementation(projects.domain.yieldSupply)
|
||||
implementation(projects.domain.notifications)
|
||||
|
||||
/** Common modules */
|
||||
implementation(projects.common.ui)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ sealed interface SwapState {
|
|||
val isAccountsMode: Boolean,
|
||||
val isFeeCoverage: Boolean,
|
||||
val sendingAmount: BigDecimal,
|
||||
val tronFeeNotificationShowCount: Int,
|
||||
val isSendingAmountLoading: Boolean = false,
|
||||
val currencyCheck: CryptoCurrencyCheck? = null,
|
||||
val validationResult: Throwable? = null,
|
||||
|
|
|
|||
|
|
@ -53,4 +53,6 @@ interface SwapTransferInteractor {
|
|||
cryptoAmount: BigDecimal,
|
||||
toSwapCurrencyStatus: SwapCurrencyStatus,
|
||||
): Either<SendTransactionError, WithdrawalResult>
|
||||
|
||||
suspend fun incrementTronTokenFeeShowCount(cryptoCurrencyStatus: CryptoCurrencyStatus?)
|
||||
}
|
||||
|
|
@ -19,6 +19,8 @@ import com.tangem.domain.models.currency.CryptoCurrency
|
|||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.notifications.GetTronFeeNotificationShowCountUseCase
|
||||
import com.tangem.domain.notifications.IncrementNotificationsShowCountUseCase
|
||||
import com.tangem.domain.pay.WithdrawalResult
|
||||
import com.tangem.domain.swap.models.SwapCurrencyStatus
|
||||
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
|
||||
|
|
@ -62,6 +64,8 @@ class SwapTransferInteractorImpl @Inject constructor(
|
|||
private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase,
|
||||
private val tangemPayWithdrawUseCase: TangemPayWithdrawUseCase,
|
||||
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase,
|
||||
private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase,
|
||||
private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase,
|
||||
) : SwapTransferInteractor {
|
||||
|
||||
override suspend fun updateTransfer(
|
||||
|
|
@ -120,6 +124,7 @@ class SwapTransferInteractorImpl @Inject constructor(
|
|||
feeStatus = feeStatus,
|
||||
)
|
||||
}
|
||||
val tronFeeNotificationShowCount = getTronFeeNotificationShowCountUseCase()
|
||||
return SwapState.Transfer(
|
||||
userWallet = userWallet,
|
||||
fromTokenInfo = fromTokenInfo,
|
||||
|
|
@ -131,6 +136,7 @@ class SwapTransferInteractorImpl @Inject constructor(
|
|||
isAccountsMode = isAccountsMode,
|
||||
isFeeCoverage = coverageState.isFeeCoverage,
|
||||
sendingAmount = coverageState.sendingAmount,
|
||||
tronFeeNotificationShowCount = tronFeeNotificationShowCount,
|
||||
isSendingAmountLoading = coverageState.isSendingAmountLoading,
|
||||
currencyCheck = currencyCheck,
|
||||
)
|
||||
|
|
@ -390,4 +396,10 @@ class SwapTransferInteractorImpl @Inject constructor(
|
|||
private fun SwapCurrencyStatus.destinationAddress(): String? {
|
||||
return status.value.networkAddress?.defaultAddress?.value
|
||||
}
|
||||
|
||||
override suspend fun incrementTronTokenFeeShowCount(cryptoCurrencyStatus: CryptoCurrencyStatus?) {
|
||||
cryptoCurrencyStatus?.currency?.let { cryptoCurrency ->
|
||||
incrementNotificationsShowCountUseCase(cryptoCurrency)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@ import com.tangem.domain.models.network.Network
|
|||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.notifications.GetTronFeeNotificationShowCountUseCase
|
||||
import com.tangem.domain.notifications.IncrementNotificationsShowCountUseCase
|
||||
import com.tangem.domain.pay.WithdrawalResult
|
||||
import com.tangem.domain.swap.models.SwapCurrencyStatus
|
||||
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
|
||||
|
|
@ -61,6 +63,8 @@ internal class SwapTransferInteractorImplTest {
|
|||
private val isAmountSubtractAvailableUseCase: IsAmountSubtractAvailableUseCase = mockk()
|
||||
private val tangemPayWithdrawUseCase: TangemPayWithdrawUseCase = mockk()
|
||||
private val getBalanceNotEnoughForFeeWarningUseCase: GetBalanceNotEnoughForFeeWarningUseCase = mockk(relaxed = true)
|
||||
private val getTronFeeNotificationShowCountUseCase: GetTronFeeNotificationShowCountUseCase = mockk(relaxed = true)
|
||||
private val incrementNotificationsShowCountUseCase: IncrementNotificationsShowCountUseCase = mockk(relaxed = true)
|
||||
|
||||
private val sut = SwapTransferInteractorImpl(
|
||||
swapFeatureToggles = swapFeatureToggles,
|
||||
|
|
@ -76,6 +80,8 @@ internal class SwapTransferInteractorImplTest {
|
|||
isAmountSubtractAvailableUseCase = isAmountSubtractAvailableUseCase,
|
||||
tangemPayWithdrawUseCase = tangemPayWithdrawUseCase,
|
||||
getBalanceNotEnoughForFeeWarningUseCase = getBalanceNotEnoughForFeeWarningUseCase,
|
||||
getTronFeeNotificationShowCountUseCase = getTronFeeNotificationShowCountUseCase,
|
||||
incrementNotificationsShowCountUseCase = incrementNotificationsShowCountUseCase,
|
||||
)
|
||||
|
||||
@AfterEach
|
||||
|
|
@ -180,6 +186,7 @@ internal class SwapTransferInteractorImplTest {
|
|||
isAccountsMode = true,
|
||||
isFeeCoverage = false,
|
||||
sendingAmount = expectedAmount,
|
||||
tronFeeNotificationShowCount = 0,
|
||||
currencyCheck = currencyCheck,
|
||||
)
|
||||
assertThat(result).isEqualTo(expected)
|
||||
|
|
@ -251,6 +258,7 @@ internal class SwapTransferInteractorImplTest {
|
|||
isAccountsMode = true,
|
||||
isFeeCoverage = false,
|
||||
sendingAmount = expectedAmount,
|
||||
tronFeeNotificationShowCount = 0,
|
||||
currencyCheck = currencyCheck,
|
||||
)
|
||||
assertThat(result).isEqualTo(expected)
|
||||
|
|
|
|||
|
|
@ -822,6 +822,7 @@ internal class SwapModel @Inject constructor(
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = feePaidCryptoCurrency,
|
||||
fee = selectedFee,
|
||||
feeError = feeSelectorRepository.state.value as? FeeSelectorUM.Error,
|
||||
)
|
||||
when {
|
||||
uiState.successState != null -> Unit
|
||||
|
|
@ -866,9 +867,10 @@ internal class SwapModel @Inject constructor(
|
|||
transferState = refreshed,
|
||||
actions = actions,
|
||||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = feePaidCryptoCurrencyStatus,
|
||||
feePaidCryptoCurrencyStatus = feePaidCryptoCurrencyStatus ?: dataState.feePaidCryptoCurrency,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = isTangemPayWithdrawal(),
|
||||
feeError = feeSelectorRepository.state.value as? FeeSelectorUM.Error,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -2105,6 +2107,7 @@ internal class SwapModel @Inject constructor(
|
|||
},
|
||||
onSwapUIModeChange = ::onSwapUIModeChange,
|
||||
onSwapTypeMenuOpened = ::onSwapTypeMenuOpened,
|
||||
onTronBannerShown = ::incrementTronTokenFeeShowCount,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -2132,6 +2135,16 @@ internal class SwapModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun incrementTronTokenFeeShowCount() {
|
||||
// Fired once per banner appearance from the UI (tied to the banner's composition lifecycle),
|
||||
// so the show-count advances per appearance rather than on every transfer-state rebuild.
|
||||
modelScope.launch {
|
||||
swapTransferInteractor.incrementTronTokenFeeShowCount(
|
||||
cryptoCurrencyStatus = dataState.fromSwapCurrencyStatus?.status,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun selectWalletInSelector(
|
||||
fromSwapCurrencyStatus: SwapCurrencyStatus?,
|
||||
toSwapCurrencyStatus: SwapCurrencyStatus?,
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ internal data class SwapStateHolder(
|
|||
val onShowPermissionBottomSheet: () -> Unit = {},
|
||||
val onSwapUIModeChange: (SwapUIMode) -> Unit = {},
|
||||
val onSwapTypeMenuOpened: () -> Unit = {},
|
||||
val onTronBannerShown: () -> Unit = {},
|
||||
)
|
||||
|
||||
@Immutable
|
||||
|
|
|
|||
|
|
@ -34,4 +34,5 @@ internal data class UiActions(
|
|||
val onReceiveCardWarningClick: () -> Unit,
|
||||
val onSwapUIModeChange: (SwapUIMode) -> Unit,
|
||||
val onSwapTypeMenuOpened: () -> Unit,
|
||||
val onTronBannerShown: () -> Unit,
|
||||
)
|
||||
|
|
@ -251,5 +251,10 @@ internal object SwapNotificationUM {
|
|||
onClick = onApproveClick,
|
||||
),
|
||||
)
|
||||
|
||||
data object TronTokenFee : Info(
|
||||
title = resourceReference(R.string.tron_will_be_send_token_fee_title),
|
||||
subtitle = resourceReference(R.string.tron_will_be_send_token_fee_description),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -122,6 +122,7 @@ internal class StateBuilder(
|
|||
swapUIMode = swapUIMode,
|
||||
onSwapUIModeChange = actions.onSwapUIModeChange,
|
||||
onSwapTypeMenuOpened = actions.onSwapTypeMenuOpened,
|
||||
onTronBannerShown = actions.onTronBannerShown,
|
||||
shouldShowAbMenu = swapFeatureToggles.isSwapAbEnabled,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,12 @@ internal fun SwapScreenContent(
|
|||
|
||||
feeBlock?.invoke(Modifier.fillMaxWidth())
|
||||
|
||||
if (state.notifications.isNotEmpty()) SwapNotifications(notifications = state.notifications)
|
||||
if (state.notifications.isNotEmpty()) {
|
||||
SwapNotifications(
|
||||
notifications = state.notifications,
|
||||
onTronBannerShown = state.onTronBannerShown,
|
||||
)
|
||||
}
|
||||
|
||||
SpacerHMax()
|
||||
|
||||
|
|
@ -342,7 +347,13 @@ private fun SwapButton(state: SwapStateHolder, modifier: Modifier = Modifier) {
|
|||
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
private fun SwapNotifications(notifications: List<NotificationUM>) {
|
||||
private fun SwapNotifications(notifications: List<NotificationUM>, onTronBannerShown: () -> Unit) {
|
||||
// The Tron token-fee banner's show-count is an "impression": tied to actual on-screen visibility.
|
||||
// LaunchedEffect re-arms only when the boolean flips, so it fires once per hidden -> shown appearance.
|
||||
val isTronBannerShown = notifications.any { it is SwapNotificationUM.Info.TronTokenFee }
|
||||
LaunchedEffect(isTronBannerShown) {
|
||||
if (isTronBannerShown) onTronBannerShown()
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = TangemTheme.colors.background.secondary)
|
||||
|
|
|
|||
|
|
@ -6,18 +6,22 @@ import com.tangem.common.ui.notifications.NotificationsFactory.addDustWarningNot
|
|||
import com.tangem.common.ui.notifications.NotificationsFactory.addExceedsBalanceNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addExistentialWarningNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeCoverageNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addFeeUnreachableNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addReserveAmountErrorNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addTransactionLimitErrorNotification
|
||||
import com.tangem.common.ui.notifications.NotificationsFactory.addValidateTransactionNotifications
|
||||
import com.tangem.core.ui.utils.parseBigDecimal
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.ui.SwapState
|
||||
import com.tangem.feature.swap.models.UiActions
|
||||
import com.tangem.feature.swap.models.states.SwapNotificationUM
|
||||
import com.tangem.lib.crypto.BlockchainUtils
|
||||
import com.tangem.lib.crypto.BlockchainUtils.getTezosThreshold
|
||||
import com.tangem.lib.crypto.BlockchainUtils.isTezos
|
||||
import com.tangem.lib.crypto.BlockchainUtils.isTron
|
||||
import com.tangem.utils.extensions.orZero
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
|
@ -31,9 +35,8 @@ internal class SwapTransferNotificationsFactory @Inject constructor() {
|
|||
transferState: SwapState.Transfer,
|
||||
feeCryptoCurrencyStatus: CryptoCurrencyStatus?,
|
||||
fee: Fee?,
|
||||
onReduceByAmount: (SwapAmount, BigDecimal) -> Unit,
|
||||
onReduceToAmount: (SwapAmount) -> Unit,
|
||||
onBuyClick: (CryptoCurrency) -> Unit,
|
||||
actions: UiActions,
|
||||
getFeeError: GetFeeError?,
|
||||
): ImmutableList<NotificationUM> {
|
||||
return buildList {
|
||||
maybeAddRentExemptionError(transferState)
|
||||
|
|
@ -41,11 +44,21 @@ internal class SwapTransferNotificationsFactory @Inject constructor() {
|
|||
state = transferState,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
fee = fee,
|
||||
onReduceByAmount = onReduceByAmount,
|
||||
onReduceToAmount = onReduceToAmount,
|
||||
onReduceByAmount = actions.onReduceByAmount,
|
||||
onReduceToAmount = actions.onReduceToAmount,
|
||||
)
|
||||
maybeAddNeedReserveToCreateAccountWarning(transferState)
|
||||
maybeAddExceedsBalanceNotification(transferState, onBuyClick)
|
||||
maybeAddExceedsBalanceNotification(transferState, onBuyClick = actions.openTokenDetailsScreen)
|
||||
addTronNetworkFeesNotification(
|
||||
cryptoCurrencyStatus = transferState.fromTokenInfo.swapCurrencyStatus.status,
|
||||
transferState = transferState,
|
||||
)
|
||||
maybeAddFeeUnreachableNotification(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
feeError = getFeeError,
|
||||
actions = actions,
|
||||
)
|
||||
}.toPersistentList()
|
||||
}
|
||||
|
||||
|
|
@ -194,4 +207,39 @@ internal class SwapTransferNotificationsFactory @Inject constructor() {
|
|||
onResetAnalyticsEvent = {},
|
||||
)
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.addTronNetworkFeesNotification(
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
transferState: SwapState.Transfer,
|
||||
) {
|
||||
val cryptoCurrency = cryptoCurrencyStatus.currency
|
||||
val isTronToken = cryptoCurrency is CryptoCurrency.Token && isTron(cryptoCurrency.network.rawId)
|
||||
val isVisible = isTronToken &&
|
||||
transferState.tronFeeNotificationShowCount <= TRON_FEE_NOTIFICATION_MAX_SHOW_COUNT
|
||||
|
||||
if (isVisible) {
|
||||
add(SwapNotificationUM.Info.TronTokenFee)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<NotificationUM>.maybeAddFeeUnreachableNotification(
|
||||
transferState: SwapState.Transfer,
|
||||
feeCryptoCurrencyStatus: CryptoCurrencyStatus?,
|
||||
feeError: GetFeeError?,
|
||||
actions: UiActions,
|
||||
) {
|
||||
feeCryptoCurrencyStatus ?: return
|
||||
addFeeUnreachableNotification(
|
||||
tokenStatus = transferState.fromTokenInfo.swapCurrencyStatus.status,
|
||||
coinStatus = feeCryptoCurrencyStatus,
|
||||
feeError = feeError,
|
||||
dustValue = transferState.currencyCheck?.dustValue,
|
||||
onReload = actions.onRetryClick,
|
||||
onClick = actions.openTokenDetailsScreen,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TRON_FEE_NOTIFICATION_MAX_SHOW_COUNT = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ import com.tangem.feature.swap.models.states.SwapNotificationUM
|
|||
import com.tangem.feature.swap.presentation.R
|
||||
import com.tangem.feature.swap.ui.SwapAmountScreenClickIntents
|
||||
import com.tangem.feature.swap.ui.swapSuccessNavigation
|
||||
import com.tangem.features.send.api.entity.FeeSelectorUM
|
||||
import com.tangem.features.send.api.utils.formatFooterFiatFee
|
||||
import com.tangem.features.send.api.utils.getTronTokenFeeSendingText
|
||||
import com.tangem.utils.extensions.orZero
|
||||
|
|
@ -52,12 +53,14 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
|
||||
private val iconConverter by lazy(::CryptoCurrencyToIconStateConverter)
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
fun createTransferState(
|
||||
actions: UiActions,
|
||||
transferState: SwapState.Transfer,
|
||||
uiStateHolder: SwapStateHolder,
|
||||
feePaidCryptoCurrencyStatus: CryptoCurrencyStatus?,
|
||||
fee: Fee?,
|
||||
feeError: FeeSelectorUM.Error?,
|
||||
): SwapStateHolder {
|
||||
val fromTokenSwapInfo = transferState.fromTokenInfo
|
||||
val isInsufficientBalance = transferState.isInsufficientBalance
|
||||
|
|
@ -67,9 +70,8 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = feePaidCryptoCurrencyStatus,
|
||||
fee = fee,
|
||||
onBuyClick = actions.openTokenDetailsScreen,
|
||||
onReduceByAmount = actions.onReduceByAmount,
|
||||
onReduceToAmount = actions.onReduceToAmount,
|
||||
actions = actions,
|
||||
getFeeError = feeError?.error,
|
||||
)
|
||||
return uiStateHolder.copy(
|
||||
sendCardData = createSendSwapCardState(
|
||||
|
|
@ -342,14 +344,14 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
feePaidCryptoCurrencyStatus: CryptoCurrencyStatus?,
|
||||
fee: Fee?,
|
||||
isTangemPayWithdrawal: Boolean,
|
||||
feeError: FeeSelectorUM.Error?,
|
||||
): SwapStateHolder {
|
||||
val notifications = notificationsFactory.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = feePaidCryptoCurrencyStatus,
|
||||
fee = fee,
|
||||
onBuyClick = actions.openTokenDetailsScreen,
|
||||
onReduceByAmount = actions.onReduceByAmount,
|
||||
onReduceToAmount = actions.onReduceToAmount,
|
||||
actions = actions,
|
||||
getFeeError = feeError?.error,
|
||||
)
|
||||
return uiStateHolder.copy(
|
||||
notifications = notifications,
|
||||
|
|
@ -395,7 +397,8 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
|
||||
val fiatAmountValue = tokenSwapInfo.amountFiat
|
||||
val status = dataState.fromSwapCurrencyStatus?.status ?: return null
|
||||
val fiatFeeValue = fee.amount.value
|
||||
val value = dataState.feePaidCryptoCurrency?.value
|
||||
val fiatFeeValue = value?.fiatRate?.multiply(fee.amount.value)
|
||||
val isFeeConvertibleToFiat = status.currency.network.hasFiatFeeRate
|
||||
|
||||
val fiatSendingValue = if (isFeeConvertibleToFiat) {
|
||||
|
|
@ -412,8 +415,11 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
}
|
||||
|
||||
val networkId = status.currency.network.id
|
||||
// When the fee is convertible to fiat, show the fiat-converted value; otherwise keep the raw
|
||||
// crypto fee amount — formatFooterFiatFee renders amount.value as crypto in the non-fiat case.
|
||||
val feeAmount = if (isFeeConvertibleToFiat) fee.amount.copy(value = fiatFeeValue) else fee.amount
|
||||
val fiatFee = formatFooterFiatFee(
|
||||
amount = fee.amount.copy(value = fiatFeeValue),
|
||||
amount = feeAmount,
|
||||
isFeeConvertibleToFiat = isFeeConvertibleToFiat,
|
||||
isFeeApproximate = isFeeApproximateUseCase(networkId = networkId, amountType = fee.amount.type),
|
||||
appCurrency = appCurrency,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ internal class SwapAmountScreenClickIntentsTest {
|
|||
onReceiveCardWarningClick = {},
|
||||
onSwapUIModeChange = {},
|
||||
onSwapTypeMenuOpened = {},
|
||||
onTronBannerShown = {},
|
||||
)
|
||||
|
||||
private val sut = SwapAmountScreenClickIntents(actions)
|
||||
|
|
|
|||
|
|
@ -12,9 +12,11 @@ import com.tangem.domain.models.wallet.UserWalletId
|
|||
import com.tangem.domain.swap.models.SwapCurrencyStatus
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyCheck
|
||||
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
import com.tangem.feature.swap.domain.models.SwapAmount
|
||||
import com.tangem.feature.swap.domain.models.ui.SwapState
|
||||
import com.tangem.feature.swap.domain.models.ui.TokenSwapInfo
|
||||
import com.tangem.feature.swap.models.UiActions
|
||||
import com.tangem.feature.swap.models.states.SwapNotificationUM
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
|
|
@ -28,6 +30,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
|
||||
private val sut = SwapTransferNotificationsFactory()
|
||||
|
||||
private val actions: UiActions = mockk(relaxed = true)
|
||||
|
||||
private val userWalletId = UserWalletId(stringValue = "deadbeef")
|
||||
private val coldWallet: UserWallet.Cold = mockk(relaxed = true) {
|
||||
every { walletId } returns userWalletId
|
||||
|
|
@ -41,9 +45,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result).isEmpty()
|
||||
|
|
@ -64,9 +67,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Solana.RentInfo>()).hasSize(1)
|
||||
|
|
@ -91,9 +93,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Error.ExistentialDeposit>()).hasSize(1)
|
||||
|
|
@ -114,9 +115,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Error.MinimumAmountError>()).hasSize(1)
|
||||
|
|
@ -133,9 +133,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Cardano.MinAdaValueCharged>()).hasSize(1)
|
||||
|
|
@ -157,9 +156,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Warning.FeeCoverageNotification>()).hasSize(1)
|
||||
|
|
@ -180,9 +178,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
val reserve = result.filterIsInstance<SwapNotificationUM.Warning.NeedReserveToCreateAccount>()
|
||||
|
|
@ -204,9 +201,8 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<SwapNotificationUM.Warning.ReduceAmount>()).hasSize(1)
|
||||
|
|
@ -226,14 +222,146 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = { _, _ -> },
|
||||
onReduceToAmount = {},
|
||||
onBuyClick = {},
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Error.TokenExceedsBalance>()).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN Tron token and show count within limit WHEN getNotifications THEN Tron network fees Info is added`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState(
|
||||
fromTokenInfo = buildTokenInfo(
|
||||
swapCurrencyStatus = buildTronTokenStatus(),
|
||||
amount = BigDecimal("10"),
|
||||
),
|
||||
tronFeeNotificationShowCount = TRON_FEE_NOTIFICATION_MAX_SHOW_COUNT,
|
||||
)
|
||||
|
||||
val result = sut.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<SwapNotificationUM.Info.TronTokenFee>()).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN Tron token but show count exceeds limit WHEN getNotifications THEN no Tron network fees Info`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState(
|
||||
fromTokenInfo = buildTokenInfo(
|
||||
swapCurrencyStatus = buildTronTokenStatus(),
|
||||
amount = BigDecimal("10"),
|
||||
),
|
||||
tronFeeNotificationShowCount = TRON_FEE_NOTIFICATION_MAX_SHOW_COUNT + 1,
|
||||
)
|
||||
|
||||
val result = sut.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<SwapNotificationUM.Info.TronTokenFee>()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN Tron coin (not token) WHEN getNotifications THEN no Tron network fees Info`() = runTest {
|
||||
val transferState = buildTransferState(
|
||||
fromTokenInfo = buildTokenInfo(
|
||||
swapCurrencyStatus = buildCoinStatus(rawNetworkId = "tron"),
|
||||
amount = BigDecimal("10"),
|
||||
),
|
||||
tronFeeNotificationShowCount = 0,
|
||||
)
|
||||
|
||||
val result = sut.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<SwapNotificationUM.Info.TronTokenFee>()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN UnknownError fee error and fee currency status WHEN getNotifications THEN NetworkFeeUnreachable is added`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState()
|
||||
val feeCryptoCurrencyStatus = buildCoinStatus().status
|
||||
|
||||
val result = sut.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
fee = null,
|
||||
actions = actions,
|
||||
getFeeError = GetFeeError.UnknownError,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Warning.NetworkFeeUnreachable>()).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN TronActivationError fee error and fee currency status WHEN getNotifications THEN TronAccountNotActivated is added`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState()
|
||||
val feeCryptoCurrencyStatus = buildCoinStatus().status
|
||||
|
||||
val result = sut.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = feeCryptoCurrencyStatus,
|
||||
fee = null,
|
||||
actions = actions,
|
||||
getFeeError = GetFeeError.BlockchainErrors.TronActivationError,
|
||||
)
|
||||
|
||||
val notifications = result.filterIsInstance<NotificationUM.Warning.TronAccountNotActivated>()
|
||||
assertThat(notifications).hasSize(1)
|
||||
assertThat(notifications.first().tokenName).isEqualTo(feeCryptoCurrencyStatus.currency.name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN fee error but null fee currency status WHEN getNotifications THEN no fee unreachable notification`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState()
|
||||
|
||||
val result = sut.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
actions = actions,
|
||||
getFeeError = GetFeeError.UnknownError,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Warning.NetworkFeeUnreachable>()).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN null fee error and fee currency status WHEN getNotifications THEN no fee unreachable notification`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState()
|
||||
|
||||
val result = sut.getNotifications(
|
||||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = buildCoinStatus().status,
|
||||
fee = null,
|
||||
actions = actions,
|
||||
getFeeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.filterIsInstance<NotificationUM.Warning.NetworkFeeUnreachable>()).isEmpty()
|
||||
}
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
private fun buildTransferState(
|
||||
fromTokenInfo: TokenSwapInfo = buildTokenInfo(buildCoinStatus()),
|
||||
|
|
@ -244,6 +372,7 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
minAdaValue: BigDecimal? = null,
|
||||
isFeeCoverage: Boolean = false,
|
||||
sendingAmount: BigDecimal = fromTokenInfo.tokenAmount.value,
|
||||
tronFeeNotificationShowCount: Int = 0,
|
||||
): SwapState.Transfer = SwapState.Transfer(
|
||||
userWallet = coldWallet,
|
||||
fromTokenInfo = fromTokenInfo,
|
||||
|
|
@ -255,6 +384,7 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
isAccountsMode = false,
|
||||
isFeeCoverage = isFeeCoverage,
|
||||
sendingAmount = sendingAmount,
|
||||
tronFeeNotificationShowCount = tronFeeNotificationShowCount,
|
||||
currencyCheck = currencyCheck,
|
||||
validationResult = validationResult,
|
||||
minAdaValue = minAdaValue,
|
||||
|
|
@ -326,4 +456,31 @@ internal class SwapTransferNotificationsFactoryTest {
|
|||
every { decimals } returns 18
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildTronTokenStatus(): SwapCurrencyStatus {
|
||||
val token = mockk<CryptoCurrency.Token>(relaxed = true) {
|
||||
every { id } returns mockk(relaxed = true)
|
||||
every { network } returns mockk(relaxed = true) {
|
||||
every { rawId } returns "tron"
|
||||
every { name } returns "Tron"
|
||||
}
|
||||
every { name } returns "Tether"
|
||||
every { symbol } returns "USDT"
|
||||
every { decimals } returns 6
|
||||
}
|
||||
val statusValue: CryptoCurrencyStatus.Loaded = mockk(relaxed = true) {
|
||||
every { amount } returns BigDecimal("100")
|
||||
every { fiatRate } returns BigDecimal.ONE
|
||||
every { fiatAmount } returns BigDecimal("100")
|
||||
}
|
||||
return SwapCurrencyStatus(
|
||||
userWallet = coldWallet,
|
||||
status = CryptoCurrencyStatus(currency = token, value = statusValue),
|
||||
account = Account.CryptoPortfolio.createMainAccount(userWalletId),
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TRON_FEE_NOTIFICATION_MAX_SHOW_COUNT = 3
|
||||
}
|
||||
}
|
||||
|
|
@ -59,9 +59,8 @@ internal class SwapTransferStateBuilderTest {
|
|||
transferState = any(),
|
||||
feeCryptoCurrencyStatus = any(),
|
||||
fee = any(),
|
||||
onReduceByAmount = any(),
|
||||
onReduceToAmount = any(),
|
||||
onBuyClick = any(),
|
||||
actions = any(),
|
||||
getFeeError = any(),
|
||||
)
|
||||
} returns persistentListOf()
|
||||
}
|
||||
|
|
@ -125,6 +124,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val portfolioAccount = fromCurrencyStatus.account as Account.CryptoPortfolio
|
||||
|
|
@ -156,9 +156,8 @@ internal class SwapTransferStateBuilderTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = any(),
|
||||
onReduceToAmount = any(),
|
||||
onBuyClick = any(),
|
||||
actions = any(),
|
||||
getFeeError = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -179,6 +178,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val sendType = (result.sendCardData as SwapCardState.SwapCardData).type as TransactionCardType.Inputtable
|
||||
|
|
@ -199,9 +199,8 @@ internal class SwapTransferStateBuilderTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = any(),
|
||||
onReduceToAmount = any(),
|
||||
onBuyClick = any(),
|
||||
actions = any(),
|
||||
getFeeError = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -223,6 +222,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val sendType = (result.sendCardData as SwapCardState.SwapCardData).type as TransactionCardType.Inputtable
|
||||
|
|
@ -243,9 +243,8 @@ internal class SwapTransferStateBuilderTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = any(),
|
||||
onReduceToAmount = any(),
|
||||
onBuyClick = any(),
|
||||
actions = any(),
|
||||
getFeeError = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -267,6 +266,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val portfolioAccount = toCurrencyStatus.account as Account.CryptoPortfolio
|
||||
|
|
@ -293,9 +293,8 @@ internal class SwapTransferStateBuilderTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
onReduceByAmount = any(),
|
||||
onReduceToAmount = any(),
|
||||
onBuyClick = any(),
|
||||
actions = any(),
|
||||
getFeeError = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -341,9 +340,8 @@ internal class SwapTransferStateBuilderTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
onReduceByAmount = any(),
|
||||
onReduceToAmount = any(),
|
||||
onBuyClick = any(),
|
||||
actions = any(),
|
||||
getFeeError = any(),
|
||||
)
|
||||
} returns persistentListOf()
|
||||
|
||||
|
|
@ -355,6 +353,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isTrue()
|
||||
|
|
@ -365,9 +364,8 @@ internal class SwapTransferStateBuilderTest {
|
|||
transferState = transferState,
|
||||
feeCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
onReduceByAmount = any(),
|
||||
onReduceToAmount = any(),
|
||||
onBuyClick = any(),
|
||||
actions = any(),
|
||||
getFeeError = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -390,6 +388,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = baseStateHolder(),
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = mockk(relaxed = true),
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val sendCard = result.sendCardData as SwapCardState.SwapCardData
|
||||
|
|
@ -424,6 +423,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = baseStateHolder(),
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val receiveCard = result.receiveCardData as SwapCardState.SwapCardData
|
||||
|
|
@ -451,6 +451,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = baseStateHolder(),
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val receiveCard = result.receiveCardData as SwapCardState.SwapCardData
|
||||
|
|
@ -481,6 +482,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = mockk(relaxed = true),
|
||||
isTangemPayWithdrawal = false,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
val receiveCard = result.receiveCardData as SwapCardState.SwapCardData
|
||||
|
|
@ -515,6 +517,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.transferFooter).isInstanceOf(TextReference.Combined::class.java)
|
||||
|
|
@ -538,20 +541,27 @@ internal class SwapTransferStateBuilderTest {
|
|||
isAccountsMode = false,
|
||||
)
|
||||
val statusWithNetwork = buildStatusWithNetwork(hasFiatFeeRate = true)
|
||||
val dataState = SwapProcessDataState(fromSwapCurrencyStatus = statusWithNetwork)
|
||||
// The fee's fiat value is derived from the fee-paid currency's fiat rate, not the raw crypto fee.
|
||||
val feePaidStatus = buildSwapCurrencyStatus(coldWallet)
|
||||
val feePaidRate = feePaidStatus.status.value.fiatRate!!
|
||||
val dataState = SwapProcessDataState(
|
||||
fromSwapCurrencyStatus = statusWithNetwork,
|
||||
feePaidCryptoCurrency = feePaidStatus.status,
|
||||
)
|
||||
val feeValue = BigDecimal("0.001")
|
||||
val fee = Fee.Common(
|
||||
amount = Amount(currencySymbol = "ETH", value = feeValue, decimals = 18),
|
||||
)
|
||||
val uiState = baseStateHolder()
|
||||
val appCurrency = transferState.appCurrency
|
||||
val expectedFiatSending = (fromAmount * QUOTE).plus(feeValue).format {
|
||||
val fiatFeeValue = feePaidRate.multiply(feeValue)
|
||||
val expectedFiatSending = (fromAmount * QUOTE).plus(fiatFeeValue).format {
|
||||
fiat(
|
||||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
)
|
||||
}
|
||||
val expectedFiatFee = feeValue.format {
|
||||
val expectedFiatFee = fiatFeeValue.format {
|
||||
fiat(
|
||||
fiatCurrencyCode = appCurrency.code,
|
||||
fiatCurrencySymbol = appCurrency.symbol,
|
||||
|
|
@ -566,6 +576,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.transferFooter).isEqualTo(
|
||||
|
|
@ -611,6 +622,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.transferFooter).isEqualTo(
|
||||
|
|
@ -741,6 +753,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
isTangemPayWithdrawal = true,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isTrue()
|
||||
|
|
@ -776,6 +789,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
isTangemPayWithdrawal = false,
|
||||
feeError = null,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isFalse()
|
||||
|
|
@ -924,6 +938,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
isAccountsMode = isAccountsMode,
|
||||
isFeeCoverage = isFeeCoverage,
|
||||
sendingAmount = toAmount,
|
||||
tronFeeNotificationShowCount = 0,
|
||||
isSendingAmountLoading = isSendingAmountLoading,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue