diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt index ca86897053..f587ba19e8 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt @@ -1988,11 +1988,16 @@ class VaultAddEditViewModel @Inject constructor( dialog = null, ) } + val createdFolder = (action.result as? CreateFolderResult.Success)?.folderView updateCommonContent { it.copy( - selectedFolderId = (action.result as? CreateFolderResult.Success)?.folderView?.id, + selectedFolderId = createdFolder?.id, ) } + if (createdFolder == null) return + sendEvent( + event = VaultAddEditEvent.ShowSnackbar(BitwardenString.folder_created.asText()), + ) } private fun handleCreateCipherResultReceive( diff --git a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt index a21e35d48b..3ddccce347 100644 --- a/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt +++ b/app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModel.kt @@ -241,6 +241,7 @@ class VaultItemListingViewModel @Inject constructor( SnackbarRelay.CIPHER_DELETED_SOFT, SnackbarRelay.CIPHER_RESTORED, SnackbarRelay.CIPHER_UPDATED, + SnackbarRelay.FOLDER_CREATED, SnackbarRelay.SEND_DELETED, SnackbarRelay.SEND_UPDATED, ) diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt index 638d7caae2..e3626626ed 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModelTest.kt @@ -4624,6 +4624,13 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { @Nested inner class VaultAddEditCommonActions { + private val createdFolderId: String = "123" + private val newFolderName: String = "folderName" + private val createdFolderView: FolderView = FolderView( + id = createdFolderId, + name = newFolderName, + revisionDate = fixedClock.instant(), + ) private lateinit var viewModel: VaultAddEditViewModel private lateinit var vaultAddItemInitialState: VaultAddEditState private lateinit var secureNotesInitialSavedStateHandle: SavedStateHandle @@ -4721,20 +4728,14 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { @Test fun `AddNewFolder action calls create folder from vault repository`() = runTest { - val folderName = "folderName" - val expectedFolderResult = FolderView( - id = "123", - name = folderName, - revisionDate = fixedClock.instant(), - ) coEvery { vaultRepository.createFolder(any()) - } returns CreateFolderResult.Success(expectedFolderResult) - viewModel.trySendAction(VaultAddEditAction.Common.AddNewFolder(folderName)) + } returns CreateFolderResult.Success(createdFolderView) + viewModel.trySendAction(VaultAddEditAction.Common.AddNewFolder(newFolderName)) coVerify { vaultRepository.createFolder( FolderView( - name = folderName, + name = newFolderName, id = null, revisionDate = fixedClock.instant(), ), @@ -4744,20 +4745,13 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { @Test fun `AddNewFolder updates dialog states and selected folder id on success`() = runTest { - val folderId = "123" - val folderName = "folderName" - val expectedFolderResult = FolderView( - id = folderId, - name = folderName, - revisionDate = fixedClock.instant(), - ) coEvery { vaultRepository.createFolder(any()) - } returns CreateFolderResult.Success(expectedFolderResult) + } returns CreateFolderResult.Success(createdFolderView) viewModel.stateFlow.test { awaitItem() // initial state. - viewModel.trySendAction(VaultAddEditAction.Common.AddNewFolder(folderName)) + viewModel.trySendAction(VaultAddEditAction.Common.AddNewFolder(newFolderName)) assertEquals( vaultAddItemInitialState.copy( dialog = VaultAddEditState.DialogState.Loading( @@ -4770,7 +4764,7 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { createVaultAddItemState( dialogState = null, commonContentViewState = createCommonContentViewState( - selectedFolderId = folderId, + selectedFolderId = createdFolderId, ), ), awaitItem(), @@ -4778,6 +4772,33 @@ class VaultAddEditViewModelTest : BaseViewModelTest() { } } + @Test + fun `AddNewFolder shows the folder created snackbar on success`() = runTest { + coEvery { + vaultRepository.createFolder(any()) + } returns CreateFolderResult.Success(createdFolderView) + + viewModel.eventFlow.test { + viewModel.trySendAction(VaultAddEditAction.Common.AddNewFolder(newFolderName)) + assertEquals( + VaultAddEditEvent.ShowSnackbar(BitwardenString.folder_created.asText()), + awaitItem(), + ) + } + } + + @Test + fun `AddNewFolder does not show the folder created snackbar on error`() = runTest { + coEvery { + vaultRepository.createFolder(any()) + } returns CreateFolderResult.Error(error = Throwable("Fail")) + + viewModel.eventFlow.test { + viewModel.trySendAction(VaultAddEditAction.Common.AddNewFolder(newFolderName)) + expectNoEvents() + } + } + @Test fun `State updates when available folders state is updated`() { mutableFolderStateFlow.update { diff --git a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt index b11dfb3ac9..9aee5faef8 100644 --- a/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt +++ b/app/src/test/kotlin/com/x8bit/bitwarden/ui/vault/feature/itemlisting/VaultItemListingViewModelTest.kt @@ -6682,6 +6682,18 @@ class VaultItemListingViewModelTest : BaseViewModelTest() { } } + @Test + fun `viewModel should subscribe to the folder created snackbar relay`() { + createVaultItemListingViewModel() + + verify(exactly = 1) { + snackbarRelayManager.getSnackbarDataFlow( + relay = any(), + relays = varargAny { it == SnackbarRelay.FOLDER_CREATED }, + ) + } + } + @Test fun `BankAccount listing type should display the FAB`() { assertTrue(VaultItemListingState.ItemListingType.Vault.BankAccount.hasFab)