Updated on 2026-08-14

This commit is contained in:
Tangem 2025-12-04 10:15:05 +04:00
parent ebb562b2a0
commit ae759af1c7
14 changed files with 422 additions and 140 deletions

View file

@ -7,9 +7,11 @@ import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.networks.utils.NetworksCleaner
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import com.tangem.utils.coroutines.runSuspendCatching
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.withContext
import timber.log.Timber
/**
* Default implementation of [NetworksCleaner].
@ -27,33 +29,51 @@ internal class DefaultNetworksCleaner(
) : NetworksCleaner {
override suspend fun invoke(userWalletId: UserWalletId, currencies: List<CryptoCurrency>) {
if (currencies.isEmpty()) {
Timber.d("No currencies to clear for wallet: $userWalletId")
return
}
withContext(dispatchers.default) {
val (networks, tokens) = currencies.partitionByType()
coroutineScope {
launch { cleanStore(userWalletId = userWalletId, networks = networks) }
launch { cleanWalletManager(userWalletId = userWalletId, networks = networks, tokens = tokens) }
}
awaitAll(
async { clearStatusesStore(userWalletId = userWalletId, networks = networks) },
async { clearBlockchainSDK(userWalletId = userWalletId, networks = networks, tokens = tokens) },
)
}
}
private suspend fun cleanStore(userWalletId: UserWalletId, networks: Set<Network>) {
private suspend fun clearStatusesStore(userWalletId: UserWalletId, networks: Set<Network>) {
if (networks.isNotEmpty()) {
networksStatusesStore.clear(userWalletId = userWalletId, networks = networks)
runSuspendCatching {
networksStatusesStore.clear(userWalletId = userWalletId, networks = networks)
}
.onFailure { Timber.e(it, "Failed to clear network statuses for wallet: $userWalletId") }
}
}
private suspend fun cleanWalletManager(
private suspend fun clearBlockchainSDK(
userWalletId: UserWalletId,
networks: Set<Network>,
tokens: Set<CryptoCurrency.Token>,
) {
if (networks.isNotEmpty()) {
walletManagersFacade.remove(userWalletId = userWalletId, networks = networks)
runSuspendCatching {
walletManagersFacade.remove(userWalletId = userWalletId, networks = networks)
}
.onFailure {
Timber.e(it, "Failed to remove networks from Blockchain SDK for wallet: $userWalletId")
}
}
if (tokens.isNotEmpty()) {
walletManagersFacade.removeTokens(userWalletId = userWalletId, tokens = tokens)
runSuspendCatching {
walletManagersFacade.removeTokens(userWalletId = userWalletId, tokens = tokens)
}
.onFailure {
Timber.e(it, "Failed to remove tokens from Blockchain SDK for wallet: $userWalletId")
}
}
}

View file

@ -7,6 +7,7 @@ import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.clearMocks
import io.mockk.coEvery
import io.mockk.coVerifyOrder
import io.mockk.mockk
import kotlinx.coroutines.test.runTest
@ -45,7 +46,7 @@ class DefaultNetworksCleanerTest {
// Assert
coVerifyOrder {
networksStatusesStore.clear(userWalletId, setOf(network))
networksStatusesStore.clear(userWalletId = userWalletId, networks = setOf(network))
walletManagersFacade.remove(userWalletId = userWalletId, networks = setOf(network))
walletManagersFacade.removeTokens(userWalletId = userWalletId, tokens = setOf(token))
}
@ -66,12 +67,15 @@ class DefaultNetworksCleanerTest {
@Test
fun `should clear only networks when there are no tokens`() = runTest {
// Arrange
val currencies = listOf(coin)
// Act
cleaner(userWalletId = userWalletId, currencies = currencies)
// Assert
coVerifyOrder {
networksStatusesStore.clear(userWalletId, setOf(network))
networksStatusesStore.clear(userWalletId = userWalletId, networks = setOf(network))
walletManagersFacade.remove(userWalletId = userWalletId, networks = setOf(network))
}
@ -98,4 +102,27 @@ class DefaultNetworksCleanerTest {
walletManagersFacade.remove(userWalletId = any(), networks = any())
}
}
@Test
fun `should handle exception during cleaning`() = runTest {
// Arrange
val currencies = listOf(coin, token)
val exception = Exception("Test exception")
coEvery { networksStatusesStore.clear(userWalletId, setOf(network)) } throws exception
coEvery { walletManagersFacade.remove(userWalletId = userWalletId, networks = setOf(network)) } throws exception
coEvery {
walletManagersFacade.removeTokens(userWalletId = userWalletId, tokens = setOf(token))
} throws exception
// Act
cleaner(userWalletId = userWalletId, currencies = currencies)
// Assert
coVerifyOrder {
networksStatusesStore.clear(userWalletId = userWalletId, networks = setOf(network))
walletManagersFacade.remove(userWalletId = userWalletId, networks = setOf(network))
walletManagersFacade.removeTokens(userWalletId = userWalletId, tokens = setOf(token))
}
}
}