Updated on 2026-08-14
This commit is contained in:
parent
b6f31df9d1
commit
655eeb61ba
3 changed files with 189 additions and 147 deletions
|
|
@ -6,8 +6,10 @@ import com.tangem.domain.account.status.supplier.SingleAccountStatusListSupplier
|
||||||
import com.tangem.domain.account.status.usecase.*
|
import com.tangem.domain.account.status.usecase.*
|
||||||
import com.tangem.domain.account.status.utils.CryptoCurrencyBalanceFetcher
|
import com.tangem.domain.account.status.utils.CryptoCurrencyBalanceFetcher
|
||||||
import com.tangem.domain.account.status.utils.CryptoCurrencyMetadataCleaner
|
import com.tangem.domain.account.status.utils.CryptoCurrencyMetadataCleaner
|
||||||
|
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
||||||
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
import com.tangem.domain.account.supplier.SingleAccountListSupplier
|
||||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||||
|
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||||
import com.tangem.domain.express.ExpressServiceFetcher
|
import com.tangem.domain.express.ExpressServiceFetcher
|
||||||
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
import com.tangem.domain.networks.multi.MultiNetworkStatusFetcher
|
||||||
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
import com.tangem.domain.networks.multi.MultiNetworkStatusSupplier
|
||||||
|
|
@ -51,9 +53,13 @@ internal object AccountStatusUseCaseModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideIsAccountsModeEnabledUseCase(
|
fun provideIsAccountsModeEnabledUseCase(
|
||||||
multiAccountStatusListSupplier: MultiAccountStatusListSupplier,
|
multiAccountListSupplier: MultiAccountListSupplier,
|
||||||
|
paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||||
): IsAccountsModeEnabledUseCase {
|
): IsAccountsModeEnabledUseCase {
|
||||||
return IsAccountsModeEnabledUseCase(multiAccountStatusListSupplier = multiAccountStatusListSupplier)
|
return IsAccountsModeEnabledUseCase(
|
||||||
|
multiAccountListSupplier = multiAccountListSupplier,
|
||||||
|
paymentAccountStatusSupplier = paymentAccountStatusSupplier,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,76 @@
|
||||||
package com.tangem.domain.account.status.usecase
|
package com.tangem.domain.account.status.usecase
|
||||||
|
|
||||||
import com.tangem.domain.account.status.supplier.MultiAccountStatusListSupplier
|
import com.tangem.domain.account.models.AccountList
|
||||||
import com.tangem.domain.models.account.AccountStatus
|
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
||||||
|
import com.tangem.domain.models.account.Account
|
||||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||||
import kotlinx.coroutines.flow.Flow
|
import com.tangem.domain.pay.flow.PaymentAccountStatusProducer
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.flow.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use case to determine if the accounts mode is enabled.
|
* Use case to determine if the accounts mode is enabled.
|
||||||
* Accounts mode is considered enabled if any [com.tangem.domain.account.models.AccountStatusList] produced for the
|
|
||||||
* user's wallets has more than one [AccountStatus.CryptoPortfolio], or has a [AccountStatus.Payment] with any
|
|
||||||
|
|
||||||
* [PaymentAccountStatusValue.Empty].
|
|
||||||
*
|
*
|
||||||
* @property multiAccountStatusListSupplier supplier that provides a list of
|
* Accounts mode is considered enabled if any user wallet either:
|
||||||
* [com.tangem.domain.account.models.AccountStatusList]s for all user wallets
|
* - contains more than one [Account.CryptoPortfolio], or
|
||||||
|
* - has a [com.tangem.domain.models.account.AccountStatus.Payment] in an active state.
|
||||||
*
|
*
|
||||||
[REDACTED_AUTHOR]
|
* Splits the structural check (via [MultiAccountListSupplier]) and the payment-status check
|
||||||
|
* (via [PaymentAccountStatusSupplier] per wallet) so that the structural answer doesn't wait for
|
||||||
|
* slow per-wallet status pipelines on cold start.
|
||||||
*/
|
*/
|
||||||
class IsAccountsModeEnabledUseCase(
|
class IsAccountsModeEnabledUseCase(
|
||||||
private val multiAccountStatusListSupplier: MultiAccountStatusListSupplier,
|
private val multiAccountListSupplier: MultiAccountListSupplier,
|
||||||
|
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
operator fun invoke(): Flow<Boolean> {
|
operator fun invoke(): Flow<Boolean> {
|
||||||
return multiAccountStatusListSupplier.invoke()
|
val cryptoMode = multiAccountListSupplier.invoke()
|
||||||
.map { accountStatusLists -> accountStatusLists.any { it.accountStatuses.isModeEnabled() } }
|
.map { lists -> lists.any { it.hasMultipleCryptoPortfolios() } }
|
||||||
|
|
||||||
|
val paymentMode = multiAccountListSupplier.invoke().flatMapLatest { lists ->
|
||||||
|
val walletIdsWithPayment = lists.mapNotNull { list ->
|
||||||
|
if (list.accounts.any { it is Account.Payment }) list.userWalletId else null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walletIdsWithPayment.isEmpty()) {
|
||||||
|
flowOf(false)
|
||||||
|
} else {
|
||||||
|
val flows = walletIdsWithPayment.map { walletId ->
|
||||||
|
paymentAccountStatusSupplier.invoke(walletId)
|
||||||
|
.map { it.value.isActivePayment() }
|
||||||
|
.onStart { emit(false) }
|
||||||
|
}
|
||||||
|
combine(flows) { results -> results.any { it } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return combine(cryptoMode, paymentMode) { crypto, payment -> crypto || payment }
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun invokeSync(): Boolean {
|
suspend fun invokeSync(): Boolean {
|
||||||
return multiAccountStatusListSupplier.getSyncOrNull(Unit)
|
val accountLists = multiAccountListSupplier.getSyncOrNull(Unit).orEmpty()
|
||||||
?.any { it.accountStatuses.isModeEnabled() } == true
|
if (accountLists.any { it.hasMultipleCryptoPortfolios() }) return true
|
||||||
|
|
||||||
|
val walletIdsWithPayment = accountLists.mapNotNull { list ->
|
||||||
|
if (list.accounts.any { it is Account.Payment }) list.userWalletId else null
|
||||||
|
}
|
||||||
|
return walletIdsWithPayment.any { walletId ->
|
||||||
|
paymentAccountStatusSupplier
|
||||||
|
.getSyncOrNull(
|
||||||
|
params = PaymentAccountStatusProducer.Params(walletId),
|
||||||
|
timeMillis = PAYMENT_STATUS_SYNC_TIMEOUT_MS,
|
||||||
|
)
|
||||||
|
?.value
|
||||||
|
?.isActivePayment() == true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<AccountStatus>.isModeEnabled(): Boolean {
|
private fun AccountList.hasMultipleCryptoPortfolios(): Boolean =
|
||||||
var cryptoPortfolioCount = 0
|
accounts.filterIsInstance<Account.CryptoPortfolio>().size > 1
|
||||||
for (status in this) {
|
|
||||||
when {
|
|
||||||
status is AccountStatus.CryptoPortfolio && ++cryptoPortfolioCount > 1 -> return true
|
|
||||||
status is AccountStatus.Payment && status.value.isActivePayment() -> return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PaymentAccountStatusValue.isActivePayment(): Boolean {
|
private fun PaymentAccountStatusValue.isActivePayment(): Boolean {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
|
@ -60,4 +87,8 @@ class IsAccountsModeEnabledUseCase(
|
||||||
-> true
|
-> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val PAYMENT_STATUS_SYNC_TIMEOUT_MS = 1_000L
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
package com.tangem.domain.account.status.usecase
|
package com.tangem.domain.account.status.usecase
|
||||||
|
|
||||||
import com.google.common.truth.Truth
|
import com.google.common.truth.Truth
|
||||||
import com.tangem.domain.account.models.AccountStatusList
|
import com.tangem.domain.account.models.AccountList
|
||||||
import com.tangem.domain.account.status.supplier.MultiAccountStatusListSupplier
|
import com.tangem.domain.account.supplier.MultiAccountListSupplier
|
||||||
|
import com.tangem.domain.models.account.Account
|
||||||
import com.tangem.domain.models.account.AccountStatus
|
import com.tangem.domain.models.account.AccountStatus
|
||||||
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
import com.tangem.domain.models.account.PaymentAccountStatusValue
|
||||||
|
import com.tangem.domain.models.wallet.UserWalletId
|
||||||
|
import com.tangem.domain.pay.flow.PaymentAccountStatusProducer
|
||||||
|
import com.tangem.domain.pay.flow.PaymentAccountStatusSupplier
|
||||||
import io.mockk.clearMocks
|
import io.mockk.clearMocks
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.last
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.jupiter.api.AfterEach
|
import org.junit.jupiter.api.AfterEach
|
||||||
|
|
@ -20,13 +24,17 @@ import org.junit.jupiter.api.TestInstance
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
class IsAccountsModeEnabledUseCaseTest {
|
class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
private val multiAccountStatusListSupplier: MultiAccountStatusListSupplier = mockk()
|
private val multiAccountListSupplier: MultiAccountListSupplier = mockk()
|
||||||
|
private val paymentAccountStatusSupplier: PaymentAccountStatusSupplier = mockk()
|
||||||
|
|
||||||
private val useCase = IsAccountsModeEnabledUseCase(multiAccountStatusListSupplier = multiAccountStatusListSupplier)
|
private val useCase = IsAccountsModeEnabledUseCase(
|
||||||
|
multiAccountListSupplier = multiAccountListSupplier,
|
||||||
|
paymentAccountStatusSupplier = paymentAccountStatusSupplier,
|
||||||
|
)
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
fun tearDown() {
|
fun tearDown() {
|
||||||
clearMocks(multiAccountStatusListSupplier)
|
clearMocks(multiAccountListSupplier, paymentAccountStatusSupplier)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|
@ -35,145 +43,140 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when supplier emits empty list`() = runTest {
|
fun `returns false when supplier emits empty list`() = runTest {
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(emptyList())
|
every { multiAccountListSupplier.invoke() } returns flowOf(emptyList())
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isFalse()
|
Truth.assertThat(actual).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when single crypto portfolio account`() = runTest {
|
fun `returns false when single crypto portfolio account`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio()))
|
||||||
statuses = listOf(mockCryptoPortfolio()),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isFalse()
|
Truth.assertThat(actual).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when two crypto portfolio accounts`() = runTest {
|
fun `returns true when two crypto portfolio accounts`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockCryptoPortfolio()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockCryptoPortfolio()),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is Loaded`() = runTest {
|
fun `returns true when payment account is Loaded`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Loaded>())),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
mockPaymentStatus(WALLET_ID_1, mockk<PaymentAccountStatusValue.Loaded>())
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is Locked`() = runTest {
|
fun `returns true when payment account is Locked`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Locked>())),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
mockPaymentStatus(WALLET_ID_1, mockk<PaymentAccountStatusValue.Locked>())
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when payment account is NotCreated`() = runTest {
|
fun `returns false when payment account is NotCreated`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(PaymentAccountStatusValue.NotCreated)),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
mockPaymentStatus(WALLET_ID_1, PaymentAccountStatusValue.NotCreated)
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isFalse()
|
Truth.assertThat(actual).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when payment account is Empty`() = runTest {
|
fun `returns false when payment account is Empty`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(PaymentAccountStatusValue.Empty)),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
mockPaymentStatus(WALLET_ID_1, PaymentAccountStatusValue.Empty)
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isFalse()
|
Truth.assertThat(actual).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is UnderReview`() = runTest {
|
fun `returns true when payment account is UnderReview`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.UnderReview>())),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
mockPaymentStatus(WALLET_ID_1, mockk<PaymentAccountStatusValue.UnderReview>())
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is IssuingCard`() = runTest {
|
fun `returns true when payment account is IssuingCard`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.IssuingCard>())),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
mockPaymentStatus(WALLET_ID_1, mockk<PaymentAccountStatusValue.IssuingCard>())
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is Loading`() = runTest {
|
fun `returns true when payment account is Loading`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(PaymentAccountStatusValue.Loading)),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
)
|
mockPaymentStatus(WALLET_ID_1, PaymentAccountStatusValue.Loading)
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN payment account is Deactivated WHEN invoke THEN returns true`() = runTest {
|
fun `returns true when payment account is Deactivated`() = runTest {
|
||||||
// GIVEN
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
val statusList = createAccountStatusList(
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Deactivated>())),
|
mockPaymentStatus(WALLET_ID_1, mockk<PaymentAccountStatusValue.Deactivated>())
|
||||||
)
|
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList))
|
|
||||||
|
|
||||||
// WHEN
|
val actual = useCase.invoke().last()
|
||||||
val actual = useCase.invoke().first()
|
|
||||||
|
|
||||||
// THEN
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when multiple status lists and one has two crypto portfolios`() = runTest {
|
fun `returns true when multiple wallets and one has two crypto portfolios`() = runTest {
|
||||||
val statusList1 = createAccountStatusList(statuses = listOf(mockCryptoPortfolio()))
|
val list1 = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio()))
|
||||||
val statusList2 = createAccountStatusList(
|
val list2 = createAccountList(WALLET_ID_2, listOf(mockCryptoPortfolio(), mockCryptoPortfolio()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockCryptoPortfolio()),
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list1, list2))
|
||||||
)
|
|
||||||
every { multiAccountStatusListSupplier.invoke() } returns flowOf(listOf(statusList1, statusList2))
|
|
||||||
|
|
||||||
val actual = useCase.invoke().first()
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
|
Truth.assertThat(actual).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `returns true when multiple wallets and one has active payment`() = runTest {
|
||||||
|
val list1 = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio()))
|
||||||
|
val list2 = createAccountList(WALLET_ID_2, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
|
every { multiAccountListSupplier.invoke() } returns flowOf(listOf(list1, list2))
|
||||||
|
mockPaymentStatus(WALLET_ID_2, mockk<PaymentAccountStatusValue.Loaded>())
|
||||||
|
|
||||||
|
val actual = useCase.invoke().last()
|
||||||
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +188,7 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when getSyncOrNull returns null`() = runTest {
|
fun `returns false when getSyncOrNull returns null`() = runTest {
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns null
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns null
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -194,7 +197,7 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when getSyncOrNull returns empty list`() = runTest {
|
fun `returns false when getSyncOrNull returns empty list`() = runTest {
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns emptyList()
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns emptyList()
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -203,10 +206,8 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when single crypto portfolio account`() = runTest {
|
fun `returns false when single crypto portfolio account`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio()))
|
||||||
statuses = listOf(mockCryptoPortfolio()),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
)
|
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -215,10 +216,8 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when two crypto portfolio accounts`() = runTest {
|
fun `returns true when two crypto portfolio accounts`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockCryptoPortfolio()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockCryptoPortfolio()),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
)
|
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -227,10 +226,9 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is Loaded`() = runTest {
|
fun `returns true when payment account is Loaded`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Loaded>())),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
)
|
mockPaymentStatusSync(WALLET_ID_1, mockk<PaymentAccountStatusValue.Loaded>())
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -239,10 +237,9 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is Locked`() = runTest {
|
fun `returns true when payment account is Locked`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Locked>())),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
)
|
mockPaymentStatusSync(WALLET_ID_1, mockk<PaymentAccountStatusValue.Locked>())
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -251,10 +248,9 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when payment account is NotCreated`() = runTest {
|
fun `returns false when payment account is NotCreated`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(PaymentAccountStatusValue.NotCreated)),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
)
|
mockPaymentStatusSync(WALLET_ID_1, PaymentAccountStatusValue.NotCreated)
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -263,10 +259,9 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns false when payment account is Empty`() = runTest {
|
fun `returns false when payment account is Empty`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(PaymentAccountStatusValue.Empty)),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
)
|
mockPaymentStatusSync(WALLET_ID_1, PaymentAccountStatusValue.Empty)
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -275,10 +270,9 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when payment account is UnderReview`() = runTest {
|
fun `returns true when payment account is UnderReview`() = runTest {
|
||||||
val statusList = createAccountStatusList(
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.UnderReview>())),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
)
|
mockPaymentStatusSync(WALLET_ID_1, mockk<PaymentAccountStatusValue.UnderReview>())
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -286,27 +280,22 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `GIVEN payment account is Deactivated WHEN invokeSync THEN returns true`() = runTest {
|
fun `returns true when payment account is Deactivated`() = runTest {
|
||||||
// GIVEN
|
val list = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
val statusList = createAccountStatusList(
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list)
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Deactivated>())),
|
mockPaymentStatusSync(WALLET_ID_1, mockk<PaymentAccountStatusValue.Deactivated>())
|
||||||
)
|
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList)
|
|
||||||
|
|
||||||
// WHEN
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
// THEN
|
|
||||||
Truth.assertThat(actual).isTrue()
|
Truth.assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `returns true when multiple status lists and one has loaded payment`() = runTest {
|
fun `returns true when multiple wallets and one has loaded payment`() = runTest {
|
||||||
val statusList1 = createAccountStatusList(statuses = listOf(mockCryptoPortfolio()))
|
val list1 = createAccountList(WALLET_ID_1, listOf(mockCryptoPortfolio()))
|
||||||
val statusList2 = createAccountStatusList(
|
val list2 = createAccountList(WALLET_ID_2, listOf(mockCryptoPortfolio(), mockPaymentAccount()))
|
||||||
statuses = listOf(mockCryptoPortfolio(), mockPayment(mockk<PaymentAccountStatusValue.Loaded>())),
|
coEvery { multiAccountListSupplier.getSyncOrNull(Unit, any()) } returns listOf(list1, list2)
|
||||||
)
|
mockPaymentStatusSync(WALLET_ID_2, mockk<PaymentAccountStatusValue.Loaded>())
|
||||||
coEvery { multiAccountStatusListSupplier.getSyncOrNull(Unit, any()) } returns listOf(statusList1, statusList2)
|
|
||||||
|
|
||||||
val actual = useCase.invokeSync()
|
val actual = useCase.invokeSync()
|
||||||
|
|
||||||
|
|
@ -314,13 +303,29 @@ class IsAccountsModeEnabledUseCaseTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun mockCryptoPortfolio(): AccountStatus.CryptoPortfolio = mockk()
|
private fun mockCryptoPortfolio(): Account.CryptoPortfolio = mockk()
|
||||||
|
|
||||||
private fun mockPayment(value: PaymentAccountStatusValue): AccountStatus.Payment = mockk {
|
private fun mockPaymentAccount(): Account.Payment = mockk()
|
||||||
every { this@mockk.value } returns value
|
|
||||||
|
private fun mockPaymentStatus(walletId: UserWalletId, value: PaymentAccountStatusValue) {
|
||||||
|
val status = mockk<AccountStatus.Payment> { every { this@mockk.value } returns value }
|
||||||
|
every { paymentAccountStatusSupplier.invoke(walletId) } returns flowOf(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createAccountStatusList(statuses: List<AccountStatus>): AccountStatusList = mockk {
|
private fun mockPaymentStatusSync(walletId: UserWalletId, value: PaymentAccountStatusValue) {
|
||||||
every { accountStatuses } returns statuses
|
val status = mockk<AccountStatus.Payment> { every { this@mockk.value } returns value }
|
||||||
|
coEvery {
|
||||||
|
paymentAccountStatusSupplier.getSyncOrNull(PaymentAccountStatusProducer.Params(walletId), any())
|
||||||
|
} returns status
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createAccountList(walletId: UserWalletId, accounts: List<Account>): AccountList = mockk {
|
||||||
|
every { userWalletId } returns walletId
|
||||||
|
every { this@mockk.accounts } returns accounts
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
val WALLET_ID_1 = UserWalletId(stringValue = "011")
|
||||||
|
val WALLET_ID_2 = UserWalletId(stringValue = "022")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue