diff --git a/app/src/main/java/com/tangem/tap/di/domain/AccountDomainModule.kt b/app/src/main/java/com/tangem/tap/di/domain/AccountDomainModule.kt index 569c69c6b8..1240259f77 100644 --- a/app/src/main/java/com/tangem/tap/di/domain/AccountDomainModule.kt +++ b/app/src/main/java/com/tangem/tap/di/domain/AccountDomainModule.kt @@ -1,6 +1,5 @@ package com.tangem.tap.di.domain -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.account.fetcher.SingleAccountListFetcher import com.tangem.domain.account.repository.AccountsCRUDRepository import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier @@ -97,12 +96,10 @@ internal object AccountDomainModule { fun provideIsAccountsModeEnabledUseCase( userWalletsListRepository: UserWalletsListRepository, accountsCRUDRepository: AccountsCRUDRepository, - accountsFeatureToggles: AccountsFeatureToggles, ): IsAccountsModeEnabledUseCase { return IsAccountsModeEnabledUseCase( userWalletsListRepository = userWalletsListRepository, crudRepository = accountsCRUDRepository, - accountsFeatureToggles = accountsFeatureToggles, ) } diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json index dc14b38ca6..73b02b2af8 100644 --- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json @@ -24,10 +24,6 @@ "name": "HOT_WALLET_CREATION_RESTRICTION_ENABLED", "version": "5.32.0" }, - { - "name": "ACCOUNTS_FEATURE_ENABLED", - "version": "5.33.0" - }, { "name": "APP_REDESIGN_ENABLED", "version": "undefined" diff --git a/data/account/src/main/kotlin/com/tangem/data/account/di/AccountDataModule.kt b/data/account/src/main/kotlin/com/tangem/data/account/di/AccountDataModule.kt index fc62ab079a..5af224e026 100644 --- a/data/account/src/main/kotlin/com/tangem/data/account/di/AccountDataModule.kt +++ b/data/account/src/main/kotlin/com/tangem/data/account/di/AccountDataModule.kt @@ -4,9 +4,7 @@ import android.content.Context import androidx.datastore.core.DataStoreFactory import androidx.datastore.dataStoreFile import com.squareup.moshi.Moshi -import com.tangem.core.configtoggle.feature.FeatureTogglesManager import com.tangem.data.account.converter.AccountConverterFactoryContainer -import com.tangem.data.account.featuretoggle.DefaultAccountsFeatureToggles import com.tangem.data.account.fetcher.DefaultWalletAccountsFetcher import com.tangem.data.account.repository.AccountsExpandedDTO import com.tangem.data.account.repository.DefaultAccountsCRUDRepository @@ -25,7 +23,6 @@ import com.tangem.datasource.local.datastore.RuntimeStateStore import com.tangem.datasource.utils.MoshiDataStoreSerializer import com.tangem.datasource.utils.mapWithStringKeyTypes import com.tangem.datasource.utils.setTypes -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.account.repository.AccountsCRUDRepository import com.tangem.domain.account.repository.AccountsExpandedRepository import com.tangem.domain.account.tokens.MainAccountTokensMigration @@ -43,12 +40,6 @@ import javax.inject.Singleton @InstallIn(SingletonComponent::class) internal object AccountDataModule { - @Provides - @Singleton - fun provideAccountFeatureToggle(featureTogglesManager: FeatureTogglesManager): AccountsFeatureToggles { - return DefaultAccountsFeatureToggles(featureTogglesManager = featureTogglesManager) - } - @Provides @Singleton fun provideAccountsCRUDRepository( diff --git a/data/account/src/main/kotlin/com/tangem/data/account/di/MultiWalletCryptoCurrenciesProducerModule.kt b/data/account/src/main/kotlin/com/tangem/data/account/di/MultiWalletCryptoCurrenciesProducerModule.kt index e283366b5b..deb207e821 100644 --- a/data/account/src/main/kotlin/com/tangem/data/account/di/MultiWalletCryptoCurrenciesProducerModule.kt +++ b/data/account/src/main/kotlin/com/tangem/data/account/di/MultiWalletCryptoCurrenciesProducerModule.kt @@ -1,8 +1,6 @@ package com.tangem.data.account.di import com.tangem.data.account.producer.AccountListCryptoCurrenciesProducer -import com.tangem.data.account.producer.DefaultMultiWalletCryptoCurrenciesProducer -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesProducer import dagger.Module import dagger.Provides @@ -17,10 +15,8 @@ internal object MultiWalletCryptoCurrenciesProducerModule { @Singleton @Provides fun provideMultiWalletCryptoCurrenciesProducerFactory( - accountsFeatureToggles: AccountsFeatureToggles, - defaultImpl: DefaultMultiWalletCryptoCurrenciesProducer.Factory, accountsImpl: AccountListCryptoCurrenciesProducer.Factory, ): MultiWalletCryptoCurrenciesProducer.Factory { - return if (accountsFeatureToggles.isFeatureEnabled) accountsImpl else defaultImpl + return accountsImpl } } \ No newline at end of file diff --git a/data/account/src/main/kotlin/com/tangem/data/account/featuretoggle/DefaultAccountsFeatureToggles.kt b/data/account/src/main/kotlin/com/tangem/data/account/featuretoggle/DefaultAccountsFeatureToggles.kt deleted file mode 100644 index 0a6accf03f..0000000000 --- a/data/account/src/main/kotlin/com/tangem/data/account/featuretoggle/DefaultAccountsFeatureToggles.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.tangem.data.account.featuretoggle - -import com.tangem.core.configtoggle.feature.FeatureTogglesManager -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles - -internal class DefaultAccountsFeatureToggles( - private val featureTogglesManager: FeatureTogglesManager, -) : AccountsFeatureToggles { - - override val isFeatureEnabled: Boolean - get() = featureTogglesManager.isFeatureEnabled(name = "ACCOUNTS_FEATURE_ENABLED") -} \ No newline at end of file diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt index a55c9c0da8..8dfe637ba5 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactory.kt @@ -5,8 +5,6 @@ import com.tangem.blockchainsdk.utils.toBlockchain import com.tangem.blockchainsdk.utils.toNetworkId import com.tangem.data.common.account.WalletAccountsFetcher import com.tangem.data.common.tokens.getDefaultWalletBlockchains -import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.getSyncStrict @@ -23,17 +21,13 @@ import com.tangem.domain.models.wallet.isMultiCurrency * * @property demoConfig demo config * @property excludedBlockchains excluded blockchains - * @property userWalletsStore user wallets store - * @property userTokensResponseStore user tokens response store */ @Suppress("LongParameterList") internal class DefaultCardCryptoCurrencyFactory( private val demoConfig: DemoConfig, private val excludedBlockchains: ExcludedBlockchains, private val userWalletsListRepository: UserWalletsListRepository, - private val accountsFeatureToggles: AccountsFeatureToggles, private val walletAccountsFetcher: WalletAccountsFetcher, - private val userTokensResponseStore: UserTokensResponseStore, private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, ) : CardCryptoCurrencyFactory { @@ -140,34 +134,21 @@ internal class DefaultCardCryptoCurrencyFactory( userWallet: UserWallet, networks: Set, ): Map> { - val existingNetworkWithCurrencies = if (accountsFeatureToggles.isFeatureEnabled) { - val response = walletAccountsFetcher.getSaved(userWallet.walletId) - ?: return emptyMap() + val response = walletAccountsFetcher.getSaved(userWallet.walletId) + ?: return emptyMap() - response.accounts.flatMapTo(hashSetOf()) { accountDTO -> - val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull() - ?: return@flatMapTo emptySet() - - responseCryptoCurrenciesFactory.createCurrencies( - tokens = accountDTO.tokens.orEmpty().filter { token -> - networks.any { - it.backendId == token.networkId && it.derivationPath.value == token.derivationPath - } - }, - userWallet = userWallet, - accountIndex = accountIndex, - ) - } - } else { - val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId) - ?: return emptyMap() + val existingNetworkWithCurrencies = response.accounts.flatMapTo(hashSetOf()) { accountDTO -> + val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull() + ?: return@flatMapTo emptySet() responseCryptoCurrenciesFactory.createCurrencies( - tokens = response.tokens.filter { token -> - networks.any { it.backendId == token.networkId && it.derivationPath.value == token.derivationPath } + tokens = accountDTO.tokens.orEmpty().filter { token -> + networks.any { + it.backendId == token.networkId && it.derivationPath.value == token.derivationPath + } }, userWallet = userWallet, - accountIndex = DerivationIndex.Main, + accountIndex = accountIndex, ) } .groupBy(CryptoCurrency::network) @@ -181,28 +162,17 @@ internal class DefaultCardCryptoCurrencyFactory( ): Map> { val networkIds = rawIds.map { it.toBlockchain().toNetworkId() } - return if (accountsFeatureToggles.isFeatureEnabled) { - val response = walletAccountsFetcher.getSaved(userWallet.walletId) - ?: return emptyMap() + val response = walletAccountsFetcher.getSaved(userWallet.walletId) + ?: return emptyMap() - response.accounts.flatMapTo(hashSetOf()) { accountDTO -> - val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull() - ?: return@flatMapTo emptySet() - - responseCryptoCurrenciesFactory.createCurrencies( - tokens = accountDTO.tokens.orEmpty().filter { token -> token.networkId in networkIds }, - userWallet = userWallet, - accountIndex = accountIndex, - ) - } - } else { - val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId) - ?: return emptyMap() + return response.accounts.flatMapTo(hashSetOf()) { accountDTO -> + val accountIndex = DerivationIndex(accountDTO.derivationIndex).getOrNull() + ?: return@flatMapTo emptySet() responseCryptoCurrenciesFactory.createCurrencies( - tokens = response.tokens.filter { token -> token.networkId in networkIds }, + tokens = accountDTO.tokens.orEmpty().filter { token -> token.networkId in networkIds }, userWallet = userWallet, - accountIndex = DerivationIndex.Main, + accountIndex = accountIndex, ) } .groupBy { it.network.id.rawId } diff --git a/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt b/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt index cff0ae1d6d..a1ab6f180b 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/currency/UserTokensSaver.kt @@ -8,10 +8,7 @@ import com.tangem.datasource.api.common.response.ApiResponseError import com.tangem.datasource.api.common.response.isNetworkError import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.api.tangemTech.models.UserTokensResponse -import com.tangem.datasource.api.tangemTech.models.WalletType -import com.tangem.datasource.local.appsflyer.AppsFlyerStore import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.getSyncOrNull import com.tangem.domain.models.wallet.UserWallet @@ -30,8 +27,6 @@ class UserTokensSaver( private val dispatchers: CoroutineDispatcherProvider, private val addressesEnricher: UserTokensResponseAddressesEnricher, private val walletServerBinder: WalletServerBinder, - private val appsFlyerStore: AppsFlyerStore, - private val accountsFeatureToggles: AccountsFeatureToggles, private val pushTokensRetryerPool: RetryerPool, ) { private val userTokensBackwardCompatibility = UserTokensBackwardCompatibility() @@ -68,22 +63,9 @@ class UserTokensSaver( return@withContext } - if (accountsFeatureToggles.isFeatureEnabled) { - val enrichedResponse = response.enrichIf(userWalletId = userWalletId, condition = useEnricher) + val enrichedResponse = response.enrichIf(userWalletId = userWalletId, condition = useEnricher) - pushNew(userWallet = userWallet, response = enrichedResponse, onFailSend = onFailSend) - } else { - val conversionData = appsFlyerStore.get() - - val enrichedResponse = response.enrichIf(userWalletId = userWalletId, condition = useEnricher).copy( - walletName = userWallet.name.takeIf { it.isNotBlank() }, - walletType = WalletType.from(userWallet), - refcode = conversionData?.refcode, - campaign = conversionData?.campaign, - ) - - pushLegacy(userWalletId = userWalletId, response = enrichedResponse, onFailSend = onFailSend) - } + push(userWallet = userWallet, response = enrichedResponse, onFailSend = onFailSend) } suspend fun pushWithRetryer( @@ -103,14 +85,7 @@ class UserTokensSaver( ) } - private suspend fun pushLegacy(userWalletId: UserWalletId, response: UserTokensResponse, onFailSend: () -> Unit) { - safeApiCall( - call = { tangemTechApi.saveUserTokens(userId = userWalletId.stringValue, userTokens = response).bind() }, - onError = { onFailSend() }, - ) - } - - private suspend fun pushNew(userWallet: UserWallet, response: UserTokensResponse, onFailSend: () -> Unit) { + private suspend fun push(userWallet: UserWallet, response: UserTokensResponse, onFailSend: () -> Unit) { safeApiCall( call = { val apiResponse = tangemTechApi.saveTokens( @@ -148,13 +123,7 @@ class UserTokensSaver( return this .enrichByAddress(userWalletId = userWalletId) - .let { response -> - if (accountsFeatureToggles.isFeatureEnabled) { - response.enrichByAccountId(userWalletId = userWalletId) - } else { - response - } - } + .enrichByAccountId(userWalletId = userWalletId) } private suspend fun UserTokensResponse.enrichByAddress(userWalletId: UserWalletId): UserTokensResponse { diff --git a/data/common/src/main/kotlin/com/tangem/data/common/di/DataCommonModule.kt b/data/common/src/main/kotlin/com/tangem/data/common/di/DataCommonModule.kt index 9ce3a6b121..2d0f7de535 100644 --- a/data/common/src/main/kotlin/com/tangem/data/common/di/DataCommonModule.kt +++ b/data/common/src/main/kotlin/com/tangem/data/common/di/DataCommonModule.kt @@ -13,7 +13,6 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.local.appsflyer.AppsFlyerStore import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.demo.models.DemoConfig import com.tangem.domain.walletmanager.WalletManagersFacade @@ -37,18 +36,14 @@ internal object DataCommonModule { fun provideCardCryptoCurrencyFactory( excludedBlockchains: ExcludedBlockchains, userWalletsListRepository: UserWalletsListRepository, - accountsFeatureToggles: AccountsFeatureToggles, walletAccountsFetcher: WalletAccountsFetcher, - userTokensResponseStore: UserTokensResponseStore, responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, ): CardCryptoCurrencyFactory { return DefaultCardCryptoCurrencyFactory( demoConfig = DemoConfig, excludedBlockchains = excludedBlockchains, userWalletsListRepository = userWalletsListRepository, - accountsFeatureToggles = accountsFeatureToggles, walletAccountsFetcher = walletAccountsFetcher, - userTokensResponseStore = userTokensResponseStore, responseCryptoCurrenciesFactory = responseCryptoCurrenciesFactory, ) } @@ -76,8 +71,6 @@ internal object DataCommonModule { dispatchers: CoroutineDispatcherProvider, addressesEnricher: UserTokensResponseAddressesEnricher, walletServerBinder: WalletServerBinder, - appsFlyerStore: AppsFlyerStore, - accountsFeatureToggles: AccountsFeatureToggles, ): UserTokensSaver { return UserTokensSaver( tangemTechApi = tangemTechApi, @@ -85,12 +78,10 @@ internal object DataCommonModule { userTokensResponseStore = userTokensResponseStore, dispatchers = dispatchers, addressesEnricher = addressesEnricher, - accountsFeatureToggles = accountsFeatureToggles, pushTokensRetryerPool = RetryerPool( coroutineScope = CoroutineScope(SupervisorJob() + dispatchers.default), ), walletServerBinder = walletServerBinder, - appsFlyerStore = appsFlyerStore, ) } diff --git a/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt b/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt index eb90a1efb0..749eadff8b 100644 --- a/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt +++ b/data/common/src/test/kotlin/com/tangem/data/common/currency/DefaultCardCryptoCurrencyFactoryTest.kt @@ -11,8 +11,8 @@ import com.tangem.common.test.domain.wallet.MockUserWalletFactory import com.tangem.data.common.account.WalletAccountsFetcher import com.tangem.data.common.network.NetworkFactory import com.tangem.datasource.api.tangemTech.models.UserTokensResponse -import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles +import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse +import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.card.configs.GenericCardConfig import com.tangem.domain.common.wallets.UserWalletsListRepository @@ -38,20 +38,16 @@ import org.junit.jupiter.params.ParameterizedTest internal class DefaultCardCryptoCurrencyFactoryTest { private val userWalletsListRepository: UserWalletsListRepository = mockk() - private val userTokensResponseStore: UserTokensResponseStore = mockk() private val excludedBlockchains = ExcludedBlockchains() - private val accountsFeatureToggles = mockk() private val walletAccountsFetcher = mockk() private val factory = DefaultCardCryptoCurrencyFactory( demoConfig = DemoConfig, excludedBlockchains = excludedBlockchains, userWalletsListRepository = userWalletsListRepository, - userTokensResponseStore = userTokensResponseStore, responseCryptoCurrenciesFactory = ResponseCryptoCurrenciesFactory( networkFactory = NetworkFactory(excludedBlockchains = excludedBlockchains), ), - accountsFeatureToggles = accountsFeatureToggles, walletAccountsFetcher = walletAccountsFetcher, ) @@ -64,7 +60,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { @BeforeEach fun init() { - clearMocks(userWalletsListRepository, userTokensResponseStore, accountsFeatureToggles, walletAccountsFetcher, iconUri) + clearMocks(userWalletsListRepository, walletAccountsFetcher, iconUri) mockkStatic(Uri::class) every { Uri.parse(any()) } returns iconUri @@ -80,12 +76,11 @@ internal class DefaultCardCryptoCurrencyFactoryTest { // Arrange val userWallet = createMultiWallet() val userWalletsFlow = MutableStateFlow(listOf(userWallet)) - val userTokensResponse = model.userTokensResponse + val accountsResponse = model.accountsResponse val network = ethereum.network - every { accountsFeatureToggles.isFeatureEnabled } returns false every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { userTokensResponseStore.getSyncOrNull(userWallet.walletId) } returns userTokensResponse + coEvery { walletAccountsFetcher.getSaved(userWallet.walletId) } returns accountsResponse // Act val actual = factory.create(userWalletId = userWallet.walletId, network = network) @@ -97,25 +92,25 @@ internal class DefaultCardCryptoCurrencyFactoryTest { coVerifyOrder { userWalletsListRepository.userWallets - userTokensResponseStore.getSyncOrNull(userWalletId = userWallet.walletId) + walletAccountsFetcher.getSaved(userWalletId = userWallet.walletId) } } private fun provideTestModels() = listOf( - CreateTestModel.MultiWallet(userTokensResponse = null, expected = emptyList()), - CreateTestModel.MultiWallet(userTokensResponse = createUserTokensResponse(), expected = emptyList()), + CreateTestModel.MultiWallet(accountsResponse = null, expected = emptyList()), + CreateTestModel.MultiWallet(accountsResponse = createAccountsResponse(), expected = emptyList()), CreateTestModel.MultiWallet( - userTokensResponse = createUserTokensResponse(currencies = listOf(ethereum)), + accountsResponse = createAccountsResponse(currencies = listOf(ethereum)), expected = listOf(ethereum), ), CreateTestModel.MultiWallet( - userTokensResponse = createUserTokensResponse(listOf(element = bitcoin)), + accountsResponse = createAccountsResponse(listOf(element = bitcoin)), expected = emptyList(), ), ) - private fun createUserTokensResponse(currencies: List = emptyList()): UserTokensResponse { - return userTokensResponseFactory.createUserTokensResponse( + private fun createAccountsResponse(currencies: List = emptyList()): GetWalletAccountsResponse { + return createWalletAccountsResponse( currencies = currencies, isGroupedByNetwork = false, isSortedByBalance = false, @@ -150,7 +145,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { } coVerify(inverse = true) { - userTokensResponseStore.getSyncOrNull(userWalletId = any()) + walletAccountsFetcher.getSaved(userWalletId = any()) } } @@ -195,7 +190,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { } coVerify(inverse = true) { - userTokensResponseStore.getSyncOrNull(userWalletId = any()) + walletAccountsFetcher.getSaved(userWalletId = any()) } } @@ -218,7 +213,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { val expected: List data class MultiWallet( - val userTokensResponse: UserTokensResponse?, + val accountsResponse: GetWalletAccountsResponse?, override val expected: List, ) : CreateTestModel @@ -245,10 +240,9 @@ internal class DefaultCardCryptoCurrencyFactoryTest { // Arrange val userWallet = model.multiWallet val networks = setOf(ethereum.network, bitcoin.network) - val userTokensResponse = model.userTokensResponse + val accountsResponse = model.accountsResponse - every { accountsFeatureToggles.isFeatureEnabled } returns false - coEvery { userTokensResponseStore.getSyncOrNull(userWallet.walletId) } returns userTokensResponse + coEvery { walletAccountsFetcher.getSaved(userWallet.walletId) } returns accountsResponse // Act val actual = runCatching { @@ -273,19 +267,19 @@ internal class DefaultCardCryptoCurrencyFactoryTest { private fun provideTestModels() = listOf( CreateCurrenciesForMultiWalletModel( multiWallet = createMultiWallet(), - userTokensResponse = null, + accountsResponse = null, expected = Result.success(emptyMap()), ), CreateCurrenciesForMultiWalletModel( multiWallet = createMultiWallet(), - userTokensResponse = createUserTokensResponse(), + accountsResponse = createWalletAccountsResponse(emptyList(), false, false), expected = Result.success( setOf(ethereum.network, bitcoin.network).associateWith { emptyList() }, ), ), CreateCurrenciesForMultiWalletModel( multiWallet = createMultiWallet(), - userTokensResponse = createUserTokensResponse(currencies = listOf(bitcoin, ethereum)), + accountsResponse = createWalletAccountsResponse(currencies = listOf(bitcoin, ethereum), false, false), expected = mapOf( bitcoin.network to listOf(bitcoin), ethereum.network to listOf(ethereum), @@ -293,12 +287,12 @@ internal class DefaultCardCryptoCurrencyFactoryTest { ), CreateCurrenciesForMultiWalletModel( multiWallet = createSingleWallet(), - userTokensResponse = null, + accountsResponse = null, expected = Result.failure(IllegalArgumentException("It isn't multi-currency wallet")), ), CreateCurrenciesForMultiWalletModel( multiWallet = MockUserWalletFactory.createSingleWalletWithToken(), - userTokensResponse = null, + accountsResponse = null, expected = Result.failure(IllegalArgumentException("It isn't multi-currency wallet")), ), ) @@ -306,7 +300,7 @@ internal class DefaultCardCryptoCurrencyFactoryTest { data class CreateCurrenciesForMultiWalletModel( val multiWallet: UserWallet, - val userTokensResponse: UserTokensResponse?, + val accountsResponse: GetWalletAccountsResponse?, val expected: Result>>, ) @@ -546,11 +540,44 @@ internal class DefaultCardCryptoCurrencyFactoryTest { )!! } - private fun createUserTokensResponse(currencies: List = emptyList()): UserTokensResponse { - return userTokensResponseFactory.createUserTokensResponse( - currencies = currencies, - isGroupedByNetwork = false, - isSortedByBalance = false, + private fun createWalletAccountsResponse( + currencies: List, + isGroupedByNetwork: Boolean, + isSortedByBalance: Boolean, + ): GetWalletAccountsResponse { + val tokens = currencies.map { currency -> + userTokensResponseFactory.createResponseToken(currency = currency, accountId = null) + } + + return GetWalletAccountsResponse( + wallet = GetWalletAccountsResponse.Wallet( + version = 0, + group = if (isGroupedByNetwork) { + UserTokensResponse.GroupType.NETWORK + } else { + UserTokensResponse.GroupType.NONE + }, + sort = if (isSortedByBalance) { + UserTokensResponse.SortType.BALANCE + } else { + UserTokensResponse.SortType.MANUAL + }, + totalAccounts = 1, + totalArchivedAccounts = 0, + ), + accounts = listOf( + WalletAccountDTO( + id = "account_0", + name = "Main", + derivationIndex = 0, + icon = "🏠", + iconColor = "#000000", + tokens = tokens, + totalTokens = tokens.size, + totalNetworks = currencies.map { it.network }.distinct().size, + ), + ), + unassignedTokens = emptyList(), ) } diff --git a/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt b/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt index 16bb9deefe..4cc3f5aa9f 100644 --- a/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt +++ b/data/common/src/test/kotlin/com/tangem/data/common/currency/UserTokensSaverTest.kt @@ -6,9 +6,7 @@ import com.tangem.datasource.api.common.response.ApiResponseError import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.api.tangemTech.models.UserTokensResponse import com.tangem.datasource.api.tangemTech.models.WalletType -import com.tangem.datasource.local.appsflyer.AppsFlyerStore import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId @@ -27,11 +25,7 @@ class UserTokensSaverTest { private val userWalletsListRepository: UserWalletsListRepository = mockk(relaxUnitFun = true) private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxed = true) private val enricher: UserTokensResponseAddressesEnricher = mockk() - private val accountsFeatureToggles = mockk { - every { this@mockk.isFeatureEnabled } returns true - } private val walletServerBinder: WalletServerBinder = mockk() - private val appsFlyerStore: AppsFlyerStore = mockk() private val userTokensSaver: UserTokensSaver = UserTokensSaver( tangemTechApi = tangemTechApi, @@ -40,8 +34,6 @@ class UserTokensSaverTest { dispatchers = TestingCoroutineDispatcherProvider(), addressesEnricher = enricher, walletServerBinder = walletServerBinder, - appsFlyerStore = appsFlyerStore, - accountsFeatureToggles = accountsFeatureToggles, pushTokensRetryerPool = mockk(), ) @@ -121,7 +113,6 @@ class UserTokensSaverTest { val userWalletsFlow = MutableStateFlow(listOf(userWallet)) - every { accountsFeatureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets } returns userWalletsFlow coEvery { enricher(userWalletId, response) } returns enrichedResponse coEvery { tangemTechApi.saveTokens(any(), any()) } returns ApiResponse.Error(error) as ApiResponse diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesFetcher.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesFetcher.kt deleted file mode 100644 index 4b563eb468..0000000000 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesFetcher.kt +++ /dev/null @@ -1,129 +0,0 @@ -package com.tangem.data.tokens - -import arrow.core.Either -import com.tangem.data.common.api.safeApiCall -import com.tangem.data.common.currency.CardCryptoCurrencyFactory -import com.tangem.data.common.currency.UserTokensResponseFactory -import com.tangem.data.common.currency.UserTokensSaver -import com.tangem.data.tokens.utils.CustomTokensMerger -import com.tangem.datasource.api.common.response.ApiResponseError -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.api.tangemTech.models.UserTokensResponse -import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.common.wallets.UserWalletsListRepository -import com.tangem.domain.common.wallets.getSyncStrict -import com.tangem.domain.core.utils.catchOn -import com.tangem.domain.demo.models.DemoConfig -import com.tangem.domain.express.ExpressServiceFetcher -import com.tangem.domain.express.models.ExpressAsset -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.isMultiCurrency -import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher -import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher.Params -import com.tangem.utils.coroutines.CoroutineDispatcherProvider -import kotlinx.coroutines.withContext -import timber.log.Timber - -/** - * Default implementation of [MultiWalletCryptoCurrenciesFetcher] - * - * @property tangemTechApi Tangem Tech API - * @property userTokensResponseStore store of [UserTokensResponse] - * @property userTokensSaver user tokens saver - * @property cardCryptoCurrencyFactory factory for creating crypto currencies for specified card - * @property expressServiceFetcher express service loader - * @property dispatchers dispatchers - * -[REDACTED_AUTHOR] - */ -@Suppress("LongParameterList") -internal class DefaultMultiWalletCryptoCurrenciesFetcher( - private val demoConfig: DemoConfig, - private val userWalletsListRepository: UserWalletsListRepository, - private val tangemTechApi: TangemTechApi, - private val customTokensMerger: CustomTokensMerger, - private val userTokensResponseStore: UserTokensResponseStore, - private val userTokensSaver: UserTokensSaver, - private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory, - private val expressServiceFetcher: ExpressServiceFetcher, - private val dispatchers: CoroutineDispatcherProvider, -) : MultiWalletCryptoCurrenciesFetcher { - - private val userTokensResponseFactory = UserTokensResponseFactory() - - override suspend fun invoke(params: Params) = Either.catchOn(dispatchers.default) { - val userWallet = userWalletsListRepository.getSyncStrict(id = params.userWalletId) - - if (!userWallet.isMultiCurrency) error("${this::class.simpleName} supports only multi-currency wallet") - - val response = if (userWallet is UserWallet.Cold && userWallet.isDemoWalletWithoutSavedTokens()) { - createDefaultUserTokensResponse(userWallet = userWallet) - } else { - safeApiCall( - call = { - withContext(dispatchers.io) { - tangemTechApi.getUserTokens(userId = userWallet.walletId.stringValue).bind() - } - }, - onError = { - handleFetchTokensError(error = it, userWallet = userWallet) - }, - ) - } - - val compatibleUserTokensResponse = response - .let { it.copy(tokens = it.tokens.distinct()) } - .let { customTokensMerger.mergeIfPresented(userWalletId = userWallet.walletId, response = it) } - - userTokensSaver.store(userWalletId = userWallet.walletId, response = compatibleUserTokensResponse) - - fetchExpressAssetsByNetworkIds(userWallet = userWallet, userTokens = compatibleUserTokensResponse) - } - - private suspend fun UserWallet.Cold.isDemoWalletWithoutSavedTokens(): Boolean { - val isDemoCard = demoConfig.isDemoCardId(cardId = cardId) - - return if (isDemoCard) { - val response = userTokensResponseStore.getSyncOrNull(userWalletId = walletId) - - response == null - } else { - false - } - } - - private suspend fun handleFetchTokensError(error: ApiResponseError, userWallet: UserWallet): UserTokensResponse { - val userWalletId = userWallet.walletId - - val response = userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) - ?: createDefaultUserTokensResponse(userWallet = userWallet) - - if (error is ApiResponseError.HttpException && error.code == ApiResponseError.HttpException.Code.NOT_FOUND) { - Timber.w(error, "Requested currencies could not be found in the remote store for: $userWalletId") - - userTokensSaver.push(userWalletId, response) - } - - return response - } - - private suspend fun fetchExpressAssetsByNetworkIds(userWallet: UserWallet, userTokens: UserTokensResponse) { - val tokens = userTokens.tokens.mapTo(hashSetOf()) { token -> - ExpressAsset.ID( - networkId = token.networkId, - contractAddress = token.contractAddress, - ) - } - - expressServiceFetcher.fetch(userWallet = userWallet, assetIds = tokens) - } - - private fun createDefaultUserTokensResponse(userWallet: UserWallet): UserTokensResponse { - return userTokensResponseFactory.createUserTokensResponse( - currencies = cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet), - isGroupedByNetwork = false, - isSortedByBalance = false, - accountId = null, - ) - } -} \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/MultiWalletCryptoCurrenciesFetcherModule.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/MultiWalletCryptoCurrenciesFetcherModule.kt index e3e6f70446..68065f148b 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/MultiWalletCryptoCurrenciesFetcherModule.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/MultiWalletCryptoCurrenciesFetcherModule.kt @@ -1,16 +1,8 @@ package com.tangem.data.tokens.di import com.tangem.data.common.account.WalletAccountsFetcher -import com.tangem.data.common.currency.CardCryptoCurrencyFactory -import com.tangem.data.common.currency.UserTokensSaver import com.tangem.data.tokens.AccountListCryptoCurrenciesFetcher -import com.tangem.data.tokens.DefaultMultiWalletCryptoCurrenciesFetcher -import com.tangem.data.tokens.utils.CustomTokensMerger -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.common.wallets.UserWalletsListRepository -import com.tangem.domain.demo.models.DemoConfig import com.tangem.domain.express.ExpressServiceFetcher import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher import com.tangem.utils.coroutines.CoroutineDispatcherProvider @@ -27,39 +19,16 @@ internal class MultiWalletCryptoCurrenciesFetcherModule { @Singleton @Provides fun provideMultiWalletCryptoCurrenciesFetcher( - accountsFeatureToggles: AccountsFeatureToggles, - tangemTechApi: TangemTechApi, userWalletsListRepository: UserWalletsListRepository, - userTokensResponseStore: UserTokensResponseStore, - userTokensSaver: UserTokensSaver, - cardCryptoCurrencyFactory: CardCryptoCurrencyFactory, - expressServiceFetcher: ExpressServiceFetcher, walletAccountsFetcher: WalletAccountsFetcher, + expressServiceFetcher: ExpressServiceFetcher, dispatchers: CoroutineDispatcherProvider, ): MultiWalletCryptoCurrenciesFetcher { - return if (accountsFeatureToggles.isFeatureEnabled) { - AccountListCryptoCurrenciesFetcher( - userWalletsListRepository = userWalletsListRepository, - walletAccountsFetcher = walletAccountsFetcher, - expressServiceFetcher = expressServiceFetcher, - dispatchers = dispatchers, - ) - } else { - DefaultMultiWalletCryptoCurrenciesFetcher( - demoConfig = DemoConfig, - userWalletsListRepository = userWalletsListRepository, - tangemTechApi = tangemTechApi, - customTokensMerger = CustomTokensMerger( - tangemTechApi = tangemTechApi, - userTokensSaver = userTokensSaver, - dispatchers = dispatchers, - ), - userTokensResponseStore = userTokensResponseStore, - userTokensSaver = userTokensSaver, - cardCryptoCurrencyFactory = cardCryptoCurrencyFactory, - expressServiceFetcher = expressServiceFetcher, - dispatchers = dispatchers, - ) - } + return AccountListCryptoCurrenciesFetcher( + userWalletsListRepository = userWalletsListRepository, + walletAccountsFetcher = walletAccountsFetcher, + expressServiceFetcher = expressServiceFetcher, + dispatchers = dispatchers, + ) } } \ No newline at end of file diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt index 652ffeaa92..26626eb998 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/di/TokensDataModule.kt @@ -13,7 +13,6 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.local.preferences.AppPreferencesStore import com.tangem.datasource.local.token.TokenReceiveWarningActionStore import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.express.ExpressServiceFetcher import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesSupplier @@ -48,7 +47,6 @@ internal object TokensDataModule { tokensSaver: UserTokensSaver, responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, - accountsFeatureToggles: AccountsFeatureToggles, ): CurrenciesRepository { return DefaultCurrenciesRepository( tangemTechApi = tangemTechApi, @@ -63,7 +61,6 @@ internal object TokensDataModule { userTokensSaver = tokensSaver, responseCryptoCurrenciesFactory = responseCryptoCurrenciesFactory, multiWalletCryptoCurrenciesSupplier = multiWalletCryptoCurrenciesSupplier, - accountsFeatureToggles = accountsFeatureToggles, ) } diff --git a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt index 3e5eadeda3..16b2415e7e 100644 --- a/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt +++ b/data/tokens/src/main/kotlin/com/tangem/data/tokens/repository/DefaultCurrenciesRepository.kt @@ -3,7 +3,9 @@ package com.tangem.data.tokens.repository import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.TransactionStatus import com.tangem.blockchainsdk.compatibility.getL2CompatibilityTokenComparison -import com.tangem.blockchainsdk.utils.* +import com.tangem.blockchainsdk.utils.ExcludedBlockchains +import com.tangem.blockchainsdk.utils.fromNetworkId +import com.tangem.blockchainsdk.utils.toBlockchain import com.tangem.data.common.api.safeApiCall import com.tangem.data.common.cache.CacheRegistry import com.tangem.data.common.currency.* @@ -13,7 +15,6 @@ import com.tangem.datasource.api.common.response.getOrThrow import com.tangem.datasource.api.tangemTech.TangemTechApi import com.tangem.datasource.api.tangemTech.models.UserTokensResponse import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.card.CardTypesResolver import com.tangem.domain.card.common.util.cardTypesResolver import com.tangem.domain.common.wallets.UserWalletsListRepository @@ -51,7 +52,6 @@ internal class DefaultCurrenciesRepository( private val userTokensSaver: UserTokensSaver, private val userTokensResponseStore: UserTokensResponseStore, private val responseCryptoCurrenciesFactory: ResponseCryptoCurrenciesFactory, - private val accountsFeatureToggles: AccountsFeatureToggles, private val multiWalletCryptoCurrenciesSupplier: MultiWalletCryptoCurrenciesSupplier, excludedBlockchains: ExcludedBlockchains, ) : CurrenciesRepository { @@ -187,19 +187,7 @@ internal class DefaultCurrenciesRepository( networkId: Network.ID, derivationPath: Network.DerivationPath, ): CryptoCurrency.Coin { - return if (accountsFeatureToggles.isFeatureEnabled) { - getNetworkCoinNew(userWalletId, networkId, derivationPath) - } else { - getNetworkCoinLegacy(userWalletId, networkId, derivationPath) - } - } - - private suspend fun getNetworkCoinNew( - userWalletId: UserWalletId, - networkId: Network.ID, - derivationPath: Network.DerivationPath, - ): CryptoCurrency.Coin = withContext(dispatchers.default) { - multiWalletCryptoCurrenciesSupplier.getSyncOrNull( + return multiWalletCryptoCurrenciesSupplier.getSyncOrNull( params = MultiWalletCryptoCurrenciesProducer.Params(userWalletId = userWalletId), ) .orEmpty() @@ -211,44 +199,6 @@ internal class DefaultCurrenciesRepository( ?: error("Unable to find coin for network ID: $networkId") } - private suspend fun getNetworkCoinLegacy( - userWalletId: UserWalletId, - networkId: Network.ID, - derivationPath: Network.DerivationPath, - ): CryptoCurrency.Coin { - return withContext(dispatchers.io) { - val userWallet = userWalletsListRepository.getSyncStrict(userWalletId) - ensureIsCorrectUserWallet(userWallet = userWallet, isMultiCurrencyWalletExpected = true) - - fetchTokensIfCacheExpired(userWallet = userWallet, refresh = false) - - val storedTokens = requireNotNull( - value = getSavedUserTokensResponseSync(key = userWalletId), - lazyMessage = { - "Unable to find tokens response for user wallet with provided ID: $userWalletId" - }, - ) - val blockchain = networkId.toBlockchain() - val blockchainNetworkId = blockchain.toNetworkId() - val coinId = blockchain.toCoinId() - - val storedCoin = storedTokens.tokens - .find { token -> - token.networkId == blockchainNetworkId && - compareIdWithMigrations(token, coinId) && - token.derivationPath == derivationPath.value - } ?: error("Coin in this network $networkId not found") - - val coin = responseCryptoCurrenciesFactory.createCurrency( - responseToken = storedCoin, - userWallet = userWallet, - accountIndex = DerivationIndex.Main, - ) - - coin as? CryptoCurrency.Coin ?: error("Unable to create currency") - } - } - override fun isTokensGrouped(userWalletId: UserWalletId): Flow { return channelFlow { val userWallet = userWalletsListRepository.getSyncStrict(userWalletId) @@ -470,13 +420,6 @@ internal class DefaultCurrenciesRepository( ) } - private fun compareIdWithMigrations(token: UserTokensResponse.Token, coinId: String): Boolean { - return when { - token.id == OLD_POLYGON_NAME -> NEW_POLYGON_NAME == coinId - else -> token.id == coinId - } - } - private suspend fun fetchTokens(userWallet: UserWallet) { val userWalletId = userWallet.walletId diff --git a/data/tokens/src/test/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesFetcherTest.kt b/data/tokens/src/test/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesFetcherTest.kt deleted file mode 100644 index 1b649ebbe0..0000000000 --- a/data/tokens/src/test/kotlin/com/tangem/data/tokens/DefaultMultiWalletCryptoCurrenciesFetcherTest.kt +++ /dev/null @@ -1,549 +0,0 @@ -package com.tangem.data.tokens - -import arrow.core.left -import arrow.core.right -import com.tangem.blockchain.common.Blockchain -import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory -import com.tangem.data.common.currency.CardCryptoCurrencyFactory -import com.tangem.data.common.currency.UserTokensResponseFactory -import com.tangem.data.common.currency.UserTokensSaver -import com.tangem.data.tokens.utils.CustomTokensMerger -import com.tangem.datasource.api.common.response.ApiResponse -import com.tangem.datasource.api.common.response.ApiResponseError -import com.tangem.datasource.api.tangemTech.TangemTechApi -import com.tangem.datasource.api.tangemTech.models.UserTokensResponse -import com.tangem.datasource.local.token.UserTokensResponseStore -import com.tangem.domain.common.wallets.UserWalletsListRepository -import com.tangem.domain.demo.models.DemoConfig -import com.tangem.domain.express.ExpressServiceFetcher -import com.tangem.domain.express.models.ExpressAsset -import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.models.wallet.UserWalletId -import com.tangem.domain.models.wallet.isMultiCurrency -import com.tangem.domain.tokens.MultiWalletCryptoCurrenciesFetcher -import com.tangem.test.core.assertEither -import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider -import io.mockk.* -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.TestInstance - -/** -[REDACTED_AUTHOR] - */ -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -internal class DefaultMultiWalletCryptoCurrenciesFetcherTest { - - private val cryptoCurrencyFactory = MockCryptoCurrencyFactory() - private val userTokensResponseFactory = UserTokensResponseFactory() - - private val userWalletsListRepository: UserWalletsListRepository = mockk(relaxUnitFun = true) - private val tangemTechApi: TangemTechApi = mockk() - private val customTokensMerger: CustomTokensMerger = mockk() - private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxUnitFun = true) - private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true) - private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory = mockk() - private val expressServiceFetcher: ExpressServiceFetcher = mockk(relaxUnitFun = true) - - private val fetcher = DefaultMultiWalletCryptoCurrenciesFetcher( - demoConfig = DemoConfig, - userWalletsListRepository = userWalletsListRepository, - tangemTechApi = tangemTechApi, - customTokensMerger = customTokensMerger, - userTokensResponseStore = userTokensResponseStore, - userTokensSaver = userTokensSaver, - cardCryptoCurrencyFactory = cardCryptoCurrencyFactory, - expressServiceFetcher = expressServiceFetcher, - dispatchers = TestingCoroutineDispatcherProvider(), - ) - - @BeforeEach - fun resetMocks() { - clearMocks( - userWalletsListRepository, - tangemTechApi, - userTokensResponseStore, - userTokensSaver, - cardCryptoCurrencyFactory, - expressServiceFetcher, - ) - } - - @Test - fun `fetch failure if UserWallet ISN'T MULTI-CURRENCY wallet`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns false - } - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - - // Act - val actual = fetcher(params) - - // Assert - val expected = IllegalStateException( - "${DefaultMultiWalletCryptoCurrenciesFetcher::class.simpleName} supports only multi-currency wallet", - ).left() - assertEither(actual, expected) - - verifyOrder { userWalletsListRepository.userWallets } - coVerify(inverse = true) { - userTokensResponseStore.getSyncOrNull(any()) - } - } - - @Test - fun `fetch successfully if CARD IS DEMO and STORED TOKENS ARE EMPTY`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns true - every { cardId } returns "AC01000000041225" - } - - val defaultCoins = listOf( - cryptoCurrencyFactory.createCoin(Blockchain.Bitcoin), - cryptoCurrencyFactory.createCoin(Blockchain.Ethereum), - ) - - val userTokensResponse = UserTokensResponse( - group = UserTokensResponse.GroupType.NONE, - sort = UserTokensResponse.SortType.MANUAL, - tokens = listOf( - userTokensResponseFactory.createResponseToken(defaultCoins.first()), - userTokensResponseFactory.createResponseToken(defaultCoins.last()), - ), - ) - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId) } returns null - every { - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet) - } returns defaultCoins - coEvery { - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse) - } returns userTokensResponse - - coEvery { - expressServiceFetcher.fetch( - userWallet = mockUserWallet, - assetIds = userTokensResponse.toAssetId(), - ) - } returns Unit.right() - - // Act - val actual = fetcher(params) - - // Assert - val expected = Unit.right() - assertEither(actual, expected) - - coVerifyOrder { - userWalletsListRepository.userWallets - userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId) - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet) - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse) - userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse) - expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = userTokensResponse.toAssetId()) - } - } - - @Test - fun `fetch successfully if CARD IS DEMO and STORED TOKENS AREN'T EMPTY`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns true - every { cardId } returns "AC01000000041225" - } - - val apiResponse = ApiResponse.Success( - data = defaultResponse.copy(group = UserTokensResponse.GroupType.TOKEN), - ) - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId) } returns defaultResponse - coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse - coEvery { - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data) - } returns apiResponse.data - - coEvery { - expressServiceFetcher.fetch( - userWallet = mockUserWallet, - assetIds = defaultResponse.toAssetId(), - ) - } returns Unit.right() - - // Act - val actual = fetcher(params) - - // Assert - val expected = Unit.right() - assertEither(actual, expected) - - coVerifyOrder { - userWalletsListRepository.userWallets - userTokensResponseStore.getSyncOrNull(userWalletId = params.userWalletId) - tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data) - userTokensSaver.store(userWalletId = params.userWalletId, response = apiResponse.data) - expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId()) - } - - coVerify(inverse = true) { - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any()) - } - } - - @Test - fun `fetch successfully if CARD ISN'T DEMO`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns true - every { cardId } returns "cardID" - } - - val apiResponse = ApiResponse.Success( - data = defaultResponse.copy(group = UserTokensResponse.GroupType.TOKEN), - ) - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse - coEvery { - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data) - } returns apiResponse.data - - coEvery { - expressServiceFetcher.fetch( - userWallet = mockUserWallet, - assetIds = apiResponse.data.toAssetId(), - ) - } returns Unit.right() - - // Act - val actual = fetcher(params) - - // Assert - val expected = Unit.right() - assertEither(actual, expected) - - coVerifyOrder { - userWalletsListRepository.userWallets - tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = apiResponse.data) - userTokensSaver.store(userWalletId = params.userWalletId, response = apiResponse.data) - expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId()) - } - - coVerify(inverse = true) { - userTokensResponseStore.getSyncOrNull(userWalletId = any()) - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any()) - } - } - - @Test - fun `fetch successfully if API request RETURNS TIMEOUT EXCEPTION and STORED TOKENS ARE EMPTY`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns true - every { cardId } returns "cardID" - } - - @Suppress("UNCHECKED_CAST") - val apiResponse = ApiResponse.Error( - cause = ApiResponseError.TimeoutException(), - ) as ApiResponse - - val defaultCoins = listOf( - cryptoCurrencyFactory.createCoin(Blockchain.Bitcoin), - cryptoCurrencyFactory.createCoin(Blockchain.Ethereum), - ) - - val userTokensResponse = UserTokensResponse( - group = UserTokensResponse.GroupType.NONE, - sort = UserTokensResponse.SortType.MANUAL, - tokens = listOf( - userTokensResponseFactory.createResponseToken(defaultCoins.first()), - userTokensResponseFactory.createResponseToken(defaultCoins.last()), - ), - ) - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse - coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns null - coEvery { - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet) - } returns defaultCoins - coEvery { - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse) - } returns userTokensResponse - - coEvery { - expressServiceFetcher.fetch( - userWallet = mockUserWallet, - assetIds = userTokensResponse.toAssetId(), - ) - } returns Unit.right() - - // Act - val actual = fetcher(params) - - // Assert - val expected = Unit.right() - assertEither(actual, expected) - - coVerifyOrder { - userWalletsListRepository.userWallets - tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) - userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse) - userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse) - expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = userTokensResponse.toAssetId()) - } - - coVerify(inverse = true) { - userTokensSaver.push(userWalletId = any(), response = any()) - } - } - - @Test - fun `fetch successfully if API request RETURNS TIMEOUT EXCEPTION and STORED TOKENS AREN'T EMPTY`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns true - every { cardId } returns "cardID" - } - - @Suppress("UNCHECKED_CAST") - val apiResponse = ApiResponse.Error( - cause = ApiResponseError.TimeoutException(), - ) as ApiResponse - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse - coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns defaultResponse - coEvery { - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse) - } returns defaultResponse - - coEvery { - expressServiceFetcher.fetch( - userWallet = mockUserWallet, - assetIds = defaultResponse.toAssetId(), - ) - } returns Unit.right() - - // Act - val actual = fetcher(params) - - // Assert - val expected = Unit.right() - assertEither(actual, expected) - - coVerifyOrder { - userWalletsListRepository.userWallets - tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) - userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse) - userTokensSaver.store(userWalletId = params.userWalletId, response = defaultResponse) - expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId()) - } - - coVerify(inverse = true) { - userTokensSaver.push(userWalletId = any(), response = any()) - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any()) - } - } - - @Test - fun `fetch successfully if API request RETURNS NOT FOUND EXCEPTION and STORED TOKENS ARE EMPTY`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns true - every { cardId } returns "cardID" - } - - @Suppress("UNCHECKED_CAST") - val apiResponse = ApiResponse.Error( - cause = ApiResponseError.HttpException( - code = ApiResponseError.HttpException.Code.NOT_FOUND, - message = null, - errorBody = null, - ), - ) as ApiResponse - - val defaultCoins = listOf( - cryptoCurrencyFactory.createCoin(Blockchain.Bitcoin), - cryptoCurrencyFactory.createCoin(Blockchain.Ethereum), - ) - - val userTokensResponse = UserTokensResponse( - group = UserTokensResponse.GroupType.NONE, - sort = UserTokensResponse.SortType.MANUAL, - tokens = listOf( - userTokensResponseFactory.createResponseToken(defaultCoins.first()), - userTokensResponseFactory.createResponseToken(defaultCoins.last()), - ), - ) - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse - coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns null - coEvery { - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet) - } returns defaultCoins - coEvery { - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse) - } returns userTokensResponse - - coEvery { - expressServiceFetcher.fetch( - userWallet = mockUserWallet, - assetIds = userTokensResponse.toAssetId(), - ) - } returns Unit.right() - - // Act - val actual = fetcher(params) - - // Assert - val expected = Unit.right() - assertEither(actual, expected) - - coVerifyOrder { - userWalletsListRepository.userWallets - tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) - userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(mockUserWallet) - userTokensSaver.push(userWalletId = params.userWalletId, response = userTokensResponse) - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = userTokensResponse) - userTokensSaver.store(userWalletId = params.userWalletId, response = userTokensResponse) - expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = userTokensResponse.toAssetId()) - } - } - - @Test - fun `fetch successfully if API request RETURNS NOT FOUND EXCEPTION and STORED TOKENS AREN'T EMPTY`() = runTest { - // Arrange - val params = MultiWalletCryptoCurrenciesFetcher.Params(userWalletId = userWalletId) - - val mockUserWallet = mockk { - every { walletId } returns userWalletId - every { isMultiCurrency } returns true - every { cardId } returns "cardID" - } - - @Suppress("UNCHECKED_CAST") - val apiResponse = ApiResponse.Error( - cause = ApiResponseError.HttpException( - code = ApiResponseError.HttpException.Code.NOT_FOUND, - message = null, - errorBody = null, - ), - ) as ApiResponse - - val userWalletsFlow = MutableStateFlow(listOf(mockUserWallet)) - - every { userWalletsListRepository.userWallets } returns userWalletsFlow - coEvery { tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) } returns apiResponse - coEvery { userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) } returns defaultResponse - coEvery { - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse) - } returns defaultResponse - - coEvery { - expressServiceFetcher.fetch( - userWallet = mockUserWallet, - assetIds = defaultResponse.toAssetId(), - ) - } returns Unit.right() - - // Act - val actual = fetcher(params) - - // Assert - val expected = Unit.right() - assertEither(actual, expected) - - coVerifyOrder { - userWalletsListRepository.userWallets - tangemTechApi.getUserTokens(userId = params.userWalletId.stringValue) - userTokensResponseStore.getSyncOrNull(userWalletId = userWalletId) - userTokensSaver.push(userWalletId = params.userWalletId, response = defaultResponse) - customTokensMerger.mergeIfPresented(userWalletId = params.userWalletId, response = defaultResponse) - userTokensSaver.store(userWalletId = params.userWalletId, response = defaultResponse) - expressServiceFetcher.fetch(userWallet = mockUserWallet, assetIds = defaultResponse.toAssetId()) - } - - coVerify(inverse = true) { - cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any()) - } - } - - private companion object { - val userWalletId = UserWalletId("011") - - val defaultResponse = UserTokensResponse( - group = UserTokensResponse.GroupType.NONE, - sort = UserTokensResponse.SortType.MANUAL, - tokens = listOf( - UserTokensResponse.Token( - id = null, - networkId = "bitcoin", - derivationPath = null, - name = "Bitcoin", - symbol = "BTC", - decimals = 8, - contractAddress = null, - addresses = listOf(), - ), - ), - ) - - fun UserTokensResponse.toAssetId(): Set { - return tokens.mapTo(hashSetOf()) { token -> - ExpressAsset.ID( - networkId = token.networkId, - contractAddress = token.contractAddress, - ) - } - } - } -} \ No newline at end of file diff --git a/domain/account/src/main/java/com/tangem/domain/account/featuretoggle/AccountsFeatureToggles.kt b/domain/account/src/main/java/com/tangem/domain/account/featuretoggle/AccountsFeatureToggles.kt deleted file mode 100644 index 289b2a02e6..0000000000 --- a/domain/account/src/main/java/com/tangem/domain/account/featuretoggle/AccountsFeatureToggles.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.tangem.domain.account.featuretoggle - -/** - * Accounts feature toggle - * -[REDACTED_AUTHOR] - */ -interface AccountsFeatureToggles { - - val isFeatureEnabled: Boolean -} \ No newline at end of file diff --git a/domain/account/src/main/java/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCase.kt b/domain/account/src/main/java/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCase.kt index 2a0bfba4d0..94e6e051af 100644 --- a/domain/account/src/main/java/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCase.kt +++ b/domain/account/src/main/java/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCase.kt @@ -2,7 +2,6 @@ package com.tangem.domain.account.usecase import arrow.core.Option import arrow.core.getOrElse -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.account.repository.AccountsCRUDRepository import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.common.wallets.loadAndGet @@ -18,20 +17,16 @@ import kotlinx.coroutines.flow.* * * @property crudRepository repository to perform CRUD operations on accounts. * @property userWalletsListRepository repository to get the list of user wallets. - * @property accountsFeatureToggles feature toggles for accounts. * [REDACTED_AUTHOR] */ class IsAccountsModeEnabledUseCase( private val crudRepository: AccountsCRUDRepository, private val userWalletsListRepository: UserWalletsListRepository, - private val accountsFeatureToggles: AccountsFeatureToggles, ) { @OptIn(ExperimentalCoroutinesApi::class) operator fun invoke(): Flow { - if (!accountsFeatureToggles.isFeatureEnabled) return flowOf(value = false) - return userWalletsListRepository.loadAndGet() .flatMapLatest { userWallets -> val totalAccountsCountList = getTotalAccountsCountList(userWallets) @@ -43,8 +38,6 @@ class IsAccountsModeEnabledUseCase( } suspend fun invokeSync(): Boolean { - if (!accountsFeatureToggles.isFeatureEnabled) return false - return userWalletsListRepository.userWallets.value.orEmpty() .map { userWallet -> // If the wallet does not support multiple currencies, we consider its account count as 0 diff --git a/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCaseTest.kt b/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCaseTest.kt index 750b29926b..894d4ec39d 100644 --- a/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCaseTest.kt +++ b/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/IsAccountsModeEnabledUseCaseTest.kt @@ -3,7 +3,6 @@ package com.tangem.domain.account.usecase import arrow.core.none import arrow.core.some import com.google.common.truth.Truth -import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles import com.tangem.domain.account.repository.AccountsCRUDRepository import com.tangem.domain.common.wallets.UserWalletsListRepository import com.tangem.domain.models.wallet.UserWallet @@ -12,7 +11,6 @@ import com.tangem.domain.models.wallet.isMultiCurrency import io.mockk.* import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.jupiter.api.AfterEach @@ -26,47 +24,26 @@ class IsAccountsModeEnabledUseCaseTest { private val accountsCRUDRepository: AccountsCRUDRepository = mockk() private val userWalletsListRepository: UserWalletsListRepository = mockk(relaxUnitFun = true) - private val featureToggles: AccountsFeatureToggles = mockk() private val useCase = IsAccountsModeEnabledUseCase( crudRepository = accountsCRUDRepository, userWalletsListRepository = userWalletsListRepository, - accountsFeatureToggles = featureToggles, ) @AfterEach fun tearDown() { - clearMocks(userWalletsListRepository, accountsCRUDRepository, featureToggles) + clearMocks(userWalletsListRepository, accountsCRUDRepository) } @Nested @TestInstance(TestInstance.Lifecycle.PER_CLASS) inner class Invoke { - @Test - fun `returns false when feature is disabled`() = runTest { - // Arrange - every { featureToggles.isFeatureEnabled } returns false - - // Act - val actual = useCase.invoke().firstOrNull() - - // Assert - Truth.assertThat(actual).isFalse() - - verify(exactly = 1) { featureToggles.isFeatureEnabled } - coVerify(inverse = true) { - userWalletsListRepository.load() - userWalletsListRepository.userWallets - } - } - @Test fun `returns false when loadAndGet emits one wallet with isMultiCurrency false`() = runTest { // Arrange val wallet = createUserWallet(isMultiCurrency = false) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(wallet)) // Act @@ -76,7 +53,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isFalse() coVerifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.load() userWalletsListRepository.userWallets } @@ -89,7 +65,6 @@ class IsAccountsModeEnabledUseCaseTest { // Arrange val wallet = createUserWallet(isMultiCurrency = true) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(wallet)) every { accountsCRUDRepository.getTotalActiveAccountsCount(wallet.walletId) } returns flowOf(2.some()) @@ -100,7 +75,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isTrue() coVerifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.load() userWalletsListRepository.userWallets accountsCRUDRepository.getTotalActiveAccountsCount(wallet.walletId) @@ -112,7 +86,6 @@ class IsAccountsModeEnabledUseCaseTest { // Arrange val wallet = createUserWallet(isMultiCurrency = true) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(wallet)) every { accountsCRUDRepository.getTotalActiveAccountsCount(wallet.walletId) } returns flowOf(none()) @@ -123,7 +96,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isFalse() coVerifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.load() userWalletsListRepository.userWallets accountsCRUDRepository.getTotalActiveAccountsCount(wallet.walletId) @@ -136,7 +108,6 @@ class IsAccountsModeEnabledUseCaseTest { val wallet1 = createUserWallet(isMultiCurrency = false) val wallet2 = createUserWallet(isMultiCurrency = true) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets } returns MutableStateFlow(listOf(wallet1, wallet2)) every { accountsCRUDRepository.getTotalActiveAccountsCount(wallet2.walletId) } returns flowOf(2.some()) @@ -147,7 +118,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isTrue() coVerifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.load() userWalletsListRepository.userWallets accountsCRUDRepository.getTotalActiveAccountsCount(wallet2.walletId) @@ -161,25 +131,9 @@ class IsAccountsModeEnabledUseCaseTest { @TestInstance(TestInstance.Lifecycle.PER_CLASS) inner class InvokeSync { - @Test - fun `returns false when feature is disabled`() = runTest { - // Arrange - every { featureToggles.isFeatureEnabled } returns false - - // Act - val actual = useCase.invokeSync() - - // Assert - Truth.assertThat(actual).isFalse() - - verify(exactly = 1) { featureToggles.isFeatureEnabled } - verify(inverse = true) { userWalletsListRepository.userWallets.value } - } - @Test fun `returns false when getUserWalletsSync returns empty list`() = runTest { // Arrange - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets.value } returns emptyList() // Act @@ -189,7 +143,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isFalse() verifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.userWallets.value } @@ -201,7 +154,6 @@ class IsAccountsModeEnabledUseCaseTest { // Arrange val wallet = createUserWallet(isMultiCurrency = false) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets.value } returns listOf(wallet) // Act @@ -211,7 +163,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isFalse() verifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.userWallets.value } @@ -223,7 +174,6 @@ class IsAccountsModeEnabledUseCaseTest { // Arrange val wallet = createUserWallet(isMultiCurrency = true) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets.value } returns listOf(wallet) coEvery { accountsCRUDRepository.getTotalActiveAccountsCountSync(wallet.walletId) } returns 2.some() @@ -234,7 +184,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isTrue() coVerifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.userWallets.value accountsCRUDRepository.getTotalActiveAccountsCountSync(wallet.walletId) } @@ -245,7 +194,6 @@ class IsAccountsModeEnabledUseCaseTest { // Arrange val wallet = createUserWallet(isMultiCurrency = true) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets.value } returns listOf(wallet) coEvery { accountsCRUDRepository.getTotalActiveAccountsCountSync(wallet.walletId) } returns none() @@ -256,7 +204,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isFalse() coVerifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.userWallets.value accountsCRUDRepository.getTotalActiveAccountsCountSync(wallet.walletId) } @@ -268,7 +215,6 @@ class IsAccountsModeEnabledUseCaseTest { val wallet1 = createUserWallet(isMultiCurrency = false) val wallet2 = createUserWallet(isMultiCurrency = true) - every { featureToggles.isFeatureEnabled } returns true every { userWalletsListRepository.userWallets.value } returns listOf(wallet1, wallet2) coEvery { accountsCRUDRepository.getTotalActiveAccountsCountSync(wallet2.walletId) } returns 2.some() @@ -279,7 +225,6 @@ class IsAccountsModeEnabledUseCaseTest { Truth.assertThat(actual).isTrue() coVerifyOrder { - featureToggles.isFeatureEnabled userWalletsListRepository.userWallets.value accountsCRUDRepository.getTotalActiveAccountsCountSync(wallet2.walletId) } diff --git a/domain/models/src/main/kotlin/com/tangem/domain/models/PortfolioId.kt b/domain/models/src/main/kotlin/com/tangem/domain/models/PortfolioId.kt index 07b9e3d022..a140670520 100644 --- a/domain/models/src/main/kotlin/com/tangem/domain/models/PortfolioId.kt +++ b/domain/models/src/main/kotlin/com/tangem/domain/models/PortfolioId.kt @@ -7,11 +7,11 @@ import kotlinx.serialization.Serializable /** * Temporary wrapper over ID to support a gradual migration between two modes: * - * - [Wallet] — legacy flow, wallet design; used when the [AccountsFeatureToggles] is disabled. - * - [Account] — new flow, wallet/account design; used when the [AccountsFeatureToggles] is enabled. + * - [Wallet] — legacy flow, wallet design. + * - [Account] — new flow, wallet/account design. * - * ⚠️ When an [Account] you must verify the current app mode with [IsAccountsModeEnabledUseCase] - * and then use wallet/account design + * ⚠️ When using an [Account], you must verify the current app mode with [IsAccountsModeEnabledUseCase], + * then use the wallet/account design. * * Intended to be removed after the full migration to the new mode. */