Updated on 2026-08-14
This commit is contained in:
commit
24ef1d4ed9
120 changed files with 6250 additions and 675 deletions
|
|
@ -17,6 +17,7 @@ dependencies {
|
|||
implementation(projects.domain.wallets.models)
|
||||
|
||||
/* Project - Core */
|
||||
api(projects.core.analytics.models)
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package com.tangem.features.hotwallet
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
|
||||
interface CreateMobileWalletComponent : ComposableContentComponent {
|
||||
data class Params(
|
||||
val source: String,
|
||||
val source: AnalyticsParam.ScreensSources,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, CreateMobileWalletComponent>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ android {
|
|||
namespace = "com.tangem.features.hotwallet.impl"
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** Api */
|
||||
implementation(projects.features.hotWallet.api)
|
||||
|
|
@ -78,4 +82,11 @@ dependencies {
|
|||
/** DI */
|
||||
implementation(deps.hilt.android)
|
||||
kapt(deps.hilt.kapt)
|
||||
|
||||
/** Test */
|
||||
testImplementation(deps.test.junit5)
|
||||
testRuntimeOnly(deps.test.junit5.engine)
|
||||
testImplementation(deps.test.mockk)
|
||||
testImplementation(deps.test.truth)
|
||||
testImplementation(deps.test.coroutine)
|
||||
}
|
||||
|
|
@ -129,13 +129,13 @@ internal class AddExistingWalletImportModel @Inject constructor(
|
|||
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.Onboarding.Finished(
|
||||
source = AnalyticsParam.ScreensSources.ImportWallet.value,
|
||||
source = AnalyticsParam.ScreensSources.ImportWallet,
|
||||
),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.CreateWallet.WalletCreatedSuccessfully(
|
||||
source = AnalyticsParam.ScreensSources.ImportWallet.value,
|
||||
creationType = OnboardingAnalyticsEvent.CreateWallet.WalletCreationType.SeedImport,
|
||||
source = AnalyticsParam.ScreensSources.ImportWallet,
|
||||
creationType = AnalyticsParam.WalletCreationType.SeedImport,
|
||||
seedPhraseLength = mnemonic.mnemonicComponents.size,
|
||||
passPhraseState = if (passphrase.isNullOrBlank()) {
|
||||
AnalyticsParam.EmptyFull.Empty
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
|
||||
init {
|
||||
trackingContextProxy.addHotWalletContext()
|
||||
analyticsEventHandler.send(event = OnboardingAnalyticsEvent.Onboarding.Started(source = params.source))
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.Onboarding.Started(source = params.source),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.SeedPhrase.CreateMobileScreenOpened(source = params.source),
|
||||
)
|
||||
|
|
@ -95,11 +97,13 @@ internal class CreateMobileWalletModel @Inject constructor(
|
|||
|
||||
saveUserWalletUseCase(userWallet)
|
||||
|
||||
analyticsEventHandler.send(OnboardingAnalyticsEvent.Onboarding.Finished(source = params.source))
|
||||
analyticsEventHandler.send(
|
||||
OnboardingAnalyticsEvent.Onboarding.Finished(source = params.source),
|
||||
)
|
||||
analyticsEventHandler.send(
|
||||
event = OnboardingAnalyticsEvent.CreateWallet.WalletCreatedSuccessfully(
|
||||
source = params.source,
|
||||
creationType = OnboardingAnalyticsEvent.CreateWallet.WalletCreationType.NewSeed,
|
||||
creationType = AnalyticsParam.WalletCreationType.NewSeed,
|
||||
seedPhraseLength = SEED_PHRASE_LENGTH,
|
||||
passPhraseState = AnalyticsParam.EmptyFull.Empty,
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ internal data class WalletBackupUM(
|
|||
val onRecoveryPhraseClick: () -> Unit,
|
||||
val onGoogleDriveClick: () -> Unit,
|
||||
val onHardwareWalletClick: () -> Unit,
|
||||
val backedUp: Boolean,
|
||||
val isBackedUp: Boolean,
|
||||
)
|
||||
|
||||
internal sealed class BackupStatus {
|
||||
|
|
@ -7,10 +7,13 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.label.entity.LabelStyle
|
||||
import com.tangem.core.ui.components.label.entity.LabelUM
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
|
|
@ -19,9 +22,9 @@ import com.tangem.features.hotwallet.WalletBackupComponent
|
|||
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.WalletBackupUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import com.tangem.utils.logging.TangemLogger
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -35,6 +38,7 @@ internal class WalletBackupModel @Inject constructor(
|
|||
private val router: Router,
|
||||
private val trackingContextProxy: TrackingContextProxy,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
) : Model() {
|
||||
|
||||
private val params: WalletBackupComponent.Params = paramsContainer.require()
|
||||
|
|
@ -59,9 +63,9 @@ internal class WalletBackupModel @Inject constructor(
|
|||
),
|
||||
googleDriveStatus = BackupStatus.ComingSoon,
|
||||
onRecoveryPhraseClick = ::onRecoveryPhraseClick,
|
||||
onGoogleDriveClick = { },
|
||||
onGoogleDriveClick = ::onGoogleDriveBackupClick,
|
||||
onHardwareWalletClick = ::onHardwareWalletClick,
|
||||
backedUp = false,
|
||||
isBackedUp = false,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -116,15 +120,16 @@ internal class WalletBackupModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
googleDriveOption = LabelUM(
|
||||
text = resourceReference(R.string.common_coming_soon),
|
||||
style = LabelStyle.REGULAR,
|
||||
text = resourceReference(R.string.hw_backup_no_backup),
|
||||
style = LabelStyle.WARNING,
|
||||
),
|
||||
backedUp = userWallet.backedUp,
|
||||
isBackedUp = userWallet.backedUp,
|
||||
googleDriveStatus = BackupStatus.NoBackup,
|
||||
)
|
||||
|
||||
private fun onRecoveryPhraseClick() {
|
||||
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonRecoveryPhrase())
|
||||
if (uiState.value.backedUp) {
|
||||
if (uiState.value.isBackedUp) {
|
||||
getUserWalletUseCase.invoke(params.userWalletId)
|
||||
.fold(
|
||||
ifLeft = {
|
||||
|
|
@ -150,6 +155,20 @@ internal class WalletBackupModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun onGoogleDriveBackupClick() {
|
||||
analyticsEventHandler.send(WalletSettingsAnalyticEvents.ButtonGoogleDriveBackup())
|
||||
uiMessageSender.send(
|
||||
DialogMessage(
|
||||
title = resourceReference(id = R.string.hw_backup_google_drive_dialog_title),
|
||||
message = resourceReference(id = R.string.hw_backup_google_drive_dialog_message),
|
||||
firstAction = EventMessageAction(
|
||||
title = resourceReference(id = R.string.common_ok),
|
||||
onClick = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun showSeedPhrase(hotWallet: UserWallet.Hot) {
|
||||
modelScope.launch {
|
||||
unlockHotWalletContextualUseCase.invoke(hotWallet.hotWalletId)
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
onHardwareWalletClick = {},
|
||||
backedUp = false,
|
||||
isBackedUp = false,
|
||||
),
|
||||
WalletBackupUM(
|
||||
hardwareWalletOption = LabelUM(
|
||||
|
|
@ -152,7 +152,7 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
onHardwareWalletClick = {},
|
||||
backedUp = false,
|
||||
isBackedUp = false,
|
||||
),
|
||||
WalletBackupUM(
|
||||
hardwareWalletOption = LabelUM(
|
||||
|
|
@ -172,7 +172,7 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
onHardwareWalletClick = {},
|
||||
backedUp = false,
|
||||
isBackedUp = false,
|
||||
),
|
||||
WalletBackupUM(
|
||||
hardwareWalletOption = null,
|
||||
|
|
@ -189,7 +189,7 @@ private class WalletBackupUMProvider : CollectionPreviewParameterProvider<Wallet
|
|||
onRecoveryPhraseClick = {},
|
||||
onGoogleDriveClick = {},
|
||||
onHardwareWalletClick = {},
|
||||
backedUp = false,
|
||||
isBackedUp = false,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
package com.tangem.features.hotwallet.walletbackup.model
|
||||
|
||||
import arrow.core.left
|
||||
import arrow.core.right
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.utils.TrackingContextProxy
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.analytics.WalletSettingsAnalyticEvents
|
||||
import com.tangem.domain.wallets.models.GetUserWalletError
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.UnlockHotWalletContextualUseCase
|
||||
import com.tangem.features.hotwallet.WalletBackupComponent
|
||||
import com.tangem.features.hotwallet.walletbackup.entity.BackupStatus
|
||||
import com.tangem.hot.sdk.model.HotWalletId
|
||||
import com.tangem.hot.sdk.model.UnlockHotWallet
|
||||
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal class WalletBackupModelTest {
|
||||
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase = mockk()
|
||||
private val unlockHotWalletContextualUseCase: UnlockHotWalletContextualUseCase = mockk()
|
||||
private val router: Router = mockk(relaxUnitFun = true)
|
||||
private val trackingContextProxy: TrackingContextProxy = mockk(relaxUnitFun = true)
|
||||
private val analyticsEventHandler: AnalyticsEventHandler = mockk(relaxUnitFun = true)
|
||||
private val uiMessageSender: UiMessageSender = mockk(relaxUnitFun = true)
|
||||
private val paramsContainer: ParamsContainer = mockk()
|
||||
|
||||
private val walletId = UserWalletId("011")
|
||||
private val hotWalletId: HotWalletId = mockk()
|
||||
private val params = WalletBackupComponent.Params(
|
||||
userWalletId = walletId,
|
||||
isColdWalletOptionShown = true,
|
||||
)
|
||||
private val hotWalletNotBackedUp: UserWallet.Hot = mockk {
|
||||
every { walletId } returns this@WalletBackupModelTest.walletId
|
||||
every { hotWalletId } returns this@WalletBackupModelTest.hotWalletId
|
||||
every { backedUp } returns false
|
||||
}
|
||||
private val hotWalletBackedUp: UserWallet.Hot = mockk {
|
||||
every { walletId } returns this@WalletBackupModelTest.walletId
|
||||
every { hotWalletId } returns this@WalletBackupModelTest.hotWalletId
|
||||
every { backedUp } returns true
|
||||
}
|
||||
private val coldWallet: UserWallet.Cold = mockk {
|
||||
every { walletId } returns this@WalletBackupModelTest.walletId
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
every { paramsContainer.require<WalletBackupComponent.Params>() } returns params
|
||||
every { getUserWalletUseCase.invokeFlow(walletId) } returns flowOf(hotWalletNotBackedUp.right())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN hot wallet WHEN model is created THEN context added AND BackupScreenOpened sent AND state updated`() =
|
||||
runTest {
|
||||
every { getUserWalletUseCase.invokeFlow(walletId) } returns flowOf(hotWalletNotBackedUp.right())
|
||||
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { trackingContextProxy.addHotWalletContext() }
|
||||
verify {
|
||||
analyticsEventHandler.send(WalletSettingsAnalyticEvents.BackupScreenOpened(isBackedUp = false))
|
||||
}
|
||||
val state = model.uiState.value
|
||||
Assertions.assertEquals(false, state.isBackedUp)
|
||||
Assertions.assertEquals(BackupStatus.NoBackup, state.googleDriveStatus)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN cold wallet WHEN model is created THEN context added AND BackupScreenOpened not sent AND state untouched`() =
|
||||
runTest {
|
||||
every { getUserWalletUseCase.invokeFlow(walletId) } returns flowOf(coldWallet.right())
|
||||
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { trackingContextProxy.addHotWalletContext() }
|
||||
verify(exactly = 0) {
|
||||
analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.BackupScreenOpened> { true })
|
||||
}
|
||||
val state = model.uiState.value
|
||||
Assertions.assertEquals(false, state.isBackedUp)
|
||||
Assertions.assertEquals(BackupStatus.ComingSoon, state.googleDriveStatus)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN error WHEN model is created THEN context added AND BackupScreenOpened not sent`() = runTest {
|
||||
every { getUserWalletUseCase.invokeFlow(walletId) } returns flowOf(GetUserWalletError.UserWalletNotFound.left())
|
||||
|
||||
createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { trackingContextProxy.addHotWalletContext() }
|
||||
verify(exactly = 0) {
|
||||
analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.BackupScreenOpened> { true })
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN onDestroy THEN trackingContextProxy removeContext is called`() = runTest {
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.onDestroy()
|
||||
|
||||
verify { trackingContextProxy.removeContext() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN backed up hot wallet AND unlock success WHEN onRecoveryPhraseClick THEN ViewPhrase pushed`() = runTest {
|
||||
every { getUserWalletUseCase.invokeFlow(walletId) } returns flowOf(hotWalletBackedUp.right())
|
||||
every { getUserWalletUseCase.invoke(walletId) } returns hotWalletBackedUp.right()
|
||||
coEvery { unlockHotWalletContextualUseCase.invoke(hotWalletId) } returns mockk<UnlockHotWallet>().right()
|
||||
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
coVerify { unlockHotWalletContextualUseCase.invoke(hotWalletId) }
|
||||
verify { router.push(route = AppRoute.ViewPhrase(userWalletId = walletId), onComplete = any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN backed up hot wallet AND unlock failure WHEN onRecoveryPhraseClick THEN ViewPhrase not pushed`() =
|
||||
runTest {
|
||||
every { getUserWalletUseCase.invokeFlow(walletId) } returns flowOf(hotWalletBackedUp.right())
|
||||
every { getUserWalletUseCase.invoke(walletId) } returns hotWalletBackedUp.right()
|
||||
coEvery { unlockHotWalletContextualUseCase.invoke(hotWalletId) } returns Throwable("error").left()
|
||||
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
coVerify { unlockHotWalletContextualUseCase.invoke(hotWalletId) }
|
||||
verify(exactly = 0) {
|
||||
router.push(route = AppRoute.ViewPhrase(userWalletId = walletId), onComplete = any())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN backed up cold wallet WHEN onRecoveryPhraseClick THEN no navigation AND no unlock`() = runTest {
|
||||
every { getUserWalletUseCase.invokeFlow(walletId) } returns flowOf(hotWalletBackedUp.right())
|
||||
every { getUserWalletUseCase.invoke(walletId) } returns coldWallet.right()
|
||||
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
coVerify(exactly = 0) { unlockHotWalletContextualUseCase.invoke(any()) }
|
||||
verify(exactly = 0) { router.push(route = any(), onComplete = any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN not backed up wallet WHEN onRecoveryPhraseClick THEN WalletActivation pushed`() = runTest {
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.uiState.value.onRecoveryPhraseClick()
|
||||
advanceUntilIdle()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonRecoveryPhrase> { true }) }
|
||||
verify(exactly = 0) { getUserWalletUseCase.invoke(walletId) }
|
||||
coVerify(exactly = 0) { unlockHotWalletContextualUseCase.invoke(any()) }
|
||||
verify {
|
||||
router.push(
|
||||
route = AppRoute.WalletActivation(userWalletId = walletId, isBackupExists = false),
|
||||
onComplete = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN onHardwareWalletClick THEN ButtonHardwareUpdate sent AND WalletHardwareBackup pushed`() = runTest {
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.uiState.value.onHardwareWalletClick()
|
||||
|
||||
verify { analyticsEventHandler.send(match<WalletSettingsAnalyticEvents.ButtonHardwareUpdate> { true }) }
|
||||
verify {
|
||||
router.push(
|
||||
route = AppRoute.WalletHardwareBackup(userWalletId = walletId),
|
||||
onComplete = any(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN onGoogleDriveClick THEN DialogMessage sent AND analytics sent`() = runTest {
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.uiState.value.onGoogleDriveClick()
|
||||
|
||||
verify {
|
||||
analyticsEventHandler.send(
|
||||
event = match<WalletSettingsAnalyticEvents.ButtonGoogleDriveBackup> { true }
|
||||
)
|
||||
}
|
||||
verify {
|
||||
uiMessageSender.send(
|
||||
match<DialogMessage> {
|
||||
val isTitleCorrect = it.title == resourceReference(
|
||||
id = R.string.hw_backup_google_drive_dialog_title
|
||||
)
|
||||
val isMessageCorrect = it.message == resourceReference(
|
||||
id = R.string.hw_backup_google_drive_dialog_message
|
||||
)
|
||||
isTitleCorrect && isMessageCorrect
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN onBackClick THEN router pop is called`() = runTest {
|
||||
val model = createModel(this)
|
||||
advanceUntilIdle()
|
||||
|
||||
model.uiState.value.onBackClick()
|
||||
|
||||
verify { router.pop(onComplete = any()) }
|
||||
}
|
||||
|
||||
private fun createModel(testScope: TestScope): WalletBackupModel {
|
||||
return WalletBackupModel(
|
||||
paramsContainer = paramsContainer,
|
||||
dispatchers = testScope.createTestingCoroutineDispatcherProvider(),
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
unlockHotWalletContextualUseCase = unlockHotWalletContextualUseCase,
|
||||
router = router,
|
||||
trackingContextProxy = trackingContextProxy,
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
uiMessageSender = uiMessageSender,
|
||||
)
|
||||
}
|
||||
|
||||
private fun TestScope.createTestingCoroutineDispatcherProvider(): TestingCoroutineDispatcherProvider {
|
||||
val testDispatcher = StandardTestDispatcher(testScheduler)
|
||||
return TestingCoroutineDispatcherProvider(
|
||||
main = testDispatcher,
|
||||
mainImmediate = testDispatcher,
|
||||
io = testDispatcher,
|
||||
default = testDispatcher,
|
||||
single = testDispatcher,
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue