mirror of
https://github.com/bitwarden/android.git
synced 2025-02-17 04:19:54 +03:00
BIT-965: Navigation for vault item listing screen (#336)
This commit is contained in:
parent
1560241a13
commit
b4df58d630
12 changed files with 356 additions and 91 deletions
|
@ -31,6 +31,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.compose.NavHost
|
||||
|
@ -53,9 +54,9 @@ import com.x8bit.bitwarden.ui.tools.feature.generator.navigateToGenerator
|
|||
import com.x8bit.bitwarden.ui.tools.feature.send.SEND_GRAPH_ROUTE
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.navigateToSend
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.sendGraph
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.VAULT_ROUTE
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.navigateToVault
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.vaultDestination
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.VAULT_GRAPH_ROUTE
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.navigateToVaultGraph
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.vaultGraph
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
|
@ -76,7 +77,7 @@ fun VaultUnlockedNavBarScreen(
|
|||
val navOptions = vaultUnlockedNavBarScreenNavOptions()
|
||||
when (event) {
|
||||
VaultUnlockedNavBarEvent.NavigateToVaultScreen -> {
|
||||
navigateToVault(navOptions)
|
||||
navigateToVaultGraph(navOptions)
|
||||
}
|
||||
|
||||
VaultUnlockedNavBarEvent.NavigateToSendScreen -> {
|
||||
|
@ -170,7 +171,7 @@ private fun VaultUnlockedNavBarScaffold(
|
|||
// - consume the IME insets.
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = VAULT_ROUTE,
|
||||
startDestination = VAULT_GRAPH_ROUTE,
|
||||
modifier = Modifier
|
||||
.consumeWindowInsets(WindowInsets.navigationBars)
|
||||
.consumeWindowInsets(WindowInsets.ime)
|
||||
|
@ -180,10 +181,9 @@ private fun VaultUnlockedNavBarScaffold(
|
|||
popEnterTransition = RootTransitionProviders.Enter.fadeIn,
|
||||
popExitTransition = RootTransitionProviders.Exit.fadeOut,
|
||||
) {
|
||||
vaultDestination(
|
||||
onNavigateToVaultAddItemScreen = {
|
||||
navigateToVaultAddItem()
|
||||
},
|
||||
vaultGraph(
|
||||
navController = navController,
|
||||
onNavigateToVaultAddItemScreen = navigateToVaultAddItem,
|
||||
onNavigateToVaultItemScreen = onNavigateToVaultItem,
|
||||
onNavigateToVaultEditItemScreen = onNavigateToVaultEditItem,
|
||||
onDimBottomNavBarRequest = { shouldDim ->
|
||||
|
@ -339,7 +339,7 @@ private sealed class VaultUnlockedNavBarTab : Parcelable {
|
|||
override val iconRes get() = R.drawable.ic_vault
|
||||
override val labelRes get() = R.string.my_vault
|
||||
override val contentDescriptionRes get() = R.string.my_vault
|
||||
override val route get() = VAULT_ROUTE
|
||||
override val route get() = VAULT_GRAPH_ROUTE
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,7 +360,7 @@ private sealed class VaultUnlockedNavBarTab : Parcelable {
|
|||
*/
|
||||
private fun NavController.vaultUnlockedNavBarScreenNavOptions(): NavOptions =
|
||||
navOptions {
|
||||
popUpTo(graph.startDestinationId) {
|
||||
popUpTo(graph.findStartDestination().id) {
|
||||
saveState = true
|
||||
}
|
||||
launchSingleTop = true
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
package com.x8bit.bitwarden.ui.vault.feature.itemlisting
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.navArgument
|
||||
import com.x8bit.bitwarden.ui.platform.theme.TransitionProviders
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemListingType
|
||||
|
||||
private const val CARD: String = "card"
|
||||
private const val FOLDER: String = "folder"
|
||||
private const val IDENTITY: String = "identity"
|
||||
private const val LOGIN: String = "login"
|
||||
private const val SECURE_NOTE: String = "secure_note"
|
||||
private const val TRASH: String = "trash"
|
||||
private const val VAULT_ITEM_LISTING_PREFIX: String = "vault_item_listing"
|
||||
private const val VAULT_ITEM_LISTING_TYPE: String = "vault_item_listing_type"
|
||||
private const val ID: String = "id"
|
||||
private const val VAULT_ITEM_LISTING_ROUTE: String =
|
||||
"$VAULT_ITEM_LISTING_PREFIX/{$VAULT_ITEM_LISTING_TYPE}" +
|
||||
"?$ID={$ID}"
|
||||
|
||||
/**
|
||||
* Class to retrieve vault item listing arguments from the [SavedStateHandle].
|
||||
*/
|
||||
class VaultItemListingArgs(
|
||||
val vaultItemListingType: VaultItemListingType,
|
||||
) {
|
||||
constructor(savedStateHandle: SavedStateHandle) : this(
|
||||
vaultItemListingType = determineVaultItemListingType(
|
||||
vaultItemListingTypeString = checkNotNull(
|
||||
savedStateHandle[VAULT_ITEM_LISTING_TYPE],
|
||||
) as String,
|
||||
id = savedStateHandle[ID],
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the [VaultItemListingScreen] to the nav graph.
|
||||
*/
|
||||
fun NavGraphBuilder.vaultItemListingDestination(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToVaultItemScreen: (id: String) -> Unit,
|
||||
onNavigateToVaultAddItemScreen: () -> Unit,
|
||||
) {
|
||||
composable(
|
||||
route = VAULT_ITEM_LISTING_ROUTE,
|
||||
arguments = listOf(
|
||||
navArgument(
|
||||
name = VAULT_ITEM_LISTING_TYPE,
|
||||
builder = { type = NavType.StringType },
|
||||
),
|
||||
navArgument(
|
||||
name = ID,
|
||||
builder = {
|
||||
type = NavType.StringType
|
||||
nullable = true
|
||||
},
|
||||
),
|
||||
),
|
||||
enterTransition = TransitionProviders.Enter.pushLeft,
|
||||
exitTransition = TransitionProviders.Exit.pushLeft,
|
||||
popEnterTransition = TransitionProviders.Enter.pushLeft,
|
||||
popExitTransition = TransitionProviders.Exit.pushRight,
|
||||
) {
|
||||
VaultItemListingScreen(
|
||||
onNavigateBack = onNavigateBack,
|
||||
onNavigateToVaultItem = onNavigateToVaultItemScreen,
|
||||
onNavigateToVaultAddItemScreen = onNavigateToVaultAddItemScreen,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the [VaultItemListingScreen].
|
||||
*/
|
||||
fun NavController.navigateToVaultItemListing(
|
||||
vaultItemListingType: VaultItemListingType,
|
||||
navOptions: NavOptions? = null,
|
||||
) {
|
||||
navigate(
|
||||
route = "$VAULT_ITEM_LISTING_PREFIX/${vaultItemListingType.toTypeString()}" +
|
||||
"?$ID=${vaultItemListingType.toIdOrNull()}",
|
||||
navOptions = navOptions,
|
||||
)
|
||||
}
|
||||
|
||||
private fun VaultItemListingType.toTypeString(): String {
|
||||
return when (this) {
|
||||
is VaultItemListingType.Card -> CARD
|
||||
is VaultItemListingType.Folder -> FOLDER
|
||||
is VaultItemListingType.Identity -> IDENTITY
|
||||
is VaultItemListingType.Login -> LOGIN
|
||||
is VaultItemListingType.SecureNote -> SECURE_NOTE
|
||||
is VaultItemListingType.Trash -> TRASH
|
||||
}
|
||||
}
|
||||
|
||||
private fun VaultItemListingType.toIdOrNull(): String? =
|
||||
when (this) {
|
||||
is VaultItemListingType.Folder -> folderId
|
||||
is VaultItemListingType.Card -> null
|
||||
is VaultItemListingType.Identity -> null
|
||||
is VaultItemListingType.Login -> null
|
||||
is VaultItemListingType.SecureNote -> null
|
||||
is VaultItemListingType.Trash -> null
|
||||
}
|
||||
|
||||
private fun determineVaultItemListingType(
|
||||
vaultItemListingTypeString: String,
|
||||
id: String?,
|
||||
): VaultItemListingType {
|
||||
return when (vaultItemListingTypeString) {
|
||||
LOGIN -> VaultItemListingType.Login
|
||||
CARD -> VaultItemListingType.Card
|
||||
IDENTITY -> VaultItemListingType.Identity
|
||||
SECURE_NOTE -> VaultItemListingType.SecureNote
|
||||
TRASH -> VaultItemListingType.Trash
|
||||
FOLDER -> VaultItemListingType.Folder(folderId = id)
|
||||
// This should never occur, vaultItemListingTypeString must match
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.x8bit.bitwarden.ui.vault.feature.itemlisting
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
||||
/**
|
||||
* Displays the vault item listing screen.
|
||||
*/
|
||||
@Composable
|
||||
fun VaultItemListingScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToVaultItem: (id: String) -> Unit,
|
||||
onNavigateToVaultAddItemScreen: () -> Unit,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(text = "Listing Screen")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.x8bit.bitwarden.ui.vault.feature.vault
|
||||
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.navigation
|
||||
import com.x8bit.bitwarden.ui.vault.feature.itemlisting.navigateToVaultItemListing
|
||||
import com.x8bit.bitwarden.ui.vault.feature.itemlisting.vaultItemListingDestination
|
||||
|
||||
const val VAULT_GRAPH_ROUTE: String = "vault_graph"
|
||||
|
||||
/**
|
||||
* Add vault destinations to the nav graph.
|
||||
*/
|
||||
fun NavGraphBuilder.vaultGraph(
|
||||
navController: NavController,
|
||||
onNavigateToVaultAddItemScreen: () -> Unit,
|
||||
onNavigateToVaultItemScreen: (vaultItemId: String) -> Unit,
|
||||
onNavigateToVaultEditItemScreen: (vaultItemId: String) -> Unit,
|
||||
onDimBottomNavBarRequest: (shouldDim: Boolean) -> Unit,
|
||||
) {
|
||||
navigation(
|
||||
route = VAULT_GRAPH_ROUTE,
|
||||
startDestination = VAULT_ROUTE,
|
||||
) {
|
||||
vaultDestination(
|
||||
onNavigateToVaultAddItemScreen = onNavigateToVaultAddItemScreen,
|
||||
onNavigateToVaultItemScreen = onNavigateToVaultItemScreen,
|
||||
onNavigateToVaultEditItemScreen = onNavigateToVaultEditItemScreen,
|
||||
onNavigateToVaultItemListingScreen = { navController.navigateToVaultItemListing(it) },
|
||||
onDimBottomNavBarRequest = onDimBottomNavBarRequest,
|
||||
)
|
||||
vaultItemListingDestination(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateToVaultItemScreen = onNavigateToVaultItemScreen,
|
||||
onNavigateToVaultAddItemScreen = onNavigateToVaultAddItemScreen,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the vault graph.
|
||||
*/
|
||||
fun NavController.navigateToVaultGraph(navOptions: NavOptions? = null) {
|
||||
navigate(VAULT_GRAPH_ROUTE, navOptions)
|
||||
}
|
|
@ -4,6 +4,8 @@ import androidx.navigation.NavController
|
|||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.compose.composable
|
||||
import com.x8bit.bitwarden.ui.platform.theme.TransitionProviders
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemListingType
|
||||
|
||||
const val VAULT_ROUTE: String = "vault"
|
||||
|
||||
|
@ -14,13 +16,21 @@ fun NavGraphBuilder.vaultDestination(
|
|||
onNavigateToVaultAddItemScreen: () -> Unit,
|
||||
onNavigateToVaultItemScreen: (vaultItemId: String) -> Unit,
|
||||
onNavigateToVaultEditItemScreen: (vaultItemId: String) -> Unit,
|
||||
onNavigateToVaultItemListingScreen: (vaultItemType: VaultItemListingType) -> Unit,
|
||||
onDimBottomNavBarRequest: (shouldDim: Boolean) -> Unit,
|
||||
) {
|
||||
composable(VAULT_ROUTE) {
|
||||
composable(
|
||||
route = VAULT_ROUTE,
|
||||
enterTransition = TransitionProviders.Enter.stay,
|
||||
exitTransition = TransitionProviders.Exit.pushLeft,
|
||||
popEnterTransition = TransitionProviders.Enter.pushRight,
|
||||
popExitTransition = TransitionProviders.Exit.fadeOut,
|
||||
) {
|
||||
VaultScreen(
|
||||
onNavigateToVaultAddItemScreen = onNavigateToVaultAddItemScreen,
|
||||
onNavigateToVaultItemScreen = onNavigateToVaultItemScreen,
|
||||
onNavigateToVaultEditItemScreen = onNavigateToVaultEditItemScreen,
|
||||
onNavigateToVaultItemListingScreen = onNavigateToVaultItemListingScreen,
|
||||
onDimBottomNavBarRequest = onDimBottomNavBarRequest,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowActionItem
|
|||
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenSearchActionItem
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemListingType
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
/**
|
||||
|
@ -47,6 +48,7 @@ fun VaultScreen(
|
|||
onNavigateToVaultAddItemScreen: () -> Unit,
|
||||
onNavigateToVaultItemScreen: (vaultItemId: String) -> Unit,
|
||||
onNavigateToVaultEditItemScreen: (vaultItemId: String) -> Unit,
|
||||
onNavigateToVaultItemListingScreen: (vaultItemType: VaultItemListingType) -> Unit,
|
||||
onDimBottomNavBarRequest: (shouldDim: Boolean) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
@ -65,40 +67,8 @@ fun VaultScreen(
|
|||
|
||||
is VaultEvent.NavigateToEditVaultItem -> onNavigateToVaultEditItemScreen(event.itemId)
|
||||
|
||||
VaultEvent.NavigateToCardGroup -> {
|
||||
Toast
|
||||
.makeText(context, "Navigate to card type screen.", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
is VaultEvent.NavigateToFolder -> {
|
||||
Toast
|
||||
.makeText(context, "Navigate to folder screen.", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
VaultEvent.NavigateToIdentityGroup -> {
|
||||
Toast
|
||||
.makeText(context, "Navigate to identity type screen.", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
VaultEvent.NavigateToLoginGroup -> {
|
||||
Toast
|
||||
.makeText(context, "Navigate to login type screen.", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
VaultEvent.NavigateToSecureNotesGroup -> {
|
||||
Toast
|
||||
.makeText(context, "Navigate to secure notes type screen.", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
||||
VaultEvent.NavigateToTrash -> {
|
||||
Toast
|
||||
.makeText(context, "Navigate to trash screen.", Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
is VaultEvent.NavigateToItemListing -> {
|
||||
onNavigateToVaultItemListingScreen(event.itemListingType)
|
||||
}
|
||||
|
||||
is VaultEvent.ShowToast -> {
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.x8bit.bitwarden.ui.vault.feature.vault.util.initials
|
|||
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toAccountSummaries
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toActiveAccountSummary
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toViewState
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemListingType
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
@ -102,19 +103,25 @@ class VaultViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleCardClick() {
|
||||
sendEvent(VaultEvent.NavigateToCardGroup)
|
||||
sendEvent(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.Card),
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleFolderItemClick(action: VaultAction.FolderClick) {
|
||||
sendEvent(VaultEvent.NavigateToFolder(action.folderItem.id))
|
||||
sendEvent(
|
||||
VaultEvent.NavigateToItemListing(
|
||||
VaultItemListingType.Folder(action.folderItem.id),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleIdentityClick() {
|
||||
sendEvent(VaultEvent.NavigateToIdentityGroup)
|
||||
sendEvent(VaultEvent.NavigateToItemListing(VaultItemListingType.Identity))
|
||||
}
|
||||
|
||||
private fun handleLoginClick() {
|
||||
sendEvent(VaultEvent.NavigateToLoginGroup)
|
||||
sendEvent(VaultEvent.NavigateToItemListing(VaultItemListingType.Login))
|
||||
}
|
||||
|
||||
private fun handleSearchIconClick() {
|
||||
|
@ -137,11 +144,11 @@ class VaultViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleTrashClick() {
|
||||
sendEvent(VaultEvent.NavigateToTrash)
|
||||
sendEvent(VaultEvent.NavigateToItemListing(VaultItemListingType.Trash))
|
||||
}
|
||||
|
||||
private fun handleSecureNoteClick() {
|
||||
sendEvent(VaultEvent.NavigateToSecureNotesGroup)
|
||||
sendEvent(VaultEvent.NavigateToItemListing(VaultItemListingType.SecureNote))
|
||||
}
|
||||
|
||||
private fun handleVaultItemClick(action: VaultAction.VaultItemClick) {
|
||||
|
@ -427,37 +434,12 @@ sealed class VaultEvent {
|
|||
) : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the card group screen.
|
||||
* Navigate to the item listing screen.
|
||||
*/
|
||||
data object NavigateToCardGroup : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the folder screen.
|
||||
*/
|
||||
data class NavigateToFolder(
|
||||
val folderId: String?,
|
||||
data class NavigateToItemListing(
|
||||
val itemListingType: VaultItemListingType,
|
||||
) : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the identity group screen.
|
||||
*/
|
||||
data object NavigateToIdentityGroup : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the login group screen.
|
||||
*/
|
||||
data object NavigateToLoginGroup : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the trash screen.
|
||||
*/
|
||||
data object NavigateToTrash : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the secure notes group screen.
|
||||
*/
|
||||
data object NavigateToSecureNotesGroup : VaultEvent()
|
||||
|
||||
/**
|
||||
* Show a toast with the given [message].
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package com.x8bit.bitwarden.ui.vault.model
|
||||
|
||||
/**
|
||||
* Represents different types of listing that can be viewed.
|
||||
*/
|
||||
sealed class VaultItemListingType {
|
||||
|
||||
/**
|
||||
* A Login listing.
|
||||
*/
|
||||
data object Login : VaultItemListingType()
|
||||
|
||||
/**
|
||||
* An Identity listing.
|
||||
*/
|
||||
data object Identity : VaultItemListingType()
|
||||
|
||||
/**
|
||||
* A Secure Note listing.
|
||||
*/
|
||||
data object SecureNote : VaultItemListingType()
|
||||
|
||||
/**
|
||||
* A Card listing.
|
||||
*/
|
||||
data object Card : VaultItemListingType()
|
||||
|
||||
/**
|
||||
* A Trash listing.
|
||||
*/
|
||||
data object Trash : VaultItemListingType()
|
||||
|
||||
/**
|
||||
* A Folder listing.
|
||||
*
|
||||
* @param folderId the id of the folder, a null value indicates a, "no folder" grouping.
|
||||
*/
|
||||
data class Folder(val folderId: String?) : VaultItemListingType()
|
||||
}
|
|
@ -69,6 +69,9 @@ class FakeNavHostController : NavHostController(context = mockk()) {
|
|||
mockk<NavGraph>().apply {
|
||||
every { id } returns graphId
|
||||
every { startDestinationId } returns graphId
|
||||
every {
|
||||
findNode(graphId)
|
||||
} returns mockk { every { id } returns graphId }
|
||||
}
|
||||
|
||||
override var graph: NavGraph
|
||||
|
|
|
@ -64,11 +64,11 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
|||
onNavigateToDeleteAccount = {},
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault_graph") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToVaultScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
route = "vault",
|
||||
route = "vault_graph",
|
||||
navOptions = expectedNavOptions,
|
||||
)
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
|||
onNavigateToDeleteAccount = {},
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault_graph") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToSendScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
|
@ -166,7 +166,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
|||
onNavigateToDeleteAccount = {},
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault_graph") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToGeneratorScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
|
@ -217,7 +217,7 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
|||
onNavigateToDeleteAccount = {},
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault_graph") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToSettingsScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
|
|
|
@ -13,6 +13,7 @@ import androidx.compose.ui.test.performScrollToNode
|
|||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemListingType
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
|
@ -31,6 +32,7 @@ class VaultScreenTest : BaseComposeTest() {
|
|||
private var onNavigateToVaultAddItemScreenCalled = false
|
||||
private var onNavigateToVaultItemId: String? = null
|
||||
private var onNavigateToVaultEditItemId: String? = null
|
||||
private var onNavigateToVaultItemListingType: VaultItemListingType? = null
|
||||
private var onDimBottomNavBarRequestCalled = false
|
||||
|
||||
private val mutableEventFlow = MutableSharedFlow<VaultEvent>(
|
||||
|
@ -50,6 +52,7 @@ class VaultScreenTest : BaseComposeTest() {
|
|||
onNavigateToVaultAddItemScreen = { onNavigateToVaultAddItemScreenCalled = true },
|
||||
onNavigateToVaultItemScreen = { onNavigateToVaultItemId = it },
|
||||
onNavigateToVaultEditItemScreen = { onNavigateToVaultEditItemId = it },
|
||||
onNavigateToVaultItemListingScreen = { onNavigateToVaultItemListingType = it },
|
||||
onDimBottomNavBarRequest = { onDimBottomNavBarRequestCalled = true },
|
||||
)
|
||||
}
|
||||
|
@ -134,6 +137,45 @@ class VaultScreenTest : BaseComposeTest() {
|
|||
assertEquals(id, onNavigateToVaultEditItemId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateNavigateToCardGroup event should call onNavigateToVaultItemListingType`() {
|
||||
mutableEventFlow.tryEmit(VaultEvent.NavigateToItemListing(VaultItemListingType.Card))
|
||||
assertEquals(VaultItemListingType.Card, onNavigateToVaultItemListingType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToIdentityGroup event should call onNavigateToVaultItemListingType`() {
|
||||
mutableEventFlow.tryEmit(VaultEvent.NavigateToItemListing(VaultItemListingType.Identity))
|
||||
assertEquals(VaultItemListingType.Identity, onNavigateToVaultItemListingType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToLoginGroup event should call onNavigateToVaultItemListingType`() {
|
||||
mutableEventFlow.tryEmit(VaultEvent.NavigateToItemListing(VaultItemListingType.Login))
|
||||
assertEquals(VaultItemListingType.Login, onNavigateToVaultItemListingType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToSecureNotesGroup event should call onNavigateToVaultItemListingType`() {
|
||||
mutableEventFlow.tryEmit(VaultEvent.NavigateToItemListing(VaultItemListingType.SecureNote))
|
||||
assertEquals(VaultItemListingType.SecureNote, onNavigateToVaultItemListingType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToTrash event should call onNavigateToVaultItemListingType`() {
|
||||
mutableEventFlow.tryEmit(VaultEvent.NavigateToItemListing(VaultItemListingType.Trash))
|
||||
assertEquals(VaultItemListingType.Trash, onNavigateToVaultItemListingType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToFolder event should call onNavigateToVaultItemListingType`() {
|
||||
val mockFolderId = "mockFolderId"
|
||||
mutableEventFlow.tryEmit(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.Folder(mockFolderId)),
|
||||
)
|
||||
assertEquals(VaultItemListingType.Folder(mockFolderId), onNavigateToVaultItemListingType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking a favorite item should send VaultItemClick with the correct item`() {
|
||||
val itemText = "Test Item"
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.VaultData
|
|||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultItemListingType
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
|
@ -345,7 +346,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.CardGroupClick)
|
||||
assertEquals(VaultEvent.NavigateToCardGroup, awaitItem())
|
||||
assertEquals(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.Card),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +362,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.FolderClick(folder))
|
||||
assertEquals(VaultEvent.NavigateToFolder(folderId), awaitItem())
|
||||
assertEquals(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.Folder(folderId)),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,7 +374,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.IdentityGroupClick)
|
||||
assertEquals(VaultEvent.NavigateToIdentityGroup, awaitItem())
|
||||
assertEquals(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.Identity),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,7 +386,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.LoginGroupClick)
|
||||
assertEquals(VaultEvent.NavigateToLoginGroup, awaitItem())
|
||||
assertEquals(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.Login),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +407,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.SecureNoteGroupClick)
|
||||
assertEquals(VaultEvent.NavigateToSecureNotesGroup, awaitItem())
|
||||
assertEquals(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.SecureNote),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -403,7 +419,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.TrashClick)
|
||||
assertEquals(VaultEvent.NavigateToTrash, awaitItem())
|
||||
assertEquals(
|
||||
VaultEvent.NavigateToItemListing(VaultItemListingType.Trash),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue