diff --git a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/UserState.kt b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/UserState.kt index d8ce09016c..4aefaf7b6b 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/UserState.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/UserState.kt @@ -65,7 +65,12 @@ data class UserState( val organizations: List, val isBiometricsEnabled: Boolean, val vaultUnlockType: VaultUnlockType = VaultUnlockType.MASTER_PASSWORD, - ) + ) { + /** + * Indicates that the user does or does not have a master password. + */ + val hasMasterPassword: Boolean get() = trustedDevice?.hasMasterPassword != false + } /** * Models the data related to trusted device encryption (TDE). diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt index 1751f1b0d7..1ed04faea3 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt @@ -97,6 +97,7 @@ class SearchViewModel @Inject constructor( baseIconUrl = environmentRepo.environment.environmentUrlData.baseIconUrl, isIconLoadingDisabled = settingsRepo.isIconLoadingDisabled, autofillSelectionData = autofillSelectionData, + hasMasterPassword = userState.activeAccount.hasMasterPassword, ) }, ) { @@ -640,6 +641,7 @@ class SearchViewModel @Inject constructor( ) .toViewState( searchTerm = state.searchTerm, + hasMasterPassword = state.hasMasterPassword, baseIconUrl = state.baseIconUrl, isIconLoadingDisabled = state.isIconLoadingDisabled, isAutofill = state.isAutofill, @@ -686,6 +688,7 @@ data class SearchState( val isIconLoadingDisabled: Boolean, // Internal val autofillSelectionData: AutofillSelectionData? = null, + val hasMasterPassword: Boolean, ) : Parcelable { /** diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensions.kt index 44750f6dc7..1ee715a343 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensions.kt @@ -140,6 +140,7 @@ private fun CipherView.matchedSearch(searchTerm: String): SortPriority? { fun List.toViewState( searchTerm: String, baseIconUrl: String, + hasMasterPassword: Boolean, isIconLoadingDisabled: Boolean, isAutofill: Boolean, ): SearchState.ViewState = @@ -149,6 +150,7 @@ fun List.toViewState( SearchState.ViewState.Content( displayItems = toDisplayItemList( baseIconUrl = baseIconUrl, + hasMasterPassword = hasMasterPassword, isIconLoadingDisabled = isIconLoadingDisabled, isAutofill = isAutofill, ), @@ -164,12 +166,14 @@ fun List.toViewState( private fun List.toDisplayItemList( baseIconUrl: String, + hasMasterPassword: Boolean, isIconLoadingDisabled: Boolean, isAutofill: Boolean, ): List = this.map { it.toDisplayItem( baseIconUrl = baseIconUrl, + hasMasterPassword = hasMasterPassword, isIconLoadingDisabled = isIconLoadingDisabled, isAutofill = isAutofill, ) @@ -177,6 +181,7 @@ private fun List.toDisplayItemList( private fun CipherView.toDisplayItem( baseIconUrl: String, + hasMasterPassword: Boolean, isIconLoadingDisabled: Boolean, isAutofill: Boolean, ): SearchState.DisplayItem = @@ -191,7 +196,7 @@ private fun CipherView.toDisplayItem( isIconLoadingDisabled = isIconLoadingDisabled, ), extraIconList = toLabelIcons(), - overflowOptions = toOverflowActions(), + overflowOptions = toOverflowActions(hasMasterPassword = hasMasterPassword), overflowTestTag = "CipherOptionsButton", totpCode = login?.totp, autofillSelectionOptions = AutofillSelectionOption diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModel.kt index 6a2db3d765..3158683e21 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModel.kt @@ -749,8 +749,7 @@ class VaultItemViewModel @Inject constructor( mutableStateFlow.update { it.copy( viewState = vaultDataState.toViewStateOrError( - isPremiumUser = userState.activeAccount.isPremium, - totpCodeItemData = vaultDataState.data?.totpCodeItemData, + account = userState.activeAccount, errorText = R.string.generic_error_message.asText(), ), ) @@ -761,8 +760,7 @@ class VaultItemViewModel @Inject constructor( mutableStateFlow.update { it.copy( viewState = vaultDataState.toViewStateOrError( - isPremiumUser = userState.activeAccount.isPremium, - totpCodeItemData = vaultDataState.data.totpCodeItemData, + account = userState.activeAccount, errorText = R.string.generic_error_message.asText(), ), ) @@ -779,8 +777,7 @@ class VaultItemViewModel @Inject constructor( mutableStateFlow.update { it.copy( viewState = vaultDataState.toViewStateOrError( - isPremiumUser = userState.activeAccount.isPremium, - totpCodeItemData = vaultDataState.data?.totpCodeItemData, + account = userState.activeAccount, errorText = R.string.internet_connection_required_title .asText() .concat( @@ -796,8 +793,7 @@ class VaultItemViewModel @Inject constructor( mutableStateFlow.update { it.copy( viewState = vaultDataState.toViewStateOrError( - isPremiumUser = userState.activeAccount.isPremium, - totpCodeItemData = vaultDataState.data.totpCodeItemData, + account = userState.activeAccount, errorText = R.string.generic_error_message.asText(), ), ) @@ -807,13 +803,16 @@ class VaultItemViewModel @Inject constructor( } private fun DataState.toViewStateOrError( - isPremiumUser: Boolean, - totpCodeItemData: TotpCodeItemData?, + account: UserState.Account, errorText: Text, ): VaultItemState.ViewState = this .data ?.cipher - ?.toViewState(isPremiumUser = isPremiumUser, totpCodeItemData = totpCodeItemData) + ?.toViewState( + isPremiumUser = account.isPremium, + hasMasterPassword = account.hasMasterPassword, + totpCodeItemData = this.data?.totpCodeItemData, + ) ?: VaultItemState.ViewState.Error(message = errorText) private fun handleValidatePasswordReceive( diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensions.kt index 85588af074..8873bde032 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensions.kt @@ -33,9 +33,10 @@ private const val FIDO2_CREDENTIAL_CREATION_TIME_PATTERN: String = "h:mm a" /** * Transforms [VaultData] into [VaultState.ViewState]. */ -@Suppress("LongMethod") +@Suppress("CyclomaticComplexMethod", "LongMethod") fun CipherView.toViewState( isPremiumUser: Boolean, + hasMasterPassword: Boolean, totpCodeItemData: TotpCodeItemData?, clock: Clock = Clock.systemDefaultZone(), ): VaultItemState.ViewState = @@ -43,7 +44,7 @@ fun CipherView.toViewState( common = VaultItemState.ViewState.Content.Common( currentCipher = this, name = name, - requiresReprompt = reprompt == CipherRepromptType.PASSWORD, + requiresReprompt = reprompt == CipherRepromptType.PASSWORD && hasMasterPassword, customFields = fields.orEmpty().map { it.toCustomField() }, lastUpdated = revisionDate.toFormattedPattern( pattern = LAST_UPDATED_DATE_TIME_PATTERN, diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index ab0e52e20c..8209cd111a 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -99,6 +99,7 @@ class VaultItemListingViewModel @Inject constructor( .any(), autofillSelectionData = specialCircumstance?.autofillSelectionData, shouldFinishOnComplete = specialCircumstance?.shouldFinishWhenComplete ?: false, + hasMasterPassword = userState.activeAccount.hasMasterPassword, ) }, ) { @@ -686,6 +687,7 @@ class VaultItemListingViewModel @Inject constructor( vaultData.toViewState( vaultFilterType = state.vaultFilterType, itemListingType = listingType, + hasMasterPassword = state.hasMasterPassword, baseIconUrl = state.baseIconUrl, isIconLoadingDisabled = state.isIconLoadingDisabled, autofillSelectionData = state.autofillSelectionData, @@ -754,6 +756,7 @@ data class VaultItemListingState( private val isPullToRefreshSettingEnabled: Boolean, val autofillSelectionData: AutofillSelectionData? = null, val shouldFinishOnComplete: Boolean = false, + val hasMasterPassword: Boolean, ) { /** * Whether or not this represents a listing screen for autofill. diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/model/ListingItemOverflowAction.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/model/ListingItemOverflowAction.kt index 092a680969..4ddefc3713 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/model/ListingItemOverflowAction.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/model/ListingItemOverflowAction.kt @@ -84,9 +84,11 @@ sealed class ListingItemOverflowAction : Parcelable { * Click on the edit cipher overflow option. */ @Parcelize - data class EditClick(val cipherId: String) : VaultAction() { + data class EditClick( + val cipherId: String, + override val requiresPasswordReprompt: Boolean, + ) : VaultAction() { override val title: Text get() = R.string.edit.asText() - override val requiresPasswordReprompt: Boolean get() = true } /** @@ -102,9 +104,11 @@ sealed class ListingItemOverflowAction : Parcelable { * Click on the copy password overflow option. */ @Parcelize - data class CopyPasswordClick(val password: String) : VaultAction() { + data class CopyPasswordClick( + val password: String, + override val requiresPasswordReprompt: Boolean, + ) : VaultAction() { override val title: Text get() = R.string.copy_password.asText() - override val requiresPasswordReprompt: Boolean get() = true } /** @@ -120,18 +124,22 @@ sealed class ListingItemOverflowAction : Parcelable { * Click on the copy number overflow option. */ @Parcelize - data class CopyNumberClick(val number: String) : VaultAction() { + data class CopyNumberClick( + val number: String, + override val requiresPasswordReprompt: Boolean, + ) : VaultAction() { override val title: Text get() = R.string.copy_number.asText() - override val requiresPasswordReprompt: Boolean get() = true } /** * Click on the copy security code overflow option. */ @Parcelize - data class CopySecurityCodeClick(val securityCode: String) : VaultAction() { + data class CopySecurityCodeClick( + val securityCode: String, + override val requiresPasswordReprompt: Boolean, + ) : VaultAction() { override val title: Text get() = R.string.copy_security_code.asText() - override val requiresPasswordReprompt: Boolean get() = true } /** diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensions.kt index 877120cc72..5d7459ed3e 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensions.kt @@ -91,10 +91,11 @@ fun SendView.determineListingPredicate( /** * Transforms a list of [CipherView] into [VaultItemListingState.ViewState]. */ -@Suppress("CyclomaticComplexMethod", "LongMethod") +@Suppress("CyclomaticComplexMethod", "LongMethod", "LongParameterList") fun VaultData.toViewState( itemListingType: VaultItemListingState.ItemListingType.Vault, vaultFilterType: VaultFilterType, + hasMasterPassword: Boolean, baseIconUrl: String, isIconLoadingDisabled: Boolean, autofillSelectionData: AutofillSelectionData?, @@ -122,6 +123,7 @@ fun VaultData.toViewState( VaultItemListingState.ViewState.Content( displayItemList = filteredCipherViewList.toDisplayItemList( baseIconUrl = baseIconUrl, + hasMasterPassword = hasMasterPassword, isIconLoadingDisabled = isIconLoadingDisabled, isAutofill = autofillSelectionData != null, ), @@ -246,12 +248,14 @@ fun VaultItemListingState.ItemListingType.updateWithAdditionalDataIfNecessary( private fun List.toDisplayItemList( baseIconUrl: String, + hasMasterPassword: Boolean, isIconLoadingDisabled: Boolean, isAutofill: Boolean, ): List = this.map { it.toDisplayItem( baseIconUrl = baseIconUrl, + hasMasterPassword = hasMasterPassword, isIconLoadingDisabled = isIconLoadingDisabled, isAutofill = isAutofill, ) @@ -270,6 +274,7 @@ private fun List.toDisplayItemList( private fun CipherView.toDisplayItem( baseIconUrl: String, + hasMasterPassword: Boolean, isIconLoadingDisabled: Boolean, isAutofill: Boolean, ): VaultItemListingState.DisplayItem = @@ -285,7 +290,7 @@ private fun CipherView.toDisplayItem( ), iconTestTag = toIconTestTag(), extraIconList = toLabelIcons(), - overflowOptions = toOverflowActions(), + overflowOptions = toOverflowActions(hasMasterPassword = hasMasterPassword), optionsTestTag = "CipherOptionsButton", isAutofill = isAutofill, shouldShowMasterPasswordReprompt = reprompt == CipherRepromptType.PASSWORD, diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensions.kt index 904b796970..885cc30c0d 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensions.kt @@ -9,28 +9,44 @@ import com.x8bit.bitwarden.ui.vault.model.VaultTrailingIcon /** * Creates the list of overflow actions to be displayed for a [CipherView]. */ -fun CipherView.toOverflowActions(): List = +fun CipherView.toOverflowActions( + hasMasterPassword: Boolean, +): List = this .id ?.let { cipherId -> listOfNotNull( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = cipherId), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = cipherId) + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = cipherId, + requiresPasswordReprompt = hasMasterPassword, + ) .takeUnless { this.deletedDate != null }, this.login?.username?.let { ListingItemOverflowAction.VaultAction.CopyUsernameClick(username = it) }, this.login?.password - ?.let { ListingItemOverflowAction.VaultAction.CopyPasswordClick(password = it) } + ?.let { + ListingItemOverflowAction.VaultAction.CopyPasswordClick( + password = it, + requiresPasswordReprompt = hasMasterPassword, + ) + } .takeIf { this.viewPassword }, this.login?.totp ?.let { ListingItemOverflowAction.VaultAction.CopyTotpClick(totpCode = it) } .takeIf { this.type == CipherType.LOGIN }, this.card?.number?.let { - ListingItemOverflowAction.VaultAction.CopyNumberClick(number = it) + ListingItemOverflowAction.VaultAction.CopyNumberClick( + number = it, + requiresPasswordReprompt = hasMasterPassword, + ) }, this.card?.code?.let { - ListingItemOverflowAction.VaultAction.CopySecurityCodeClick(securityCode = it) + ListingItemOverflowAction.VaultAction.CopySecurityCodeClick( + securityCode = it, + requiresPasswordReprompt = hasMasterPassword, + ) }, this.notes ?.let { ListingItemOverflowAction.VaultAction.CopyNoteClick(notes = it) } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt index 36c521aa82..505885aeb2 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt @@ -83,6 +83,7 @@ class VaultViewModel @Inject constructor( isPremium = userState.activeAccount.isPremium, isPullToRefreshSettingEnabled = settingsRepository.getPullToRefreshEnabledFlow().value, baseIconUrl = userState.activeAccount.environment.environmentUrlData.baseIconUrl, + hasMasterPassword = userState.activeAccount.hasMasterPassword, ) }, ) { @@ -493,6 +494,7 @@ class VaultViewModel @Inject constructor( vaultFilterType = vaultFilterTypeOrDefault, isIconLoadingDisabled = state.isIconLoadingDisabled, isPremium = state.isPremium, + hasMasterPassword = state.hasMasterPassword, errorTitle = R.string.an_error_has_occurred.asText(), errorMessage = R.string.generic_error_message.asText(), ) @@ -513,6 +515,7 @@ class VaultViewModel @Inject constructor( baseIconUrl = state.baseIconUrl, isIconLoadingDisabled = state.isIconLoadingDisabled, isPremium = state.isPremium, + hasMasterPassword = state.hasMasterPassword, vaultFilterType = vaultFilterTypeOrDefault, ), dialog = null, @@ -533,6 +536,7 @@ class VaultViewModel @Inject constructor( isPremium = state.isPremium, errorTitle = R.string.internet_connection_required_title.asText(), isIconLoadingDisabled = state.isIconLoadingDisabled, + hasMasterPassword = state.hasMasterPassword, errorMessage = R.string.internet_connection_required_message.asText(), ) sendEvent(VaultEvent.DismissPullToRefresh) @@ -545,6 +549,7 @@ class VaultViewModel @Inject constructor( baseIconUrl = state.baseIconUrl, isIconLoadingDisabled = state.isIconLoadingDisabled, isPremium = state.isPremium, + hasMasterPassword = state.hasMasterPassword, vaultFilterType = vaultFilterTypeOrDefault, ), ) @@ -610,6 +615,7 @@ data class VaultState( // Internal-use properties val isSwitchingAccounts: Boolean = false, val isPremium: Boolean, + val hasMasterPassword: Boolean, private val isPullToRefreshSettingEnabled: Boolean, val baseIconUrl: String, val isIconLoadingDisabled: Boolean, @@ -1163,6 +1169,7 @@ private fun MutableStateFlow.updateToErrorStateOrDialog( vaultFilterType: VaultFilterType, isIconLoadingDisabled: Boolean, isPremium: Boolean, + hasMasterPassword: Boolean, errorTitle: Text, errorMessage: Text, ) { @@ -1172,6 +1179,7 @@ private fun MutableStateFlow.updateToErrorStateOrDialog( viewState = vaultData.toViewState( baseIconUrl = baseIconUrl, isPremium = isPremium, + hasMasterPassword = hasMasterPassword, vaultFilterType = vaultFilterType, isIconLoadingDisabled = isIconLoadingDisabled, ), diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt index 9de39fc006..8a2826c8f9 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensions.kt @@ -35,6 +35,7 @@ private const val NO_FOLDER_ITEM_THRESHOLD: Int = 100 @Suppress("LongMethod") fun VaultData.toViewState( isPremium: Boolean, + hasMasterPassword: Boolean, isIconLoadingDisabled: Boolean, baseIconUrl: String, vaultFilterType: VaultFilterType, @@ -78,6 +79,7 @@ fun VaultData.toViewState( .filter { it.favorite } .mapNotNull { it.toVaultItemOrNull( + hasMasterPassword = hasMasterPassword, isIconLoadingDisabled = isIconLoadingDisabled, baseIconUrl = baseIconUrl, ) @@ -110,6 +112,7 @@ fun VaultData.toViewState( noFolderItems = noFolderItems .mapNotNull { it.toVaultItemOrNull( + hasMasterPassword = hasMasterPassword, isIconLoadingDisabled = isIconLoadingDisabled, baseIconUrl = baseIconUrl, ) @@ -183,6 +186,7 @@ fun List?.toLoginIconData( */ @Suppress("MagicNumber") private fun CipherView.toVaultItemOrNull( + hasMasterPassword: Boolean, isIconLoadingDisabled: Boolean, baseIconUrl: String, ): VaultState.ViewState.VaultItem? { @@ -196,7 +200,7 @@ private fun CipherView.toVaultItemOrNull( isIconLoadingDisabled = isIconLoadingDisabled, baseIconUrl = baseIconUrl, ), - overflowOptions = toOverflowActions(), + overflowOptions = toOverflowActions(hasMasterPassword = hasMasterPassword), extraIconList = toLabelIcons(), shouldShowMasterPasswordReprompt = reprompt == CipherRepromptType.PASSWORD, ) @@ -204,7 +208,7 @@ private fun CipherView.toVaultItemOrNull( CipherType.SECURE_NOTE -> VaultState.ViewState.VaultItem.SecureNote( id = id, name = name.asText(), - overflowOptions = toOverflowActions(), + overflowOptions = toOverflowActions(hasMasterPassword = hasMasterPassword), extraIconList = toLabelIcons(), shouldShowMasterPasswordReprompt = reprompt == CipherRepromptType.PASSWORD, ) @@ -216,7 +220,7 @@ private fun CipherView.toVaultItemOrNull( lastFourDigits = card?.number ?.takeLast(4) ?.asText(), - overflowOptions = toOverflowActions(), + overflowOptions = toOverflowActions(hasMasterPassword = hasMasterPassword), extraIconList = toLabelIcons(), shouldShowMasterPasswordReprompt = reprompt == CipherRepromptType.PASSWORD, ) @@ -230,7 +234,7 @@ private fun CipherView.toVaultItemOrNull( else -> "${identity?.firstName} ${identity?.lastName}" } ?.asText(), - overflowOptions = toOverflowActions(), + overflowOptions = toOverflowActions(hasMasterPassword = hasMasterPassword), extraIconList = toLabelIcons(), shouldShowMasterPasswordReprompt = reprompt == CipherRepromptType.PASSWORD, ) diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt index ed4ad5cfd9..e10829d40e 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchScreenTest.kt @@ -541,6 +541,7 @@ class SearchScreenTest : BaseComposeTest() { SearchAction.OverflowOptionClick( overflowAction = ListingItemOverflowAction.VaultAction.EditClick( cipherId = "mockId-1", + requiresPasswordReprompt = true, ), ), ) @@ -579,6 +580,7 @@ class SearchScreenTest : BaseComposeTest() { SearchAction.OverflowOptionClick( overflowAction = ListingItemOverflowAction.VaultAction.CopyPasswordClick( password = "mockPassword-1", + requiresPasswordReprompt = true, ), ), ) @@ -675,6 +677,7 @@ class SearchScreenTest : BaseComposeTest() { masterPasswordRepromptData = MasterPasswordRepromptData.OverflowItem( action = ListingItemOverflowAction.VaultAction.EditClick( cipherId = "mockId-1", + requiresPasswordReprompt = true, ), ), ), @@ -882,6 +885,7 @@ private val DEFAULT_STATE: SearchState = SearchState( baseWebSendUrl = "www.test.com", baseIconUrl = "www.test.com", isIconLoadingDisabled = false, + hasMasterPassword = true, ) private fun createStateForAutofill( diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModelTest.kt index bae39b0598..ee96a9841a 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModelTest.kt @@ -477,6 +477,7 @@ class SearchViewModelTest : BaseViewModelTest() { masterPasswordRepromptData = MasterPasswordRepromptData.OverflowItem( action = ListingItemOverflowAction.VaultAction.EditClick( cipherId = cipherId, + requiresPasswordReprompt = true, ), ), ), @@ -665,7 +666,10 @@ class SearchViewModelTest : BaseViewModelTest() { val viewModel = createViewModel() viewModel.trySendAction( SearchAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.CopyNumberClick(number = number), + ListingItemOverflowAction.VaultAction.CopyNumberClick( + number = number, + requiresPasswordReprompt = true, + ), ), ) verify(exactly = 1) { @@ -726,7 +730,10 @@ class SearchViewModelTest : BaseViewModelTest() { val viewModel = createViewModel() viewModel.trySendAction( SearchAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.CopyPasswordClick(password = password), + ListingItemOverflowAction.VaultAction.CopyPasswordClick( + password = password, + requiresPasswordReprompt = true, + ), ), ) verify(exactly = 1) { @@ -744,6 +751,7 @@ class SearchViewModelTest : BaseViewModelTest() { SearchAction.OverflowOptionClick( ListingItemOverflowAction.VaultAction.CopySecurityCodeClick( securityCode = securityCode, + requiresPasswordReprompt = true, ), ), ) @@ -777,7 +785,10 @@ class SearchViewModelTest : BaseViewModelTest() { viewModel.eventFlow.test { viewModel.trySendAction( SearchAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.EditClick(cipherId = cipherId), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = cipherId, + requiresPasswordReprompt = true, + ), ), ) assertEquals(SearchEvent.NavigateToEditCipher(cipherId), awaitItem()) @@ -834,6 +845,7 @@ class SearchViewModelTest : BaseViewModelTest() { baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, isAutofill = false, + hasMasterPassword = true, ) } returns expectedViewState val dataState = DataState.Loaded( @@ -934,6 +946,7 @@ class SearchViewModelTest : BaseViewModelTest() { baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, isAutofill = false, + hasMasterPassword = true, ) } returns expectedViewState mutableVaultDataStateFlow.tryEmit( @@ -1044,6 +1057,7 @@ class SearchViewModelTest : BaseViewModelTest() { baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, isAutofill = false, + hasMasterPassword = true, ) } returns expectedViewState val dataState = DataState.Error( @@ -1154,6 +1168,7 @@ class SearchViewModelTest : BaseViewModelTest() { baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, isAutofill = false, + hasMasterPassword = true, ) } returns expectedViewState val dataState = DataState.NoNetwork( @@ -1320,6 +1335,7 @@ class SearchViewModelTest : BaseViewModelTest() { baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, isAutofill = true, + hasMasterPassword = true, ) } returns expectedViewState val dataState = DataState.Loaded( @@ -1351,6 +1367,7 @@ private val DEFAULT_STATE: SearchState = SearchState( baseWebSendUrl = "https://vault.bitwarden.com/#/send/", baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, + hasMasterPassword = true, ) private val DEFAULT_USER_STATE = UserState( diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensionsTest.kt index 6f5f0030d4..8dd6521b60 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensionsTest.kt @@ -271,6 +271,7 @@ class SearchTypeDataExtensionsTest { baseIconUrl = "www.test.com", isIconLoadingDisabled = false, isAutofill = false, + hasMasterPassword = true, ) assertEquals(SearchState.ViewState.Empty(message = null), result) @@ -294,6 +295,7 @@ class SearchTypeDataExtensionsTest { baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, isAutofill = false, + hasMasterPassword = true, ) assertEquals( @@ -332,6 +334,7 @@ class SearchTypeDataExtensionsTest { baseIconUrl = "https://vault.bitwarden.com/icons", isIconLoadingDisabled = false, isAutofill = true, + hasMasterPassword = true, ) assertEquals( @@ -380,6 +383,7 @@ class SearchTypeDataExtensionsTest { baseIconUrl = "www.test.com", isIconLoadingDisabled = false, isAutofill = false, + hasMasterPassword = true, ) assertEquals( diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchUtil.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchUtil.kt index c649c8d7ff..49a2028674 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchUtil.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchUtil.kt @@ -42,12 +42,16 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyUsernameClick( username = "mockUsername-$number", ), ListingItemOverflowAction.VaultAction.CopyPasswordClick( password = "mockPassword-$number", + requiresPasswordReprompt = true, ), ListingItemOverflowAction.VaultAction.CopyTotpClick( totpCode = "mockTotp-$number", @@ -85,7 +89,10 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyNoteClick( notes = "mockNotes-$number", ), @@ -119,12 +126,17 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyNumberClick( number = "mockNumber-$number", + requiresPasswordReprompt = true, ), ListingItemOverflowAction.VaultAction.CopySecurityCodeClick( securityCode = "mockCode-$number", + requiresPasswordReprompt = true, ), ), overflowTestTag = "CipherOptionsButton", @@ -156,7 +168,10 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ), overflowTestTag = "CipherOptionsButton", totpCode = null, diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModelTest.kt index 205d2d78fb..430d787195 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModelTest.kt @@ -142,6 +142,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns DEFAULT_VIEW_STATE @@ -163,6 +164,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -180,6 +182,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginState @@ -221,6 +224,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginState @@ -251,6 +255,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns loginViewState @@ -292,6 +297,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -336,6 +342,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns loginViewState @@ -374,6 +381,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns DEFAULT_VIEW_STATE @@ -412,6 +420,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns DEFAULT_VIEW_STATE @@ -459,6 +468,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns DEFAULT_VIEW_STATE @@ -489,6 +499,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -521,6 +532,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -582,6 +594,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -633,6 +646,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -695,6 +709,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns DEFAULT_VIEW_STATE @@ -716,6 +731,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -729,6 +745,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns createViewState(common = DEFAULT_COMMON.copy(requiresReprompt = false)) @@ -744,6 +761,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { clipboardManager.setText(text = field) mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -776,6 +794,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns DEFAULT_VIEW_STATE @@ -805,6 +824,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -835,6 +855,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -864,6 +885,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -877,6 +899,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns DEFAULT_VIEW_STATE @@ -898,6 +921,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -915,6 +939,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -947,6 +972,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -970,6 +996,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -991,6 +1018,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -1037,6 +1065,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns DEFAULT_VIEW_STATE @@ -1058,6 +1087,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -1075,6 +1105,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -1104,6 +1135,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns DEFAULT_VIEW_STATE @@ -1125,6 +1157,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -1142,6 +1175,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -1182,6 +1216,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -1236,6 +1271,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -1299,6 +1335,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns loginViewState @@ -1475,6 +1512,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns DEFAULT_VIEW_STATE @@ -1513,6 +1551,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1529,6 +1568,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns DEFAULT_VIEW_STATE @@ -1553,6 +1593,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1565,6 +1606,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns createViewState(common = DEFAULT_COMMON.copy(requiresReprompt = false)) @@ -1581,6 +1623,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { clipboardManager.setText(text = DEFAULT_LOGIN_PASSWORD) mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1619,6 +1662,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns createViewState(common = DEFAULT_COMMON.copy(requiresReprompt = false)) @@ -1633,6 +1677,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { clipboardManager.setText(text = DEFAULT_LOGIN_USERNAME) mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1655,6 +1700,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns DEFAULT_VIEW_STATE @@ -1677,6 +1723,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1690,6 +1737,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1714,6 +1762,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1728,6 +1777,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns DEFAULT_VIEW_STATE @@ -1754,6 +1804,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1771,6 +1822,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } returns loginViewState @@ -1800,6 +1852,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = createTotpCodeData(), ) } @@ -1827,6 +1880,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns CARD_VIEW_STATE @@ -1850,6 +1904,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -1862,6 +1917,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns createViewState( @@ -1879,6 +1935,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { clipboardManager.setText(text = "12345436") mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -1892,6 +1949,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns CARD_VIEW_STATE @@ -1915,6 +1973,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { verify(exactly = 1) { mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -1927,6 +1986,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { every { toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } returns createViewState( @@ -1944,6 +2004,7 @@ class VaultItemViewModelTest : BaseViewModelTest() { clipboardManager.setText(text = "987") mockCipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, ) } @@ -1975,7 +2036,11 @@ class VaultItemViewModelTest : BaseViewModelTest() { val viewState = mockk() val cipherView = mockk { every { - toViewState(isPremiumUser = true, totpCodeItemData = null) + toViewState( + isPremiumUser = true, + hasMasterPassword = true, + totpCodeItemData = null, + ) } returns viewState } val viewModel = createViewModel(state = null) @@ -2006,7 +2071,11 @@ class VaultItemViewModelTest : BaseViewModelTest() { val viewState = mockk() val cipherView = mockk { every { - toViewState(isPremiumUser = true, totpCodeItemData = null) + toViewState( + isPremiumUser = true, + hasMasterPassword = true, + totpCodeItemData = null, + ) } returns viewState } val viewModel = createViewModel(state = null) @@ -2038,7 +2107,11 @@ class VaultItemViewModelTest : BaseViewModelTest() { val viewState = mockk() val cipherView = mockk { every { - toViewState(isPremiumUser = true, totpCodeItemData = null) + toViewState( + isPremiumUser = true, + hasMasterPassword = true, + totpCodeItemData = null, + ) } returns viewState } val viewModel = createViewModel(state = null) @@ -2069,7 +2142,11 @@ class VaultItemViewModelTest : BaseViewModelTest() { val viewState = mockk() val cipherView = mockk { every { - toViewState(isPremiumUser = true, totpCodeItemData = null) + toViewState( + isPremiumUser = true, + hasMasterPassword = true, + totpCodeItemData = null, + ) } returns viewState } val viewModel = createViewModel(state = null) diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensionsTest.kt index d621611209..ac5a177989 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/item/util/CipherViewExtensionsTest.kt @@ -16,12 +16,41 @@ class CipherViewExtensionsTest { ZoneOffset.UTC, ) + @Suppress("MaxLineLength") + @Test + fun `toViewState should transform full CipherView into ViewState Login Content without master password reprompt`() { + val cipherView = createCipherView(type = CipherType.LOGIN, isEmpty = false) + val viewState = cipherView.toViewState( + isPremiumUser = true, + hasMasterPassword = false, + totpCodeItemData = TotpCodeItemData( + periodSeconds = 30, + timeLeftSeconds = 15, + verificationCode = "123456", + totpCode = "testCode", + ), + clock = fixedClock, + ) + + assertEquals( + VaultItemState.ViewState.Content( + common = createCommonContent(isEmpty = false, isPremiumUser = true).copy( + currentCipher = cipherView, + requiresReprompt = false, + ), + type = createLoginContent(isEmpty = false), + ), + viewState, + ) + } + @Test fun `toViewState should transform full CipherView into ViewState Login Content with premium`() { val cipherView = createCipherView(type = CipherType.LOGIN, isEmpty = false) val viewState = cipherView.toViewState( isPremiumUser = true, - TotpCodeItemData( + hasMasterPassword = true, + totpCodeItemData = TotpCodeItemData( periodSeconds = 30, timeLeftSeconds = 15, verificationCode = "123456", @@ -47,6 +76,7 @@ class CipherViewExtensionsTest { val cipherView = createCipherView(type = CipherType.LOGIN, isEmpty = false) val viewState = cipherView.toViewState( isPremiumUser = isPremiumUser, + hasMasterPassword = true, totpCodeItemData = TotpCodeItemData( periodSeconds = 30, timeLeftSeconds = 15, @@ -71,6 +101,7 @@ class CipherViewExtensionsTest { val cipherView = createCipherView(type = CipherType.LOGIN, isEmpty = true) val viewState = cipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, clock = fixedClock, ) @@ -91,6 +122,7 @@ class CipherViewExtensionsTest { val cipherView = createCipherView(type = CipherType.IDENTITY, isEmpty = false) val viewState = cipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, clock = fixedClock, ) @@ -110,6 +142,7 @@ class CipherViewExtensionsTest { val cipherView = createCipherView(type = CipherType.IDENTITY, isEmpty = true) val viewState = cipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, clock = fixedClock, ) @@ -139,6 +172,7 @@ class CipherViewExtensionsTest { ) val viewState = cipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, clock = fixedClock, ) @@ -173,6 +207,7 @@ class CipherViewExtensionsTest { ) val result = cipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, clock = fixedClock, ) @@ -209,6 +244,7 @@ class CipherViewExtensionsTest { val cipherView = createCipherView(type = CipherType.SECURE_NOTE, isEmpty = false) val viewState = cipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, clock = fixedClock, ) @@ -229,6 +265,7 @@ class CipherViewExtensionsTest { val cipherView = createCipherView(type = CipherType.SECURE_NOTE, isEmpty = true) val viewState = cipherView.toViewState( isPremiumUser = true, + hasMasterPassword = true, totpCodeItemData = null, clock = fixedClock, ) diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt index 4fe8f3e9d0..cc299470e9 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingScreenTest.kt @@ -1196,6 +1196,7 @@ class VaultItemListingScreenTest : BaseComposeTest() { VaultItemListingsAction.OverflowOptionClick( action = ListingItemOverflowAction.VaultAction.EditClick( cipherId = "mockId-1", + requiresPasswordReprompt = true, ), ), ) @@ -1508,6 +1509,7 @@ private val DEFAULT_STATE = VaultItemListingState( isPullToRefreshSettingEnabled = false, dialogState = null, policyDisablesSend = false, + hasMasterPassword = true, ) private val STATE_FOR_AUTOFILL = DEFAULT_STATE.copy( @@ -1567,7 +1569,10 @@ private fun createCipherDisplayItem(number: Int): VaultItemListingState.DisplayI iconData = IconData.Local(R.drawable.ic_vault), extraIconList = emptyList(), overflowOptions = listOf( - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ), optionsTestTag = "CipherOptionsButton", isAutofill = false, diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt index 36c0137fc3..663149f4f0 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt @@ -448,6 +448,7 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { masterPasswordRepromptData = MasterPasswordRepromptData.OverflowItem( action = ListingItemOverflowAction.VaultAction.EditClick( cipherId = cipherId, + requiresPasswordReprompt = true, ), ), ), @@ -688,7 +689,10 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { val viewModel = createVaultItemListingViewModel() viewModel.trySendAction( VaultItemListingsAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.CopyNumberClick(number = number), + ListingItemOverflowAction.VaultAction.CopyNumberClick( + number = number, + requiresPasswordReprompt = true, + ), ), ) verify(exactly = 1) { @@ -704,7 +708,10 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { val viewModel = createVaultItemListingViewModel() viewModel.trySendAction( VaultItemListingsAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.CopyPasswordClick(password = password), + ListingItemOverflowAction.VaultAction.CopyPasswordClick( + password = password, + requiresPasswordReprompt = true, + ), ), ) verify(exactly = 1) { @@ -722,6 +729,7 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { VaultItemListingsAction.OverflowOptionClick( ListingItemOverflowAction.VaultAction.CopySecurityCodeClick( securityCode = securityCode, + requiresPasswordReprompt = true, ), ), ) @@ -800,7 +808,10 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { viewModel.eventFlow.test { viewModel.trySendAction( VaultItemListingsAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.EditClick(cipherId = cipherId), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = cipherId, + requiresPasswordReprompt = true, + ), ), ) assertEquals(VaultItemListingEvent.NavigateToEditCipher(cipherId), awaitItem()) @@ -1443,6 +1454,7 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { autofillSelectionData = null, shouldFinishOnComplete = false, policyDisablesSend = false, + hasMasterPassword = true, ) } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensionsTest.kt index 450e36f30f..5a46d69f3f 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataExtensionsTest.kt @@ -393,6 +393,7 @@ class VaultItemListingDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, autofillSelectionData = null, + hasMasterPassword = true, ) assertEquals( @@ -466,6 +467,7 @@ class VaultItemListingDataExtensionsTest { type = AutofillSelectionData.Type.LOGIN, uri = null, ), + hasMasterPassword = true, ) assertEquals( @@ -516,6 +518,7 @@ class VaultItemListingDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, autofillSelectionData = null, + hasMasterPassword = true, ), ) @@ -533,6 +536,7 @@ class VaultItemListingDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, autofillSelectionData = null, + hasMasterPassword = true, ), ) @@ -548,6 +552,7 @@ class VaultItemListingDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, autofillSelectionData = null, + hasMasterPassword = true, ), ) @@ -566,6 +571,7 @@ class VaultItemListingDataExtensionsTest { type = AutofillSelectionData.Type.LOGIN, uri = "https://www.test.com", ), + hasMasterPassword = true, ), ) } @@ -704,6 +710,7 @@ class VaultItemListingDataExtensionsTest { autofillSelectionData = null, itemListingType = VaultItemListingState.ItemListingType.Vault.Folder("1"), vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( @@ -743,6 +750,7 @@ class VaultItemListingDataExtensionsTest { autofillSelectionData = null, itemListingType = VaultItemListingState.ItemListingType.Vault.Collection("mockId-1"), vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt index 0282f10888..72be62e789 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/itemlisting/util/VaultItemListingDataUtil.kt @@ -43,12 +43,16 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyUsernameClick( username = "mockUsername-$number", ), ListingItemOverflowAction.VaultAction.CopyPasswordClick( password = "mockPassword-$number", + requiresPasswordReprompt = true, ), ListingItemOverflowAction.VaultAction.CopyTotpClick( totpCode = "mockTotp-$number", @@ -86,7 +90,10 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyNoteClick( notes = "mockNotes-$number", ), @@ -120,12 +127,17 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyNumberClick( number = "mockNumber-$number", + requiresPasswordReprompt = true, ), ListingItemOverflowAction.VaultAction.CopySecurityCodeClick( securityCode = "mockCode-$number", + requiresPasswordReprompt = true, ), ), optionsTestTag = "CipherOptionsButton", @@ -157,7 +169,10 @@ fun createMockDisplayItemForCipher( ), overflowOptions = listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = "mockId-$number"), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = "mockId-$number"), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = "mockId-$number", + requiresPasswordReprompt = true, + ), ), optionsTestTag = "CipherOptionsButton", isAutofill = false, diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensionsTest.kt index eb48f65ef8..76e3f40462 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/util/CipherViewExtensionsTest.kt @@ -31,14 +31,20 @@ class CipherViewExtensionsTest { ), ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = false) assertEquals( listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = id), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = id, + requiresPasswordReprompt = false, + ), ListingItemOverflowAction.VaultAction.CopyUsernameClick(username = username), - ListingItemOverflowAction.VaultAction.CopyPasswordClick(password = password), + ListingItemOverflowAction.VaultAction.CopyPasswordClick( + password = password, + requiresPasswordReprompt = false, + ), ListingItemOverflowAction.VaultAction.CopyTotpClick(totpCode = totpCode), ListingItemOverflowAction.VaultAction.LaunchClick(url = uri), ), @@ -63,12 +69,15 @@ class CipherViewExtensionsTest { ), viewPassword = false, ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = true) assertEquals( listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = id), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = id, + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyUsernameClick(username = username), ListingItemOverflowAction.VaultAction.CopyTotpClick(totpCode = totpCode), ListingItemOverflowAction.VaultAction.LaunchClick(url = uri), @@ -95,7 +104,7 @@ class CipherViewExtensionsTest { ), ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = true) assertEquals( listOf(ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id)), @@ -116,15 +125,22 @@ class CipherViewExtensionsTest { ), ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = true) assertEquals( listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = id), - ListingItemOverflowAction.VaultAction.CopyNumberClick(number = number), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = id, + requiresPasswordReprompt = true, + ), + ListingItemOverflowAction.VaultAction.CopyNumberClick( + number = number, + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopySecurityCodeClick( securityCode = securityCode, + requiresPasswordReprompt = true, ), ), result, @@ -147,7 +163,7 @@ class CipherViewExtensionsTest { ), ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = false) assertEquals( listOf(ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id)), @@ -163,12 +179,15 @@ class CipherViewExtensionsTest { identity = createMockIdentityView(number = 1), ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = false) assertEquals( listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = id), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = id, + requiresPasswordReprompt = false, + ), ), result, ) @@ -187,7 +206,7 @@ class CipherViewExtensionsTest { identity = createMockIdentityView(number = 1), ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = true) assertEquals( listOf(ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id)), @@ -205,12 +224,15 @@ class CipherViewExtensionsTest { notes = notes, ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = true) assertEquals( listOf( ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id), - ListingItemOverflowAction.VaultAction.EditClick(cipherId = id), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = id, + requiresPasswordReprompt = true, + ), ListingItemOverflowAction.VaultAction.CopyNoteClick(notes = notes), ), result, @@ -231,7 +253,7 @@ class CipherViewExtensionsTest { notes = null, ) - val result = cipher.toOverflowActions() + val result = cipher.toOverflowActions(hasMasterPassword = false) assertEquals( listOf(ListingItemOverflowAction.VaultAction.ViewClick(cipherId = id)), diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultScreenTest.kt index cbe5cab694..a5ef4bf462 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultScreenTest.kt @@ -1177,6 +1177,7 @@ private val DEFAULT_STATE: VaultState = VaultState( isPullToRefreshSettingEnabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, isIconLoadingDisabled = false, + hasMasterPassword = true, ) private val DEFAULT_CONTENT_VIEW_STATE: VaultState.ViewState.Content = VaultState.ViewState.Content( diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt index 592fe864ea..4c8e13fae8 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt @@ -476,6 +476,7 @@ class VaultViewModelTest : BaseViewModelTest() { vaultFilterType = VaultFilterType.AllVaults, isIconLoadingDisabled = viewModel.stateFlow.value.isIconLoadingDisabled, baseIconUrl = viewModel.stateFlow.value.baseIconUrl, + hasMasterPassword = true, ), ) .copy( @@ -499,6 +500,7 @@ class VaultViewModelTest : BaseViewModelTest() { vaultFilterType = VaultFilterType.MyVault, isIconLoadingDisabled = viewModel.stateFlow.value.isIconLoadingDisabled, baseIconUrl = viewModel.stateFlow.value.baseIconUrl, + hasMasterPassword = true, ), ), viewModel.stateFlow.value, @@ -1186,7 +1188,10 @@ class VaultViewModelTest : BaseViewModelTest() { val viewModel = createViewModel() viewModel.trySendAction( VaultAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.CopyNumberClick(number = number), + ListingItemOverflowAction.VaultAction.CopyNumberClick( + number = number, + requiresPasswordReprompt = true, + ), ), ) verify(exactly = 1) { @@ -1202,7 +1207,10 @@ class VaultViewModelTest : BaseViewModelTest() { val viewModel = createViewModel() viewModel.trySendAction( VaultAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.CopyPasswordClick(password = password), + ListingItemOverflowAction.VaultAction.CopyPasswordClick( + password = password, + requiresPasswordReprompt = true, + ), ), ) verify(exactly = 1) { @@ -1265,6 +1273,7 @@ class VaultViewModelTest : BaseViewModelTest() { VaultAction.OverflowOptionClick( ListingItemOverflowAction.VaultAction.CopySecurityCodeClick( securityCode = securityCode, + requiresPasswordReprompt = true, ), ), ) @@ -1298,7 +1307,10 @@ class VaultViewModelTest : BaseViewModelTest() { viewModel.eventFlow.test { viewModel.trySendAction( VaultAction.OverflowOptionClick( - ListingItemOverflowAction.VaultAction.EditClick(cipherId = cipherId), + ListingItemOverflowAction.VaultAction.EditClick( + cipherId = cipherId, + requiresPasswordReprompt = true, + ), ), ) assertEquals(VaultEvent.NavigateToEditVaultItem(cipherId), awaitItem()) @@ -1352,6 +1364,7 @@ class VaultViewModelTest : BaseViewModelTest() { VaultAction.MasterPasswordRepromptSubmit( overflowAction = ListingItemOverflowAction.VaultAction.CopyPasswordClick( password = password, + requiresPasswordReprompt = true, ), password = password, ), @@ -1389,6 +1402,7 @@ class VaultViewModelTest : BaseViewModelTest() { VaultAction.MasterPasswordRepromptSubmit( overflowAction = ListingItemOverflowAction.VaultAction.CopyPasswordClick( password = password, + requiresPasswordReprompt = true, ), password = password, ), @@ -1421,6 +1435,7 @@ class VaultViewModelTest : BaseViewModelTest() { VaultAction.MasterPasswordRepromptSubmit( overflowAction = ListingItemOverflowAction.VaultAction.CopyPasswordClick( password = password, + requiresPasswordReprompt = true, ), password = password, ), @@ -1532,4 +1547,5 @@ private fun createMockVaultState( isPullToRefreshSettingEnabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, isIconLoadingDisabled = false, + hasMasterPassword = true, ) diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt index bbae4cfb24..09e0b90174 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt @@ -55,6 +55,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( @@ -115,6 +116,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.MyVault, + hasMasterPassword = true, ) assertEquals( @@ -167,6 +169,7 @@ class VaultDataExtensionsTest { organizationId = "mockOrganizationId-1", organizationName = "Mock Organization 1", ), + hasMasterPassword = true, ) assertEquals( @@ -212,6 +215,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( @@ -234,6 +238,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( @@ -257,6 +262,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( @@ -291,6 +297,7 @@ class VaultDataExtensionsTest { vaultFilterType = VaultFilterType.AllVaults, isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, + hasMasterPassword = true, ) assertEquals( @@ -439,6 +446,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( @@ -479,6 +487,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals( @@ -531,6 +540,7 @@ class VaultDataExtensionsTest { isIconLoadingDisabled = false, baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl, vaultFilterType = VaultFilterType.AllVaults, + hasMasterPassword = true, ) assertEquals(