Updated on 2026-08-14
This commit is contained in:
parent
61f2412cb5
commit
e3ec61bc4b
11 changed files with 509 additions and 8 deletions
|
|
@ -19,6 +19,9 @@ internal class RuntimeUserWalletsStore(
|
|||
override val userWallets: Flow<List<UserWallet>>
|
||||
get() = userWalletsListManager.userWallets
|
||||
|
||||
override val userWalletsSync: List<UserWallet>
|
||||
get() = userWalletsListManager.userWalletsSync
|
||||
|
||||
override fun getSyncOrNull(key: UserWalletId): UserWallet? {
|
||||
return userWalletsListManager.userWalletsSync.firstOrNull { it.walletId == key }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package com.tangem.tap.data
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.catching
|
||||
import com.tangem.datasource.local.userwallet.UserWalletsStore
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.core.wallets.UserWalletsListRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
|
|
@ -24,6 +24,9 @@ class UserWalletsStoreRepositoryProxy(
|
|||
}
|
||||
}
|
||||
|
||||
override val userWalletsSync: List<UserWallet>
|
||||
get() = userWalletsListRepository.userWallets.value.orEmpty()
|
||||
|
||||
override fun getSyncOrNull(key: UserWalletId): UserWallet? {
|
||||
return userWalletsListRepository.userWallets.value?.find { it.walletId == key }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
import com.tangem.domain.account.usecase.*
|
||||
import dagger.Module
|
||||
|
|
@ -49,4 +50,16 @@ internal object AccountDomainModule {
|
|||
): GetUnoccupiedAccountIndexUseCase {
|
||||
return GetUnoccupiedAccountIndexUseCase(crudRepository = accountsCRUDRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideIsAccountsModeEnabledUseCase(
|
||||
accountsCRUDRepository: AccountsCRUDRepository,
|
||||
accountsFeatureToggles: AccountsFeatureToggles,
|
||||
): IsAccountsModeEnabledUseCase {
|
||||
return IsAccountsModeEnabledUseCase(
|
||||
crudRepository = accountsCRUDRepository,
|
||||
accountsFeatureToggles = accountsFeatureToggles,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,8 @@ interface UserWalletsStore {
|
|||
|
||||
val userWallets: Flow<List<UserWallet>>
|
||||
|
||||
val userWalletsSync: List<UserWallet>
|
||||
|
||||
fun getSyncOrNull(key: UserWalletId): UserWallet?
|
||||
|
||||
fun getSyncStrict(key: UserWalletId): UserWallet
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
|
|
@ -108,7 +109,7 @@ internal class DefaultAccountsCRUDRepository(
|
|||
walletAccountsSaver.pushAndStore(userWalletId = userWalletId, response = accountsResponse)
|
||||
}
|
||||
|
||||
override suspend fun getTotalAccountsCount(userWalletId: UserWalletId): Option<Int> = option {
|
||||
override suspend fun getTotalAccountsCountSync(userWalletId: UserWalletId): Option<Int> = option {
|
||||
val accountListResponse = getAccountsResponseSync(userWalletId = userWalletId)
|
||||
|
||||
ensureNotNull(accountListResponse)
|
||||
|
|
@ -116,10 +117,19 @@ internal class DefaultAccountsCRUDRepository(
|
|||
return accountListResponse.wallet.totalAccounts.toOption()
|
||||
}
|
||||
|
||||
override fun getTotalAccountsCount(userWalletId: UserWalletId): Flow<Option<Int>> {
|
||||
return getAccountsResponseStore(userWalletId = userWalletId).data
|
||||
.map { it?.wallet?.totalAccounts.toOption() }
|
||||
}
|
||||
|
||||
override fun getUserWallet(userWalletId: UserWalletId): UserWallet {
|
||||
return userWalletsStore.getSyncStrict(userWalletId)
|
||||
}
|
||||
|
||||
override fun getUserWallets(): Flow<List<UserWallet>> = userWalletsStore.userWallets
|
||||
|
||||
override fun getUserWalletsSync(): List<UserWallet> = userWalletsStore.userWalletsSync
|
||||
|
||||
private suspend fun getETag(userWalletId: UserWalletId): String? {
|
||||
return eTagsStore.getSyncOrNull(userWalletId = userWalletId, key = ETagsStore.Key.WalletAccounts)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -648,4 +648,94 @@ class DefaultAccountsCRUDRepositoryTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
inner class GetTotalAccountsCountSync {
|
||||
|
||||
@Test
|
||||
fun `getTotalAccountsCountSync returns None if account list response is null`() = runTest {
|
||||
// Arrange
|
||||
accountsResponseStoreFlow.value = null
|
||||
|
||||
// Act
|
||||
val actual = repository.getTotalAccountsCountSync(userWalletId)
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isEqualTo(None)
|
||||
|
||||
verifyOrder {
|
||||
accountsResponseStoreFactory.create(userWalletId)
|
||||
accountsResponseStore.data
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getTotalAccountsCountSync returns Some with totalAccounts when response is valid`() = runTest {
|
||||
// Arrange
|
||||
val totalAccounts = 5
|
||||
val response = mockk<GetWalletAccountsResponse> {
|
||||
every { this@mockk.wallet.totalAccounts } returns totalAccounts
|
||||
}
|
||||
|
||||
accountsResponseStoreFlow.value = response
|
||||
|
||||
// Act
|
||||
val actual = repository.getTotalAccountsCountSync(userWalletId)
|
||||
|
||||
// Assert
|
||||
val expected = totalAccounts.toOption()
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
verifyOrder {
|
||||
accountsResponseStoreFactory.create(userWalletId)
|
||||
accountsResponseStore.data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
inner class GetTotalAccountsCount {
|
||||
|
||||
@Test
|
||||
fun `getTotalAccountsCount emits 0 when account list response is null`() = runTest {
|
||||
// Arrange
|
||||
accountsResponseStoreFlow.value = null
|
||||
|
||||
// Act
|
||||
val flow = repository.getTotalAccountsCount(userWalletId)
|
||||
val actual = getEmittedValues(flow)
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).containsExactly(None)
|
||||
|
||||
verifyOrder {
|
||||
accountsResponseStoreFactory.create(userWalletId)
|
||||
accountsResponseStore.data
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getTotalAccountsCount emits correct value when response is valid`() = runTest {
|
||||
// Arrange
|
||||
val totalAccounts = 7
|
||||
val response = mockk<GetWalletAccountsResponse> {
|
||||
every { this@mockk.wallet.totalAccounts } returns totalAccounts
|
||||
}
|
||||
|
||||
accountsResponseStoreFlow.value = response
|
||||
|
||||
// Act
|
||||
val flow = repository.getTotalAccountsCount(userWalletId)
|
||||
val actual = getEmittedValues(flow)
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).containsExactly(totalAccounts.toOption())
|
||||
verifyOrder {
|
||||
accountsResponseStoreFactory.create(userWalletId)
|
||||
accountsResponseStore.data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +73,14 @@ interface AccountsCRUDRepository {
|
|||
*
|
||||
* @param userWalletId the unique identifier of the user wallet
|
||||
*/
|
||||
suspend fun getTotalAccountsCount(userWalletId: UserWalletId): Option<Int>
|
||||
suspend fun getTotalAccountsCountSync(userWalletId: UserWalletId): Option<Int>
|
||||
|
||||
/**
|
||||
* Provides a flow of the total count of accounts associated with a specific user wallet including archived accounts
|
||||
*
|
||||
* @param userWalletId the unique identifier of the user wallet
|
||||
*/
|
||||
fun getTotalAccountsCount(userWalletId: UserWalletId): Flow<Option<Int>>
|
||||
|
||||
/**
|
||||
* Retrieves a user wallet by its unique identifier
|
||||
|
|
@ -82,4 +89,10 @@ interface AccountsCRUDRepository {
|
|||
* @return the [UserWallet] associated with the given identifier
|
||||
*/
|
||||
fun getUserWallet(userWalletId: UserWalletId): UserWallet
|
||||
|
||||
/** Provides a flow of all user wallets */
|
||||
fun getUserWallets(): Flow<List<UserWallet>>
|
||||
|
||||
/** Synchronously retrieves all user wallets */
|
||||
fun getUserWalletsSync(): List<UserWallet>
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@ class GetUnoccupiedAccountIndexUseCase(
|
|||
|
||||
private suspend fun Raise<Error>.getTotalAccountsCount(userWalletId: UserWalletId): Int {
|
||||
return catch(
|
||||
block = { crudRepository.getTotalAccountsCount(userWalletId = userWalletId) },
|
||||
block = { crudRepository.getTotalAccountsCountSync(userWalletId = userWalletId) },
|
||||
catch = { raise(Error.DataOperationFailed(cause = it)) },
|
||||
)
|
||||
.getOrElse { raise(Error.DataNotFound) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
package com.tangem.domain.account.usecase
|
||||
|
||||
import arrow.core.Option
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
* Use case to determine if the accounts mode is enabled.
|
||||
* Accounts mode is considered enabled if there are at least two accounts in any of the user wallets that support
|
||||
* multiple currencies.
|
||||
*
|
||||
* @property crudRepository repository to interact with user wallets and their accounts
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
class IsAccountsModeEnabledUseCase(
|
||||
private val crudRepository: AccountsCRUDRepository,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
) {
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
operator fun invoke(): Flow<Boolean> {
|
||||
if (!accountsFeatureToggles.isFeatureEnabled) return flowOf(value = false)
|
||||
|
||||
return crudRepository.getUserWallets()
|
||||
.flatMapLatest { userWallets ->
|
||||
val totalAccountsCountList = getTotalAccountsCountList(userWallets)
|
||||
|
||||
combine(flows = totalAccountsCountList) { it.toList().isModeEnabled() }
|
||||
}
|
||||
.onEmpty { emit(false) }
|
||||
}
|
||||
|
||||
suspend fun invokeSync(): Boolean {
|
||||
if (!accountsFeatureToggles.isFeatureEnabled) return false
|
||||
|
||||
return crudRepository.getUserWalletsSync()
|
||||
.map { userWallet ->
|
||||
// If the wallet does not support multiple currencies, we consider its account count as 0
|
||||
if (!userWallet.isMultiCurrency) return@map 0
|
||||
|
||||
crudRepository.getTotalAccountsCountSync(userWalletId = userWallet.walletId).getOrZero()
|
||||
}
|
||||
.isModeEnabled()
|
||||
}
|
||||
|
||||
private fun getTotalAccountsCountList(userWallets: List<UserWallet>): List<Flow<Int>> {
|
||||
return userWallets
|
||||
.map { userWallet ->
|
||||
// If the wallet does not support multiple currencies, we consider its account count as 0
|
||||
if (!userWallet.isMultiCurrency) return@map flowOf(0)
|
||||
|
||||
crudRepository.getTotalAccountsCount(userWalletId = userWallet.walletId)
|
||||
.map { maybeCount -> maybeCount.getOrZero() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Option<Int>.getOrZero(): Int = getOrElse { 0 }
|
||||
|
||||
private fun List<Int>.isModeEnabled(): Boolean = any { it >= 2 }
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ class GetUnoccupiedAccountIndexUseCaseTest {
|
|||
@Test
|
||||
fun `invoke should return next unoccupied index when repository returns count`() = runTest {
|
||||
// Arrange
|
||||
coEvery { crudRepository.getTotalAccountsCount(userWalletId) } returns 3.toOption()
|
||||
coEvery { crudRepository.getTotalAccountsCountSync(userWalletId) } returns 3.toOption()
|
||||
|
||||
// Act
|
||||
val actual = useCase(userWalletId = userWalletId)
|
||||
|
|
@ -39,14 +39,14 @@ class GetUnoccupiedAccountIndexUseCaseTest {
|
|||
val expected = DerivationIndex(4)
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerify { crudRepository.getTotalAccountsCount(userWalletId) }
|
||||
coVerify { crudRepository.getTotalAccountsCountSync(userWalletId) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke should return error if repository throws exception`() = runTest {
|
||||
// Arrange
|
||||
val exception = IllegalStateException("Test error")
|
||||
coEvery { crudRepository.getTotalAccountsCount(userWalletId) } throws exception
|
||||
coEvery { crudRepository.getTotalAccountsCountSync(userWalletId) } throws exception
|
||||
|
||||
// Act
|
||||
val actual = useCase(userWalletId = userWalletId)
|
||||
|
|
@ -55,6 +55,6 @@ class GetUnoccupiedAccountIndexUseCaseTest {
|
|||
val expected = GetUnoccupiedAccountIndexUseCase.Error.DataOperationFailed(exception).left()
|
||||
Truth.assertThat(actual).isEqualTo(expected)
|
||||
|
||||
coVerify { crudRepository.getTotalAccountsCount(userWalletId) }
|
||||
coVerify { crudRepository.getTotalAccountsCountSync(userWalletId) }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
package com.tangem.domain.account.usecase
|
||||
|
||||
import arrow.core.none
|
||||
import arrow.core.some
|
||||
import com.google.common.truth.Truth
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.repository.AccountsCRUDRepository
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class IsAccountsModeEnabledUseCaseTest {
|
||||
|
||||
private val accountsCRUDRepository: AccountsCRUDRepository = mockk()
|
||||
private val featureToggles: AccountsFeatureToggles = mockk()
|
||||
|
||||
private val useCase = IsAccountsModeEnabledUseCase(accountsCRUDRepository, featureToggles)
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
clearMocks(accountsCRUDRepository, featureToggles)
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
inner class Invoke {
|
||||
|
||||
@Test
|
||||
fun `returns false when feature is disabled`() = runTest {
|
||||
// Arrange
|
||||
every { featureToggles.isFeatureEnabled } returns false
|
||||
|
||||
// Act
|
||||
val actual = useCase.invoke().firstOrNull()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
verify(exactly = 1) { featureToggles.isFeatureEnabled }
|
||||
verify(inverse = true) { accountsCRUDRepository.getUserWallets() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when getUserWallets emits empty flow`() = runTest {
|
||||
// Arrange
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWallets() } returns emptyFlow()
|
||||
|
||||
// Act
|
||||
val actual = useCase.invoke().firstOrNull()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
verifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
}
|
||||
|
||||
verify(inverse = true) { accountsCRUDRepository.getTotalAccountsCount(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when getUserWallets emits one wallet with isMultiCurrency false`() = runTest {
|
||||
// Arrange
|
||||
val wallet = createUserWallet(isMultiCurrency = false)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWallets() } returns flowOf(listOf(wallet))
|
||||
|
||||
// Act
|
||||
val actual = useCase.invoke().first()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
verifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
}
|
||||
|
||||
verify(inverse = true) { accountsCRUDRepository.getTotalAccountsCount(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns true when getUserWallets emits one wallet with isMultiCurrency true`() = runTest {
|
||||
// Arrange
|
||||
val wallet = createUserWallet(isMultiCurrency = true)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWallets() } returns flowOf(listOf(wallet))
|
||||
every { accountsCRUDRepository.getTotalAccountsCount(wallet.walletId) } returns flowOf(2.some())
|
||||
|
||||
// Act
|
||||
val actual = useCase.invoke().first()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isTrue()
|
||||
|
||||
verifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
accountsCRUDRepository.getTotalAccountsCount(wallet.walletId)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when getUserWallets emits one wallet with isMultiCurrency true and None counts`() = runTest {
|
||||
// Arrange
|
||||
val wallet = createUserWallet(isMultiCurrency = true)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWallets() } returns flowOf(listOf(wallet))
|
||||
every { accountsCRUDRepository.getTotalAccountsCount(wallet.walletId) } returns flowOf(none())
|
||||
|
||||
// Act
|
||||
val actual = useCase.invoke().first()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
verifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
accountsCRUDRepository.getTotalAccountsCount(wallet.walletId)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns true when getUserWallets emits two wallets, one isMultiCurrency false, one true`() = runTest {
|
||||
// Arrange
|
||||
val wallet1 = createUserWallet(isMultiCurrency = false)
|
||||
val wallet2 = createUserWallet(isMultiCurrency = true)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWallets() } returns flowOf(listOf(wallet1, wallet2))
|
||||
every { accountsCRUDRepository.getTotalAccountsCount(wallet2.walletId) } returns flowOf(2.some())
|
||||
|
||||
// Act
|
||||
val actual = useCase.invoke().first()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isTrue()
|
||||
|
||||
verifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWallets()
|
||||
accountsCRUDRepository.getTotalAccountsCount(wallet2.walletId)
|
||||
}
|
||||
|
||||
verify(inverse = true) { accountsCRUDRepository.getTotalAccountsCount(wallet1.walletId) }
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
inner class InvokeSync {
|
||||
|
||||
@Test
|
||||
fun `returns false when feature is disabled`() = runTest {
|
||||
// Arrange
|
||||
every { featureToggles.isFeatureEnabled } returns false
|
||||
|
||||
// Act
|
||||
val actual = useCase.invokeSync()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
verify(exactly = 1) { featureToggles.isFeatureEnabled }
|
||||
verify(inverse = true) { accountsCRUDRepository.getUserWalletsSync() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when getUserWalletsSync returns empty list`() = runTest {
|
||||
// Arrange
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns emptyList()
|
||||
|
||||
// Act
|
||||
val actual = useCase.invokeSync()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
verifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
}
|
||||
|
||||
coVerify(inverse = true) { accountsCRUDRepository.getTotalAccountsCountSync(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when getUserWalletsSync returns one wallet with isMultiCurrency false`() = runTest {
|
||||
// Arrange
|
||||
val wallet = createUserWallet(isMultiCurrency = false)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(wallet)
|
||||
|
||||
// Act
|
||||
val actual = useCase.invokeSync()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
verifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
}
|
||||
|
||||
coVerify(inverse = true) { accountsCRUDRepository.getTotalAccountsCountSync(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns true when getUserWalletsSync returns one wallet with isMultiCurrency true`() = runTest {
|
||||
// Arrange
|
||||
val wallet = createUserWallet(isMultiCurrency = true)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(wallet)
|
||||
coEvery { accountsCRUDRepository.getTotalAccountsCountSync(wallet.walletId) } returns 2.some()
|
||||
|
||||
// Act
|
||||
val actual = useCase.invokeSync()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isTrue()
|
||||
|
||||
coVerifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
accountsCRUDRepository.getTotalAccountsCountSync(wallet.walletId)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns false when getUserWalletsSync returns multi wallet with None counts`() = runTest {
|
||||
// Arrange
|
||||
val wallet = createUserWallet(isMultiCurrency = true)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(wallet)
|
||||
coEvery { accountsCRUDRepository.getTotalAccountsCountSync(wallet.walletId) } returns none()
|
||||
|
||||
// Act
|
||||
val actual = useCase.invokeSync()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isFalse()
|
||||
|
||||
coVerifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
accountsCRUDRepository.getTotalAccountsCountSync(wallet.walletId)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `returns true when getUserWalletsSync returns multi and single wallets`() = runTest {
|
||||
// Arrange
|
||||
val wallet1 = createUserWallet(isMultiCurrency = false)
|
||||
val wallet2 = createUserWallet(isMultiCurrency = true)
|
||||
|
||||
every { featureToggles.isFeatureEnabled } returns true
|
||||
every { accountsCRUDRepository.getUserWalletsSync() } returns listOf(wallet1, wallet2)
|
||||
coEvery { accountsCRUDRepository.getTotalAccountsCountSync(wallet2.walletId) } returns 2.some()
|
||||
|
||||
// Act
|
||||
val actual = useCase.invokeSync()
|
||||
|
||||
// Assert
|
||||
Truth.assertThat(actual).isTrue()
|
||||
|
||||
coVerifyOrder {
|
||||
featureToggles.isFeatureEnabled
|
||||
accountsCRUDRepository.getUserWalletsSync()
|
||||
accountsCRUDRepository.getTotalAccountsCountSync(wallet2.walletId)
|
||||
}
|
||||
|
||||
coVerify(inverse = true) { accountsCRUDRepository.getTotalAccountsCountSync(wallet1.walletId) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun createUserWallet(isMultiCurrency: Boolean): UserWallet = mockk {
|
||||
every { this@mockk.walletId } returns UserWalletId(stringValue = "011")
|
||||
every { this@mockk.isMultiCurrency } returns isMultiCurrency
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue