Updated on 2026-08-14

This commit is contained in:
Tangem 2023-08-07 13:01:47 +03:00
parent dd186d6fbc
commit 3f5f3ef68b
23 changed files with 351 additions and 128 deletions

View file

@ -6,4 +6,9 @@ sealed class DataError : Exception() {
object NoInternetConnection : NetworkError()
}
sealed class UserWalletError : DataError() {
data class WrongUserWallet(override val message: String) : UserWalletError()
}
}

View file

@ -9,14 +9,14 @@ import arrow.core.toNonEmptySetOrNull
import com.tangem.domain.tokens.error.TokenListSortingError
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.tokens.repository.TokensRepository
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.withContext
class ApplyTokenListSortingUseCase(
private val tokensRepository: TokensRepository,
private val currenciesRepository: CurrenciesRepository,
private val dispatchers: CoroutineDispatcherProvider,
) {
@ -67,7 +67,9 @@ class ApplyTokenListSortingUseCase(
private suspend fun Raise<TokenListSortingError>.getCurrencies(userWalletId: UserWalletId): Set<CryptoCurrency> {
val tokens = catch(
block = { tokensRepository.getMultiCurrencyWalletCurrencies(userWalletId, refresh = false).firstOrNull() },
block = {
currenciesRepository.getMultiCurrencyWalletCurrencies(userWalletId, refresh = false).firstOrNull()
},
catch = { raise(TokenListSortingError.DataError(it)) },
)
@ -83,7 +85,7 @@ class ApplyTokenListSortingUseCase(
isSortedByBalance: Boolean,
) = withContext(dispatchers.io) {
catch(
block = { tokensRepository.saveTokens(userWalletId, tokens, isGrouped, isSortedByBalance) },
block = { currenciesRepository.saveTokens(userWalletId, tokens, isGrouped, isSortedByBalance) },
catch = { raise(TokenListSortingError.DataError(it)) },
)
}

View file

@ -0,0 +1,82 @@
package com.tangem.domain.tokens
import arrow.core.Either
import arrow.core.left
import arrow.core.raise.Raise
import arrow.core.raise.recover
import arrow.core.right
import com.tangem.domain.tokens.error.CurrencyError
import com.tangem.domain.tokens.error.mapper.mapToTokenError
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest
/**
* Use case for fetching the status of a specific cryptocurrency associated with a user wallet.
*
* @property currenciesRepository Repository for managing and fetching cryptocurrencies.
* @property quotesRepository Repository for managing and fetching cryptocurrency quotes.
* @property networksRepository Repository for managing and fetching information related to blockchain networks.
* @property dispatchers Provides coroutine dispatchers.
*/
class GetCurrencyUseCase(
private val currenciesRepository: CurrenciesRepository,
private val quotesRepository: QuotesRepository,
private val networksRepository: NetworksRepository,
private val dispatchers: CoroutineDispatcherProvider,
) {
/**
* Invokes the use case.
*
* @param userWalletId The unique identifier of the user's wallet.
* @param currencyId The unique identifier of the cryptocurrency.
* @param refresh A boolean flag indicating whether the data should be refreshed.
* @return A [Flow] emitting either a [CurrencyError] or a [CryptoCurrencyStatus], indicating the result of the fetch operation.
*/
operator fun invoke(
userWalletId: UserWalletId,
currencyId: CryptoCurrency.ID,
refresh: Boolean = false,
): Flow<Either<CurrencyError, CryptoCurrencyStatus>> {
return channelFlow {
recover(
block = {
getCurrency(userWalletId, currencyId, refresh).collectLatest { currencyStatus ->
send(currencyStatus.right())
}
},
recover = { error ->
send(error.left())
},
)
}
}
private suspend fun Raise<CurrencyError>.getCurrency(
userWalletId: UserWalletId,
currencyId: CryptoCurrency.ID,
refresh: Boolean,
): Flow<CryptoCurrencyStatus> {
val operations = CurrenciesStatusesOperations(
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
networksRepository = networksRepository,
userWalletId = userWalletId,
refresh = refresh,
dispatchers = dispatchers,
raise = this,
transformError = CurrenciesStatusesOperations.Error::mapToTokenError,
)
return operations.getCurrencyStatusFlow(currencyId)
}
}

View file

@ -5,35 +5,50 @@ import arrow.core.left
import arrow.core.raise.Raise
import arrow.core.raise.recover
import arrow.core.right
import com.tangem.domain.tokens.error.TokenError
import com.tangem.domain.tokens.error.CurrencyError
import com.tangem.domain.tokens.error.mapper.mapToTokenError
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.tokens.repository.TokensRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest
/**
* Use case for fetching the status of the primary cryptocurrency associated with a user wallet.
*
* @property currenciesRepository Repository for managing and fetching cryptocurrencies.
* @property quotesRepository Repository for managing and fetching cryptocurrency quotes.
* @property networksRepository Repository for managing and fetching information related to blockchain networks.
* @property dispatchers Provides coroutine dispatchers.
*/
class GetPrimaryCurrencyUseCase(
private val tokensRepository: TokensRepository,
private val currenciesRepository: CurrenciesRepository,
private val quotesRepository: QuotesRepository,
private val networksRepository: NetworksRepository,
private val dispatchers: CoroutineDispatcherProvider,
) {
/**
* Invokes the use case.
*
* @param userWalletId The unique identifier of the user's wallet.
* @param refresh A boolean flag indicating whether the data should be refreshed.
* @return A [Flow] emitting either a [CurrencyError] or a [CryptoCurrencyStatus], indicating the result of the fetch operation.
*/
operator fun invoke(
userWalletId: UserWalletId,
refresh: Boolean = false,
): Flow<Either<TokenError, CryptoCurrencyStatus>> {
): Flow<Either<CurrencyError, CryptoCurrencyStatus>> {
return channelFlow {
recover(
block = {
getToken(userWalletId, refresh).collectLatest { token ->
send(token.right())
getCurrency(userWalletId, refresh).collectLatest { currencyStatus ->
send(currencyStatus.right())
}
},
recover = { error ->
@ -43,12 +58,12 @@ class GetPrimaryCurrencyUseCase(
}
}
private suspend fun Raise<TokenError>.getToken(
private suspend fun Raise<CurrencyError>.getCurrency(
userWalletId: UserWalletId,
refresh: Boolean,
): Flow<CryptoCurrencyStatus> {
val operations = CurrenciesStatusesOperations(
tokensRepository = tokensRepository,
currenciesRepository = currenciesRepository,
quotesRepository = quotesRepository,
networksRepository = networksRepository,
userWalletId = userWalletId,

View file

@ -11,9 +11,9 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
import com.tangem.domain.tokens.operations.TokenListOperations
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.tokens.repository.TokensRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
@ -22,7 +22,7 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flatMapConcat
class GetTokenListUseCase(
internal val tokensRepository: TokensRepository,
internal val currenciesRepository: CurrenciesRepository,
internal val quotesRepository: QuotesRepository,
internal val networksRepository: NetworksRepository,
internal val dispatchers: CoroutineDispatcherProvider,
@ -60,7 +60,7 @@ class GetTokenListUseCase(
transformError = CurrenciesStatusesOperations.Error::mapToTokenListError,
)
return operations.getMultiCurrencyWalletStatusesFlow()
return operations.getCurrenciesStatusesFlow()
}
private fun Raise<TokenListError>.createTokenList(

View file

@ -0,0 +1,8 @@
package com.tangem.domain.tokens.error
sealed class CurrencyError {
object UnableToCreateCurrency : CurrencyError()
data class DataError(val cause: Throwable) : CurrencyError()
}

View file

@ -1,8 +0,0 @@
package com.tangem.domain.tokens.error
sealed class TokenError {
object UnableToCreateToken : TokenError()
data class DataError(val cause: Throwable) : TokenError()
}

View file

@ -1,15 +1,15 @@
package com.tangem.domain.tokens.error.mapper
import com.tangem.domain.tokens.error.TokenError
import com.tangem.domain.tokens.error.CurrencyError
import com.tangem.domain.tokens.operations.CurrenciesStatusesOperations
internal fun CurrenciesStatusesOperations.Error.mapToTokenError(): TokenError {
internal fun CurrenciesStatusesOperations.Error.mapToTokenError(): CurrencyError {
return when (this) {
is CurrenciesStatusesOperations.Error.DataError -> TokenError.DataError(this.cause)
is CurrenciesStatusesOperations.Error.DataError -> CurrencyError.DataError(this.cause)
is CurrenciesStatusesOperations.Error.EmptyNetworksStatuses,
is CurrenciesStatusesOperations.Error.EmptyQuotes,
is CurrenciesStatusesOperations.Error.EmptyCurrencies,
is CurrenciesStatusesOperations.Error.UnableToCreateCurrencyStatus,
-> TokenError.UnableToCreateToken
-> CurrencyError.UnableToCreateCurrency
}
}

View file

@ -7,9 +7,9 @@ import com.tangem.domain.core.raise.DelegatedRaise
import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.model.*
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import com.tangem.domain.tokens.repository.TokensRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
@ -17,7 +17,7 @@ import kotlinx.coroutines.withContext
@Suppress("LongParameterList")
internal class CurrenciesStatusesOperations<E>(
private val tokensRepository: TokensRepository,
private val currenciesRepository: CurrenciesRepository,
private val quotesRepository: QuotesRepository,
private val networksRepository: NetworksRepository,
private val userWalletId: UserWalletId,
@ -34,7 +34,7 @@ internal class CurrenciesStatusesOperations<E>(
raise: Raise<E>,
transformError: (Error) -> E,
) : this(
tokensRepository = useCase.tokensRepository,
currenciesRepository = useCase.currenciesRepository,
quotesRepository = useCase.quotesRepository,
networksRepository = useCase.networksRepository,
userWalletId = userWalletId,
@ -44,7 +44,7 @@ internal class CurrenciesStatusesOperations<E>(
transformError = transformError,
)
fun getMultiCurrencyWalletStatusesFlow(): Flow<Set<CryptoCurrencyStatus>> {
fun getCurrenciesStatusesFlow(): Flow<Set<CryptoCurrencyStatus>> {
return getMultiCurrencyWalletCurrencies().flatMapConcat {
val currencies = it.toNonEmptySetOrNull()
@ -68,9 +68,19 @@ internal class CurrenciesStatusesOperations<E>(
}
}
suspend fun getCurrencyStatusFlow(currencyId: CryptoCurrency.ID): Flow<CryptoCurrencyStatus> {
val currency = getMultiCurrencyWalletCurrency(currencyId)
return getCurrencyStatusFlow(currency)
}
suspend fun getPrimaryCurrencyStatusFlow(): Flow<CryptoCurrencyStatus> {
val currency = getPrimaryCurrency()
return getCurrencyStatusFlow(currency)
}
private fun getCurrencyStatusFlow(currency: CryptoCurrency): Flow<CryptoCurrencyStatus> {
val quoteFlow = getQuotes(nonEmptySetOf(currency.id))
.map { quotes ->
quotes.singleOrNull { it.currencyId == currency.id }
@ -116,34 +126,36 @@ internal class CurrenciesStatusesOperations<E>(
return currencyStatusOperations.createTokenStatus()
}
private suspend fun getMultiCurrencyWalletCurrency(currencyId: CryptoCurrency.ID): CryptoCurrency {
return catch(
block = { currenciesRepository.getMultiCurrencyWalletCurrency(userWalletId, currencyId) },
catch = { raise(Error.DataError(it)) },
)
}
private fun getMultiCurrencyWalletCurrencies(): Flow<Set<CryptoCurrency>> {
return tokensRepository.getMultiCurrencyWalletCurrencies(userWalletId, refresh)
return currenciesRepository.getMultiCurrencyWalletCurrencies(userWalletId, refresh)
.catch { raise(Error.DataError(it)) }
.onEmpty { raise(Error.EmptyCurrencies) }
.flowOn(dispatchers.io)
}
private suspend fun getPrimaryCurrency(): CryptoCurrency {
return withContext(dispatchers.io) {
catch(
block = { tokensRepository.getPrimaryCurrency(userWalletId) },
catch = { raise(Error.DataError(it)) },
)
}
return catch(
block = { currenciesRepository.getSingleCurrencyWalletPrimaryCurrency(userWalletId) },
catch = { raise(Error.DataError(it)) },
)
}
private fun getQuotes(tokensIds: NonEmptySet<CryptoCurrency.ID>): Flow<Set<Quote>> {
return quotesRepository.getQuotes(tokensIds, refresh)
.catch { raise(Error.DataError(it)) }
.onEmpty { raise(Error.EmptyQuotes) }
.flowOn(dispatchers.io)
}
private fun getNetworksStatues(networks: NonEmptySet<Network.ID>): Flow<Set<NetworkStatus>> {
return networksRepository.getNetworkStatuses(userWalletId, networks, refresh)
.catch { raise(Error.DataError(it)) }
.onEmpty { raise(Error.EmptyNetworksStatuses) }
.flowOn(dispatchers.io)
}
sealed class Error {

View file

@ -10,8 +10,8 @@ import com.tangem.domain.tokens.GetTokenListUseCase
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.tokens.repository.CurrenciesRepository
import com.tangem.domain.tokens.repository.NetworksRepository
import com.tangem.domain.tokens.repository.TokensRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.*
@ -19,7 +19,7 @@ import kotlinx.coroutines.withContext
@Suppress("LongParameterList")
internal class TokenListOperations<E>(
private val tokensRepository: TokensRepository,
private val currenciesRepository: CurrenciesRepository,
private val networksRepository: NetworksRepository,
private val userWalletId: UserWalletId,
private val tokens: Set<CryptoCurrencyStatus>,
@ -35,7 +35,7 @@ internal class TokenListOperations<E>(
raise: Raise<E>,
transform: (Error) -> E,
) : this(
tokensRepository = useCase.tokensRepository,
currenciesRepository = useCase.currenciesRepository,
networksRepository = useCase.networksRepository,
userWalletId = userWalletId,
tokens = tokens,
@ -149,14 +149,14 @@ internal class TokenListOperations<E>(
}
private fun getIsGrouped(): Flow<Boolean> {
return tokensRepository.isTokensGrouped(userWalletId)
return currenciesRepository.isTokensGrouped(userWalletId)
.catch { raise(Error.DataError(it)) }
.onEmpty { emit(value = false) }
.flowOn(dispatchers.io)
}
private fun getIsSortedByBalance(): Flow<Boolean> {
return tokensRepository.isTokensSortedByBalance(userWalletId)
return currenciesRepository.isTokensSortedByBalance(userWalletId)
.catch { raise(Error.DataError(it)) }
.onEmpty { emit(value = false) }
.flowOn(dispatchers.io)

View file

@ -7,7 +7,7 @@ import kotlinx.coroutines.flow.Flow
/**
* Repository for everything related to the tokens of user wallet
* */
interface TokensRepository {
interface CurrenciesRepository {
/**
* Saves the given set of cryptocurrencies, along with the preferences for grouping and sorting, for a specific
@ -17,6 +17,8 @@ interface TokensRepository {
* @param currencies The set of cryptocurrencies to be saved.
* @param isGroupedByNetwork A boolean flag indicating whether the tokens should be grouped by network.
* @param isSortedByBalance A boolean flag indicating whether the tokens should be sorted by balance.
* @throws com.tangem.domain.core.error.DataError.UserWalletError.WrongUserWallet If single-currency user wallet
* ID provided.
*/
suspend fun saveTokens(
userWalletId: UserWalletId,
@ -30,8 +32,10 @@ interface TokensRepository {
*
* @param userWalletId The unique identifier of the user wallet.
* @return The primary cryptocurrency associated with the user wallet.
* @throws com.tangem.domain.core.error.DataError.UserWalletError.WrongUserWallet If multi-currency user wallet
* ID provided.
*/
suspend fun getPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency
suspend fun getSingleCurrencyWalletPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency
/**
* Retrieves the set of cryptocurrencies within a multi-currency wallet.
@ -39,14 +43,29 @@ interface TokensRepository {
* @param userWalletId The unique identifier of the user wallet.
* @param refresh A boolean flag indicating whether the data should be refreshed.
* @return A [Flow] emitting the set of cryptocurrencies associated with the user wallet.
* @throws com.tangem.domain.core.error.DataError.UserWalletError.WrongUserWallet If single-currency user wallet
* ID provided.
*/
fun getMultiCurrencyWalletCurrencies(userWalletId: UserWalletId, refresh: Boolean): Flow<Set<CryptoCurrency>>
/**
* Retrieves the cryptocurrency for a specific multi-currency user wallet.
*
* @param userWalletId The unique identifier of the user wallet.
* @param id The unique identifier of the cryptocurrency to be retrieved.
* @return The cryptocurrency associated with the user wallet and ID.
* @throws com.tangem.domain.core.error.DataError.UserWalletError.WrongUserWallet If single-currency user wallet
* ID provided.
*/
suspend fun getMultiCurrencyWalletCurrency(userWalletId: UserWalletId, id: CryptoCurrency.ID): CryptoCurrency
/**
* Determines whether the tokens within a specific multi-currency user wallet are grouped.
*
* @param userWalletId The unique identifier of the user wallet.
* @return A [Flow] emitting a boolean value indicating whether the tokens are grouped.
* @throws com.tangem.domain.core.error.DataError.UserWalletError.WrongUserWallet If single-currency user wallet
* ID provided.
*/
fun isTokensGrouped(userWalletId: UserWalletId): Flow<Boolean>
@ -55,6 +74,8 @@ interface TokensRepository {
*
* @param userWalletId The unique identifier of the user wallet.
* @return A [Flow] emitting a boolean value indicating whether the tokens are sorted by balance.
* @throws com.tangem.domain.core.error.DataError.UserWalletError.WrongUserWallet If single-currency user wallet
* ID provided.
*/
fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow<Boolean>
}

View file

@ -7,7 +7,7 @@ import com.tangem.domain.core.error.DataError
import com.tangem.domain.tokens.error.TokenListSortingError
import com.tangem.domain.tokens.mock.MockTokens
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.repository.MockTokensRepository
import com.tangem.domain.tokens.repository.MockCurrenciesRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import junit.framework.TestCase.assertEquals
@ -183,16 +183,16 @@ internal class ApplyTokenListSortingUseCaseTest {
.sortedBy { Random.nextInt(0, MockTokens.tokens.size) }
.toSet()
private fun getUseCase(tokensRepository: MockTokensRepository = getTokensRepository()) =
private fun getUseCase(tokensRepository: MockCurrenciesRepository = getTokensRepository()) =
ApplyTokenListSortingUseCase(
tokensRepository = tokensRepository,
currenciesRepository = tokensRepository,
dispatchers = TestingCoroutineDispatcherProvider(),
)
private fun getTokensRepository(
sortTokensResult: Either<DataError, Unit> = Unit.right(),
tokens: Flow<Either<DataError, Set<CryptoCurrency>>> = flowOf(MockTokens.tokens.right()),
): MockTokensRepository {
return MockTokensRepository(sortTokensResult, MockTokens.token1.right(), tokens, emptyFlow(), emptyFlow())
): MockCurrenciesRepository {
return MockCurrenciesRepository(sortTokensResult, MockTokens.token1.right(), tokens, emptyFlow(), emptyFlow())
}
}

View file

@ -4,7 +4,7 @@ import arrow.core.Either
import arrow.core.left
import arrow.core.right
import com.tangem.domain.core.error.DataError
import com.tangem.domain.tokens.error.TokenError
import com.tangem.domain.tokens.error.CurrencyError
import com.tangem.domain.tokens.mock.MockNetworks
import com.tangem.domain.tokens.mock.MockQuotes
import com.tangem.domain.tokens.mock.MockTokens
@ -13,9 +13,9 @@ import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.tokens.model.NetworkStatus
import com.tangem.domain.tokens.model.Quote
import com.tangem.domain.tokens.repository.MockCurrenciesRepository
import com.tangem.domain.tokens.repository.MockNetworksRepository
import com.tangem.domain.tokens.repository.MockQuotesRepository
import com.tangem.domain.tokens.repository.MockTokensRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import junit.framework.TestCase.assertEquals
@ -47,7 +47,7 @@ internal class GetPrimaryCurrencyUseCaseTest {
@Test
fun `when token getting failed then error should be received`() = runTest {
// Given
val expectedResult = TokenError.DataError(DataError.NetworkError.NoInternetConnection).left()
val expectedResult = CurrencyError.DataError(DataError.NetworkError.NoInternetConnection).left()
val useCase = getUseCase(token = DataError.NetworkError.NoInternetConnection.left())
@ -61,7 +61,7 @@ internal class GetPrimaryCurrencyUseCaseTest {
@Test
fun `when quotes getting failed then error should be received`() = runTest {
// Given
val expectedResult = TokenError.DataError(DataError.NetworkError.NoInternetConnection).left()
val expectedResult = CurrencyError.DataError(DataError.NetworkError.NoInternetConnection).left()
val useCase = getUseCase(quotes = flowOf(DataError.NetworkError.NoInternetConnection.left()))
@ -75,7 +75,7 @@ internal class GetPrimaryCurrencyUseCaseTest {
@Test
fun `when networks statuses getting failed then error should be received`() = runTest {
// Given
val expectedResult = TokenError.DataError(DataError.NetworkError.NoInternetConnection).left()
val expectedResult = CurrencyError.DataError(DataError.NetworkError.NoInternetConnection).left()
val useCase = getUseCase(statuses = flowOf(DataError.NetworkError.NoInternetConnection.left()))
@ -88,7 +88,7 @@ internal class GetPrimaryCurrencyUseCaseTest {
@Test
fun `when networks statuses flow is empty then error should be received`() = runTest {
val expectedResult = TokenError.UnableToCreateToken.left()
val expectedResult = CurrencyError.UnableToCreateCurrency.left()
val useCase = getUseCase(statuses = flowOf())
@ -101,7 +101,7 @@ internal class GetPrimaryCurrencyUseCaseTest {
@Test
fun `when quotes flow is empty then error should be received`() = runTest {
val expectedResult = TokenError.UnableToCreateToken.left()
val expectedResult = CurrencyError.UnableToCreateCurrency.left()
val useCase = getUseCase(quotes = flowOf())
@ -154,7 +154,7 @@ internal class GetPrimaryCurrencyUseCaseTest {
statuses: Flow<Either<DataError, Set<NetworkStatus>>> = flowOf(MockNetworks.verifiedNetworksStatuses.right()),
) = GetPrimaryCurrencyUseCase(
dispatchers = dispatchers,
tokensRepository = MockTokensRepository(
currenciesRepository = MockCurrenciesRepository(
sortTokensResult = Unit.right(),
token = token,
tokens = flowOf(),

View file

@ -13,9 +13,9 @@ import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.NetworkStatus
import com.tangem.domain.tokens.model.Quote
import com.tangem.domain.tokens.models.Network
import com.tangem.domain.tokens.repository.MockCurrenciesRepository
import com.tangem.domain.tokens.repository.MockNetworksRepository
import com.tangem.domain.tokens.repository.MockQuotesRepository
import com.tangem.domain.tokens.repository.MockTokensRepository
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import junit.framework.TestCase.assertEquals
@ -326,7 +326,7 @@ internal class GetTokenListUseCaseTest {
isSortedByBalance: Flow<Either<DataError, Boolean>> = flowOf(MockTokenLists.isSortedByBalance.right()),
) = GetTokenListUseCase(
dispatchers = dispatchers,
tokensRepository = MockTokensRepository(
currenciesRepository = MockCurrenciesRepository(
sortTokensResult = Unit.right(),
token = MockTokens.token1.right(),
tokens = tokens,

View file

@ -8,13 +8,13 @@ import com.tangem.domain.wallets.models.UserWalletId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
internal class MockTokensRepository(
internal class MockCurrenciesRepository(
private val sortTokensResult: Either<DataError, Unit>,
private val token: Either<DataError, CryptoCurrency>,
private val tokens: Flow<Either<DataError, Set<CryptoCurrency>>>,
private val isGrouped: Flow<Either<DataError, Boolean>>,
private val isSortedByBalance: Flow<Either<DataError, Boolean>>,
) : TokensRepository {
) : CurrenciesRepository {
var tokensIdsAfterSortingApply: Set<CryptoCurrency>? = null
private set
@ -38,7 +38,7 @@ internal class MockTokensRepository(
isTokensSortedByBalanceAfterSortingApply = isSortedByBalance
}
override suspend fun getPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency {
override suspend fun getSingleCurrencyWalletPrimaryCurrency(userWalletId: UserWalletId): CryptoCurrency {
return token.getOrElse { e -> throw e }
}
@ -49,6 +49,17 @@ internal class MockTokensRepository(
return tokens.map { it.getOrElse { e -> throw e } }
}
override suspend fun getMultiCurrencyWalletCurrency(
userWalletId: UserWalletId,
id: CryptoCurrency.ID,
): CryptoCurrency {
val token = token.getOrElse { e -> throw e }
require(token.id == id)
return token
}
override fun isTokensGrouped(userWalletId: UserWalletId): Flow<Boolean> {
return isGrouped.map { it.getOrElse { e -> throw e } }
}