mirror of
https://github.com/bitwarden/android.git
synced 2024-11-27 12:00:19 +03:00
BIT-1411, BIT-1414: Add delete send confirmation dialog (#680)
This commit is contained in:
parent
a706db2b28
commit
2fa7851b42
4 changed files with 93 additions and 4 deletions
|
@ -30,6 +30,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowActionItem
|
|||
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenSearchActionItem
|
||||
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.components.OverflowMenuItemData
|
||||
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
||||
|
@ -92,6 +93,9 @@ fun VaultItemListingScreen(
|
|||
|
||||
VaultItemListingDialogs(
|
||||
dialogState = state.dialogState,
|
||||
onDeleteSendConfirm = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultItemListingsAction.DeleteSendConfirmClick(it)) }
|
||||
},
|
||||
onDismissRequest = remember(viewModel) {
|
||||
{ viewModel.trySendAction(VaultItemListingsAction.DismissDialogClick) }
|
||||
},
|
||||
|
@ -108,9 +112,20 @@ fun VaultItemListingScreen(
|
|||
@Composable
|
||||
private fun VaultItemListingDialogs(
|
||||
dialogState: VaultItemListingState.DialogState?,
|
||||
onDeleteSendConfirm: (sendId: String) -> Unit,
|
||||
onDismissRequest: () -> Unit,
|
||||
) {
|
||||
when (dialogState) {
|
||||
is VaultItemListingState.DialogState.DeleteSendConfirmation -> BitwardenTwoButtonDialog(
|
||||
title = stringResource(id = R.string.delete),
|
||||
message = stringResource(id = R.string.are_you_sure_delete_send),
|
||||
confirmButtonText = stringResource(id = R.string.yes),
|
||||
dismissButtonText = stringResource(id = R.string.cancel),
|
||||
onConfirmClick = { onDeleteSendConfirm(dialogState.sendId) },
|
||||
onDismissClick = onDismissRequest,
|
||||
onDismissRequest = onDismissRequest,
|
||||
)
|
||||
|
||||
is VaultItemListingState.DialogState.Error -> BitwardenBasicDialog(
|
||||
visibilityState = BasicDialogState.Shown(
|
||||
title = dialogState.title,
|
||||
|
|
|
@ -86,6 +86,10 @@ class VaultItemListingViewModel @Inject constructor(
|
|||
is VaultItemListingsAction.RefreshClick -> handleRefreshClick()
|
||||
is VaultItemListingsAction.CopySendUrlClick -> handleCopySendUrlClick(action)
|
||||
is VaultItemListingsAction.DeleteSendClick -> handleDeleteSendClick(action)
|
||||
is VaultItemListingsAction.DeleteSendConfirmClick -> {
|
||||
handleDeleteSendConfirmClick(action)
|
||||
}
|
||||
|
||||
is VaultItemListingsAction.ShareSendUrlClick -> handleShareSendUrlClick(action)
|
||||
is VaultItemListingsAction.RemoveSendPasswordClick -> {
|
||||
handleRemoveSendPasswordClick(action)
|
||||
|
@ -105,6 +109,18 @@ class VaultItemListingViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleDeleteSendClick(action: VaultItemListingsAction.DeleteSendClick) {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = VaultItemListingState.DialogState.DeleteSendConfirmation(
|
||||
sendId = action.sendId,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDeleteSendConfirmClick(
|
||||
action: VaultItemListingsAction.DeleteSendConfirmClick,
|
||||
) {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = VaultItemListingState.DialogState.Loading(
|
||||
|
@ -395,6 +411,14 @@ data class VaultItemListingState(
|
|||
*/
|
||||
sealed class DialogState : Parcelable {
|
||||
|
||||
/**
|
||||
* Represents a dismissible dialog with the given error [message].
|
||||
*/
|
||||
@Parcelize
|
||||
data class DeleteSendConfirmation(
|
||||
val sendId: String,
|
||||
) : DialogState()
|
||||
|
||||
/**
|
||||
* Represents a dismissible dialog with the given error [message].
|
||||
*/
|
||||
|
@ -710,6 +734,11 @@ sealed class VaultItemListingsAction {
|
|||
*/
|
||||
data class DeleteSendClick(val sendId: String) : VaultItemListingsAction()
|
||||
|
||||
/**
|
||||
* Click on the delete send confirmation button.
|
||||
*/
|
||||
data class DeleteSendConfirmClick(val sendId: String) : VaultItemListingsAction()
|
||||
|
||||
/**
|
||||
* Models actions that the [VaultItemListingViewModel] itself might send.
|
||||
*/
|
||||
|
|
|
@ -605,6 +605,36 @@ class VaultItemListingScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `delete send confirmation dialog should be displayed according to state and emits DeleteSendConfirmClick on confirmation`() {
|
||||
val sendId = "sendId"
|
||||
val message = "Are you sure you want to delete this Send?"
|
||||
composeTestRule.onNode(isDialog()).assertDoesNotExist()
|
||||
composeTestRule.onNodeWithText(message).assertDoesNotExist()
|
||||
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = VaultItemListingState.DialogState.DeleteSendConfirmation(
|
||||
sendId = sendId,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText(message)
|
||||
.assertIsDisplayed()
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
composeTestRule
|
||||
.onNodeWithText("Yes")
|
||||
.assert(hasAnyAncestor(isDialog()))
|
||||
.performClick()
|
||||
|
||||
verify(exactly = 1) {
|
||||
viewModel.trySendAction(VaultItemListingsAction.DeleteSendConfirmClick(sendId))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `error dialog should be displayed according to state`() {
|
||||
val errorMessage = "Fail"
|
||||
|
|
|
@ -200,14 +200,29 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `DeleteSendClick with deleteSend error should display error dialog`() = runTest {
|
||||
fun `DeleteSendClick should display delete confirmation dialog`() {
|
||||
val sendId = "sendId"
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
viewModel.trySendAction(VaultItemListingsAction.DeleteSendClick(sendId))
|
||||
assertEquals(
|
||||
initialState.copy(
|
||||
dialogState = VaultItemListingState.DialogState.DeleteSendConfirmation(
|
||||
sendId = sendId,
|
||||
),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `DeleteSendConfirmClick with deleteSend error should display error dialog`() = runTest {
|
||||
val sendId = "sendId1234"
|
||||
coEvery { vaultRepository.deleteSend(sendId) } returns DeleteSendResult.Error
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
viewModel.stateFlow.test {
|
||||
assertEquals(initialState, awaitItem())
|
||||
viewModel.trySendAction(VaultItemListingsAction.DeleteSendClick(sendId))
|
||||
viewModel.trySendAction(VaultItemListingsAction.DeleteSendConfirmClick(sendId))
|
||||
assertEquals(
|
||||
initialState.copy(
|
||||
dialogState = VaultItemListingState.DialogState.Loading(
|
||||
|
@ -229,13 +244,13 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `DeleteSendClick with deleteSend success should emit ShowToast`() = runTest {
|
||||
fun `DeleteSendConfirmClick with deleteSend success should emit ShowToast`() = runTest {
|
||||
val sendId = "sendId1234"
|
||||
coEvery { vaultRepository.deleteSend(sendId) } returns DeleteSendResult.Success
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultItemListingsAction.DeleteSendClick(sendId))
|
||||
viewModel.trySendAction(VaultItemListingsAction.DeleteSendConfirmClick(sendId))
|
||||
assertEquals(
|
||||
VaultItemListingEvent.ShowToast(R.string.send_deleted.asText()),
|
||||
awaitItem(),
|
||||
|
|
Loading…
Reference in a new issue