Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-01 17:55:36 +03:00
parent 7e375ac36b
commit 1906481ac6
11 changed files with 28 additions and 2633 deletions

View file

@ -2,6 +2,7 @@ package com.tangem.data.account.fetcher
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.store.AccountsResponseStore
import com.tangem.data.account.store.AccountsResponseStoreFactory
import com.tangem.data.common.cache.etag.ETagsStore
@ -13,7 +14,6 @@ import com.tangem.datasource.api.tangemTech.TangemTechApi
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.SaveWalletAccountsResponse
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.*
@ -24,6 +24,7 @@ import org.junit.jupiter.api.*
/**
[REDACTED_AUTHOR]
*/
@Suppress("Unchecked_Cast", "UnusedFlow")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class DefaultWalletAccountsFetcherTest {
@ -78,10 +79,13 @@ class DefaultWalletAccountsFetcherTest {
val savedAccountsResponse = null
val unassignedToken = createToken(accountId = null)
val accounts = listOf(createWalletAccountDTO(userWalletId = userWalletId, tokens = null))
val accountsResponse = createGetWalletAccountsResponse(
userWalletId = userWalletId,
unassignedTokens = listOf(unassignedToken),
)
.copy(accounts = accounts)
val newETag = "newEtag"
val apiResponse = ApiResponse.Success(
data = accountsResponse,
@ -124,12 +128,6 @@ class DefaultWalletAccountsFetcherTest {
eTagsStore.store(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts, value = newETag)
accountsResponseStoreFactory.create(userWalletId = userWalletId)
accountsResponseStore.updateData(any())
eTagsStore.getSyncOrNull(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts)
tangemTechApi.saveWalletAccounts(
walletId = userWalletId.stringValue,
eTag = eTag,
body = SaveWalletAccountsResponse(updatedAccountsResponse.accounts),
)
accountsResponseStoreFactory.create(userWalletId = userWalletId)
accountsResponseStore.updateData(any())
}
@ -199,7 +197,7 @@ class DefaultWalletAccountsFetcherTest {
fun `fetch should call error handler when getWalletAccounts returns error`() = runTest {
// Arrange
val savedAccountsResponse = null
val apiError = ApiResponse.Error(ApiResponseError.NetworkException)
val apiError = ApiResponse.Error(ApiResponseError.NetworkException())
accountsResponseStoreFlow.value = savedAccountsResponse
@ -232,87 +230,6 @@ class DefaultWalletAccountsFetcherTest {
userTokensSaver.push(userWalletId = any(), response = any())
}
}
@Test
fun `push should throw error when saveWalletAccounts returns PRECONDITION_FAILED`() = runTest {
// Arrange
val savedAccountsResponse = null
val unassignedToken = createToken(accountId = null)
val accountsResponse = createGetWalletAccountsResponse(
userWalletId = userWalletId,
unassignedTokens = listOf(unassignedToken),
)
val newETag = "newEtag"
val apiResponse = ApiResponse.Success(
data = accountsResponse,
headers = mapOf(ETAG_HEADER to listOf(newETag)),
)
val apiError = ApiResponseError.HttpException(
code = ApiResponseError.HttpException.Code.PRECONDITION_FAILED,
message = null,
errorBody = null,
)
val saveApiResponse = ApiResponse.Error(apiError)
accountsResponseStoreFlow.value = savedAccountsResponse
val accountId = "957B88B12730E646E0F33D3618B77DFA579E8231E3C59C7104BE7165611C8027"
val updatedAccountsResponse = accountsResponse.copy(
accounts = accountsResponse.accounts.map {
it.copy(tokens = listOf(unassignedToken.copy(accountId = accountId)))
},
unassignedTokens = emptyList(),
)
coEvery {
tangemTechApi.getWalletAccounts(walletId = userWalletId.stringValue, eTag = eTag)
} returns apiResponse
coEvery { accountsResponseStore.updateData(any()) } returns accountsResponse
coEvery {
tangemTechApi.saveWalletAccounts(
walletId = userWalletId.stringValue,
eTag = eTag,
body = SaveWalletAccountsResponse(updatedAccountsResponse.accounts),
)
} returns saveApiResponse as ApiResponse<Unit>
// Act
val actual = runCatching { fetcher.fetch(userWalletId) }.exceptionOrNull()!!
// Assert
Truth.assertThat(actual).isEqualTo(apiError)
coVerifyOrder {
accountsResponseStoreFactory.create(userWalletId = userWalletId)
accountsResponseStore.data
eTagsStore.getSyncOrNull(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts)
tangemTechApi.getWalletAccounts(walletId = userWalletId.stringValue, eTag = eTag)
eTagsStore.store(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts, value = newETag)
accountsResponseStoreFactory.create(userWalletId = userWalletId)
accountsResponseStore.updateData(any())
eTagsStore.getSyncOrNull(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts)
tangemTechApi.saveWalletAccounts(
walletId = userWalletId.stringValue,
eTag = eTag,
body = SaveWalletAccountsResponse(updatedAccountsResponse.accounts),
)
}
coVerify(inverse = true) {
fetchWalletAccountsErrorHandler.handle(
error = any(),
userWalletId = any(),
savedAccountsResponse = any(),
pushWalletAccounts = any(),
storeWalletAccounts = any(),
)
}
}
}
@Nested
@ -343,9 +260,7 @@ class DefaultWalletAccountsFetcherTest {
@Test
fun `push should call saveWalletAccounts with correct params`() = runTest {
// Arrange
val accounts = listOf(
mockk<WalletAccountDTO>(),
)
val accounts = listOf(createWalletAccountDTO(userWalletId = userWalletId, tokens = null))
val response = SaveWalletAccountsResponse(accounts)
coEvery {
@ -373,7 +288,7 @@ class DefaultWalletAccountsFetcherTest {
fun `push should throw error when saveWalletAccounts returns PRECONDITION_FAILED`() = runTest {
// Arrange
val accounts = listOf(
mockk<WalletAccountDTO>(),
createWalletAccountDTO(userWalletId = userWalletId, tokens = null),
)
val response = SaveWalletAccountsResponse(accounts)
val apiError = ApiResponseError.HttpException(
@ -405,10 +320,8 @@ class DefaultWalletAccountsFetcherTest {
@Test
fun `pushAndStore should call push and store with correct params`() = runTest {
// Arrange
listOf(
mockk<WalletAccountDTO>(),
)
val response = createGetWalletAccountsResponse(userWalletId)
val accounts = listOf(createWalletAccountDTO(userWalletId = userWalletId, tokens = null))
val response = createGetWalletAccountsResponse(userWalletId).copy(accounts = accounts)
coEvery {
tangemTechApi.saveWalletAccounts(

View file

@ -158,7 +158,7 @@ class FetchWalletAccountsErrorHandlerTest {
@Test
fun `uses default accounts when savedAccountsResponse is null`() = runTest {
// Arrange
val error = ApiResponseError.TimeoutException
val error = ApiResponseError.TimeoutException()
val accounts = AccountList.empty(userWallet).accounts
.filterIsInstance<Account.CryptoPortfolio>()