diff --git a/domain/tokens/build.gradle.kts b/domain/tokens/build.gradle.kts index d4297e1590..d6c92daddb 100644 --- a/domain/tokens/build.gradle.kts +++ b/domain/tokens/build.gradle.kts @@ -7,4 +7,7 @@ dependencies { implementation(projects.domain.core) implementation(projects.domain.wallets.models) implementation(projects.core.utils) + + testImplementation(deps.test.junit) + testImplementation(deps.test.coroutine) } \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/GetTokenListUseCaseTest.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/GetTokenListUseCaseTest.kt new file mode 100644 index 0000000000..e876c1924d --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/GetTokenListUseCaseTest.kt @@ -0,0 +1,334 @@ +package com.tangem.domain.tokens + +import arrow.core.Either +import arrow.core.left +import arrow.core.right +import com.tangem.domain.tokens.error.TokensError +import com.tangem.domain.tokens.mock.MockNetworks +import com.tangem.domain.tokens.mock.MockQuotes +import com.tangem.domain.tokens.mock.MockTokenLists +import com.tangem.domain.tokens.mock.MockTokens +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.NetworkStatus +import com.tangem.domain.tokens.model.Quote +import com.tangem.domain.tokens.model.Token +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 +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +internal class GetTokenListUseCaseTest { + + private val dispatchers = TestingCoroutineDispatcherProvider() + private val userWalletId = UserWalletId(value = null) + + @Test + fun `when list ungrouped and unsorted then correct token list should be returned`() = runTest { + // Given + val expectedResult = MockTokenLists.ungroupedTokenList.right() + + val useCase = getUseCase( + isGrouped = flowOf(false.right()), + isSortedByBalance = flowOf(false.right()), + ) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when tokens getting failed then error should be received`() = runTest { + // Given + val expectedResult = TokensError.EmptyTokens.left() + + val useCase = getUseCase(tokens = flowOf(expectedResult)) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when quotes getting failed then error should be received`() = runTest { + // Given + val expectedResult = TokensError.EmptyQuotes.left() + + val useCase = getUseCase(quotes = flowOf(expectedResult)) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when networks getting failed and list is groped then error should be received`() = runTest { + // Given + val expectedResult = TokensError.EmptyNetworkStatues.left() + + val useCase = getUseCase( + networks = expectedResult, + isGrouped = flowOf(true.right()), + ) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when networks statuses getting failed then error should be received`() = runTest { + // Given + val expectedResult = TokensError.EmptyNetworkStatues.left() + + val useCase = getUseCase(statuses = flowOf(expectedResult)) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when grouping type getting failed then error should be received`() = runTest { + // Given + val expectedResult = TokensError.EmptyTokens.left() + + val useCase = getUseCase(isGrouped = flowOf(expectedResult)) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when sorting type getting failed then error should be received`() = runTest { + // Given + val expectedResult = TokensError.EmptyTokens.left() + + val useCase = getUseCase(isSortedByBalance = flowOf(expectedResult)) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when tokens getting failed on second emit then error should be received`() = runTest { + // Given + val error = TokensError.EmptyTokens.left() + val expectedResult = listOf( + MockTokenLists.ungroupedTokenList.right(), + error, + ) + + val useCase = getUseCase( + tokens = flowOf( + MockTokens.tokens.right(), + error, + ), + ) + + // When + val result = useCase(userWalletId) + .take(count = 2) + .toList() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when list grouped then correct token list should be received`() = runTest { + val expectedResult = MockTokenLists.groupedTokenList.right() + + val useCase = getUseCase(isGrouped = flowOf(true.right())) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when list is grouped and networks getting failed then error should be received`() = runTest { + val expectedResult = TokensError.EmptyNetworks.left() + + val useCase = getUseCase( + networks = expectedResult, + isGrouped = flowOf(true.right()), + ) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when list is sorted and ungrouped then correct token list should be received`() = runTest { + val expectedResult = MockTokenLists.sortedUngroupedTokenList.right() + + val useCase = getUseCase( + statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()), + isGrouped = flowOf(false.right()), + isSortedByBalance = flowOf(true.right()), + ) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when list is sorted and grouped then correct token list should be received`() = runTest { + val expectedResult = MockTokenLists.sortedGroupedTokenList.right() + + val useCase = getUseCase( + statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()), + isGrouped = flowOf(true.right()), + isSortedByBalance = flowOf(true.right()), + ) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when tokens is empty then not initialized token list should be received`() = runTest { + val expectedResult = MockTokenLists.notInitializedTokenList.right() + + val useCase = getUseCase(tokens = flowOf(emptySet().right())) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when networks is empty and list is grouped then error should be received`() = runTest { + val expectedResult = TokensError.EmptyNetworks.left() + + val useCase = getUseCase( + networks = emptySet().right(), + isGrouped = flowOf(true.right()), + ) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when tokens flow is empty then error should be received`() = runTest { + val expectedResult = TokensError.EmptyTokens.left() + + val useCase = getUseCase(tokens = flowOf()) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when networks statuses flow is empty then error should be received`() = runTest { + val expectedResult = TokensError.EmptyNetworkStatues.left() + + val useCase = getUseCase(statuses = flowOf()) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when networks statuses is empty then loading token list should be received`() = runTest { + val expectedResult = MockTokenLists.loadingUngroupedTokenList.right() + + val useCase = getUseCase(statuses = flowOf(emptySet().right())) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when quotes flow is empty then error should be received`() = runTest { + val expectedResult = TokensError.EmptyQuotes.left() + + val useCase = getUseCase(quotes = flowOf()) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + @Test + fun `when quotes is empty and statuses verified then loading token list should be received`() = runTest { + val expectedResult = MockTokenLists.loadingUngroupedTokenList.right() + + val useCase = getUseCase( + statuses = flowOf(MockNetworks.verifiedNetworksStatuses.right()), + quotes = flowOf(emptySet().right()), + ) + + // When + val result = useCase(userWalletId).first() + + // Then + assertEquals(expectedResult, result) + } + + private fun getUseCase( + tokens: Flow>> = flowOf(MockTokens.tokens.right()), + quotes: Flow>> = flowOf(MockQuotes.quotes.right()), + networks: Either> = MockNetworks.networks.right(), + statuses: Flow>> = flowOf(MockNetworks.errorNetworksStatuses.right()), + isGrouped: Flow> = flowOf(MockTokenLists.isGrouped.right()), + isSortedByBalance: Flow> = flowOf(MockTokenLists.isSortedByBalance.right()), + ) = GetTokenListUseCase( + dispatchers = dispatchers, + tokensRepository = MockTokensRepository(tokens, isGrouped, isSortedByBalance), + quotesRepository = MockQuotesRepository(quotes), + networksRepository = MockNetworksRepository(networks, statuses), + ) +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockNetworks.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockNetworks.kt new file mode 100644 index 0000000000..03ad43ba70 --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockNetworks.kt @@ -0,0 +1,90 @@ +package com.tangem.domain.tokens.mock + +import arrow.core.NonEmptySet +import arrow.core.nonEmptySetOf +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.NetworkStatus +import java.math.BigDecimal + +@Suppress("MemberVisibilityCanBePrivate") +internal object MockNetworks { + + val amountToCreateAccount: BigDecimal = BigDecimal.TEN + + val network1 = Network( + id = Network.ID("network1"), + name = "Network One", + ) + + val network2 = Network( + id = Network.ID("network2"), + name = "Network Two", + ) + + val network3 = Network( + id = Network.ID("network3"), + name = "Network Three", + ) + + val networks = nonEmptySetOf(network1, network2, network3) + + val networkStatus1 = NetworkStatus( + networkId = network1.id, + value = NetworkStatus.Unreachable, + ) + + val networkStatus2 = NetworkStatus( + networkId = network2.id, + value = NetworkStatus.MissedDerivation, + ) + + val networkStatus3 = NetworkStatus( + networkId = network3.id, + value = NetworkStatus.NoAccount( + amountToCreateAccount = amountToCreateAccount, + ), + ) + + val errorNetworksStatuses = nonEmptySetOf(networkStatus1, networkStatus2, networkStatus3) + + val verifiedNetworkStatus1: NetworkStatus + get() = networkStatus1.copy( + value = NetworkStatus.Verified( + amounts = mapOf( + MockTokens.token1.id to BigDecimal.TEN, + MockTokens.token2.id to BigDecimal.TEN, + MockTokens.token3.id to BigDecimal.TEN, + ), + ), + ) + + val verifiedNetworkStatus2: NetworkStatus + get() = networkStatus2.copy( + value = NetworkStatus.Verified( + amounts = mapOf( + MockTokens.token4.id to BigDecimal.TEN, + MockTokens.token5.id to BigDecimal.TEN, + MockTokens.token6.id to BigDecimal.TEN, + ), + ), + ) + + val verifiedNetworkStatus3: NetworkStatus + get() = networkStatus3.copy( + value = NetworkStatus.Verified( + amounts = mapOf( + MockTokens.token7.id to BigDecimal.TEN, + MockTokens.token8.id to BigDecimal.TEN, + MockTokens.token9.id to BigDecimal.TEN, + MockTokens.token10.id to BigDecimal.TEN, + ), + ), + ) + + val verifiedNetworksStatuses: NonEmptySet + get() = nonEmptySetOf( + verifiedNetworkStatus1, + verifiedNetworkStatus2, + verifiedNetworkStatus3, + ) +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockQuotes.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockQuotes.kt new file mode 100644 index 0000000000..767391423e --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockQuotes.kt @@ -0,0 +1,71 @@ +package com.tangem.domain.tokens.mock + +import arrow.core.nonEmptySetOf +import com.tangem.domain.tokens.model.Quote +import java.math.BigDecimal + +@Suppress("MemberVisibilityCanBePrivate") +internal object MockQuotes { + + val quote1 = Quote( + tokenId = MockTokens.token1.id, + fiatRate = BigDecimal("1.23"), + priceChange = BigDecimal("0.01"), + ) + + val quote2 = Quote( + tokenId = MockTokens.token2.id, + fiatRate = BigDecimal("2.34"), + priceChange = BigDecimal("-0.02"), + ) + + val quote3 = Quote( + tokenId = MockTokens.token3.id, + fiatRate = BigDecimal("3.45"), + priceChange = BigDecimal("0.03"), + ) + + val quote4 = Quote( + tokenId = MockTokens.token4.id, + fiatRate = BigDecimal("4.56"), + priceChange = BigDecimal("-0.04"), + ) + + val quote5 = Quote( + tokenId = MockTokens.token5.id, + fiatRate = BigDecimal("5.67"), + priceChange = BigDecimal("0.05"), + ) + + val quote6 = Quote( + tokenId = MockTokens.token6.id, + fiatRate = BigDecimal("6.78"), + priceChange = BigDecimal("-0.06"), + ) + + val quote7 = Quote( + tokenId = MockTokens.token7.id, + fiatRate = BigDecimal("7.89"), + priceChange = BigDecimal("0.07"), + ) + + val quote8 = Quote( + tokenId = MockTokens.token8.id, + fiatRate = BigDecimal("8.90"), + priceChange = BigDecimal("-0.08"), + ) + + val quote9 = Quote( + tokenId = MockTokens.token9.id, + fiatRate = BigDecimal("9.01"), + priceChange = BigDecimal("0.09"), + ) + + val quote10 = Quote( + tokenId = MockTokens.token10.id, + fiatRate = BigDecimal("10.12"), + priceChange = BigDecimal("-0.10"), + ) + + val quotes = nonEmptySetOf(quote1, quote2, quote3, quote4, quote5, quote6, quote7, quote8, quote9, quote10) +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokenLists.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokenLists.kt new file mode 100644 index 0000000000..2951fbef39 --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokenLists.kt @@ -0,0 +1,107 @@ +package com.tangem.domain.tokens.mock + +import arrow.core.nonEmptySetOf +import arrow.core.toNonEmptySetOrNull +import com.tangem.domain.tokens.model.NetworkGroup +import com.tangem.domain.tokens.model.TokenList +import com.tangem.domain.tokens.model.TokenStatus +import java.math.BigDecimal + +@Suppress("MemberVisibilityCanBePrivate") +internal object MockTokenLists { + + const val isGrouped = false + const val isSortedByBalance = false + + val networkGroup1 = NetworkGroup( + networkId = MockNetworks.network1.id, + name = MockNetworks.network1.name, + tokens = MockTokensStates.tokenStates + .filter { it.networkId == MockNetworks.network1.id } + .toNonEmptySetOrNull()!!, + ) + + val networkGroup2 = NetworkGroup( + networkId = MockNetworks.network2.id, + name = MockNetworks.network2.name, + tokens = MockTokensStates.tokenStates + .filter { it.networkId == MockNetworks.network2.id } + .toNonEmptySetOrNull()!!, + ) + + val networkGroup3 = NetworkGroup( + networkId = MockNetworks.network3.id, + name = MockNetworks.network3.name, + tokens = MockTokensStates.tokenStates + .filter { it.networkId == MockNetworks.network3.id } + .toNonEmptySetOrNull()!!, + ) + + val networksGroups = nonEmptySetOf(networkGroup1, networkGroup2, networkGroup3) + + val sortedNetworksGroups = networksGroups.map { group -> + group.copy( + tokens = MockTokensStates.loadedTokensStates + .filter { it.networkId == group.networkId } + .sortedByDescending { it.value.fiatAmount } + .toNonEmptySetOrNull()!!, + ) + } + .sortedByDescending { group -> + group.tokens.sumOf { it.value.fiatAmount!! } + } + .toNonEmptySetOrNull()!! + + val notInitializedTokenList = TokenList.NotInitialized + + val groupedTokenList = TokenList.GroupedByNetwork( + groups = networksGroups, + totalFiatBalance = TokenList.FiatBalance.Failed, + sortedBy = TokenList.SortType.NONE, + ) + + val ungroupedTokenList = TokenList.Ungrouped( + tokens = MockTokensStates.tokenStates, + totalFiatBalance = TokenList.FiatBalance.Failed, + sortedBy = TokenList.SortType.NONE, + ) + + val loadingUngroupedTokenList = with(ungroupedTokenList) { + copy( + tokens = tokens.map { it.copy(value = TokenStatus.Loading) }, + totalFiatBalance = TokenList.FiatBalance.Loading, + ) + } + + val sortedUngroupedTokenList: TokenList.Ungrouped + get() { + val tokens = MockTokensStates.loadedTokensStates + .sortedByDescending { it.value.fiatAmount } + .toNonEmptySetOrNull()!! + + return ungroupedTokenList.copy( + tokens = tokens, + sortedBy = TokenList.SortType.BALANCE, + totalFiatBalance = TokenList.FiatBalance.Loaded( + amount = tokens.sumOf { it.value.fiatAmount ?: BigDecimal.ZERO }, + isAllAmountsSummarized = true, + ), + ) + } + + val sortedGroupedTokenList: TokenList.GroupedByNetwork + get() { + val groups = sortedNetworksGroups + + return groupedTokenList.copy( + groups = groups, + sortedBy = TokenList.SortType.BALANCE, + totalFiatBalance = TokenList.FiatBalance.Loaded( + amount = groups + .flatMap { it.tokens } + .sumOf { it.value.fiatAmount ?: BigDecimal.ZERO }, + isAllAmountsSummarized = true, + ), + ) + } +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokens.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokens.kt new file mode 100644 index 0000000000..e57f0f2471 --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokens.kt @@ -0,0 +1,90 @@ +package com.tangem.domain.tokens.mock + +import arrow.core.nonEmptySetOf +import com.tangem.domain.tokens.model.Token + +internal object MockTokens { + + val token1 = Token( + id = Token.ID("token1"), + networkId = MockNetworks.network1.id, + name = "Token 1", + symbol = "T1", + isCustom = false, + isCoin = true, + ) + val token2 = Token( + id = Token.ID("token2"), + networkId = MockNetworks.network1.id, + name = "Token 2", + symbol = "T2", + isCustom = false, + isCoin = false, + ) + val token3 = Token( + id = Token.ID("token3"), + networkId = MockNetworks.network1.id, + name = "Token 3", + symbol = "T3", + isCustom = false, + isCoin = false, + ) + val token4 = Token( + id = Token.ID("token4"), + networkId = MockNetworks.network2.id, + name = "Token 4", + symbol = "T4", + isCustom = false, + isCoin = true, + ) + val token5 = Token( + id = Token.ID("token5"), + networkId = MockNetworks.network2.id, + name = "Token 5", + symbol = "T5", + isCustom = false, + isCoin = true, + ) + val token6 = Token( + id = Token.ID("token6"), + networkId = MockNetworks.network2.id, + name = "Token 6", + symbol = "T6", + isCustom = false, + isCoin = false, + ) + val token7 = Token( + id = Token.ID("token7"), + networkId = MockNetworks.network3.id, + name = "Token 7", + symbol = "T7", + isCustom = false, + isCoin = false, + ) + val token8 = Token( + id = Token.ID("token8"), + networkId = MockNetworks.network3.id, + name = "Token 8", + symbol = "T8", + isCustom = false, + isCoin = true, + ) + val token9 = Token( + id = Token.ID("token9"), + networkId = MockNetworks.network3.id, + name = "Token 9", + symbol = "T9", + isCustom = false, + isCoin = true, + ) + val token10 = Token( + id = Token.ID("token10"), + networkId = MockNetworks.network3.id, + name = "Token 10", + symbol = "T10", + isCustom = false, + isCoin = false, + ) + + val tokens = nonEmptySetOf(token1, token2, token3, token4, token5, token6, token7, token8, token9, token10) +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt new file mode 100644 index 0000000000..338b4e1698 --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/mock/MockTokensStates.kt @@ -0,0 +1,128 @@ +package com.tangem.domain.tokens.mock + +import arrow.core.nonEmptySetOf +import com.tangem.domain.tokens.model.NetworkStatus +import com.tangem.domain.tokens.model.TokenStatus + +@Suppress("MemberVisibilityCanBePrivate") +internal object MockTokensStates { + + val tokenState1 = TokenStatus( + id = MockTokens.token1.id, + networkId = MockTokens.token1.networkId, + name = MockTokens.token1.name, + symbol = MockTokens.token1.symbol, + isCoin = MockTokens.token1.isCoin, + value = TokenStatus.Unreachable, + ) + + val tokenState2 = TokenStatus( + id = MockTokens.token2.id, + networkId = MockTokens.token2.networkId, + name = MockTokens.token2.name, + symbol = MockTokens.token2.symbol, + isCoin = MockTokens.token2.isCoin, + value = TokenStatus.Unreachable, + ) + + val tokenState3 = TokenStatus( + id = MockTokens.token3.id, + networkId = MockTokens.token3.networkId, + name = MockTokens.token3.name, + symbol = MockTokens.token3.symbol, + isCoin = MockTokens.token3.isCoin, + value = TokenStatus.Unreachable, + ) + + val tokenState4 = TokenStatus( + id = MockTokens.token4.id, + networkId = MockTokens.token4.networkId, + name = MockTokens.token4.name, + symbol = MockTokens.token4.symbol, + isCoin = MockTokens.token4.isCoin, + value = TokenStatus.MissedDerivation, + ) + + val tokenState5 = TokenStatus( + id = MockTokens.token5.id, + networkId = MockTokens.token5.networkId, + name = MockTokens.token5.name, + symbol = MockTokens.token5.symbol, + isCoin = MockTokens.token5.isCoin, + value = TokenStatus.MissedDerivation, + ) + + val tokenState6 = TokenStatus( + id = MockTokens.token6.id, + networkId = MockTokens.token6.networkId, + name = MockTokens.token6.name, + symbol = MockTokens.token6.symbol, + isCoin = MockTokens.token6.isCoin, + value = TokenStatus.MissedDerivation, + ) + + val tokenState7 = TokenStatus( + id = MockTokens.token7.id, + networkId = MockTokens.token7.networkId, + name = MockTokens.token7.name, + symbol = MockTokens.token7.symbol, + isCoin = MockTokens.token7.isCoin, + value = TokenStatus.NoAccount, + ) + + val tokenState8 = TokenStatus( + id = MockTokens.token8.id, + networkId = MockTokens.token8.networkId, + name = MockTokens.token8.name, + symbol = MockTokens.token8.symbol, + isCoin = MockTokens.token8.isCoin, + value = TokenStatus.NoAccount, + ) + + val tokenState9 = TokenStatus( + id = MockTokens.token9.id, + networkId = MockTokens.token9.networkId, + name = MockTokens.token9.name, + symbol = MockTokens.token9.symbol, + isCoin = MockTokens.token9.isCoin, + value = TokenStatus.NoAccount, + ) + + val tokenState10 = TokenStatus( + id = MockTokens.token10.id, + networkId = MockTokens.token10.networkId, + name = MockTokens.token10.name, + symbol = MockTokens.token10.symbol, + isCoin = MockTokens.token10.isCoin, + value = TokenStatus.NoAccount, + ) + + val tokenStates = nonEmptySetOf( + tokenState1, + tokenState2, + tokenState3, + tokenState4, + tokenState5, + tokenState6, + tokenState7, + tokenState8, + tokenState9, + tokenState10, + ) + + val loadedTokensStates = tokenStates.map { state -> + val networkStatus = MockNetworks.verifiedNetworksStatuses.first { it.networkId == state.networkId } + val amount = (networkStatus.value as NetworkStatus.Verified).amounts[state.id]!! + val quote = MockQuotes.quotes.first { it.tokenId == state.id } + val fiatAmount = amount * quote.fiatRate + + state.copy( + value = TokenStatus.Loaded( + amount = amount, + fiatAmount = fiatAmount, + priceChange = quote.priceChange, + hasTransactionsInProgress = false, + ), + ) + } +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockNetworksRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockNetworksRepository.kt new file mode 100644 index 0000000000..3267a30ba2 --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockNetworksRepository.kt @@ -0,0 +1,27 @@ +package com.tangem.domain.tokens.repository + +import arrow.core.Either +import com.tangem.domain.tokens.error.TokensError +import com.tangem.domain.tokens.model.Network +import com.tangem.domain.tokens.model.NetworkStatus +import com.tangem.domain.tokens.model.Token +import com.tangem.domain.wallets.models.UserWalletId +import kotlinx.coroutines.flow.Flow + +internal class MockNetworksRepository( + private val networks: Either>, + private val statuses: Flow>>, +) : NetworksRepository { + + override fun getNetworks(networksIds: Set): Either> { + return networks + } + + override fun getNetworkStatuses( + userWalletId: UserWalletId, + networks: Map>, + refresh: Boolean, + ): Flow>> { + return statuses + } +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockQuotesRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockQuotesRepository.kt new file mode 100644 index 0000000000..e82b0c0c82 --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockQuotesRepository.kt @@ -0,0 +1,16 @@ +package com.tangem.domain.tokens.repository + +import arrow.core.Either +import com.tangem.domain.tokens.error.TokensError +import com.tangem.domain.tokens.model.Quote +import com.tangem.domain.tokens.model.Token +import kotlinx.coroutines.flow.Flow + +internal class MockQuotesRepository( + private val quotes: Flow>>, +) : QuotesRepository { + + override fun getQuotes(tokensIds: Set, refresh: Boolean): Flow>> { + return quotes + } +} \ No newline at end of file diff --git a/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockTokensRepository.kt b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockTokensRepository.kt new file mode 100644 index 0000000000..5a7a757179 --- /dev/null +++ b/domain/tokens/src/test/kotlin/com/tangem/domain/tokens/repository/MockTokensRepository.kt @@ -0,0 +1,34 @@ +package com.tangem.domain.tokens.repository + +import arrow.core.Either +import arrow.core.right +import com.tangem.domain.tokens.error.TokensError +import com.tangem.domain.tokens.model.Token +import com.tangem.domain.wallets.models.UserWalletId +import kotlinx.coroutines.flow.Flow + +internal class MockTokensRepository( + private val tokens: Flow>>, + private val isGrouped: Flow>, + private val isSortedByBalance: Flow>, +) : TokensRepository { + + override suspend fun sortTokens( + userWalletId: UserWalletId, + sortedTokensIds: Set, + isGrouped: Boolean, + isSortedByBalance: Boolean, + ): Either = Unit.right() + + override fun getTokens(userWalletId: UserWalletId, refresh: Boolean): Flow>> { + return tokens + } + + override fun isTokensGrouped(userWalletId: UserWalletId): Flow> { + return isGrouped + } + + override fun isTokensSortedByBalance(userWalletId: UserWalletId): Flow> { + return isSortedByBalance + } +} \ No newline at end of file