diff --git a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/QuotesResponse.kt b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/QuotesResponse.kt index 8c42687aa8..b9b4460255 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/QuotesResponse.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/api/tangemTech/models/QuotesResponse.kt @@ -20,5 +20,16 @@ data class QuotesResponse( val priceChange1w: BigDecimal?, @Json(name = "priceChange30d") val priceChange30d: BigDecimal?, - ) + ) { + + companion object { + + val EMPTY = Quote( + price = null, + priceChange24h = null, + priceChange1w = null, + priceChange30d = null, + ) + } + } } \ No newline at end of file diff --git a/data/quotes/src/main/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcher.kt b/data/quotes/src/main/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcher.kt index 618f75178d..4eac6b1927 100644 --- a/data/quotes/src/main/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcher.kt +++ b/data/quotes/src/main/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcher.kt @@ -8,6 +8,7 @@ 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.QuotesResponse import com.tangem.datasource.appcurrency.AppCurrencyResponseStore import com.tangem.domain.core.utils.catchOn import com.tangem.domain.models.currency.CryptoCurrency @@ -58,6 +59,7 @@ internal class DefaultMultiQuoteStatusFetcher @Inject constructor( fields = setOf(Field.PRICE, Field.PRICE_CHANGE_24H), ) .getOrElse { error("Cause: $it") } + .addSkippedIfHas(ids = replacementIdsResult.idsForRequest) val updatedResponse = QuotesUnsupportedCurrenciesIdAdapter.getResponseWithUnsupportedCurrencies( response = response, @@ -84,4 +86,16 @@ internal class DefaultMultiQuoteStatusFetcher @Inject constructor( return appCurrencyId } + + private fun QuotesResponse.addSkippedIfHas(ids: Set): QuotesResponse { + val skippedIds = ids.filterNot(quotes.keys::contains).ifEmpty { + return this + } + + Timber.d("Some quotes are missing from the server response: $skippedIds") + + val emptyQuotes = skippedIds.associateWith { QuotesResponse.Quote.EMPTY } + + return copy(quotes = quotes + emptyQuotes) + } } \ No newline at end of file diff --git a/data/quotes/src/test/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcherTest.kt b/data/quotes/src/test/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcherTest.kt index d522ca5ba9..16d16ee6b0 100644 --- a/data/quotes/src/test/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcherTest.kt +++ b/data/quotes/src/test/java/com/tangem/data/quotes/multi/DefaultMultiQuoteStatusFetcherTest.kt @@ -215,6 +215,50 @@ internal class DefaultMultiQuoteStatusFetcherTest { } } + @Test + fun `fetch successfully if not all quotes are fetched`() = runTest { + // Arrange + val params = MultiQuoteStatusFetcher.Params(currenciesIds = currenciesIds, appCurrencyId = null) + + coEvery { appCurrencyResponseStore.getSyncOrNull() } returns usdAppCurrency + + val currenciesIds = setOf("BTC", "ETH") + val response = QuotesResponse( + quotes = mapOf( + "BTC" to MockQuoteResponseFactory.createSinglePrice(value = BigDecimal.ONE), + ), + ) + + coEvery { + quotesFetcher.fetch(fiatCurrencyId = "usd", currenciesIds = currenciesIds, fields = fields) + } returns response.right() + + // Act + val actual = fetcher(params) + + // Assert + val expected = Unit.right() + Truth.assertThat(actual).isEqualTo(expected) + + val storedQuotes = QuotesResponse( + quotes = mapOf( + "BTC" to MockQuoteResponseFactory.createSinglePrice(value = BigDecimal.ONE), + "ETH" to QuotesResponse.Quote.EMPTY, + ), + ) + + coVerifyOrder { + quotesStore.setSourceAsCache(currenciesIds = params.currenciesIds) + appCurrencyResponseStore.getSyncOrNull() + quotesFetcher.fetch(fiatCurrencyId = "usd", currenciesIds = currenciesIds, fields = fields) + quotesStore.store(values = storedQuotes.quotes) + } + + coVerify(inverse = true) { + quotesStore.setSourceAsOnlyCache(currenciesIds = any()) + } + } + private companion object { val currenciesIds = setOf(