Updated on 2026-08-14

This commit is contained in:
Tangem 2026-02-03 17:41:42 +04:00
parent b861d63402
commit 652009a7bf
29 changed files with 271 additions and 256 deletions

View file

@ -1,6 +1,6 @@
package com.tangem.data.account.converter
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWalletId
import javax.inject.Inject
@ -10,7 +10,7 @@ import javax.inject.Inject
* @property getWalletAccountsResponseCF factory for creating a wallet accounts response converter
* @property accountsListCF factory for creating an account list converter
* @property cryptoPortfolioCF factory for creating a crypto portfolio converter
* @property userWalletsStore store for accessing user wallet data
* @property userWalletsListRepository repository for getting user wallets
*
* @constructor Creates an instance of the container with injected factories.
*
@ -20,23 +20,23 @@ internal class AccountConverterFactoryContainer @Inject constructor(
private val getWalletAccountsResponseCF: GetWalletAccountsResponseConverter.Factory,
private val accountsListCF: AccountListConverter.Factory,
private val cryptoPortfolioCF: CryptoPortfolioConverter.Factory,
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
) {
fun createWalletAccountsResponseConverter(userWalletId: UserWalletId): GetWalletAccountsResponseConverter {
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(id = userWalletId)
return getWalletAccountsResponseCF.create(userWallet)
}
fun createAccountListConverter(userWalletId: UserWalletId): AccountListConverter {
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(id = userWalletId)
return accountsListCF.create(userWallet)
}
fun createCryptoPortfolioConverter(userWalletId: UserWalletId): CryptoPortfolioConverter {
val userWallet = userWalletsStore.getSyncStrict(key = userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(id = userWalletId)
return cryptoPortfolioCF.create(userWallet)
}

View file

@ -22,7 +22,6 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.di.NetworkMoshi
import com.tangem.datasource.local.accounts.AccountTokenMigrationStore
import com.tangem.datasource.local.datastore.RuntimeStateStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.datasource.utils.MoshiDataStoreSerializer
import com.tangem.datasource.utils.mapWithStringKeyTypes
import com.tangem.datasource.utils.setTypes
@ -56,7 +55,6 @@ internal object AccountDataModule {
tangemTechApi: TangemTechApi,
walletAccountsSaver: WalletAccountsSaver,
accountsResponseStoreFactory: AccountsResponseStoreFactory,
userWalletsStore: UserWalletsStore,
userTokensSaver: UserTokensSaver,
accountConverterFactoryContainer: AccountConverterFactoryContainer,
@ApplicationContext context: Context,
@ -67,7 +65,6 @@ internal object AccountDataModule {
walletAccountsSaver = walletAccountsSaver,
accountsResponseStoreFactory = accountsResponseStoreFactory,
archivedAccountsStoreFactory = ArchivedAccountsStoreFactory,
userWalletsStore = userWalletsStore,
userTokensSaver = userTokensSaver,
archivedAccountsETagStore = RuntimeStateStore(emptyMap()),
convertersContainer = accountConverterFactoryContainer,

View file

@ -2,9 +2,9 @@ package com.tangem.data.account.fetcher
import arrow.core.Either
import arrow.core.raise.either
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.fetcher.MultiAccountListFetcher
import com.tangem.domain.account.fetcher.SingleAccountListFetcher
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import kotlinx.coroutines.coroutineScope
@ -17,13 +17,13 @@ import javax.inject.Inject
* Implementation of [MultiAccountListFetcher]
*
* @property singleAccountListFetcher instance of [SingleAccountListFetcher] to fetch accounts for a single wallet
* @property userWalletsStore instance of [UserWalletsStore] to get all user wallets
* @property userWalletsListRepository repository for getting user wallets
*
[REDACTED_AUTHOR]
*/
internal class DefaultMultiAccountListFetcher @Inject constructor(
private val singleAccountListFetcher: SingleAccountListFetcher,
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
) : MultiAccountListFetcher {
override suspend fun invoke(params: MultiAccountListFetcher.Params): Either<Throwable, Unit> = either {
@ -58,7 +58,9 @@ internal class DefaultMultiAccountListFetcher @Inject constructor(
}
}
MultiAccountListFetcher.Params.All -> {
val userWalletsIds = userWalletsStore.userWalletsSync.map(UserWallet::walletId).toSet()
val userWalletsIds = userWalletsListRepository.userWallets.value.orEmpty()
.map(UserWallet::walletId)
.toSet()
invoke(params = MultiAccountListFetcher.Params.Set(ids = userWalletsIds)).bind()
}

View file

@ -4,7 +4,7 @@ import arrow.core.Option
import arrow.core.some
import com.tangem.data.account.store.AccountsResponseStoreFactory
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.*
* Implementation of [MultiWalletCryptoCurrenciesProducer] that produces crypto currencies of all accounts
*
* @property params params
* @property userWalletsStore UserWallet's store
* @property userWalletsListRepository repository for getting user wallets
* @property accountsResponseStoreFactory factory to create store with accounts response
* @property responseCryptoCurrenciesFactory factory for creating [CryptoCurrency] from `UserTokensResponse`
* @property dispatchers dispatchers
@ -29,7 +29,7 @@ import kotlinx.coroutines.flow.*
*/
internal class AccountListCryptoCurrenciesProducer @AssistedInject constructor(
@Assisted val params: MultiWalletCryptoCurrenciesProducer.Params,
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val accountsResponseStoreFactory: AccountsResponseStoreFactory,
private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory,
override val flowProducerTools: FlowProducerTools,
@ -40,7 +40,7 @@ internal class AccountListCryptoCurrenciesProducer @AssistedInject constructor(
@Suppress("NullableToStringCall")
override fun produce(): Flow<Set<CryptoCurrency>> {
val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(id = params.userWalletId)
if (!userWallet.isMultiCurrency) {
error("${this::class.simpleName ?: this::class.toString()} supports only multi-currency wallet")

View file

@ -2,9 +2,9 @@ package com.tangem.data.account.producer
import arrow.core.Option
import arrow.core.some
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.account.producer.MultiAccountListProducer
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
@ -19,7 +19,8 @@ import kotlinx.coroutines.flow.*
* Produces a list of [AccountList]s for all user wallets.
*
* @property params params
* @property userWalletsStore store that provides user wallets
* @property flowProducerTools tools for producing flows
* @property userWalletsListRepository repository for getting user wallets
* @property walletAccountListFlowFactory builder to create flows of [AccountList] for each wallet
* @property dispatchers coroutine dispatchers provider
*
@ -28,7 +29,7 @@ import kotlinx.coroutines.flow.*
internal class DefaultMultiAccountListProducer @AssistedInject constructor(
@Assisted val params: Unit,
override val flowProducerTools: FlowProducerTools,
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val walletAccountListFlowFactory: WalletAccountListFlowFactory,
private val dispatchers: CoroutineDispatcherProvider,
) : MultiAccountListProducer {
@ -37,7 +38,7 @@ internal class DefaultMultiAccountListProducer @AssistedInject constructor(
@OptIn(ExperimentalCoroutinesApi::class)
override fun produce(): Flow<List<AccountList>> {
return userWalletsStore.userWallets
return userWalletsListRepository.loadAndGet()
.map { it.map(UserWallet::walletId) }
.distinctUntilChanged()
.flatMapLatest { ids ->

View file

@ -4,7 +4,7 @@ import arrow.core.Option
import arrow.core.some
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
@ -20,7 +20,8 @@ import kotlinx.coroutines.flow.*
* Default implementation of [MultiWalletCryptoCurrenciesProducer]
*
* @property params params
* @property userWalletsStore UserWallet's store
* @property flowProducerTools tools for producing flows
* @property userWalletsListRepository repository for getting user wallets
* @property userTokensResponseStore store of `UserTokensResponse`
* @property responseCryptoCurrenciesFactory factory for creating [CryptoCurrency] from `UserTokensResponse`
* @property dispatchers dispatchers
@ -30,7 +31,7 @@ import kotlinx.coroutines.flow.*
internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constructor(
@Assisted val params: MultiWalletCryptoCurrenciesProducer.Params,
override val flowProducerTools: FlowProducerTools,
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val userTokensResponseStore: UserTokensResponseStore,
private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory,
private val dispatchers: CoroutineDispatcherProvider,
@ -39,7 +40,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducer @AssistedInject constr
override val fallback: Option<Set<CryptoCurrency>> = emptySet<CryptoCurrency>().some()
override fun produce(): Flow<Set<CryptoCurrency>> {
val userWallet = userWalletsStore.getSyncStrict(key = params.userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(id = params.userWalletId)
if (!userWallet.isMultiCurrency) {
error("${this::class.simpleName ?: this::class.toString()} supports only multi-currency wallet")

View file

@ -4,9 +4,9 @@ import com.tangem.data.account.converter.AccountListConverter
import com.tangem.data.account.store.AccountsResponseStore
import com.tangem.data.account.store.AccountsResponseStoreFactory
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.card.common.util.cardTypesResolver
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isMultiCurrency
@ -17,6 +17,7 @@ import javax.inject.Inject
/**
* Factory that creates a flow of [AccountList] for a specific [UserWallet]
*
* @property userWalletsListRepository repository to get user wallets
* @property accountsResponseStoreFactory factory to create [AccountsResponseStore]
* @property accountListConverterFactory factory to create [AccountListConverter]
* @property cardCryptoCurrencyFactory factory to create supported crypto currencies for a card
@ -24,14 +25,14 @@ import javax.inject.Inject
[REDACTED_AUTHOR]
*/
internal class WalletAccountListFlowFactory @Inject constructor(
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val accountsResponseStoreFactory: AccountsResponseStoreFactory,
private val accountListConverterFactory: AccountListConverter.Factory,
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory,
) {
fun create(userWalletId: UserWalletId): Flow<AccountList> {
val userWallet = userWalletsStore.getSyncStrict(userWalletId)
val userWallet = userWalletsListRepository.getSyncStrict(userWalletId)
return if (userWallet.isMultiCurrency) {
createForMultiWallet(userWallet)

View file

@ -22,7 +22,6 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
import com.tangem.datasource.api.tangemTech.models.account.toUserTokensResponse
import com.tangem.datasource.local.datastore.RuntimeStateStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.datasource.utils.getSyncOrNull
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.account.models.ArchivedAccount
@ -30,7 +29,6 @@ import com.tangem.domain.account.repository.AccountsCRUDRepository
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.AccountName
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.replaceBy
@ -48,7 +46,6 @@ internal class DefaultAccountsCRUDRepository(
private val walletAccountsSaver: WalletAccountsSaver,
private val accountsResponseStoreFactory: AccountsResponseStoreFactory,
private val archivedAccountsStoreFactory: ArchivedAccountsStoreFactory,
private val userWalletsStore: UserWalletsStore,
private val userTokensSaver: UserTokensSaver,
private val archivedAccountsETagStore: RuntimeStateStore<Map<String, String?>>,
private val convertersContainer: AccountConverterFactoryContainer,
@ -205,14 +202,6 @@ internal class DefaultAccountsCRUDRepository(
.map { it?.accounts?.size.toOption() }
}
override fun getUserWallet(userWalletId: UserWalletId): UserWallet {
return userWalletsStore.getSyncStrict(userWalletId)
}
override fun getUserWallets(): Flow<List<UserWallet>> = userWalletsStore.userWallets
override fun getUserWalletsSync(): List<UserWallet> = userWalletsStore.userWalletsSync
override fun checkDefaultAccountName(accountList: AccountList, accountName: AccountName) {
val hasDefaultName = accountList.accounts.any { it.accountName is AccountName.DefaultMain }

View file

@ -6,8 +6,8 @@ import com.tangem.data.common.network.NetworkFactory
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
import com.tangem.domain.models.account.DerivationIndex
@ -18,7 +18,7 @@ import javax.inject.Inject
/**
* Factory to create default [GetWalletAccountsResponse].
*
* @property userWalletsStore store to get user wallet information
* @property userWalletsListRepository repository to get user wallets
* @property cryptoPortfolioCF converter factory to convert crypto portfolio accounts
* @property userTokensResponseFactory factory to create [UserTokensResponse]
* @property networkFactory factory to create network derivation path
@ -26,14 +26,14 @@ import javax.inject.Inject
[REDACTED_AUTHOR]
*/
internal class DefaultWalletAccountsResponseFactory @Inject constructor(
private val userWalletsStore: UserWalletsStore,
private val userWalletsListRepository: UserWalletsListRepository,
private val cryptoPortfolioCF: CryptoPortfolioConverter.Factory,
private val userTokensResponseFactory: UserTokensResponseFactory,
private val networkFactory: NetworkFactory,
) {
fun create(userWalletId: UserWalletId, userTokensResponse: UserTokensResponse?): GetWalletAccountsResponse {
val userWallet = userWalletsStore.getSyncOrNull(userWalletId)
val userWallet = userWalletsListRepository.getSyncOrNull(userWalletId)
val accountDTOs = userWallet?.let(::createDefaultAccountDTOs).orEmpty()
val response = userTokensResponse.orDefault(userWallet = userWallet)

View file

@ -2,9 +2,9 @@ package com.tangem.data.account.fetcher
import arrow.core.left
import arrow.core.right
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.fetcher.MultiAccountListFetcher
import com.tangem.domain.account.fetcher.SingleAccountListFetcher
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.test.core.assertEitherLeft
@ -19,9 +19,12 @@ import org.junit.jupiter.api.TestInstance
class DefaultMultiAccountListFetcherTest {
private val singleAccountListFetcher: SingleAccountListFetcher = mockk()
private val userWalletsStore: UserWalletsStore = mockk(relaxUnitFun = true)
private val userWalletsListRepository: UserWalletsListRepository = mockk(relaxUnitFun = true)
private val fetcher = DefaultMultiAccountListFetcher(singleAccountListFetcher, userWalletsStore)
private val fetcher = DefaultMultiAccountListFetcher(
singleAccountListFetcher = singleAccountListFetcher,
userWalletsListRepository = userWalletsListRepository,
)
private val userWalletId1 = UserWalletId("011")
private val userWalletId2 = UserWalletId("012")
@ -35,7 +38,7 @@ class DefaultMultiAccountListFetcherTest {
@AfterEach
fun tearDown() {
clearMocks(singleAccountListFetcher, userWalletsStore)
clearMocks(singleAccountListFetcher, userWalletsListRepository)
}
@Test
@ -98,7 +101,7 @@ class DefaultMultiAccountListFetcherTest {
// Arrange
val params = MultiAccountListFetcher.Params.All
every { userWalletsStore.userWalletsSync } returns listOf(userWallets.first())
every { userWalletsListRepository.userWallets.value } returns listOf(userWallets.first())
coEvery {
singleAccountListFetcher(params = SingleAccountListFetcher.Params(userWalletId1))
@ -111,7 +114,7 @@ class DefaultMultiAccountListFetcherTest {
assertEitherRight(actual)
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWalletsSync
userWalletsListRepository.userWallets.value
singleAccountListFetcher(params = SingleAccountListFetcher.Params(userWalletId1))
}
}
@ -121,7 +124,7 @@ class DefaultMultiAccountListFetcherTest {
// Arrange
val params = MultiAccountListFetcher.Params.All
every { userWalletsStore.userWalletsSync } returns userWallets
every { userWalletsListRepository.userWallets.value } returns userWallets
val exception = Exception("Fetch failed")
coEvery {
@ -145,7 +148,7 @@ class DefaultMultiAccountListFetcherTest {
assertEitherLeft(actual, expected)
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWalletsSync
userWalletsListRepository.userWallets.value
singleAccountListFetcher(params = SingleAccountListFetcher.Params(userWalletId1))
singleAccountListFetcher(params = SingleAccountListFetcher.Params(userWalletId2))
}

View file

@ -1,8 +1,8 @@
package com.tangem.data.account.producer
import com.google.common.truth.Truth
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.TokensSortType
import com.tangem.domain.models.wallet.UserWallet
@ -27,15 +27,15 @@ import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DefaultMultiAccountListProducerTest {
private val userWalletsStore: UserWalletsStore = mockk()
private val userWalletsListRepository: UserWalletsListRepository = mockk()
private val walletAccountListFlowFactory: WalletAccountListFlowFactory = mockk()
private val flowProducerTools: FlowProducerTools = mockk()
private val producer = DefaultMultiAccountListProducer(
params = Unit,
userWalletsStore = userWalletsStore,
walletAccountListFlowFactory = walletAccountListFlowFactory,
flowProducerTools = flowProducerTools,
userWalletsListRepository = userWalletsListRepository,
walletAccountListFlowFactory = walletAccountListFlowFactory,
dispatchers = TestingCoroutineDispatcherProvider(),
)
@ -46,14 +46,14 @@ class DefaultMultiAccountListProducerTest {
@AfterEach
fun tearDownEach() {
clearMocks(userWalletsStore, walletAccountListFlowFactory)
clearMocks(userWalletsListRepository, walletAccountListFlowFactory)
}
@Test
fun produce() = runTest {
// Arrange
val userWalletsFlow = MutableStateFlow(value = listOf(userWallet))
every { userWalletsStore.userWallets } returns userWalletsFlow
every { userWalletsListRepository.loadAndGet() } returns userWalletsFlow
val accountList = AccountList.empty(userWalletId)
every { walletAccountListFlowFactory.create(userWalletId) } returns flowOf(accountList)
@ -66,7 +66,7 @@ class DefaultMultiAccountListProducerTest {
Truth.assertThat(actual).containsExactly(expected)
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
}
}
@ -75,7 +75,7 @@ class DefaultMultiAccountListProducerTest {
fun `flow will updated if factoryFlow is updated`() = runTest {
// Arrange
val userWalletsFlow = MutableStateFlow(value = listOf(userWallet))
every { userWalletsStore.userWallets } returns userWalletsFlow
every { userWalletsListRepository.loadAndGet() } returns userWalletsFlow
val accountList = AccountList.empty(userWalletId)
val updatedAccountList = AccountList.empty(userWalletId = userWalletId, sortType = TokensSortType.NONE)
@ -98,9 +98,9 @@ class DefaultMultiAccountListProducerTest {
Truth.assertThat(secondEmission).containsExactly(listOf(updatedAccountList))
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
}
}
@ -109,7 +109,7 @@ class DefaultMultiAccountListProducerTest {
fun `flow is filtered the same response`() = runTest {
// Arrange
val userWalletsFlow = MutableStateFlow(value = listOf(userWallet))
every { userWalletsStore.userWallets } returns userWalletsFlow
every { userWalletsListRepository.loadAndGet() } returns userWalletsFlow
val accountList = AccountList.empty(userWalletId)
val factoryFlow = MutableStateFlow<AccountList?>(null)
@ -131,9 +131,9 @@ class DefaultMultiAccountListProducerTest {
Truth.assertThat(secondEmission).containsExactly(listOf(accountList))
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
}
}
@ -143,7 +143,7 @@ class DefaultMultiAccountListProducerTest {
fun `flow returns empty list if factory throws exception`() = runTest {
// Arrange
val userWalletsFlow = MutableStateFlow(value = listOf(userWallet))
every { userWalletsStore.userWallets } returns userWalletsFlow
every { userWalletsListRepository.loadAndGet() } returns userWalletsFlow
val exception = RuntimeException("Converter error")
every { walletAccountListFlowFactory.create(userWalletId) } throws exception
@ -156,7 +156,7 @@ class DefaultMultiAccountListProducerTest {
Truth.assertThat(actual).containsExactly(expected)
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
}
}
@ -165,7 +165,7 @@ class DefaultMultiAccountListProducerTest {
fun `flow is empty if userWalletsFlow returns empty flow`() = runTest {
// Arrange
val userWalletsFlow = emptyFlow<List<UserWallet>>()
every { userWalletsStore.userWallets } returns userWalletsFlow
every { userWalletsListRepository.loadAndGet() } returns userWalletsFlow
// Act
val actual = producer.produce().let(::getEmittedValues)
@ -173,7 +173,7 @@ class DefaultMultiAccountListProducerTest {
// Assert
Truth.assertThat(actual).isEmpty() // no emissions
coVerify(exactly = 1) { userWalletsStore.userWallets }
coVerify(exactly = 1) { userWalletsListRepository.loadAndGet() }
coVerify(inverse = true) { walletAccountListFlowFactory.create(any()) }
}
@ -181,7 +181,7 @@ class DefaultMultiAccountListProducerTest {
fun `flow is empty if factory returns empty flow`() = runTest {
// Arrange
val userWalletsFlow = MutableStateFlow(value = listOf(userWallet))
every { userWalletsStore.userWallets } returns userWalletsFlow
every { userWalletsListRepository.loadAndGet() } returns userWalletsFlow
every { walletAccountListFlowFactory.create(userWalletId) } returns emptyFlow()
@ -192,7 +192,7 @@ class DefaultMultiAccountListProducerTest {
Truth.assertThat(actual).isEmpty() // no emissions
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
}
}
@ -206,7 +206,7 @@ class DefaultMultiAccountListProducerTest {
}
val userWalletsFlow = MutableStateFlow(listOf(userWallet, userWallet2))
every { userWalletsStore.userWallets } returns userWalletsFlow
every { userWalletsListRepository.loadAndGet() } returns userWalletsFlow
val accountList = AccountList.empty(userWalletId)
every { walletAccountListFlowFactory.create(userWalletId) } returns flowOf(accountList)
@ -219,7 +219,7 @@ class DefaultMultiAccountListProducerTest {
Truth.assertThat(actual).isEmpty() // no emissions
coVerify(ordering = Ordering.SEQUENCE) {
userWalletsStore.userWallets
userWalletsListRepository.loadAndGet()
walletAccountListFlowFactory.create(userWalletId)
walletAccountListFlowFactory.create(userWalletId2)
}

View file

@ -8,8 +8,8 @@ import com.tangem.common.test.domain.wallet.MockUserWalletFactory
import com.tangem.data.common.currency.ResponseCryptoCurrenciesFactory
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.local.token.UserTokensResponseStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.card.configs.GenericCardConfig
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.core.flow.FlowProducerTools
import com.tangem.domain.models.account.DerivationIndex
import com.tangem.domain.models.currency.CryptoCurrency
@ -35,23 +35,23 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
private val cryptoCurrencyFactory = MockCryptoCurrencyFactory()
private val params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId = userWallet.walletId)
private val userWalletsStore: UserWalletsStore = mockk(relaxUnitFun = true)
private val userWalletsListRepository: UserWalletsListRepository = mockk(relaxUnitFun = true)
private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxUnitFun = true)
private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory = mockk()
private val flowProducerTools: FlowProducerTools = mockk()
private val producer = DefaultMultiWalletCryptoCurrenciesProducer(
params = params,
userWalletsStore = userWalletsStore,
flowProducerTools = flowProducerTools,
userWalletsListRepository = userWalletsListRepository,
userTokensResponseStore = userTokensResponseStore,
responseCryptoCurrenciesFactory = responseCryptoCurrenciesFactory,
flowProducerTools = flowProducerTools,
dispatchers = TestingCoroutineDispatcherProvider(),
)
@BeforeEach
fun resetMocks() {
clearMocks(userWalletsStore, userTokensResponseStore, responseCryptoCurrenciesFactory)
clearMocks(userWalletsListRepository, userTokensResponseStore, responseCryptoCurrenciesFactory)
}
@Test
@ -59,7 +59,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
// Arrange
val userTokensResponseFlow = flowOf<UserTokensResponse?>(null)
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns userWallet
every { userWalletsListRepository.getSyncStrict(params.userWalletId) } returns userWallet
every { userTokensResponseStore.get(params.userWalletId) } returns userTokensResponseFlow
// Act
@ -72,7 +72,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
Truth.assertThat(actual.first()).isEqualTo(expected)
verifyOrder {
userWalletsStore.getSyncStrict(params.userWalletId)
userWalletsListRepository.getSyncStrict(params.userWalletId)
userTokensResponseStore.get(params.userWalletId)
}
@ -113,7 +113,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
cryptoCurrencyFactory.createCoin(Blockchain.Bitcoin),
)
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns userWallet
every { userWalletsListRepository.getSyncStrict(params.userWalletId) } returns userWallet
every { userTokensResponseStore.get(params.userWalletId) } returns userTokensResponseFlow
every {
@ -146,7 +146,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
Truth.assertThat(actual1.first()).isEqualTo(expected1)
verifyOrder {
userWalletsStore.getSyncStrict(params.userWalletId)
userWalletsListRepository.getSyncStrict(params.userWalletId)
userTokensResponseStore.get(params.userWalletId)
responseCryptoCurrenciesFactory.createCurrencies(
response = userTokensResponse,
@ -188,7 +188,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
val cryptoCurrencies = emptySet<CryptoCurrency>()
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns userWallet
every { userWalletsListRepository.getSyncStrict(params.userWalletId) } returns userWallet
every { userTokensResponseStore.get(params.userWalletId) } returns userTokensResponseFlow
every {
@ -213,7 +213,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
Truth.assertThat(actual1.first()).isEqualTo(expected1)
verifyOrder {
userWalletsStore.getSyncStrict(params.userWalletId)
userWalletsListRepository.getSyncStrict(params.userWalletId)
userTokensResponseStore.get(params.userWalletId)
responseCryptoCurrenciesFactory.createCurrencies(
response = userTokensResponse,
@ -257,7 +257,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
}
.buffer(capacity = 5)
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns userWallet
every { userWalletsListRepository.getSyncStrict(params.userWalletId) } returns userWallet
every { userTokensResponseStore.get(params.userWalletId) } returns userTokensResponseFlow
every {
@ -279,7 +279,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
Truth.assertThat(actual1.first()).isEqualTo(expected1)
verifyOrder {
userWalletsStore.getSyncStrict(params.userWalletId)
userWalletsListRepository.getSyncStrict(params.userWalletId)
userTokensResponseStore.get(params.userWalletId)
}
@ -304,7 +304,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
@Test
fun `flow is empty if store returns empty flow`() = runTest {
// Arrange
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns userWallet
every { userWalletsListRepository.getSyncStrict(params.userWalletId) } returns userWallet
every { userTokensResponseStore.get(params.userWalletId) } returns emptyFlow()
// Act
@ -316,7 +316,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
Truth.assertThat(actual.first()).isEqualTo(expected)
verifyOrder {
userWalletsStore.getSyncStrict(params.userWalletId)
userWalletsListRepository.getSyncStrict(params.userWalletId)
userTokensResponseStore.get(params.userWalletId)
}
@ -332,7 +332,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
every { isMultiCurrency } returns false
}
every { userWalletsStore.getSyncStrict(params.userWalletId) } returns mockUserWallet
every { userWalletsListRepository.getSyncStrict(params.userWalletId) } returns mockUserWallet
// Act
val actual = runCatching { producer.produce() }.exceptionOrNull()
@ -345,7 +345,7 @@ internal class DefaultMultiWalletCryptoCurrenciesProducerTest {
Truth.assertThat(actual).isInstanceOf(expected::class.java)
Truth.assertThat(actual).hasMessageThat().isEqualTo(expected.message)
verifyOrder { userWalletsStore.getSyncStrict(params.userWalletId) }
verifyOrder { userWalletsListRepository.getSyncStrict(params.userWalletId) }
verify(inverse = true) {
userTokensResponseStore.get(any())

View file

@ -9,8 +9,8 @@ import com.tangem.data.account.store.AccountsResponseStore
import com.tangem.data.account.store.AccountsResponseStoreFactory
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.models.wallet.isMultiCurrency
@ -29,7 +29,7 @@ import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class WalletAccountListFlowFactoryTest {
private val userWalletsStore: UserWalletsStore = mockk()
private val userWalletsListRepository: UserWalletsListRepository = mockk()
private val accountsResponseStoreFactory: AccountsResponseStoreFactory = mockk()
private val accountsResponseStore: AccountsResponseStore = mockk()
private val accountsResponseStoreFlow = MutableStateFlow<GetWalletAccountsResponse?>(value = null)
@ -40,7 +40,7 @@ class WalletAccountListFlowFactoryTest {
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory = mockk()
private val factory = WalletAccountListFlowFactory(
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
accountsResponseStoreFactory = accountsResponseStoreFactory,
accountListConverterFactory = accountListConverterFactory,
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
@ -52,7 +52,7 @@ class WalletAccountListFlowFactoryTest {
@AfterEach
fun tearDownEach() {
clearMocks(
userWalletsStore,
userWalletsListRepository,
accountsResponseStoreFactory,
accountsResponseStore,
accountListConverterFactory,
@ -70,7 +70,7 @@ class WalletAccountListFlowFactoryTest {
every { this@mockk.isMultiCurrency } returns true
}
every { userWalletsStore.getSyncStrict(userWalletId) } returns userWallet
every { userWalletsListRepository.getSyncStrict(userWalletId) } returns userWallet
val accountsResponse = createGetWalletAccountsResponse(userWalletId)
every { accountsResponseStoreFactory.create(userWalletId) } returns accountsResponseStore
@ -105,7 +105,7 @@ class WalletAccountListFlowFactoryTest {
fun `create for single wallet`() = runTest {
val userWallet = MockUserWalletFactory.create().copy(isMultiCurrency = false)
every { userWalletsStore.getSyncStrict(userWallet.walletId) } returns userWallet
every { userWalletsListRepository.getSyncStrict(userWallet.walletId) } returns userWallet
val currency = cryptoCurrencyFactory.ethereum
every { cardCryptoCurrencyFactory.createPrimaryCurrencyForSingleCurrencyCard(userWallet) } returns currency
@ -134,7 +134,7 @@ class WalletAccountListFlowFactoryTest {
fun `flow is created for single wallet with token`() = runTest {
val nodl = MockUserWalletFactory.createSingleWalletWithToken()
every { userWalletsStore.getSyncStrict(nodl.walletId) } returns nodl
every { userWalletsListRepository.getSyncStrict(nodl.walletId) } returns nodl
val currencies = cryptoCurrencyFactory.ethereumAndStellar.toSet()
every {

View file

@ -17,7 +17,6 @@ import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResp
import com.tangem.datasource.api.tangemTech.models.account.GetWalletArchivedAccountsResponse
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
import com.tangem.datasource.local.datastore.RuntimeStateStore
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.account.models.ArchivedAccount
import com.tangem.domain.models.account.Account.CryptoPortfolio
@ -52,7 +51,6 @@ class DefaultAccountsCRUDRepositoryTest {
private val archivedAccountsInnerStore = RuntimeStateStore<List<ArchivedAccount>?>(defaultValue = null)
private val archivedAccountsStore = ArchivedAccountsStore(runtimeStore = archivedAccountsInnerStore)
private val userWalletsStore: UserWalletsStore = mockk()
private val userTokensSaver: UserTokensSaver = mockk()
private val archivedAccountsETagStore: RuntimeStateStore<Map<String, String?>> = mockk(relaxUnitFun = true)
@ -67,7 +65,6 @@ class DefaultAccountsCRUDRepositoryTest {
walletAccountsSaver = walletAccountsSaver,
accountsResponseStoreFactory = accountsResponseStoreFactory,
archivedAccountsStoreFactory = archivedAccountsStoreFactory,
userWalletsStore = userWalletsStore,
userTokensSaver = userTokensSaver,
archivedAccountsETagStore = archivedAccountsETagStore,
convertersContainer = convertersContainer,

View file

@ -8,8 +8,8 @@ import com.tangem.data.common.currency.UserTokensResponseFactory
import com.tangem.data.common.network.NetworkFactory
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
import com.tangem.datasource.local.userwallet.UserWalletsStore
import com.tangem.domain.account.models.AccountList
import com.tangem.domain.common.wallets.UserWalletsListRepository
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.wallet.UserWallet
import com.tangem.domain.models.wallet.UserWalletId
@ -23,14 +23,14 @@ import org.junit.jupiter.api.TestInstance
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DefaultWalletAccountsResponseFactoryTest {
private val userWalletsStore = mockk<UserWalletsStore>()
private val userWalletsListRepository = mockk<UserWalletsListRepository>()
private val cryptoPortfolioCF = mockk<CryptoPortfolioConverter.Factory>()
private val cryptoPortfolioConverter = mockk<CryptoPortfolioConverter>()
private val userTokensResponseFactory = mockk<UserTokensResponseFactory>()
private val networkFactory = mockk<NetworkFactory>()
private val factory = DefaultWalletAccountsResponseFactory(
userWalletsStore = userWalletsStore,
userWalletsListRepository = userWalletsListRepository,
cryptoPortfolioCF = cryptoPortfolioCF,
userTokensResponseFactory = userTokensResponseFactory,
networkFactory = networkFactory,
@ -46,7 +46,7 @@ class DefaultWalletAccountsResponseFactoryTest {
@AfterEach
fun tearDownEach() {
clearMocks(
userWalletsStore,
userWalletsListRepository,
cryptoPortfolioCF,
cryptoPortfolioConverter,
userTokensResponseFactory,
@ -63,7 +63,7 @@ class DefaultWalletAccountsResponseFactoryTest {
tokens = emptyList(),
)
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns null
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns null
every {
userTokensResponseFactory.createDefaultResponse(
userWallet = null,
@ -89,7 +89,7 @@ class DefaultWalletAccountsResponseFactoryTest {
Truth.assertThat(actual).isEqualTo(expected)
coVerifyOrder {
userWalletsStore.getSyncOrNull(userWalletId)
userWalletsListRepository.getSyncOrNull(userWalletId)
userTokensResponseFactory.createDefaultResponse(
userWallet = null,
networkFactory = networkFactory,
@ -105,7 +105,7 @@ class DefaultWalletAccountsResponseFactoryTest {
every { walletId } returns userWalletId
}
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
val accounts = AccountList.empty(userWallet.walletId).accounts
.filterIsInstance<Account.CryptoPortfolio>()
@ -145,7 +145,7 @@ class DefaultWalletAccountsResponseFactoryTest {
Truth.assertThat(actual).isEqualTo(expected)
coVerifyOrder {
userWalletsStore.getSyncOrNull(userWalletId)
userWalletsListRepository.getSyncOrNull(userWalletId)
cryptoPortfolioConverter.convertListBack(accounts)
userTokensResponseFactory.createDefaultResponse(
userWallet = userWallet,
@ -165,7 +165,7 @@ class DefaultWalletAccountsResponseFactoryTest {
val accounts = AccountList.empty(userWallet.walletId).accounts
.filterIsInstance<Account.CryptoPortfolio>()
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
val defaultResponse = UserTokensResponse(
group = UserTokensResponse.GroupType.NETWORK,
@ -206,7 +206,7 @@ class DefaultWalletAccountsResponseFactoryTest {
val userWallet = mockk<UserWallet>(relaxed = true) {
every { walletId } returns userWalletId
}
coEvery { userWalletsStore.getSyncOrNull(userWalletId) } returns userWallet
coEvery { userWalletsListRepository.getSyncOrNull(userWalletId) } returns userWallet
val userTokensResponse = UserTokensResponse(
group = UserTokensResponse.GroupType.NETWORK,