Updated on 2026-08-14
This commit is contained in:
parent
7bbab0a40b
commit
46dd1333ff
5 changed files with 306 additions and 2 deletions
|
|
@ -1,11 +1,13 @@
|
|||
package com.tangem.data.account.fetcher
|
||||
|
||||
import arrow.core.right
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.data.account.converter.createGetWalletAccountsResponse
|
||||
import com.tangem.data.account.converter.createWalletAccountDTO
|
||||
import com.tangem.data.account.fetcher.DefaultWalletAccountsFetcher.FetchResult
|
||||
import com.tangem.data.account.store.AccountsResponseStore
|
||||
import com.tangem.data.account.store.AccountsResponseStoreFactory
|
||||
import com.tangem.data.account.tokens.DefaultMainAccountTokensMigration
|
||||
import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory
|
||||
import com.tangem.data.common.cache.etag.ETagsStore
|
||||
import com.tangem.data.common.currency.UserTokensSaver
|
||||
|
|
@ -35,6 +37,7 @@ class DefaultWalletAccountsFetcherTest {
|
|||
private val accountsResponseStoreFactory: AccountsResponseStoreFactory = mockk()
|
||||
private val accountsResponseStore: AccountsResponseStore = mockk()
|
||||
private val accountsResponseStoreFlow = MutableStateFlow<GetWalletAccountsResponse?>(value = null)
|
||||
private val tokensMigration: DefaultMainAccountTokensMigration = mockk(relaxed = true)
|
||||
|
||||
private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true)
|
||||
private val fetchWalletAccountsErrorHandler: FetchWalletAccountsErrorHandler = mockk(relaxUnitFun = true)
|
||||
|
|
@ -49,16 +52,19 @@ class DefaultWalletAccountsFetcherTest {
|
|||
defaultWalletAccountsResponseFactory = defaultWalletAccountsResponseFactory,
|
||||
eTagsStore = eTagsStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
mainAccountTokensMigration = tokensMigration,
|
||||
)
|
||||
|
||||
private val userWalletId = UserWalletId("011")
|
||||
private val eTag = "etag"
|
||||
private val migratedAccountsResponse = createGetWalletAccountsResponse(userWalletId)
|
||||
|
||||
@BeforeAll
|
||||
fun setUp() {
|
||||
every { accountsResponseStoreFactory.create(userWalletId) } returns accountsResponseStore
|
||||
every { accountsResponseStore.data } returns accountsResponseStoreFlow
|
||||
|
||||
coEvery { tokensMigration.migrate(userWalletId) } returns migratedAccountsResponse.right()
|
||||
coEvery { eTagsStore.getSyncOrNull(userWalletId, ETagsStore.Key.WalletAccounts) } returns eTag
|
||||
}
|
||||
|
||||
|
|
@ -134,6 +140,7 @@ class DefaultWalletAccountsFetcherTest {
|
|||
accountsResponseStore.updateData(any())
|
||||
accountsResponseStoreFactory.create(userWalletId = userWalletId)
|
||||
accountsResponseStore.updateData(any())
|
||||
tokensMigration.migrate(userWalletId)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -181,6 +188,7 @@ class DefaultWalletAccountsFetcherTest {
|
|||
eTagsStore.store(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts, value = newETag)
|
||||
accountsResponseStoreFactory.create(userWalletId = userWalletId)
|
||||
accountsResponseStore.updateData(any())
|
||||
tokensMigration.migrate(userWalletId)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
@ -236,6 +244,7 @@ class DefaultWalletAccountsFetcherTest {
|
|||
pushWalletAccounts = any(),
|
||||
storeWalletAccounts = any(),
|
||||
)
|
||||
tokensMigration.migrate(userWalletId)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.data.account.token
|
||||
|
||||
import arrow.core.right
|
||||
import com.tangem.data.account.converter.createGetWalletAccountsResponse
|
||||
import com.tangem.data.account.converter.createWalletAccountDTO
|
||||
import com.tangem.data.account.store.AccountsResponseStore
|
||||
|
|
@ -13,6 +14,7 @@ import com.tangem.datasource.local.accounts.AccountTokenMigrationStore
|
|||
import com.tangem.domain.models.account.AccountId
|
||||
import com.tangem.domain.models.account.DerivationIndex
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.test.core.assertEither
|
||||
import com.tangem.test.core.assertEitherLeft
|
||||
import com.tangem.test.core.assertEitherRight
|
||||
import io.mockk.*
|
||||
|
|
@ -214,6 +216,212 @@ class DefaultMainAccountTokensMigrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `migrate updates tokens for all accounts`() = runTest {
|
||||
// Arrange
|
||||
val unassignedToken1 = createBitcoin(accountIndex = 1)
|
||||
val unassignedToken2 = createBitcoin(accountIndex = 2)
|
||||
|
||||
val derivationIndex1 = DerivationIndex(1).getOrNull()!!
|
||||
val derivationIndex2 = DerivationIndex(2).getOrNull()!!
|
||||
|
||||
val mainAccount = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, DerivationIndex.Main).value,
|
||||
derivationIndex = DerivationIndex.Main.value,
|
||||
tokens = listOf(
|
||||
createBitcoin(accountIndex = 0),
|
||||
unassignedToken1,
|
||||
unassignedToken2,
|
||||
),
|
||||
)
|
||||
|
||||
val account1 = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, derivationIndex1).value,
|
||||
derivationIndex = derivationIndex1.value,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
val account2 = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, derivationIndex2).value,
|
||||
derivationIndex = derivationIndex2.value,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
val response = GetWalletAccountsResponse(
|
||||
wallet = GetWalletAccountsResponse.Wallet(
|
||||
group = UserTokensResponse.GroupType.NONE,
|
||||
sort = UserTokensResponse.SortType.MANUAL,
|
||||
totalAccounts = 3,
|
||||
totalArchivedAccounts = 0,
|
||||
),
|
||||
accounts = listOf(mainAccount, account1, account2),
|
||||
unassignedTokens = emptyList(),
|
||||
)
|
||||
|
||||
accountsResponseStoreFlow.value = response
|
||||
|
||||
coEvery { accountsResponseStore.updateData(any()) } returns mockk()
|
||||
|
||||
// Act
|
||||
val actual = migration.migrate(userWalletId)
|
||||
|
||||
val migratedResponse = response.copy(
|
||||
accounts = listOf(
|
||||
mainAccount.copy(tokens = mainAccount.tokens!! - unassignedToken1 - unassignedToken2),
|
||||
account1.copy(tokens = listOf(unassignedToken1)),
|
||||
account2.copy(tokens = listOf(unassignedToken2)),
|
||||
),
|
||||
)
|
||||
|
||||
// Assert
|
||||
assertEither(actual, migratedResponse.right())
|
||||
|
||||
coVerifySequence {
|
||||
accountsResponseStoreFactory.create(userWalletId)
|
||||
accountsResponseStore.data
|
||||
accountsResponseStore.updateData(any())
|
||||
userTokensSaver.pushWithRetryer(
|
||||
userWalletId = userWalletId,
|
||||
response = migratedResponse.toUserTokensResponse(),
|
||||
onFailSend = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `migrate updates tokens only for one account`() = runTest {
|
||||
// Arrange
|
||||
val unassignedToken1 = createBitcoin(accountIndex = 1)
|
||||
|
||||
val derivationIndex1 = DerivationIndex(1).getOrNull()!!
|
||||
val derivationIndex2 = DerivationIndex(2).getOrNull()!!
|
||||
|
||||
val mainAccount = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, DerivationIndex.Main).value,
|
||||
derivationIndex = DerivationIndex.Main.value,
|
||||
tokens = listOf(
|
||||
createBitcoin(accountIndex = 0),
|
||||
unassignedToken1,
|
||||
),
|
||||
)
|
||||
|
||||
val account1 = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, derivationIndex1).value,
|
||||
derivationIndex = derivationIndex1.value,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
val account2 = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, derivationIndex2).value,
|
||||
derivationIndex = derivationIndex2.value,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
val response = GetWalletAccountsResponse(
|
||||
wallet = GetWalletAccountsResponse.Wallet(
|
||||
group = UserTokensResponse.GroupType.NONE,
|
||||
sort = UserTokensResponse.SortType.MANUAL,
|
||||
totalAccounts = 3,
|
||||
totalArchivedAccounts = 0,
|
||||
),
|
||||
accounts = listOf(mainAccount, account1, account2),
|
||||
unassignedTokens = emptyList(),
|
||||
)
|
||||
|
||||
accountsResponseStoreFlow.value = response
|
||||
|
||||
coEvery { accountsResponseStore.updateData(any()) } returns mockk()
|
||||
|
||||
// Act
|
||||
val actual = migration.migrate(userWalletId)
|
||||
|
||||
val migratedResponse = response.copy(
|
||||
accounts = listOf(
|
||||
mainAccount.copy(tokens = mainAccount.tokens!! - unassignedToken1),
|
||||
account1.copy(tokens = listOf(unassignedToken1)),
|
||||
account2,
|
||||
),
|
||||
)
|
||||
|
||||
// Assert
|
||||
assertEither(actual, migratedResponse.right())
|
||||
|
||||
coVerifySequence {
|
||||
accountsResponseStoreFactory.create(userWalletId)
|
||||
accountsResponseStore.data
|
||||
accountsResponseStore.updateData(any())
|
||||
userTokensSaver.pushWithRetryer(
|
||||
userWalletId = userWalletId,
|
||||
response = migratedResponse.toUserTokensResponse(),
|
||||
onFailSend = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `migrate all skips when no unassigned tokens`() = runTest {
|
||||
// Arrange
|
||||
val derivationIndex1 = DerivationIndex(1).getOrNull()!!
|
||||
val derivationIndex2 = DerivationIndex(2).getOrNull()!!
|
||||
|
||||
val mainAccount = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, DerivationIndex.Main).value,
|
||||
derivationIndex = DerivationIndex.Main.value,
|
||||
tokens = listOf(
|
||||
createBitcoin(accountIndex = 0),
|
||||
),
|
||||
)
|
||||
|
||||
val account1 = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, derivationIndex1).value,
|
||||
derivationIndex = derivationIndex1.value,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
val account2 = createWalletAccountDTO(
|
||||
userWalletId = userWalletId,
|
||||
accountId = AccountId.forCryptoPortfolio(userWalletId, derivationIndex2).value,
|
||||
derivationIndex = derivationIndex2.value,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
val response = GetWalletAccountsResponse(
|
||||
wallet = GetWalletAccountsResponse.Wallet(
|
||||
group = UserTokensResponse.GroupType.NONE,
|
||||
sort = UserTokensResponse.SortType.MANUAL,
|
||||
totalAccounts = 3,
|
||||
totalArchivedAccounts = 0,
|
||||
),
|
||||
accounts = listOf(mainAccount, account1, account2),
|
||||
unassignedTokens = emptyList(),
|
||||
)
|
||||
|
||||
accountsResponseStoreFlow.value = response
|
||||
|
||||
// Act
|
||||
val actual = migration.migrate(userWalletId)
|
||||
|
||||
// Assert
|
||||
assertEither(actual, response.right())
|
||||
|
||||
coVerifySequence {
|
||||
accountsResponseStoreFactory.create(userWalletId)
|
||||
accountsResponseStore.data
|
||||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
userTokensSaver.pushWithRetryer(userWalletId = any(), response = any(), onFailSend = any())
|
||||
}
|
||||
}
|
||||
|
||||
private fun createBitcoin(accountIndex: Int): UserTokensResponse.Token {
|
||||
return UserTokensResponse.Token(
|
||||
id = "ne",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue