diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModel.kt index 22f9d9d503..ca180dc86b 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModel.kt @@ -2,18 +2,15 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.vault import androidx.lifecycle.viewModelScope import com.bitwarden.core.data.manager.BuildInfoManager -import com.bitwarden.core.data.manager.model.FlagKey import com.bitwarden.network.model.PolicyTypeJson import com.bitwarden.ui.platform.base.BackgroundEvent import com.bitwarden.ui.platform.base.BaseViewModel import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData import com.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager -import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager import com.x8bit.bitwarden.data.platform.manager.PolicyManager import com.x8bit.bitwarden.ui.platform.model.SnackbarRelay import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach @@ -29,17 +26,13 @@ class VaultSettingsViewModel @Inject constructor( snackbarRelayManager: SnackbarRelayManager, private val buildInfoManager: BuildInfoManager, private val firstTimeActionManager: FirstTimeActionManager, - private val featureFlagManager: FeatureFlagManager, private val policyManager: PolicyManager, ) : BaseViewModel( initialState = run { val firstTimeState = firstTimeActionManager.currentOrDefaultUserFirstTimeState VaultSettingsState( showImportActionCard = firstTimeState.showImportLoginsCardInSettings, - showImportItemsChevron = !buildInfoManager.isFdroid && - featureFlagManager.getFeatureFlag( - key = FlagKey.CredentialExchangeProtocolImport, - ), + showImportItemsChevron = !buildInfoManager.isFdroid, ) }, ) { @@ -60,15 +53,11 @@ class VaultSettingsViewModel @Inject constructor( .onEach(::sendAction) .launchIn(viewModelScope) - featureFlagManager - .getFeatureFlagFlow(key = FlagKey.CredentialExchangeProtocolImport) - .combine( - policyManager.getActivePoliciesFlow(type = PolicyTypeJson.PERSONAL_OWNERSHIP), - ) { isEnabled, policies -> + policyManager + .getActivePoliciesFlow(type = PolicyTypeJson.PERSONAL_OWNERSHIP) + .map { policies -> VaultSettingsAction.Internal.CredentialExchangeAvailabilityChanged( - isEnabled = isEnabled && - !buildInfoManager.isFdroid && - policies.isEmpty(), + isEnabled = !buildInfoManager.isFdroid && policies.isEmpty(), ) } .onEach(::sendAction) @@ -144,7 +133,6 @@ class VaultSettingsViewModel @Inject constructor( private fun handleImportItemsClicked() { if (!buildInfoManager.isFdroid && - featureFlagManager.getFeatureFlag(FlagKey.CredentialExchangeProtocolImport) && policyManager.getActivePolicies(PolicyTypeJson.PERSONAL_OWNERSHIP).isEmpty() ) { sendEvent(VaultSettingsEvent.NavigateToImportItems) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendContent.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendContent.kt index cbd9a4ccc9..7267cf05c4 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendContent.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendContent.kt @@ -37,10 +37,8 @@ import com.bitwarden.ui.platform.base.util.standardHorizontalMargin import com.bitwarden.ui.platform.components.animation.AnimateNullableContentVisibility import com.bitwarden.ui.platform.components.button.BitwardenOutlinedButton import com.bitwarden.ui.platform.components.button.BitwardenOutlinedErrorButton -import com.bitwarden.ui.platform.components.button.BitwardenStandardIconButton import com.bitwarden.ui.platform.components.card.BitwardenInfoCalloutCard import com.bitwarden.ui.platform.components.dialog.BitwardenTwoButtonDialog -import com.bitwarden.ui.platform.components.field.BitwardenPasswordField import com.bitwarden.ui.platform.components.field.BitwardenTextField import com.bitwarden.ui.platform.components.header.BitwardenExpandingHeader import com.bitwarden.ui.platform.components.header.BitwardenListHeaderText @@ -161,26 +159,24 @@ fun AddEditSendContent( ) } - if (state.common.isSendEmailVerificationEnabled) { - Spacer(modifier = Modifier.height(height = 8.dp)) - AddEditSendAuthTypeChooser( - sendAuth = state.common.sendAuth, - onAuthTypeSelect = addSendHandlers.onAuthTypeSelect, - onPasswordChange = addSendHandlers.onAuthPasswordChange, - onEmailValueChange = addSendHandlers.onEmailValueChange, - onRemoveEmailClick = addSendHandlers.onEmailsRemoveClick, - onAddNewEmailClick = addSendHandlers.onAddNewEmailClick, - onOpenPasswordGeneratorClick = addSendHandlers.onOpenPasswordGeneratorClick, - onPasswordCopyClick = addSendHandlers.onPasswordCopyClick, - password = state.common.passwordInput, - isEnabled = !policyDisablesSend, - isSendsRestrictedByPolicy = policyDisablesSend, - modifier = Modifier - .testTag("SendAuthTypeChooser") - .fillMaxWidth() - .standardHorizontalMargin(), - ) - } + Spacer(modifier = Modifier.height(height = 8.dp)) + AddEditSendAuthTypeChooser( + sendAuth = state.common.sendAuth, + onAuthTypeSelect = addSendHandlers.onAuthTypeSelect, + onPasswordChange = addSendHandlers.onAuthPasswordChange, + onEmailValueChange = addSendHandlers.onEmailValueChange, + onRemoveEmailClick = addSendHandlers.onEmailsRemoveClick, + onAddNewEmailClick = addSendHandlers.onAddNewEmailClick, + onOpenPasswordGeneratorClick = addSendHandlers.onOpenPasswordGeneratorClick, + onPasswordCopyClick = addSendHandlers.onPasswordCopyClick, + password = state.common.passwordInput, + isEnabled = !policyDisablesSend, + isSendsRestrictedByPolicy = policyDisablesSend, + modifier = Modifier + .testTag("SendAuthTypeChooser") + .fillMaxWidth() + .standardHorizontalMargin(), + ) AddEditSendOptions( state = state, @@ -452,43 +448,6 @@ private fun AddEditSendOptions( .standardHorizontalMargin(), ) - if (!state.common.isSendEmailVerificationEnabled) { - Spacer(modifier = Modifier.height(8.dp)) - BitwardenPasswordField( - label = stringResource(id = BitwardenString.new_password), - supportingText = stringResource(id = BitwardenString.password_info), - readOnly = isSendsRestrictedByPolicy, - value = state.common.passwordInput, - onValueChange = addSendHandlers.onPasswordChange, - passwordFieldTestTag = "SendNewPasswordEntry", - cardStyle = CardStyle.Full, - modifier = Modifier - .fillMaxWidth() - .standardHorizontalMargin(), - ) { - BitwardenStandardIconButton( - vectorIconRes = BitwardenDrawable.ic_generate, - contentDescription = stringResource(id = BitwardenString.generate_password), - onClick = { - if (state.common.passwordInput.isEmpty()) { - addSendHandlers.onOpenPasswordGeneratorClick() - } else { - shouldShowDialog = true - } - }, - modifier = Modifier.testTag(tag = "RegeneratePasswordButton"), - ) - BitwardenStandardIconButton( - vectorIconRes = BitwardenDrawable.ic_copy, - contentDescription = stringResource(id = BitwardenString.copy_password), - isEnabled = state.common.passwordInput.isNotEmpty(), - onClick = { - addSendHandlers.onPasswordCopyClick(state.common.passwordInput) - }, - modifier = Modifier.testTag(tag = "CopyPasswordButton"), - ) - } - } if (shouldShowDialog) { BitwardenTwoButtonDialog( title = stringResource(id = BitwardenString.password), diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt index dbb1f84005..626dc832a5 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModel.kt @@ -4,7 +4,6 @@ import android.net.Uri import android.os.Parcelable import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope -import com.bitwarden.core.data.manager.model.FlagKey import com.bitwarden.core.data.repository.model.DataState import com.bitwarden.core.data.repository.util.takeUntilLoaded import com.bitwarden.data.repository.util.baseWebSendUrl @@ -22,9 +21,8 @@ import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText import com.bitwarden.ui.util.concat import com.x8bit.bitwarden.data.auth.repository.AuthRepository -import com.x8bit.bitwarden.data.billing.manager.PremiumStateManager import com.x8bit.bitwarden.data.auth.repository.model.PolicyInformation -import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager +import com.x8bit.bitwarden.data.billing.manager.PremiumStateManager import com.x8bit.bitwarden.data.platform.manager.PolicyManager import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager @@ -90,7 +88,6 @@ class AddEditSendViewModel @Inject constructor( private val policyManager: PolicyManager, private val networkConnectionManager: NetworkConnectionManager, private val snackbarRelayManager: SnackbarRelayManager, - private val featureFlagManager: FeatureFlagManager, private val premiumStateManager: PremiumStateManager, ) : BaseViewModel( // We load the state from the savedStateHandle for testing purposes. @@ -126,8 +123,6 @@ class AddEditSendViewModel @Inject constructor( expirationDate = null, sendUrl = null, hasPassword = false, - isSendEmailVerificationEnabled = featureFlagManager - .getFeatureFlag(key = FlagKey.SendEmailVerification), sendAuth = SendAuth.None, ), selectedType = shareSendType ?: when (sendType) { @@ -203,7 +198,6 @@ class AddEditSendViewModel @Inject constructor( is AddEditSendAction.MaxAccessCountChange -> handleMaxAccessCountChange(action) is AddEditSendAction.TextChange -> handleTextChange(action) is AddEditSendAction.NoteChange -> handleNoteChange(action) - is AddEditSendAction.PasswordChange -> handlePasswordChange(action) is AddEditSendAction.HideByDefaultToggle -> handleHideByDefaultToggle(action) is AddEditSendAction.DeactivateThisSendToggle -> handleDeactivateThisSendToggle(action) is AddEditSendAction.HideMyEmailToggle -> handleHideMyEmailToggle(action) @@ -413,7 +407,6 @@ class AddEditSendViewModel @Inject constructor( .environmentUrlData .baseWebSendUrl, isHideEmailAddressEnabled = isHideEmailAddressEnabled, - isSendEmailVerificationEnabled = isSendEmailVerificationEnabled, ) ?: AddEditSendState.ViewState.Error( message = BitwardenString.generic_error_message.asText(), @@ -454,7 +447,6 @@ class AddEditSendViewModel @Inject constructor( .environmentUrlData .baseWebSendUrl, isHideEmailAddressEnabled = isHideEmailAddressEnabled, - isSendEmailVerificationEnabled = isSendEmailVerificationEnabled, ) ?: AddEditSendState.ViewState.Error( message = BitwardenString.generic_error_message.asText(), @@ -526,19 +518,6 @@ class AddEditSendViewModel @Inject constructor( } } - private fun handlePasswordChange(action: AddEditSendAction.PasswordChange) { - updateCommonContent { - it.copy( - passwordInput = action.input, - sendAuth = when { - action.input.isNotEmpty() -> SendAuth.Password - !isSendEmailVerificationEnabled -> SendAuth.None - else -> it.sendAuth - }, - ) - } - } - private fun handleNoteChange(action: AddEditSendAction.NoteChange) { updateCommonContent { it.copy(noteInput = action.input) @@ -854,10 +833,6 @@ class AddEditSendViewModel @Inject constructor( .getActivePolicies() .any { it.shouldDisableHideEmail ?: false } - private val isSendEmailVerificationEnabled: Boolean - get() = featureFlagManager - .getFeatureFlag(key = FlagKey.SendEmailVerification) - private inline fun onContent( crossinline block: (AddEditSendState.ViewState.Content) -> Unit, ) { @@ -1007,7 +982,6 @@ data class AddEditSendState( val expirationDate: Instant?, val sendUrl: String?, val hasPassword: Boolean, - val isSendEmailVerificationEnabled: Boolean, val sendAuth: SendAuth, ) : Parcelable @@ -1193,11 +1167,6 @@ sealed class AddEditSendAction { */ data class TextChange(val input: String) : AddEditSendAction() - /** - * Value of the password field updated. - */ - data class PasswordChange(val input: String) : AddEditSendAction() - /** * Value of the note text field updated. */ diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt index 0d0e5fbd0e..9f3e55bdb4 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/handlers/AddEditSendHandlers.kt @@ -18,7 +18,6 @@ data class AddEditSendHandlers( val onTextChange: (String) -> Unit, val onIsHideByDefaultToggle: (Boolean) -> Unit, val onMaxAccessCountChange: (Int) -> Unit, - val onPasswordChange: (String) -> Unit, val onNoteChange: (String) -> Unit, val onHideEmailToggle: (Boolean) -> Unit, val onDeactivateSendToggle: (Boolean) -> Unit, @@ -54,9 +53,6 @@ data class AddEditSendHandlers( onMaxAccessCountChange = { viewModel.trySendAction(AddEditSendAction.MaxAccessCountChange(it)) }, - onPasswordChange = { - viewModel.trySendAction(AddEditSendAction.PasswordChange(it)) - }, onNoteChange = { viewModel.trySendAction(AddEditSendAction.NoteChange(it)) }, onHideEmailToggle = { viewModel.trySendAction(AddEditSendAction.HideMyEmailToggle(it)) diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensions.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensions.kt index 162b35f54f..7749473b65 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensions.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensions.kt @@ -24,10 +24,7 @@ fun AddEditSendState.ViewState.Content.toSendView( key = common.originalSendView?.key, newPassword = common .passwordInput - .takeIf { - common.sendAuth is SendAuth.Password || - !common.isSendEmailVerificationEnabled - } + .takeIf { common.sendAuth is SendAuth.Password } .orNullIfBlank(), hasPassword = false, type = selectedType.toSendType(), diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensions.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensions.kt index 3afe617bc7..35d92805d9 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensions.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensions.kt @@ -7,13 +7,13 @@ import com.x8bit.bitwarden.ui.tools.feature.send.addedit.model.AuthEmail import com.x8bit.bitwarden.ui.tools.feature.send.addedit.model.SendAuth import com.x8bit.bitwarden.ui.tools.feature.send.util.toSendUrl import kotlinx.collections.immutable.toImmutableList + /** * Transforms [SendView] into [AddEditSendState.ViewState.Content]. */ fun SendView.toViewState( baseWebSendUrl: String, isHideEmailAddressEnabled: Boolean, - isSendEmailVerificationEnabled: Boolean, ): AddEditSendState.ViewState.Content = AddEditSendState.ViewState.Content( common = AddEditSendState.ViewState.Content.Common( @@ -32,7 +32,6 @@ fun SendView.toViewState( sendUrl = this.toSendUrl(baseWebSendUrl), hasPassword = this.hasPassword, isHideEmailAddressEnabled = isHideEmailAddressEnabled, - isSendEmailVerificationEnabled = isSendEmailVerificationEnabled, sendAuth = when { hasPassword -> SendAuth.Password emails.isNotEmpty() -> { diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt index 7f776fcf24..8a0b5c0617 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModel.kt @@ -121,7 +121,7 @@ class VaultViewModel @Inject constructor( private val browserAutofillDialogManager: BrowserAutofillDialogManager, private val credentialExchangeRegistryManager: CredentialExchangeRegistryManager, private val buildInfoManager: BuildInfoManager, - private val featureFlagManager: FeatureFlagManager, + featureFlagManager: FeatureFlagManager, snackbarRelayManager: SnackbarRelayManager, ) : BaseViewModel( initialState = run { @@ -292,16 +292,16 @@ class VaultViewModel @Inject constructor( .onEach(::sendAction) .launchIn(viewModelScope) - featureFlagManager.getFeatureFlagFlow(FlagKey.CredentialExchangeProtocolExport) - .map { VaultAction.Internal.CredentialExchangeProtocolExportFlagUpdateReceive(it) } - .onEach(::sendAction) - .launchIn(viewModelScope) - featureFlagManager.getFeatureFlagFlow(FlagKey.NewItemTypes) .map { VaultAction.Internal.NewItemTypesFlagUpdateReceive(isEnabled = it) } .onEach(::sendAction) .launchIn(viewModelScope) + if (!buildInfoManager.isFdroid) { + viewModelScope.launch { + credentialExchangeRegistryManager.register() + } + } viewModelScope.launch { delay(timeMillis = BROWSER_AUTOFILL_DIALOG_DELAY) mutableStateFlow.update { vaultState -> @@ -1131,10 +1131,6 @@ class VaultViewModel @Inject constructor( handleNewItemTypesFlagUpdateReceive(action) } - is VaultAction.Internal.CredentialExchangeProtocolExportFlagUpdateReceive -> { - handleCredentialExchangeProtocolExportFlagUpdateReceive(action) - } - is VaultAction.Internal.ArchiveCipherReceive -> handleArchiveCipherReceive(action) is VaultAction.Internal.UnarchiveCipherReceive -> handleUnarchiveCipherReceive(action) is VaultAction.Internal.IntroducingArchiveActionCardDismissedFlowReceive -> { @@ -1221,20 +1217,6 @@ class VaultViewModel @Inject constructor( } } - private fun handleCredentialExchangeProtocolExportFlagUpdateReceive( - action: VaultAction.Internal.CredentialExchangeProtocolExportFlagUpdateReceive, - ) { - viewModelScope.launch { - if (action.isCredentialExchangeProtocolExportEnabled && - !buildInfoManager.isFdroid - ) { - credentialExchangeRegistryManager.register() - } else { - credentialExchangeRegistryManager.unregister() - } - } - } - private fun handleArchiveCipherReceive(action: VaultAction.Internal.ArchiveCipherReceive) { when (val result = action.result) { is ArchiveCipherResult.Error -> { @@ -2696,13 +2678,6 @@ sealed class VaultAction { */ data object KdfSyncCompletedReceive : Internal() - /** - * Indicates that the Credential Exchange Protocol export flag has been updated. - */ - data class CredentialExchangeProtocolExportFlagUpdateReceive( - val isCredentialExchangeProtocolExportEnabled: Boolean, - ) : Internal() - /** * Indicates that the New Item Types feature flag has been updated. */ diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/data/platform/repository/DebugMenuRepositoryTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/data/platform/repository/DebugMenuRepositoryTest.kt index 2a3f1db45c..ee7ad797c5 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/data/platform/repository/DebugMenuRepositoryTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/data/platform/repository/DebugMenuRepositoryTest.kt @@ -105,8 +105,8 @@ class DebugMenuRepositoryTest { debugMenuRepository.resetFeatureFlagOverrides() verify(exactly = 1) { mockFeatureFlagOverrideDiskSource.saveFeatureFlag( - FlagKey.CredentialExchangeProtocolImport, - FlagKey.CredentialExchangeProtocolImport.defaultValue, + FlagKey.AttachmentUpdates, + FlagKey.AttachmentUpdates.defaultValue, ) } debugMenuRepository.featureFlagOverridesUpdatedFlow.test { @@ -175,6 +175,7 @@ class DebugMenuRepositoryTest { mockSettingsDiskSource.storeShouldShowAddLoginCoachMark(shouldShow = null) } } + @Test fun `clearSsoCookies should call clearCookies on CookieDiskSource`() { debugMenuRepository.clearSsoCookies() diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModelTest.kt index bfab45d2b6..9339281435 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/platform/feature/settings/vault/VaultSettingsViewModelTest.kt @@ -2,7 +2,6 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.vault import app.cash.turbine.test import com.bitwarden.core.data.manager.BuildInfoManager -import com.bitwarden.core.data.manager.model.FlagKey import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow import com.bitwarden.network.model.PolicyTypeJson import com.bitwarden.network.model.SyncResponseJson @@ -10,7 +9,6 @@ import com.bitwarden.ui.platform.base.BaseViewModelTest import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData import com.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager import com.bitwarden.ui.util.asText -import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager import com.x8bit.bitwarden.data.platform.manager.PolicyManager import com.x8bit.bitwarden.data.platform.manager.model.FirstTimeState @@ -38,13 +36,6 @@ class VaultSettingsViewModelTest : BaseViewModelTest() { every { firstTimeStateFlow } returns mutableFirstTimeStateFlow every { storeShowImportLoginsSettingsBadge(any()) } just runs } - private val mutableFeatureFlagFlow = bufferedMutableSharedFlow() - private val featureFlagManager = mockk { - every { getFeatureFlag(FlagKey.CredentialExchangeProtocolImport) } returns true - every { - getFeatureFlagFlow(FlagKey.CredentialExchangeProtocolImport) - } returns mutableFeatureFlagFlow - } private val mutablePoliciesFlow = bufferedMutableSharedFlow>() private val policyManager = mockk { every { getActivePolicies(any()) } returns emptyList() @@ -79,28 +70,8 @@ class VaultSettingsViewModelTest : BaseViewModelTest() { } } - @Suppress("MaxLineLength") - @Test - fun `ImportItemsClick should emit NavigateToImportVault when CredentialExchangeProtocolImport is disabled`() = - runTest { - val viewModel = createViewModel() - viewModel.eventFlow.test { - every { - featureFlagManager.getFeatureFlag(FlagKey.CredentialExchangeProtocolImport) - } returns false - viewModel.trySendAction(VaultSettingsAction.ImportItemsClick) - assertEquals( - VaultSettingsEvent.NavigateToImportVault, - awaitItem(), - ) - } - } - @Test fun `ImportItemsClick should emit NavigateToImportVault when policy is not empty`() = runTest { - every { - featureFlagManager.getFeatureFlag(FlagKey.CredentialExchangeProtocolImport) - } returns true every { policyManager.getActivePolicies(PolicyTypeJson.PERSONAL_OWNERSHIP) } returns listOf(mockk()) @@ -115,22 +86,17 @@ class VaultSettingsViewModelTest : BaseViewModelTest() { } } - @Suppress("MaxLineLength") @Test - fun `ImportItemsClick should emit NavigateToImportItems when CredentialExchangeProtocolImport is enabled`() = - runTest { - val viewModel = createViewModel() - viewModel.eventFlow.test { - every { - featureFlagManager.getFeatureFlag(FlagKey.CredentialExchangeProtocolImport) - } returns true - viewModel.trySendAction(VaultSettingsAction.ImportItemsClick) - assertEquals( - VaultSettingsEvent.NavigateToImportItems, - awaitItem(), - ) - } + fun `ImportItemsClick should emit NavigateToImportItems when policy is empty`() = runTest { + val viewModel = createViewModel() + viewModel.eventFlow.test { + viewModel.trySendAction(VaultSettingsAction.ImportItemsClick) + assertEquals( + VaultSettingsEvent.NavigateToImportItems, + awaitItem(), + ) } + } @Test fun `shouldShowImportCard should update when first time state changes`() = runTest { @@ -191,44 +157,34 @@ class VaultSettingsViewModelTest : BaseViewModelTest() { } @Test - fun `showImportItemsChevron should display based on feature flag and policies`() { + fun `showImportItemsChevron should display based on policies`() = runTest { val viewModel = createViewModel() - // Verify chevron is shown when feature flag is enabled and no policies (default state) - assertEquals( - viewModel.stateFlow.value, - VaultSettingsState(showImportActionCard = true, showImportItemsChevron = true), - ) + viewModel.stateFlow.test { + // Verify chevron is shown when there are no policies (default state) + assertEquals( + VaultSettingsState(showImportActionCard = true, showImportItemsChevron = true), + awaitItem(), + ) - // Verify chevron is hidden when feature flag is disabled and no policies - mutableFeatureFlagFlow.tryEmit(false) - mutablePoliciesFlow.tryEmit(emptyList()) - assertEquals( - viewModel.stateFlow.value, - VaultSettingsState(showImportActionCard = true, showImportItemsChevron = false), - ) + // Verify chevron is hidden when policies exist + mutablePoliciesFlow.tryEmit(listOf(mockk())) + assertEquals( + VaultSettingsState(showImportActionCard = true, showImportItemsChevron = false), + awaitItem(), + ) - // Verify chevron is hidden when feature flag is enabled and policies exist - mutableFeatureFlagFlow.tryEmit(true) - mutablePoliciesFlow.tryEmit(listOf(mockk())) - assertEquals( - viewModel.stateFlow.value, - VaultSettingsState(showImportActionCard = true, showImportItemsChevron = false), - ) - - // Verify chevron is hidden when feature flag is disabled and no policies - mutableFeatureFlagFlow.tryEmit(false) - mutablePoliciesFlow.tryEmit(emptyList()) - assertEquals( - viewModel.stateFlow.value, - VaultSettingsState(showImportActionCard = true, showImportItemsChevron = false), - ) + // Verify chevron is hidden when there are no policies + mutablePoliciesFlow.tryEmit(emptyList()) + assertEquals( + VaultSettingsState(showImportActionCard = true, showImportItemsChevron = true), + awaitItem(), + ) + } } - @Suppress("MaxLineLength") @Test - fun `showImportItemsChevron should be false when feature flag is enabled but policy exists`() { + fun `showImportItemsChevron should be false when policy exists`() { val viewModel = createViewModel() - mutableFeatureFlagFlow.tryEmit(true) mutablePoliciesFlow.tryEmit(listOf(mockk())) assertEquals( VaultSettingsState(showImportActionCard = true, showImportItemsChevron = false), @@ -267,7 +223,6 @@ class VaultSettingsViewModelTest : BaseViewModelTest() { buildInfoManager = buildInfoManager, firstTimeActionManager = firstTimeActionManager, snackbarRelayManager = snackbarRelayManager, - featureFlagManager = featureFlagManager, policyManager = policyManager, ) } diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendScreenTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendScreenTest.kt index f90ad6f747..19a153125e 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendScreenTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendScreenTest.kt @@ -208,15 +208,13 @@ class AddEditSendScreenTest : BitwardenComposeTest() { @Test fun `on copyPassword click should send PasswordCopyClick when passwordInput is not empty`() { - // Expand options section: - composeTestRule - .onNodeWithText("Additional options") - .performScrollTo() - .performClick() mutableStateFlow.update { it.copy( viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy(passwordInput = "somePass"), + common = DEFAULT_COMMON_STATE.copy( + sendAuth = SendAuth.Password, + passwordInput = "somePass", + ), ), ) } @@ -227,25 +225,20 @@ class AddEditSendScreenTest : BitwardenComposeTest() { verify { viewModel.trySendAction( - AddEditSendAction.PasswordCopyClick( - "somePass", - ), + AddEditSendAction.PasswordCopyClick(password = "somePass"), ) } } @Test fun `on copyPassword click should not send PasswordCopyClick when passwordInput is empty`() { - // Expand options section: - composeTestRule - .onNodeWithText("Additional options") - .performScrollTo() - .performClick() - mutableStateFlow.update { it.copy( viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy(passwordInput = ""), + common = DEFAULT_COMMON_STATE.copy( + sendAuth = SendAuth.Password, + passwordInput = "", + ), ), ) } @@ -254,20 +247,22 @@ class AddEditSendScreenTest : BitwardenComposeTest() { .performScrollTo() .performClick() verify(exactly = 0) { - viewModel.trySendAction( - AddEditSendAction.PasswordCopyClick(password = ""), - ) + viewModel.trySendAction(any()) } } @Suppress("MaxLineLength") @Test fun `on generatePassword click should send OpenPasswordGeneratorClick when passwordInput is empty`() { - // Expand options section: - composeTestRule - .onNodeWithText("Additional options") - .performScrollTo() - .performClick() + mutableStateFlow.update { + it.copy( + viewState = DEFAULT_VIEW_STATE.copy( + common = DEFAULT_COMMON_STATE.copy( + sendAuth = SendAuth.Password, + ), + ), + ) + } composeTestRule .onNodeWithTag(testTag = "RegeneratePasswordButton") .performScrollTo() @@ -282,15 +277,13 @@ class AddEditSendScreenTest : BitwardenComposeTest() { @Suppress("MaxLineLength") @Test fun `on generatePassword click should show Password Overwrite dialog when passwordInput is not empty`() { - // Expand options section: - composeTestRule - .onNodeWithText("Additional options") - .performScrollTo() - .performClick() mutableStateFlow.update { it.copy( viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy(passwordInput = "somePass"), + common = DEFAULT_COMMON_STATE.copy( + sendAuth = SendAuth.Password, + passwordInput = "somePass", + ), ), ) } @@ -636,9 +629,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { composeTestRule .onNodeWithText("Maximum access count") .assertExists() - composeTestRule - .onNodeWithText("New password") - .assertExists() composeTestRule .onNodeWithText("Private notes") .assertExists() @@ -698,41 +688,29 @@ class AddEditSendScreenTest : BitwardenComposeTest() { verify { viewModel.trySendAction(AddEditSendAction.MaxAccessCountChange(1)) } } - @Test - fun `on password input change should send PasswordChange`() = runTest { - // Expand options section: - composeTestRule - .onNodeWithText("Additional options") - .performScrollTo() - .performClick() - - composeTestRule - .onNodeWithText("New password") - .performTextInput("input") - verify { viewModel.trySendAction(AddEditSendAction.PasswordChange("input")) } - } - @Test fun `password input should change according to the state`() { - // Expand options section: + val commonState = DEFAULT_COMMON_STATE.copy( + sendAuth = SendAuth.Password, + passwordInput = "", + ) + mutableStateFlow.update { + it.copy(viewState = DEFAULT_VIEW_STATE.copy(common = commonState)) + } composeTestRule - .onNodeWithText("Additional options") - .performScrollTo() - .performClick() - composeTestRule - .onNodeWithText("New password") - .assertTextEquals("New password", "") + .onNodeWithText("Password") + .assertTextEquals("Password", "") mutableStateFlow.update { it.copy( viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy(passwordInput = "input"), + common = commonState.copy(passwordInput = "input"), ), ) } composeTestRule - .onNodeWithText("New password") - .assertTextEquals("New password", "•••••") + .onNodeWithText("Password") + .assertTextEquals("Password", "•••••") } @Test @@ -1033,52 +1011,12 @@ class AddEditSendScreenTest : BitwardenComposeTest() { //region Authentication UI Tests - @Test - fun `auth type chooser should be displayed when feature flag is enabled`() { - mutableStateFlow.update { - it.copy( - viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, - ), - ), - ) - } - - composeTestRule - .onNodeWithTag("SendAuthTypeChooser") - .performScrollTo() - .assertIsDisplayed() - - composeTestRule - .onNodeWithText("Who can view") - .assertIsDisplayed() - } - - @Test - fun `auth type chooser should not be displayed when feature flag is disabled`() { - mutableStateFlow.update { - it.copy( - viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = false, - ), - ), - ) - } - - composeTestRule - .onNodeWithTag("SendAuthTypeChooser") - .assertDoesNotExist() - } - @Test fun `selecting EMAIL auth type should display email fields`() { mutableStateFlow.update { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.None, ), ), @@ -1112,7 +1050,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, hasPassword = false, sendAuth = SendAuth.None, ), @@ -1147,7 +1084,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( hasPassword = false, - isSendEmailVerificationEnabled = true, passwordInput = "", sendAuth = SendAuth.None, ), @@ -1169,7 +1105,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, passwordInput = "", sendAuth = SendAuth.Password, ), @@ -1192,7 +1127,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.None, ), ), @@ -1214,7 +1148,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.Email(emails = persistentListOf(testEmail)), ), ), @@ -1244,7 +1177,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( hasPassword = false, - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.Email( emails = persistentListOf( AuthEmail( @@ -1277,7 +1209,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( hasPassword = false, - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.Email(emails = persistentListOf(email1, email2)), ), ), @@ -1298,7 +1229,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.Email( emails = persistentListOf(email1, email2), ), @@ -1331,7 +1261,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { isPremium = true, viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.None, ), ), @@ -1350,46 +1279,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { .assertIsDisplayed() } - @Test - fun `legacy password field should be hidden when auth chooser is displayed`() { - // Expand options section - composeTestRule - .onNodeWithText("Additional options") - .performScrollTo() - .performClick() - - // With feature flag OFF, legacy password field should be visible - mutableStateFlow.update { - it.copy( - viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = false, - ), - ), - ) - } - - composeTestRule - .onNodeWithText("New password") - .performScrollTo() - .assertIsDisplayed() - - // With feature flag ON, legacy password field should be hidden - mutableStateFlow.update { - it.copy( - viewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, - ), - ), - ) - } - - composeTestRule - .onNodeWithText("New password") - .assertDoesNotExist() - } - @Test fun `email fields should display provided emails from state`() { val email1 = AuthEmail(id = "id1", value = "user1@example.com") @@ -1398,7 +1287,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.Email(emails = persistentListOf(email1, email2)), ), ), @@ -1420,7 +1308,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.Email(emails = persistentListOf(email1, email2)), ), ), @@ -1439,7 +1326,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.None, ), ), @@ -1461,7 +1347,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, sendAuth = SendAuth.Email( emails = persistentListOf( AuthEmail( @@ -1489,7 +1374,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, passwordInput = "", sendAuth = SendAuth.Password, ), @@ -1514,7 +1398,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, passwordInput = "existing-password", sendAuth = SendAuth.Password, ), @@ -1546,7 +1429,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, passwordInput = "existing-password", sendAuth = SendAuth.Password, ), @@ -1578,7 +1460,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, passwordInput = "existing-password", sendAuth = SendAuth.Password, ), @@ -1610,7 +1491,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, passwordInput = "test-password", sendAuth = SendAuth.Password, ), @@ -1635,7 +1515,6 @@ class AddEditSendScreenTest : BitwardenComposeTest() { it.copy( viewState = DEFAULT_VIEW_STATE.copy( common = DEFAULT_COMMON_STATE.copy( - isSendEmailVerificationEnabled = true, passwordInput = "", sendAuth = SendAuth.Password, ), @@ -1665,7 +1544,6 @@ private val DEFAULT_COMMON_STATE = AddEditSendState.ViewState.Content.Common( sendUrl = null, hasPassword = true, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, sendAuth = SendAuth.None, ) diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt index 3bd31909cc..ce8306a6be 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/AddEditSendViewModelTest.kt @@ -3,7 +3,6 @@ package com.x8bit.bitwarden.ui.tools.feature.send.addedit import android.net.Uri import androidx.lifecycle.SavedStateHandle import app.cash.turbine.test -import com.bitwarden.core.data.manager.model.FlagKey import com.bitwarden.core.data.repository.model.DataState import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow import com.bitwarden.data.repository.model.Environment @@ -19,10 +18,9 @@ import com.bitwarden.ui.util.Text import com.bitwarden.ui.util.asText import com.x8bit.bitwarden.data.auth.datasource.disk.model.OnboardingStatus import com.x8bit.bitwarden.data.auth.repository.AuthRepository -import com.x8bit.bitwarden.data.billing.manager.PremiumStateManager import com.x8bit.bitwarden.data.auth.repository.model.PolicyInformation import com.x8bit.bitwarden.data.auth.repository.model.UserState -import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager +import com.x8bit.bitwarden.data.billing.manager.PremiumStateManager import com.x8bit.bitwarden.data.platform.manager.PolicyManager import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager @@ -113,15 +111,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { private val premiumStateManager: PremiumStateManager = mockk { every { isInAppUpgradeAvailable() } returns false } - private val mutableSendEmailVerificationFeatureFlagFlow = MutableStateFlow(false) - private val featureFlagManager: FeatureFlagManager = mockk { - every { - getFeatureFlagFlow(FlagKey.SendEmailVerification) - } returns mutableSendEmailVerificationFeatureFlagFlow - every { - getFeatureFlag(FlagKey.SendEmailVerification) - } answers { mutableSendEmailVerificationFeatureFlagFlow.value } - } @BeforeEach fun setup() { @@ -324,7 +313,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns viewState every { viewState.toSendView(clock) } returns mockSendView @@ -368,7 +356,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns viewState every { viewState.toSendView(clock) } returns mockSendView @@ -612,7 +599,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns viewState mutableSendDataStateFlow.value = DataState.Loaded(mockSendView) @@ -674,7 +660,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns DEFAULT_VIEW_STATE mutableSendDataStateFlow.value = DataState.Loaded(mockSendView) @@ -720,7 +705,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns DEFAULT_VIEW_STATE mutableSendDataStateFlow.value = DataState.Loaded(mockSendView) @@ -795,7 +779,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns DEFAULT_VIEW_STATE mutableSendDataStateFlow.value = DataState.Loaded(mockSendView) @@ -848,7 +831,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns DEFAULT_VIEW_STATE mutableSendDataStateFlow.value = DataState.Loaded(mockSendView) @@ -916,7 +898,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { mockSendView.toViewState( baseWebSendUrl = DEFAULT_ENVIRONMENT_URL, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) } returns viewState mutableSendDataStateFlow.value = DataState.Loaded(mockSendView) @@ -1096,23 +1077,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { } } - @Test - fun `PasswordChange should update note input`() = runTest { - val viewModel = createViewModel() - val expectedViewState = DEFAULT_VIEW_STATE.copy( - common = DEFAULT_COMMON_STATE.copy( - passwordInput = "input", - sendAuth = SendAuth.Password, - ), - ) - - viewModel.stateFlow.test { - assertEquals(DEFAULT_STATE, awaitItem()) - viewModel.trySendAction(AddEditSendAction.PasswordChange("input")) - assertEquals(DEFAULT_STATE.copy(viewState = expectedViewState), awaitItem()) - } - } - @Test fun `DeactivateThisSendToggle should update isDeactivateChecked`() = runTest { val viewModel = createViewModel() @@ -1515,7 +1479,6 @@ class AddEditSendViewModelTest : BaseViewModelTest() { networkConnectionManager = networkConnectionManager, snackbarRelayManager = snackbarRelayManager, generatorRepository = generatorRepository, - featureFlagManager = featureFlagManager, premiumStateManager = premiumStateManager, ) } @@ -1533,7 +1496,6 @@ private val DEFAULT_COMMON_STATE = AddEditSendState.ViewState.Content.Common( sendUrl = null, hasPassword = false, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, sendAuth = SendAuth.None, ) diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensionsTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensionsTest.kt index 0d72ec5f8d..e33afee1a8 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensionsTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/AddEditSendStateExtensionsTest.kt @@ -157,7 +157,6 @@ private val DEFAULT_COMMON_STATE = AddEditSendState.ViewState.Content.Common( sendUrl = null, hasPassword = false, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, sendAuth = SendAuth.Password, ) diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensionsTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensionsTest.kt index 79504b0270..61d66a1f12 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensionsTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/tools/feature/send/addedit/util/SendViewExtensionsTest.kt @@ -17,7 +17,6 @@ class SendViewExtensionsTest { val result = sendView.toViewState( baseWebSendUrl = "www.test.com/", isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) assertEquals( @@ -38,7 +37,6 @@ class SendViewExtensionsTest { val result = sendView.toViewState( baseWebSendUrl = "www.test.com/", isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, ) assertEquals( @@ -68,7 +66,6 @@ private val DEFAULT_COMMON: AddEditSendState.ViewState.Content.Common = sendUrl = "www.test.com/mockAccessId-1/mockKey-1", hasPassword = true, isHideEmailAddressEnabled = true, - isSendEmailVerificationEnabled = false, sendAuth = SendAuth.None, ) diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt index f343617e35..09de01d43f 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt @@ -232,12 +232,8 @@ class VaultViewModelTest : BaseViewModelTest() { coEvery { register() } returns RegisterExportResult.Success coEvery { unregister() } returns UnregisterExportResult.Success } - private val mutableCxpExportFeatureFlagFlow = MutableStateFlow(false) private val mutableNewItemTypesFlagFlow = MutableStateFlow(false) private val featureFlagManager: FeatureFlagManager = mockk { - every { - getFeatureFlagFlow(FlagKey.CredentialExchangeProtocolExport) - } returns mutableCxpExportFeatureFlagFlow every { getFeatureFlagFlow(FlagKey.NewItemTypes) } returns mutableNewItemTypesFlagFlow } @@ -1260,7 +1256,6 @@ class VaultViewModelTest : BaseViewModelTest() { ) } - @Suppress("MaxLineLength") @Test fun `on AddAccountClick should set hasPendingAccountAddition to true on the AuthRepository`() { val viewModel = createViewModel() @@ -3945,7 +3940,6 @@ class VaultViewModelTest : BaseViewModelTest() { } } - @Suppress("MaxLineLength") @Test fun `when ImportActionCardClick is sent, NavigateToImportLogins event is sent`() = runTest { @@ -3959,7 +3953,6 @@ class VaultViewModelTest : BaseViewModelTest() { } } - @Suppress("MaxLineLength") @Test fun `when ImportActionCardClick is sent, repository is not called if value is already false`() { mutableUserStateFlow.value = DEFAULT_USER_STATE.copy( @@ -4411,70 +4404,24 @@ class VaultViewModelTest : BaseViewModelTest() { } } - @Suppress("MaxLineLength") @Test - fun `CredentialExchangeProtocolExportFlagUpdateReceive should register for export when flag is enabled`() = - runTest { - mutableCxpExportFeatureFlagFlow.value = false - coEvery { credentialExchangeRegistryManager.register() } just awaits + fun `credentialExchangeRegistryManager should register when not fdroid`() = runTest { + createViewModel() - val viewModel = createViewModel() - - viewModel.trySendAction( - VaultAction.Internal.CredentialExchangeProtocolExportFlagUpdateReceive( - isCredentialExchangeProtocolExportEnabled = true, - ), - ) - - coVerify { - credentialExchangeRegistryManager.register() - } + coVerify(exactly = 1) { + credentialExchangeRegistryManager.register() } + } - @Suppress("MaxLineLength") @Test - fun `CredentialExchangeProtocolExportFlagUpdateReceive should unregister when flag is disabled`() = - runTest { - mutableCxpExportFeatureFlagFlow.value = true - every { settingsRepository.isAppRegisteredForExport() } returns true - coEvery { credentialExchangeRegistryManager.unregister() } just awaits + fun `credentialExchangeRegistryManager should not register when fdroid`() = runTest { + every { buildInfoManager.isFdroid } returns true + createViewModel() - val viewModel = createViewModel() - - viewModel.trySendAction( - VaultAction.Internal.CredentialExchangeProtocolExportFlagUpdateReceive( - isCredentialExchangeProtocolExportEnabled = false, - ), - ) - - coVerify { - credentialExchangeRegistryManager.unregister() - } - } - - @Suppress("MaxLineLength") - @Test - fun `CredentialExchangeProtocolExportFlagUpdateReceive should unregister when flag is enabled but isFdroid is true`() = - runTest { - every { buildInfoManager.isFdroid } returns true - mutableCxpExportFeatureFlagFlow.value = false - coEvery { credentialExchangeRegistryManager.unregister() } just awaits - - val viewModel = createViewModel() - - viewModel.trySendAction( - VaultAction.Internal.CredentialExchangeProtocolExportFlagUpdateReceive( - isCredentialExchangeProtocolExportEnabled = true, - ), - ) - - coVerify { - credentialExchangeRegistryManager.unregister() - } - coVerify(exactly = 0) { - credentialExchangeRegistryManager.register() - } + coVerify(exactly = 0) { + credentialExchangeRegistryManager.register() } + } @Test fun `vault data loaded with premium user should set validTotpIds from getValidTotpCipherIds`() = diff --git a/core/src/main/kotlin/com/bitwarden/core/data/manager/model/FlagKey.kt b/core/src/main/kotlin/com/bitwarden/core/data/manager/model/FlagKey.kt index 1b496f9937..ed5eb442ad 100644 --- a/core/src/main/kotlin/com/bitwarden/core/data/manager/model/FlagKey.kt +++ b/core/src/main/kotlin/com/bitwarden/core/data/manager/model/FlagKey.kt @@ -30,12 +30,9 @@ sealed class FlagKey { */ val activePasswordManagerFlags: List> by lazy { listOf( - CredentialExchangeProtocolImport, - CredentialExchangeProtocolExport, ForceUpdateKdfSettings, NoLogoutOnKdfChange, MigrateMyVaultToMyItems, - SendEmailVerification, CardScanner, MobilePremiumUpgrade, ManageDevices, @@ -50,24 +47,6 @@ sealed class FlagKey { } } - /** - * Data object holding hte feature flag key for the Credential Exchange Protocol (CXP) import - * feature. - */ - data object CredentialExchangeProtocolImport : FlagKey() { - override val keyName: String = "cxp-import-mobile" - override val defaultValue: Boolean = false - } - - /** - * Data object holding the feature flag key for the Credential Exchange Protocol (CXP) export - * feature. - */ - data object CredentialExchangeProtocolExport : FlagKey() { - override val keyName: String = "cxp-export-mobile" - override val defaultValue: Boolean = false - } - /** * Indicates the state of Bitwarden authentication. */ @@ -100,14 +79,6 @@ sealed class FlagKey { override val defaultValue: Boolean = false } - /** - * Data object holding the feature flag key for the Send Email Verification feature. - */ - data object SendEmailVerification : FlagKey() { - override val keyName: String = "pm-19051-send-email-verification" - override val defaultValue: Boolean = false - } - /** * Data object holding the feature flag key for the card scanner feature. */ diff --git a/core/src/test/kotlin/com/bitwarden/core/data/manager/model/FlagKeyTest.kt b/core/src/test/kotlin/com/bitwarden/core/data/manager/model/FlagKeyTest.kt index d1f67c8967..395e2b5704 100644 --- a/core/src/test/kotlin/com/bitwarden/core/data/manager/model/FlagKeyTest.kt +++ b/core/src/test/kotlin/com/bitwarden/core/data/manager/model/FlagKeyTest.kt @@ -8,14 +8,6 @@ class FlagKeyTest { @Test fun `Feature flags have the correct key name set`() { - assertEquals( - FlagKey.CredentialExchangeProtocolImport.keyName, - "cxp-import-mobile", - ) - assertEquals( - FlagKey.CredentialExchangeProtocolExport.keyName, - "cxp-export-mobile", - ) assertEquals( FlagKey.BitwardenAuthenticationEnabled.keyName, "bitwarden-authentication-enabled", @@ -28,10 +20,6 @@ class FlagKeyTest { FlagKey.MigrateMyVaultToMyItems.keyName, "pm-20558-migrate-myvault-to-myitems", ) - assertEquals( - FlagKey.SendEmailVerification.keyName, - "pm-19051-send-email-verification", - ) assertEquals( FlagKey.MobilePremiumUpgrade.keyName, "pm-31697-premium-upgrade-path", @@ -70,12 +58,9 @@ class FlagKeyTest { fun `All feature flags have the correct default value set`() { assertTrue( listOf( - FlagKey.CredentialExchangeProtocolImport, - FlagKey.CredentialExchangeProtocolExport, FlagKey.BitwardenAuthenticationEnabled, FlagKey.ForceUpdateKdfSettings, FlagKey.MigrateMyVaultToMyItems, - FlagKey.SendEmailVerification, FlagKey.MobilePremiumUpgrade, FlagKey.AttachmentUpdates, FlagKey.V2EncryptionJitPassword, diff --git a/ui/src/main/kotlin/com/bitwarden/ui/platform/components/debug/FeatureFlagListItems.kt b/ui/src/main/kotlin/com/bitwarden/ui/platform/components/debug/FeatureFlagListItems.kt index 1e536f477f..c69302aaf3 100644 --- a/ui/src/main/kotlin/com/bitwarden/ui/platform/components/debug/FeatureFlagListItems.kt +++ b/ui/src/main/kotlin/com/bitwarden/ui/platform/components/debug/FeatureFlagListItems.kt @@ -24,13 +24,10 @@ fun FlagKey.ListItemContent( FlagKey.DummyBoolean, FlagKey.BitwardenAuthenticationEnabled, - FlagKey.CredentialExchangeProtocolImport, - FlagKey.CredentialExchangeProtocolExport, FlagKey.ForceUpdateKdfSettings, FlagKey.NoLogoutOnKdfChange, FlagKey.MigrateMyVaultToMyItems, FlagKey.CardScanner, - FlagKey.SendEmailVerification, FlagKey.MobilePremiumUpgrade, FlagKey.ManageDevices, FlagKey.AttachmentUpdates, @@ -81,8 +78,6 @@ private fun FlagKey.getDisplayLabel(): String = when (this) { FlagKey.DummyString, -> this.keyName - FlagKey.CredentialExchangeProtocolImport -> stringResource(BitwardenString.cxp_import) - FlagKey.CredentialExchangeProtocolExport -> stringResource(BitwardenString.cxp_export) FlagKey.ForceUpdateKdfSettings -> stringResource(BitwardenString.force_update_kdf_settings) FlagKey.NoLogoutOnKdfChange -> stringResource(BitwardenString.avoid_logout_on_kdf_change) FlagKey.BitwardenAuthenticationEnabled -> { @@ -91,7 +86,6 @@ private fun FlagKey.getDisplayLabel(): String = when (this) { FlagKey.MigrateMyVaultToMyItems -> stringResource(BitwardenString.migrate_my_vault_to_my_items) FlagKey.CardScanner -> stringResource(BitwardenString.scan_card) - FlagKey.SendEmailVerification -> stringResource(BitwardenString.send_email_verification) FlagKey.MobilePremiumUpgrade -> stringResource(BitwardenString.mobile_premium_upgrade) FlagKey.ManageDevices -> stringResource(BitwardenString.manage_devices) FlagKey.AttachmentUpdates -> stringResource(BitwardenString.attachment_updates) diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 83bd98b565..bc9da8c0d4 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -472,8 +472,6 @@ Scanning will happen automatically. If set, users will no longer be able to access this Send once the maximum access count is reached. Max access count reached Current access count: %s - New password - Require this password to view the Send. Remove password Removing password Password removed @@ -892,8 +890,6 @@ Do you want to switch to this account? Copy address Biometrics are no longer supported on this device You’ve been logged out because your device’s biometrics don’t meet the latest security requirements. To update settings, log in once again or contact your administrator for access. - CXP Import - CXP Export Choose three or four random words Pick three or four random, unrelated words that you can easily remember. Think of objects, places, or things you like. Combine those words together diff --git a/ui/src/main/res/values/strings_non_localized.xml b/ui/src/main/res/values/strings_non_localized.xml index dabe4891c8..c9738efba5 100644 --- a/ui/src/main/res/values/strings_non_localized.xml +++ b/ui/src/main/res/values/strings_non_localized.xml @@ -42,7 +42,6 @@ Force update KDF settings Avoid logout on KDF change Migrate My Vault to My Items - Send Email Verification Trigger cookie acquisition Clear SSO cookies Mobile Premium Upgrade