Updated on 2026-08-14
This commit is contained in:
parent
6e92e35a38
commit
4d0cb6a243
24 changed files with 697 additions and 887 deletions
|
|
@ -5,7 +5,9 @@ import com.tangem.data.express.converter.ExpressProviderConverter
|
|||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
|
||||
import com.tangem.datasource.local.converter.toEntity
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.txhistory.db.dao.ExpressHistoryDao
|
||||
import com.tangem.domain.express.ExpressRepository
|
||||
import com.tangem.domain.express.models.ExpressProvider
|
||||
import com.tangem.domain.express.models.ExpressProviderType
|
||||
|
|
@ -16,6 +18,7 @@ import com.tangem.utils.logging.TangemLogger
|
|||
|
||||
internal class DefaultExpressRepository(
|
||||
private val tangemExpressApi: TangemExpressApi,
|
||||
private val expressHistoryDao: ExpressHistoryDao,
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : ExpressRepository {
|
||||
|
|
@ -26,13 +29,17 @@ internal class DefaultExpressRepository(
|
|||
): List<ExpressProvider> = with(dispatchers.io) {
|
||||
safeApiCall(
|
||||
call = {
|
||||
tangemExpressApi.getProviders(
|
||||
val providers = tangemExpressApi.getProviders(
|
||||
userWalletId = userWallet.walletId.stringValue,
|
||||
refCode = ExpressUtils.getRefCode(
|
||||
userWallet = userWallet,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
),
|
||||
).getOrThrow().map(ExpressProviderConverter()::convert)
|
||||
).getOrThrow()
|
||||
|
||||
expressHistoryDao.upsertProviders(providers.map { it.toEntity() })
|
||||
|
||||
providers.map(ExpressProviderConverter()::convert)
|
||||
.filterIf(filterProviderTypes.isNotEmpty()) { it.type in filterProviderTypes }
|
||||
},
|
||||
onError = { error ->
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.datasource.api.express.TangemExpressApi
|
|||
import com.tangem.datasource.api.express.models.response.ExpressErrorResponse
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.txhistory.db.dao.ExpressHistoryDao
|
||||
import com.tangem.domain.express.ExpressErrorResolver
|
||||
import com.tangem.domain.express.ExpressRepository
|
||||
import com.tangem.domain.express.ExpressServiceFetcher
|
||||
|
|
@ -36,11 +37,13 @@ internal object ExpressDataModule {
|
|||
@Singleton
|
||||
fun provideExpressRepository(
|
||||
tangemExpressApi: TangemExpressApi,
|
||||
expressHistoryDao: ExpressHistoryDao,
|
||||
appPreferencesStore: AppPreferencesStore,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
): ExpressRepository {
|
||||
return DefaultExpressRepository(
|
||||
tangemExpressApi = tangemExpressApi,
|
||||
expressHistoryDao = expressHistoryDao,
|
||||
appPreferencesStore = appPreferencesStore,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.tangem.datasource.api.onramp.models.response.model.OnrampPairDTO
|
|||
import com.tangem.datasource.api.onramp.models.response.model.PaymentMethodDTO
|
||||
import com.tangem.datasource.crypto.DataSignatureVerifier
|
||||
import com.tangem.datasource.exchangeservice.swap.ExpressUtils
|
||||
import com.tangem.datasource.local.converter.toEntity
|
||||
import com.tangem.datasource.local.onramp.countries.OnrampCountriesStore
|
||||
import com.tangem.datasource.local.onramp.currencies.OnrampCurrenciesStore
|
||||
import com.tangem.datasource.local.onramp.pairs.OnrampPairsStore
|
||||
|
|
@ -35,6 +36,7 @@ import com.tangem.datasource.local.preferences.PreferencesKeys
|
|||
import com.tangem.datasource.local.preferences.utils.getObject
|
||||
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
|
||||
import com.tangem.datasource.local.preferences.utils.storeObject
|
||||
import com.tangem.datasource.local.txhistory.db.dao.ExpressHistoryDao
|
||||
import com.tangem.domain.express.models.ExpressAsset
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -72,12 +74,13 @@ internal class DefaultOnrampRepository(
|
|||
private val currenciesStore: OnrampCurrenciesStore,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val dataSignatureVerifier: DataSignatureVerifier,
|
||||
private val expressHistoryDao: ExpressHistoryDao,
|
||||
moshi: Moshi,
|
||||
) : OnrampRepository {
|
||||
|
||||
private val currencyConverter = CurrencyConverter()
|
||||
private val countryConverter = CountryConverter(currencyConverter)
|
||||
private val statusConverter = StatusConverter()
|
||||
private val statusConverter = StatusConverter(moshi)
|
||||
private val paymentMethodsConverter = PaymentMethodConverter()
|
||||
private val onrampDataAdapter = moshi.adapter(OnrampDataJson::class.java)
|
||||
private val onrampErrorAdapter = moshi.adapter(ExpressErrorResponse::class.java)
|
||||
|
|
@ -162,6 +165,8 @@ internal class DefaultOnrampRepository(
|
|||
)
|
||||
.getOrThrow()
|
||||
|
||||
expressHistoryDao.upsertOnramps(listOf(response.toEntity(ownerAddress = response.payoutAddress)))
|
||||
|
||||
statusConverter.convert(response)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,21 @@
|
|||
package com.tangem.data.onramp.converters
|
||||
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampStatusResponse
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampItemResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.Status
|
||||
import com.tangem.domain.onramp.model.OnrampStatus
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
internal class StatusConverter : Converter<OnrampStatusResponse, OnrampStatus> {
|
||||
override fun convert(value: OnrampStatusResponse): OnrampStatus {
|
||||
internal class StatusConverter(moshi: Moshi) : Converter<OnrampItemResponse, OnrampStatus> {
|
||||
|
||||
private val responseStatusAdapter = moshi.adapter(Status::class.java)
|
||||
|
||||
override fun convert(value: OnrampItemResponse): OnrampStatus {
|
||||
return OnrampStatus(
|
||||
txId = value.txId,
|
||||
providerId = value.providerId,
|
||||
payoutAddress = value.payoutAddress,
|
||||
status = OnrampStatus.Status.valueOf(value.status.name),
|
||||
status = OnrampStatus.Status.valueOf(value.status.toResponseStatus().name),
|
||||
failReason = value.failReason,
|
||||
externalTxId = value.externalTxId,
|
||||
externalTxUrl = value.externalTxUrl,
|
||||
|
|
@ -20,11 +25,14 @@ internal class StatusConverter : Converter<OnrampStatusResponse, OnrampStatus> {
|
|||
fromAmount = value.fromAmount,
|
||||
toContractAddress = value.toContractAddress,
|
||||
toNetwork = value.toNetwork,
|
||||
toDecimals = value.toDecimals,
|
||||
toDecimals = value.toDecimals.toString(),
|
||||
toAmount = value.toAmount,
|
||||
toActualAmount = value.toActualAmount,
|
||||
paymentMethod = value.paymentMethod,
|
||||
countryCode = value.countryCode,
|
||||
)
|
||||
}
|
||||
|
||||
private fun String.toResponseStatus(): Status = responseStatusAdapter.fromJsonValue(this)
|
||||
?: error("Unknown onramp status: $this")
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ import com.tangem.datasource.local.onramp.paymentmethods.OnrampPaymentMethodsSto
|
|||
import com.tangem.datasource.local.onramp.quotes.OnrampQuotesStore
|
||||
import com.tangem.datasource.local.onramp.country.OnrampCurrentCountryByIPStore
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.txhistory.db.dao.ExpressHistoryDao
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.domain.onramp.repositories.*
|
||||
|
|
@ -56,6 +57,7 @@ internal object OnrampDataModule {
|
|||
walletManagersFacade: WalletManagersFacade,
|
||||
dataSignatureVerifier: DataSignatureVerifier,
|
||||
onrampCurrentCountryByIPStore: OnrampCurrentCountryByIPStore,
|
||||
expressHistoryDao: ExpressHistoryDao,
|
||||
@NetworkMoshi moshi: Moshi,
|
||||
): OnrampRepository {
|
||||
return DefaultOnrampRepository(
|
||||
|
|
@ -71,6 +73,7 @@ internal object OnrampDataModule {
|
|||
countriesStore = countriesStore,
|
||||
walletManagersFacade = walletManagersFacade,
|
||||
dataSignatureVerifier = dataSignatureVerifier,
|
||||
expressHistoryDao = expressHistoryDao,
|
||||
moshi = moshi,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.data.txhistory.repository
|
||||
|
||||
import com.tangem.data.txhistory.repository.converter.toEntity
|
||||
import com.tangem.datasource.api.common.response.getOrThrow
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
import com.tangem.datasource.api.express.models.response.ExchangeHistoryDeltaResponse
|
||||
|
|
@ -12,6 +11,7 @@ import com.tangem.datasource.api.onramp.OnrampApi
|
|||
import com.tangem.datasource.api.onramp.models.response.OnrampHistoryDeltaResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampHistoryResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampItemResponse
|
||||
import com.tangem.datasource.local.converter.toEntity
|
||||
import com.tangem.datasource.local.txhistory.db.dao.ExpressHistoryDao
|
||||
import com.tangem.datasource.local.txhistory.db.dao.ExpressSyncStateDao
|
||||
import com.tangem.datasource.local.txhistory.db.entity.express.ExpressSyncStateEntity
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
package com.tangem.data.txhistory.repository.converter
|
||||
|
||||
import com.tangem.datasource.api.express.models.response.ExchangeItemResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampItemResponse
|
||||
import com.tangem.datasource.local.txhistory.db.entity.express.ExpressExchangeEntity
|
||||
import com.tangem.datasource.local.txhistory.db.entity.express.ExpressOnrampEntity
|
||||
|
||||
/**
|
||||
* Maps API history items into their persisted [androidx.room.Entity] representations.
|
||||
*
|
||||
* @param ownerAddress address the history was requested for. Stored as the query key.
|
||||
*/
|
||||
internal fun ExchangeItemResponse.toEntity(ownerAddress: String): ExpressExchangeEntity {
|
||||
return ExpressExchangeEntity(
|
||||
txId = txId,
|
||||
ownerAddress = ownerAddress,
|
||||
providerId = providerId,
|
||||
fromAddress = fromAddress,
|
||||
payinAddress = payinAddress,
|
||||
payinExtraId = payinExtraId,
|
||||
payoutAddress = payoutAddress,
|
||||
refundAddress = refundAddress,
|
||||
refundExtraId = refundExtraId,
|
||||
rateType = rateType,
|
||||
status = status.name,
|
||||
externalTxId = externalTxId,
|
||||
externalTxStatus = externalTxStatus,
|
||||
externalTxUrl = externalTxUrl,
|
||||
payinHash = payinHash,
|
||||
payoutHash = payoutHash,
|
||||
refundNetwork = refundNetwork,
|
||||
refundContractAddress = refundContractAddress,
|
||||
createdAt = createdAt,
|
||||
payTill = payTill,
|
||||
averageDuration = averageDuration,
|
||||
from = ExpressExchangeEntity.AssetEmbedded(
|
||||
contractAddress = fromContractAddress,
|
||||
network = fromNetwork,
|
||||
decimals = fromDecimals,
|
||||
amount = fromAmount,
|
||||
actualAmount = null,
|
||||
),
|
||||
to = ExpressExchangeEntity.AssetEmbedded(
|
||||
contractAddress = toContractAddress,
|
||||
network = toNetwork,
|
||||
decimals = toDecimals,
|
||||
amount = toAmount,
|
||||
actualAmount = toActualAmount,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
internal fun OnrampItemResponse.toEntity(ownerAddress: String): ExpressOnrampEntity {
|
||||
return ExpressOnrampEntity(
|
||||
txId = txId,
|
||||
ownerAddress = ownerAddress,
|
||||
providerId = providerId,
|
||||
fromAddress = fromAddress,
|
||||
payinAddress = payinAddress,
|
||||
payinExtraId = payinExtraId,
|
||||
payoutAddress = payoutAddress,
|
||||
refundAddress = refundAddress,
|
||||
refundExtraId = refundExtraId,
|
||||
rateType = rateType,
|
||||
status = status.name,
|
||||
externalTxId = externalTxId,
|
||||
externalTxStatus = externalTxStatus,
|
||||
externalTxUrl = externalTxUrl,
|
||||
payinHash = payinHash,
|
||||
payoutHash = payoutHash,
|
||||
refundNetwork = refundNetwork,
|
||||
refundContractAddress = refundContractAddress,
|
||||
createdAt = createdAt,
|
||||
payTill = payTill,
|
||||
averageDuration = averageDuration,
|
||||
from = ExpressOnrampEntity.AssetEmbedded(
|
||||
contractAddress = fromContractAddress,
|
||||
network = fromNetwork,
|
||||
decimals = fromDecimals,
|
||||
amount = fromAmount,
|
||||
actualAmount = null,
|
||||
),
|
||||
to = ExpressOnrampEntity.AssetEmbedded(
|
||||
contractAddress = toContractAddress,
|
||||
network = toNetwork,
|
||||
decimals = toDecimals,
|
||||
amount = toAmount,
|
||||
actualAmount = toActualAmount,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.data.txhistory.repository
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.data.txhistory.repository.converter.toEntity
|
||||
import com.tangem.datasource.local.converter.toEntity
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.express.TangemExpressApi
|
||||
|
|
@ -305,15 +305,15 @@ internal class ExpressHistoryRepositoryTest {
|
|||
refundAddress = null,
|
||||
refundExtraId = null,
|
||||
rateType = "float",
|
||||
status = ExchangeItemResponse.Status.FINISHED,
|
||||
status = "finished",
|
||||
externalTxId = null,
|
||||
externalTxStatus = null,
|
||||
externalTxUrl = null,
|
||||
payinHash = "payin-hash",
|
||||
payoutHash = "payout-hash",
|
||||
refundNetwork = null,
|
||||
refundContractAddress = null,
|
||||
createdAt = "2026-06-01T00:00:00Z",
|
||||
updatedAt = "2026-06-01T00:05:00Z",
|
||||
payTill = null,
|
||||
averageDuration = null,
|
||||
fromContractAddress = "0xfromContract",
|
||||
|
|
@ -330,33 +330,24 @@ internal class ExpressHistoryRepositoryTest {
|
|||
private fun createOnrampItem(txId: String = "onramp-tx-1") = OnrampItemResponse(
|
||||
txId = txId,
|
||||
providerId = "mercuryo",
|
||||
fromAddress = "0xfrom",
|
||||
payinAddress = "0xpayin",
|
||||
payinExtraId = null,
|
||||
payoutAddress = "0xpayout",
|
||||
refundAddress = null,
|
||||
refundExtraId = null,
|
||||
rateType = "fixed",
|
||||
status = OnrampItemResponse.Status.FINISHED,
|
||||
status = "finished",
|
||||
failReason = null,
|
||||
externalTxId = null,
|
||||
externalTxStatus = null,
|
||||
externalTxUrl = null,
|
||||
payinHash = "payin-hash",
|
||||
payoutHash = "payout-hash",
|
||||
refundNetwork = null,
|
||||
refundContractAddress = null,
|
||||
createdAt = "2026-06-01T00:00:00Z",
|
||||
payTill = null,
|
||||
averageDuration = null,
|
||||
fromContractAddress = "0xfromContract",
|
||||
fromNetwork = "usd",
|
||||
fromDecimals = 2,
|
||||
updatedAt = "2026-06-01T00:05:00Z",
|
||||
fromCurrencyCode = "USD",
|
||||
fromAmount = "100.0",
|
||||
fromPrecision = 2,
|
||||
toContractAddress = "0xtoContract",
|
||||
toNetwork = "bitcoin",
|
||||
toDecimals = 8,
|
||||
toAmount = "0.001",
|
||||
toActualAmount = "0.99",
|
||||
paymentMethod = "card",
|
||||
countryCode = "US",
|
||||
)
|
||||
|
||||
private companion object {
|
||||
|
|
|
|||
|
|
@ -1,316 +0,0 @@
|
|||
package com.tangem.data.txhistory.repository.converter
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.datasource.api.express.models.response.ExchangeItemResponse
|
||||
import com.tangem.datasource.api.onramp.models.response.OnrampItemResponse
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
internal class ExpressHistoryConverterTest {
|
||||
|
||||
@Test
|
||||
fun `GIVEN exchange item WHEN toEntity THEN all transaction fields are mapped`() {
|
||||
// GIVEN
|
||||
val item = createExchangeItem()
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.txId).isEqualTo(item.txId)
|
||||
assertThat(entity.ownerAddress).isEqualTo(OWNER_ADDRESS)
|
||||
assertThat(entity.providerId).isEqualTo(item.providerId)
|
||||
assertThat(entity.fromAddress).isEqualTo(item.fromAddress)
|
||||
assertThat(entity.payinAddress).isEqualTo(item.payinAddress)
|
||||
assertThat(entity.payinExtraId).isEqualTo(item.payinExtraId)
|
||||
assertThat(entity.payoutAddress).isEqualTo(item.payoutAddress)
|
||||
assertThat(entity.refundAddress).isEqualTo(item.refundAddress)
|
||||
assertThat(entity.refundExtraId).isEqualTo(item.refundExtraId)
|
||||
assertThat(entity.rateType).isEqualTo(item.rateType)
|
||||
assertThat(entity.externalTxId).isEqualTo(item.externalTxId)
|
||||
assertThat(entity.externalTxStatus).isEqualTo(item.externalTxStatus)
|
||||
assertThat(entity.externalTxUrl).isEqualTo(item.externalTxUrl)
|
||||
assertThat(entity.payinHash).isEqualTo(item.payinHash)
|
||||
assertThat(entity.payoutHash).isEqualTo(item.payoutHash)
|
||||
assertThat(entity.refundNetwork).isEqualTo(item.refundNetwork)
|
||||
assertThat(entity.refundContractAddress).isEqualTo(item.refundContractAddress)
|
||||
assertThat(entity.createdAt).isEqualTo(item.createdAt)
|
||||
assertThat(entity.payTill).isEqualTo(item.payTill)
|
||||
assertThat(entity.averageDuration).isEqualTo(item.averageDuration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN exchange item WHEN toEntity THEN status is stored as enum name`() {
|
||||
// GIVEN
|
||||
val item = createExchangeItem(status = ExchangeItemResponse.Status.FINISHED)
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.status).isEqualTo("FINISHED")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN exchange item WHEN toEntity THEN from and to assets are mapped`() {
|
||||
// GIVEN
|
||||
val item = createExchangeItem()
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.from.contractAddress).isEqualTo(item.fromContractAddress)
|
||||
assertThat(entity.from.network).isEqualTo(item.fromNetwork)
|
||||
assertThat(entity.from.decimals).isEqualTo(item.fromDecimals)
|
||||
assertThat(entity.from.amount).isEqualTo(item.fromAmount)
|
||||
// `from` asset never carries an actual amount
|
||||
assertThat(entity.from.actualAmount).isNull()
|
||||
|
||||
assertThat(entity.to.contractAddress).isEqualTo(item.toContractAddress)
|
||||
assertThat(entity.to.network).isEqualTo(item.toNetwork)
|
||||
assertThat(entity.to.decimals).isEqualTo(item.toDecimals)
|
||||
assertThat(entity.to.amount).isEqualTo(item.toAmount)
|
||||
assertThat(entity.to.actualAmount).isEqualTo(item.toActualAmount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN exchange item with null optional fields WHEN toEntity THEN nulls are preserved`() {
|
||||
// GIVEN
|
||||
val item = createExchangeItem(
|
||||
payinExtraId = null,
|
||||
refundAddress = null,
|
||||
refundExtraId = null,
|
||||
externalTxId = null,
|
||||
externalTxStatus = null,
|
||||
externalTxUrl = null,
|
||||
payinHash = null,
|
||||
payoutHash = null,
|
||||
refundNetwork = null,
|
||||
refundContractAddress = null,
|
||||
payTill = null,
|
||||
averageDuration = null,
|
||||
toActualAmount = null,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.payinExtraId).isNull()
|
||||
assertThat(entity.refundAddress).isNull()
|
||||
assertThat(entity.refundExtraId).isNull()
|
||||
assertThat(entity.externalTxId).isNull()
|
||||
assertThat(entity.externalTxStatus).isNull()
|
||||
assertThat(entity.externalTxUrl).isNull()
|
||||
assertThat(entity.payinHash).isNull()
|
||||
assertThat(entity.payoutHash).isNull()
|
||||
assertThat(entity.refundNetwork).isNull()
|
||||
assertThat(entity.refundContractAddress).isNull()
|
||||
assertThat(entity.payTill).isNull()
|
||||
assertThat(entity.averageDuration).isNull()
|
||||
assertThat(entity.to.actualAmount).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN onramp item WHEN toEntity THEN all transaction fields are mapped`() {
|
||||
// GIVEN
|
||||
val item = createOnrampItem()
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.txId).isEqualTo(item.txId)
|
||||
assertThat(entity.ownerAddress).isEqualTo(OWNER_ADDRESS)
|
||||
assertThat(entity.providerId).isEqualTo(item.providerId)
|
||||
assertThat(entity.fromAddress).isEqualTo(item.fromAddress)
|
||||
assertThat(entity.payinAddress).isEqualTo(item.payinAddress)
|
||||
assertThat(entity.payinExtraId).isEqualTo(item.payinExtraId)
|
||||
assertThat(entity.payoutAddress).isEqualTo(item.payoutAddress)
|
||||
assertThat(entity.refundAddress).isEqualTo(item.refundAddress)
|
||||
assertThat(entity.refundExtraId).isEqualTo(item.refundExtraId)
|
||||
assertThat(entity.rateType).isEqualTo(item.rateType)
|
||||
assertThat(entity.externalTxId).isEqualTo(item.externalTxId)
|
||||
assertThat(entity.externalTxStatus).isEqualTo(item.externalTxStatus)
|
||||
assertThat(entity.externalTxUrl).isEqualTo(item.externalTxUrl)
|
||||
assertThat(entity.payinHash).isEqualTo(item.payinHash)
|
||||
assertThat(entity.payoutHash).isEqualTo(item.payoutHash)
|
||||
assertThat(entity.refundNetwork).isEqualTo(item.refundNetwork)
|
||||
assertThat(entity.refundContractAddress).isEqualTo(item.refundContractAddress)
|
||||
assertThat(entity.createdAt).isEqualTo(item.createdAt)
|
||||
assertThat(entity.payTill).isEqualTo(item.payTill)
|
||||
assertThat(entity.averageDuration).isEqualTo(item.averageDuration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN onramp item WHEN toEntity THEN status is stored as enum name`() {
|
||||
// GIVEN
|
||||
val item = createOnrampItem(status = OnrampItemResponse.Status.WAITING_TX_HASH)
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.status).isEqualTo("WAITING_TX_HASH")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN onramp item WHEN toEntity THEN from and to assets are mapped`() {
|
||||
// GIVEN
|
||||
val item = createOnrampItem()
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.from.contractAddress).isEqualTo(item.fromContractAddress)
|
||||
assertThat(entity.from.network).isEqualTo(item.fromNetwork)
|
||||
assertThat(entity.from.decimals).isEqualTo(item.fromDecimals)
|
||||
assertThat(entity.from.amount).isEqualTo(item.fromAmount)
|
||||
assertThat(entity.from.actualAmount).isNull()
|
||||
|
||||
assertThat(entity.to.contractAddress).isEqualTo(item.toContractAddress)
|
||||
assertThat(entity.to.network).isEqualTo(item.toNetwork)
|
||||
assertThat(entity.to.decimals).isEqualTo(item.toDecimals)
|
||||
assertThat(entity.to.amount).isEqualTo(item.toAmount)
|
||||
assertThat(entity.to.actualAmount).isEqualTo(item.toActualAmount)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN onramp item with null optional fields WHEN toEntity THEN nulls are preserved`() {
|
||||
// GIVEN
|
||||
val item = createOnrampItem(
|
||||
payinExtraId = null,
|
||||
refundAddress = null,
|
||||
refundExtraId = null,
|
||||
externalTxId = null,
|
||||
externalTxStatus = null,
|
||||
externalTxUrl = null,
|
||||
payinHash = null,
|
||||
payoutHash = null,
|
||||
refundNetwork = null,
|
||||
refundContractAddress = null,
|
||||
payTill = null,
|
||||
averageDuration = null,
|
||||
toActualAmount = null,
|
||||
)
|
||||
|
||||
// WHEN
|
||||
val entity = item.toEntity(ownerAddress = OWNER_ADDRESS)
|
||||
|
||||
// THEN
|
||||
assertThat(entity.payinExtraId).isNull()
|
||||
assertThat(entity.refundAddress).isNull()
|
||||
assertThat(entity.refundExtraId).isNull()
|
||||
assertThat(entity.externalTxId).isNull()
|
||||
assertThat(entity.externalTxStatus).isNull()
|
||||
assertThat(entity.externalTxUrl).isNull()
|
||||
assertThat(entity.payinHash).isNull()
|
||||
assertThat(entity.payoutHash).isNull()
|
||||
assertThat(entity.refundNetwork).isNull()
|
||||
assertThat(entity.refundContractAddress).isNull()
|
||||
assertThat(entity.payTill).isNull()
|
||||
assertThat(entity.averageDuration).isNull()
|
||||
assertThat(entity.to.actualAmount).isNull()
|
||||
}
|
||||
|
||||
private fun createExchangeItem(
|
||||
status: ExchangeItemResponse.Status = ExchangeItemResponse.Status.WAITING,
|
||||
payinExtraId: String? = "payin-extra",
|
||||
refundAddress: String? = "refund-address",
|
||||
refundExtraId: String? = "refund-extra",
|
||||
externalTxId: String? = "external-tx-id",
|
||||
externalTxStatus: String? = "external-status",
|
||||
externalTxUrl: String? = "https://provider.example/tx",
|
||||
payinHash: String? = "payin-hash",
|
||||
payoutHash: String? = "payout-hash",
|
||||
refundNetwork: String? = "ethereum",
|
||||
refundContractAddress: String? = "0xrefund",
|
||||
payTill: String? = "2026-06-01T00:10:00Z",
|
||||
averageDuration: Long? = 600L,
|
||||
toActualAmount: String? = "0.99",
|
||||
) = ExchangeItemResponse(
|
||||
txId = "exchange-tx-1",
|
||||
providerId = "changelly",
|
||||
fromAddress = "0xfrom",
|
||||
payinAddress = "0xpayin",
|
||||
payinExtraId = payinExtraId,
|
||||
payoutAddress = "0xpayout",
|
||||
refundAddress = refundAddress,
|
||||
refundExtraId = refundExtraId,
|
||||
rateType = "float",
|
||||
status = status,
|
||||
externalTxId = externalTxId,
|
||||
externalTxStatus = externalTxStatus,
|
||||
externalTxUrl = externalTxUrl,
|
||||
payinHash = payinHash,
|
||||
payoutHash = payoutHash,
|
||||
refundNetwork = refundNetwork,
|
||||
refundContractAddress = refundContractAddress,
|
||||
createdAt = "2026-06-01T00:00:00Z",
|
||||
payTill = payTill,
|
||||
averageDuration = averageDuration,
|
||||
fromContractAddress = "0xfromContract",
|
||||
fromNetwork = "ethereum",
|
||||
fromDecimals = 18,
|
||||
fromAmount = "1.0",
|
||||
toContractAddress = "0xtoContract",
|
||||
toNetwork = "bitcoin",
|
||||
toDecimals = 8,
|
||||
toAmount = "1.0",
|
||||
toActualAmount = toActualAmount,
|
||||
)
|
||||
|
||||
private fun createOnrampItem(
|
||||
status: OnrampItemResponse.Status = OnrampItemResponse.Status.WAITING,
|
||||
payinExtraId: String? = "payin-extra",
|
||||
refundAddress: String? = "refund-address",
|
||||
refundExtraId: String? = "refund-extra",
|
||||
externalTxId: String? = "external-tx-id",
|
||||
externalTxStatus: String? = "external-status",
|
||||
externalTxUrl: String? = "https://provider.example/tx",
|
||||
payinHash: String? = "payin-hash",
|
||||
payoutHash: String? = "payout-hash",
|
||||
refundNetwork: String? = "ethereum",
|
||||
refundContractAddress: String? = "0xrefund",
|
||||
payTill: String? = "2026-06-01T00:10:00Z",
|
||||
averageDuration: Long? = 600L,
|
||||
toActualAmount: String? = "0.99",
|
||||
) = OnrampItemResponse(
|
||||
txId = "onramp-tx-1",
|
||||
providerId = "mercuryo",
|
||||
fromAddress = "0xfrom",
|
||||
payinAddress = "0xpayin",
|
||||
payinExtraId = payinExtraId,
|
||||
payoutAddress = "0xpayout",
|
||||
refundAddress = refundAddress,
|
||||
refundExtraId = refundExtraId,
|
||||
rateType = "fixed",
|
||||
status = status,
|
||||
externalTxId = externalTxId,
|
||||
externalTxStatus = externalTxStatus,
|
||||
externalTxUrl = externalTxUrl,
|
||||
payinHash = payinHash,
|
||||
payoutHash = payoutHash,
|
||||
refundNetwork = refundNetwork,
|
||||
refundContractAddress = refundContractAddress,
|
||||
createdAt = "2026-06-01T00:00:00Z",
|
||||
payTill = payTill,
|
||||
averageDuration = averageDuration,
|
||||
fromContractAddress = "0xfromContract",
|
||||
fromNetwork = "usd",
|
||||
fromDecimals = 2,
|
||||
fromAmount = "100.0",
|
||||
toContractAddress = "0xtoContract",
|
||||
toNetwork = "bitcoin",
|
||||
toDecimals = 8,
|
||||
toAmount = "0.001",
|
||||
toActualAmount = toActualAmount,
|
||||
)
|
||||
|
||||
private companion object {
|
||||
const val OWNER_ADDRESS = "0xowner"
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue