BIT-874: Expose Collections data from VaultRepository (#382)

This commit is contained in:
Brian Yencho
2023-12-13 10:00:15 -06:00
committed by GitHub
parent f3113dc602
commit 93b136a879
10 changed files with 241 additions and 3 deletions

View File

@@ -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,
)

View File

@@ -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,
)

View File

@@ -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<VaultData>(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()

View File

@@ -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(),
),
)
}
}

View File

@@ -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(),
),
)

View File

@@ -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)),
)