Updated on 2026-08-14
This commit is contained in:
parent
40f7df2c5d
commit
1ce3399a02
15 changed files with 890 additions and 65 deletions
|
|
@ -68,7 +68,7 @@ import com.tangem.domain.swap.models.PredefinedPercentAmount
|
|||
import com.tangem.domain.swap.models.SwapCurrencyStatus
|
||||
import com.tangem.domain.swap.usecase.CalculateAmountUseCase
|
||||
import com.tangem.domain.tangempay.GetTangemPayCustomerIdUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayWithdrawUseCase
|
||||
import com.tangem.domain.tangempay.TangemPayWithdrawWithSwapUseCase
|
||||
import com.tangem.domain.tokens.GetMinimumTransactionAmountSyncUseCase
|
||||
import com.tangem.domain.tokens.UpdateDelayedNetworkStatusUseCase
|
||||
import com.tangem.domain.transaction.error.GetFeeError
|
||||
|
|
@ -155,7 +155,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val urlOpener: UrlOpener,
|
||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val getPaymentAccountCryptoCurrencyStatusUseCase: GetPaymentAccountCryptoCurrencyStatusUseCase,
|
||||
private val tangemPayWithdrawUseCase: TangemPayWithdrawUseCase,
|
||||
private val tangemPayWithdrawWithSwapUseCase: TangemPayWithdrawWithSwapUseCase,
|
||||
private val isGaslessFeeSupportedForNetwork: IsGaslessFeeSupportedForNetwork,
|
||||
private val feeSelectorReloadTrigger: FeeSelectorReloadTrigger,
|
||||
private val getTangemPayCustomerIdUseCase: GetTangemPayCustomerIdUseCase,
|
||||
|
|
@ -738,14 +738,18 @@ internal class SwapModel @Inject constructor(
|
|||
feePaidCryptoCurrencyStatus = feePaidCryptoCurrency,
|
||||
fee = selectedFee,
|
||||
)
|
||||
feeSelectorRepository.state.value = FeeSelectorUM.Loading
|
||||
feeSelectorReloadTrigger.triggerUpdate()
|
||||
if (isTangemPayWithdrawal()) {
|
||||
refreshTransferUIStateIfNeeded()
|
||||
} else {
|
||||
feeSelectorRepository.state.value = FeeSelectorUM.Loading
|
||||
feeSelectorReloadTrigger.triggerUpdate()
|
||||
}
|
||||
}
|
||||
is SwapState.QuotesLoadedState, is SwapState.SwapError -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshTransferUIStateAfterFeeUpdateIfNeeded(
|
||||
private fun refreshTransferUIStateIfNeeded(
|
||||
feePaidCryptoCurrencyStatus: CryptoCurrencyStatus? = null,
|
||||
fee: Fee? = null,
|
||||
) {
|
||||
|
|
@ -774,6 +778,7 @@ internal class SwapModel @Inject constructor(
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = feePaidCryptoCurrencyStatus,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = isTangemPayWithdrawal(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1287,61 +1292,122 @@ internal class SwapModel @Inject constructor(
|
|||
val fromSwapCurrencyStatus = dataState.fromSwapCurrencyStatus
|
||||
val toSwapCurrencyStatus = dataState.toSwapCurrencyStatus
|
||||
val fee = (feeSelectorRepository.state.value as? FeeSelectorUM.Content)?.selectedFeeItem?.fee
|
||||
if (fromSwapCurrencyStatus == null || toSwapCurrencyStatus == null || fee == null) {
|
||||
TangemLogger.e("onTransferClick: missing currency status or fee, aborting")
|
||||
if (fromSwapCurrencyStatus == null || toSwapCurrencyStatus == null) {
|
||||
TangemLogger.e("onTransferClick: missing currency status, aborting")
|
||||
showAlert()
|
||||
return
|
||||
}
|
||||
val transferState = dataState.currentTransferState ?: return
|
||||
uiState = swapTransferStateBuilder.createTransferInProgressState(uiState)
|
||||
modelScope.launch(dispatchers.main) {
|
||||
swapTransferInteractor.sendTransfer(
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
sendingAmount = transferState.sendingAmount,
|
||||
fee = fee,
|
||||
transactionFeeResult = requireNotNull(getSelectedSwapFee()?.transactionFeeResult) {
|
||||
"It should be not null at this stage"
|
||||
},
|
||||
).fold(
|
||||
ifLeft = { error ->
|
||||
TangemLogger.e("onTransferClick: transfer failed: ${error.getAnalyticsDescription()}")
|
||||
when {
|
||||
isTangemPayWithdrawal() -> withdrawTangemPay(
|
||||
transferState = transferState,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
)
|
||||
fee != null -> sendTransfer(
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
transferState = transferState,
|
||||
fee = fee,
|
||||
)
|
||||
else -> {
|
||||
TangemLogger.e("onTransferClick: Illegal state, aborting")
|
||||
showAlert()
|
||||
},
|
||||
ifRight = { txHash ->
|
||||
val txUrl = getExplorerTransactionUrlUseCase(
|
||||
txHash = txHash,
|
||||
currency = fromSwapCurrencyStatus.currency,
|
||||
).getOrElse {
|
||||
TangemLogger.i("onTransferClick: tx hash explore not supported")
|
||||
""
|
||||
}
|
||||
updateWalletBalance()
|
||||
uiState = swapTransferStateBuilder.createSuccessState(
|
||||
uiState = uiState,
|
||||
dataState = dataState,
|
||||
appCurrency = selectedAppCurrencyFlow.value,
|
||||
isAccountsMode = isAccountsMode,
|
||||
txUrl = txUrl,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
fee = null,
|
||||
onExplorerClick = {
|
||||
if (txUrl.isNotEmpty()) {
|
||||
urlOpener.openUrl(txUrl)
|
||||
}
|
||||
},
|
||||
)
|
||||
router.replaceAll(SwapRoute.Success)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun withdrawTangemPay(
|
||||
transferState: SwapState.Transfer,
|
||||
toSwapCurrencyStatus: SwapCurrencyStatus,
|
||||
) {
|
||||
swapTransferInteractor.withdrawTangemPay(
|
||||
userWallet = transferState.userWallet,
|
||||
cryptoAmount = transferState.sendingAmount,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
)
|
||||
.onLeft { error ->
|
||||
TangemLogger.e(
|
||||
messageString = "onTransferClick: withdrawTangemPay failed: ${error.getAnalyticsDescription()}",
|
||||
)
|
||||
showAlert()
|
||||
}
|
||||
.onRight { result ->
|
||||
when (result) {
|
||||
WithdrawalResult.Cancelled -> startLoadingQuotesFromLastState()
|
||||
WithdrawalResult.Success -> updateTransferModeTangemPayState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTransferModeTangemPayState() {
|
||||
uiState = swapTransferStateBuilder.createTangemPayWithdrawalSuccessState(
|
||||
uiState = uiState,
|
||||
dataState = dataState,
|
||||
onExploreClick = {
|
||||
val txUrl = uiState.successState?.txUrl.orEmpty()
|
||||
if (txUrl.isNotEmpty()) {
|
||||
urlOpener.openUrl(txUrl)
|
||||
}
|
||||
},
|
||||
)
|
||||
router.replaceAll(SwapRoute.Success)
|
||||
}
|
||||
|
||||
private suspend fun sendTransfer(
|
||||
fromSwapCurrencyStatus: SwapCurrencyStatus,
|
||||
toSwapCurrencyStatus: SwapCurrencyStatus,
|
||||
transferState: SwapState.Transfer,
|
||||
fee: Fee,
|
||||
) {
|
||||
swapTransferInteractor.sendTransfer(
|
||||
fromSwapCurrencyStatus = fromSwapCurrencyStatus,
|
||||
toSwapCurrencyStatus = toSwapCurrencyStatus,
|
||||
sendingAmount = transferState.sendingAmount,
|
||||
fee = fee,
|
||||
transactionFeeResult = requireNotNull(getSelectedSwapFee()?.transactionFeeResult) {
|
||||
"It should be not null at this stage"
|
||||
},
|
||||
).fold(
|
||||
ifLeft = { error ->
|
||||
TangemLogger.e("onTransferClick: transfer failed: ${error.getAnalyticsDescription()}")
|
||||
showAlert()
|
||||
},
|
||||
ifRight = { txHash ->
|
||||
val txUrl = getExplorerTransactionUrlUseCase(
|
||||
txHash = txHash,
|
||||
currency = fromSwapCurrencyStatus.currency,
|
||||
).getOrElse {
|
||||
TangemLogger.i("onTransferClick: tx hash explore not supported")
|
||||
""
|
||||
}
|
||||
updateWalletBalance()
|
||||
uiState = swapTransferStateBuilder.createSuccessState(
|
||||
uiState = uiState,
|
||||
dataState = dataState,
|
||||
appCurrency = selectedAppCurrencyFlow.value,
|
||||
isAccountsMode = isAccountsMode,
|
||||
txUrl = txUrl,
|
||||
timestamp = System.currentTimeMillis(),
|
||||
fee = null,
|
||||
onExplorerClick = {
|
||||
if (txUrl.isNotEmpty()) {
|
||||
urlOpener.openUrl(txUrl)
|
||||
}
|
||||
},
|
||||
)
|
||||
router.replaceAll(SwapRoute.Success)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun processTangemPayWithdrawal(
|
||||
fromSwapCurrencyStatus: SwapCurrencyStatus,
|
||||
swapTransactionState: SwapTransactionState.TangemPayWithdrawalData,
|
||||
) {
|
||||
tangemPayWithdrawUseCase(
|
||||
tangemPayWithdrawWithSwapUseCase(
|
||||
userWallet = fromSwapCurrencyStatus.userWallet,
|
||||
cryptoAmount = swapTransactionState.cryptoAmount,
|
||||
cryptoCurrencyId = swapTransactionState.cryptoCurrencyId,
|
||||
|
|
@ -2224,7 +2290,7 @@ internal class SwapModel @Inject constructor(
|
|||
|
||||
if (newState is FeeSelectorUM.Error) {
|
||||
TangemLogger.e("loadFee: ${newState.error}, isHidden = true")
|
||||
refreshTransferUIStateAfterFeeUpdateIfNeeded()
|
||||
refreshTransferUIStateIfNeeded()
|
||||
uiState = stateBuilder.createFeeErrorState(
|
||||
uiStateHolder = uiState,
|
||||
quoteModel = dataState.getCurrentLoadedSwapState() ?: return,
|
||||
|
|
@ -2234,7 +2300,7 @@ internal class SwapModel @Inject constructor(
|
|||
modelScope.launch { forceUpdateState.emit(newState.copy(isHidden = true)) }
|
||||
return
|
||||
}
|
||||
refreshTransferUIStateAfterFeeUpdateIfNeeded(
|
||||
refreshTransferUIStateIfNeeded(
|
||||
feePaidCryptoCurrencyStatus = dataState.feePaidCryptoCurrency,
|
||||
fee = (newState as? FeeSelectorUM.Content)?.selectedFeeItem?.fee,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -210,6 +210,9 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [isTangemPayWithdrawal] - if true - Tangem pay withdrawal done with no fee, skip fee nullability check
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
fun updateTransferButtonEnableState(
|
||||
dataState: SwapProcessDataState,
|
||||
|
|
@ -218,6 +221,7 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
uiStateHolder: SwapStateHolder,
|
||||
feePaidCryptoCurrencyStatus: CryptoCurrencyStatus?,
|
||||
fee: Fee?,
|
||||
isTangemPayWithdrawal: Boolean,
|
||||
): SwapStateHolder {
|
||||
val notifications = notificationsFactory.getNotifications(
|
||||
transferState = transferState,
|
||||
|
|
@ -229,7 +233,7 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
return uiStateHolder.copy(
|
||||
notifications = notifications,
|
||||
swapButton = uiStateHolder.swapButton.copy(
|
||||
isEnabled = getTransferButtonEnabled(notifications, fee),
|
||||
isEnabled = getTransferButtonEnabled(notifications, fee, isTangemPayWithdrawal),
|
||||
),
|
||||
transferFooter = getSendingFooterText(
|
||||
dataState = dataState,
|
||||
|
|
@ -240,8 +244,12 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun getTransferButtonEnabled(notifications: ImmutableList<NotificationUM>, fee: Fee?): Boolean {
|
||||
return fee != null && notifications.none { notification ->
|
||||
private fun getTransferButtonEnabled(
|
||||
notifications: ImmutableList<NotificationUM>,
|
||||
fee: Fee?,
|
||||
isTangemPayWithdrawal: Boolean,
|
||||
): Boolean {
|
||||
return (fee != null || isTangemPayWithdrawal) && notifications.none { notification ->
|
||||
notification is SwapNotificationUM.Error || notification is NotificationUM.Error ||
|
||||
notification is SwapNotificationUM.Warning.ExpressErrorWarning ||
|
||||
notification is SwapNotificationUM.Warning.ExpressGeneralError ||
|
||||
|
|
@ -373,4 +381,52 @@ internal class SwapTransferStateBuilder @Inject constructor(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createTangemPayWithdrawalSuccessState(
|
||||
uiState: SwapStateHolder,
|
||||
dataState: SwapProcessDataState,
|
||||
onExploreClick: () -> Unit,
|
||||
): SwapStateHolder {
|
||||
val fromSwapCurrencyStatus = requireNotNull(dataState.fromSwapCurrencyStatus)
|
||||
val toSwapCurrencyStatus = requireNotNull(dataState.toSwapCurrencyStatus)
|
||||
val transferState = requireNotNull(dataState.currentTransferState)
|
||||
val amountValue = transferState.sendingAmount
|
||||
|
||||
val fiatAmount = getFormattedFiatAmount(
|
||||
appCurrency = transferState.appCurrency,
|
||||
amount = fromSwapCurrencyStatus.status.value.fiatRate?.multiply(amountValue),
|
||||
)
|
||||
|
||||
return uiState.copy(
|
||||
successState = SwapSuccessStateHolder(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
txUrl = "",
|
||||
providerName = stringReference(""),
|
||||
providerType = stringReference(""),
|
||||
shouldShowStatusButton = false,
|
||||
isTransferMode = true,
|
||||
providerIcon = "",
|
||||
rate = TextReference.EMPTY,
|
||||
fee = null,
|
||||
fromTitle = getCardAccountTitle(
|
||||
account = fromSwapCurrencyStatus.account,
|
||||
isAccountsMode = transferState.isAccountsMode,
|
||||
isFromCard = true,
|
||||
),
|
||||
toTitle = getCardAccountTitle(
|
||||
account = toSwapCurrencyStatus.account,
|
||||
isAccountsMode = transferState.isAccountsMode,
|
||||
isFromCard = false,
|
||||
),
|
||||
fromTokenAmount = stringReference(amountValue.toString()),
|
||||
toTokenAmount = stringReference(amountValue.toString()),
|
||||
fromTokenFiatAmount = fiatAmount,
|
||||
toTokenFiatAmount = fiatAmount,
|
||||
fromTokenIconState = iconConverter.convert(fromSwapCurrencyStatus.status),
|
||||
toTokenIconState = iconConverter.convert(toSwapCurrencyStatus.status),
|
||||
onExploreButtonClick = onExploreClick,
|
||||
onStatusButtonClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -317,6 +317,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isTrue()
|
||||
|
|
@ -358,6 +359,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
)
|
||||
|
||||
assertThat(result.transferFooter).isInstanceOf(TextReference.Combined::class.java)
|
||||
|
|
@ -408,6 +410,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
)
|
||||
|
||||
assertThat(result.transferFooter).isEqualTo(
|
||||
|
|
@ -452,6 +455,7 @@ internal class SwapTransferStateBuilderTest {
|
|||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = fee,
|
||||
isTangemPayWithdrawal = false,
|
||||
)
|
||||
|
||||
assertThat(result.transferFooter).isEqualTo(
|
||||
|
|
@ -518,6 +522,139 @@ internal class SwapTransferStateBuilderTest {
|
|||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN null fee but tangem pay withdrawal WHEN updateTransferButtonEnableState THEN swap button is enabled with no footer`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState(
|
||||
fromAmount = BigDecimal("1"),
|
||||
toAmount = BigDecimal("1"),
|
||||
isAccountsMode = false,
|
||||
)
|
||||
val dataState = SwapProcessDataState()
|
||||
val uiState = baseStateHolder().copy(
|
||||
swapButton = SwapButton(
|
||||
walletInteractionIcon = null,
|
||||
isEnabled = false,
|
||||
mode = SwapButton.Mode.TRANSFER,
|
||||
onClick = {},
|
||||
),
|
||||
)
|
||||
|
||||
val result = sut.updateTransferButtonEnableState(
|
||||
dataState = dataState,
|
||||
transferState = transferState,
|
||||
actions = actions,
|
||||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
isTangemPayWithdrawal = true,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isTrue()
|
||||
assertThat(result.swapButton.mode).isEqualTo(SwapButton.Mode.TRANSFER)
|
||||
// fee is null → footer is omitted, but the button stays enabled because it is a Tangem Pay withdrawal
|
||||
assertThat(result.transferFooter).isNull()
|
||||
assertThat(result.notifications).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN null fee and not tangem pay withdrawal WHEN updateTransferButtonEnableState THEN swap button stays disabled`() =
|
||||
runTest {
|
||||
val transferState = buildTransferState(
|
||||
fromAmount = BigDecimal("1"),
|
||||
toAmount = BigDecimal("1"),
|
||||
isAccountsMode = false,
|
||||
)
|
||||
val dataState = SwapProcessDataState()
|
||||
val uiState = baseStateHolder().copy(
|
||||
swapButton = SwapButton(
|
||||
walletInteractionIcon = null,
|
||||
isEnabled = false,
|
||||
mode = SwapButton.Mode.TRANSFER,
|
||||
onClick = {},
|
||||
),
|
||||
)
|
||||
|
||||
val result = sut.updateTransferButtonEnableState(
|
||||
dataState = dataState,
|
||||
transferState = transferState,
|
||||
actions = actions,
|
||||
uiStateHolder = uiState,
|
||||
feePaidCryptoCurrencyStatus = null,
|
||||
fee = null,
|
||||
isTangemPayWithdrawal = false,
|
||||
)
|
||||
|
||||
assertThat(result.swapButton.isEnabled).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN transfer dataState WHEN createTangemPayWithdrawalSuccessState THEN feeless transfer success holder is built`() {
|
||||
val sendingAmount = BigDecimal("1.5")
|
||||
val transferState = buildTransferState(
|
||||
fromAmount = sendingAmount,
|
||||
toAmount = sendingAmount,
|
||||
isAccountsMode = true,
|
||||
)
|
||||
val dataState = SwapProcessDataState(
|
||||
fromSwapCurrencyStatus = fromCurrencyStatus,
|
||||
toSwapCurrencyStatus = toCurrencyStatus,
|
||||
currentTransferState = transferState,
|
||||
)
|
||||
val onExploreClick = {}
|
||||
val appCurrency = transferState.appCurrency
|
||||
val expectedFiat = stringReference(
|
||||
fromCurrencyStatus.status.value.fiatRate!!.multiply(sendingAmount).format {
|
||||
fiat(fiatCurrencyCode = appCurrency.code, fiatCurrencySymbol = appCurrency.symbol)
|
||||
},
|
||||
)
|
||||
|
||||
val before = System.currentTimeMillis()
|
||||
val result = sut.createTangemPayWithdrawalSuccessState(
|
||||
uiState = baseStateHolder(),
|
||||
dataState = dataState,
|
||||
onExploreClick = onExploreClick,
|
||||
)
|
||||
val after = System.currentTimeMillis()
|
||||
|
||||
val success = requireNotNull(result.successState)
|
||||
assertThat(success.isTransferMode).isTrue()
|
||||
assertThat(success.shouldShowStatusButton).isFalse()
|
||||
assertThat(success.fee).isNull()
|
||||
assertThat(success.txUrl).isEmpty()
|
||||
assertThat(success.providerName).isEqualTo(stringReference(""))
|
||||
assertThat(success.providerType).isEqualTo(stringReference(""))
|
||||
assertThat(success.providerIcon).isEmpty()
|
||||
assertThat(success.rate).isEqualTo(TextReference.EMPTY)
|
||||
assertThat(success.timestamp).isAtLeast(before)
|
||||
assertThat(success.timestamp).isAtMost(after)
|
||||
assertThat(success.fromTokenAmount).isEqualTo(stringReference(sendingAmount.toString()))
|
||||
assertThat(success.toTokenAmount).isEqualTo(stringReference(sendingAmount.toString()))
|
||||
assertThat(success.fromTokenFiatAmount).isEqualTo(expectedFiat)
|
||||
assertThat(success.toTokenFiatAmount).isEqualTo(expectedFiat)
|
||||
assertThat(success.fromTokenIconState).isEqualTo(fromIcon)
|
||||
assertThat(success.toTokenIconState).isEqualTo(toIcon)
|
||||
assertThat(success.onExploreButtonClick).isEqualTo(onExploreClick)
|
||||
|
||||
val portfolioAccount = fromCurrencyStatus.account as Account.CryptoPortfolio
|
||||
val expectedIcon = CryptoPortfolioIconConverter.convert(portfolioAccount.icon)
|
||||
val expectedName = portfolioAccount.accountName.toUM().value
|
||||
assertThat(success.fromTitle).isEqualTo(
|
||||
AccountTitleUM.Account(
|
||||
prefixText = resourceReference(R.string.swapping_from_account_title),
|
||||
name = expectedName,
|
||||
icon = expectedIcon,
|
||||
),
|
||||
)
|
||||
assertThat(success.toTitle).isEqualTo(
|
||||
AccountTitleUM.Account(
|
||||
prefixText = resourceReference(R.string.swapping_to_account_title),
|
||||
name = expectedName,
|
||||
icon = expectedIcon,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun assertSharedCardShape(
|
||||
result: SwapStateHolder,
|
||||
transferState: SwapState.Transfer,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue