Updated on 2026-08-14
This commit is contained in:
parent
4197574fca
commit
7f587d170c
25 changed files with 348 additions and 571 deletions
|
|
@ -15,7 +15,7 @@ data class OnrampOffer(
|
|||
)
|
||||
|
||||
enum class OnrampOfferAdvantages {
|
||||
Default, BestRate, Fastest,
|
||||
Default, BestRate, Fastest, GreatRate,
|
||||
}
|
||||
|
||||
enum class OnrampOfferCategory {
|
||||
|
|
|
|||
|
|
@ -18,31 +18,73 @@ enum class PaymentMethodType(val id: String?) {
|
|||
OTHER(id = null),
|
||||
;
|
||||
|
||||
// TODO will be removed in next request [REDACTED_TASK_KEY]
|
||||
@Suppress("MagicNumber")
|
||||
fun getPriority(isGooglePayEnabled: Boolean): Int = if (isGooglePayEnabled) {
|
||||
when (this) {
|
||||
GOOGLE_PAY -> 0
|
||||
CARD -> 1
|
||||
SEPA -> 2
|
||||
REVOLUT_PAY -> 3
|
||||
REVOLUT_PAY -> 2
|
||||
SEPA -> 3
|
||||
OTHER -> 4
|
||||
}
|
||||
} else {
|
||||
when (this) {
|
||||
CARD -> 0
|
||||
GOOGLE_PAY -> 1
|
||||
CARD -> 2
|
||||
REVOLUT_PAY -> 1
|
||||
SEPA -> 2
|
||||
REVOLUT_PAY -> 3
|
||||
OTHER -> 3
|
||||
GOOGLE_PAY -> 4
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get priority regardless of real speed. By business logic.
|
||||
*/
|
||||
@Suppress("MagicNumber")
|
||||
fun getPriorityForMethod(isGooglePayEnabled: Boolean): Int = if (isGooglePayEnabled) {
|
||||
when (this) {
|
||||
GOOGLE_PAY -> 0
|
||||
CARD -> 1
|
||||
REVOLUT_PAY -> 2
|
||||
SEPA -> 3
|
||||
OTHER -> 4
|
||||
}
|
||||
} else {
|
||||
when (this) {
|
||||
CARD -> 2
|
||||
REVOLUT_PAY -> 1
|
||||
SEPA -> 2
|
||||
OTHER -> 3
|
||||
GOOGLE_PAY -> 4
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun getPriorityBySpeed(isGooglePayEnabled: Boolean): Int = if (isGooglePayEnabled) {
|
||||
when (this) {
|
||||
GOOGLE_PAY -> 0
|
||||
REVOLUT_PAY -> 1
|
||||
CARD -> 2
|
||||
SEPA -> 3
|
||||
OTHER -> 4
|
||||
}
|
||||
} else {
|
||||
when (this) {
|
||||
REVOLUT_PAY -> 0
|
||||
CARD -> 1
|
||||
SEPA -> 2
|
||||
OTHER -> 3
|
||||
GOOGLE_PAY -> 4
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* BE AWARE. HARDCODED. Returns the speed of transaction for payment method type.
|
||||
*/
|
||||
fun getProcessingSpeed(): PaymentSpeed = when (this) {
|
||||
REVOLUT_PAY,
|
||||
GOOGLE_PAY,
|
||||
REVOLUT_PAY,
|
||||
-> PaymentSpeed.Instant
|
||||
CARD -> PaymentSpeed.FewMin
|
||||
SEPA -> PaymentSpeed.FewDays
|
||||
|
|
|
|||
|
|
@ -47,7 +47,12 @@ class GetOnrampOffersUseCase(
|
|||
if (validQuotes.isEmpty()) return emptyList()
|
||||
|
||||
val isGooglePayAvailable = settingsRepository.isGooglePayAvailability()
|
||||
val bestRateQuote = validQuotes.maxWithOrNull(compareOffersByRateSpeedAndPriority(isGooglePayAvailable))
|
||||
val bestRateQuote = validQuotes.maxWithOrNull(
|
||||
compareOffersByRateSpeedAndPriority(
|
||||
isGooglePayAvailable = isGooglePayAvailable,
|
||||
isSepaPrioritized = true,
|
||||
),
|
||||
)
|
||||
val bestRate = bestRateQuote?.toAmount?.value
|
||||
|
||||
val offers = validQuotes.map { quote ->
|
||||
|
|
@ -71,8 +76,9 @@ class GetOnrampOffersUseCase(
|
|||
val lastTransaction = transactions.maxByOrNull { it.timestamp } ?: return null
|
||||
|
||||
return offers.find { offer ->
|
||||
offer.quote.provider.id == lastTransaction.providerType &&
|
||||
offer.quote.paymentMethod.id == lastTransaction.paymentMethod
|
||||
offer.quote.provider.info.name == lastTransaction.providerName &&
|
||||
offer.quote.paymentMethod.name == lastTransaction.paymentMethod &&
|
||||
lastTransaction.status.isTerminal
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,14 +89,14 @@ class GetOnrampOffersUseCase(
|
|||
private fun findFastestOffer(offers: List<OnrampOffer>, isGooglePayAvailable: Boolean): OnrampOffer? {
|
||||
val instantOffers = offers.filter { it.quote.paymentMethod.type.isInstant() }
|
||||
return if (instantOffers.isNotEmpty()) {
|
||||
instantOffers.maxWithOrNull(offerComparator(isGooglePayAvailable))
|
||||
instantOffers.maxWithOrNull(fastestOfferComparator(isGooglePayAvailable))
|
||||
} else {
|
||||
val offersBySpeed = offers.groupBy { offer ->
|
||||
offer.quote.paymentMethod.type.getProcessingSpeed().speed
|
||||
}
|
||||
val fastestSpeed = offersBySpeed.keys.minOrNull() ?: return null
|
||||
val fastestOffers = offersBySpeed[fastestSpeed] ?: return null
|
||||
fastestOffers.maxWithOrNull(offerComparator(isGooglePayAvailable))
|
||||
fastestOffers.maxWithOrNull(fastestOfferComparator(isGooglePayAvailable))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +105,10 @@ class GetOnrampOffersUseCase(
|
|||
is OnrampQuote.Data -> {
|
||||
when (val quote2 = offer2.quote) {
|
||||
is OnrampQuote.Data -> {
|
||||
compareOffersByRateSpeedAndPriority(isGooglePayAvailable).compare(quote1, quote2)
|
||||
compareOffersByRateSpeedAndPriority(
|
||||
isGooglePayAvailable = isGooglePayAvailable,
|
||||
isSepaPrioritized = true,
|
||||
).compare(quote1, quote2)
|
||||
}
|
||||
else -> 1
|
||||
}
|
||||
|
|
@ -108,6 +117,30 @@ class GetOnrampOffersUseCase(
|
|||
}
|
||||
}
|
||||
|
||||
private fun fastestOfferComparator(isGooglePayAvailable: Boolean): Comparator<OnrampOffer> =
|
||||
Comparator { offer1, offer2 ->
|
||||
when (val quote1 = offer1.quote) {
|
||||
is OnrampQuote.Data -> {
|
||||
when (val quote2 = offer2.quote) {
|
||||
is OnrampQuote.Data -> {
|
||||
// For fastest offer, first compare by priority of speed
|
||||
val priorityComparison = quote2.paymentMethod.type.getPriorityBySpeed(isGooglePayAvailable)
|
||||
.compareTo(quote1.paymentMethod.type.getPriorityBySpeed(isGooglePayAvailable))
|
||||
|
||||
// If priorities are equal, compare by rate
|
||||
if (priorityComparison != 0) {
|
||||
priorityComparison
|
||||
} else {
|
||||
quote1.toAmount.value.compareTo(quote2.toAmount.value)
|
||||
}
|
||||
}
|
||||
else -> 1
|
||||
}
|
||||
}
|
||||
else -> -1
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildOffersBlocks(
|
||||
recentOffer: OnrampOffer?,
|
||||
bestRateOffer: OnrampOffer?,
|
||||
|
|
@ -143,7 +176,7 @@ class GetOnrampOffersUseCase(
|
|||
)
|
||||
}
|
||||
|
||||
if (recommendedOffers.isNotEmpty() && hasOnlyOneMethodAndProvider(allOffers).not()) {
|
||||
if (recommendedOffers.isNotEmpty()) {
|
||||
add(
|
||||
OnrampOffersBlock(
|
||||
category = OnrampOfferCategory.Recommended,
|
||||
|
|
@ -161,10 +194,10 @@ class GetOnrampOffersUseCase(
|
|||
fastestOffer: OnrampOffer?,
|
||||
): OnrampOfferAdvantages {
|
||||
if (isSameOffer(recentOffer, bestRateOffer) && isSameOffer(recentOffer, fastestOffer)) {
|
||||
return OnrampOfferAdvantages.BestRate
|
||||
return OnrampOfferAdvantages.GreatRate
|
||||
}
|
||||
if (isSameOffer(recentOffer, bestRateOffer)) {
|
||||
return OnrampOfferAdvantages.BestRate
|
||||
return OnrampOfferAdvantages.GreatRate
|
||||
}
|
||||
if (isSameOffer(recentOffer, fastestOffer)) {
|
||||
return OnrampOfferAdvantages.Fastest
|
||||
|
|
@ -182,7 +215,7 @@ class GetOnrampOffersUseCase(
|
|||
bestRateOffer?.let { offer ->
|
||||
add(
|
||||
offer.copy(
|
||||
advantages = OnrampOfferAdvantages.BestRate,
|
||||
advantages = OnrampOfferAdvantages.GreatRate,
|
||||
rateDif = null,
|
||||
),
|
||||
)
|
||||
|
|
@ -191,7 +224,7 @@ class GetOnrampOffersUseCase(
|
|||
if (bestRateOffer != null && !isSameOffer(bestRateOffer, recentOffer)) {
|
||||
add(
|
||||
bestRateOffer.copy(
|
||||
advantages = OnrampOfferAdvantages.BestRate,
|
||||
advantages = OnrampOfferAdvantages.GreatRate,
|
||||
rateDif = null,
|
||||
),
|
||||
)
|
||||
|
|
@ -211,12 +244,6 @@ class GetOnrampOffersUseCase(
|
|||
}
|
||||
}
|
||||
|
||||
private fun hasOnlyOneMethodAndProvider(offers: List<OnrampOffer>): Boolean {
|
||||
val uniquePaymentMethods = offers.map { it.quote.paymentMethod.id }.distinct()
|
||||
val uniqueProviders = offers.map { it.quote.provider.id }.distinct()
|
||||
return uniquePaymentMethods.size == 1 && uniqueProviders.size == 1
|
||||
}
|
||||
|
||||
private fun isSameOffer(offer1: OnrampOffer?, offer2: OnrampOffer?): Boolean {
|
||||
if (offer1 == null || offer2 == null) return false
|
||||
return offer1.quote.provider.id == offer2.quote.provider.id &&
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class GetOnrampPaymentMethodsUseCase(
|
|||
|
||||
repository.getAvailablePaymentMethods()
|
||||
.toList()
|
||||
.sortedBy { it.type.getPriority(isGooglePayAvailable) }
|
||||
.sortedBy { it.type.getPriorityBySpeed(isGooglePayAvailable) }
|
||||
.toSet()
|
||||
}.mapLeft(errorResolver::resolve)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class GetOnrampQuotesUseCase(
|
|||
|
||||
quotes.groupBy { it.paymentMethod.type }
|
||||
.asSequence()
|
||||
.sortedBy { it.key.getPriority(isGooglePayAvailable) }
|
||||
.sortedBy { it.key.getPriorityBySpeed(isGooglePayAvailable) }
|
||||
.sortByRate()
|
||||
.toList()
|
||||
.flatten()
|
||||
|
|
@ -53,7 +53,6 @@ class GetOnrampQuotesUseCase(
|
|||
when (val error = it.error) {
|
||||
is OnrampError.AmountError.TooSmallError -> it.fromAmount.value - error.requiredAmount
|
||||
is OnrampError.AmountError.TooBigError -> error.requiredAmount - it.fromAmount.value
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
package com.tangem.domain.onramp
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.left
|
||||
import arrow.core.right
|
||||
import com.tangem.domain.onramp.model.OnrampQuote
|
||||
import com.tangem.domain.onramp.model.error.OnrampError
|
||||
import com.tangem.domain.onramp.repositories.OnrampErrorResolver
|
||||
import com.tangem.domain.onramp.repositories.OnrampRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.math.BigDecimal
|
||||
import java.util.Comparator
|
||||
|
||||
class GetOnrampV2QuotesUseCase(
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val repository: OnrampRepository,
|
||||
private val errorResolver: OnrampErrorResolver,
|
||||
) {
|
||||
|
||||
operator fun invoke(): Flow<Either<OnrampError, List<OnrampQuote>>> {
|
||||
return repository.getQuotes()
|
||||
.map<List<OnrampQuote>, Either<OnrampError, List<OnrampQuote>>> { quotes ->
|
||||
val isGooglePayAvailable = settingsRepository.isGooglePayAvailability()
|
||||
quotes.sortedWith(
|
||||
Comparator.comparing<OnrampQuote, SortableBigDecimalWrapper> { quote ->
|
||||
getQuoteSortPriority(quote)
|
||||
}
|
||||
.thenComparingInt { quote ->
|
||||
quote.paymentMethod.type.getPriority(isGooglePayAvailable)
|
||||
},
|
||||
).right()
|
||||
}
|
||||
.catch {
|
||||
emit(errorResolver.resolve(it).left())
|
||||
}
|
||||
}
|
||||
|
||||
private class SortableBigDecimalWrapper(
|
||||
val value: BigDecimal?,
|
||||
val negateForSort: Boolean = false,
|
||||
) : Comparable<SortableBigDecimalWrapper> {
|
||||
override fun compareTo(other: SortableBigDecimalWrapper): Int {
|
||||
return when {
|
||||
value == null && other.value == null -> 0
|
||||
value == null -> 1
|
||||
other.value == null -> -1
|
||||
else -> {
|
||||
val thisValue = if (negateForSort) value.negate() else value
|
||||
val otherValue = if (other.negateForSort) other.value.negate() else other.value
|
||||
thisValue.compareTo(otherValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getQuoteSortPriority(quote: OnrampQuote): SortableBigDecimalWrapper {
|
||||
return when (quote) {
|
||||
is OnrampQuote.Data -> SortableBigDecimalWrapper(quote.toAmount.value, negateForSort = true)
|
||||
is OnrampQuote.Error -> SortableBigDecimalWrapper(null)
|
||||
is OnrampQuote.AmountError -> {
|
||||
when (val error = quote.error) {
|
||||
is OnrampError.AmountError.TooSmallError ->
|
||||
SortableBigDecimalWrapper((quote.fromAmount.value - error.requiredAmount).abs())
|
||||
is OnrampError.AmountError.TooBigError ->
|
||||
SortableBigDecimalWrapper((error.requiredAmount - quote.fromAmount.value).abs())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,42 @@
|
|||
package com.tangem.domain.onramp.utils
|
||||
|
||||
import com.tangem.domain.onramp.model.OnrampQuote
|
||||
import com.tangem.domain.onramp.model.PaymentMethodType
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal fun calculateRateDif(currentTokenRate: BigDecimal, bestRate: BigDecimal?): BigDecimal? {
|
||||
if (bestRate == null) return null
|
||||
return BigDecimal.ONE - currentTokenRate / bestRate
|
||||
if (currentTokenRate > bestRate) return null
|
||||
|
||||
val rateDif = BigDecimal.ONE - currentTokenRate / bestRate
|
||||
return if (rateDif >= BigDecimal("0.01")) rateDif else null
|
||||
}
|
||||
|
||||
internal fun compareOffersByRateSpeedAndPriority(isGooglePayAvailable: Boolean): Comparator<OnrampQuote.Data> {
|
||||
/**
|
||||
* @param isSepaPrioritized Sepa provider should be prioritized over all offers no matter what.
|
||||
*/
|
||||
internal fun compareOffersByRateSpeedAndPriority(
|
||||
isGooglePayAvailable: Boolean,
|
||||
isSepaPrioritized: Boolean = false,
|
||||
): Comparator<OnrampQuote.Data> {
|
||||
return Comparator { quote1, quote2 ->
|
||||
val rateComparison = quote1
|
||||
.toAmount
|
||||
.value
|
||||
.compareTo(quote2.toAmount.value)
|
||||
if (isSepaPrioritized) {
|
||||
val isQuote1Sepa = quote1.paymentMethod.type == PaymentMethodType.SEPA
|
||||
val isQuote2Sepa = quote2.paymentMethod.type == PaymentMethodType.SEPA
|
||||
|
||||
if (isQuote1Sepa && !isQuote2Sepa) return@Comparator 1
|
||||
if (!isQuote1Sepa && isQuote2Sepa) return@Comparator -1
|
||||
}
|
||||
|
||||
val rateComparison = quote1.toAmount.value.compareTo(quote2.toAmount.value)
|
||||
if (rateComparison != 0) return@Comparator rateComparison
|
||||
|
||||
val speedComparison =
|
||||
quote2
|
||||
.paymentMethod
|
||||
.type
|
||||
.getProcessingSpeed()
|
||||
.speed
|
||||
quote2.paymentMethod.type.getProcessingSpeed().speed
|
||||
.compareTo(quote1.paymentMethod.type.getProcessingSpeed().speed)
|
||||
if (speedComparison != 0) return@Comparator speedComparison
|
||||
|
||||
quote1
|
||||
.paymentMethod
|
||||
.type
|
||||
.getPriority(isGooglePayAvailable)
|
||||
.compareTo(quote2.paymentMethod.type.getPriority(isGooglePayAvailable))
|
||||
quote2.paymentMethod.type.getPriorityBySpeed(isGooglePayAvailable)
|
||||
.compareTo(quote1.paymentMethod.type.getPriorityBySpeed(isGooglePayAvailable))
|
||||
}
|
||||
}
|
||||
|
|
@ -67,8 +67,8 @@ class GetOnrampOffersUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `invoke should return offers blocks with recent and recommended categories`() = runTest {
|
||||
val paymentMethod1 = createMockPaymentMethod("card", "Card", isInstant = true)
|
||||
val paymentMethod2 = createMockPaymentMethod("bank", "Bank Transfer", isInstant = false)
|
||||
val paymentMethod1 = createMockPaymentMethod("card", "Card", PaymentMethodType.GOOGLE_PAY)
|
||||
val paymentMethod2 = createMockPaymentMethod("bank", "Bank Transfer", PaymentMethodType.CARD)
|
||||
val provider1 = createMockProvider("provider1", "Provider 1")
|
||||
val provider2 = createMockProvider("provider2", "Provider 2")
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ class GetOnrampOffersUseCaseTest {
|
|||
)
|
||||
|
||||
val transactions = listOf(
|
||||
createMockTransaction("provider1", "card", 1000L),
|
||||
createMockTransaction("Provider 1", "Card", 1000L),
|
||||
)
|
||||
|
||||
coEvery { settingsRepository.isGooglePayAvailability() } returns false
|
||||
|
|
@ -105,7 +105,7 @@ class GetOnrampOffersUseCaseTest {
|
|||
Truth.assertThat(recommendedBlock).isNotNull()
|
||||
Truth.assertThat(recommendedBlock?.offers).hasSize(1)
|
||||
Truth.assertThat(recommendedBlock?.offers?.first()?.advantages)
|
||||
.isEqualTo(OnrampOfferAdvantages.BestRate)
|
||||
.isEqualTo(OnrampOfferAdvantages.GreatRate)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -113,8 +113,8 @@ class GetOnrampOffersUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `invoke should find best rate offer correctly`() = runTest {
|
||||
val paymentMethod1 = createMockPaymentMethod("card", "Card", isInstant = false)
|
||||
val paymentMethod2 = createMockPaymentMethod("bank", "Bank Transfer", isInstant = false)
|
||||
val paymentMethod1 = createMockPaymentMethod("card", "Card", PaymentMethodType.CARD)
|
||||
val paymentMethod2 = createMockPaymentMethod("bank", "Bank Transfer", PaymentMethodType.CARD)
|
||||
val provider1 = createMockProvider("provider1", "Provider 1")
|
||||
val provider2 = createMockProvider("provider2", "Provider 2")
|
||||
|
||||
|
|
@ -145,10 +145,10 @@ class GetOnrampOffersUseCaseTest {
|
|||
Truth.assertThat(recommendedBlock).isNotNull()
|
||||
Truth.assertThat(recommendedBlock?.offers).hasSize(1)
|
||||
|
||||
val bestRateOffer = recommendedBlock?.offers?.first()
|
||||
Truth.assertThat(bestRateOffer?.advantages).isEqualTo(OnrampOfferAdvantages.BestRate)
|
||||
val grateRateOffer = recommendedBlock?.offers?.first()
|
||||
Truth.assertThat(grateRateOffer?.advantages).isEqualTo(OnrampOfferAdvantages.GreatRate)
|
||||
|
||||
when (val quote = bestRateOffer?.quote) {
|
||||
when (val quote = grateRateOffer?.quote) {
|
||||
is OnrampQuote.Data -> Truth.assertThat(quote.toAmount.value).isEqualTo(BigDecimal("100.0"))
|
||||
else -> Truth.assertThat(false).isTrue()
|
||||
}
|
||||
|
|
@ -159,8 +159,10 @@ class GetOnrampOffersUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `invoke should find fastest offer correctly`() = runTest {
|
||||
val instantPaymentMethod = createMockPaymentMethod("card", "Card", isInstant = true)
|
||||
val slowPaymentMethod = createMockPaymentMethod("bank", "Bank Transfer", isInstant = false)
|
||||
val instantPaymentMethod =
|
||||
createMockPaymentMethod("card", "Card", PaymentMethodType.GOOGLE_PAY)
|
||||
val slowPaymentMethod =
|
||||
createMockPaymentMethod("bank", "Bank Transfer", PaymentMethodType.CARD)
|
||||
val provider1 = createMockProvider("provider1", "Provider 1")
|
||||
val provider2 = createMockProvider("provider2", "Provider 2")
|
||||
|
||||
|
|
@ -190,17 +192,17 @@ class GetOnrampOffersUseCaseTest {
|
|||
Truth.assertThat(recommendedBlock).isNotNull()
|
||||
Truth.assertThat(recommendedBlock?.offers).hasSize(2)
|
||||
|
||||
val bestRateOffer = recommendedBlock
|
||||
val grateRateOffer = recommendedBlock
|
||||
?.offers
|
||||
?.find { it.advantages == OnrampOfferAdvantages.BestRate }
|
||||
?.find { it.advantages == OnrampOfferAdvantages.GreatRate }
|
||||
val fastestOffer = recommendedBlock
|
||||
?.offers
|
||||
?.find { it.advantages == OnrampOfferAdvantages.Fastest }
|
||||
|
||||
Truth.assertThat(bestRateOffer).isNotNull()
|
||||
Truth.assertThat(grateRateOffer).isNotNull()
|
||||
Truth.assertThat(fastestOffer).isNotNull()
|
||||
|
||||
when (val quote = bestRateOffer?.quote) {
|
||||
when (val quote = grateRateOffer?.quote) {
|
||||
is OnrampQuote.Data -> Truth.assertThat(quote.toAmount.value).isEqualTo(BigDecimal("100.0"))
|
||||
else -> Truth.assertThat(false).isTrue()
|
||||
}
|
||||
|
|
@ -215,8 +217,8 @@ class GetOnrampOffersUseCaseTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `invoke should not show recommended block when only one method and provider`() = runTest {
|
||||
val paymentMethod = createMockPaymentMethod("card", "Card", isInstant = false)
|
||||
fun `invoke should show recommended block when only one method and provider`() = runTest {
|
||||
val paymentMethod = createMockPaymentMethod("card", "Card", PaymentMethodType.CARD)
|
||||
val provider = createMockProvider("provider1", "Provider 1")
|
||||
|
||||
val quotes = listOf(
|
||||
|
|
@ -238,22 +240,22 @@ class GetOnrampOffersUseCaseTest {
|
|||
either.fold(
|
||||
ifLeft = { error -> Truth.assertThat(error).isNull() },
|
||||
ifRight = { offers ->
|
||||
Truth.assertThat(offers).isEmpty()
|
||||
Truth.assertThat(offers).isNotEmpty()
|
||||
Truth.assertThat(offers).hasSize(1)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMockPaymentMethod(id: String, name: String, isInstant: Boolean): OnrampPaymentMethod {
|
||||
private fun createMockPaymentMethod(
|
||||
id: String,
|
||||
name: String,
|
||||
type: PaymentMethodType = PaymentMethodType.CARD,
|
||||
): OnrampPaymentMethod {
|
||||
return mockk<OnrampPaymentMethod> {
|
||||
every { this@mockk.id } returns id
|
||||
every { this@mockk.name } returns name
|
||||
every { this@mockk.type } returns mockk {
|
||||
every { isInstant() } returns isInstant
|
||||
every { getProcessingSpeed() } returns mockk {
|
||||
every { speed } returns if (isInstant) 1 else 3
|
||||
}
|
||||
}
|
||||
every { this@mockk.type } returns type
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,11 +280,12 @@ class GetOnrampOffersUseCaseTest {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createMockTransaction(providerType: String, paymentMethod: String, timestamp: Long): OnrampTransaction {
|
||||
private fun createMockTransaction(providerName: String, paymentMethod: String, timestamp: Long): OnrampTransaction {
|
||||
return mockk<OnrampTransaction> {
|
||||
every { this@mockk.providerType } returns providerType
|
||||
every { this@mockk.providerName } returns providerName
|
||||
every { this@mockk.paymentMethod } returns paymentMethod
|
||||
every { this@mockk.timestamp } returns timestamp
|
||||
every { this@mockk.status.isTerminal } returns true
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue