[PM-37289] fix: Refresh archive row after premium upgrade (#6949)

This commit is contained in:
Patrick Honkonen
2026-05-20 15:19:58 -04:00
committed by GitHub
parent a9048c6393
commit 31011b5789
2 changed files with 110 additions and 3 deletions

View File

@@ -1391,6 +1391,8 @@ class VaultViewModel @Inject constructor(
.any(),
)
val appBarTitle = vaultFilterData.toAppBarTitle()
val previousIsPremium = state.isPremium
val nextIsPremium = userState.activeAccount.isPremium
mutableStateFlow.update {
val accountSummaries = userState.toAccountSummaries()
@@ -1401,10 +1403,20 @@ class VaultViewModel @Inject constructor(
avatarColorString = activeAccountSummary.avatarColorHex,
accountSummaries = accountSummaries,
vaultFilterData = vaultFilterData,
isPremium = userState.activeAccount.isPremium,
isPremium = nextIsPremium,
showImportActionCard = firstTimeState.showImportLoginsCard,
)
}
// Archive UI fields (count, lock icon, "Premium required" subtext) are precomputed
// from isPremium when the viewState is built. Recompute when isPremium transitions
// so the row reflects the new entitlement immediately after upgrade.
if (previousIsPremium != nextIsPremium) {
updateViewState(
vaultData = vaultRepository.vaultDataStateFlow.value,
validTotpIds = state.validTotpIds,
)
}
}
private fun handleVaultDataReceive(action: VaultAction.Internal.VaultDataReceive) {

View File

@@ -49,17 +49,17 @@ import com.x8bit.bitwarden.data.platform.manager.network.NetworkConnectionManage
import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
import com.x8bit.bitwarden.data.platform.repository.util.FakeEnvironmentRepository
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockBankAccountView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockDriversLicenseView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockPassportView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCardListView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCardView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherListView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCollectionView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockDecryptCipherListResult
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockDriversLicenseView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockFolderView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockLoginListView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockLoginView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockPassportView
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSdkCipher
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSendView
import com.x8bit.bitwarden.data.vault.manager.model.GetCipherResult
@@ -2429,6 +2429,101 @@ class VaultViewModelTest : BaseViewModelTest() {
)
}
@Test
fun `isPremium transitioning from false to true should refresh archive viewState fields`() =
runTest {
mutableUserStateFlow.update {
DEFAULT_USER_STATE.copy(
accounts = listOf(
DEFAULT_ACTIVE_ACCOUNT.copy(isPremium = false),
DEFAULT_INACTIVE_ACCOUNT,
),
)
}
mutableVaultDataStateFlow.update {
DataState.Loaded(
VaultData(
decryptCipherListResult = createMockDecryptCipherListResult(
number = 1,
successes = listOf(
createMockCipherListView(number = 1, isArchived = false),
),
failures = emptyList(),
),
collectionViewList = emptyList(),
folderViewList = emptyList(),
sendViewList = emptyList(),
),
)
}
val viewModel = createViewModel()
assertEquals(
VaultState.ViewState.Content(
loginItemsCount = 1,
cardItemsCount = 0,
identityItemsCount = 0,
secureNoteItemsCount = 0,
favoriteItems = listOf(),
folderItems = listOf(),
collectionItems = listOf(),
noFolderItems = listOf(),
trashItemsCount = 0,
totpItemsCount = 0,
itemTypesCount = CipherType.entries.size,
sshKeyItemsCount = 0,
bankAccountItemsCount = 0,
licenseItemsCount = 0,
passportItemsCount = 0,
archivedItemsCount = null,
archiveSubText = BitwardenString.premium_subscription_required.asText(),
archiveEndIcon = BitwardenDrawable.ic_locked,
showCardGroup = true,
showBankAccountGroup = false,
showLicenseGroup = false,
showPassportGroup = false,
),
viewModel.stateFlow.value.viewState,
)
mutableUserStateFlow.update {
DEFAULT_USER_STATE.copy(
accounts = listOf(
DEFAULT_ACTIVE_ACCOUNT.copy(isPremium = true),
DEFAULT_INACTIVE_ACCOUNT,
),
)
}
assertEquals(
VaultState.ViewState.Content(
loginItemsCount = 1,
cardItemsCount = 0,
identityItemsCount = 0,
secureNoteItemsCount = 0,
favoriteItems = listOf(),
folderItems = listOf(),
collectionItems = listOf(),
noFolderItems = listOf(),
trashItemsCount = 0,
totpItemsCount = 0,
itemTypesCount = CipherType.entries.size,
sshKeyItemsCount = 0,
bankAccountItemsCount = 0,
licenseItemsCount = 0,
passportItemsCount = 0,
archivedItemsCount = 0,
archiveSubText = null,
archiveEndIcon = null,
showCardGroup = true,
showBankAccountGroup = false,
showLicenseGroup = false,
showPassportGroup = false,
),
viewModel.stateFlow.value.viewState,
)
}
@Test
fun `TrashClick should emit NavigateToItemListing event with Trash type`() = runTest {
val viewModel = createViewModel()