mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 18:58:59 +03:00
Adding in tests for the custom type fields (#398)
This commit is contained in:
parent
5235310de5
commit
6f85d80f9f
7 changed files with 1183 additions and 99 deletions
|
@ -15,9 +15,9 @@ import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
|
|||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.concat
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemAction.ItemType.SecureNotesType.TooltipClick.toCustomField
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.util.toViewState
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.toCustomField
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toCipherView
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
|
@ -29,7 +29,6 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val KEY_STATE = "state"
|
||||
|
@ -1320,43 +1319,4 @@ sealed class VaultAddItemAction {
|
|||
val updateCipherResult: UpdateCipherResult,
|
||||
) : Internal()
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension function for adding custom field types.
|
||||
*/
|
||||
fun CustomFieldType.toCustomField(name: String): VaultAddItemState.Custom {
|
||||
return when (this) {
|
||||
CustomFieldType.BOOLEAN -> {
|
||||
VaultAddItemState.Custom.BooleanField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
value = false,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.LINKED -> {
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
vaultLinkedFieldType = VaultLinkedFieldType.USERNAME,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.HIDDEN -> {
|
||||
VaultAddItemState.Custom.HiddenField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
value = "",
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.TEXT -> {
|
||||
VaultAddItemState.Custom.TextField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
value = "",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@ package com.x8bit.bitwarden.ui.vault.feature.additem.model
|
|||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* The Enum representing the Custom Field type that is being added by the user.
|
||||
|
@ -13,3 +16,44 @@ enum class CustomFieldType(val typeText: Text) {
|
|||
BOOLEAN(R.string.field_type_boolean.asText()),
|
||||
TEXT(R.string.field_type_text.asText()),
|
||||
}
|
||||
|
||||
/**
|
||||
* A function that converts [CustomFieldType] and a string to [VaultAddItemState.Custom].
|
||||
*/
|
||||
fun CustomFieldType.toCustomField(
|
||||
name: String,
|
||||
): VaultAddItemState.Custom {
|
||||
return when (this) {
|
||||
CustomFieldType.BOOLEAN -> {
|
||||
VaultAddItemState.Custom.BooleanField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
value = false,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.LINKED -> {
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
vaultLinkedFieldType = VaultLinkedFieldType.USERNAME,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.HIDDEN -> {
|
||||
VaultAddItemState.Custom.HiddenField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
value = "",
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.TEXT -> {
|
||||
VaultAddItemState.Custom.TextField(
|
||||
itemId = UUID.randomUUID().toString(),
|
||||
name = name,
|
||||
value = "",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.compose.ui.test.onNodeWithText
|
|||
import androidx.compose.ui.test.onSiblings
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.compose.ui.test.performScrollTo
|
||||
import androidx.compose.ui.test.performTextClearance
|
||||
import androidx.compose.ui.test.performTextInput
|
||||
import androidx.compose.ui.test.performTouchInput
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
|
@ -28,7 +29,9 @@ import com.x8bit.bitwarden.ui.util.isProgressBar
|
|||
import com.x8bit.bitwarden.ui.util.onAllNodesWithTextAfterScroll
|
||||
import com.x8bit.bitwarden.ui.util.onNodeWithContentDescriptionAfterScroll
|
||||
import com.x8bit.bitwarden.ui.util.onNodeWithTextAfterScroll
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
|
@ -542,6 +545,204 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertTextContains("NewNote")
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Text type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Text")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestText")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.TEXT,
|
||||
name = "TestText",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Linked type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Linked")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestLinked")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.LINKED,
|
||||
name = "TestLinked",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Boolean type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Boolean")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestBoolean")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.BOOLEAN,
|
||||
name = "TestBoolean",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking New Custom Field button should allow creation of Hidden type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Hidden")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestHidden")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.HIDDEN,
|
||||
name = "TestHidden",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking and changing the custom text field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestText")
|
||||
.performTextClearance()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking and changing the custom hidden field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestHidden")
|
||||
.performTextClearance()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking and changing the custom boolean field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_LOGIN_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestBoolean")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", true),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `in ItemType_Login state clicking a Ownership option should send OwnershipChange action`() {
|
||||
// Opens the menu
|
||||
|
@ -823,6 +1024,188 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
.assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should allow creation of Text type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Text")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestText")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.TEXT,
|
||||
name = "TestText",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should not display linked type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Linked")
|
||||
.assertIsNotDisplayed()
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should allow creation of Boolean type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Boolean")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestBoolean")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Ok")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.BOOLEAN,
|
||||
name = "TestBoolean",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking New Custom Field button should allow creation of Hidden type`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll(text = "New custom field")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Cancel")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(text = "Hidden")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Name")
|
||||
.performTextInput("TestHidden")
|
||||
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Ok")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
customFieldType = CustomFieldType.HIDDEN,
|
||||
name = "TestHidden",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking and changing the custom text field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestText")
|
||||
.performTextClearance()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking and changing the custom hidden field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestHidden")
|
||||
.performTextClearance()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", ""),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `in ItemType_SecureNotes state clicking and changing the custom boolean field will send a CustomFieldValueChange event`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithTextAfterScroll("TestBoolean")
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", true),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//region Helper functions
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
|
@ -852,6 +1235,23 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
//endregion Helper functions
|
||||
|
||||
companion object {
|
||||
private val DEFAULT_STATE_LOGIN_CUSTOM_FIELDS = VaultAddItemState(
|
||||
viewState = VaultAddItemState.ViewState.Content.Login(
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", "TestTextVal"),
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", "TestHiddenVal"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
"LinkedID",
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
),
|
||||
dialog = null,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
|
||||
private val DEFAULT_STATE_LOGIN_DIALOG = VaultAddItemState(
|
||||
viewState = VaultAddItemState.ViewState.Content.Login(),
|
||||
dialog = VaultAddItemState.DialogState.Error("test".asText()),
|
||||
|
@ -864,6 +1264,18 @@ class VaultAddItemScreenTest : BaseComposeTest() {
|
|||
dialog = null,
|
||||
)
|
||||
|
||||
private val DEFAULT_STATE_SECURE_NOTES_CUSTOM_FIELDS = VaultAddItemState(
|
||||
viewState = VaultAddItemState.ViewState.Content.SecureNotes(
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("Test ID", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("Test ID", "TestText", "TestTextVal"),
|
||||
VaultAddItemState.Custom.HiddenField("Test ID", "TestHidden", "TestHiddenVal"),
|
||||
),
|
||||
),
|
||||
dialog = null,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
|
||||
private val DEFAULT_STATE_SECURE_NOTES = VaultAddItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
viewState = VaultAddItemState.ViewState.Content.SecureNotes(),
|
||||
|
|
|
@ -11,8 +11,11 @@ import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult
|
|||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.model.toCustomField
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.util.toViewState
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
|
@ -27,12 +30,13 @@ import org.junit.jupiter.api.Assertions.assertEquals
|
|||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Nested
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.UUID
|
||||
|
||||
class VaultAddItemViewModelTest : BaseViewModelTest() {
|
||||
|
||||
private val initialState = createVaultAddLoginItemState()
|
||||
private val initialSavedStateHandle = createSavedStateHandleWithState(
|
||||
state = initialState,
|
||||
private val loginInitialState = createVaultAddLoginItemState()
|
||||
private val loginInitialSavedStateHandle = createSavedStateHandleWithState(
|
||||
state = loginInitialState,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
private val mutableVaultItemFlow = MutableStateFlow<DataState<CipherView?>>(DataState.Loading)
|
||||
|
@ -43,11 +47,14 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(CIPHER_VIEW_EXTENSIONS_PATH)
|
||||
mockkStatic(UUID::randomUUID)
|
||||
every { UUID.randomUUID().toString() } returns TEST_ID
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
unmockkStatic(CIPHER_VIEW_EXTENSIONS_PATH)
|
||||
unmockkStatic(CustomFieldType::toCustomField)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -59,7 +66,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
),
|
||||
)
|
||||
viewModel.stateFlow.test {
|
||||
assertEquals(initialState, awaitItem())
|
||||
assertEquals(loginInitialState, awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,6 +118,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
fun `in add mode, SaveClick should show dialog, and remove it once an item is saved`() =
|
||||
runTest {
|
||||
val stateWithDialog = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
name = "tester",
|
||||
dialogState = VaultAddItemState.DialogState.Loading(
|
||||
R.string.saving.asText(),
|
||||
|
@ -118,6 +126,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
)
|
||||
|
||||
val stateWithName = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
name = "tester",
|
||||
)
|
||||
|
||||
|
@ -147,6 +156,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@Test
|
||||
fun `in add mode, SaveClick should update value to loading`() = runTest {
|
||||
val stateWithName = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
name = "tester",
|
||||
)
|
||||
|
||||
|
@ -169,6 +179,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@Test
|
||||
fun `in add mode, SaveClick createCipher error should emit ShowToast`() = runTest {
|
||||
val stateWithName = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
name = "tester",
|
||||
)
|
||||
|
||||
|
@ -266,7 +277,10 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
|
||||
@Test
|
||||
fun `Saving item with an empty name field will cause a dialog to show up`() = runTest {
|
||||
val stateWithNoName = createVaultAddSecureNotesItemState(name = "")
|
||||
val stateWithNoName = createVaultAddSecureNotesItemState(
|
||||
name = "",
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
|
||||
val stateWithNoNameAndDialog = createVaultAddSecureNotesItemState(
|
||||
name = "",
|
||||
|
@ -274,6 +288,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
R.string.validation_field_required
|
||||
.asText(R.string.name.asText()),
|
||||
),
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
|
||||
val viewModel = createAddVaultItemViewModel(
|
||||
|
@ -293,6 +308,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@Test
|
||||
fun `HandleDialogDismiss will remove the current dialog`() = runTest {
|
||||
val errorState = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
dialogState = VaultAddItemState.DialogState.Error(
|
||||
R.string.validation_field_required
|
||||
.asText(R.string.name.asText()),
|
||||
|
@ -321,7 +337,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedState = initialState.copy(
|
||||
val expectedState = loginInitialState.copy(
|
||||
viewState = VaultAddItemState.ViewState.Content.Login(),
|
||||
)
|
||||
|
||||
|
@ -345,10 +361,10 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(name = "newName")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -356,16 +372,15 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `UsernameTextChange should update username in LoginItem`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
val action = VaultAddItemAction.ItemType.LoginType.UsernameTextChange("newUsername")
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(username = "newUsername")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -373,64 +388,60 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `PasswordTextChange should update password in LoginItem`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
val action = VaultAddItemAction.ItemType.LoginType.PasswordTextChange("newPassword")
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(password = "newPassword")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `UriTextChange should update uri in LoginItem`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
val action = VaultAddItemAction.ItemType.LoginType.UriTextChange("newUri")
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(uri = "newUri")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `FolderChange should update folder in LoginItem`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
val action = VaultAddItemAction.ItemType.LoginType.FolderChange("newFolder".asText())
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(folderName = "newFolder".asText())
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ToggleFavorite should update favorite in LoginItem`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
val action = VaultAddItemAction.ItemType.LoginType.ToggleFavorite(true)
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(favorite = true)
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -439,7 +450,6 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@Test
|
||||
fun `ToggleMasterPasswordReprompt should update masterPasswordReprompt in LoginItem`() =
|
||||
runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
val action = VaultAddItemAction.ItemType.LoginType.ToggleMasterPasswordReprompt(
|
||||
isMasterPasswordReprompt = true,
|
||||
)
|
||||
|
@ -447,30 +457,151 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(masterPasswordReprompt = true)
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NotesTextChange should update notes in LoginItem`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
val action = VaultAddItemAction.ItemType.LoginType.NotesTextChange(notes = "newNotes")
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(notes = "newNotes")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `AddNewCustomFieldClick should allow a user to add a custom text field in Login item`() =
|
||||
runTest {
|
||||
assertAddNewCustomFieldClick(
|
||||
initialState = loginInitialState,
|
||||
type = CustomFieldType.TEXT,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `AddNewCustomFieldClick should allow a user to add a custom boolean field in Login item`() =
|
||||
runTest {
|
||||
assertAddNewCustomFieldClick(
|
||||
initialState = loginInitialState,
|
||||
type = CustomFieldType.BOOLEAN,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `AddNewCustomFieldClick should allow a user to add a custom hidden field in Login item`() =
|
||||
runTest {
|
||||
assertAddNewCustomFieldClick(
|
||||
initialState = loginInitialState,
|
||||
type = CustomFieldType.HIDDEN,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `AddNewCustomFieldClick should allow a user to add a custom linked field in Login item`() =
|
||||
runTest {
|
||||
assertAddNewCustomFieldClick(
|
||||
initialState = loginInitialState,
|
||||
type = CustomFieldType.LINKED,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `CustomFieldValueChange should allow a user to update a text custom field in Login item`() =
|
||||
runTest {
|
||||
val initState = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.TextField(
|
||||
"TestId 1",
|
||||
"Test Text",
|
||||
"Test Text",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertCustomFieldValueChange(
|
||||
initState,
|
||||
CustomFieldType.TEXT,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CustomFieldValueChange should update hidden custom fields in Login item`() =
|
||||
runTest {
|
||||
val initState = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.HiddenField(
|
||||
"TestId 2",
|
||||
"Test Text",
|
||||
"Test Text",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertCustomFieldValueChange(
|
||||
initState,
|
||||
CustomFieldType.HIDDEN,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `CustomFieldValueChange should update boolean custom fields in Login item`() =
|
||||
runTest {
|
||||
val initState = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(
|
||||
"TestId 3",
|
||||
"Boolean Field",
|
||||
true,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertCustomFieldValueChange(
|
||||
initState,
|
||||
CustomFieldType.BOOLEAN,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CustomFieldValueChange should update linked custom fields in Login item`() =
|
||||
runTest {
|
||||
val initState = createVaultAddLoginItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
"TestId 4",
|
||||
"Linked Field",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertCustomFieldValueChange(
|
||||
initState,
|
||||
CustomFieldType.LINKED,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `OwnershipChange should update ownership in LoginItem`() = runTest {
|
||||
val viewModel = createAddVaultItemViewModel()
|
||||
|
@ -480,10 +611,10 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedLoginItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
(loginInitialState.viewState as VaultAddItemState.ViewState.Content.Login)
|
||||
.copy(ownership = "newOwner")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedLoginItem)
|
||||
val expectedState = loginInitialState.copy(viewState = expectedLoginItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -592,18 +723,19 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
@Nested
|
||||
inner class VaultAddSecureNotesTypeItemActions {
|
||||
private lateinit var viewModel: VaultAddItemViewModel
|
||||
private lateinit var initialState: VaultAddItemState
|
||||
private lateinit var initialSavedStateHandle: SavedStateHandle
|
||||
private lateinit var secureNotesInitialState: VaultAddItemState
|
||||
private lateinit var secureNotesInitialSavedStateHandle: SavedStateHandle
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
initialState = createVaultAddSecureNotesItemState()
|
||||
initialSavedStateHandle = createSavedStateHandleWithState(
|
||||
state = initialState,
|
||||
secureNotesInitialState =
|
||||
createVaultAddSecureNotesItemState(vaultAddEditType = VaultAddEditType.AddItem)
|
||||
secureNotesInitialSavedStateHandle = createSavedStateHandleWithState(
|
||||
state = secureNotesInitialState,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
)
|
||||
viewModel = VaultAddItemViewModel(
|
||||
savedStateHandle = initialSavedStateHandle,
|
||||
savedStateHandle = secureNotesInitialSavedStateHandle,
|
||||
vaultRepository = vaultRepository,
|
||||
)
|
||||
}
|
||||
|
@ -615,10 +747,11 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedSecureNotesItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
(secureNotesInitialState.viewState as
|
||||
VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
.copy(name = "newName")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedSecureNotesItem)
|
||||
val expectedState = secureNotesInitialState.copy(viewState = expectedSecureNotesItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -632,10 +765,11 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedSecureNotesItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
(secureNotesInitialState.viewState as
|
||||
VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
.copy(folderName = "newFolder".asText())
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedSecureNotesItem)
|
||||
val expectedState = secureNotesInitialState.copy(viewState = expectedSecureNotesItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -647,10 +781,11 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedSecureNotesItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
(secureNotesInitialState.viewState as
|
||||
VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
.copy(favorite = true)
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedSecureNotesItem)
|
||||
val expectedState = secureNotesInitialState.copy(viewState = expectedSecureNotesItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -667,10 +802,10 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedSecureNotesItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
(secureNotesInitialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
.copy(masterPasswordReprompt = true)
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedSecureNotesItem)
|
||||
val expectedState = secureNotesInitialState.copy(viewState = expectedSecureNotesItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -684,10 +819,10 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedSecureNotesItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
(secureNotesInitialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
.copy(notes = "newNotes")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedSecureNotesItem)
|
||||
val expectedState = secureNotesInitialState.copy(viewState = expectedSecureNotesItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
@ -700,14 +835,108 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
val expectedSecureNotesItem =
|
||||
(initialState.viewState as VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
(secureNotesInitialState.viewState as
|
||||
VaultAddItemState.ViewState.Content.SecureNotes)
|
||||
.copy(ownership = "newOwner")
|
||||
|
||||
val expectedState = initialState.copy(viewState = expectedSecureNotesItem)
|
||||
val expectedState = secureNotesInitialState.copy(viewState = expectedSecureNotesItem)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `AddNewCustomFieldClick should allow a user to add a custom boolean field in Secure notes item`() =
|
||||
runTest {
|
||||
assertAddNewCustomFieldClick(
|
||||
initialState = secureNotesInitialState,
|
||||
type = CustomFieldType.BOOLEAN,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `AddNewCustomFieldClick should allow a user to add a custom hidden field in Secure notes item`() =
|
||||
runTest {
|
||||
assertAddNewCustomFieldClick(
|
||||
initialState = secureNotesInitialState,
|
||||
type = CustomFieldType.HIDDEN,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `AddNewCustomFieldClick should allow a user to add a custom text field in Secure notes item`() =
|
||||
runTest {
|
||||
|
||||
assertAddNewCustomFieldClick(
|
||||
initialState = secureNotesInitialState,
|
||||
type = CustomFieldType.TEXT,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `CustomFieldValueChange should allow a user to update a text custom field in Secure notes item`() =
|
||||
runTest {
|
||||
val initState = createVaultAddSecureNotesItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.TextField(
|
||||
"TestId 1",
|
||||
"Test Text",
|
||||
"Test Text",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertCustomFieldValueChange(
|
||||
initState,
|
||||
CustomFieldType.TEXT,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `CustomFieldValueChange should update hidden custom fields in Secure notes item`() =
|
||||
runTest {
|
||||
val initState = createVaultAddSecureNotesItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.HiddenField(
|
||||
"TestId 2",
|
||||
"Test Text",
|
||||
"Test Text",
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertCustomFieldValueChange(
|
||||
initState,
|
||||
CustomFieldType.HIDDEN,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `CustomFieldValueChange should update boolean custom fields in Secure notes item`() =
|
||||
runTest {
|
||||
val initState = createVaultAddSecureNotesItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(
|
||||
"TestId 3",
|
||||
"Boolean Field",
|
||||
true,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
assertCustomFieldValueChange(
|
||||
initState,
|
||||
CustomFieldType.BOOLEAN,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `TooltipClick should emit ShowToast with 'Tooltip' message`() = runTest {
|
||||
viewModel.eventFlow.test {
|
||||
|
@ -721,6 +950,8 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
}
|
||||
|
||||
//region Helper functions
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
private fun createVaultAddLoginItemState(
|
||||
vaultAddEditType: VaultAddEditType = VaultAddEditType.AddItem,
|
||||
|
@ -732,6 +963,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
favorite: Boolean = false,
|
||||
masterPasswordReprompt: Boolean = false,
|
||||
notes: String = "",
|
||||
customFieldData: List<VaultAddItemState.Custom> = listOf(),
|
||||
ownership: String = "placeholder@email.com",
|
||||
dialogState: VaultAddItemState.DialogState? = null,
|
||||
): VaultAddItemState =
|
||||
|
@ -744,6 +976,7 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
uri = uri,
|
||||
folderName = folder,
|
||||
favorite = favorite,
|
||||
customFieldData = customFieldData,
|
||||
masterPasswordReprompt = masterPasswordReprompt,
|
||||
notes = notes,
|
||||
ownership = ownership,
|
||||
|
@ -753,22 +986,25 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
|
||||
@Suppress("LongParameterList")
|
||||
private fun createVaultAddSecureNotesItemState(
|
||||
vaultAddEditType: VaultAddEditType.AddItem,
|
||||
name: String = "",
|
||||
folder: Text = "No Folder".asText(),
|
||||
favorite: Boolean = false,
|
||||
masterPasswordReprompt: Boolean = false,
|
||||
notes: String = "",
|
||||
customFieldData: List<VaultAddItemState.Custom> = listOf(),
|
||||
ownership: String = "placeholder@email.com",
|
||||
dialogState: VaultAddItemState.DialogState? = null,
|
||||
): VaultAddItemState =
|
||||
VaultAddItemState(
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
vaultAddEditType = vaultAddEditType,
|
||||
viewState = VaultAddItemState.ViewState.Content.SecureNotes(
|
||||
name = name,
|
||||
folderName = folder,
|
||||
favorite = favorite,
|
||||
masterPasswordReprompt = masterPasswordReprompt,
|
||||
notes = notes,
|
||||
customFieldData = customFieldData,
|
||||
ownership = ownership,
|
||||
),
|
||||
dialog = dialogState,
|
||||
|
@ -790,15 +1026,181 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
|
||||
private fun createAddVaultItemViewModel(
|
||||
savedStateHandle: SavedStateHandle = initialSavedStateHandle,
|
||||
savedStateHandle: SavedStateHandle = loginInitialSavedStateHandle,
|
||||
vaultRepo: VaultRepository = vaultRepository,
|
||||
): VaultAddItemViewModel =
|
||||
VaultAddItemViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
vaultRepository = vaultRepo,
|
||||
)
|
||||
|
||||
/**
|
||||
* A function to test the changes in custom fields for each type.
|
||||
*/
|
||||
private fun assertCustomFieldValueChange(
|
||||
initialState: VaultAddItemState,
|
||||
type: CustomFieldType,
|
||||
) {
|
||||
lateinit var expectedCustomField: VaultAddItemState.Custom
|
||||
lateinit var action: VaultAddItemAction.ItemType
|
||||
lateinit var expectedState: VaultAddItemState.ViewState.Content
|
||||
|
||||
when (type) {
|
||||
CustomFieldType.LINKED -> {
|
||||
expectedCustomField = VaultAddItemState.Custom.LinkedField(
|
||||
"TestId 4",
|
||||
"Linked Field",
|
||||
VaultLinkedFieldType.PASSWORD,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.HIDDEN -> {
|
||||
expectedCustomField = VaultAddItemState.Custom.HiddenField(
|
||||
"TestId 2",
|
||||
"Test Hidden",
|
||||
"Updated Test Text",
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.BOOLEAN -> {
|
||||
expectedCustomField = VaultAddItemState.Custom.BooleanField(
|
||||
"TestId 3",
|
||||
"Boolean Field",
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.TEXT -> {
|
||||
expectedCustomField = VaultAddItemState.Custom.TextField(
|
||||
"TestId 1",
|
||||
"Test Text",
|
||||
"Updated Test Text",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val viewModel = createAddVaultItemViewModel(
|
||||
savedStateHandle = createSavedStateHandleWithState(
|
||||
state = initialState,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
),
|
||||
)
|
||||
|
||||
when (val state =
|
||||
viewModel.stateFlow.value.viewState as VaultAddItemState.ViewState.Content) {
|
||||
is VaultAddItemState.ViewState.Content.Login -> {
|
||||
action = VaultAddItemAction.ItemType.LoginType.CustomFieldValueChange(
|
||||
expectedCustomField,
|
||||
)
|
||||
expectedState = state.copy(customFieldData = listOf(expectedCustomField))
|
||||
}
|
||||
|
||||
is VaultAddItemState.ViewState.Content.SecureNotes -> {
|
||||
action =
|
||||
VaultAddItemAction.ItemType.SecureNotesType.CustomFieldValueChange(
|
||||
expectedCustomField,
|
||||
)
|
||||
expectedState = state.copy(customFieldData = listOf(expectedCustomField))
|
||||
}
|
||||
// TODO: Create UI for card-type item creation (BIT-507)
|
||||
is VaultAddItemState.ViewState.Content.Card -> Unit
|
||||
// TODO: Create UI for identity-type item creation (BIT-667)
|
||||
is VaultAddItemState.ViewState.Content.Identity -> Unit
|
||||
}
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
|
||||
assertEquals(expectedState, viewModel.stateFlow.value.viewState)
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to test the addition of new custom fields for each type.
|
||||
*/
|
||||
private fun assertAddNewCustomFieldClick(
|
||||
initialState: VaultAddItemState,
|
||||
type: CustomFieldType,
|
||||
) {
|
||||
val viewModel = createAddVaultItemViewModel(
|
||||
savedStateHandle = createSavedStateHandleWithState(
|
||||
state = initialState,
|
||||
vaultAddEditType = VaultAddEditType.AddItem,
|
||||
),
|
||||
)
|
||||
|
||||
var name = ""
|
||||
lateinit var expectedCustomField: VaultAddItemState.Custom
|
||||
lateinit var action: VaultAddItemAction.ItemType
|
||||
lateinit var expectedState: VaultAddItemState.ViewState.Content
|
||||
|
||||
when (type) {
|
||||
CustomFieldType.LINKED -> {
|
||||
name = "Linked"
|
||||
expectedCustomField = VaultAddItemState.Custom.LinkedField(
|
||||
itemId = TEST_ID,
|
||||
name = name,
|
||||
vaultLinkedFieldType = VaultLinkedFieldType.USERNAME,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.HIDDEN -> {
|
||||
name = "Hidden"
|
||||
expectedCustomField = VaultAddItemState.Custom.HiddenField(
|
||||
itemId = TEST_ID,
|
||||
name = name,
|
||||
value = "",
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.BOOLEAN -> {
|
||||
name = "Boolean"
|
||||
expectedCustomField = VaultAddItemState.Custom.BooleanField(
|
||||
itemId = TEST_ID,
|
||||
name = name,
|
||||
value = false,
|
||||
)
|
||||
}
|
||||
|
||||
CustomFieldType.TEXT -> {
|
||||
name = "Text"
|
||||
expectedCustomField = VaultAddItemState.Custom.TextField(
|
||||
itemId = TEST_ID,
|
||||
name = name,
|
||||
value = "",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
when (
|
||||
val state =
|
||||
viewModel.stateFlow.value.viewState as VaultAddItemState.ViewState.Content) {
|
||||
is VaultAddItemState.ViewState.Content.Login -> {
|
||||
action = VaultAddItemAction.ItemType.LoginType.AddNewCustomFieldClick(type, name)
|
||||
expectedState = state.copy(customFieldData = listOf(expectedCustomField))
|
||||
}
|
||||
|
||||
is VaultAddItemState.ViewState.Content.SecureNotes -> {
|
||||
action =
|
||||
VaultAddItemAction.ItemType.SecureNotesType.AddNewCustomFieldClick(
|
||||
customFieldType = type,
|
||||
name = name,
|
||||
)
|
||||
expectedState = state.copy(customFieldData = listOf(expectedCustomField))
|
||||
}
|
||||
// TODO: Create UI for card-type item creation (BIT-507)
|
||||
is VaultAddItemState.ViewState.Content.Card -> Unit
|
||||
// TODO: Create UI for identity-type item creation (BIT-667)
|
||||
is VaultAddItemState.ViewState.Content.Identity -> Unit
|
||||
}
|
||||
|
||||
viewModel.actionChannel.trySend(action)
|
||||
assertEquals(expectedState, viewModel.stateFlow.value.viewState)
|
||||
}
|
||||
|
||||
//endregion Helper functions
|
||||
}
|
||||
|
||||
private const val TEST_ID = "testId"
|
||||
|
||||
private const val CIPHER_VIEW_EXTENSIONS_PATH: String =
|
||||
"com.x8bit.bitwarden.ui.vault.feature.additem.util.CipherViewExtensionsKt"
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package com.x8bit.bitwarden.ui.vault.feature.additem.model
|
||||
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import io.mockk.every
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.util.UUID
|
||||
|
||||
class CustomFieldTypeTests {
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(UUID::randomUUID)
|
||||
every { UUID.randomUUID().toString() } returns TEST_ID
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
unmockkStatic(UUID::randomUUID)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `toCustomField should return a custom boolean type when we pass in required boolean type`() {
|
||||
val name = "test"
|
||||
val type = CustomFieldType.BOOLEAN
|
||||
|
||||
val expected = VaultAddItemState.Custom.BooleanField(TEST_ID, "test", false)
|
||||
val actual = type.toCustomField(name)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toCustomField should return a custom linked type when we pass in required linked type`() {
|
||||
val name = "test"
|
||||
val type = CustomFieldType.LINKED
|
||||
|
||||
val expected =
|
||||
VaultAddItemState.Custom.LinkedField(TEST_ID, "test", VaultLinkedFieldType.USERNAME)
|
||||
val actual = type.toCustomField(name)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toCustomField should return a custom texttype when we pass in required text type`() {
|
||||
val name = "test"
|
||||
val type = CustomFieldType.TEXT
|
||||
|
||||
val expected = VaultAddItemState.Custom.TextField(TEST_ID, "test", "")
|
||||
val actual = type.toCustomField(name)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toCustomField should return a custom hidden type when we pass in required hidden type`() {
|
||||
val name = "test"
|
||||
val type = CustomFieldType.HIDDEN
|
||||
|
||||
val expected = VaultAddItemState.Custom.HiddenField(TEST_ID, "test", "")
|
||||
val actual = type.toCustomField(name)
|
||||
|
||||
assertEquals(expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
private const val TEST_ID = "testID"
|
|
@ -4,6 +4,8 @@ import com.bitwarden.core.CardView
|
|||
import com.bitwarden.core.CipherRepromptType
|
||||
import com.bitwarden.core.CipherType
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.FieldType
|
||||
import com.bitwarden.core.FieldView
|
||||
import com.bitwarden.core.IdentityView
|
||||
import com.bitwarden.core.LoginUriView
|
||||
import com.bitwarden.core.LoginView
|
||||
|
@ -13,12 +15,30 @@ import com.bitwarden.core.SecureNoteView
|
|||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import io.mockk.every
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.Instant
|
||||
import java.util.UUID
|
||||
|
||||
class CipherViewExtensionsTest {
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
mockkStatic(UUID::randomUUID)
|
||||
every { UUID.randomUUID().toString() } returns TEST_ID
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
unmockkStatic(UUID::randomUUID)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toViewState should create a Card ViewState`() {
|
||||
val cipherView = DEFAULT_CARD_CIPHER_VIEW
|
||||
|
@ -63,7 +83,16 @@ class CipherViewExtensionsTest {
|
|||
ownership = "",
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
customFieldData = emptyList(),
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
TEST_ID,
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
),
|
||||
result,
|
||||
)
|
||||
|
@ -84,9 +113,13 @@ class CipherViewExtensionsTest {
|
|||
masterPasswordReprompt = true,
|
||||
notes = "Lots of notes",
|
||||
ownership = "",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField(TEST_ID, "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField(TEST_ID, "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField(TEST_ID, "TestHidden", "TestHidden"),
|
||||
),
|
||||
availableFolders = emptyList(),
|
||||
availableOwners = emptyList(),
|
||||
customFieldData = emptyList(),
|
||||
),
|
||||
result,
|
||||
)
|
||||
|
@ -113,7 +146,32 @@ private val DEFAULT_BASE_CIPHER_VIEW: CipherView = CipherView(
|
|||
viewPassword = false,
|
||||
localData = null,
|
||||
attachments = null,
|
||||
fields = emptyList(),
|
||||
fields = listOf(
|
||||
FieldView(
|
||||
name = "TestBoolean",
|
||||
value = false.toString(),
|
||||
type = FieldType.BOOLEAN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestText",
|
||||
value = "TestText",
|
||||
type = FieldType.TEXT,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestHidden",
|
||||
value = "TestHidden",
|
||||
type = FieldType.HIDDEN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestLinked",
|
||||
value = null,
|
||||
type = FieldType.LINKED,
|
||||
linkedId = VaultLinkedFieldType.USERNAME.id,
|
||||
),
|
||||
),
|
||||
passwordHistory = listOf(
|
||||
PasswordHistoryView(
|
||||
password = "old_password",
|
||||
|
@ -180,5 +238,27 @@ private val DEFAULT_LOGIN_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.cop
|
|||
|
||||
private val DEFAULT_SECURE_NOTES_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy(
|
||||
type = CipherType.SECURE_NOTE,
|
||||
fields = listOf(
|
||||
FieldView(
|
||||
name = "TestBoolean",
|
||||
value = false.toString(),
|
||||
type = FieldType.BOOLEAN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestText",
|
||||
value = "TestText",
|
||||
type = FieldType.TEXT,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestHidden",
|
||||
value = "TestHidden",
|
||||
type = FieldType.HIDDEN,
|
||||
linkedId = null,
|
||||
),
|
||||
),
|
||||
secureNote = SecureNoteView(type = SecureNoteType.GENERIC),
|
||||
)
|
||||
|
||||
private const val TEST_ID = "testID"
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.x8bit.bitwarden.ui.vault.feature.vault.util
|
|||
import com.bitwarden.core.CipherRepromptType
|
||||
import com.bitwarden.core.CipherType
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.FieldType
|
||||
import com.bitwarden.core.FieldView
|
||||
import com.bitwarden.core.LoginUriView
|
||||
import com.bitwarden.core.LoginView
|
||||
import com.bitwarden.core.PasswordHistoryView
|
||||
|
@ -16,6 +18,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.VaultData
|
|||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemState
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.VaultState
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import io.mockk.every
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.unmockkStatic
|
||||
|
@ -197,9 +200,18 @@ class VaultDataExtensionsTest {
|
|||
folderName = "mockFolder-1".asText(),
|
||||
favorite = true,
|
||||
masterPasswordReprompt = false,
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("testId", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("testId", "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField("testId", "TestHidden", "TestHidden"),
|
||||
VaultAddItemState.Custom.LinkedField(
|
||||
"testId",
|
||||
"TestLinked",
|
||||
VaultLinkedFieldType.USERNAME,
|
||||
),
|
||||
),
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
customFieldData = emptyList(),
|
||||
)
|
||||
|
||||
val result = loginItemType.toCipherView()
|
||||
|
@ -225,7 +237,32 @@ class VaultDataExtensionsTest {
|
|||
),
|
||||
favorite = true,
|
||||
reprompt = CipherRepromptType.NONE,
|
||||
fields = emptyList(),
|
||||
fields = listOf(
|
||||
FieldView(
|
||||
name = "TestBoolean",
|
||||
value = "false",
|
||||
type = FieldType.BOOLEAN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestText",
|
||||
value = "TestText",
|
||||
type = FieldType.TEXT,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestHidden",
|
||||
value = "TestHidden",
|
||||
type = FieldType.HIDDEN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestLinked",
|
||||
value = null,
|
||||
type = FieldType.LINKED,
|
||||
linkedId = VaultLinkedFieldType.USERNAME.id,
|
||||
),
|
||||
),
|
||||
passwordHistory = listOf(
|
||||
PasswordHistoryView(
|
||||
password = "old_password",
|
||||
|
@ -248,6 +285,11 @@ class VaultDataExtensionsTest {
|
|||
masterPasswordReprompt = false,
|
||||
notes = "mockNotes-1",
|
||||
ownership = "mockOwnership-1",
|
||||
customFieldData = listOf(
|
||||
VaultAddItemState.Custom.BooleanField("testId", "TestBoolean", false),
|
||||
VaultAddItemState.Custom.TextField("testId", "TestText", "TestText"),
|
||||
VaultAddItemState.Custom.HiddenField("testId", "TestHidden", "TestHidden"),
|
||||
),
|
||||
)
|
||||
|
||||
val result = secureNotesItemType.toCipherView()
|
||||
|
@ -273,7 +315,26 @@ class VaultDataExtensionsTest {
|
|||
viewPassword = true,
|
||||
localData = null,
|
||||
attachments = null,
|
||||
fields = emptyList(),
|
||||
fields = listOf(
|
||||
FieldView(
|
||||
name = "TestBoolean",
|
||||
value = "false",
|
||||
type = FieldType.BOOLEAN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestText",
|
||||
value = "TestText",
|
||||
type = FieldType.TEXT,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "TestHidden",
|
||||
value = "TestHidden",
|
||||
type = FieldType.HIDDEN,
|
||||
linkedId = null,
|
||||
),
|
||||
),
|
||||
passwordHistory = null,
|
||||
creationDate = Instant.MIN,
|
||||
deletedDate = null,
|
||||
|
@ -333,7 +394,38 @@ private val DEFAULT_BASE_CIPHER_VIEW: CipherView = CipherView(
|
|||
viewPassword = false,
|
||||
localData = null,
|
||||
attachments = null,
|
||||
fields = emptyList(),
|
||||
fields = listOf(
|
||||
FieldView(
|
||||
name = "text",
|
||||
value = "value",
|
||||
type = FieldType.TEXT,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "hidden",
|
||||
value = "value",
|
||||
type = FieldType.HIDDEN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "boolean",
|
||||
value = "true",
|
||||
type = FieldType.BOOLEAN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "linked username",
|
||||
value = null,
|
||||
type = FieldType.LINKED,
|
||||
linkedId = 100U,
|
||||
),
|
||||
FieldView(
|
||||
name = "linked password",
|
||||
value = null,
|
||||
type = FieldType.LINKED,
|
||||
linkedId = 101U,
|
||||
),
|
||||
),
|
||||
passwordHistory = listOf(
|
||||
PasswordHistoryView(
|
||||
password = "old_password",
|
||||
|
@ -364,5 +456,25 @@ private val DEFAULT_LOGIN_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.cop
|
|||
|
||||
private val DEFAULT_SECURE_NOTES_CIPHER_VIEW: CipherView = DEFAULT_BASE_CIPHER_VIEW.copy(
|
||||
type = CipherType.SECURE_NOTE,
|
||||
fields = listOf(
|
||||
FieldView(
|
||||
name = "text",
|
||||
value = "value",
|
||||
type = FieldType.TEXT,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "hidden",
|
||||
value = "value",
|
||||
type = FieldType.HIDDEN,
|
||||
linkedId = null,
|
||||
),
|
||||
FieldView(
|
||||
name = "boolean",
|
||||
value = "true",
|
||||
type = FieldType.BOOLEAN,
|
||||
linkedId = null,
|
||||
),
|
||||
),
|
||||
secureNote = SecureNoteView(type = SecureNoteType.GENERIC),
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue