mirror of
https://github.com/bitwarden/android.git
synced 2025-02-17 04:19:54 +03:00
BIT-1337 Adding new section for verification codes (#567)
This commit is contained in:
parent
9e6c49fb7c
commit
fc5529e2ad
8 changed files with 264 additions and 10 deletions
|
@ -27,6 +27,7 @@ fun VaultContent(
|
|||
vaultItemClick: (VaultState.ViewState.VaultItem) -> Unit,
|
||||
folderClick: (VaultState.ViewState.FolderItem) -> Unit,
|
||||
collectionClick: (VaultState.ViewState.CollectionItem) -> Unit,
|
||||
totpItemsClick: () -> Unit,
|
||||
loginGroupClick: () -> Unit,
|
||||
cardGroupClick: () -> Unit,
|
||||
identityGroupClick: () -> Unit,
|
||||
|
@ -37,6 +38,31 @@ fun VaultContent(
|
|||
LazyColumn(
|
||||
modifier = modifier,
|
||||
) {
|
||||
if (state.totpItemsCount > 0) {
|
||||
|
||||
item {
|
||||
BitwardenListHeaderTextWithSupportLabel(
|
||||
label = stringResource(id = R.string.totp),
|
||||
supportingLabel = "1",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
BitwardenGroupItem(
|
||||
startIcon = painterResource(id = R.drawable.access_time),
|
||||
label = stringResource(id = R.string.verification_codes),
|
||||
supportingLabel = state.totpItemsCount.toString(),
|
||||
onClick = totpItemsClick,
|
||||
showDivider = true,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (state.favoriteItems.isNotEmpty()) {
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.x8bit.bitwarden.R
|
|||
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.IntentHandler
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.showNotYetImplementedToast
|
||||
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenAccountActionItem
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenAccountSwitcher
|
||||
|
@ -80,6 +81,11 @@ fun VaultScreen(
|
|||
.show()
|
||||
}
|
||||
|
||||
is VaultEvent.NavigateToVerificationCodeScreen -> {
|
||||
// TODO Add Verification codes detail screen (BIT-1338)
|
||||
showNotYetImplementedToast(context = context)
|
||||
}
|
||||
|
||||
is VaultEvent.NavigateToVaultItem -> onNavigateToVaultItemScreen(event.itemId)
|
||||
|
||||
is VaultEvent.NavigateToEditVaultItem -> onNavigateToVaultEditItemScreen(event.itemId)
|
||||
|
@ -140,6 +146,9 @@ fun VaultScreen(
|
|||
viewModel.trySendAction(VaultAction.CollectionClick(collectionItem))
|
||||
}
|
||||
},
|
||||
verificationCodesClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultAction.VerificationCodesClick) }
|
||||
},
|
||||
loginGroupClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultAction.LoginGroupClick) }
|
||||
},
|
||||
|
@ -186,6 +195,7 @@ private fun VaultScreenScaffold(
|
|||
vaultItemClick: (VaultState.ViewState.VaultItem) -> Unit,
|
||||
folderClick: (VaultState.ViewState.FolderItem) -> Unit,
|
||||
collectionClick: (VaultState.ViewState.CollectionItem) -> Unit,
|
||||
verificationCodesClick: () -> Unit,
|
||||
loginGroupClick: () -> Unit,
|
||||
cardGroupClick: () -> Unit,
|
||||
identityGroupClick: () -> Unit,
|
||||
|
@ -345,6 +355,7 @@ private fun VaultScreenScaffold(
|
|||
cardGroupClick = cardGroupClick,
|
||||
identityGroupClick = identityGroupClick,
|
||||
secureNoteGroupClick = secureNoteGroupClick,
|
||||
totpItemsClick = verificationCodesClick,
|
||||
trashClick = trashClick,
|
||||
modifier = innerModifier,
|
||||
)
|
||||
|
|
|
@ -56,6 +56,7 @@ class VaultViewModel @Inject constructor(
|
|||
accountSummaries = accountSummaries,
|
||||
vaultFilterData = vaultFilterData,
|
||||
viewState = VaultState.ViewState.Loading,
|
||||
isPremium = userState.activeAccount.isPremium,
|
||||
)
|
||||
},
|
||||
) {
|
||||
|
@ -86,6 +87,7 @@ class VaultViewModel @Inject constructor(
|
|||
is VaultAction.FolderClick -> handleFolderItemClick(action)
|
||||
is VaultAction.CollectionClick -> handleCollectionItemClick(action)
|
||||
is VaultAction.IdentityGroupClick -> handleIdentityClick()
|
||||
is VaultAction.VerificationCodesClick -> handleVerificationCodeClick()
|
||||
is VaultAction.LoginGroupClick -> handleLoginClick()
|
||||
is VaultAction.SearchIconClick -> handleSearchIconClick()
|
||||
is VaultAction.LockAccountClick -> handleLockAccountClick(action)
|
||||
|
@ -133,6 +135,10 @@ class VaultViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private fun handleVerificationCodeClick() {
|
||||
sendEvent(VaultEvent.NavigateToVerificationCodeScreen)
|
||||
}
|
||||
|
||||
private fun handleIdentityClick() {
|
||||
sendEvent(VaultEvent.NavigateToItemListing(VaultItemListingType.Identity))
|
||||
}
|
||||
|
@ -268,6 +274,7 @@ class VaultViewModel @Inject constructor(
|
|||
mutableStateFlow.updateToErrorStateOrDialog(
|
||||
vaultData = vaultData.data,
|
||||
vaultFilterType = vaultFilterTypeOrDefault,
|
||||
isPremium = state.isPremium,
|
||||
errorTitle = R.string.an_error_has_occurred.asText(),
|
||||
errorMessage = R.string.generic_error_message.asText(),
|
||||
)
|
||||
|
@ -283,7 +290,10 @@ class VaultViewModel @Inject constructor(
|
|||
}
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
viewState = vaultData.data.toViewState(vaultFilterTypeOrDefault),
|
||||
viewState = vaultData.data.toViewState(
|
||||
isPremium = state.isPremium,
|
||||
vaultFilterType = vaultFilterTypeOrDefault,
|
||||
),
|
||||
dialog = null,
|
||||
)
|
||||
}
|
||||
|
@ -297,6 +307,7 @@ class VaultViewModel @Inject constructor(
|
|||
mutableStateFlow.updateToErrorStateOrDialog(
|
||||
vaultData = vaultData.data,
|
||||
vaultFilterType = vaultFilterTypeOrDefault,
|
||||
isPremium = state.isPremium,
|
||||
errorTitle = R.string.internet_connection_required_title.asText(),
|
||||
errorMessage = R.string.internet_connection_required_message.asText(),
|
||||
)
|
||||
|
@ -305,7 +316,12 @@ class VaultViewModel @Inject constructor(
|
|||
private fun vaultPendingReceive(vaultData: DataState.Pending<VaultData>) {
|
||||
// TODO update state to refresh state BIT-505
|
||||
mutableStateFlow.update {
|
||||
it.copy(viewState = vaultData.data.toViewState(vaultFilterTypeOrDefault))
|
||||
it.copy(
|
||||
viewState = vaultData.data.toViewState(
|
||||
isPremium = state.isPremium,
|
||||
vaultFilterType = vaultFilterTypeOrDefault,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,6 +337,7 @@ class VaultViewModel @Inject constructor(
|
|||
* @property viewState The specific view state representing loading, no items, or content state.
|
||||
* @property dialog Information about any dialogs that may need to be displayed.
|
||||
* @property isSwitchingAccounts Whether or not we are actively switching accounts.
|
||||
* @property isPremium Whether the user is a premium user.
|
||||
*/
|
||||
@Parcelize
|
||||
data class VaultState(
|
||||
|
@ -333,6 +350,7 @@ data class VaultState(
|
|||
val dialog: DialogState? = null,
|
||||
// Internal-use properties
|
||||
val isSwitchingAccounts: Boolean = false,
|
||||
val isPremium: Boolean,
|
||||
) : Parcelable {
|
||||
|
||||
/**
|
||||
|
@ -390,6 +408,7 @@ data class VaultState(
|
|||
/**
|
||||
* Content state for the [VaultScreen] showing the actual content or items.
|
||||
*
|
||||
* @property totpItemsCount The count of totp code items.
|
||||
* @property loginItemsCount The count of Login type items.
|
||||
* @property cardItemsCount The count of Card type items.
|
||||
* @property identityItemsCount The count of Identity type items.
|
||||
|
@ -402,6 +421,7 @@ data class VaultState(
|
|||
*/
|
||||
@Parcelize
|
||||
data class Content(
|
||||
val totpItemsCount: Int,
|
||||
val loginItemsCount: Int,
|
||||
val cardItemsCount: Int,
|
||||
val identityItemsCount: Int,
|
||||
|
@ -608,6 +628,11 @@ sealed class VaultEvent {
|
|||
val itemListingType: VaultItemListingType,
|
||||
) : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the verification code screen.
|
||||
*/
|
||||
data object NavigateToVerificationCodeScreen : VaultEvent()
|
||||
|
||||
/**
|
||||
* Navigate out of the app.
|
||||
*/
|
||||
|
@ -706,6 +731,11 @@ sealed class VaultAction {
|
|||
val collectionItem: VaultState.ViewState.CollectionItem,
|
||||
) : VaultAction()
|
||||
|
||||
/**
|
||||
* User clicked on the verification codes button.
|
||||
*/
|
||||
data object VerificationCodesClick : VaultAction()
|
||||
|
||||
/**
|
||||
* User clicked the login types button.
|
||||
*/
|
||||
|
@ -765,13 +795,17 @@ sealed class VaultAction {
|
|||
private fun MutableStateFlow<VaultState>.updateToErrorStateOrDialog(
|
||||
vaultData: VaultData?,
|
||||
vaultFilterType: VaultFilterType,
|
||||
isPremium: Boolean,
|
||||
errorTitle: Text,
|
||||
errorMessage: Text,
|
||||
) {
|
||||
this.update {
|
||||
if (vaultData != null) {
|
||||
it.copy(
|
||||
viewState = vaultData.toViewState(vaultFilterType = vaultFilterType),
|
||||
viewState = vaultData.toViewState(
|
||||
isPremium = isPremium,
|
||||
vaultFilterType = vaultFilterType,
|
||||
),
|
||||
dialog = VaultState.DialogState.Error(
|
||||
title = errorTitle,
|
||||
message = errorMessage,
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterType
|
|||
* Transforms [VaultData] into [VaultState.ViewState] using the given [vaultFilterType].
|
||||
*/
|
||||
fun VaultData.toViewState(
|
||||
isPremium: Boolean,
|
||||
vaultFilterType: VaultFilterType,
|
||||
): VaultState.ViewState {
|
||||
val filteredCipherViewList = cipherViewList.toFilteredList(vaultFilterType)
|
||||
|
@ -23,6 +24,11 @@ fun VaultData.toViewState(
|
|||
VaultState.ViewState.NoItems
|
||||
} else {
|
||||
VaultState.ViewState.Content(
|
||||
totpItemsCount = if (isPremium) {
|
||||
filteredCipherViewList.count { it.login?.totp != null }
|
||||
} else {
|
||||
0
|
||||
},
|
||||
loginItemsCount = filteredCipherViewList.count { it.type == CipherType.LOGIN },
|
||||
cardItemsCount = filteredCipherViewList.count { it.type == CipherType.CARD },
|
||||
identityItemsCount = filteredCipherViewList.count { it.type == CipherType.IDENTITY },
|
||||
|
|
18
app/src/main/res/drawable/access_time.xml
Normal file
18
app/src/main/res/drawable/access_time.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M2,2h20v20h-20z"/>
|
||||
<path
|
||||
android:pathData="M12.625,7C12.97,7 13.25,7.28 13.25,7.625V12.732C13.25,13.229 13.052,13.706 12.701,14.058L10.567,16.192C10.323,16.436 9.927,16.436 9.683,16.192C9.439,15.948 9.439,15.552 9.683,15.308L11.817,13.174C11.934,13.057 12,12.898 12,12.732V7.625C12,7.28 12.28,7 12.625,7Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M12,20.75C16.833,20.75 20.75,16.833 20.75,12C20.75,7.168 16.833,3.25 12,3.25C7.168,3.25 3.25,7.168 3.25,12C3.25,16.833 7.168,20.75 12,20.75ZM12,22C17.523,22 22,17.523 22,12C22,6.477 17.523,2 12,2C6.477,2 2,6.477 2,12C2,17.523 6.477,22 12,22Z"
|
||||
android:fillColor="#000000"
|
||||
android:fillType="evenOdd"/>
|
||||
</group>
|
||||
</vector>
|
|
@ -1,6 +1,7 @@
|
|||
package com.x8bit.bitwarden.ui.vault.feature.vault
|
||||
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.assertIsNotDisplayed
|
||||
import androidx.compose.ui.test.assertTextEquals
|
||||
import androidx.compose.ui.test.filterToOne
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
|
@ -622,6 +623,61 @@ class VaultScreenTest : BaseComposeTest() {
|
|||
verify { intentHandler.exitApplication() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `totp section should be visible based on state`() {
|
||||
mutableStateFlow.update { state ->
|
||||
state.copy(
|
||||
viewState = DEFAULT_CONTENT_VIEW_STATE.copy(
|
||||
totpItemsCount = 2,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("TOTP")
|
||||
.assertTextEquals("TOTP", "1")
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Verification codes")
|
||||
.assertTextEquals("Verification codes", "2")
|
||||
.assertIsDisplayed()
|
||||
|
||||
mutableStateFlow.update { state ->
|
||||
state.copy(
|
||||
viewState = DEFAULT_CONTENT_VIEW_STATE.copy(
|
||||
totpItemsCount = 0,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("TOTP")
|
||||
.assertIsNotDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Verification codes")
|
||||
.assertIsNotDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking totp section should emit VerificationCodesClick action`() {
|
||||
mutableStateFlow.update { state ->
|
||||
state.copy(
|
||||
isPremium = true,
|
||||
viewState = DEFAULT_CONTENT_VIEW_STATE.copy(
|
||||
totpItemsCount = 2,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Verification codes")
|
||||
.performClick()
|
||||
|
||||
verify { viewModel.trySendAction(VaultAction.VerificationCodesClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `clicking a favorite item should send VaultItemClick with the correct item`() {
|
||||
val itemText = "Test Item"
|
||||
|
@ -1003,14 +1059,15 @@ private val VAULT_FILTER_DATA = VaultFilterData(
|
|||
)
|
||||
|
||||
private val DEFAULT_STATE: VaultState = VaultState(
|
||||
appBarTitle = R.string.my_vault.asText(),
|
||||
avatarColorString = "#aa00aa",
|
||||
initials = "AU",
|
||||
accountSummaries = persistentListOf(
|
||||
ACTIVE_ACCOUNT_SUMMARY,
|
||||
LOCKED_ACCOUNT_SUMMARY,
|
||||
),
|
||||
appBarTitle = R.string.my_vault.asText(),
|
||||
viewState = VaultState.ViewState.Loading,
|
||||
isPremium = false,
|
||||
)
|
||||
|
||||
private val DEFAULT_CONTENT_VIEW_STATE: VaultState.ViewState.Content = VaultState.ViewState.Content(
|
||||
|
@ -1023,4 +1080,5 @@ private val DEFAULT_CONTENT_VIEW_STATE: VaultState.ViewState.Content = VaultStat
|
|||
noFolderItems = emptyList(),
|
||||
collectionItems = emptyList(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 0,
|
||||
)
|
||||
|
|
|
@ -345,7 +345,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
)
|
||||
val viewModel = createViewModel()
|
||||
val initialState = createMockVaultState(
|
||||
viewState = vaultData.toViewState(VaultFilterType.AllVaults),
|
||||
viewState = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.AllVaults,
|
||||
),
|
||||
)
|
||||
.copy(
|
||||
appBarTitle = R.string.vaults.asText(),
|
||||
|
@ -363,7 +366,10 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
vaultFilterData = VAULT_FILTER_DATA.copy(
|
||||
selectedVaultFilterType = VaultFilterType.MyVault,
|
||||
),
|
||||
viewState = vaultData.toViewState(VaultFilterType.MyVault),
|
||||
viewState = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.MyVault,
|
||||
),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
|
@ -408,6 +414,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
|
@ -429,6 +436,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
collectionItems = listOf(),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
)
|
||||
val viewModel = createViewModel()
|
||||
|
@ -540,6 +548,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
|
@ -637,6 +646,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
dialog = VaultState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
|
@ -734,6 +744,7 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
dialog = VaultState.DialogState.Error(
|
||||
title = R.string.internet_connection_required_title.asText(),
|
||||
|
@ -806,6 +817,15 @@ class VaultViewModelTest : BaseViewModelTest() {
|
|||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `VerificationCodesClick should emit NavigateToVerificationCodeScreen`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.VerificationCodesClick)
|
||||
assertEquals(VaultEvent.NavigateToVerificationCodeScreen, awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `AddItemClick should emit NavigateToAddItemScreen`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
|
@ -1057,4 +1077,5 @@ private fun createMockVaultState(
|
|||
viewState = viewState,
|
||||
dialog = dialog,
|
||||
isSwitchingAccounts = false,
|
||||
isPremium = true,
|
||||
)
|
||||
|
|
|
@ -23,7 +23,10 @@ class VaultDataExtensionsTest {
|
|||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
)
|
||||
|
||||
val actual = vaultData.toViewState(vaultFilterType = VaultFilterType.AllVaults)
|
||||
val actual = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.AllVaults,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState.ViewState.Content(
|
||||
|
@ -48,6 +51,7 @@ class VaultDataExtensionsTest {
|
|||
),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
actual,
|
||||
)
|
||||
|
@ -66,7 +70,10 @@ class VaultDataExtensionsTest {
|
|||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
)
|
||||
|
||||
val actual = vaultData.toViewState(vaultFilterType = VaultFilterType.MyVault)
|
||||
val actual = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.MyVault,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState.ViewState.Content(
|
||||
|
@ -85,6 +92,7 @@ class VaultDataExtensionsTest {
|
|||
collectionItems = listOf(),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
actual,
|
||||
)
|
||||
|
@ -107,6 +115,7 @@ class VaultDataExtensionsTest {
|
|||
)
|
||||
|
||||
val actual = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.OrganizationVault(
|
||||
organizationId = "mockOrganizationId-1",
|
||||
organizationName = "Mock Organization 1",
|
||||
|
@ -130,6 +139,7 @@ class VaultDataExtensionsTest {
|
|||
),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
actual,
|
||||
)
|
||||
|
@ -144,7 +154,10 @@ class VaultDataExtensionsTest {
|
|||
sendViewList = emptyList(),
|
||||
)
|
||||
|
||||
val actual = vaultData.toViewState(vaultFilterType = VaultFilterType.AllVaults)
|
||||
val actual = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.AllVaults,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState.ViewState.NoItems,
|
||||
|
@ -161,11 +174,78 @@ class VaultDataExtensionsTest {
|
|||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
)
|
||||
|
||||
val actual = vaultData.toViewState(vaultFilterType = VaultFilterType.AllVaults)
|
||||
val actual = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.AllVaults,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState.ViewState.NoItems,
|
||||
actual,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `toViewState should return 1 for totpItemsCount if user has premium and has one totp item`() {
|
||||
val vaultData = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1)),
|
||||
collectionViewList = listOf(),
|
||||
folderViewList = listOf(),
|
||||
sendViewList = listOf(),
|
||||
)
|
||||
|
||||
val actual = vaultData.toViewState(
|
||||
isPremium = true,
|
||||
vaultFilterType = VaultFilterType.AllVaults,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState.ViewState.Content(
|
||||
loginItemsCount = 1,
|
||||
cardItemsCount = 0,
|
||||
identityItemsCount = 0,
|
||||
secureNoteItemsCount = 0,
|
||||
favoriteItems = listOf(),
|
||||
folderItems = listOf(),
|
||||
collectionItems = listOf(),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 1,
|
||||
),
|
||||
actual,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `toViewState should return 0 for totpItemsCount if user does not have premium and has any totp items`() {
|
||||
val vaultData = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1)),
|
||||
collectionViewList = listOf(),
|
||||
folderViewList = listOf(),
|
||||
sendViewList = listOf(),
|
||||
)
|
||||
|
||||
val actual = vaultData.toViewState(
|
||||
isPremium = false,
|
||||
vaultFilterType = VaultFilterType.AllVaults,
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
VaultState.ViewState.Content(
|
||||
loginItemsCount = 1,
|
||||
cardItemsCount = 0,
|
||||
identityItemsCount = 0,
|
||||
secureNoteItemsCount = 0,
|
||||
favoriteItems = listOf(),
|
||||
folderItems = listOf(),
|
||||
collectionItems = listOf(),
|
||||
noFolderItems = listOf(),
|
||||
trashItemsCount = 0,
|
||||
totpItemsCount = 0,
|
||||
),
|
||||
actual,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue