BIT-1304: Options menu UI for view item (#580)

This commit is contained in:
Ramsey Smith
2024-01-12 11:05:50 -07:00
committed by GitHub
parent cdb80095a6
commit c5a3340ac5
5 changed files with 270 additions and 9 deletions

View File

@@ -1,15 +1,18 @@
package com.x8bit.bitwarden.ui.vault.feature.item
import androidx.compose.ui.test.assert
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsEnabled
import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.assertTextContains
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.filter
import androidx.compose.ui.test.filterToOne
import androidx.compose.ui.test.hasAnyAncestor
import androidx.compose.ui.test.hasContentDescription
import androidx.compose.ui.test.isDialog
import androidx.compose.ui.test.isPopup
import androidx.compose.ui.test.onAllNodesWithContentDescription
import androidx.compose.ui.test.onAllNodesWithText
import androidx.compose.ui.test.onChildren
@@ -64,16 +67,17 @@ class VaultItemScreenTest : BaseComposeTest() {
VaultItemScreen(
viewModel = viewModel,
onNavigateBack = { onNavigateBackCalled = true },
onNavigateToVaultEditItem = { onNavigateToVaultEditItemId = it },
onNavigateToVaultAddEditItem = { onNavigateToVaultEditItemId = it },
intentHandler = intentHandler,
)
}
}
//region common
@Test
fun `NavigateToEdit event should invoke onNavigateToVaultEditItem`() {
val id = "id1234"
mutableEventFlow.tryEmit(VaultItemEvent.NavigateToEdit(id))
mutableEventFlow.tryEmit(VaultItemEvent.NavigateToAddEdit(itemId = id, isClone = false))
assertEquals(id, onNavigateToVaultEditItemId)
}
@@ -544,6 +548,84 @@ class VaultItemScreenTest : BaseComposeTest() {
.assertDoesNotExist()
}
@Test
fun `Delete option menu click should send DeleteClick action`() {
// Confirm dropdown version of item is absent
composeTestRule
.onAllNodesWithText("Delete")
.filter(hasAnyAncestor(isPopup()))
.assertCountEquals(0)
// Open the overflow menu
composeTestRule.onNodeWithContentDescription("More").performClick()
// Click on the delete item in the dropdown
composeTestRule
.onAllNodesWithText("Delete")
.filterToOne(hasAnyAncestor(isPopup()))
.performClick()
verify {
viewModel.trySendAction(VaultItemAction.Common.DeleteClick)
}
}
@Test
fun `Attachments option menu click should send AttachmentsClick action`() {
// Confirm dropdown version of item is absent
composeTestRule
.onAllNodesWithText("Attachments")
.filter(hasAnyAncestor(isPopup()))
.assertCountEquals(0)
// Open the overflow menu
composeTestRule.onNodeWithContentDescription("More").performClick()
// Click on the attachments hint item in the dropdown
composeTestRule
.onAllNodesWithText("Attachments")
.filterToOne(hasAnyAncestor(isPopup()))
.performClick()
verify {
viewModel.trySendAction(VaultItemAction.Common.AttachmentsClick)
}
}
@Test
fun `Clone option menu click should send CloneClick action`() {
// Confirm dropdown version of item is absent
composeTestRule
.onAllNodesWithText("Clone")
.filter(hasAnyAncestor(isPopup()))
.assertCountEquals(0)
// Open the overflow menu
composeTestRule.onNodeWithContentDescription("More").performClick()
// Click on the clone item in the dropdown
composeTestRule
.onAllNodesWithText("Clone")
.filterToOne(hasAnyAncestor(isPopup()))
.performClick()
verify {
viewModel.trySendAction(VaultItemAction.Common.CloneClick)
}
}
@Test
fun `Move to organization option menu click should send MoveToOrganizationClick action`() {
// Confirm dropdown version of item is absent
composeTestRule
.onAllNodesWithText("Move to Organization")
.filter(hasAnyAncestor(isPopup()))
.assertCountEquals(0)
// Open the overflow menu
composeTestRule.onNodeWithContentDescription("More").performClick()
// Click on the move to organization hint item in the dropdown
composeTestRule
.onAllNodesWithText("Move to Organization")
.filterToOne(hasAnyAncestor(isPopup()))
.performClick()
verify {
viewModel.trySendAction(VaultItemAction.Common.MoveToOrganizationClick)
}
}
//endregion common
//region login
@Test
fun `in login state, linked custom fields should be displayed according to state`() {
val linkedFieldUserName =
@@ -947,7 +1029,9 @@ class VaultItemScreenTest : BaseComposeTest() {
composeTestRule.assertScrollableNodeDoesNotExist("Password history: ")
composeTestRule.assertScrollableNodeDoesNotExist("1")
}
//endregion login
//region identity
@Test
fun `in identity state, identityName should be displayed according to state`() {
val identityName = "the identity name"
@@ -1064,6 +1148,7 @@ class VaultItemScreenTest : BaseComposeTest() {
composeTestRule.assertScrollableNodeDoesNotExist(identityName)
}
//endregion identity
@Test
fun `in card state, cardholderName should be displayed according to state`() {

View File

@@ -149,7 +149,13 @@ class VaultItemViewModelTest : BaseViewModelTest() {
viewModel.eventFlow.test {
viewModel.trySendAction(VaultItemAction.Common.EditClick)
assertEquals(VaultItemEvent.NavigateToEdit(VAULT_ITEM_ID), awaitItem())
assertEquals(
VaultItemEvent.NavigateToAddEdit(
itemId = VAULT_ITEM_ID,
isClone = false,
),
awaitItem(),
)
}
}
@@ -327,6 +333,57 @@ class VaultItemViewModelTest : BaseViewModelTest() {
mockCipherView.toViewState(isPremiumUser = true)
}
}
@Test
fun `on DeleteClick should emit ShowToast`() = runTest {
val viewModel = createViewModel(state = DEFAULT_STATE)
viewModel.eventFlow.test {
viewModel.trySendAction(VaultItemAction.Common.DeleteClick)
assertEquals(
VaultItemEvent.ShowToast("Not yet implemented.".asText()),
awaitItem(),
)
}
}
@Test
fun `on AttachmentsClick should emit NavigateToAttachments`() = runTest {
val viewModel = createViewModel(state = DEFAULT_STATE)
viewModel.eventFlow.test {
viewModel.trySendAction(VaultItemAction.Common.AttachmentsClick)
assertEquals(
VaultItemEvent.NavigateToAttachments(itemId = VAULT_ITEM_ID),
awaitItem(),
)
}
}
@Test
fun `on CloneClick should emit NavigateToAddEdit with isClone set to true`() = runTest {
val viewModel = createViewModel(state = DEFAULT_STATE)
viewModel.eventFlow.test {
viewModel.trySendAction(VaultItemAction.Common.CloneClick)
assertEquals(
VaultItemEvent.NavigateToAddEdit(
itemId = VAULT_ITEM_ID,
isClone = true,
),
awaitItem(),
)
}
}
@Test
fun `on MoveToOrganizationClick should emit NavigateToMoveToOrganization`() = runTest {
val viewModel = createViewModel(state = DEFAULT_STATE)
viewModel.eventFlow.test {
viewModel.trySendAction(VaultItemAction.Common.MoveToOrganizationClick)
assertEquals(
VaultItemEvent.NavigateToMoveToOrganization(itemId = VAULT_ITEM_ID),
awaitItem(),
)
}
}
}
@Nested