Update Item listing and search screens to user immutable lists (#6037)

This commit is contained in:
David Perez
2025-10-16 15:43:52 +00:00
committed by GitHub
parent 4b96007a77
commit 8a90d77fd7
9 changed files with 148 additions and 116 deletions
@@ -665,8 +665,8 @@ private fun ContentPreview() {
ItemListingContent(
state = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = listOf(
favoriteItems = persistentListOf(),
itemList = persistentListOf(
VerificationCodeDisplayItem(
id = "",
title = "Local item",
@@ -681,13 +681,13 @@ private fun ContentPreview() {
),
),
sharedItems = SharedCodesDisplayState.Codes(
sections = listOf(
sections = persistentListOf(
SharedCodesDisplayState.SharedCodesAccountSection(
id = "id",
label =
"longemailaddress+verification+codes@email.com | Bitawrden.eu (1)"
.asText(),
codes = listOf(
codes = persistentListOf(
VerificationCodeDisplayItem(
id = "",
title = "Shared item",
@@ -1,7 +1,7 @@
package com.bitwarden.authenticator.ui.authenticator.feature.itemlisting
import android.net.Uri
import android.os.Parcelable
import androidx.core.net.toUri
import androidx.lifecycle.viewModelScope
import com.bitwarden.authenticator.data.authenticator.datasource.disk.entity.AuthenticatorItemAlgorithm
import com.bitwarden.authenticator.data.authenticator.datasource.disk.entity.AuthenticatorItemEntity
@@ -31,6 +31,9 @@ import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.util.Text
import com.bitwarden.ui.util.asText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
@@ -478,7 +481,7 @@ class ItemListingViewModel @Inject constructor(
SharedVerificationCodesState.Loading,
SharedVerificationCodesState.OsVersionNotSupported,
SharedVerificationCodesState.SyncNotEnabled,
-> SharedCodesDisplayState.Codes(emptyList())
-> SharedCodesDisplayState.Codes(persistentListOf())
is SharedVerificationCodesState.Success -> {
val viewState = state.viewState as? ItemListingState.ViewState.Content
@@ -511,7 +514,8 @@ class ItemListingViewModel @Inject constructor(
.value,
allowLongPressActions = true,
)
},
}
.toImmutableList(),
itemList = localItems
.filter { it.source is AuthenticatorItem.Source.Local && !it.source.isFavorite }
.map {
@@ -522,7 +526,8 @@ class ItemListingViewModel @Inject constructor(
.value,
allowLongPressActions = true,
)
},
}
.toImmutableList(),
sharedItems = sharedItemsState,
actionCard = action.sharedCodesState.toActionCard(),
)
@@ -590,15 +595,18 @@ class ItemListingViewModel @Inject constructor(
private fun handleSectionExpandedClick(action: ItemListingAction.SectionExpandedClick) {
updateSharedItems { codes ->
codes.copy(
sections = codes.sections.map {
it.copy(
isExpanded = if (it == action.section) {
!it.isExpanded
} else {
it.isExpanded
},
)
},
sections = codes
.sections
.map {
it.copy(
isExpanded = if (it == action.section) {
!it.isExpanded
} else {
it.isExpanded
},
)
}
.toImmutableList(),
)
}
}
@@ -631,7 +639,7 @@ class ItemListingViewModel @Inject constructor(
}
private fun String.toAuthenticatorEntityOrNull(): AuthenticatorItemEntity? {
val uri = Uri.parse(this)
val uri = this.toUri()
val type = AuthenticatorItemType
.entries
@@ -747,8 +755,8 @@ data class ItemListingState(
@Parcelize
data class Content(
val actionCard: ActionCardState,
val favoriteItems: List<VerificationCodeDisplayItem>,
val itemList: List<VerificationCodeDisplayItem>,
val favoriteItems: ImmutableList<VerificationCodeDisplayItem>,
val itemList: ImmutableList<VerificationCodeDisplayItem>,
val sharedItems: SharedCodesDisplayState,
) : ViewState() {
@@ -18,6 +18,9 @@ import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.util.Text
import com.bitwarden.ui.util.asText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -166,7 +169,7 @@ class ItemSearchViewModel @Inject constructor(
SharedVerificationCodesState.Loading,
SharedVerificationCodesState.OsVersionNotSupported,
SharedVerificationCodesState.SyncNotEnabled,
-> SharedCodesDisplayState.Codes(emptyList())
-> SharedCodesDisplayState.Codes(persistentListOf())
is SharedVerificationCodesState.Success -> {
sharedData
@@ -184,15 +187,17 @@ class ItemSearchViewModel @Inject constructor(
else -> {
ItemSearchState.ViewState.Content(
itemList = filteredLocalCodes.map {
it.toDisplayItem(
alertThresholdSeconds = 7,
sharedVerificationCodesState = authenticatorRepository
.sharedCodesStateFlow
.value,
allowLongPressActions = false,
)
},
itemList = filteredLocalCodes
.map {
it.toDisplayItem(
alertThresholdSeconds = 7,
sharedVerificationCodesState = authenticatorRepository
.sharedCodesStateFlow
.value,
allowLongPressActions = false,
)
}
.toImmutableList(),
sharedItems = sharedItemsState,
)
}
@@ -219,7 +224,7 @@ data class ItemSearchState(
*/
@Parcelize
data class Content(
val itemList: List<VerificationCodeDisplayItem>,
val itemList: ImmutableList<VerificationCodeDisplayItem>,
val sharedItems: SharedCodesDisplayState,
) : ViewState() {
/**
@@ -6,6 +6,7 @@ import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedC
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.util.asText
import kotlinx.collections.immutable.toImmutableList
/**
* Convert [SharedVerificationCodesState.Success] into [SharedCodesDisplayState.Codes].
@@ -40,12 +41,12 @@ fun SharedVerificationCodesState.Success.toSharedCodesDisplayState(
it.key.environmentLabel,
it.value.size,
),
codes = it.value,
codes = it.value.toImmutableList(),
isExpanded = currentSections
.find { section -> section.id == it.key.userId }
?.isExpanded
?: true,
)
}
.let { SharedCodesDisplayState.Codes(it) }
.let { SharedCodesDisplayState.Codes(it.toImmutableList()) }
}
@@ -2,6 +2,7 @@ package com.bitwarden.authenticator.ui.platform.components.listitem.model
import android.os.Parcelable
import com.bitwarden.ui.util.Text
import kotlinx.collections.immutable.ImmutableList
import kotlinx.parcelize.Parcelize
/**
@@ -19,7 +20,9 @@ sealed class SharedCodesDisplayState : Parcelable {
* Display the given [sections] of verification codes.
*/
@Parcelize
data class Codes(val sections: List<SharedCodesAccountSection>) : SharedCodesDisplayState()
data class Codes(
val sections: ImmutableList<SharedCodesAccountSection>,
) : SharedCodesDisplayState()
/**
* Models a section of shared authenticator codes to be displayed.
@@ -28,7 +31,7 @@ sealed class SharedCodesDisplayState : Parcelable {
data class SharedCodesAccountSection(
val id: String,
val label: Text,
val codes: List<VerificationCodeDisplayItem>,
val codes: ImmutableList<VerificationCodeDisplayItem>,
val isExpanded: Boolean,
) : Parcelable
@@ -9,10 +9,10 @@ import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollTo
import androidx.compose.ui.test.performTouchInput
import androidx.core.net.toUri
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VaultDropdownMenuAction
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
import com.bitwarden.authenticator.ui.platform.base.AuthenticatorComposeTest
import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedCodesDisplayState
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VaultDropdownMenuAction
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
import com.bitwarden.authenticator.ui.platform.manager.permissions.FakePermissionManager
import com.bitwarden.authenticator.ui.platform.util.startBitwardenAccountSettings
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
@@ -27,6 +27,7 @@ import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.runs
import io.mockk.verify
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import org.junit.Before
@@ -117,8 +118,8 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = emptyList(),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Error,
),
)
@@ -130,9 +131,9 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = emptyList(),
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
@@ -146,12 +147,10 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = emptyList(),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(
sections = listOf(
SHARED_ACCOUNTS_SECTION,
),
sections = persistentListOf(SHARED_ACCOUNTS_SECTION),
),
),
)
@@ -229,9 +228,9 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.update {
it.copy(
viewState = ItemListingState.ViewState.Content(
favoriteItems = emptyList(),
itemList = emptyList(),
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
actionCard = ItemListingState.ActionCardState.SyncWithBitwarden,
),
)
@@ -247,9 +246,9 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.update {
it.copy(
viewState = ItemListingState.ViewState.Content(
favoriteItems = emptyList(),
itemList = emptyList(),
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
actionCard = ItemListingState.ActionCardState.SyncWithBitwarden,
),
)
@@ -279,9 +278,9 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
fun `on sync with bitwarden action card dismiss in full state should send SyncWithBitwardenDismiss`() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
favoriteItems = emptyList(),
itemList = emptyList(),
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
actionCard = ItemListingState.ActionCardState.SyncWithBitwarden,
),
)
@@ -308,9 +307,9 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
fun `on download bitwarden click in full state should send DownloadBitwardenClick`() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
favoriteItems = emptyList(),
itemList = emptyList(),
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
actionCard = ItemListingState.ActionCardState.DownloadBitwardenApp,
),
)
@@ -337,9 +336,9 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
fun `on download bitwarden dismiss in full state should send DownloadBitwardenDismiss`() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
favoriteItems = emptyList(),
itemList = emptyList(),
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
actionCard = ItemListingState.ActionCardState.DownloadBitwardenApp,
),
)
@@ -354,8 +353,8 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = listOf(LOCAL_CODE),
favoriteItems = persistentListOf(),
itemList = persistentListOf(LOCAL_CODE),
sharedItems = SharedCodesDisplayState.Error,
),
)
@@ -383,8 +382,8 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = listOf(LOCAL_CODE.copy(showMoveToBitwarden = false)),
favoriteItems = persistentListOf(),
itemList = persistentListOf(LOCAL_CODE.copy(showMoveToBitwarden = false)),
sharedItems = SharedCodesDisplayState.Error,
),
)
@@ -403,9 +402,9 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = emptyList(),
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
}
@@ -428,12 +427,10 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = listOf(LOCAL_CODE),
favoriteItems = persistentListOf(),
itemList = persistentListOf(LOCAL_CODE),
sharedItems = SharedCodesDisplayState.Codes(
sections = listOf(
SHARED_ACCOUNTS_SECTION,
),
sections = persistentListOf(SHARED_ACCOUNTS_SECTION),
),
),
)
@@ -450,12 +447,12 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
@Test
fun `shared codes header click should emit SectionExpandedClick`() {
val sharedItems = SharedCodesDisplayState.Codes(
sections = listOf(SHARED_ACCOUNTS_SECTION),
sections = persistentListOf(SHARED_ACCOUNTS_SECTION),
)
val viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = listOf(LOCAL_CODE),
favoriteItems = persistentListOf(),
itemList = persistentListOf(LOCAL_CODE),
sharedItems = sharedItems,
)
mutableStateFlow.value = DEFAULT_STATE.copy(viewState = viewState)
@@ -472,12 +469,12 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
@Test
fun `shared codes header should be displayed and collapsed when syncing is enabled`() {
val sharedItems = SharedCodesDisplayState.Codes(
sections = listOf(SHARED_ACCOUNTS_SECTION),
sections = persistentListOf(SHARED_ACCOUNTS_SECTION),
)
val viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = listOf(LOCAL_CODE),
favoriteItems = persistentListOf(),
itemList = persistentListOf(LOCAL_CODE),
sharedItems = sharedItems,
)
mutableStateFlow.value = DEFAULT_STATE.copy(viewState = viewState)
@@ -493,7 +490,7 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = viewState.copy(
sharedItems = sharedItems.copy(
sections = listOf(SHARED_ACCOUNTS_SECTION.copy(isExpanded = false)),
sections = persistentListOf(SHARED_ACCOUNTS_SECTION.copy(isExpanded = false)),
),
),
)
@@ -512,12 +509,10 @@ class ItemListingScreenTest : AuthenticatorComposeTest() {
mutableStateFlow.value = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = listOf(LOCAL_CODE),
favoriteItems = persistentListOf(),
itemList = persistentListOf(LOCAL_CODE),
sharedItems = SharedCodesDisplayState.Codes(
sections = listOf(
SHARED_ACCOUNTS_SECTION,
),
sections = persistentListOf(SHARED_ACCOUNTS_SECTION),
),
),
)
@@ -555,7 +550,7 @@ private val LOCAL_CODE = VerificationCodeDisplayItem(
private val SHARED_ACCOUNTS_SECTION = SharedCodesDisplayState.SharedCodesAccountSection(
id = "id",
label = "test@test.com | bitwarden.com (1)".asText(),
codes = listOf(
codes = persistentListOf(
VerificationCodeDisplayItem(
id = "1",
title = "bitwarden.com",
@@ -25,6 +25,8 @@ import io.mockk.just
import io.mockk.mockk
import io.mockk.runs
import io.mockk.verify
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.emptyFlow
@@ -109,7 +111,7 @@ class ItemListingViewModelTest : BaseViewModelTest() {
actionCard = ItemListingState.ActionCardState.DownloadBitwardenApp,
favoriteItems = LOCAL_FAVORITE_ITEMS,
itemList = LOCAL_NON_FAVORITE_ITEMS,
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
every { settingsRepository.hasUserDismissedDownloadBitwardenCard } returns false
@@ -127,7 +129,7 @@ class ItemListingViewModelTest : BaseViewModelTest() {
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = LOCAL_FAVORITE_ITEMS,
itemList = LOCAL_NON_FAVORITE_ITEMS,
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
every { settingsRepository.hasUserDismissedDownloadBitwardenCard } returns true
@@ -160,8 +162,12 @@ class ItemListingViewModelTest : BaseViewModelTest() {
val expectedState = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = LOCAL_FAVORITE_ITEMS.map { it.copy(showMoveToBitwarden = true) },
itemList = LOCAL_NON_FAVORITE_ITEMS.map { it.copy(showMoveToBitwarden = true) },
favoriteItems = LOCAL_FAVORITE_ITEMS
.map { it.copy(showMoveToBitwarden = true) }
.toImmutableList(),
itemList = LOCAL_NON_FAVORITE_ITEMS
.map { it.copy(showMoveToBitwarden = true) }
.toImmutableList(),
sharedItems = SHARED_DISPLAY_ITEMS,
),
)
@@ -193,8 +199,8 @@ class ItemListingViewModelTest : BaseViewModelTest() {
val expectedState = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = emptyList(),
itemList = emptyList(),
favoriteItems = persistentListOf(),
itemList = persistentListOf(),
sharedItems = SHARED_DISPLAY_ITEMS,
),
)
@@ -223,7 +229,7 @@ class ItemListingViewModelTest : BaseViewModelTest() {
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = LOCAL_FAVORITE_ITEMS,
itemList = LOCAL_NON_FAVORITE_ITEMS,
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
every { settingsRepository.hasUserDismissedDownloadBitwardenCard = true } just runs
@@ -271,7 +277,7 @@ class ItemListingViewModelTest : BaseViewModelTest() {
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = LOCAL_FAVORITE_ITEMS,
itemList = LOCAL_NON_FAVORITE_ITEMS,
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
mutableSharedCodesFlow.value = SharedVerificationCodesState.SyncNotEnabled
@@ -340,7 +346,7 @@ class ItemListingViewModelTest : BaseViewModelTest() {
actionCard = ItemListingState.ActionCardState.SyncWithBitwarden,
favoriteItems = LOCAL_FAVORITE_ITEMS,
itemList = LOCAL_NON_FAVORITE_ITEMS,
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
every { settingsRepository.hasUserDismissedSyncWithBitwardenCard } returns false
@@ -358,7 +364,7 @@ class ItemListingViewModelTest : BaseViewModelTest() {
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = LOCAL_FAVORITE_ITEMS,
itemList = LOCAL_NON_FAVORITE_ITEMS,
sharedItems = SharedCodesDisplayState.Codes(emptyList()),
sharedItems = SharedCodesDisplayState.Codes(persistentListOf()),
),
)
every { settingsRepository.hasUserDismissedSyncWithBitwardenCard } returns true
@@ -511,10 +517,17 @@ class ItemListingViewModelTest : BaseViewModelTest() {
val expectedState = DEFAULT_STATE.copy(
viewState = ItemListingState.ViewState.Content(
actionCard = ItemListingState.ActionCardState.None,
favoriteItems = LOCAL_FAVORITE_ITEMS.map { it.copy(showMoveToBitwarden = true) },
itemList = LOCAL_NON_FAVORITE_ITEMS.map { it.copy(showMoveToBitwarden = true) },
favoriteItems = LOCAL_FAVORITE_ITEMS
.map { it.copy(showMoveToBitwarden = true) }
.toImmutableList(),
itemList = LOCAL_NON_FAVORITE_ITEMS
.map { it.copy(showMoveToBitwarden = true) }
.toImmutableList(),
sharedItems = SHARED_DISPLAY_ITEMS.copy(
sections = SHARED_DISPLAY_ITEMS.sections.map { it.copy(isExpanded = false) },
sections = SHARED_DISPLAY_ITEMS
.sections
.map { it.copy(isExpanded = false) }
.toImmutableList(),
),
),
)
@@ -614,5 +627,7 @@ private val LOCAL_DISPLAY_ITEMS = LOCAL_VERIFICATION_ITEMS.map {
private val SHARED_DISPLAY_ITEMS = SharedVerificationCodesState.Success(SHARED_VERIFICATION_ITEMS)
.toSharedCodesDisplayState(AUTHENTICATOR_ALERT_SECONDS)
private val LOCAL_FAVORITE_ITEMS = LOCAL_DISPLAY_ITEMS.filter { it.favorite }
private val LOCAL_NON_FAVORITE_ITEMS = LOCAL_DISPLAY_ITEMS.filterNot { it.favorite }
private val LOCAL_FAVORITE_ITEMS = LOCAL_DISPLAY_ITEMS.filter { it.favorite }.toImmutableList()
private val LOCAL_NON_FAVORITE_ITEMS = LOCAL_DISPLAY_ITEMS
.filterNot { it.favorite }
.toImmutableList()
@@ -17,6 +17,8 @@ import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.util.asText
import io.mockk.every
import io.mockk.mockk
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.MutableStateFlow
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@@ -75,7 +77,7 @@ class ItemSearchViewModelTest : BaseViewModelTest() {
assertEquals(
ItemSearchState.ViewState.Content(
itemList = LOCAL_DISPLAY_ITEMS,
sharedItems = SharedCodesDisplayState.Codes(sections = emptyList()),
sharedItems = SharedCodesDisplayState.Codes(sections = persistentListOf()),
),
viewModel.stateFlow.value.viewState,
)
@@ -91,8 +93,10 @@ class ItemSearchViewModelTest : BaseViewModelTest() {
assertEquals(
ItemSearchState.ViewState.Content(
itemList = LOCAL_DISPLAY_ITEMS.map { it.copy(showMoveToBitwarden = false) },
sharedItems = SharedCodesDisplayState.Codes(sections = emptyList()),
itemList = LOCAL_DISPLAY_ITEMS
.map { it.copy(showMoveToBitwarden = false) }
.toImmutableList(),
sharedItems = SharedCodesDisplayState.Codes(sections = persistentListOf()),
),
viewModel.stateFlow.value.viewState,
)
@@ -122,7 +126,7 @@ private val SHARED_ITEMS = listOf(
)
private val SHARED_DISPLAY_ITEMS = SharedCodesDisplayState.Codes(
sections = listOf(
sections = persistentListOf(
SharedCodesDisplayState.SharedCodesAccountSection(
id = "mockUserId-2",
label = BitwardenString.shared_accounts_header.asText(
@@ -130,7 +134,7 @@ private val SHARED_DISPLAY_ITEMS = SharedCodesDisplayState.Codes(
"mockkEnvironmentLabel-2",
1,
),
codes = listOf(
codes = persistentListOf(
VerificationCodeDisplayItem(
id = "mockId-2",
title = "mockIssuer-2",
@@ -149,7 +153,7 @@ private val SHARED_DISPLAY_ITEMS = SharedCodesDisplayState.Codes(
),
)
private val LOCAL_DISPLAY_ITEMS = listOf(
private val LOCAL_DISPLAY_ITEMS = persistentListOf(
VerificationCodeDisplayItem(
id = LOCAL_ITEMS[0].id,
authCode = LOCAL_ITEMS[0].code,
@@ -7,6 +7,7 @@ import com.bitwarden.authenticator.ui.platform.components.listitem.model.SharedC
import com.bitwarden.authenticator.ui.platform.components.listitem.model.VerificationCodeDisplayItem
import com.bitwarden.ui.platform.resource.BitwardenString
import com.bitwarden.ui.util.asText
import kotlinx.collections.immutable.persistentListOf
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
@@ -15,7 +16,7 @@ class SharedVerificationCodesStateTest {
@Test
fun `toSharedCodesDisplayState on empty list should return empty list`() {
val state = SharedVerificationCodesState.Success(emptyList())
val expected = SharedCodesDisplayState.Codes(emptyList())
val expected = SharedCodesDisplayState.Codes(persistentListOf())
assertEquals(
expected,
state.toSharedCodesDisplayState(ALERT_THRESHOLD),
@@ -59,7 +60,7 @@ class SharedVerificationCodesStateTest {
),
)
val expected = SharedCodesDisplayState.Codes(
sections = listOf(
sections = persistentListOf(
SharedCodesDisplayState.SharedCodesAccountSection(
id = "user1",
label = BitwardenString.shared_accounts_header.asText(
@@ -67,7 +68,7 @@ class SharedVerificationCodesStateTest {
"bitwarden.com",
1,
),
codes = listOf(
codes = persistentListOf(
VerificationCodeDisplayItem(
authCode = "123456",
periodSeconds = 30,
@@ -90,7 +91,7 @@ class SharedVerificationCodesStateTest {
"bitwarden.eu",
1,
),
codes = listOf(
codes = persistentListOf(
VerificationCodeDisplayItem(
authCode = "987654",
periodSeconds = 30,
@@ -151,7 +152,7 @@ class SharedVerificationCodesStateTest {
),
)
val expected = SharedCodesDisplayState.Codes(
sections = listOf(
sections = persistentListOf(
SharedCodesDisplayState.SharedCodesAccountSection(
id = "user1",
label = BitwardenString.shared_accounts_header.asText(
@@ -159,7 +160,7 @@ class SharedVerificationCodesStateTest {
"bitwarden.com",
1,
),
codes = listOf(
codes = persistentListOf(
VerificationCodeDisplayItem(
authCode = "123456",
periodSeconds = 30,
@@ -182,7 +183,7 @@ class SharedVerificationCodesStateTest {
"bitwarden.eu",
1,
),
codes = listOf(
codes = persistentListOf(
VerificationCodeDisplayItem(
authCode = "987654",
periodSeconds = 30,