mirror of
https://github.com/bitwarden/android.git
synced 2025-12-11 04:39:19 -06:00
PM-23292: Migrate toasts to snackbars (#5940)
This commit is contained in:
parent
7bf4acbb28
commit
d5d4caea62
@ -1,6 +1,5 @@
|
|||||||
package com.x8bit.bitwarden.ui.auth.feature.completeregistration
|
package com.x8bit.bitwarden.ui.auth.feature.completeregistration
|
||||||
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@ -26,7 +25,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
@ -48,6 +46,9 @@ import com.bitwarden.ui.platform.components.field.BitwardenPasswordField
|
|||||||
import com.bitwarden.ui.platform.components.field.BitwardenTextField
|
import com.bitwarden.ui.platform.components.field.BitwardenTextField
|
||||||
import com.bitwarden.ui.platform.components.model.CardStyle
|
import com.bitwarden.ui.platform.components.model.CardStyle
|
||||||
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarHost
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.model.rememberBitwardenSnackbarHostState
|
||||||
import com.bitwarden.ui.platform.components.text.BitwardenClickableText
|
import com.bitwarden.ui.platform.components.text.BitwardenClickableText
|
||||||
import com.bitwarden.ui.platform.components.toggle.BitwardenSwitch
|
import com.bitwarden.ui.platform.components.toggle.BitwardenSwitch
|
||||||
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
|
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
|
||||||
@ -74,16 +75,15 @@ fun CompleteRegistrationScreen(
|
|||||||
) {
|
) {
|
||||||
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
|
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
|
||||||
val handler = rememberCompleteRegistrationHandler(viewModel = viewModel)
|
val handler = rememberCompleteRegistrationHandler(viewModel = viewModel)
|
||||||
val context = LocalContext.current
|
val snackbarHostState = rememberBitwardenSnackbarHostState()
|
||||||
|
|
||||||
// route OS back actions through the VM to clear the special circumstance
|
// route OS back actions through the VM to clear the special circumstance
|
||||||
BackHandler(onBack = handler.onBackClick)
|
BackHandler(onBack = handler.onBackClick)
|
||||||
|
|
||||||
EventsEffect(viewModel) { event ->
|
EventsEffect(viewModel) { event ->
|
||||||
when (event) {
|
when (event) {
|
||||||
is CompleteRegistrationEvent.NavigateBack -> onNavigateBack.invoke()
|
is CompleteRegistrationEvent.NavigateBack -> onNavigateBack.invoke()
|
||||||
is CompleteRegistrationEvent.ShowToast -> {
|
is CompleteRegistrationEvent.ShowSnackbar -> {
|
||||||
Toast.makeText(context, event.message(context.resources), Toast.LENGTH_SHORT).show()
|
snackbarHostState.showSnackbar(BitwardenSnackbarData(message = event.message))
|
||||||
}
|
}
|
||||||
|
|
||||||
CompleteRegistrationEvent.NavigateToMakePasswordStrong -> onNavigateToPasswordGuidance()
|
CompleteRegistrationEvent.NavigateToMakePasswordStrong -> onNavigateToPasswordGuidance()
|
||||||
@ -143,6 +143,7 @@ fun CompleteRegistrationScreen(
|
|||||||
onNavigationIconClick = handler.onBackClick,
|
onNavigationIconClick = handler.onBackClick,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
snackbarHost = { BitwardenSnackbarHost(bitwardenHostState = snackbarHostState) },
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.auth.feature.completeregistration
|
|||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.bitwarden.core.data.manager.toast.ToastManager
|
||||||
import com.bitwarden.ui.platform.base.BaseViewModel
|
import com.bitwarden.ui.platform.base.BaseViewModel
|
||||||
import com.bitwarden.ui.platform.base.util.isValidEmail
|
import com.bitwarden.ui.platform.base.util.isValidEmail
|
||||||
import com.bitwarden.ui.platform.resource.BitwardenPlurals
|
import com.bitwarden.ui.platform.resource.BitwardenPlurals
|
||||||
@ -54,6 +55,7 @@ class CompleteRegistrationViewModel @Inject constructor(
|
|||||||
private val authRepository: AuthRepository,
|
private val authRepository: AuthRepository,
|
||||||
private val environmentRepository: EnvironmentRepository,
|
private val environmentRepository: EnvironmentRepository,
|
||||||
private val specialCircumstanceManager: SpecialCircumstanceManager,
|
private val specialCircumstanceManager: SpecialCircumstanceManager,
|
||||||
|
private val toastManager: ToastManager,
|
||||||
) : BaseViewModel<CompleteRegistrationState, CompleteRegistrationEvent, CompleteRegistrationAction>(
|
) : BaseViewModel<CompleteRegistrationState, CompleteRegistrationEvent, CompleteRegistrationAction>(
|
||||||
initialState = savedStateHandle[KEY_STATE] ?: run {
|
initialState = savedStateHandle[KEY_STATE] ?: run {
|
||||||
val args = savedStateHandle.toCompleteRegistrationArgs()
|
val args = savedStateHandle.toCompleteRegistrationArgs()
|
||||||
@ -146,9 +148,7 @@ class CompleteRegistrationViewModel @Inject constructor(
|
|||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
sendEvent(
|
sendEvent(
|
||||||
CompleteRegistrationEvent.ShowToast(
|
CompleteRegistrationEvent.ShowSnackbar(BitwardenString.email_verified.asText()),
|
||||||
message = BitwardenString.email_verified.asText(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,11 +243,7 @@ class CompleteRegistrationViewModel @Inject constructor(
|
|||||||
|
|
||||||
private fun handleLoginResult(action: Internal.ReceiveLoginResult) {
|
private fun handleLoginResult(action: Internal.ReceiveLoginResult) {
|
||||||
clearDialogState()
|
clearDialogState()
|
||||||
sendEvent(
|
toastManager.show(messageId = BitwardenString.account_created_success)
|
||||||
CompleteRegistrationEvent.ShowToast(
|
|
||||||
message = BitwardenString.account_created_success.asText(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
authRepository.setOnboardingStatus(
|
authRepository.setOnboardingStatus(
|
||||||
status = OnboardingStatus.NOT_STARTED,
|
status = OnboardingStatus.NOT_STARTED,
|
||||||
@ -504,9 +500,9 @@ sealed class CompleteRegistrationEvent {
|
|||||||
data object NavigateBack : CompleteRegistrationEvent()
|
data object NavigateBack : CompleteRegistrationEvent()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a toast with the given message.
|
* Show a snackbar with the given message.
|
||||||
*/
|
*/
|
||||||
data class ShowToast(
|
data class ShowSnackbar(
|
||||||
val message: Text,
|
val message: Text,
|
||||||
) : CompleteRegistrationEvent()
|
) : CompleteRegistrationEvent()
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,8 @@ import com.bitwarden.ui.platform.components.content.BitwardenLoadingContent
|
|||||||
import com.bitwarden.ui.platform.components.fab.BitwardenFloatingActionButton
|
import com.bitwarden.ui.platform.components.fab.BitwardenFloatingActionButton
|
||||||
import com.bitwarden.ui.platform.components.row.BitwardenTextRow
|
import com.bitwarden.ui.platform.components.row.BitwardenTextRow
|
||||||
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
import com.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.BitwardenSnackbarHost
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.model.rememberBitwardenSnackbarHostState
|
||||||
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
|
import com.bitwarden.ui.platform.components.util.rememberVectorPainter
|
||||||
import com.bitwarden.ui.platform.resource.BitwardenDrawable
|
import com.bitwarden.ui.platform.resource.BitwardenDrawable
|
||||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||||
@ -54,6 +56,7 @@ fun FoldersScreen(
|
|||||||
viewModel: FoldersViewModel = hiltViewModel(),
|
viewModel: FoldersViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val state = viewModel.stateFlow.collectAsStateWithLifecycle()
|
val state = viewModel.stateFlow.collectAsStateWithLifecycle()
|
||||||
|
val snackbarHostState = rememberBitwardenSnackbarHostState()
|
||||||
EventsEffect(viewModel = viewModel) { event ->
|
EventsEffect(viewModel = viewModel) { event ->
|
||||||
when (event) {
|
when (event) {
|
||||||
is FoldersEvent.NavigateBack -> onNavigateBack()
|
is FoldersEvent.NavigateBack -> onNavigateBack()
|
||||||
@ -61,6 +64,8 @@ fun FoldersScreen(
|
|||||||
is FoldersEvent.NavigateToEditFolderScreen -> {
|
is FoldersEvent.NavigateToEditFolderScreen -> {
|
||||||
onNavigateToEditFolderScreen(event.folderId)
|
onNavigateToEditFolderScreen(event.folderId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is FoldersEvent.ShowSnackbar -> snackbarHostState.showSnackbar(event.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,6 +97,7 @@ fun FoldersScreen(
|
|||||||
.navigationBarsPadding(),
|
.navigationBarsPadding(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
snackbarHost = { BitwardenSnackbarHost(bitwardenHostState = snackbarHostState) },
|
||||||
) {
|
) {
|
||||||
when (val viewState = state.value.viewState) {
|
when (val viewState = state.value.viewState) {
|
||||||
is FoldersState.ViewState.Content -> {
|
is FoldersState.ViewState.Content -> {
|
||||||
|
|||||||
@ -3,7 +3,9 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.folders
|
|||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.bitwarden.core.data.repository.model.DataState
|
import com.bitwarden.core.data.repository.model.DataState
|
||||||
|
import com.bitwarden.ui.platform.base.BackgroundEvent
|
||||||
import com.bitwarden.ui.platform.base.BaseViewModel
|
import com.bitwarden.ui.platform.base.BaseViewModel
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData
|
||||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||||
import com.bitwarden.ui.util.Text
|
import com.bitwarden.ui.util.Text
|
||||||
import com.bitwarden.ui.util.asText
|
import com.bitwarden.ui.util.asText
|
||||||
@ -11,8 +13,11 @@ import com.bitwarden.ui.util.concat
|
|||||||
import com.bitwarden.vault.FolderView
|
import com.bitwarden.vault.FolderView
|
||||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||||
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderDisplayItem
|
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderDisplayItem
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
@ -25,6 +30,7 @@ import javax.inject.Inject
|
|||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class FoldersViewModel @Inject constructor(
|
class FoldersViewModel @Inject constructor(
|
||||||
vaultRepository: VaultRepository,
|
vaultRepository: VaultRepository,
|
||||||
|
snackbarRelayManager: SnackbarRelayManager,
|
||||||
) : BaseViewModel<FoldersState, FoldersEvent, FoldersAction>(
|
) : BaseViewModel<FoldersState, FoldersEvent, FoldersAction>(
|
||||||
initialState = FoldersState(viewState = FoldersState.ViewState.Loading),
|
initialState = FoldersState(viewState = FoldersState.ViewState.Loading),
|
||||||
) {
|
) {
|
||||||
@ -33,15 +39,31 @@ class FoldersViewModel @Inject constructor(
|
|||||||
.foldersStateFlow
|
.foldersStateFlow
|
||||||
.onEach { sendAction(FoldersAction.Internal.VaultDataReceive(it)) }
|
.onEach { sendAction(FoldersAction.Internal.VaultDataReceive(it)) }
|
||||||
.launchIn(viewModelScope)
|
.launchIn(viewModelScope)
|
||||||
|
snackbarRelayManager
|
||||||
|
.getSnackbarDataFlow(
|
||||||
|
SnackbarRelay.FOLDER_CREATED,
|
||||||
|
SnackbarRelay.FOLDER_DELETED,
|
||||||
|
SnackbarRelay.FOLDER_UPDATED,
|
||||||
|
)
|
||||||
|
.map { FoldersAction.Internal.SnackbarDataReceived(it) }
|
||||||
|
.onEach(::sendAction)
|
||||||
|
.launchIn(viewModelScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleAction(action: FoldersAction): Unit = when (action) {
|
override fun handleAction(action: FoldersAction): Unit = when (action) {
|
||||||
is FoldersAction.AddFolderButtonClick -> handleAddFolderButtonClicked()
|
is FoldersAction.AddFolderButtonClick -> handleAddFolderButtonClicked()
|
||||||
is FoldersAction.CloseButtonClick -> handleCloseButtonClicked()
|
is FoldersAction.CloseButtonClick -> handleCloseButtonClicked()
|
||||||
is FoldersAction.Internal.VaultDataReceive -> handleVaultDataReceive(action)
|
is FoldersAction.Internal -> handleInternalAction(action)
|
||||||
is FoldersAction.FolderClick -> handleFolderClick(action)
|
is FoldersAction.FolderClick -> handleFolderClick(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleInternalAction(action: FoldersAction.Internal) {
|
||||||
|
when (action) {
|
||||||
|
is FoldersAction.Internal.SnackbarDataReceived -> handleSnackbarDataReceived(action)
|
||||||
|
is FoldersAction.Internal.VaultDataReceive -> handleVaultDataReceive(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun handleFolderClick(action: FoldersAction.FolderClick) {
|
private fun handleFolderClick(action: FoldersAction.FolderClick) {
|
||||||
sendEvent(FoldersEvent.NavigateToEditFolderScreen(action.folderId))
|
sendEvent(FoldersEvent.NavigateToEditFolderScreen(action.folderId))
|
||||||
}
|
}
|
||||||
@ -54,6 +76,10 @@ class FoldersViewModel @Inject constructor(
|
|||||||
sendEvent(FoldersEvent.NavigateBack)
|
sendEvent(FoldersEvent.NavigateBack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleSnackbarDataReceived(action: FoldersAction.Internal.SnackbarDataReceived) {
|
||||||
|
sendEvent(FoldersEvent.ShowSnackbar(action.data))
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("LongMethod")
|
@Suppress("LongMethod")
|
||||||
private fun handleVaultDataReceive(action: FoldersAction.Internal.VaultDataReceive) {
|
private fun handleVaultDataReceive(action: FoldersAction.Internal.VaultDataReceive) {
|
||||||
when (val vaultDataState = action.vaultDataState) {
|
when (val vaultDataState = action.vaultDataState) {
|
||||||
@ -180,6 +206,13 @@ sealed class FoldersEvent {
|
|||||||
* Navigates to the screen to edit a folder.
|
* Navigates to the screen to edit a folder.
|
||||||
*/
|
*/
|
||||||
data class NavigateToEditFolderScreen(val folderId: String) : FoldersEvent()
|
data class NavigateToEditFolderScreen(val folderId: String) : FoldersEvent()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a snackbar.
|
||||||
|
*/
|
||||||
|
data class ShowSnackbar(
|
||||||
|
val data: BitwardenSnackbarData,
|
||||||
|
) : FoldersEvent(), BackgroundEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,6 +238,12 @@ sealed class FoldersAction {
|
|||||||
* Actions for internal use by the ViewModel.
|
* Actions for internal use by the ViewModel.
|
||||||
*/
|
*/
|
||||||
sealed class Internal : FoldersAction() {
|
sealed class Internal : FoldersAction() {
|
||||||
|
/**
|
||||||
|
* Indicates that the vault folders data has been received.
|
||||||
|
*/
|
||||||
|
data class SnackbarDataReceived(
|
||||||
|
val data: BitwardenSnackbarData,
|
||||||
|
) : Internal()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the vault folders data has been received.
|
* Indicates that the vault folders data has been received.
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package com.x8bit.bitwarden.ui.platform.feature.settings.folders.addedit
|
package com.x8bit.bitwarden.ui.platform.feature.settings.folders.addedit
|
||||||
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
@ -18,7 +17,6 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.platform.testTag
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@ -55,16 +53,10 @@ fun FolderAddEditScreen(
|
|||||||
viewModel: FolderAddEditViewModel = hiltViewModel(),
|
viewModel: FolderAddEditViewModel = hiltViewModel(),
|
||||||
) {
|
) {
|
||||||
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
|
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
var shouldShowConfirmationDialog by rememberSaveable { mutableStateOf(false) }
|
var shouldShowConfirmationDialog by rememberSaveable { mutableStateOf(false) }
|
||||||
|
|
||||||
EventsEffect(viewModel = viewModel) { event ->
|
EventsEffect(viewModel = viewModel) { event ->
|
||||||
when (event) {
|
when (event) {
|
||||||
is FolderAddEditEvent.NavigateBack -> onNavigateBack.invoke()
|
is FolderAddEditEvent.NavigateBack -> onNavigateBack.invoke()
|
||||||
is FolderAddEditEvent.ShowToast -> {
|
|
||||||
Toast.makeText(context, event.message(context.resources), Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import com.bitwarden.core.DateTime
|
import com.bitwarden.core.DateTime
|
||||||
import com.bitwarden.core.data.repository.model.DataState
|
import com.bitwarden.core.data.repository.model.DataState
|
||||||
import com.bitwarden.ui.platform.base.BaseViewModel
|
import com.bitwarden.ui.platform.base.BaseViewModel
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData
|
||||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||||
import com.bitwarden.ui.util.Text
|
import com.bitwarden.ui.util.Text
|
||||||
import com.bitwarden.ui.util.asText
|
import com.bitwarden.ui.util.asText
|
||||||
@ -16,6 +17,8 @@ import com.x8bit.bitwarden.data.vault.repository.model.CreateFolderResult
|
|||||||
import com.x8bit.bitwarden.data.vault.repository.model.DeleteFolderResult
|
import com.x8bit.bitwarden.data.vault.repository.model.DeleteFolderResult
|
||||||
import com.x8bit.bitwarden.data.vault.repository.model.UpdateFolderResult
|
import com.x8bit.bitwarden.data.vault.repository.model.UpdateFolderResult
|
||||||
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderAddEditType
|
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderAddEditType
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@ -35,6 +38,7 @@ private const val KEY_STATE = "state"
|
|||||||
class FolderAddEditViewModel @Inject constructor(
|
class FolderAddEditViewModel @Inject constructor(
|
||||||
savedStateHandle: SavedStateHandle,
|
savedStateHandle: SavedStateHandle,
|
||||||
private val vaultRepository: VaultRepository,
|
private val vaultRepository: VaultRepository,
|
||||||
|
private val relayManager: SnackbarRelayManager,
|
||||||
) : BaseViewModel<FolderAddEditState, FolderAddEditEvent, FolderAddEditAction>(
|
) : BaseViewModel<FolderAddEditState, FolderAddEditEvent, FolderAddEditAction>(
|
||||||
// We load the state from the savedStateHandle for testing purposes.
|
// We load the state from the savedStateHandle for testing purposes.
|
||||||
initialState = savedStateHandle[KEY_STATE]
|
initialState = savedStateHandle[KEY_STATE]
|
||||||
@ -263,7 +267,10 @@ class FolderAddEditViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is UpdateFolderResult.Success -> {
|
is UpdateFolderResult.Success -> {
|
||||||
sendEvent(FolderAddEditEvent.ShowToast(BitwardenString.folder_updated.asText()))
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_updated.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_UPDATED,
|
||||||
|
)
|
||||||
sendEvent(FolderAddEditEvent.NavigateBack)
|
sendEvent(FolderAddEditEvent.NavigateBack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,7 +296,10 @@ class FolderAddEditViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
is CreateFolderResult.Success -> {
|
is CreateFolderResult.Success -> {
|
||||||
sendEvent(FolderAddEditEvent.ShowToast(BitwardenString.folder_created.asText()))
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_created.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_CREATED,
|
||||||
|
)
|
||||||
sendEvent(FolderAddEditEvent.NavigateBack)
|
sendEvent(FolderAddEditEvent.NavigateBack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,7 +322,10 @@ class FolderAddEditViewModel @Inject constructor(
|
|||||||
|
|
||||||
DeleteFolderResult.Success -> {
|
DeleteFolderResult.Success -> {
|
||||||
mutableStateFlow.update { it.copy(dialog = null) }
|
mutableStateFlow.update { it.copy(dialog = null) }
|
||||||
sendEvent(FolderAddEditEvent.ShowToast(BitwardenString.folder_deleted.asText()))
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_deleted.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_DELETED,
|
||||||
|
)
|
||||||
sendEvent(event = FolderAddEditEvent.NavigateBack)
|
sendEvent(event = FolderAddEditEvent.NavigateBack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,11 +429,6 @@ sealed class FolderAddEditEvent {
|
|||||||
* Navigate back to previous screen.
|
* Navigate back to previous screen.
|
||||||
*/
|
*/
|
||||||
data object NavigateBack : FolderAddEditEvent()
|
data object NavigateBack : FolderAddEditEvent()
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a toast with the given [message].
|
|
||||||
*/
|
|
||||||
data class ShowToast(val message: Text) : FolderAddEditEvent()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -16,6 +16,9 @@ enum class SnackbarRelay {
|
|||||||
CIPHER_RESTORED,
|
CIPHER_RESTORED,
|
||||||
CIPHER_UPDATED,
|
CIPHER_UPDATED,
|
||||||
ENVIRONMENT_SAVED,
|
ENVIRONMENT_SAVED,
|
||||||
|
FOLDER_CREATED,
|
||||||
|
FOLDER_DELETED,
|
||||||
|
FOLDER_UPDATED,
|
||||||
LOGIN_APPROVAL,
|
LOGIN_APPROVAL,
|
||||||
LOGIN_SUCCESS,
|
LOGIN_SUCCESS,
|
||||||
LOGINS_IMPORTED,
|
LOGINS_IMPORTED,
|
||||||
|
|||||||
@ -189,6 +189,7 @@ class VaultViewModel @Inject constructor(
|
|||||||
SnackbarRelay.CIPHER_DELETED_SOFT,
|
SnackbarRelay.CIPHER_DELETED_SOFT,
|
||||||
SnackbarRelay.CIPHER_RESTORED,
|
SnackbarRelay.CIPHER_RESTORED,
|
||||||
SnackbarRelay.CIPHER_UPDATED,
|
SnackbarRelay.CIPHER_UPDATED,
|
||||||
|
SnackbarRelay.FOLDER_CREATED,
|
||||||
SnackbarRelay.LOGINS_IMPORTED,
|
SnackbarRelay.LOGINS_IMPORTED,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -70,6 +70,14 @@ class CompleteRegistrationScreenTest : BitwardenComposeTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `on ShowSnackbar should display snackbar content`() {
|
||||||
|
val message = "message"
|
||||||
|
composeTestRule.onNodeWithText(text = message).assertDoesNotExist()
|
||||||
|
mutableEventFlow.tryEmit(CompleteRegistrationEvent.ShowSnackbar(message = message.asText()))
|
||||||
|
composeTestRule.onNodeWithText(text = message).assertIsDisplayed()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `close click should send CloseClick action`() {
|
fun `close click should send CloseClick action`() {
|
||||||
composeTestRule.onNodeWithContentDescription("Back").performClick()
|
composeTestRule.onNodeWithContentDescription("Back").performClick()
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.ui.auth.feature.completeregistration
|
|||||||
|
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
|
import com.bitwarden.core.data.manager.toast.ToastManager
|
||||||
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
|
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
|
||||||
import com.bitwarden.data.datasource.disk.base.FakeDispatcherManager
|
import com.bitwarden.data.datasource.disk.base.FakeDispatcherManager
|
||||||
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
||||||
@ -38,6 +39,7 @@ import io.mockk.every
|
|||||||
import io.mockk.just
|
import io.mockk.just
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.runs
|
||||||
import io.mockk.unmockkStatic
|
import io.mockk.unmockkStatic
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -46,7 +48,6 @@ import org.junit.jupiter.api.AfterEach
|
|||||||
import org.junit.jupiter.api.Assertions.assertEquals
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import org.junit.jupiter.api.Assertions.assertFalse
|
import org.junit.jupiter.api.Assertions.assertFalse
|
||||||
import org.junit.jupiter.api.Assertions.assertNull
|
import org.junit.jupiter.api.Assertions.assertNull
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
@ -60,13 +61,7 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() {
|
|||||||
private val mutableUserStateFlow = MutableStateFlow<UserState?>(null)
|
private val mutableUserStateFlow = MutableStateFlow<UserState?>(null)
|
||||||
private val mockAuthRepository = mockk<AuthRepository> {
|
private val mockAuthRepository = mockk<AuthRepository> {
|
||||||
every { userStateFlow } returns mutableUserStateFlow
|
every { userStateFlow } returns mutableUserStateFlow
|
||||||
coEvery {
|
coEvery { login(email = any(), password = any()) } returns LoginResult.Success
|
||||||
login(
|
|
||||||
email = any(),
|
|
||||||
password = any(),
|
|
||||||
)
|
|
||||||
} returns LoginResult.Success
|
|
||||||
|
|
||||||
coEvery {
|
coEvery {
|
||||||
register(
|
register(
|
||||||
email = any(),
|
email = any(),
|
||||||
@ -77,10 +72,10 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() {
|
|||||||
isMasterPasswordStrong = any(),
|
isMasterPasswordStrong = any(),
|
||||||
)
|
)
|
||||||
} returns RegisterResult.Success
|
} returns RegisterResult.Success
|
||||||
|
coEvery { setOnboardingStatus(OnboardingStatus.NOT_STARTED) } just Runs
|
||||||
coEvery {
|
}
|
||||||
setOnboardingStatus(OnboardingStatus.NOT_STARTED)
|
private val toastManager: ToastManager = mockk {
|
||||||
} just Runs
|
every { show(messageId = any(), duration = any()) } just runs
|
||||||
}
|
}
|
||||||
|
|
||||||
private val fakeEnvironmentRepository = FakeEnvironmentRepository()
|
private val fakeEnvironmentRepository = FakeEnvironmentRepository()
|
||||||
@ -155,21 +150,18 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() {
|
|||||||
)
|
)
|
||||||
} returns RegisterResult.Success
|
} returns RegisterResult.Success
|
||||||
val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE)
|
val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE)
|
||||||
viewModel.stateEventFlow(backgroundScope) { stateFlow, eventFlow ->
|
viewModel.stateFlow.test {
|
||||||
assertEquals(VALID_INPUT_STATE, stateFlow.awaitItem())
|
assertEquals(VALID_INPUT_STATE, awaitItem())
|
||||||
viewModel.trySendAction(CompleteRegistrationAction.CallToActionClick)
|
viewModel.trySendAction(CompleteRegistrationAction.CallToActionClick)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
VALID_INPUT_STATE.copy(dialog = CompleteRegistrationDialog.Loading),
|
VALID_INPUT_STATE.copy(dialog = CompleteRegistrationDialog.Loading),
|
||||||
stateFlow.awaitItem(),
|
awaitItem(),
|
||||||
)
|
|
||||||
assertEquals(
|
|
||||||
CompleteRegistrationEvent.ShowToast(
|
|
||||||
BitwardenString.account_created_success.asText(),
|
|
||||||
),
|
|
||||||
eventFlow.awaitItem(),
|
|
||||||
)
|
)
|
||||||
// Make sure loading dialog is hidden:
|
// Make sure loading dialog is hidden:
|
||||||
assertEquals(VALID_INPUT_STATE, stateFlow.awaitItem())
|
assertEquals(VALID_INPUT_STATE, awaitItem())
|
||||||
|
}
|
||||||
|
verify(exactly = 1) {
|
||||||
|
toastManager.show(messageId = BitwardenString.account_created_success)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +216,6 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() {
|
|||||||
val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE)
|
val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE)
|
||||||
viewModel.trySendAction(CompleteRegistrationAction.CallToActionClick)
|
viewModel.trySendAction(CompleteRegistrationAction.CallToActionClick)
|
||||||
viewModel.eventFlow.test {
|
viewModel.eventFlow.test {
|
||||||
assertTrue(awaitItem() is CompleteRegistrationEvent.ShowToast)
|
|
||||||
expectNoEvents()
|
expectNoEvents()
|
||||||
}
|
}
|
||||||
verify(exactly = 1) {
|
verify(exactly = 1) {
|
||||||
@ -246,7 +237,6 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() {
|
|||||||
val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE)
|
val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE)
|
||||||
viewModel.trySendAction(CompleteRegistrationAction.CallToActionClick)
|
viewModel.trySendAction(CompleteRegistrationAction.CallToActionClick)
|
||||||
viewModel.eventFlow.test {
|
viewModel.eventFlow.test {
|
||||||
assertTrue(awaitItem() is CompleteRegistrationEvent.ShowToast)
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
CompleteRegistrationEvent.NavigateToLogin(EMAIL),
|
CompleteRegistrationEvent.NavigateToLogin(EMAIL),
|
||||||
awaitItem(),
|
awaitItem(),
|
||||||
@ -404,13 +394,13 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `On init should show toast if from email is true`() = runTest {
|
fun `On init should show snackbar if from email is true`() = runTest {
|
||||||
val viewModel = createCompleteRegistrationViewModel(
|
val viewModel = createCompleteRegistrationViewModel(
|
||||||
DEFAULT_STATE.copy(fromEmail = true),
|
DEFAULT_STATE.copy(fromEmail = true),
|
||||||
)
|
)
|
||||||
viewModel.eventFlow.test {
|
viewModel.eventFlow.test {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
CompleteRegistrationEvent.ShowToast(BitwardenString.email_verified.asText()),
|
CompleteRegistrationEvent.ShowSnackbar(BitwardenString.email_verified.asText()),
|
||||||
awaitItem(),
|
awaitItem(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -666,6 +656,7 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() {
|
|||||||
environmentRepository = fakeEnvironmentRepository,
|
environmentRepository = fakeEnvironmentRepository,
|
||||||
specialCircumstanceManager = specialCircumstanceManager,
|
specialCircumstanceManager = specialCircumstanceManager,
|
||||||
generatorRepository = generatorRepository,
|
generatorRepository = generatorRepository,
|
||||||
|
toastManager = toastManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@ -3,13 +3,16 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.folders
|
|||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.bitwarden.core.DateTime
|
import com.bitwarden.core.DateTime
|
||||||
import com.bitwarden.core.data.repository.model.DataState
|
import com.bitwarden.core.data.repository.model.DataState
|
||||||
|
import com.bitwarden.core.data.repository.util.bufferedMutableSharedFlow
|
||||||
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData
|
||||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||||
import com.bitwarden.ui.util.asText
|
import com.bitwarden.ui.util.asText
|
||||||
import com.bitwarden.ui.util.concat
|
import com.bitwarden.ui.util.concat
|
||||||
import com.bitwarden.vault.FolderView
|
import com.bitwarden.vault.FolderView
|
||||||
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||||
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderDisplayItem
|
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderDisplayItem
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -25,6 +28,26 @@ class FoldersViewModelTest : BaseViewModelTest() {
|
|||||||
private val vaultRepository: VaultRepository = mockk {
|
private val vaultRepository: VaultRepository = mockk {
|
||||||
every { foldersStateFlow } returns mutableFoldersStateFlow
|
every { foldersStateFlow } returns mutableFoldersStateFlow
|
||||||
}
|
}
|
||||||
|
private val mutableSnackbarDataFlow = bufferedMutableSharedFlow<BitwardenSnackbarData>()
|
||||||
|
private val snackbarRelayManager: SnackbarRelayManager = mockk {
|
||||||
|
every {
|
||||||
|
getSnackbarDataFlow(relay = any(), relays = anyVararg())
|
||||||
|
} returns mutableSnackbarDataFlow
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `on snackbar data received should emit ShowSnackbar`() = runTest {
|
||||||
|
val viewModel = createViewModel()
|
||||||
|
|
||||||
|
val data = BitwardenSnackbarData(message = "Snackbar!".asText())
|
||||||
|
viewModel.eventFlow.test {
|
||||||
|
mutableSnackbarDataFlow.emit(data)
|
||||||
|
assertEquals(
|
||||||
|
FoldersEvent.ShowSnackbar(data = data),
|
||||||
|
awaitItem(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `BackClick should emit NavigateBack`() = runTest {
|
fun `BackClick should emit NavigateBack`() = runTest {
|
||||||
@ -161,6 +184,7 @@ class FoldersViewModelTest : BaseViewModelTest() {
|
|||||||
|
|
||||||
private fun createViewModel(): FoldersViewModel = FoldersViewModel(
|
private fun createViewModel(): FoldersViewModel = FoldersViewModel(
|
||||||
vaultRepository = vaultRepository,
|
vaultRepository = vaultRepository,
|
||||||
|
snackbarRelayManager = snackbarRelayManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun createFolderState(
|
private fun createFolderState(
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import app.cash.turbine.test
|
|||||||
import com.bitwarden.core.DateTime
|
import com.bitwarden.core.DateTime
|
||||||
import com.bitwarden.core.data.repository.model.DataState
|
import com.bitwarden.core.data.repository.model.DataState
|
||||||
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
import com.bitwarden.ui.platform.base.BaseViewModelTest
|
||||||
|
import com.bitwarden.ui.platform.components.snackbar.model.BitwardenSnackbarData
|
||||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||||
import com.bitwarden.ui.util.asText
|
import com.bitwarden.ui.util.asText
|
||||||
import com.bitwarden.ui.util.concat
|
import com.bitwarden.ui.util.concat
|
||||||
@ -14,11 +15,15 @@ import com.x8bit.bitwarden.data.vault.repository.model.CreateFolderResult
|
|||||||
import com.x8bit.bitwarden.data.vault.repository.model.DeleteFolderResult
|
import com.x8bit.bitwarden.data.vault.repository.model.DeleteFolderResult
|
||||||
import com.x8bit.bitwarden.data.vault.repository.model.UpdateFolderResult
|
import com.x8bit.bitwarden.data.vault.repository.model.UpdateFolderResult
|
||||||
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderAddEditType
|
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.model.FolderAddEditType
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay
|
||||||
|
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager
|
||||||
import io.mockk.coEvery
|
import io.mockk.coEvery
|
||||||
import io.mockk.coVerify
|
import io.mockk.coVerify
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
|
import io.mockk.just
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.runs
|
||||||
import io.mockk.unmockkStatic
|
import io.mockk.unmockkStatic
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -38,6 +43,9 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
private val vaultRepository: VaultRepository = mockk {
|
private val vaultRepository: VaultRepository = mockk {
|
||||||
every { getVaultFolderStateFlow(DEFAULT_EDIT_ITEM_ID) } returns mutableFoldersStateFlow
|
every { getVaultFolderStateFlow(DEFAULT_EDIT_ITEM_ID) } returns mutableFoldersStateFlow
|
||||||
}
|
}
|
||||||
|
private val relayManager: SnackbarRelayManager = mockk {
|
||||||
|
every { sendSnackbarData(data = any(), relay = any()) } just runs
|
||||||
|
}
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun setup() {
|
fun setup() {
|
||||||
@ -125,15 +133,17 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
viewModel.trySendAction(FolderAddEditAction.DeleteClick)
|
viewModel.trySendAction(FolderAddEditAction.DeleteClick)
|
||||||
|
|
||||||
viewModel.eventFlow.test {
|
viewModel.eventFlow.test {
|
||||||
assertEquals(
|
|
||||||
FolderAddEditEvent.ShowToast(BitwardenString.folder_deleted.asText()),
|
|
||||||
awaitItem(),
|
|
||||||
)
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
FolderAddEditEvent.NavigateBack,
|
FolderAddEditEvent.NavigateBack,
|
||||||
awaitItem(),
|
awaitItem(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
verify(exactly = 1) {
|
||||||
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_deleted.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_DELETED,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@ -180,6 +190,12 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
assertEquals(stateWithDialog, awaitItem())
|
assertEquals(stateWithDialog, awaitItem())
|
||||||
assertEquals(stateWithoutDialog, awaitItem())
|
assertEquals(stateWithoutDialog, awaitItem())
|
||||||
}
|
}
|
||||||
|
verify(exactly = 1) {
|
||||||
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_deleted.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_DELETED,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@ -322,6 +338,12 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
assertEquals(stateWithDialog, awaitItem())
|
assertEquals(stateWithDialog, awaitItem())
|
||||||
assertEquals(stateWithoutDialog, awaitItem())
|
assertEquals(stateWithoutDialog, awaitItem())
|
||||||
}
|
}
|
||||||
|
verify(exactly = 1) {
|
||||||
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_created.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_CREATED,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
@Suppress("MaxLineLength")
|
||||||
@ -348,9 +370,7 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
vaultRepository.createFolder(any())
|
vaultRepository.createFolder(any())
|
||||||
} returns CreateFolderResult.Success(mockk())
|
} returns CreateFolderResult.Success(mockk())
|
||||||
viewModel.trySendAction(FolderAddEditAction.SaveClick)
|
viewModel.trySendAction(FolderAddEditAction.SaveClick)
|
||||||
coVerify(
|
coVerify(exactly = 1) {
|
||||||
exactly = 1,
|
|
||||||
) {
|
|
||||||
vaultRepository.createFolder(
|
vaultRepository.createFolder(
|
||||||
folderView = FolderView(
|
folderView = FolderView(
|
||||||
name = DEFAULT_FOLDER_NAME,
|
name = DEFAULT_FOLDER_NAME,
|
||||||
@ -359,6 +379,12 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
verify(exactly = 1) {
|
||||||
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_created.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_CREATED,
|
||||||
|
)
|
||||||
|
}
|
||||||
unmockkStatic(DateTime::class)
|
unmockkStatic(DateTime::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,9 +413,7 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
vaultRepository.createFolder(any())
|
vaultRepository.createFolder(any())
|
||||||
} returns CreateFolderResult.Success(mockk())
|
} returns CreateFolderResult.Success(mockk())
|
||||||
viewModel.trySendAction(FolderAddEditAction.SaveClick)
|
viewModel.trySendAction(FolderAddEditAction.SaveClick)
|
||||||
coVerify(
|
coVerify(exactly = 1) {
|
||||||
exactly = 1,
|
|
||||||
) {
|
|
||||||
vaultRepository.createFolder(
|
vaultRepository.createFolder(
|
||||||
folderView = FolderView(
|
folderView = FolderView(
|
||||||
name = "$parentFolderName/$DEFAULT_FOLDER_NAME",
|
name = "$parentFolderName/$DEFAULT_FOLDER_NAME",
|
||||||
@ -398,6 +422,12 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
verify(exactly = 1) {
|
||||||
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_created.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_CREATED,
|
||||||
|
)
|
||||||
|
}
|
||||||
unmockkStatic(DateTime::class)
|
unmockkStatic(DateTime::class)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +513,12 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
assertEquals(stateWithDialog, awaitItem())
|
assertEquals(stateWithDialog, awaitItem())
|
||||||
assertEquals(stateWithoutDialog, awaitItem())
|
assertEquals(stateWithoutDialog, awaitItem())
|
||||||
}
|
}
|
||||||
|
verify(exactly = 1) {
|
||||||
|
relayManager.sendSnackbarData(
|
||||||
|
data = BitwardenSnackbarData(BitwardenString.folder_updated.asText()),
|
||||||
|
relay = SnackbarRelay.FOLDER_UPDATED,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -758,6 +794,7 @@ class FolderAddEditViewModelTest : BaseViewModelTest() {
|
|||||||
): FolderAddEditViewModel = FolderAddEditViewModel(
|
): FolderAddEditViewModel = FolderAddEditViewModel(
|
||||||
savedStateHandle = savedStateHandle,
|
savedStateHandle = savedStateHandle,
|
||||||
vaultRepository = vaultRepository,
|
vaultRepository = vaultRepository,
|
||||||
|
relayManager = relayManager,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user