From 93b136a87918495fc88d8ec79e647aeccb956ddb Mon Sep 17 00:00:00 2001 From: Brian Yencho Date: Wed, 13 Dec 2023 10:00:15 -0600 Subject: [PATCH] BIT-874: Expose Collections data from VaultRepository (#382) --- .../network/model/SyncResponseJson.kt | 4 +- .../vault/repository/VaultRepositoryImpl.kt | 13 ++- .../data/vault/repository/model/VaultData.kt | 3 + .../util/VaultSdkCollectionExtensions.kt | 25 +++++ .../sdk/model/CollectionViewUtil.kt | 16 +++ .../sdk/model/VaultSdkCollectionUtil.kt | 16 +++ .../vault/repository/VaultRepositoryTest.kt | 100 ++++++++++++++++++ .../util/VaultSdkCollectionExtensionsTest.kt | 59 +++++++++++ .../vault/feature/vault/VaultViewModelTest.kt | 4 + .../vault/util/VaultDataExtensionsTest.kt | 4 + 10 files changed, 241 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt create mode 100644 app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/CollectionViewUtil.kt create mode 100644 app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkCollectionUtil.kt create mode 100644 app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt index eaed436d28..091f508648 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/SyncResponseJson.kt @@ -951,7 +951,7 @@ data class SyncResponseJson( * * @property organizationId The organization ID of the collection. * @property shouldHidePasswords If the collection should hide passwords. - * @property name The name of the collection (nullable). + * @property name The name of the collection. * @property externalId The external ID of the collection (nullable). * @property isReadOnly If the collection is marked as read only. * @property id The ID of the collection. @@ -965,7 +965,7 @@ data class SyncResponseJson( val shouldHidePasswords: Boolean, @SerialName("name") - val name: String?, + val name: String, @SerialName("externalId") val externalId: String?, diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt index 9a7e708d7d..2e6012357b 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryImpl.kt @@ -29,6 +29,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.VaultState import com.x8bit.bitwarden.data.vault.repository.model.VaultUnlockResult import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkCipher import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCipherList +import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCollectionList import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkFolderList import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkSendList import com.x8bit.bitwarden.data.vault.repository.util.toVaultUnlockResult @@ -399,9 +400,19 @@ class VaultRepositoryImpl constructor( .toEncryptedSdkFolderList(), ) }, - ) { decryptedCipherList, decryptedFolderList -> + { + vaultSdkSource + .decryptCollectionList( + collectionList = syncResponse + .collections + .orEmpty() + .toEncryptedSdkCollectionList(), + ) + }, + ) { decryptedCipherList, decryptedFolderList, decryptedCollectionList -> VaultData( cipherViewList = decryptedCipherList, + collectionViewList = decryptedCollectionList, folderViewList = decryptedFolderList, ) } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/model/VaultData.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/model/VaultData.kt index 2d4f9d1954..562f08b4c3 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/model/VaultData.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/model/VaultData.kt @@ -1,15 +1,18 @@ package com.x8bit.bitwarden.data.vault.repository.model import com.bitwarden.core.CipherView +import com.bitwarden.core.CollectionView import com.bitwarden.core.FolderView /** * Represents decrypted vault data. * * @param cipherViewList List of decrypted ciphers. + * @param collectionViewList List of decrypted collections. * @param folderViewList List of decrypted folders. */ data class VaultData( val cipherViewList: List, + val collectionViewList: List, val folderViewList: List, ) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt new file mode 100644 index 0000000000..28deca62db --- /dev/null +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensions.kt @@ -0,0 +1,25 @@ +package com.x8bit.bitwarden.data.vault.repository.util + +import com.bitwarden.core.Collection +import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson + +/** + * Converts a [SyncResponseJson.Collection] object to a corresponding Bitwarden SDK [Collection] + * object. + */ +fun SyncResponseJson.Collection.toEncryptedSdkCollection(): Collection = + Collection( + id = this.id, + organizationId = this.organizationId, + name = this.name, + externalId = this.externalId, + hidePasswords = this.shouldHidePasswords, + readOnly = this.isReadOnly, + ) + +/** + * Converts a list of [SyncResponseJson.Collection] objects to a list of corresponding + * Bitwarden SDK [Collection] objects. + */ +fun List.toEncryptedSdkCollectionList(): List = + map { it.toEncryptedSdkCollection() } diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/CollectionViewUtil.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/CollectionViewUtil.kt new file mode 100644 index 0000000000..c99d2e4cf9 --- /dev/null +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/CollectionViewUtil.kt @@ -0,0 +1,16 @@ +package com.x8bit.bitwarden.data.vault.datasource.sdk.model + +import com.bitwarden.core.CollectionView + +/** + * Create a mock [CollectionView] with a given [number]. + */ +fun createMockCollectionView(number: Int): CollectionView = + CollectionView( + id = "mockId-$number", + organizationId = "mockOrganizationId-$number", + hidePasswords = false, + name = "mockName-$number", + externalId = "mockExternalId-$number", + readOnly = false, + ) diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkCollectionUtil.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkCollectionUtil.kt new file mode 100644 index 0000000000..e9f0081003 --- /dev/null +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/sdk/model/VaultSdkCollectionUtil.kt @@ -0,0 +1,16 @@ +package com.x8bit.bitwarden.data.vault.datasource.sdk.model + +import com.bitwarden.core.Collection + +/** + * Create a mock [Collection] with a given [number]. + */ +fun createMockSdkCollection(number: Int): Collection = + Collection( + id = "mockId-$number", + organizationId = "mockOrganizationId-$number", + hidePasswords = false, + name = "mockName-$number", + externalId = "mockExternalId-$number", + readOnly = false, + ) diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt index e06879c28a..50a8ab8ded 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/VaultRepositoryTest.kt @@ -26,8 +26,10 @@ import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource import com.x8bit.bitwarden.data.vault.datasource.sdk.model.InitializeCryptoResult import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView +import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCollectionView import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockFolderView import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSdkCipher +import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSdkCollection import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSdkFolder import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSdkSend import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSendView @@ -87,6 +89,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -124,6 +129,7 @@ class VaultRepositoryTest { DataState.Loaded( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -165,6 +171,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -180,6 +189,7 @@ class VaultRepositoryTest { DataState.Loaded( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -190,6 +200,7 @@ class VaultRepositoryTest { DataState.Pending( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -199,6 +210,7 @@ class VaultRepositoryTest { DataState.Loaded( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -226,6 +238,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -285,6 +300,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -318,6 +336,45 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns mockException.asFailure() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) + } returns listOf(createMockSendView(number = 1)).asSuccess() + fakeAuthDiskSource.userState = MOCK_USER_STATE + + vaultRepository.sync() + + assertEquals( + DataState.Error(error = mockException), + vaultRepository.vaultDataStateFlow.value, + ) + } + + @Test + fun `sync with decryptCollectionList Failure should update vaultDataStateFlow with Error`() = + runTest { + val mockException = IllegalStateException() + coEvery { + syncService.sync() + } returns Result.success(createMockSyncResponse(number = 1)) + coEvery { + vaultSdkSource.initializeOrganizationCrypto( + request = InitOrgCryptoRequest( + organizationKeys = createMockOrganizationKeys(1), + ), + ) + } returns InitializeCryptoResult.Success.asSuccess() + coEvery { + vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1))) + } returns listOf(createMockCipherView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) + } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns mockException.asFailure() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -351,6 +408,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns mockException.asFailure() @@ -434,6 +494,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -449,6 +512,7 @@ class VaultRepositoryTest { DataState.Loaded( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -462,6 +526,7 @@ class VaultRepositoryTest { DataState.Pending( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -471,6 +536,7 @@ class VaultRepositoryTest { DataState.NoNetwork( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -501,6 +567,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -608,6 +677,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -680,6 +752,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -1518,6 +1593,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -1533,6 +1611,7 @@ class VaultRepositoryTest { DataState.Loaded( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -1567,6 +1646,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(number = 1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1))) } returns listOf(createMockSendView(number = 1)).asSuccess() @@ -1617,6 +1699,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(itemId))) } returns listOf(createMockFolderView(1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(itemId))) + } returns listOf(createMockCollectionView(itemId)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(itemId))) } returns listOf(createMockSendView(itemId)).asSuccess() @@ -1698,6 +1783,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(1))) } returns listOf(createMockSendView(1)).asSuccess() @@ -1737,6 +1825,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(folderId))) } returns listOf(createMockFolderView(folderId)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(folderId))) + } returns listOf(createMockCollectionView(folderId)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(folderId))) } returns listOf(createMockSendView(folderId)).asSuccess() @@ -1818,6 +1909,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(1))) } returns listOf(createMockSendView(1)).asSuccess() @@ -1903,6 +1997,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(1))) } returns listOf(createMockSendView(1)).asSuccess() @@ -1987,6 +2084,9 @@ class VaultRepositoryTest { coEvery { vaultSdkSource.decryptFolderList(listOf(createMockSdkFolder(1))) } returns listOf(createMockFolderView(1)).asSuccess() + coEvery { + vaultSdkSource.decryptCollectionList(listOf(createMockSdkCollection(1))) + } returns listOf(createMockCollectionView(number = 1)).asSuccess() coEvery { vaultSdkSource.decryptSendList(listOf(createMockSdkSend(1))) } returns listOf(createMockSendView(1)).asSuccess() diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt new file mode 100644 index 0000000000..2a1d3e6267 --- /dev/null +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCollectionExtensionsTest.kt @@ -0,0 +1,59 @@ +package com.x8bit.bitwarden.data.vault.repository.util + +import com.bitwarden.core.Collection +import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson +import org.junit.Test +import org.junit.jupiter.api.Assertions.assertEquals + +class VaultSdkCollectionExtensionsTest { + @Test + fun `toEncryptedSdkCollection should convert a network Collection to an SDK Collection`() { + assertEquals( + Collection( + organizationId = "organizationId", + hidePasswords = true, + name = "name", + externalId = "externalId", + readOnly = true, + id = "id", + ), + SyncResponseJson.Collection( + organizationId = "organizationId", + shouldHidePasswords = true, + name = "name", + externalId = "externalId", + isReadOnly = true, + id = "id", + ) + .toEncryptedSdkCollection(), + ) + } + + @Suppress("MaxLineLength") + @Test + fun `toEncryptedSdkCollectionList should convert a list of network Collections to a list of SDK Collections`() { + assertEquals( + listOf( + Collection( + organizationId = "organizationId", + hidePasswords = true, + name = "name", + externalId = "externalId", + readOnly = true, + id = "id", + ), + ), + listOf( + SyncResponseJson.Collection( + organizationId = "organizationId", + shouldHidePasswords = true, + name = "name", + externalId = "externalId", + isReadOnly = true, + id = "id", + ) + .toEncryptedSdkCollection(), + ), + ) + } +} diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt index d445dc5bc3..2c9928ee4d 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/VaultViewModelTest.kt @@ -8,6 +8,7 @@ import com.x8bit.bitwarden.data.auth.repository.model.UserState.SpecialCircumsta import com.x8bit.bitwarden.data.platform.repository.model.DataState import com.x8bit.bitwarden.data.platform.repository.model.Environment import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView +import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCollectionView import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockFolderView import com.x8bit.bitwarden.data.vault.repository.VaultRepository import com.x8bit.bitwarden.data.vault.repository.model.VaultData @@ -260,6 +261,7 @@ class VaultViewModelTest : BaseViewModelTest() { value = DataState.Loaded( data = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ), ), @@ -296,6 +298,7 @@ class VaultViewModelTest : BaseViewModelTest() { value = DataState.Loaded( data = VaultData( cipherViewList = emptyList(), + collectionViewList = emptyList(), folderViewList = emptyList(), ), ), @@ -384,6 +387,7 @@ class VaultViewModelTest : BaseViewModelTest() { mutableVaultDataStateFlow.value = DataState.Loaded( data = VaultData( cipherViewList = emptyList(), + collectionViewList = emptyList(), folderViewList = emptyList(), ), ) diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt index eaebdd07ee..a0333fd68c 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/vault/feature/vault/util/VaultDataExtensionsTest.kt @@ -10,6 +10,7 @@ import com.bitwarden.core.SecureNoteType import com.bitwarden.core.SecureNoteView import com.bitwarden.core.UriMatchType import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCipherView +import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockCollectionView import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockFolderView import com.x8bit.bitwarden.data.vault.repository.model.VaultData import com.x8bit.bitwarden.ui.platform.base.util.asText @@ -35,6 +36,7 @@ class VaultDataExtensionsTest { fun `toViewState should transform full VaultData into ViewState Content`() { val vaultData = VaultData( cipherViewList = listOf(createMockCipherView(number = 1)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), ) @@ -65,6 +67,7 @@ class VaultDataExtensionsTest { fun `toViewState should transform empty VaultData into ViewState NoItems`() { val vaultData = VaultData( cipherViewList = emptyList(), + collectionViewList = emptyList(), folderViewList = emptyList(), ) @@ -80,6 +83,7 @@ class VaultDataExtensionsTest { fun `toViewState should not transform ciphers with no ID into ViewState items`() { val vaultData = VaultData( cipherViewList = listOf(createMockCipherView(number = 1).copy(id = null)), + collectionViewList = listOf(createMockCollectionView(number = 1)), folderViewList = listOf(createMockFolderView(number = 1)), )