mirror of
https://github.com/bitwarden/android.git
synced 2024-11-26 19:36:18 +03:00
BIT-1277 BIT-1279: Confirmation dialog (#805)
This commit is contained in:
parent
f023650730
commit
b991acd0d0
4 changed files with 84 additions and 32 deletions
|
@ -17,7 +17,9 @@ import androidx.compose.material3.TopAppBarDefaults
|
|||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
|
@ -40,6 +42,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenMultiSelectButton
|
|||
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordField
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTwoButtonDialog
|
||||
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.exportvault.model.ExportVaultFormat
|
||||
import com.x8bit.bitwarden.ui.platform.util.displayLabel
|
||||
|
@ -67,6 +70,29 @@ fun ExportVaultScreen(
|
|||
}
|
||||
}
|
||||
|
||||
var shouldShowConfirmationDialog by remember { mutableStateOf(false) }
|
||||
if (shouldShowConfirmationDialog) {
|
||||
BitwardenTwoButtonDialog(
|
||||
title = stringResource(id = R.string.export_vault_confirmation_title),
|
||||
message = if (state.exportFormat == ExportVaultFormat.JSON_ENCRYPTED) {
|
||||
stringResource(id = R.string.enc_export_key_warning)
|
||||
.plus("\n\n")
|
||||
.plus(stringResource(id = R.string.enc_export_account_warning))
|
||||
} else {
|
||||
stringResource(
|
||||
id = R.string.export_vault_warning,
|
||||
)
|
||||
},
|
||||
confirmButtonText = stringResource(id = R.string.export_vault),
|
||||
dismissButtonText = stringResource(id = R.string.cancel),
|
||||
onConfirmClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(ExportVaultAction.ConfirmExportVaultClicked) }
|
||||
},
|
||||
onDismissClick = { shouldShowConfirmationDialog = false },
|
||||
onDismissRequest = { shouldShowConfirmationDialog = false },
|
||||
)
|
||||
}
|
||||
|
||||
when (val dialog = state.dialogState) {
|
||||
is ExportVaultState.DialogState.Error -> {
|
||||
BitwardenBasicDialog(
|
||||
|
@ -116,9 +142,7 @@ fun ExportVaultScreen(
|
|||
onPasswordInputChanged = remember(viewModel) {
|
||||
{ viewModel.trySendAction(ExportVaultAction.PasswordInputChanged(it)) }
|
||||
},
|
||||
onExportVaultClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(ExportVaultAction.ExportVaultClick) }
|
||||
},
|
||||
onExportVaultClick = { shouldShowConfirmationDialog = true },
|
||||
modifier = Modifier
|
||||
.padding(innerPadding)
|
||||
.fillMaxSize(),
|
||||
|
|
|
@ -40,9 +40,9 @@ class ExportVaultViewModel @Inject constructor(
|
|||
override fun handleAction(action: ExportVaultAction) {
|
||||
when (action) {
|
||||
ExportVaultAction.CloseButtonClick -> handleCloseButtonClicked()
|
||||
ExportVaultAction.ConfirmExportVaultClicked -> handleConfirmExportVaultClicked()
|
||||
ExportVaultAction.DialogDismiss -> handleDialogDismiss()
|
||||
is ExportVaultAction.ExportFormatOptionSelect -> handleExportFormatOptionSelect(action)
|
||||
ExportVaultAction.ExportVaultClick -> handleExportVaultClick()
|
||||
is ExportVaultAction.PasswordInputChanged -> handlePasswordInputChanged(action)
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,15 @@ class ExportVaultViewModel @Inject constructor(
|
|||
sendEvent(ExportVaultEvent.NavigateBack)
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the master password after confirming exporting the vault.
|
||||
*/
|
||||
private fun handleConfirmExportVaultClicked() {
|
||||
// TODO: BIT-1273
|
||||
mutableStateFlow.update { it.copy(dialogState = null) }
|
||||
sendEvent(ExportVaultEvent.ShowToast("Coming soon to a PR near you!".asText()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismiss the dialog.
|
||||
*/
|
||||
|
@ -70,14 +79,6 @@ class ExportVaultViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the confirmation dialog and export the vault.
|
||||
*/
|
||||
private fun handleExportVaultClick() {
|
||||
// TODO: BIT-1273
|
||||
sendEvent(ExportVaultEvent.ShowToast(message = "Coming soon to an app near you!".asText()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the state with the new password input.
|
||||
*/
|
||||
|
@ -145,6 +146,11 @@ sealed class ExportVaultAction {
|
|||
*/
|
||||
data object CloseButtonClick : ExportVaultAction()
|
||||
|
||||
/**
|
||||
* Indicates that the confirm export vault button was clicked.
|
||||
*/
|
||||
data object ConfirmExportVaultClicked : ExportVaultAction()
|
||||
|
||||
/**
|
||||
* Indicates that the dialog has been dismissed.
|
||||
*/
|
||||
|
@ -155,11 +161,6 @@ sealed class ExportVaultAction {
|
|||
*/
|
||||
data class ExportFormatOptionSelect(val option: ExportVaultFormat) : ExportVaultAction()
|
||||
|
||||
/**
|
||||
* Indicates that the export vault button was clicked.
|
||||
*/
|
||||
data object ExportVaultClick : ExportVaultAction()
|
||||
|
||||
/**
|
||||
* Indicates that the password input has changed.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package com.x8bit.bitwarden.ui.platform.feature.settings.exportvault
|
||||
|
||||
import androidx.compose.ui.test.assert
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.filterToOne
|
||||
import androidx.compose.ui.test.hasAnyAncestor
|
||||
import androidx.compose.ui.test.isDialog
|
||||
import androidx.compose.ui.test.isDisplayed
|
||||
import androidx.compose.ui.test.onAllNodesWithText
|
||||
import androidx.compose.ui.test.onFirst
|
||||
|
@ -13,6 +17,7 @@ import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFl
|
|||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.exportvault.model.ExportVaultFormat
|
||||
import com.x8bit.bitwarden.ui.util.assertNoDialogExists
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
|
@ -65,13 +70,48 @@ class ExportVaultScreenTest : BaseComposeTest() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `export vault button click should emit ExportVaultClick action`() {
|
||||
fun `export vault button click should display confirmation dialog`() {
|
||||
composeTestRule.onNodeWithText("Confirm vault export").assertDoesNotExist()
|
||||
|
||||
// Click the export vault button shows the alert.
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Export vault")
|
||||
.onFirst()
|
||||
.performClick()
|
||||
composeTestRule
|
||||
.onNodeWithText("Confirm vault export")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
// Clicking the cancel button dismisses the alert.
|
||||
composeTestRule
|
||||
.onNodeWithText("Cancel")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.performClick()
|
||||
composeTestRule.assertNoDialogExists()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `confirm export vault button click should send ConfirmExportClick action`() {
|
||||
composeTestRule.onNodeWithText("Confirm vault export").assertDoesNotExist()
|
||||
|
||||
// Click the export vault button shows the alert.
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Export vault")
|
||||
.onFirst()
|
||||
.performClick()
|
||||
composeTestRule
|
||||
.onNodeWithText("Confirm vault export")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.assertIsDisplayed()
|
||||
|
||||
// Clicking the confirm button sends the confirm action.
|
||||
composeTestRule
|
||||
.onAllNodesWithText("Export vault")
|
||||
.filterToOne(hasAnyAncestor(isDialog()))
|
||||
.performClick()
|
||||
verify {
|
||||
viewModel.trySendAction(ExportVaultAction.ExportVaultClick)
|
||||
viewModel.trySendAction(ExportVaultAction.ConfirmExportVaultClicked)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.exportvault
|
|||
import androidx.lifecycle.SavedStateHandle
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.exportvault.model.ExportVaultFormat
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
@ -50,18 +49,6 @@ class ExportVaultViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ExportVaultClick should emit ShowToast`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.actionChannel.trySend(ExportVaultAction.ExportVaultClick)
|
||||
assertEquals(
|
||||
ExportVaultEvent.ShowToast(message = "Coming soon to an app near you!".asText()),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PasswordInputChanged should update the password input in the state`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
|
|
Loading…
Reference in a new issue