PM-19723 Group "no folder" items when there is a collection present. (#4941)

This commit is contained in:
Dave Severns
2025-03-31 15:19:25 -04:00
committed by GitHub
parent 75af4868e2
commit 05094cf6e7
3 changed files with 101 additions and 4 deletions

View File

@@ -67,6 +67,8 @@ fun VaultData.toViewState(
VaultState.ViewState.NoItems
} else {
val totpItems = filteredCipherViewList.filter { it.login?.totp != null }
val shouldShowUnGroupedItems = filteredCollectionViewList.isEmpty() &&
noFolderItems.size < NO_FOLDER_ITEM_THRESHOLD
VaultState.ViewState.Content(
itemTypesCount = itemTypesCount,
totpItemsCount = if (isPremium) {
@@ -103,7 +105,7 @@ fun VaultData.toViewState(
)
}
.let { folderItems ->
if (noFolderItems.size < NO_FOLDER_ITEM_THRESHOLD) {
if (shouldShowUnGroupedItems) {
folderItems
} else {
folderItems.plus(
@@ -124,7 +126,7 @@ fun VaultData.toViewState(
isPremiumUser = isPremium,
)
}
.takeIf { it.size < NO_FOLDER_ITEM_THRESHOLD }
.takeIf { shouldShowUnGroupedItems }
.orEmpty(),
collectionItems = filteredCollectionViewList
.filter { it.id != null }

View File

@@ -672,6 +672,11 @@ class VaultViewModelTest : BaseViewModelTest() {
name = "mockName-5".asText(),
itemCount = 1,
),
VaultState.ViewState.FolderItem(
id = null,
name = R.string.folder_none.asText(),
itemCount = 0,
),
),
collectionItems = listOf(
VaultState.ViewState.CollectionItem(
@@ -830,6 +835,11 @@ class VaultViewModelTest : BaseViewModelTest() {
name = "mockName-1".asText(),
itemCount = 1,
),
VaultState.ViewState.FolderItem(
id = null,
name = R.string.folder_none.asText(),
itemCount = 0,
),
),
collectionItems = listOf(
VaultState.ViewState.CollectionItem(
@@ -930,6 +940,11 @@ class VaultViewModelTest : BaseViewModelTest() {
name = "mockName-1".asText(),
itemCount = 1,
),
VaultState.ViewState.FolderItem(
id = null,
name = R.string.folder_none.asText(),
itemCount = 0,
),
),
collectionItems = listOf(
VaultState.ViewState.CollectionItem(
@@ -1028,6 +1043,11 @@ class VaultViewModelTest : BaseViewModelTest() {
name = "mockName-1".asText(),
itemCount = 1,
),
VaultState.ViewState.FolderItem(
id = null,
name = R.string.folder_none.asText(),
itemCount = 0,
),
),
collectionItems = listOf(
VaultState.ViewState.CollectionItem(

View File

@@ -19,6 +19,8 @@ import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.components.model.IconData
import com.x8bit.bitwarden.ui.platform.components.model.IconRes
import com.x8bit.bitwarden.ui.vault.feature.itemlisting.model.ListingItemOverflowAction
import com.x8bit.bitwarden.ui.vault.feature.util.toLabelIcons
import com.x8bit.bitwarden.ui.vault.feature.util.toOverflowActions
import com.x8bit.bitwarden.ui.vault.feature.vault.VaultState
import com.x8bit.bitwarden.ui.vault.feature.vault.model.VaultFilterType
import io.mockk.every
@@ -86,8 +88,12 @@ class VaultDataExtensionsTest {
name = "Folder".asText(),
itemCount = 0,
),
VaultState.ViewState.FolderItem(
id = null,
name = R.string.folder_none.asText(),
itemCount = 0,
),
),
collectionItems = listOf(
VaultState.ViewState.CollectionItem(
id = "mockId-1",
@@ -194,6 +200,11 @@ class VaultDataExtensionsTest {
name = "mockName-1".asText(),
itemCount = 1,
),
VaultState.ViewState.FolderItem(
id = null,
name = R.string.folder_none.asText(),
itemCount = 0,
),
),
collectionItems = listOf(
VaultState.ViewState.CollectionItem(
@@ -719,6 +730,66 @@ class VaultDataExtensionsTest {
unmockkStatic(Uri::class)
}
@Suppress("MaxLineLength")
@Test
fun `toViewState with under 100 no folder items and no collections should not show no folder option`() {
mockkStatic(Uri::class)
val uriMock = mockk<Uri>()
every { Uri.parse(any()) } returns uriMock
every { uriMock.host } returns "www.mockuri1.com"
val mockCipher = createMockCipherView(number = 1, folderId = null)
val vaultData = VaultData(
cipherViewList = listOf(mockCipher),
collectionViewList = listOf(),
folderViewList = listOf(),
sendViewList = listOf(),
)
val actual = vaultData.toViewState(
isPremium = true,
isIconLoadingDisabled = false,
baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl,
vaultFilterType = VaultFilterType.AllVaults,
hasMasterPassword = true,
)
assertEquals(
VaultState.ViewState.Content(
loginItemsCount = 1,
cardItemsCount = 0,
identityItemsCount = 0,
secureNoteItemsCount = 0,
favoriteItems = listOf(),
folderItems = listOf(),
collectionItems = listOf(),
noFolderItems = listOf(
VaultState.ViewState.VaultItem.Login(
id = "mockId-1",
name = mockCipher.name.asText(),
startIcon = IconData.Network(
uri = "https://vault.bitwarden.com/icons/www.mockuri1.com/icon.png",
fallbackIconRes = R.drawable.ic_globe,
),
startIconTestTag = "LoginCipherIcon",
extraIconList = mockCipher.toLabelIcons(),
overflowOptions = mockCipher.toOverflowActions(
hasMasterPassword = true,
isPremiumUser = true,
),
shouldShowMasterPasswordReprompt = false,
username = "mockUsername-1".asText(),
),
),
trashItemsCount = 0,
totpItemsCount = 1,
itemTypesCount = 5,
sshKeyItemsCount = 0,
),
actual,
)
unmockkStatic(Uri::class)
}
@Test
fun `toViewState should properly filter nested items out`() {
val vaultData = VaultData(
@@ -783,8 +854,12 @@ class VaultDataExtensionsTest {
name = "Folder".asText(),
itemCount = 0,
),
VaultState.ViewState.FolderItem(
id = null,
name = R.string.folder_none.asText(),
itemCount = 0,
),
),
noFolderItems = listOf(),
trashItemsCount = 0,
totpItemsCount = 1,