mirror of
https://github.com/bitwarden/android.git
synced 2026-04-29 12:32:26 -05:00
Item migration flow has been moved into a graph (#6427)
This commit is contained in:
@@ -12,9 +12,11 @@ import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.browser.auth.AuthTabIntent
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
@@ -120,6 +122,8 @@ class MainActivity : AppCompatActivity() {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = RootNavigationRoute,
|
||||
modifier = Modifier
|
||||
.background(color = BitwardenTheme.colorScheme.background.primary),
|
||||
) {
|
||||
// Both root navigation and debug menu exist at this top level.
|
||||
// The debug menu can appear on top of the rest of the app without
|
||||
|
||||
@@ -70,8 +70,9 @@ import com.x8bit.bitwarden.ui.vault.feature.exportitems.exportItemsGraph
|
||||
import com.x8bit.bitwarden.ui.vault.feature.exportitems.navigateToExportItemsGraph
|
||||
import com.x8bit.bitwarden.ui.vault.feature.exportitems.verifypassword.navigateToVerifyPassword
|
||||
import com.x8bit.bitwarden.ui.vault.feature.itemlisting.navigateToVaultItemListingAsRoot
|
||||
import com.x8bit.bitwarden.ui.vault.feature.migratetomyitems.MigrateToMyItemsRoute
|
||||
import com.x8bit.bitwarden.ui.vault.feature.migratetomyitems.navigateToMigrateToMyItems
|
||||
import com.x8bit.bitwarden.ui.vault.feature.migratetomyitems.MigrateToMyItemsGraphRoute
|
||||
import com.x8bit.bitwarden.ui.vault.feature.migratetomyitems.migrateToMyItemsGraph
|
||||
import com.x8bit.bitwarden.ui.vault.feature.migratetomyitems.navigateToMigrateToMyItemsGraph
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemCipherType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemListingType
|
||||
@@ -119,6 +120,7 @@ fun RootNavScreen(
|
||||
setupAutoFillDestinationAsRoot()
|
||||
setupCompleteDestination()
|
||||
exportItemsGraph(navController)
|
||||
migrateToMyItemsGraph(navController)
|
||||
}
|
||||
|
||||
val targetRoute = when (state) {
|
||||
@@ -155,13 +157,7 @@ fun RootNavScreen(
|
||||
RootNavState.OnboardingAutoFillSetup -> SetupAutofillRoute.AsRoot
|
||||
RootNavState.OnboardingBrowserAutofillSetup -> SetupBrowserAutofillRoute.AsRoot
|
||||
RootNavState.OnboardingStepsComplete -> SetupCompleteRoute
|
||||
is RootNavState.MigrateToMyItems -> {
|
||||
val migrateState = state as RootNavState.MigrateToMyItems
|
||||
MigrateToMyItemsRoute(
|
||||
organizationId = migrateState.organizationId,
|
||||
organizationName = migrateState.organizationName,
|
||||
)
|
||||
}
|
||||
is RootNavState.MigrateToMyItems -> MigrateToMyItemsGraphRoute
|
||||
}
|
||||
val currentRoute = navController.currentDestination?.rootLevelRoute()
|
||||
|
||||
@@ -214,11 +210,7 @@ fun RootNavScreen(
|
||||
}
|
||||
|
||||
is RootNavState.MigrateToMyItems -> {
|
||||
navController.navigateToMigrateToMyItems(
|
||||
organizationName = currentState.organizationName,
|
||||
organizationId = currentState.organizationId,
|
||||
navOptions = rootNavOptions,
|
||||
)
|
||||
navController.navigateToMigrateToMyItemsGraph(rootNavOptions)
|
||||
}
|
||||
|
||||
RootNavState.RemovePassword -> navController.navigateToRemovePassword(rootNavOptions)
|
||||
@@ -354,31 +346,57 @@ private fun NavDestination?.rootLevelRoute(): String? {
|
||||
* Define the enter transition for each route.
|
||||
*/
|
||||
@Suppress("MaxLineLength")
|
||||
private fun AnimatedContentTransitionScope<NavBackStackEntry>.toEnterTransition(): NonNullEnterTransitionProvider =
|
||||
when (targetState.destination.rootLevelRoute()) {
|
||||
ResetPasswordRoute.toObjectNavigationRoute() -> RootTransitionProviders.Enter.slideUp
|
||||
else -> when (initialState.destination.rootLevelRoute()) {
|
||||
// Disable transitions when coming from the splash screen
|
||||
SplashRoute.toObjectNavigationRoute() -> RootTransitionProviders.Enter.none
|
||||
// The RESET_PASSWORD_ROUTE animation should be stay but due to an issue when combining
|
||||
// certain animations, we are just using a fadeIn instead.
|
||||
ResetPasswordRoute.toObjectNavigationRoute() -> RootTransitionProviders.Enter.fadeIn
|
||||
else -> RootTransitionProviders.Enter.fadeIn
|
||||
private fun AnimatedContentTransitionScope<NavBackStackEntry>.toEnterTransition(): NonNullEnterTransitionProvider {
|
||||
val initialRoute = initialState.destination.rootLevelRoute()
|
||||
val targetRoute = targetState.destination.rootLevelRoute()
|
||||
return if (initialRoute == targetRoute) {
|
||||
RootTransitionProviders.Enter.none
|
||||
} else {
|
||||
when (targetState.destination.rootLevelRoute()) {
|
||||
MigrateToMyItemsGraphRoute.toObjectNavigationRoute(),
|
||||
ResetPasswordRoute.toObjectNavigationRoute(),
|
||||
-> RootTransitionProviders.Enter.slideUp
|
||||
|
||||
else -> when (initialState.destination.rootLevelRoute()) {
|
||||
// Disable transitions when coming from the splash screen
|
||||
SplashRoute.toObjectNavigationRoute() -> RootTransitionProviders.Enter.none
|
||||
// The MigrateToMyItemsGraphRoute and ResetPasswordRoute animation should be stay
|
||||
// but due to an issue when combining certain animations, we are just using a
|
||||
// fadeIn instead.
|
||||
MigrateToMyItemsGraphRoute.toObjectNavigationRoute(),
|
||||
ResetPasswordRoute.toObjectNavigationRoute(),
|
||||
-> RootTransitionProviders.Enter.fadeIn
|
||||
|
||||
else -> RootTransitionProviders.Enter.fadeIn
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the exit transition for each route.
|
||||
*/
|
||||
@Suppress("MaxLineLength")
|
||||
private fun AnimatedContentTransitionScope<NavBackStackEntry>.toExitTransition(): NonNullExitTransitionProvider {
|
||||
return when (initialState.destination.rootLevelRoute()) {
|
||||
// Disable transitions when coming from the splash screen
|
||||
SplashRoute.toObjectNavigationRoute() -> RootTransitionProviders.Exit.none
|
||||
ResetPasswordRoute.toObjectNavigationRoute() -> RootTransitionProviders.Exit.slideDown
|
||||
else -> when (targetState.destination.rootLevelRoute()) {
|
||||
ResetPasswordRoute.toObjectNavigationRoute() -> RootTransitionProviders.Exit.stay
|
||||
else -> RootTransitionProviders.Exit.fadeOut
|
||||
val initialRoute = initialState.destination.rootLevelRoute()
|
||||
val targetRoute = targetState.destination.rootLevelRoute()
|
||||
return if (initialRoute == targetRoute) {
|
||||
RootTransitionProviders.Exit.none
|
||||
} else {
|
||||
when (initialRoute) {
|
||||
// Disable transitions when coming from the splash screen
|
||||
SplashRoute.toObjectNavigationRoute() -> RootTransitionProviders.Exit.none
|
||||
MigrateToMyItemsGraphRoute.toObjectNavigationRoute(),
|
||||
ResetPasswordRoute.toObjectNavigationRoute(),
|
||||
-> RootTransitionProviders.Exit.slideDown
|
||||
|
||||
else -> when (targetRoute) {
|
||||
MigrateToMyItemsGraphRoute.toObjectNavigationRoute(),
|
||||
ResetPasswordRoute.toObjectNavigationRoute(),
|
||||
-> RootTransitionProviders.Exit.stay
|
||||
|
||||
else -> RootTransitionProviders.Exit.fadeOut
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class RootNavViewModel @Inject constructor(
|
||||
vaultMigrationData = vaultMigrationData,
|
||||
)
|
||||
}
|
||||
.onEach(::handleAction)
|
||||
.onEach(::sendAction)
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
@@ -118,12 +118,7 @@ class RootNavViewModel @Inject constructor(
|
||||
|
||||
userState.activeAccount.isVaultUnlocked &&
|
||||
action.vaultMigrationData is VaultMigrationData.MigrationRequired &&
|
||||
shouldShowVaultMigration(specialCircumstance) -> {
|
||||
RootNavState.MigrateToMyItems(
|
||||
organizationId = action.vaultMigrationData.organizationId,
|
||||
organizationName = action.vaultMigrationData.organizationName,
|
||||
)
|
||||
}
|
||||
shouldShowVaultMigration(specialCircumstance) -> RootNavState.MigrateToMyItems
|
||||
|
||||
userState.activeAccount.isVaultUnlocked -> {
|
||||
when (specialCircumstance) {
|
||||
@@ -363,13 +358,10 @@ sealed class RootNavState : Parcelable {
|
||||
data object VaultLocked : RootNavState()
|
||||
|
||||
/**
|
||||
* App should show MigrateToMyItems screen.
|
||||
* App should show MigrateToMyItems graph.
|
||||
*/
|
||||
@Parcelize
|
||||
data class MigrateToMyItems(
|
||||
val organizationId: String,
|
||||
val organizationName: String,
|
||||
) : RootNavState()
|
||||
data object MigrateToMyItems : RootNavState()
|
||||
|
||||
/**
|
||||
* App should show vault unlocked nav graph for the given [activeUserId].
|
||||
|
||||
@@ -57,11 +57,8 @@ import com.x8bit.bitwarden.ui.vault.feature.importlogins.navigateToImportLoginsS
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.navigateToVaultItem
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.vaultItemDestination
|
||||
import com.x8bit.bitwarden.ui.vault.feature.itemlisting.vaultItemListingDestinationAsRoot
|
||||
import com.x8bit.bitwarden.ui.vault.feature.leaveorganization.leaveOrganizationDestination
|
||||
import com.x8bit.bitwarden.ui.vault.feature.leaveorganization.navigateToLeaveOrganization
|
||||
import com.x8bit.bitwarden.ui.vault.feature.manualcodeentry.navigateToManualCodeEntryScreen
|
||||
import com.x8bit.bitwarden.ui.vault.feature.manualcodeentry.vaultManualCodeEntryDestination
|
||||
import com.x8bit.bitwarden.ui.vault.feature.migratetomyitems.migrateToMyItemsDestination
|
||||
import com.x8bit.bitwarden.ui.vault.feature.movetoorganization.navigateToVaultMoveToOrganization
|
||||
import com.x8bit.bitwarden.ui.vault.feature.movetoorganization.vaultMoveToOrganizationDestination
|
||||
import com.x8bit.bitwarden.ui.vault.feature.qrcodescan.navigateToQrCodeScanScreen
|
||||
@@ -266,19 +263,6 @@ fun NavGraphBuilder.vaultUnlockedGraph(
|
||||
importLoginsScreenDestination(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
)
|
||||
|
||||
migrateToMyItemsDestination(
|
||||
onNavigateToLeaveOrganization = { organizationId, organizationName ->
|
||||
navController.navigateToLeaveOrganization(
|
||||
organizationId = organizationId,
|
||||
organizationName = organizationName,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
leaveOrganizationDestination(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
@file:OmitFromCoverage
|
||||
|
||||
package com.x8bit.bitwarden.ui.vault.feature.migratetomyitems
|
||||
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.navigation
|
||||
import com.bitwarden.annotation.OmitFromCoverage
|
||||
import com.x8bit.bitwarden.ui.vault.feature.leaveorganization.leaveOrganizationDestination
|
||||
import com.x8bit.bitwarden.ui.vault.feature.leaveorganization.navigateToLeaveOrganization
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* The type-safe route for the migrate to my items graph.
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
@Serializable
|
||||
data object MigrateToMyItemsGraphRoute
|
||||
|
||||
/**
|
||||
* Navigate to the migrate to my items graph.
|
||||
*/
|
||||
fun NavController.navigateToMigrateToMyItemsGraph(
|
||||
navOptions: NavOptions? = null,
|
||||
) {
|
||||
navigate(route = MigrateToMyItemsGraphRoute, navOptions = navOptions)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the migrate to my items graph to the nav graph.
|
||||
*/
|
||||
fun NavGraphBuilder.migrateToMyItemsGraph(
|
||||
navController: NavController,
|
||||
) {
|
||||
navigation<MigrateToMyItemsGraphRoute>(
|
||||
startDestination = MigrateToMyItemsRoute,
|
||||
) {
|
||||
migrateToMyItemsDestination(
|
||||
onNavigateToLeaveOrganization = { organizationId, organizationName ->
|
||||
navController.navigateToLeaveOrganization(
|
||||
organizationId = organizationId,
|
||||
organizationName = organizationName,
|
||||
)
|
||||
},
|
||||
)
|
||||
leaveOrganizationDestination(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2,69 +2,17 @@
|
||||
|
||||
package com.x8bit.bitwarden.ui.vault.feature.migratetomyitems
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.toRoute
|
||||
import androidx.navigation.compose.composable
|
||||
import com.bitwarden.annotation.OmitFromCoverage
|
||||
import com.bitwarden.ui.platform.base.util.composableWithSlideTransitions
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* The type-safe route for the migrate to my items screen.
|
||||
*
|
||||
* @property organizationId The ID of the organization requiring migration.
|
||||
* @property organizationName The name of the organization requiring migration.
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
@Serializable
|
||||
data class MigrateToMyItemsRoute(
|
||||
val organizationId: String,
|
||||
val organizationName: String,
|
||||
)
|
||||
|
||||
/**
|
||||
* Class to retrieve migrate to my items arguments from the [SavedStateHandle].
|
||||
*
|
||||
* @property organizationId The ID of the organization requiring migration.
|
||||
* @property organizationName The name of the organization requiring migration.
|
||||
*/
|
||||
data class MigrateToMyItemsArgs(
|
||||
val organizationId: String,
|
||||
val organizationName: String,
|
||||
)
|
||||
|
||||
/**
|
||||
* Constructs a [MigrateToMyItemsArgs] from the [SavedStateHandle] and internal route data.
|
||||
*/
|
||||
fun SavedStateHandle.toMigrateToMyItemsArgs(): MigrateToMyItemsArgs {
|
||||
val route = this.toRoute<MigrateToMyItemsRoute>()
|
||||
return MigrateToMyItemsArgs(
|
||||
organizationId = route.organizationId,
|
||||
organizationName = route.organizationName,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the migrate to my items screen.
|
||||
*
|
||||
* @param organizationId The ID of the organization requiring migration.
|
||||
* @param organizationName The name of the organization requiring migration.
|
||||
*/
|
||||
fun NavController.navigateToMigrateToMyItems(
|
||||
organizationId: String,
|
||||
organizationName: String,
|
||||
navOptions: NavOptions? = null,
|
||||
) {
|
||||
this.navigate(
|
||||
route = MigrateToMyItemsRoute(
|
||||
organizationId = organizationId,
|
||||
organizationName = organizationName,
|
||||
),
|
||||
navOptions = navOptions,
|
||||
)
|
||||
}
|
||||
data object MigrateToMyItemsRoute
|
||||
|
||||
/**
|
||||
* Add the migrate to my items screen to the nav graph.
|
||||
@@ -72,7 +20,7 @@ fun NavController.navigateToMigrateToMyItems(
|
||||
fun NavGraphBuilder.migrateToMyItemsDestination(
|
||||
onNavigateToLeaveOrganization: (organizationId: String, organizationName: String) -> Unit,
|
||||
) {
|
||||
composableWithSlideTransitions<MigrateToMyItemsRoute> {
|
||||
composable<MigrateToMyItemsRoute> {
|
||||
MigrateToMyItemsScreen(
|
||||
onNavigateToLeaveOrganization = onNavigateToLeaveOrganization,
|
||||
)
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.x8bit.bitwarden.data.platform.manager.event.OrganizationEventManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.OrganizationEvent
|
||||
import com.x8bit.bitwarden.data.vault.manager.VaultMigrationManager
|
||||
import com.x8bit.bitwarden.data.vault.manager.VaultSyncManager
|
||||
import com.x8bit.bitwarden.data.vault.manager.model.VaultMigrationData
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.MigratePersonalVaultResult
|
||||
import com.x8bit.bitwarden.ui.platform.model.SnackbarRelay
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@@ -43,10 +44,12 @@ class MigrateToMyItemsViewModel @Inject constructor(
|
||||
private val snackbarRelayManager: SnackbarRelayManager<SnackbarRelay>,
|
||||
) : BaseViewModel<MigrateToMyItemsState, MigrateToMyItemsEvent, MigrateToMyItemsAction>(
|
||||
initialState = savedStateHandle[KEY_STATE] ?: run {
|
||||
val args = savedStateHandle.toMigrateToMyItemsArgs()
|
||||
// This must be true or we would have never navigated here.
|
||||
val migrationData = (vaultMigrationManager.vaultMigrationDataStateFlow.value
|
||||
as VaultMigrationData.MigrationRequired)
|
||||
MigrateToMyItemsState(
|
||||
organizationId = args.organizationId,
|
||||
organizationName = args.organizationName,
|
||||
organizationId = migrationData.organizationId,
|
||||
organizationName = migrationData.organizationName,
|
||||
dialog = null,
|
||||
)
|
||||
},
|
||||
|
||||
@@ -1586,7 +1586,6 @@ class RootNavViewModelTest : BaseViewModelTest() {
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `when vaultMigrationDataStateFlow emits true the nav state should be MigrateToMyItems`() {
|
||||
mutableVaultMigrationDataStateFlow.value = MOCK_VAULT_MIGRATION_DATA
|
||||
@@ -1594,10 +1593,7 @@ class RootNavViewModelTest : BaseViewModelTest() {
|
||||
val viewModel = createViewModel()
|
||||
|
||||
assertEquals(
|
||||
RootNavState.MigrateToMyItems(
|
||||
organizationId = "mockOrganizationId-1",
|
||||
organizationName = "organizationName",
|
||||
),
|
||||
RootNavState.MigrateToMyItems,
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
@@ -1676,28 +1672,22 @@ class RootNavViewModelTest : BaseViewModelTest() {
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `when migration required with ShareNewSend shortcut should show migration screen`() {
|
||||
specialCircumstanceManager.specialCircumstance =
|
||||
SpecialCircumstance.ShareNewSend(
|
||||
data = mockk<ShareData.TextSend>(),
|
||||
shouldFinishWhenComplete = true,
|
||||
)
|
||||
specialCircumstanceManager.specialCircumstance = SpecialCircumstance.ShareNewSend(
|
||||
data = mockk<ShareData.TextSend>(),
|
||||
shouldFinishWhenComplete = true,
|
||||
)
|
||||
mutableVaultMigrationDataStateFlow.value = MOCK_VAULT_MIGRATION_DATA
|
||||
mutableUserStateFlow.tryEmit(MOCK_VAULT_UNLOCKED_USER_STATE)
|
||||
val viewModel = createViewModel()
|
||||
|
||||
assertEquals(
|
||||
RootNavState.MigrateToMyItems(
|
||||
organizationId = "mockOrganizationId-1",
|
||||
organizationName = "organizationName",
|
||||
),
|
||||
RootNavState.MigrateToMyItems,
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `when migration required with VaultShortcut should show migration screen`() {
|
||||
specialCircumstanceManager.specialCircumstance = SpecialCircumstance.VaultShortcut
|
||||
@@ -1706,10 +1696,7 @@ class RootNavViewModelTest : BaseViewModelTest() {
|
||||
val viewModel = createViewModel()
|
||||
|
||||
assertEquals(
|
||||
RootNavState.MigrateToMyItems(
|
||||
organizationId = "mockOrganizationId-1",
|
||||
organizationName = "organizationName",
|
||||
),
|
||||
RootNavState.MigrateToMyItems,
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.x8bit.bitwarden.data.platform.manager.event.OrganizationEventManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.OrganizationEvent
|
||||
import com.x8bit.bitwarden.data.vault.manager.VaultMigrationManager
|
||||
import com.x8bit.bitwarden.data.vault.manager.VaultSyncManager
|
||||
import com.x8bit.bitwarden.data.vault.manager.model.VaultMigrationData
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.MigratePersonalVaultResult
|
||||
import com.x8bit.bitwarden.ui.platform.model.SnackbarRelay
|
||||
import io.mockk.coEvery
|
||||
@@ -22,10 +23,8 @@ import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkConstructor
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.runs
|
||||
import io.mockk.unmockkConstructor
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -45,10 +44,15 @@ class MigrateToMyItemsViewModelTest : BaseViewModelTest() {
|
||||
every { activeUserId } returns "test-user-id"
|
||||
},
|
||||
)
|
||||
private val mutableVaultMigrationDataStateFlow = MutableStateFlow<VaultMigrationData>(
|
||||
VaultMigrationData.MigrationRequired(
|
||||
organizationId = ORGANIZATION_ID,
|
||||
organizationName = ORGANIZATION_NAME,
|
||||
),
|
||||
)
|
||||
private val mockVaultMigrationManager: VaultMigrationManager = mockk {
|
||||
coEvery {
|
||||
migratePersonalVault(any(), any())
|
||||
} returns MigratePersonalVaultResult.Success
|
||||
coEvery { vaultMigrationDataStateFlow } returns mutableVaultMigrationDataStateFlow
|
||||
coEvery { migratePersonalVault(any(), any()) } returns MigratePersonalVaultResult.Success
|
||||
every { clearMigrationState() } just runs
|
||||
}
|
||||
private val mockVaultSyncManager: VaultSyncManager = mockk(relaxed = true)
|
||||
@@ -62,7 +66,6 @@ class MigrateToMyItemsViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(SavedStateHandle::toMigrateToMyItemsArgs)
|
||||
mockkConstructor(NoActiveUserException::class)
|
||||
every {
|
||||
anyConstructed<NoActiveUserException>() == any<NoActiveUserException>()
|
||||
@@ -71,7 +74,6 @@ class MigrateToMyItemsViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
unmockkStatic(SavedStateHandle::toMigrateToMyItemsArgs)
|
||||
unmockkConstructor(NoActiveUserException::class)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user