Updated on 2026-08-14
This commit is contained in:
parent
f3f1d88d1b
commit
f57fc16ff6
29 changed files with 107 additions and 264 deletions
|
|
@ -3,20 +3,14 @@ package com.tangem.common.test.data.quote
|
|||
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.utils.extensions.orZero
|
||||
|
||||
fun QuotesResponse.Quote.toDomain(
|
||||
rawCurrencyId: String,
|
||||
source: StatusSource = StatusSource.ACTUAL,
|
||||
fiatCurrency: FiatCurrency = FiatCurrency.Default,
|
||||
): QuoteStatus {
|
||||
fun QuotesResponse.Quote.toDomain(rawCurrencyId: String, source: StatusSource = StatusSource.ACTUAL): QuoteStatus {
|
||||
return QuoteStatus(
|
||||
rawCurrencyId = CryptoCurrency.RawID(rawCurrencyId),
|
||||
value = QuoteStatus.Data(
|
||||
source = source,
|
||||
fiatCurrency = fiatCurrency,
|
||||
fiatRate = price.orZero(),
|
||||
priceChange = priceChange24h.orZero().movePointLeft(2),
|
||||
fiatRateUSD = priceUsd.orZero(),
|
||||
|
|
@ -24,9 +18,6 @@ fun QuotesResponse.Quote.toDomain(
|
|||
)
|
||||
}
|
||||
|
||||
fun Pair<String, QuotesResponse.Quote>.toDomain(
|
||||
source: StatusSource = StatusSource.ACTUAL,
|
||||
fiatCurrency: FiatCurrency = FiatCurrency.Default,
|
||||
): QuoteStatus {
|
||||
return second.toDomain(rawCurrencyId = first, source = source, fiatCurrency = fiatCurrency)
|
||||
fun Pair<String, QuotesResponse.Quote>.toDomain(source: StatusSource = StatusSource.ACTUAL): QuoteStatus {
|
||||
return second.toDomain(rawCurrencyId = first, source = source)
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import com.tangem.data.common.network.NetworkFactory
|
|||
import com.tangem.datasource.api.tangemTech.models.HotCryptoResponse
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
|
|
@ -95,7 +94,6 @@ internal class HotCryptoCurrencyConverter(
|
|||
QuoteStatus(
|
||||
rawCurrencyId = rawCurrencyId,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default, // hot crypto rates are quoted in USD
|
||||
fiatRate = fiatRate,
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
priceChange = priceChange.movePointLeft(2),
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
package com.tangem.data.quotes.converter
|
||||
|
||||
import com.tangem.data.quotes.store.QuoteStatusDM
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.utils.converter.TwoWayConverter
|
||||
|
||||
/**
|
||||
* Two-way converter between domain [FiatCurrency] and persisted [QuoteStatusDM.FiatCurrency].
|
||||
*
|
||||
* - [convert] — domain → DM (for persistence).
|
||||
* - [convertBack] — DM → domain (for restore on cold start).
|
||||
*/
|
||||
internal object FiatCurrencyConverter : TwoWayConverter<FiatCurrency, QuoteStatusDM.FiatCurrency> {
|
||||
|
||||
override fun convert(value: FiatCurrency): QuoteStatusDM.FiatCurrency =
|
||||
QuoteStatusDM.FiatCurrency(code = value.code, symbol = value.symbol)
|
||||
|
||||
override fun convertBack(value: QuoteStatusDM.FiatCurrency): FiatCurrency =
|
||||
FiatCurrency(code = value.code, symbol = value.symbol)
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.tangem.data.quotes.converter
|
|||
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.utils.converter.Converter
|
||||
import com.tangem.utils.extensions.orZero
|
||||
|
|
@ -12,13 +11,11 @@ import com.tangem.utils.extensions.orZero
|
|||
* Converter from [QuotesResponse.Quote] to [QuoteStatus]
|
||||
*
|
||||
* @property source status source
|
||||
* @property fiatCurrency fiat currency in which the quote is expressed
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class QuoteStatusConverter(
|
||||
private val source: StatusSource,
|
||||
private val fiatCurrency: FiatCurrency,
|
||||
) : Converter<Map.Entry<String, QuotesResponse.Quote>, QuoteStatus> {
|
||||
|
||||
override fun convert(value: Map.Entry<String, QuotesResponse.Quote>): QuoteStatus {
|
||||
|
|
@ -28,7 +25,6 @@ internal class QuoteStatusConverter(
|
|||
rawCurrencyId = CryptoCurrency.RawID(currencyId),
|
||||
value = QuoteStatus.Data(
|
||||
source = source,
|
||||
fiatCurrency = fiatCurrency,
|
||||
fiatRate = quote.price.orZero(),
|
||||
priceChange = quote.priceChange24h.orZero().movePointLeft(2),
|
||||
fiatRateUSD = quote.priceUsd.orZero(),
|
||||
|
|
|
|||
|
|
@ -4,16 +4,16 @@ import android.content.Context
|
|||
import androidx.datastore.core.DataStoreFactory
|
||||
import androidx.datastore.dataStoreFile
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.adapter
|
||||
import com.tangem.data.quotes.multi.DefaultMultiQuoteUpdater
|
||||
import com.tangem.data.quotes.repository.DefaultQuotesRepository
|
||||
import com.tangem.data.quotes.store.DefaultQuotesStatusesStore
|
||||
import com.tangem.data.quotes.store.QuoteStatusDM
|
||||
import com.tangem.data.quotes.store.QuotesStatusesStore
|
||||
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
|
||||
import com.tangem.datasource.appcurrency.AppCurrencyResponseStore
|
||||
import com.tangem.datasource.di.NetworkMoshi
|
||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
||||
import com.tangem.datasource.utils.mapWithStringKeyTypes
|
||||
import com.tangem.domain.quotes.GetCurrencyUSDQuoteUseCase
|
||||
import com.tangem.domain.quotes.QuotesRepository
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
|
||||
|
|
@ -30,7 +30,6 @@ import javax.inject.Singleton
|
|||
@InstallIn(SingletonComponent::class)
|
||||
internal object QuotesDataModule {
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideQuotesStoreV2(
|
||||
|
|
@ -42,13 +41,13 @@ internal object QuotesDataModule {
|
|||
runtimeStore = RuntimeSharedStore(),
|
||||
persistenceDataStore = DataStoreFactory.create(
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
defaultValue = QuoteStatusDM.Empty,
|
||||
adapter = moshi.adapter<QuoteStatusDM>(),
|
||||
moshi = moshi,
|
||||
types = mapWithStringKeyTypes<QuotesResponse.Quote>(),
|
||||
defaultValue = emptyMap(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "quotes_v2") },
|
||||
produceFile = { context.dataStoreFile(fileName = "quotes") },
|
||||
scope = appScope,
|
||||
),
|
||||
legacyCacheFile = context.dataStoreFile(fileName = "quotes"),
|
||||
scope = appScope,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@ import com.tangem.data.quotes.store.QuotesStatusesStore
|
|||
import com.tangem.data.quotes.store.setSourceAsCache
|
||||
import com.tangem.data.quotes.store.setSourceAsOnlyCache
|
||||
import com.tangem.data.quotes.utils.QuotesUnsupportedCurrenciesIdAdapter
|
||||
import com.tangem.datasource.api.tangemTech.models.CurrenciesResponse
|
||||
import com.tangem.datasource.appcurrency.AppCurrencyResponseStore
|
||||
import com.tangem.domain.core.utils.catchOn
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.quotes.multi.MultiQuoteStatusFetcher
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
|
|
@ -52,10 +50,10 @@ internal class DefaultMultiQuoteStatusFetcher @Inject constructor(
|
|||
),
|
||||
)
|
||||
|
||||
val (fiatCurrencyId, fiatCurrency) = resolveFiatCurrency()
|
||||
val appCurrencyId = getAppCurrencyId(params = params)
|
||||
|
||||
val response = quotesFetcher.fetch(
|
||||
fiatCurrencyId = fiatCurrencyId,
|
||||
fiatCurrencyId = appCurrencyId,
|
||||
currenciesIds = replacementIdsResult.idsForRequest,
|
||||
fields = setOf(Field.PRICE, Field.PRICE_CHANGE_24H, Field.PRICE_USD),
|
||||
)
|
||||
|
|
@ -66,27 +64,24 @@ internal class DefaultMultiQuoteStatusFetcher @Inject constructor(
|
|||
filteredIds = replacementIdsResult.idsFiltered,
|
||||
)
|
||||
|
||||
quotesStatusesStore.store(values = updatedResponse.quotes, fiatCurrency = fiatCurrency)
|
||||
quotesStatusesStore.store(values = updatedResponse.quotes)
|
||||
}
|
||||
.onLeft { throwable ->
|
||||
TangemLogger.e("Error", throwable)
|
||||
quotesStatusesStore.setSourceAsOnlyCache(currenciesIds = params.currenciesIds)
|
||||
}
|
||||
|
||||
private suspend fun resolveFiatCurrency(): Pair<String, FiatCurrency> {
|
||||
val stored = appCurrencyResponseStore.getSyncOrNull() ?: failOnMissingAppCurrency()
|
||||
if (stored.id.isBlank()) failOnMissingAppCurrency()
|
||||
private suspend fun getAppCurrencyId(params: MultiQuoteStatusFetcher.Params): String {
|
||||
val appCurrencyId = params.appCurrencyId
|
||||
?: appCurrencyResponseStore.getSyncOrNull()?.id
|
||||
|
||||
return stored.id to stored.toFiatCurrency()
|
||||
}
|
||||
|
||||
private fun failOnMissingAppCurrency(): Nothing {
|
||||
if (appCurrencyId.isNullOrBlank()) {
|
||||
val exception = IllegalStateException("Unable to get AppCurrency for updating quotes")
|
||||
TangemLogger.e("Error", exception)
|
||||
|
||||
throw exception
|
||||
}
|
||||
|
||||
private fun CurrenciesResponse.Currency.toFiatCurrency(): FiatCurrency {
|
||||
return FiatCurrency(code = code, symbol = unit)
|
||||
return appCurrencyId
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
package com.tangem.data.quotes.store
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.tangem.data.quotes.converter.FiatCurrencyConverter
|
||||
import com.tangem.data.quotes.converter.QuoteStatusConverter
|
||||
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
|
||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.utils.coroutines.AppCoroutineScope
|
||||
import com.tangem.utils.extensions.addOrReplace
|
||||
|
|
@ -16,7 +14,6 @@ import kotlinx.coroutines.coroutineScope
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
|
||||
internal typealias CurrencyIdWithQuote = Map<String, QuotesResponse.Quote>
|
||||
|
||||
|
|
@ -24,46 +21,27 @@ internal typealias CurrencyIdWithQuote = Map<String, QuotesResponse.Quote>
|
|||
* Default implementation of [QuotesStatusesStore]
|
||||
*
|
||||
* @property runtimeStore runtime store
|
||||
* @property persistenceDataStore persistence store (keeps quotes together with the fiat currency they're expressed in)
|
||||
* @property legacyCacheFile pre-v2 cache file kept on disk; deleted once on init
|
||||
* @param scope app coroutine scope
|
||||
* @property persistenceDataStore persistence store
|
||||
* @param dispatchers dispatchers
|
||||
*/
|
||||
internal class DefaultQuotesStatusesStore(
|
||||
private val runtimeStore: RuntimeSharedStore<Set<QuoteStatus>>,
|
||||
private val persistenceDataStore: DataStore<QuoteStatusDM>,
|
||||
private val legacyCacheFile: File,
|
||||
private val persistenceDataStore: DataStore<CurrencyIdWithQuote>,
|
||||
private val scope: AppCoroutineScope,
|
||||
) : QuotesStatusesStore {
|
||||
|
||||
init {
|
||||
scope.launch {
|
||||
deleteLegacyCacheFile()
|
||||
val cachedStatuses = persistenceDataStore.data.firstOrNull()
|
||||
|
||||
val cached = persistenceDataStore.data.firstOrNull() ?: return@launch
|
||||
val fiatCurrency = cached.fiatCurrency?.let(FiatCurrencyConverter::convertBack) ?: return@launch
|
||||
|
||||
if (cached.quotes.isEmpty()) return@launch
|
||||
if (cachedStatuses.isNullOrEmpty()) return@launch
|
||||
|
||||
runtimeStore.store(
|
||||
value = QuoteStatusConverter(source = StatusSource.CACHE, fiatCurrency = fiatCurrency)
|
||||
.convertSet(input = cached.quotes.entries),
|
||||
value = QuoteStatusConverter(source = StatusSource.CACHE).convertSet(input = cachedStatuses.entries),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteLegacyCacheFile() {
|
||||
if (!legacyCacheFile.exists()) return
|
||||
runCatching { legacyCacheFile.delete() }
|
||||
.onSuccess { deleted ->
|
||||
if (deleted) {
|
||||
TangemLogger.i("Deleted legacy quotes cache file: ${legacyCacheFile.name}")
|
||||
} else {
|
||||
TangemLogger.e("Could not delete legacy quotes cache file: ${legacyCacheFile.name}")
|
||||
}
|
||||
}
|
||||
.onFailure { TangemLogger.e("Failed to delete legacy quotes cache file", it) }
|
||||
}
|
||||
|
||||
override fun get(): Flow<Set<QuoteStatus>> = runtimeStore.get()
|
||||
|
||||
override suspend fun getAllSyncOrNull(): Set<QuoteStatus>? = runtimeStore.getSyncOrNull()
|
||||
|
|
@ -103,33 +81,24 @@ internal class DefaultQuotesStatusesStore(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun store(values: CurrencyIdWithQuote, fiatCurrency: FiatCurrency) {
|
||||
override suspend fun store(values: CurrencyIdWithQuote) {
|
||||
if (values.isEmpty()) return
|
||||
|
||||
coroutineScope {
|
||||
launch { storeInRuntime(values = values, fiatCurrency = fiatCurrency) }
|
||||
launch { storeInPersistence(values = values, fiatCurrency = fiatCurrency) }
|
||||
launch { storeInRuntime(values = values) }
|
||||
launch { storeInPersistence(values = values) }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun storeInRuntime(values: CurrencyIdWithQuote, fiatCurrency: FiatCurrency) {
|
||||
val quotes = QuoteStatusConverter(source = StatusSource.ACTUAL, fiatCurrency = fiatCurrency)
|
||||
.convertSet(input = values.entries)
|
||||
private suspend fun storeInRuntime(values: CurrencyIdWithQuote) {
|
||||
val quotes = QuoteStatusConverter(source = StatusSource.ACTUAL).convertSet(input = values.entries)
|
||||
|
||||
runtimeStore.update(default = emptySet()) { saved ->
|
||||
saved.addOrReplace(items = quotes) { prev, new -> prev.rawCurrencyId == new.rawCurrencyId }
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun storeInPersistence(values: CurrencyIdWithQuote, fiatCurrency: FiatCurrency) {
|
||||
persistenceDataStore.updateData { stored ->
|
||||
val isSameCurrency = stored.fiatCurrency?.code == fiatCurrency.code
|
||||
val mergedQuotes = if (isSameCurrency) stored.quotes + values else values
|
||||
|
||||
QuoteStatusDM(
|
||||
fiatCurrency = FiatCurrencyConverter.convert(fiatCurrency),
|
||||
quotes = mergedQuotes,
|
||||
)
|
||||
}
|
||||
private suspend fun storeInPersistence(values: CurrencyIdWithQuote) {
|
||||
persistenceDataStore.updateData { storedQuotes -> storedQuotes + values }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package com.tangem.data.quotes.store
|
||||
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
|
||||
|
||||
/**
|
||||
* Persisted form of [com.tangem.domain.models.quote.QuoteStatus] cache. Carries the fiat currency
|
||||
* the quotes are expressed in, so it can be restored on cold start.
|
||||
*
|
||||
* @property fiatCurrency fiat currency the [quotes] are expressed in; `null` for an empty default cache
|
||||
* @property quotes map of currency id to its quote
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class QuoteStatusDM(
|
||||
val fiatCurrency: FiatCurrency?,
|
||||
val quotes: Map<String, QuotesResponse.Quote>,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class FiatCurrency(
|
||||
val code: String,
|
||||
val symbol: String,
|
||||
)
|
||||
|
||||
companion object {
|
||||
val Empty = QuoteStatusDM(fiatCurrency = null, quotes = emptyMap())
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.tangem.data.quotes.store
|
|||
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
|
|
@ -40,9 +39,8 @@ internal interface QuotesStatusesStore {
|
|||
* Store quotes statuses
|
||||
*
|
||||
* @param values map of currency ids and quotes
|
||||
* @param fiatCurrency fiat currency the [values] are expressed in
|
||||
*
|
||||
* See complex methods in `QuotesStatusesStoreExt`.
|
||||
*/
|
||||
suspend fun store(values: Map<String, QuotesResponse.Quote>, fiatCurrency: FiatCurrency)
|
||||
suspend fun store(values: Map<String, QuotesResponse.Quote>)
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import com.tangem.common.test.data.quote.toDomain
|
|||
import com.tangem.datasource.api.tangemTech.models.QuotesResponse
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.test.core.ProvideTestModels
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
|
@ -25,8 +24,7 @@ internal class QuoteStatusConverterTest {
|
|||
@ProvideTestModels
|
||||
fun convert(model: ConvertTestModel) {
|
||||
// Act
|
||||
val actual = QuoteStatusConverter(source = model.source, fiatCurrency = FiatCurrency.Default)
|
||||
.convert(value = model.value)
|
||||
val actual = QuoteStatusConverter(source = model.source).convert(value = model.value)
|
||||
|
||||
// Assert
|
||||
val expected = model.expected
|
||||
|
|
@ -64,7 +62,6 @@ internal class QuoteStatusConverterTest {
|
|||
rawCurrencyId = CryptoCurrency.RawID("ETH"),
|
||||
value = QuoteStatus.Data(
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal.ZERO,
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
priceChange = BigDecimal("0.00"),
|
||||
|
|
@ -86,7 +83,6 @@ internal class QuoteStatusConverterTest {
|
|||
rawCurrencyId = CryptoCurrency.RawID("ETH"),
|
||||
value = QuoteStatus.Data(
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal.ZERO,
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
priceChange = BigDecimal("0.00"),
|
||||
|
|
@ -108,7 +104,6 @@ internal class QuoteStatusConverterTest {
|
|||
rawCurrencyId = CryptoCurrency.RawID("ETH"),
|
||||
value = QuoteStatus.Data(
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal.ONE,
|
||||
fiatRateUSD = BigDecimal.ONE,
|
||||
priceChange = BigDecimal("0.01"),
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ internal class DefaultMultiQuoteStatusFetcherTest {
|
|||
quotesStore.setSourceAsCache(currenciesIds = params.currenciesIds)
|
||||
appCurrencyResponseStore.getSyncOrNull()
|
||||
quotesFetcher.fetch(fiatCurrencyId = "usd", currenciesIds = currenciesIds, fields = fields)
|
||||
quotesStore.store(values = successResponse.quotes, fiatCurrency = any())
|
||||
quotesStore.store(values = successResponse.quotes)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -93,21 +93,21 @@ internal class DefaultMultiQuoteStatusFetcherTest {
|
|||
quotesStore.setSourceAsCache(currenciesIds = any())
|
||||
appCurrencyResponseStore.getSyncOrNull()
|
||||
quotesFetcher.fetch(fiatCurrencyId = any(), currenciesIds = any(), fields = any())
|
||||
quotesStore.store(values = any(), fiatCurrency = any())
|
||||
quotesStore.store(values = any())
|
||||
quotesStore.setSourceAsOnlyCache(currenciesIds = any())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `fetch ignores params appCurrencyId and uses stored app currency`() = runTest {
|
||||
// Arrange: params.appCurrencyId is set but different from stored — fetcher must still use stored
|
||||
val params = MultiQuoteStatusFetcher.Params(currenciesIds = currenciesIds, appCurrencyId = "eur")
|
||||
fun `fetch successfully if appCurrencyId from params is not null`() = runTest {
|
||||
// Arrange
|
||||
val appCurrencyId = "usd"
|
||||
val params = MultiQuoteStatusFetcher.Params(currenciesIds = currenciesIds, appCurrencyId = appCurrencyId)
|
||||
|
||||
val currenciesIds = setOf("BTC", "ETH")
|
||||
|
||||
coEvery { appCurrencyResponseStore.getSyncOrNull() } returns usdAppCurrency
|
||||
coEvery {
|
||||
quotesFetcher.fetch(fiatCurrencyId = "usd", currenciesIds = currenciesIds, fields = fields)
|
||||
quotesFetcher.fetch(fiatCurrencyId = appCurrencyId, currenciesIds = currenciesIds, fields = fields)
|
||||
} returns successResponse.right()
|
||||
|
||||
// Act
|
||||
|
|
@ -119,16 +119,42 @@ internal class DefaultMultiQuoteStatusFetcherTest {
|
|||
|
||||
coVerifyOrder {
|
||||
quotesStore.setSourceAsCache(currenciesIds = params.currenciesIds)
|
||||
appCurrencyResponseStore.getSyncOrNull()
|
||||
quotesFetcher.fetch(fiatCurrencyId = "usd", currenciesIds = currenciesIds, fields = fields)
|
||||
quotesStore.store(values = successResponse.quotes, fiatCurrency = any())
|
||||
quotesFetcher.fetch(fiatCurrencyId = appCurrencyId, currenciesIds = currenciesIds, fields = fields)
|
||||
quotesStore.store(values = successResponse.quotes)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
appCurrencyResponseStore.getSyncOrNull()
|
||||
quotesStore.setSourceAsOnlyCache(currenciesIds = any())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `fetch failure because appCurrencyId from params is blank`() = runTest {
|
||||
// Arrange
|
||||
val appCurrencyId = ""
|
||||
val params = MultiQuoteStatusFetcher.Params(currenciesIds = currenciesIds, appCurrencyId = appCurrencyId)
|
||||
|
||||
// Act
|
||||
val actual = fetcher(params)
|
||||
|
||||
// Assert
|
||||
val expected = IllegalStateException("Unable to get AppCurrency for updating quotes").left()
|
||||
|
||||
assertEither(actual, expected)
|
||||
|
||||
coVerifyOrder {
|
||||
quotesStore.setSourceAsCache(currenciesIds = params.currenciesIds)
|
||||
quotesStore.setSourceAsOnlyCache(currenciesIds = params.currenciesIds)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
appCurrencyResponseStore.getSyncOrNull()
|
||||
quotesFetcher.fetch(fiatCurrencyId = any(), currenciesIds = any(), fields = any())
|
||||
quotesStore.store(values = any())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `fetch failure because api request failed`() = runTest {
|
||||
// Arrange
|
||||
|
|
@ -160,7 +186,7 @@ internal class DefaultMultiQuoteStatusFetcherTest {
|
|||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
quotesStore.store(values = any(), fiatCurrency = any())
|
||||
quotesStore.store(values = any())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -187,7 +213,7 @@ internal class DefaultMultiQuoteStatusFetcherTest {
|
|||
|
||||
coVerify(inverse = true) {
|
||||
quotesFetcher.fetch(fiatCurrencyId = any(), currenciesIds = any(), fields = any())
|
||||
quotesStore.store(values = any(), fiatCurrency = any())
|
||||
quotesStore.store(values = any())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.google.common.truth.Truth
|
|||
import com.tangem.data.quotes.store.QuotesStatusesStore
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.quotes.QuotesRepository
|
||||
import com.tangem.test.core.ProvideTestModels
|
||||
|
|
@ -42,7 +41,6 @@ internal class DefaultQuotesRepositoryTest {
|
|||
private val ethQuote = QuoteStatus(
|
||||
rawCurrencyId = ethRawId,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatRate = BigDecimal.ZERO,
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
|
|
@ -113,7 +111,6 @@ internal class DefaultQuotesRepositoryTest {
|
|||
private val ethQuote = QuoteStatus(
|
||||
rawCurrencyId = ethRawId,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatRate = BigDecimal.ZERO,
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import com.tangem.data.quotes.store.QuotesStatusesStore
|
|||
import com.tangem.domain.core.flow.FlowProducerTools
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.quotes.single.SingleQuoteStatusProducer
|
||||
import com.tangem.test.core.getEmittedValues
|
||||
|
|
@ -82,7 +81,6 @@ internal class DefaultSingleQuoteStatusProducerTest {
|
|||
val updatedStatus = QuoteStatus(
|
||||
rawCurrencyId = params.rawCurrencyId,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal.ONE,
|
||||
priceChange = BigDecimal.ZERO,
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
|
|
@ -131,7 +129,6 @@ internal class DefaultSingleQuoteStatusProducerTest {
|
|||
val status = QuoteStatus(
|
||||
rawCurrencyId = params.rawCurrencyId,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal.ONE,
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
priceChange = BigDecimal.ZERO,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import kotlin.properties.Delegates
|
|||
internal class QuotesStatusesStoreExtTest {
|
||||
|
||||
private var runtimeStore: RuntimeSharedStore<Set<QuoteStatus>> by Delegates.notNull()
|
||||
private var persistenceStore: MockStateDataStore<QuoteStatusDM> by Delegates.notNull()
|
||||
private var persistenceStore: MockStateDataStore<CurrencyIdWithQuote> by Delegates.notNull()
|
||||
private var store: DefaultQuotesStatusesStore by Delegates.notNull()
|
||||
|
||||
private val btcQuoteDM = "BTC" to MockQuoteResponseFactory.createSinglePrice(BigDecimal.ZERO)
|
||||
|
|
@ -34,12 +34,11 @@ internal class QuotesStatusesStoreExtTest {
|
|||
@BeforeEach
|
||||
fun resetMocks() {
|
||||
runtimeStore = RuntimeSharedStore()
|
||||
persistenceStore = MockStateDataStore(default = QuoteStatusDM.Empty)
|
||||
persistenceStore = MockStateDataStore(default = emptyMap())
|
||||
|
||||
store = DefaultQuotesStatusesStore(
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
legacyCacheFile = java.io.File("legacy-quotes-cache-noop"),
|
||||
scope = TestAppCoroutineScope(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ import com.tangem.common.test.TestAppCoroutineScope
|
|||
import com.tangem.common.test.data.quote.MockQuoteResponseFactory
|
||||
import com.tangem.common.test.data.quote.toDomain
|
||||
import com.tangem.common.test.datastore.MockStateDataStore
|
||||
import com.tangem.data.quotes.converter.FiatCurrencyConverter
|
||||
import com.tangem.datasource.local.datastore.RuntimeSharedStore
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.test.core.ProvideTestModels
|
||||
import com.tangem.test.core.getEmittedValues
|
||||
|
|
@ -33,7 +31,7 @@ import kotlin.properties.Delegates
|
|||
internal class QuotesStatusesStoreTest {
|
||||
|
||||
private var runtimeStore: RuntimeSharedStore<Set<QuoteStatus>> by Delegates.notNull()
|
||||
private var persistenceStore: MockStateDataStore<QuoteStatusDM> by Delegates.notNull()
|
||||
private var persistenceStore: MockStateDataStore<CurrencyIdWithQuote> by Delegates.notNull()
|
||||
private var store: DefaultQuotesStatusesStore by Delegates.notNull()
|
||||
|
||||
// region Data models
|
||||
|
|
@ -50,12 +48,11 @@ internal class QuotesStatusesStoreTest {
|
|||
@BeforeEach
|
||||
fun resetMocks() {
|
||||
runtimeStore = RuntimeSharedStore()
|
||||
persistenceStore = MockStateDataStore(default = QuoteStatusDM.Empty)
|
||||
persistenceStore = MockStateDataStore(default = emptyMap())
|
||||
|
||||
store = DefaultQuotesStatusesStore(
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
legacyCacheFile = java.io.File("legacy-quotes-cache-noop"),
|
||||
scope = TestAppCoroutineScope(),
|
||||
)
|
||||
}
|
||||
|
|
@ -68,7 +65,7 @@ internal class QuotesStatusesStoreTest {
|
|||
fun `initialization if cache store is empty`() = runTest {
|
||||
// Arrange
|
||||
val runtimeStore = RuntimeSharedStore<Set<QuoteStatus>>()
|
||||
val persistenceStore: DataStore<QuoteStatusDM> = mockk()
|
||||
val persistenceStore: DataStore<CurrencyIdWithQuote> = mockk()
|
||||
|
||||
every { persistenceStore.data } returns emptyFlow()
|
||||
|
||||
|
|
@ -76,7 +73,6 @@ internal class QuotesStatusesStoreTest {
|
|||
DefaultQuotesStatusesStore(
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
legacyCacheFile = java.io.File("legacy-quotes-cache-noop"),
|
||||
scope = TestAppCoroutineScope(),
|
||||
)
|
||||
|
||||
|
|
@ -91,13 +87,12 @@ internal class QuotesStatusesStoreTest {
|
|||
fun `initialization if cache store contains empty map`() = runTest {
|
||||
// Arrange
|
||||
val runtimeStore = RuntimeSharedStore<Set<QuoteStatus>>()
|
||||
val persistenceStore = MockStateDataStore<QuoteStatusDM>(default = QuoteStatusDM.Empty)
|
||||
val persistenceStore = MockStateDataStore<CurrencyIdWithQuote>(default = emptyMap())
|
||||
|
||||
// Act
|
||||
DefaultQuotesStatusesStore(
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
legacyCacheFile = java.io.File("legacy-quotes-cache-noop"),
|
||||
scope = TestAppCoroutineScope(),
|
||||
)
|
||||
|
||||
|
|
@ -112,20 +107,19 @@ internal class QuotesStatusesStoreTest {
|
|||
fun `initialization if cache store is not empty`() = runTest {
|
||||
// Arrange
|
||||
val runtimeStore = RuntimeSharedStore<Set<QuoteStatus>>()
|
||||
val persistenceStore = MockStateDataStore<QuoteStatusDM>(default = QuoteStatusDM.Empty)
|
||||
val persistenceStore = MockStateDataStore<CurrencyIdWithQuote>(default = emptyMap())
|
||||
|
||||
persistenceStore.updateData {
|
||||
QuoteStatusDM(
|
||||
fiatCurrency = FiatCurrencyConverter.convert(FiatCurrency.Default),
|
||||
quotes = mapOf(btcQuoteDM, ethQuoteDM),
|
||||
)
|
||||
it.toMutableMap().apply {
|
||||
this += btcQuoteDM
|
||||
this += ethQuoteDM
|
||||
}
|
||||
}
|
||||
|
||||
// Act
|
||||
DefaultQuotesStatusesStore(
|
||||
runtimeStore = runtimeStore,
|
||||
persistenceDataStore = persistenceStore,
|
||||
legacyCacheFile = java.io.File("legacy-quotes-cache-noop"),
|
||||
scope = TestAppCoroutineScope(),
|
||||
)
|
||||
|
||||
|
|
@ -477,7 +471,7 @@ internal class QuotesStatusesStoreTest {
|
|||
}
|
||||
|
||||
// Act
|
||||
store.store(values = model.values, fiatCurrency = FiatCurrency.Default)
|
||||
store.store(values = model.values)
|
||||
|
||||
val runtimeActual = runtimeStore.getSyncOrNull()
|
||||
val persistenceActual = getEmittedValues(persistenceStore.data)
|
||||
|
|
@ -497,14 +491,14 @@ internal class QuotesStatusesStoreTest {
|
|||
initialPersistence = null,
|
||||
values = emptyMap(),
|
||||
runtimeExpected = null,
|
||||
persistenceExpected = QuoteStatusDM.Empty,
|
||||
persistenceExpected = emptyMap(),
|
||||
),
|
||||
StoreTestModel(
|
||||
initialRuntime = null,
|
||||
initialPersistence = null,
|
||||
values = mapOf(btcQuoteDM),
|
||||
runtimeExpected = setOf(btcQuote),
|
||||
persistenceExpected = persistedDefault(btcQuoteDM),
|
||||
persistenceExpected = mapOf(btcQuoteDM),
|
||||
),
|
||||
// endregion
|
||||
|
||||
|
|
@ -514,48 +508,48 @@ internal class QuotesStatusesStoreTest {
|
|||
initialPersistence = null,
|
||||
values = emptyMap(),
|
||||
runtimeExpected = setOf(btcQuote),
|
||||
persistenceExpected = QuoteStatusDM.Empty,
|
||||
persistenceExpected = emptyMap(),
|
||||
),
|
||||
StoreTestModel(
|
||||
initialRuntime = setOf(ethQuote),
|
||||
initialPersistence = null,
|
||||
values = mapOf(btcQuoteDM),
|
||||
runtimeExpected = setOf(ethQuote, btcQuote),
|
||||
persistenceExpected = persistedDefault(btcQuoteDM),
|
||||
persistenceExpected = mapOf(btcQuoteDM),
|
||||
),
|
||||
// endregion
|
||||
|
||||
// region runtime store is null
|
||||
StoreTestModel(
|
||||
initialRuntime = null,
|
||||
initialPersistence = persistedDefault(btcQuoteDM),
|
||||
initialPersistence = mapOf(btcQuoteDM),
|
||||
values = emptyMap(),
|
||||
runtimeExpected = null,
|
||||
persistenceExpected = persistedDefault(btcQuoteDM),
|
||||
persistenceExpected = mapOf(btcQuoteDM),
|
||||
),
|
||||
StoreTestModel(
|
||||
initialRuntime = null,
|
||||
initialPersistence = persistedDefault(ethQuoteDM),
|
||||
initialPersistence = mapOf(ethQuoteDM),
|
||||
values = mapOf(btcQuoteDM),
|
||||
runtimeExpected = setOf(btcQuote),
|
||||
persistenceExpected = persistedDefault(ethQuoteDM, btcQuoteDM),
|
||||
persistenceExpected = mapOf(ethQuoteDM, btcQuoteDM),
|
||||
),
|
||||
// endregion
|
||||
|
||||
// region stores contain data
|
||||
StoreTestModel(
|
||||
initialRuntime = setOf(btcQuote),
|
||||
initialPersistence = persistedDefault(btcQuoteDM),
|
||||
initialPersistence = mapOf(btcQuoteDM),
|
||||
values = emptyMap(),
|
||||
runtimeExpected = setOf(btcQuote),
|
||||
persistenceExpected = persistedDefault(btcQuoteDM),
|
||||
persistenceExpected = mapOf(btcQuoteDM),
|
||||
),
|
||||
StoreTestModel(
|
||||
initialRuntime = setOf(btcQuote),
|
||||
initialPersistence = persistedDefault(btcQuoteDM),
|
||||
initialPersistence = mapOf(btcQuoteDM),
|
||||
values = mapOf(ethQuoteDM),
|
||||
runtimeExpected = setOf(ethQuote, btcQuote),
|
||||
persistenceExpected = persistedDefault(ethQuoteDM, btcQuoteDM),
|
||||
persistenceExpected = mapOf(ethQuoteDM, btcQuoteDM),
|
||||
),
|
||||
// endregion
|
||||
)
|
||||
|
|
@ -563,18 +557,9 @@ internal class QuotesStatusesStoreTest {
|
|||
|
||||
data class StoreTestModel(
|
||||
val initialRuntime: Set<QuoteStatus>?,
|
||||
val initialPersistence: QuoteStatusDM?,
|
||||
val initialPersistence: CurrencyIdWithQuote?,
|
||||
val values: CurrencyIdWithQuote,
|
||||
val persistenceExpected: QuoteStatusDM?,
|
||||
val persistenceExpected: CurrencyIdWithQuote?,
|
||||
val runtimeExpected: Set<QuoteStatus>?,
|
||||
)
|
||||
|
||||
companion object {
|
||||
private fun persistedDefault(
|
||||
vararg quotes: Pair<String, com.tangem.datasource.api.tangemTech.models.QuotesResponse.Quote>,
|
||||
): QuoteStatusDM = QuoteStatusDM(
|
||||
fiatCurrency = FiatCurrencyConverter.convert(FiatCurrency.Default),
|
||||
quotes = mapOf(*quotes),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,5 @@ dependencies {
|
|||
/** Project - Domain */
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.domain.core)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.appCurrency.models)
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.tangem.domain.appcurrency.extenstions
|
|||
import arrow.core.getOrElse
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
|
|
@ -15,5 +14,3 @@ suspend fun GetSelectedAppCurrencyUseCase.unwrap(): AppCurrency {
|
|||
.firstOrNull()
|
||||
?: AppCurrency.Default
|
||||
}
|
||||
|
||||
fun AppCurrency.toFiatCurrency(): FiatCurrency = FiatCurrency(code = code, symbol = symbol)
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
package com.tangem.domain.models.currency
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Fiat currency in which a [com.tangem.domain.models.quote.QuoteStatus] is expressed. Plain business
|
||||
* entity without UI metadata (icons, localized name) — those live in `AppCurrency`.
|
||||
*
|
||||
* @property code ISO code, e.g. "USD"
|
||||
* @property symbol display symbol, e.g. "$"
|
||||
*/
|
||||
@Serializable
|
||||
data class FiatCurrency(
|
||||
val code: String,
|
||||
val symbol: String,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
val Default = FiatCurrency(code = "USD", symbol = "$")
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,6 @@ package com.tangem.domain.models.quote
|
|||
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import java.math.BigDecimal
|
||||
|
||||
/**
|
||||
|
|
@ -40,14 +39,12 @@ data class QuoteStatus(val rawCurrencyId: CryptoCurrency.RawID, val value: Value
|
|||
* price change.
|
||||
*
|
||||
* @property source status source
|
||||
* @property fiatCurrency fiat currency in which [fiatRate] is expressed
|
||||
* @property fiatRate the current fiat exchange rate for the cryptocurrency
|
||||
* @property fiatRateUSD the current fiat exchange rate in USD for the cryptocurrency
|
||||
* @property priceChange the price change for the cryptocurrency
|
||||
*/
|
||||
data class Data(
|
||||
override val source: StatusSource,
|
||||
val fiatCurrency: FiatCurrency,
|
||||
val fiatRate: BigDecimal,
|
||||
val fiatRateUSD: BigDecimal,
|
||||
val priceChange: BigDecimal,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.domain.tokens.mock
|
|||
import arrow.core.nonEmptySetOf
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import java.math.BigDecimal
|
||||
|
||||
|
|
@ -13,7 +12,6 @@ internal object MockQuotes {
|
|||
val quote1 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token1.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("1.23"),
|
||||
fiatRateUSD = BigDecimal("1.23"),
|
||||
priceChange = BigDecimal("0.01"),
|
||||
|
|
@ -24,7 +22,6 @@ internal object MockQuotes {
|
|||
val quote2 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token2.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("2.34"),
|
||||
fiatRateUSD = BigDecimal("2.34"),
|
||||
priceChange = BigDecimal("-0.02"),
|
||||
|
|
@ -35,7 +32,6 @@ internal object MockQuotes {
|
|||
val quote3 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token3.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("3.45"),
|
||||
fiatRateUSD = BigDecimal("3.45"),
|
||||
priceChange = BigDecimal("0.03"),
|
||||
|
|
@ -46,7 +42,6 @@ internal object MockQuotes {
|
|||
val quote4 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token4.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("4.56"),
|
||||
fiatRateUSD = BigDecimal("4.56"),
|
||||
priceChange = BigDecimal("-0.04"),
|
||||
|
|
@ -57,7 +52,6 @@ internal object MockQuotes {
|
|||
val quote5 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token5.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("5.67"),
|
||||
fiatRateUSD = BigDecimal("5.67"),
|
||||
priceChange = BigDecimal("0.05"),
|
||||
|
|
@ -68,7 +62,6 @@ internal object MockQuotes {
|
|||
val quote6 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token6.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("6.78"),
|
||||
fiatRateUSD = BigDecimal("6.78"),
|
||||
priceChange = BigDecimal("-0.06"),
|
||||
|
|
@ -79,7 +72,6 @@ internal object MockQuotes {
|
|||
val quote7 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token7.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("7.89"),
|
||||
fiatRateUSD = BigDecimal("7.89"),
|
||||
priceChange = BigDecimal("0.07"),
|
||||
|
|
@ -90,7 +82,6 @@ internal object MockQuotes {
|
|||
val quote8 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token8.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("8.90"),
|
||||
fiatRateUSD = BigDecimal("8.90"),
|
||||
priceChange = BigDecimal("-0.08"),
|
||||
|
|
@ -101,7 +92,6 @@ internal object MockQuotes {
|
|||
val quote9 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token9.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("9.01"),
|
||||
fiatRateUSD = BigDecimal("9.01"),
|
||||
priceChange = BigDecimal("0.09"),
|
||||
|
|
@ -112,7 +102,6 @@ internal object MockQuotes {
|
|||
val quote10 = QuoteStatus(
|
||||
rawCurrencyId = MockTokens.token10.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = BigDecimal("10.12"),
|
||||
fiatRateUSD = BigDecimal("10.12"),
|
||||
priceChange = BigDecimal("-0.10"),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.network.NetworkStatus
|
||||
|
|
@ -44,7 +43,6 @@ class CryptoCurrencyStatusFactoryTest {
|
|||
)
|
||||
|
||||
private val fullQuote = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
fiatRate = 1800.0.toBigDecimal(),
|
||||
fiatRateUSD = 1800.0.toBigDecimal(),
|
||||
priceChange = (-2.5).toBigDecimal(),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import com.tangem.domain.core.utils.lceError
|
|||
import com.tangem.domain.core.utils.lceLoading
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.quote.PriceChange
|
||||
import com.tangem.domain.tokens.mock.MockTokens
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.domain.models.StatusSource
|
|||
import com.tangem.domain.models.TotalFiatBalance
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.staking.BalanceItem
|
||||
import com.tangem.domain.models.staking.BalanceType
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.domain.account.models.AccountList
|
|||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
|
|
@ -82,7 +81,6 @@ class YieldSupplyMinAmountUseCaseTest {
|
|||
QuoteStatus(
|
||||
rawCurrencyId = CryptoCurrency.RawID("polygon-ecosystem-token"),
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatRate = nativeFiatRate,
|
||||
fiatRateUSD = nativeFiatRate,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import arrow.core.Either
|
|||
import com.google.common.truth.Truth.assertThat
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.domain.account.models.AccountList
|
|||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
|
|
@ -78,7 +77,6 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
QuoteStatus(
|
||||
rawCurrencyId = nativeCoin.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatRate = nativeFiatRate,
|
||||
fiatRateUSD = nativeFiatRate,
|
||||
|
|
@ -131,7 +129,6 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
QuoteStatus(
|
||||
rawCurrencyId = nativeCoin.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatRate = nativeFiatRate,
|
||||
fiatRateUSD = nativeFiatRate,
|
||||
|
|
@ -259,7 +256,6 @@ class YieldSupplyGetCurrentFeeUseCaseTest {
|
|||
QuoteStatus(
|
||||
rawCurrencyId = nativeCoin.id.rawCurrencyId!!,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatRate = BigDecimal.ZERO, // non-positive
|
||||
fiatRateUSD = BigDecimal.ZERO,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.google.common.truth.Truth.assertThat
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import org.junit.jupiter.api.Test
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.core.ui.format.bigdecimal.format
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.network.Network
|
||||
import com.tangem.domain.models.network.NetworkAddress
|
||||
import com.tangem.domain.yield.supply.YieldSupplyRepository
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import com.tangem.blockchain.common.transaction.TransactionFee
|
|||
import com.tangem.blockchainsdk.utils.toNetworkId
|
||||
import com.tangem.domain.models.StatusSource
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.FiatCurrency
|
||||
import com.tangem.domain.models.quote.QuoteStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.swap.models.SwapCurrencyStatus
|
||||
|
|
@ -87,7 +86,6 @@ internal class SwapInteractorImplFindBestQuoteTest : SwapInteractorImplTestBase(
|
|||
QuoteStatus(
|
||||
rawCurrencyId = rawId,
|
||||
value = QuoteStatus.Data(
|
||||
fiatCurrency = FiatCurrency.Default,
|
||||
source = StatusSource.ACTUAL,
|
||||
fiatRate = BigDecimal.ONE,
|
||||
fiatRateUSD = BigDecimal.ONE,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue