mirror of
https://github.com/bitwarden/android.git
synced 2026-06-01 18:26:31 -05:00
BIT-509: Adding the Ability to Save a SecureNote Item (#347)
This commit is contained in:
@@ -34,11 +34,8 @@ import org.junit.Test
|
||||
|
||||
@Suppress("LargeClass")
|
||||
class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
private val mutableStateFlow = MutableStateFlow(
|
||||
VaultAddItemState(
|
||||
selectedType = VaultAddItemState.ItemType.Login(),
|
||||
),
|
||||
)
|
||||
|
||||
private val mutableStateFlow = MutableStateFlow(DEFAULT_STATE_LOGIN)
|
||||
|
||||
private val viewModel = mockk<VaultAddItemViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns emptyFlow()
|
||||
@@ -623,8 +620,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state changing Name text field should trigger NameTextChange`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -643,8 +639,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the name control should display the text provided by the state`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -665,8 +660,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking a Folder Option should send FolderChange action`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -694,8 +688,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the folder control should display the text provided by the state`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -717,8 +710,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state, toggling the favorite toggle should send ToggleFavorite action`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -740,8 +732,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the favorite toggle should be enabled or disabled according to state`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -763,8 +754,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state, toggling the Master password re-prompt toggle should send ToggleMasterPasswordReprompt action`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -788,8 +778,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the master password re-prompt toggle should be enabled or disabled according to state`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -811,8 +800,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state, toggling the Master password re-prompt tooltip button should send TooltipClick action`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -831,8 +819,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state changing Notes text field should trigger NotesTextChange`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -853,8 +840,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the Notes control should display the text provided by the state`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -878,8 +864,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should trigger AddNewCustomFieldClick`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -899,8 +884,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking a Ownership option should send OwnershipChange action`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -928,8 +912,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes the Ownership control should display the text provided by the state`() {
|
||||
mutableStateFlow.value =
|
||||
VaultAddItemState(selectedType = VaultAddItemState.ItemType.SecureNotes())
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule.setContent {
|
||||
VaultAddItemScreen(viewModel = viewModel, onNavigateBack = {})
|
||||
@@ -974,4 +957,16 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
||||
}
|
||||
|
||||
//endregion Helper functions
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_STATE_LOGIN = VaultAddItemState(
|
||||
selectedType = VaultAddItemState.ItemType.Login(),
|
||||
dialog = null,
|
||||
)
|
||||
|
||||
private val DEFAULT_STATE_SECURE_NOTES = VaultAddItemState(
|
||||
selectedType = VaultAddItemState.ItemType.SecureNotes(),
|
||||
dialog = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.x8bit.bitwarden.ui.vault.feature.additem
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.CreateCipherResult
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
@@ -39,7 +40,27 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `SaveClick createCipher success should emit NavigateBack`() = runTest {
|
||||
fun `SaveClick should show dialog, and remove it once an item is saved`() = runTest {
|
||||
val stateWithDialog = createVaultAddLoginItemState(
|
||||
dialogState = VaultAddItemState.DialogState.Loading(
|
||||
R.string.saving.asText(),
|
||||
),
|
||||
)
|
||||
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
coEvery {
|
||||
vaultRepository.createCipher(any())
|
||||
} returns CreateCipherResult.Success
|
||||
viewModel.stateFlow.test {
|
||||
viewModel.actionChannel.trySend(VaultAddItemAction.SaveClick)
|
||||
assertEquals(initialState, awaitItem())
|
||||
assertEquals(stateWithDialog, awaitItem())
|
||||
assertEquals(initialState, awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `SaveClick should update value to loading`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
coEvery {
|
||||
vaultRepository.createCipher(any())
|
||||
@@ -505,6 +526,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
||||
masterPasswordReprompt: Boolean = false,
|
||||
notes: String = "",
|
||||
ownership: String = "placeholder@email.com",
|
||||
dialogState: VaultAddItemState.DialogState? = null,
|
||||
): VaultAddItemState =
|
||||
VaultAddItemState(
|
||||
selectedType = VaultAddItemState.ItemType.Login(
|
||||
@@ -518,6 +540,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
||||
notes = notes,
|
||||
ownership = ownership,
|
||||
),
|
||||
dialog = dialogState,
|
||||
)
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@@ -538,6 +561,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
||||
notes = notes,
|
||||
ownership = ownership,
|
||||
),
|
||||
dialog = null,
|
||||
)
|
||||
|
||||
private fun createSavedStateHandleWithState(state: VaultAddItemState) =
|
||||
|
||||
@@ -5,6 +5,8 @@ import com.bitwarden.core.CipherType
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.LoginUriView
|
||||
import com.bitwarden.core.LoginView
|
||||
import com.bitwarden.core.SecureNoteType
|
||||
import com.bitwarden.core.SecureNoteView
|
||||
import com.bitwarden.core.UriMatchType
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockFolderView
|
||||
@@ -163,4 +165,50 @@ class VaultDataExtensionsTest {
|
||||
result,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toCipherView should transform SecureNotes ItemType to CipherView`() {
|
||||
mockkStatic(Instant::class)
|
||||
every { Instant.now() } returns Instant.MIN
|
||||
val secureNotesItemType = VaultAddItemState.ItemType.SecureNotes(
|
||||
name = "mockName-1",
|
||||
folderName = "mockFolder-1".asText(),
|
||||
favorite = false,
|
||||
masterPasswordReprompt = false,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
)
|
||||
|
||||
val result = secureNotesItemType.toCipherView()
|
||||
|
||||
assertEquals(
|
||||
CipherView(
|
||||
id = null,
|
||||
organizationId = null,
|
||||
folderId = null,
|
||||
collectionIds = emptyList(),
|
||||
key = null,
|
||||
name = "mockName-1",
|
||||
notes = "mockNotes-1",
|
||||
type = CipherType.SECURE_NOTE,
|
||||
login = null,
|
||||
identity = null,
|
||||
card = null,
|
||||
secureNote = SecureNoteView(SecureNoteType.GENERIC),
|
||||
favorite = false,
|
||||
reprompt = CipherRepromptType.NONE,
|
||||
organizationUseTotp = false,
|
||||
edit = true,
|
||||
viewPassword = true,
|
||||
localData = null,
|
||||
attachments = null,
|
||||
fields = null,
|
||||
passwordHistory = null,
|
||||
creationDate = Instant.MIN,
|
||||
deletedDate = null,
|
||||
revisionDate = Instant.MIN,
|
||||
),
|
||||
result,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user