Updated on 2026-08-14

This commit is contained in:
Tangem 2025-07-25 18:58:54 +04:00
parent b2a199a568
commit 3f60d15820
23 changed files with 405 additions and 303 deletions

View file

@ -1,15 +1,11 @@
package com.tangem.data.staking.multi
import arrow.core.Either
import arrow.core.getOrElse
import arrow.core.left
import arrow.core.raise.catch
import arrow.core.raise.either
import arrow.core.raise.ensure
import arrow.core.right
import arrow.core.toOption
import com.tangem.data.common.api.safeApiCall
import com.tangem.data.staking.store.YieldsBalancesStore
import com.tangem.data.staking.utils.StakingIdFactory
import com.tangem.data.staking.utils.YieldBalanceRequestBodyFactory
import com.tangem.datasource.api.stakekit.StakeKitApi
import com.tangem.datasource.api.stakekit.models.request.YieldBalanceRequestBody
@ -36,7 +32,6 @@ import javax.inject.Inject
* @property userWalletsStore user wallets store
* @property stakingYieldsStore staking yields store
* @property yieldsBalancesStore yields balances store
* @property stakingIdFactory factory for creating StakingID
* @property stakeKitApi stake kit API
* @property dispatchers dispatchers
*
@ -46,7 +41,6 @@ internal class DefaultMultiYieldBalanceFetcher @Inject constructor(
private val userWalletsStore: UserWalletsStore,
private val stakingYieldsStore: StakingYieldsStore,
private val yieldsBalancesStore: YieldsBalancesStore,
private val stakingIdFactory: StakingIdFactory,
private val stakeKitApi: StakeKitApi,
private val dispatchers: CoroutineDispatcherProvider,
) : MultiYieldBalanceFetcher {
@ -54,11 +48,12 @@ internal class DefaultMultiYieldBalanceFetcher @Inject constructor(
override suspend fun invoke(params: MultiYieldBalanceFetcher.Params): Either<Throwable, Unit> {
Timber.i("Start fetching yield balances for params:\n$params")
checkIsSupportedByWalletOrElse(userWalletId = params.userWalletId) {
return it.left()
val stakingIds = params.stakingIds.ifEmpty {
Timber.i("Nothing to fetch, empty stakingIds for ${params.userWalletId}")
return Unit.right()
}
val stakingIds = getStakingIds(params).getOrElse {
checkIsSupportedByWalletOrElse(userWalletId = params.userWalletId) {
return it.left()
}
@ -94,30 +89,6 @@ internal class DefaultMultiYieldBalanceFetcher @Inject constructor(
}
}
private suspend fun getStakingIds(params: MultiYieldBalanceFetcher.Params) = either {
val stakingIds = catch(
block = {
params.currencyIdWithNetworkMap.mapNotNullTo(hashSetOf()) { (currencyId, network) ->
stakingIdFactory.create(
userWalletId = params.userWalletId,
currencyId = currencyId,
network = network,
)
}
},
catch = ::raise,
)
ensure(stakingIds.isNotEmpty()) {
val exception = IllegalStateException("Unable to create staking ids for $params: list is empty")
Timber.e(exception)
raise(exception)
}
stakingIds
}
private suspend fun getAvailableStakingIds(userWalletId: UserWalletId, stakingIds: Set<StakingID>): Set<StakingID> {
val yieldIds = getYieldsIds(userWalletId = userWalletId)

View file

@ -20,9 +20,7 @@ internal class DefaultSingleYieldBalanceFetcher @Inject constructor(
return multiYieldBalanceFetcher(
params = MultiYieldBalanceFetcher.Params(
userWalletId = params.userWalletId,
currencyIdWithNetworkMap = mapOf(
params.currencyId to params.network,
),
stakingIds = setOf(params.stakingId),
),
)
}

View file

@ -1,14 +1,12 @@
package com.tangem.data.staking.multi
import arrow.core.toOption
import com.google.common.truth.Truth
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.test.data.staking.MockYieldBalanceWrapperDTOFactory
import com.tangem.common.test.data.staking.MockYieldDTOFactory
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
import com.tangem.common.test.domain.wallet.MockUserWalletFactory
import com.tangem.common.test.utils.assertEitherLeft
import com.tangem.common.test.utils.assertEitherRight
import com.tangem.data.staking.store.YieldsBalancesStore
import com.tangem.data.staking.utils.StakingIdFactory
import com.tangem.data.staking.utils.YieldBalanceRequestBodyFactory
import com.tangem.datasource.api.common.response.ApiResponse
import com.tangem.datasource.api.common.response.ApiResponseError
@ -34,55 +32,46 @@ internal class DefaultMultiYieldBalanceFetcherTest {
private val userWalletsStore: UserWalletsStore = mockk()
private val stakingYieldsStore: StakingYieldsStore = mockk()
private val yieldsBalancesStore: YieldsBalancesStore = mockk()
private val stakingIdFactory: StakingIdFactory = mockk()
private val yieldsBalancesStore: YieldsBalancesStore = mockk(relaxUnitFun = true)
private val stakeKitApi: StakeKitApi = mockk()
private val fetcher = DefaultMultiYieldBalanceFetcher(
userWalletsStore = userWalletsStore,
stakingYieldsStore = stakingYieldsStore,
yieldsBalancesStore = yieldsBalancesStore,
stakingIdFactory = stakingIdFactory,
stakeKitApi = stakeKitApi,
dispatchers = TestingCoroutineDispatcherProvider(),
)
@BeforeEach
fun resetMocks() {
clearMocks(userWalletsStore, stakingYieldsStore, yieldsBalancesStore, stakingIdFactory, stakeKitApi)
clearMocks(userWalletsStore, stakingYieldsStore, yieldsBalancesStore, stakeKitApi)
}
@Test
fun `fetch yields balances successfully`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns tonId
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns solanaId
coEvery { yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds) } just Runs
val yields = listOf(MockYieldDTOFactory.create(tonId), MockYieldDTOFactory.create(solanaId))
coEvery { stakingYieldsStore.getSyncWithTimeout() } returns yields
val requests = tonAndSolanaIds.map(YieldBalanceRequestBodyFactory::create).sortedBy { it.integrationId }
val requests = tonAndSolanaIds.map(YieldBalanceRequestBodyFactory::create)
val result = setOf(
MockYieldBalanceWrapperDTOFactory.createWithBalance(solanaId),
MockYieldBalanceWrapperDTOFactory.createWithBalance(tonId),
)
coEvery { stakeKitApi.getMultipleYieldBalances(requests) } returns ApiResponse.Success(result)
coEvery { yieldsBalancesStore.storeActual(userWalletId = userWalletId, values = result) } just Runs
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
coVerifyOrder {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
yieldsBalancesStore.refresh(userWalletId = params.userWalletId, stakingIds = tonAndSolanaIds)
stakingYieldsStore.getSyncWithTimeout()
stakeKitApi.getMultipleYieldBalances(requests)
@ -91,40 +80,30 @@ internal class DefaultMultiYieldBalanceFetcherTest {
coVerify(inverse = true) { yieldsBalancesStore.storeError(any(), any()) }
Truth.assertThat(actual.isRight()).isTrue()
assertEitherRight(actual)
}
@Test
fun `fetch yields balances successfully if one of stakingIds is unavailable`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns tonId
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns solanaId
coEvery { yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds) } just Runs
val yields = listOf(MockYieldDTOFactory.create(tonId))
coEvery { stakingYieldsStore.getSyncWithTimeout() } returns yields
coEvery { yieldsBalancesStore.storeError(userWalletId = userWalletId, stakingIds = setOf(solanaId)) } just Runs
val requests = listOf(YieldBalanceRequestBodyFactory.create(tonId))
val result = setOf(MockYieldBalanceWrapperDTOFactory.createWithBalance(tonId))
coEvery { stakeKitApi.getMultipleYieldBalances(requests) } returns ApiResponse.Success(result)
coEvery { yieldsBalancesStore.storeActual(userWalletId = userWalletId, values = result) } just Runs
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
coVerifyOrder {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
yieldsBalancesStore.refresh(userWalletId = params.userWalletId, stakingIds = tonAndSolanaIds)
stakingYieldsStore.getSyncWithTimeout()
yieldsBalancesStore.storeError(userWalletId = userWalletId, stakingIds = setOf(solanaId))
@ -132,15 +111,13 @@ internal class DefaultMultiYieldBalanceFetcherTest {
yieldsBalancesStore.storeActual(userWalletId = userWalletId, values = result)
}
Truth.assertThat(actual.isRight()).isTrue()
assertEitherRight(actual)
}
@Test
fun `fetch yields balances failure if user wallet is not supported`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
val userWallet = MockUserWalletFactory.create().copy(isMultiCurrency = false)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
@ -149,10 +126,9 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val actual = fetcher.invoke(params)
// Assert
coVerify { userWalletsStore.getSyncOrNull(params.userWalletId) }
coVerifyOrder { userWalletsStore.getSyncOrNull(params.userWalletId) }
coVerify(inverse = true) {
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
yieldsBalancesStore.refresh(userWalletId = any(), stakingIds = any())
stakingYieldsStore.getSyncWithTimeout()
stakeKitApi.getSingleYieldBalance(integrationId = any(), body = any())
@ -162,17 +138,13 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val expected = IllegalStateException("Wallet ${params.userWalletId} is not supported: ${userWallet.toOption()}")
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
assertEitherLeft(actual, expected)
}
@Test
fun `fetch yields balances failure if userWalletsStore returns null`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns null
@ -180,10 +152,9 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val actual = fetcher.invoke(params)
// Assert
coVerify { userWalletsStore.getSyncOrNull(params.userWalletId) }
coVerifyOrder { userWalletsStore.getSyncOrNull(params.userWalletId) }
coVerify(inverse = true) {
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
yieldsBalancesStore.refresh(userWalletId = any(), stakingIds = any())
stakingYieldsStore.getSyncWithTimeout()
stakeKitApi.getSingleYieldBalance(integrationId = any(), body = any())
@ -193,69 +164,23 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val expected = IllegalStateException("Wallet ${params.userWalletId} is not supported: ${null.toOption()}")
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
}
@Test
fun `fetch yields balances failure if stakingIdFactory returns null`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns null
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns null
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
}
coVerify(inverse = true) {
yieldsBalancesStore.refresh(any(), any<Set<StakingID>>())
stakingYieldsStore.getSyncWithTimeout()
stakeKitApi.getMultipleYieldBalances(any())
yieldsBalancesStore.storeActual(any(), any())
yieldsBalancesStore.storeError(any(), any())
}
val expected = IllegalStateException("Unable to create staking ids for $params: list is empty")
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
assertEitherLeft(actual, expected)
}
@Test
fun `fetch yields balances failure if stakingYieldsStore getSyncWithTimeout returns null`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns tonId
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns solanaId
coEvery { yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds) } just Runs
coEvery { stakingYieldsStore.getSyncWithTimeout() } returns null
coEvery { yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds) } just Runs
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
coVerifyOrder {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds)
stakingYieldsStore.getSyncWithTimeout()
yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds)
@ -268,33 +193,23 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val expected = IllegalStateException("No enabled yields for ${params.userWalletId}")
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
assertEitherLeft(actual, expected)
}
@Test
fun `fetch yields balances failure if stakingYieldsStore getSyncWithTimeout returns empty list`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns tonId
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns solanaId
coEvery { yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds) } just Runs
coEvery { stakingYieldsStore.getSyncWithTimeout() } returns emptyList()
coEvery { yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds) } just Runs
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
coVerifyOrder {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
yieldsBalancesStore.refresh(userWalletId = params.userWalletId, stakingIds = tonAndSolanaIds)
stakingYieldsStore.getSyncWithTimeout()
yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds)
@ -307,38 +222,28 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val expected = IllegalStateException("No enabled yields for ${params.userWalletId}")
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
assertEitherLeft(actual, expected)
}
@Test
fun `fetch yields balances failure if yields converting is failed`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns tonId
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns solanaId
coEvery { yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds) } just Runs
val yields = listOf(
MockYieldDTOFactory.create(tonId).copy(id = null),
MockYieldDTOFactory.create(solanaId).copy(id = null),
)
coEvery { stakingYieldsStore.getSyncWithTimeout() } returns yields
coEvery { yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds) } just Runs
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
coVerifyOrder {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
yieldsBalancesStore.refresh(userWalletId = params.userWalletId, stakingIds = tonAndSolanaIds)
stakingYieldsStore.getSyncWithTimeout()
yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds)
@ -351,35 +256,25 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val expected = IllegalStateException("No enabled yields for ${params.userWalletId}")
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
assertEitherLeft(actual, expected)
}
@Test
fun `fetch yields balances failure if available yields does not contain ids from params`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns tonId
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns solanaId
coEvery { yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds) } just Runs
val yields = listOf(MockYieldDTOFactory.create(StakingID(integrationId = "polygon", address = "0x1")))
coEvery { stakingYieldsStore.getSyncWithTimeout() } returns yields
coEvery { yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds) } just Runs
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
coVerifyOrder {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
yieldsBalancesStore.refresh(userWalletId = params.userWalletId, stakingIds = tonAndSolanaIds)
stakingYieldsStore.getSyncWithTimeout()
yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds)
@ -394,47 +289,37 @@ internal class DefaultMultiYieldBalanceFetcherTest {
"""
No available yields to fetch yield balances:
userWalletId: $userWalletId
stakingIds: ${setOf(solanaId, tonId).joinToString()}
stakingIds: ${tonAndSolanaIds.joinToString()}
""".trimIndent(),
)
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
assertEitherLeft(actual, expected)
}
@Test
fun `fetch yields balances failure if stakeKitApi getMultipleYieldBalances is failed`() = runTest {
// Arrange
val currencyIdWithNetworkMap = mapOf(ton.id to ton.network, solana.id to solana.network)
val params = MultiYieldBalanceFetcher.Params(userWalletId, currencyIdWithNetworkMap)
val params = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = tonAndSolanaIds)
coEvery { userWalletsStore.getSyncOrNull(params.userWalletId) } returns userWallet
coEvery { stakingIdFactory.create(params.userWalletId, ton.id, ton.network) } returns tonId
coEvery { stakingIdFactory.create(params.userWalletId, solana.id, solana.network) } returns solanaId
coEvery { yieldsBalancesStore.refresh(params.userWalletId, tonAndSolanaIds) } just Runs
val yields = listOf(MockYieldDTOFactory.create(tonId), MockYieldDTOFactory.create(solanaId))
coEvery { stakingYieldsStore.getSyncWithTimeout() } returns yields
val requests = setOf(solanaId, tonId).map(YieldBalanceRequestBodyFactory::create)
val requests = setOf(tonId, solanaId).map(YieldBalanceRequestBodyFactory::create)
@Suppress("UNCHECKED_CAST")
val errorResponse = ApiResponse.Error(ApiResponseError.NetworkException)
as ApiResponse<Set<YieldBalanceWrapperDTO>>
coEvery { stakeKitApi.getMultipleYieldBalances(requests) } returns errorResponse
coEvery { yieldsBalancesStore.storeError(userWalletId, tonAndSolanaIds) } just Runs
// Actual
val actual = fetcher.invoke(params)
// Assert
coVerify {
coVerifyOrder {
userWalletsStore.getSyncOrNull(params.userWalletId)
stakingIdFactory.create(params.userWalletId, ton.id, ton.network)
stakingIdFactory.create(params.userWalletId, solana.id, solana.network)
yieldsBalancesStore.refresh(userWalletId = params.userWalletId, stakingIds = tonAndSolanaIds)
stakingYieldsStore.getSyncWithTimeout()
stakeKitApi.getMultipleYieldBalances(requests)
@ -445,20 +330,13 @@ internal class DefaultMultiYieldBalanceFetcherTest {
val expected = ApiResponseError.NetworkException
Truth.assertThat(actual.isLeft()).isTrue()
Truth.assertThat(actual.leftOrNull()).isInstanceOf(expected::class.java)
Truth.assertThat(actual.leftOrNull()).hasMessageThat().isEqualTo(expected.message)
assertEitherLeft(actual, expected)
}
private companion object {
val userWalletId = UserWalletId("011")
val userWallet = MockUserWalletFactory.create()
val mocks = MockCryptoCurrencyFactory()
val ton = mocks.createCoin(Blockchain.TON)
val solana = mocks.createCoin(Blockchain.Solana)
val tonId = MockYieldBalanceWrapperDTOFactory.defaultStakingId
val solanaId = StakingID(
integrationId = "solana-sol-native-multivalidator-staking",

View file

@ -3,8 +3,7 @@ package com.tangem.data.staking.single
import arrow.core.left
import arrow.core.right
import com.google.common.truth.Truth
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.test.domain.token.MockCryptoCurrencyFactory
import com.tangem.common.test.data.staking.MockYieldBalanceWrapperDTOFactory
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.domain.staking.multi.MultiYieldBalanceFetcher
import com.tangem.domain.staking.single.SingleYieldBalanceFetcher
@ -37,15 +36,11 @@ internal class DefaultSingleYieldBalanceFetcherTest {
@Test
fun `fetch yield balance successfully`() = runTest {
// Arrange
val params = SingleYieldBalanceFetcher.Params(
userWalletId = userWalletId,
currencyId = ton.id,
network = ton.network,
)
val params = SingleYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingId = tonId)
val multiParams = MultiYieldBalanceFetcher.Params(
userWalletId = userWalletId,
currencyIdWithNetworkMap = mapOf(ton.id to ton.network),
stakingIds = setOf(tonId),
)
val multiResult = Unit.right()
@ -64,16 +59,9 @@ internal class DefaultSingleYieldBalanceFetcherTest {
@Test
fun `fetch yield balance failure`() = runTest {
// Arrange
val params = SingleYieldBalanceFetcher.Params(
userWalletId = userWalletId,
currencyId = ton.id,
network = ton.network,
)
val params = SingleYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingId = tonId)
val multiParams = MultiYieldBalanceFetcher.Params(
userWalletId = userWalletId,
currencyIdWithNetworkMap = mapOf(ton.id to ton.network),
)
val multiParams = MultiYieldBalanceFetcher.Params(userWalletId = userWalletId, stakingIds = setOf(tonId))
val multiResult = IllegalStateException().left()
@ -89,6 +77,6 @@ internal class DefaultSingleYieldBalanceFetcherTest {
private companion object {
val userWalletId = UserWalletId("011")
val ton = MockCryptoCurrencyFactory().createCoin(Blockchain.TON)
val tonId = MockYieldBalanceWrapperDTOFactory.defaultStakingId
}
}