Updated on 2026-08-14
This commit is contained in:
parent
373880691e
commit
cafd4d074b
7 changed files with 378 additions and 126 deletions
|
|
@ -5,6 +5,7 @@ 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.account.utils.DefaultWalletAccountsResponseFactory
|
||||
import com.tangem.data.common.cache.etag.ETagsStore
|
||||
import com.tangem.data.common.currency.UserTokensSaver
|
||||
import com.tangem.datasource.api.common.response.ApiResponse
|
||||
|
|
@ -36,6 +37,7 @@ class DefaultWalletAccountsFetcherTest {
|
|||
|
||||
private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true)
|
||||
private val fetchWalletAccountsErrorHandler: FetchWalletAccountsErrorHandler = mockk(relaxUnitFun = true)
|
||||
private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory = mockk()
|
||||
private val eTagsStore: ETagsStore = mockk(relaxUnitFun = true)
|
||||
|
||||
private val fetcher: DefaultWalletAccountsFetcher = DefaultWalletAccountsFetcher(
|
||||
|
|
@ -43,6 +45,7 @@ class DefaultWalletAccountsFetcherTest {
|
|||
accountsResponseStoreFactory = accountsResponseStoreFactory,
|
||||
userTokensSaver = userTokensSaver,
|
||||
fetchWalletAccountsErrorHandler = fetchWalletAccountsErrorHandler,
|
||||
defaultWalletAccountsResponseFactory = defaultWalletAccountsResponseFactory,
|
||||
eTagsStore = eTagsStore,
|
||||
dispatchers = TestingCoroutineDispatcherProvider(),
|
||||
)
|
||||
|
|
@ -205,6 +208,16 @@ class DefaultWalletAccountsFetcherTest {
|
|||
tangemTechApi.getWalletAccounts(walletId = userWalletId.stringValue, eTag = eTag)
|
||||
} returns apiError as ApiResponse<GetWalletAccountsResponse>
|
||||
|
||||
coEvery {
|
||||
fetchWalletAccountsErrorHandler.handle(
|
||||
error = apiError.cause,
|
||||
userWalletId = userWalletId,
|
||||
savedAccountsResponse = null,
|
||||
pushWalletAccounts = any(),
|
||||
storeWalletAccounts = any(),
|
||||
)
|
||||
} returns savedAccountsResponse
|
||||
|
||||
// Act
|
||||
fetcher.fetch(userWalletId)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
package com.tangem.data.account.fetcher
|
||||
|
||||
import com.tangem.data.account.converter.CryptoPortfolioConverter
|
||||
import com.tangem.data.account.utils.DefaultWalletAccountsResponseFactory
|
||||
import com.tangem.data.account.utils.toUserTokensResponse
|
||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||
import com.tangem.data.common.currency.UserTokensResponseFactory
|
||||
import com.tangem.data.common.currency.UserTokensSaver
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError
|
||||
import com.tangem.datasource.api.common.response.ApiResponseError.HttpException.Code
|
||||
|
|
@ -11,12 +9,11 @@ import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
|||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.WalletAccountDTO
|
||||
import com.tangem.datasource.local.token.UserTokensResponseStore
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import io.mockk.*
|
||||
import io.mockk.clearMocks
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
|
@ -29,35 +26,21 @@ import org.junit.jupiter.api.TestInstance
|
|||
class FetchWalletAccountsErrorHandlerTest {
|
||||
|
||||
private val userTokensSaver: UserTokensSaver = mockk(relaxUnitFun = true)
|
||||
private val userWalletsStore: UserWalletsStore = mockk()
|
||||
private val userTokensResponseStore: UserTokensResponseStore = mockk(relaxUnitFun = true)
|
||||
private val cryptoPortfolioCF: CryptoPortfolioConverter.Factory = mockk()
|
||||
private val cryptoPortfolioConverter = mockk<CryptoPortfolioConverter>()
|
||||
private val userTokensResponseFactory: UserTokensResponseFactory = mockk()
|
||||
private val cardCryptoCurrencyFactory: CardCryptoCurrencyFactory = mockk()
|
||||
private val defaultWalletAccountsResponseFactory: DefaultWalletAccountsResponseFactory = mockk()
|
||||
|
||||
private val handler = FetchWalletAccountsErrorHandler(
|
||||
userTokensSaver = userTokensSaver,
|
||||
userWalletsStore = userWalletsStore,
|
||||
userTokensResponseStore = userTokensResponseStore,
|
||||
cryptoPortfolioCF = cryptoPortfolioCF,
|
||||
userTokensResponseFactory = userTokensResponseFactory,
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
defaultWalletAccountsResponseFactory = defaultWalletAccountsResponseFactory,
|
||||
)
|
||||
|
||||
private val userWallet = mockk<UserWallet> {
|
||||
every { this@mockk.walletId } returns userWalletId
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
fun setupEach() {
|
||||
clearMocks(
|
||||
userTokensSaver,
|
||||
userWalletsStore,
|
||||
userTokensResponseStore,
|
||||
cryptoPortfolioCF,
|
||||
cryptoPortfolioConverter,
|
||||
cardCryptoCurrencyFactory,
|
||||
defaultWalletAccountsResponseFactory,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -84,12 +67,8 @@ class FetchWalletAccountsErrorHandlerTest {
|
|||
|
||||
// Assert
|
||||
coVerify(inverse = true) {
|
||||
userWalletsStore.getSyncStrict(key = any())
|
||||
userTokensResponseStore.getSyncOrNull(userWalletId = any())
|
||||
userTokensResponseFactory.createUserTokensResponse(any(), any(), any())
|
||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any())
|
||||
cryptoPortfolioCF.create(any())
|
||||
cryptoPortfolioConverter.convertListBack(any())
|
||||
defaultWalletAccountsResponseFactory.create(userWalletId = any(), userTokensResponse = any())
|
||||
pushWalletAccounts(any(), any())
|
||||
userTokensSaver.push(userWalletId = any(), response = any())
|
||||
storeWalletAccounts(any(), any())
|
||||
|
|
@ -146,12 +125,8 @@ class FetchWalletAccountsErrorHandlerTest {
|
|||
}
|
||||
|
||||
coVerify(inverse = true) {
|
||||
userWalletsStore.getSyncStrict(key = any())
|
||||
userTokensResponseStore.getSyncOrNull(userWalletId = any())
|
||||
userTokensResponseFactory.createUserTokensResponse(any(), any(), any())
|
||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(any())
|
||||
cryptoPortfolioCF.create(any())
|
||||
cryptoPortfolioConverter.convertListBack(any())
|
||||
defaultWalletAccountsResponseFactory.create(userWalletId = any(), userTokensResponse = any())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,9 +135,6 @@ class FetchWalletAccountsErrorHandlerTest {
|
|||
// Arrange
|
||||
val error = ApiResponseError.TimeoutException()
|
||||
|
||||
val accounts = AccountList.empty(userWalletId).accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
|
||||
val accountDTO = WalletAccountDTO(
|
||||
id = "nibh",
|
||||
name = "Michael Dotson",
|
||||
|
|
@ -186,18 +158,10 @@ class FetchWalletAccountsErrorHandlerTest {
|
|||
|
||||
val userTokensResponse = savedAccountsResponse.toUserTokensResponse()
|
||||
|
||||
every { userWalletsStore.getSyncStrict(userWalletId) } returns userWallet
|
||||
every { cryptoPortfolioCF.create(userWallet) } returns cryptoPortfolioConverter
|
||||
every { cryptoPortfolioConverter.convertListBack(accounts) } returns listOf(accountDTO)
|
||||
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId) } returns null
|
||||
every {
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = emptyList(),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
} returns userTokensResponse
|
||||
every { cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet) } returns emptyList()
|
||||
coEvery { userTokensResponseStore.getSyncOrNull(userWalletId) } returns userTokensResponse
|
||||
coEvery {
|
||||
defaultWalletAccountsResponseFactory.create(userWalletId, userTokensResponse)
|
||||
} returns savedAccountsResponse
|
||||
|
||||
val pushWalletAccounts: suspend (UserWalletId, List<WalletAccountDTO>) -> Unit = mockk(relaxed = true)
|
||||
val storeWalletAccounts: suspend (UserWalletId, GetWalletAccountsResponse) -> Unit = mockk(relaxed = true)
|
||||
|
|
@ -213,16 +177,8 @@ class FetchWalletAccountsErrorHandlerTest {
|
|||
|
||||
// Assert
|
||||
coVerify {
|
||||
userWalletsStore.getSyncStrict(userWalletId)
|
||||
cryptoPortfolioCF.create(userWallet)
|
||||
cryptoPortfolioConverter.convertListBack(accounts)
|
||||
userTokensResponseStore.getSyncOrNull(userWalletId)
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = emptyList(),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet)
|
||||
defaultWalletAccountsResponseFactory.create(userWalletId, userTokensResponse)
|
||||
storeWalletAccounts(userWalletId, any())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,240 @@
|
|||
package com.tangem.data.account.utils
|
||||
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.data.account.converter.CryptoPortfolioConverter
|
||||
import com.tangem.data.account.converter.createWalletAccountDTO
|
||||
import com.tangem.data.common.currency.CardCryptoCurrencyFactory
|
||||
import com.tangem.data.common.currency.UserTokensResponseFactory
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.api.tangemTech.models.account.GetWalletAccountsResponse
|
||||
import com.tangem.domain.account.models.AccountList
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class DefaultWalletAccountsResponseFactoryTest {
|
||||
|
||||
private val userWalletsListRepository = mockk<UserWalletsListRepository>()
|
||||
private val cryptoPortfolioCF = mockk<CryptoPortfolioConverter.Factory>()
|
||||
private val cryptoPortfolioConverter = mockk<CryptoPortfolioConverter>()
|
||||
private val userTokensResponseFactory = mockk<UserTokensResponseFactory>()
|
||||
private val cardCryptoCurrencyFactory = mockk<CardCryptoCurrencyFactory>()
|
||||
|
||||
private val factory = DefaultWalletAccountsResponseFactory(
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
cryptoPortfolioCF = cryptoPortfolioCF,
|
||||
userTokensResponseFactory = userTokensResponseFactory,
|
||||
cardCryptoCurrencyFactory = cardCryptoCurrencyFactory,
|
||||
)
|
||||
|
||||
private val userWalletId = UserWalletId("011")
|
||||
|
||||
@BeforeEach
|
||||
fun setUpEach() {
|
||||
every { cryptoPortfolioCF.create(any()) } returns cryptoPortfolioConverter
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDownEach() {
|
||||
clearMocks(
|
||||
userWalletsListRepository,
|
||||
cryptoPortfolioCF,
|
||||
cryptoPortfolioConverter,
|
||||
userTokensResponseFactory,
|
||||
cardCryptoCurrencyFactory,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create returns empty accounts when user wallet not found`() = runTest {
|
||||
// Arrange
|
||||
val userTokensResponse = UserTokensResponse(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns emptyList()
|
||||
every {
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = emptyList(),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
} returns userTokensResponse
|
||||
|
||||
// Act
|
||||
val actual = factory.create(userWalletId = userWalletId, userTokensResponse = null)
|
||||
|
||||
// Assert
|
||||
val expected = GetWalletAccountsResponse(
|
||||
wallet = GetWalletAccountsResponse.Wallet(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
totalAccounts = 0,
|
||||
),
|
||||
accounts = emptyList(),
|
||||
unassignedTokens = emptyList(),
|
||||
)
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerifyOrder {
|
||||
userWalletsListRepository.userWalletsSync()
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = emptyList(),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create returns response with default tokens when userTokensResponse is null`() = runTest {
|
||||
// Arrange
|
||||
val userWallet = mockk<UserWallet>(relaxed = true) {
|
||||
every { walletId } returns userWalletId
|
||||
}
|
||||
|
||||
val defaultCoins = listOf(mockk<CryptoCurrency.Coin>())
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns listOf(userWallet)
|
||||
every { cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet) } returns defaultCoins
|
||||
|
||||
val defaultResponse = UserTokensResponse(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = listOf(mockk(relaxed = true)),
|
||||
)
|
||||
|
||||
every {
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = defaultCoins,
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
} returns defaultResponse
|
||||
|
||||
val accounts = AccountList.empty(userWallet.walletId).accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
|
||||
val accountsDTO = createWalletAccountDTO(userWalletId)
|
||||
every { cryptoPortfolioConverter.convertListBack(accounts) } returns listOf(accountsDTO)
|
||||
|
||||
// Act
|
||||
val actual = factory.create(userWalletId, null)
|
||||
|
||||
// Assert
|
||||
val expected = GetWalletAccountsResponse(
|
||||
wallet = GetWalletAccountsResponse.Wallet(
|
||||
group = defaultResponse.group,
|
||||
sort = defaultResponse.sort,
|
||||
totalAccounts = 1,
|
||||
),
|
||||
accounts = listOf(accountsDTO),
|
||||
unassignedTokens = emptyList(),
|
||||
)
|
||||
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerifyOrder {
|
||||
userWalletsListRepository.userWalletsSync()
|
||||
cryptoPortfolioConverter.convertListBack(accounts)
|
||||
cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet)
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = defaultCoins,
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create returns response with default tokens when userTokensResponse is null and no default coins`() = runTest {
|
||||
// Arrange
|
||||
val userWallet = mockk<UserWallet>(relaxed = true) {
|
||||
every { walletId } returns userWalletId
|
||||
}
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns listOf(userWallet)
|
||||
every { cardCryptoCurrencyFactory.createDefaultCoinsForMultiCurrencyWallet(userWallet) } returns emptyList()
|
||||
val defaultResponse = UserTokensResponse(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = emptyList(),
|
||||
)
|
||||
every {
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = emptyList(),
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
} returns defaultResponse
|
||||
val accounts = AccountList.empty(userWallet.walletId).accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
every { cryptoPortfolioConverter.convertListBack(accounts) } returns emptyList()
|
||||
|
||||
// Act
|
||||
val actual = factory.create(userWalletId, null)
|
||||
|
||||
// Assert
|
||||
val expected = GetWalletAccountsResponse(
|
||||
wallet = GetWalletAccountsResponse.Wallet(
|
||||
group = defaultResponse.group,
|
||||
sort = defaultResponse.sort,
|
||||
totalAccounts = 0,
|
||||
),
|
||||
accounts = emptyList(),
|
||||
unassignedTokens = emptyList(),
|
||||
)
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create returns response with assigned tokens`() = runTest {
|
||||
// Arrange
|
||||
val userWallet = mockk<UserWallet>(relaxed = true) {
|
||||
every { walletId } returns userWalletId
|
||||
}
|
||||
val assignedTokens = listOf(mockk<CryptoCurrency.Token>(), mockk<CryptoCurrency.Token>())
|
||||
coEvery { userWalletsListRepository.userWalletsSync() } returns listOf(userWallet)
|
||||
val userTokensResponse = UserTokensResponse(
|
||||
group = UserTokensResponse.GroupType.NETWORK,
|
||||
sort = UserTokensResponse.SortType.BALANCE,
|
||||
tokens = listOf(mockk(relaxed = true)),
|
||||
)
|
||||
every {
|
||||
userTokensResponseFactory.createUserTokensResponse(
|
||||
currencies = assignedTokens,
|
||||
isGroupedByNetwork = false,
|
||||
isSortedByBalance = false,
|
||||
)
|
||||
} returns userTokensResponse
|
||||
|
||||
val accounts = AccountList.empty(userWallet.walletId).accounts
|
||||
.filterIsInstance<Account.CryptoPortfolio>()
|
||||
val accountsDTO = createWalletAccountDTO(userWalletId)
|
||||
every { cryptoPortfolioConverter.convertListBack(accounts) } returns listOf(accountsDTO)
|
||||
|
||||
// Act
|
||||
val actual = factory.create(userWalletId, userTokensResponse)
|
||||
|
||||
// Assert
|
||||
val expected = GetWalletAccountsResponse(
|
||||
wallet = GetWalletAccountsResponse.Wallet(
|
||||
group = userTokensResponse.group,
|
||||
sort = userTokensResponse.sort,
|
||||
totalAccounts = 1,
|
||||
),
|
||||
accounts = listOf(accountsDTO),
|
||||
unassignedTokens = emptyList(),
|
||||
)
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue