mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 18:58:59 +03:00
BIT-474, BIT-518, BIT-519, BIT-521: Expose flows from the vault database tables (#414)
This commit is contained in:
parent
8a2a205247
commit
abe2354c15
4 changed files with 495 additions and 74 deletions
|
@ -1,6 +1,7 @@
|
|||
package com.x8bit.bitwarden.data.vault.repository
|
||||
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.CollectionView
|
||||
import com.bitwarden.core.FolderView
|
||||
import com.bitwarden.core.Kdf
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.DataState
|
||||
|
@ -22,6 +23,21 @@ interface VaultRepository {
|
|||
*/
|
||||
val vaultDataStateFlow: StateFlow<DataState<VaultData>>
|
||||
|
||||
/**
|
||||
* Flow that represents all ciphers for the active user.
|
||||
*/
|
||||
val ciphersStateFlow: StateFlow<DataState<List<CipherView>>>
|
||||
|
||||
/**
|
||||
* Flow that represents all collections for the active user.
|
||||
*/
|
||||
val collectionsStateFlow: StateFlow<DataState<List<CollectionView>>>
|
||||
|
||||
/**
|
||||
* Flow that represents all folders for the active user.
|
||||
*/
|
||||
val foldersStateFlow: StateFlow<DataState<List<FolderView>>>
|
||||
|
||||
/**
|
||||
* Flow that represents the current vault state.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.x8bit.bitwarden.data.vault.repository
|
||||
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.CollectionView
|
||||
import com.bitwarden.core.FolderView
|
||||
import com.bitwarden.core.InitOrgCryptoRequest
|
||||
import com.bitwarden.core.InitUserCryptoMethod
|
||||
|
@ -13,10 +14,12 @@ import com.x8bit.bitwarden.data.platform.datasource.network.util.isNoConnectionE
|
|||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.repository.model.DataState
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.map
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.observeWhenSubscribedAndLoggedIn
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.updateToPendingOrLoading
|
||||
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||
import com.x8bit.bitwarden.data.platform.util.flatMap
|
||||
import com.x8bit.bitwarden.data.platform.util.zip
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||
|
@ -36,14 +39,19 @@ import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkSendList
|
|||
import com.x8bit.bitwarden.data.vault.repository.util.toVaultUnlockResult
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -53,9 +61,10 @@ import kotlinx.coroutines.withContext
|
|||
* Default implementation of [VaultRepository].
|
||||
*/
|
||||
@Suppress("TooManyFunctions")
|
||||
class VaultRepositoryImpl constructor(
|
||||
class VaultRepositoryImpl(
|
||||
private val syncService: SyncService,
|
||||
private val ciphersService: CiphersService,
|
||||
private val vaultDiskSource: VaultDiskSource,
|
||||
private val vaultSdkSource: VaultSdkSource,
|
||||
private val authDiskSource: AuthDiskSource,
|
||||
private val dispatcherManager: DispatcherManager,
|
||||
|
@ -67,6 +76,8 @@ class VaultRepositoryImpl constructor(
|
|||
|
||||
private var willSyncAfterUnlock = false
|
||||
|
||||
private val activeUserId: String? get() = authDiskSource.userState?.activeUserId
|
||||
|
||||
private val vaultDataMutableStateFlow =
|
||||
MutableStateFlow<DataState<VaultData>>(DataState.Loading)
|
||||
|
||||
|
@ -79,19 +90,65 @@ class VaultRepositoryImpl constructor(
|
|||
override val vaultDataStateFlow: StateFlow<DataState<VaultData>>
|
||||
get() = vaultDataMutableStateFlow.asStateFlow()
|
||||
|
||||
override val ciphersStateFlow: StateFlow<DataState<List<CipherView>>>
|
||||
get() = mutableCiphersStateFlow.asStateFlow()
|
||||
|
||||
override val foldersStateFlow: StateFlow<DataState<List<FolderView>>>
|
||||
get() = mutableFoldersStateFlow.asStateFlow()
|
||||
|
||||
override val collectionsStateFlow: StateFlow<DataState<List<CollectionView>>>
|
||||
get() = mutableCollectionsStateFlow.asStateFlow()
|
||||
|
||||
override val vaultStateFlow: StateFlow<VaultState>
|
||||
get() = vaultMutableStateFlow.asStateFlow()
|
||||
|
||||
override val sendDataStateFlow: StateFlow<DataState<SendData>>
|
||||
get() = sendDataMutableStateFlow.asStateFlow()
|
||||
|
||||
private val mutableCiphersStateFlow =
|
||||
MutableStateFlow<DataState<List<CipherView>>>(DataState.Loading)
|
||||
|
||||
private val mutableFoldersStateFlow =
|
||||
MutableStateFlow<DataState<List<FolderView>>>(DataState.Loading)
|
||||
|
||||
private val mutableCollectionsStateFlow =
|
||||
MutableStateFlow<DataState<List<CollectionView>>>(DataState.Loading)
|
||||
|
||||
init {
|
||||
// Setup ciphers MutableStateFlow
|
||||
mutableCiphersStateFlow
|
||||
.observeWhenSubscribedAndLoggedIn(authDiskSource.userStateFlow) { activeUserId ->
|
||||
observeVaultDiskCiphers(activeUserId)
|
||||
}
|
||||
.launchIn(scope)
|
||||
// Setup folders MutableStateFlow
|
||||
mutableFoldersStateFlow
|
||||
.observeWhenSubscribedAndLoggedIn(authDiskSource.userStateFlow) { activeUserId ->
|
||||
observeVaultDiskFolders(activeUserId)
|
||||
}
|
||||
.launchIn(scope)
|
||||
// Setup collections MutableStateFlow
|
||||
mutableCollectionsStateFlow
|
||||
.observeWhenSubscribedAndLoggedIn(authDiskSource.userStateFlow) { activeUserId ->
|
||||
observeVaultDiskCollections(activeUserId)
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
|
||||
override fun clearUnlockedData() {
|
||||
mutableCiphersStateFlow.update { DataState.Loading }
|
||||
mutableFoldersStateFlow.update { DataState.Loading }
|
||||
mutableCollectionsStateFlow.update { DataState.Loading }
|
||||
vaultDataMutableStateFlow.update { DataState.Loading }
|
||||
sendDataMutableStateFlow.update { DataState.Loading }
|
||||
}
|
||||
|
||||
override fun sync() {
|
||||
if (!syncJob.isCompleted || willSyncAfterUnlock) return
|
||||
val userId = activeUserId ?: return
|
||||
mutableCiphersStateFlow.updateToPendingOrLoading()
|
||||
mutableFoldersStateFlow.updateToPendingOrLoading()
|
||||
mutableCollectionsStateFlow.updateToPendingOrLoading()
|
||||
vaultDataMutableStateFlow.updateToPendingOrLoading()
|
||||
sendDataMutableStateFlow.updateToPendingOrLoading()
|
||||
syncJob = scope.launch {
|
||||
|
@ -108,10 +165,28 @@ class VaultRepositoryImpl constructor(
|
|||
|
||||
unlockVaultForOrganizationsIfNecessary(syncResponse = syncResponse)
|
||||
storeKeys(syncResponse = syncResponse)
|
||||
decryptSyncResponseAndUpdateVaultDataState(syncResponse = syncResponse)
|
||||
decryptSyncResponseAndUpdateVaultDataState(
|
||||
userId = userId,
|
||||
syncResponse = syncResponse,
|
||||
)
|
||||
decryptSendsAndUpdateSendDataState(sendList = syncResponse.sends)
|
||||
},
|
||||
onFailure = { throwable ->
|
||||
mutableCiphersStateFlow.update { currentState ->
|
||||
throwable.toNetworkOrErrorState(
|
||||
data = currentState.data,
|
||||
)
|
||||
}
|
||||
mutableFoldersStateFlow.update { currentState ->
|
||||
throwable.toNetworkOrErrorState(
|
||||
data = currentState.data,
|
||||
)
|
||||
}
|
||||
mutableCollectionsStateFlow.update { currentState ->
|
||||
throwable.toNetworkOrErrorState(
|
||||
data = currentState.data,
|
||||
)
|
||||
}
|
||||
vaultDataMutableStateFlow.update { currentState ->
|
||||
throwable.toNetworkOrErrorState(
|
||||
data = currentState.data,
|
||||
|
@ -371,8 +446,13 @@ class VaultRepositoryImpl constructor(
|
|||
}
|
||||
|
||||
private suspend fun decryptSyncResponseAndUpdateVaultDataState(
|
||||
userId: String,
|
||||
syncResponse: SyncResponseJson,
|
||||
) = withContext(dispatcherManager.default) {
|
||||
val deferred = async {
|
||||
vaultDiskSource.replaceVaultData(userId = userId, vault = syncResponse)
|
||||
}
|
||||
|
||||
// Allow decryption of various types in parallel.
|
||||
val newState = zip(
|
||||
{
|
||||
|
@ -414,7 +494,56 @@ class VaultRepositoryImpl constructor(
|
|||
onFailure = { DataState.Error(error = it) },
|
||||
)
|
||||
vaultDataMutableStateFlow.update { newState }
|
||||
deferred.await()
|
||||
}
|
||||
|
||||
private fun observeVaultDiskCiphers(
|
||||
userId: String,
|
||||
): Flow<DataState<List<CipherView>>> =
|
||||
vaultDiskSource
|
||||
.getCiphers(userId = userId)
|
||||
.onStart { mutableCiphersStateFlow.value = DataState.Loading }
|
||||
.map {
|
||||
vaultSdkSource
|
||||
.decryptCipherList(cipherList = it.toEncryptedSdkCipherList())
|
||||
.fold(
|
||||
onSuccess = { ciphers -> DataState.Loaded(ciphers) },
|
||||
onFailure = { throwable -> DataState.Error(throwable) },
|
||||
)
|
||||
}
|
||||
.onEach { mutableCiphersStateFlow.value = it }
|
||||
|
||||
private fun observeVaultDiskFolders(
|
||||
userId: String,
|
||||
): Flow<DataState<List<FolderView>>> =
|
||||
vaultDiskSource
|
||||
.getFolders(userId = userId)
|
||||
.onStart { mutableFoldersStateFlow.value = DataState.Loading }
|
||||
.map {
|
||||
vaultSdkSource
|
||||
.decryptFolderList(folderList = it.toEncryptedSdkFolderList())
|
||||
.fold(
|
||||
onSuccess = { folders -> DataState.Loaded(folders) },
|
||||
onFailure = { throwable -> DataState.Error(throwable) },
|
||||
)
|
||||
}
|
||||
.onEach { mutableFoldersStateFlow.value = it }
|
||||
|
||||
private fun observeVaultDiskCollections(
|
||||
userId: String,
|
||||
): Flow<DataState<List<CollectionView>>> =
|
||||
vaultDiskSource
|
||||
.getCollections(userId = userId)
|
||||
.onStart { mutableCollectionsStateFlow.value = DataState.Loading }
|
||||
.map {
|
||||
vaultSdkSource
|
||||
.decryptCollectionList(collectionList = it.toEncryptedSdkCollectionList())
|
||||
.fold(
|
||||
onSuccess = { collections -> DataState.Loaded(collections) },
|
||||
onFailure = { throwable -> DataState.Error(throwable) },
|
||||
)
|
||||
}
|
||||
.onEach { mutableCollectionsStateFlow.value = it }
|
||||
}
|
||||
|
||||
private fun <T> Throwable.toNetworkOrErrorState(data: T?): DataState<T> =
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.vault.repository.di
|
|||
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.SyncService
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||
|
@ -25,12 +26,14 @@ object VaultRepositoryModule {
|
|||
fun providesVaultRepository(
|
||||
syncService: SyncService,
|
||||
ciphersService: CiphersService,
|
||||
vaultDiskSource: VaultDiskSource,
|
||||
vaultSdkSource: VaultSdkSource,
|
||||
authDiskSource: AuthDiskSource,
|
||||
dispatcherManager: DispatcherManager,
|
||||
): VaultRepository = VaultRepositoryImpl(
|
||||
syncService = syncService,
|
||||
ciphersService = ciphersService,
|
||||
vaultDiskSource = vaultDiskSource,
|
||||
vaultSdkSource = vaultSdkSource,
|
||||
authDiskSource = authDiskSource,
|
||||
dispatcherManager = dispatcherManager,
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.vault.repository
|
|||
|
||||
import app.cash.turbine.test
|
||||
import com.bitwarden.core.CipherView
|
||||
import com.bitwarden.core.CollectionView
|
||||
import com.bitwarden.core.FolderView
|
||||
import com.bitwarden.core.InitOrgCryptoRequest
|
||||
import com.bitwarden.core.InitUserCryptoMethod
|
||||
|
@ -17,8 +18,12 @@ import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
|||
import com.x8bit.bitwarden.data.platform.repository.model.DataState
|
||||
import com.x8bit.bitwarden.data.platform.util.asFailure
|
||||
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipher
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipherJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCollection
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockFolder
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockOrganizationKeys
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockSyncResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.service.CiphersService
|
||||
|
@ -39,14 +44,20 @@ import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult
|
|||
import com.x8bit.bitwarden.data.vault.repository.model.VaultData
|
||||
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.toEncryptedSdkCipherList
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCollectionList
|
||||
import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkFolderList
|
||||
import io.mockk.awaits
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.runs
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
|
@ -60,22 +71,185 @@ class VaultRepositoryTest {
|
|||
private val fakeAuthDiskSource = FakeAuthDiskSource()
|
||||
private val syncService: SyncService = mockk()
|
||||
private val ciphersService: CiphersService = mockk()
|
||||
private val vaultDiskSource: VaultDiskSource = mockk()
|
||||
private val vaultSdkSource: VaultSdkSource = mockk()
|
||||
private val vaultRepository = VaultRepositoryImpl(
|
||||
syncService = syncService,
|
||||
ciphersService = ciphersService,
|
||||
vaultDiskSource = vaultDiskSource,
|
||||
vaultSdkSource = vaultSdkSource,
|
||||
authDiskSource = fakeAuthDiskSource,
|
||||
dispatcherManager = dispatcherManager,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `ciphersStateFlow should emit decrypted list of ciphers when decryptCipherList succeeds`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockCipherList = listOf(createMockCipher(number = 1))
|
||||
val mockEncryptedCipherList = mockCipherList.toEncryptedSdkCipherList()
|
||||
val mockCipherViewList = listOf(createMockCipherView(number = 1))
|
||||
val mutableCiphersStateFlow = MutableSharedFlow<List<SyncResponseJson.Cipher>>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
every {
|
||||
vaultDiskSource.getCiphers(userId = MOCK_USER_STATE.activeUserId)
|
||||
} returns mutableCiphersStateFlow
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(mockEncryptedCipherList)
|
||||
} returns mockCipherViewList.asSuccess()
|
||||
|
||||
vaultRepository
|
||||
.ciphersStateFlow
|
||||
.test {
|
||||
assertEquals(DataState.Loading, awaitItem())
|
||||
mutableCiphersStateFlow.tryEmit(mockCipherList)
|
||||
assertEquals(DataState.Loaded(mockCipherViewList), awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ciphersStateFlow should emit an error when decryptCipherList fails`() = runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val throwable = Throwable("Fail")
|
||||
val mockCipherList = listOf(createMockCipher(number = 1))
|
||||
val mockEncryptedCipherList = mockCipherList.toEncryptedSdkCipherList()
|
||||
val mutableCiphersStateFlow = MutableSharedFlow<List<SyncResponseJson.Cipher>>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
every {
|
||||
vaultDiskSource.getCiphers(userId = MOCK_USER_STATE.activeUserId)
|
||||
} returns mutableCiphersStateFlow
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(mockEncryptedCipherList)
|
||||
} returns throwable.asFailure()
|
||||
|
||||
vaultRepository
|
||||
.ciphersStateFlow
|
||||
.test {
|
||||
assertEquals(DataState.Loading, awaitItem())
|
||||
mutableCiphersStateFlow.tryEmit(mockCipherList)
|
||||
assertEquals(DataState.Error<List<CipherView>>(throwable), awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `collectionsStateFlow should emit decrypted list of collections when decryptCollectionList succeeds`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockCollectionList = listOf(createMockCollection(number = 1))
|
||||
val mockEncryptedCollectionList = mockCollectionList.toEncryptedSdkCollectionList()
|
||||
val mockCollectionViewList = listOf(createMockCollectionView(number = 1))
|
||||
val mutableCollectionsStateFlow = MutableSharedFlow<List<SyncResponseJson.Collection>>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
every {
|
||||
vaultDiskSource.getCollections(userId = MOCK_USER_STATE.activeUserId)
|
||||
} returns mutableCollectionsStateFlow
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCollectionList(mockEncryptedCollectionList)
|
||||
} returns mockCollectionViewList.asSuccess()
|
||||
|
||||
vaultRepository
|
||||
.collectionsStateFlow
|
||||
.test {
|
||||
assertEquals(DataState.Loading, awaitItem())
|
||||
mutableCollectionsStateFlow.tryEmit(mockCollectionList)
|
||||
assertEquals(DataState.Loaded(mockCollectionViewList), awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `collectionsStateFlow should emit an error when decryptCollectionList fails`() = runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val throwable = Throwable("Fail")
|
||||
val mockCollectionList = listOf(createMockCollection(number = 1))
|
||||
val mockEncryptedCollectionList = mockCollectionList.toEncryptedSdkCollectionList()
|
||||
val mutableCollectionStateFlow = MutableSharedFlow<List<SyncResponseJson.Collection>>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
every {
|
||||
vaultDiskSource.getCollections(userId = MOCK_USER_STATE.activeUserId)
|
||||
} returns mutableCollectionStateFlow
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCollectionList(mockEncryptedCollectionList)
|
||||
} returns throwable.asFailure()
|
||||
|
||||
vaultRepository
|
||||
.collectionsStateFlow
|
||||
.test {
|
||||
assertEquals(DataState.Loading, awaitItem())
|
||||
mutableCollectionStateFlow.tryEmit(mockCollectionList)
|
||||
assertEquals(DataState.Error<List<CollectionView>>(throwable), awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `foldersStateFlow should emit decrypted list of folders when decryptFolderList succeeds`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockFolderList = listOf(createMockFolder(number = 1))
|
||||
val mockEncryptedFolderList = mockFolderList.toEncryptedSdkFolderList()
|
||||
val mockFolderViewList = listOf(createMockFolderView(number = 1))
|
||||
val mutableFoldersStateFlow = MutableSharedFlow<List<SyncResponseJson.Folder>>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
every {
|
||||
vaultDiskSource.getFolders(userId = MOCK_USER_STATE.activeUserId)
|
||||
} returns mutableFoldersStateFlow
|
||||
coEvery {
|
||||
vaultSdkSource.decryptFolderList(mockEncryptedFolderList)
|
||||
} returns mockFolderViewList.asSuccess()
|
||||
|
||||
vaultRepository
|
||||
.foldersStateFlow
|
||||
.test {
|
||||
assertEquals(DataState.Loading, awaitItem())
|
||||
mutableFoldersStateFlow.tryEmit(mockFolderList)
|
||||
assertEquals(DataState.Loaded(mockFolderViewList), awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `foldersStateFlow should emit an error when decryptFolderList fails`() = runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val throwable = Throwable("Fail")
|
||||
val mockFolderList = listOf(createMockFolder(number = 1))
|
||||
val mockEncryptedFolderList = mockFolderList.toEncryptedSdkFolderList()
|
||||
val mutableFoldersStateFlow = MutableSharedFlow<List<SyncResponseJson.Folder>>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
every {
|
||||
vaultDiskSource.getFolders(userId = MOCK_USER_STATE.activeUserId)
|
||||
} returns mutableFoldersStateFlow
|
||||
coEvery {
|
||||
vaultSdkSource.decryptFolderList(mockEncryptedFolderList)
|
||||
} returns throwable.asFailure()
|
||||
|
||||
vaultRepository
|
||||
.foldersStateFlow
|
||||
.test {
|
||||
assertEquals(DataState.Loading, awaitItem())
|
||||
mutableFoldersStateFlow.tryEmit(mockFolderList)
|
||||
assertEquals(DataState.Error<List<FolderView>>(throwable), awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@Test
|
||||
fun `sync with syncService Success should unlock the vault for orgs if necessary and update AuthDiskSource and DataStateFlows`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -83,6 +257,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -155,9 +335,9 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `sync with data should update vaultDataStateFlow to Pending before service sync`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -165,6 +345,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -177,7 +363,6 @@ class VaultRepositoryTest {
|
|||
coEvery {
|
||||
vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1)))
|
||||
} returns listOf(createMockSendView(number = 1)).asSuccess()
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
|
||||
vaultRepository.vaultDataStateFlow.test {
|
||||
assertEquals(
|
||||
|
@ -222,9 +407,8 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `sync with data should update sendDataStateFlow to Pending before service sync`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -232,6 +416,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -283,10 +473,10 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `sync with decryptCipherList Failure should update vaultDataStateFlow with Error`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockException = IllegalStateException()
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -294,6 +484,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns mockException.asFailure()
|
||||
|
@ -320,9 +516,9 @@ class VaultRepositoryTest {
|
|||
fun `sync with decryptFolderList Failure should update vaultDataStateFlow with Error`() =
|
||||
runTest {
|
||||
val mockException = IllegalStateException()
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -330,6 +526,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -356,9 +558,9 @@ class VaultRepositoryTest {
|
|||
fun `sync with decryptCollectionList Failure should update vaultDataStateFlow with Error`() =
|
||||
runTest {
|
||||
val mockException = IllegalStateException()
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -366,6 +568,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -378,7 +586,6 @@ class VaultRepositoryTest {
|
|||
coEvery {
|
||||
vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1)))
|
||||
} returns listOf(createMockSendView(number = 1)).asSuccess()
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
|
||||
vaultRepository.sync()
|
||||
|
||||
|
@ -392,9 +599,9 @@ class VaultRepositoryTest {
|
|||
fun `sync with decryptSendList Failure should update sendDataStateFlow with Error`() =
|
||||
runTest {
|
||||
val mockException = IllegalStateException()
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -402,6 +609,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -427,6 +640,7 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `sync with syncService Failure should update vault and send DataStateFlow with an Error`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockException = IllegalStateException(
|
||||
"sad",
|
||||
)
|
||||
|
@ -453,34 +667,32 @@ class VaultRepositoryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `sync with NoNetwork should update vault and send DataStateFlow to NoNetwork`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns UnknownHostException().asFailure()
|
||||
fun `sync with NoNetwork should update vault and send DataStateFlow to NoNetwork`() = runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
coEvery { syncService.sync() } returns UnknownHostException().asFailure()
|
||||
|
||||
vaultRepository.sync()
|
||||
vaultRepository.sync()
|
||||
|
||||
assertEquals(
|
||||
DataState.NoNetwork(
|
||||
data = null,
|
||||
),
|
||||
vaultRepository.vaultDataStateFlow.value,
|
||||
)
|
||||
assertEquals(
|
||||
DataState.NoNetwork(
|
||||
data = null,
|
||||
),
|
||||
vaultRepository.sendDataStateFlow.value,
|
||||
)
|
||||
}
|
||||
assertEquals(
|
||||
DataState.NoNetwork(
|
||||
data = null,
|
||||
),
|
||||
vaultRepository.vaultDataStateFlow.value,
|
||||
)
|
||||
assertEquals(
|
||||
DataState.NoNetwork(
|
||||
data = null,
|
||||
),
|
||||
vaultRepository.sendDataStateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sync with NoNetwork data should update vaultDataStateFlow to NoNetwork with data`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -488,6 +700,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -500,7 +718,6 @@ class VaultRepositoryTest {
|
|||
coEvery {
|
||||
vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1)))
|
||||
} returns listOf(createMockSendView(number = 1)).asSuccess()
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
|
||||
vaultRepository.vaultDataStateFlow.test {
|
||||
assertEquals(
|
||||
|
@ -548,10 +765,12 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `sync with NoNetwork data should update sendDataStateFlow to NoNetwork with data`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returnsMany listOf(
|
||||
Result.success(createMockSyncResponse(number = 1)),
|
||||
mockSyncResponse.asSuccess(),
|
||||
UnknownHostException().asFailure(),
|
||||
)
|
||||
coEvery {
|
||||
|
@ -561,6 +780,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -573,7 +798,6 @@ class VaultRepositoryTest {
|
|||
coEvery {
|
||||
vaultSdkSource.decryptSendList(listOf(createMockSdkSend(number = 1)))
|
||||
} returns listOf(createMockSendView(number = 1)).asSuccess()
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
|
||||
vaultRepository.sendDataStateFlow.test {
|
||||
assertEquals(
|
||||
|
@ -661,9 +885,8 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `unlockVaultAndSyncForCurrentUser with unlockVault Success should sync and return Success`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -671,6 +894,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -736,9 +965,8 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `sync should be able to be called after unlockVaultAndSyncForCurrentUser is canceled`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -746,6 +974,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -1577,9 +1811,9 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `clearUnlockedData should update the vaultDataStateFlow to Loading`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -1587,6 +1821,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -1630,9 +1870,8 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `clearUnlockedData should update the sendDataStateFlow to Loading`() =
|
||||
runTest {
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(number = 1))
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -1640,6 +1879,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(number = 1)).asSuccess()
|
||||
|
@ -1683,9 +1928,9 @@ class VaultRepositoryTest {
|
|||
val itemId = 1234
|
||||
val itemIdString = "mockId-$itemId"
|
||||
val item = createMockCipherView(itemId)
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(itemId))
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val mockSyncResponse = createMockSyncResponse(number = itemId)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -1693,6 +1938,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(itemId)))
|
||||
} returns listOf(item).asSuccess()
|
||||
|
@ -1728,6 +1979,7 @@ class VaultRepositoryTest {
|
|||
val folderId = 1234
|
||||
val folderIdString = "mockId-$folderId"
|
||||
val throwable = Throwable("Fail")
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns throwable.asFailure()
|
||||
|
@ -1748,6 +2000,7 @@ class VaultRepositoryTest {
|
|||
runTest {
|
||||
val itemId = 1234
|
||||
val itemIdString = "mockId-$itemId"
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns UnknownHostException().asFailure()
|
||||
|
@ -1766,10 +2019,10 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `getVaultItemStateFlow should update to Loaded with null when a item cannot be found`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val itemIdString = "mockId-1234"
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(1))
|
||||
val mockSyncResponse = createMockSyncResponse(1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -1777,6 +2030,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(1)).asSuccess()
|
||||
|
@ -1806,12 +2065,12 @@ class VaultRepositoryTest {
|
|||
|
||||
@Test
|
||||
fun `getVaultFolderStateFlow should receive updates whenever a sync is called`() = runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val folderId = 1234
|
||||
val folderIdString = "mockId-$folderId"
|
||||
val folder = createMockFolderView(folderId)
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(folderId))
|
||||
val mockSyncResponse = createMockSyncResponse(folderId)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -1819,6 +2078,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(folderId)))
|
||||
} returns listOf(createMockCipherView(folderId)).asSuccess()
|
||||
|
@ -1854,6 +2119,7 @@ class VaultRepositoryTest {
|
|||
runTest {
|
||||
val folderId = 1234
|
||||
val folderIdString = "mockId-$folderId"
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns UnknownHostException().asFailure()
|
||||
|
@ -1874,6 +2140,7 @@ class VaultRepositoryTest {
|
|||
val folderId = 1234
|
||||
val folderIdString = "mockId-$folderId"
|
||||
val throwable = Throwable("Fail")
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns throwable.asFailure()
|
||||
|
@ -1892,10 +2159,10 @@ class VaultRepositoryTest {
|
|||
@Test
|
||||
fun `getVaultFolderStateFlow should update to Loaded with null when a item cannot be found`() =
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val folderIdString = "mockId-1234"
|
||||
coEvery {
|
||||
syncService.sync()
|
||||
} returns Result.success(createMockSyncResponse(1))
|
||||
val mockSyncResponse = createMockSyncResponse(number = 1)
|
||||
coEvery { syncService.sync() } returns mockSyncResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.initializeOrganizationCrypto(
|
||||
request = InitOrgCryptoRequest(
|
||||
|
@ -1903,6 +2170,12 @@ class VaultRepositoryTest {
|
|||
),
|
||||
)
|
||||
} returns InitializeCryptoResult.Success.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.replaceVaultData(
|
||||
userId = MOCK_USER_STATE.activeUserId,
|
||||
vault = mockSyncResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptCipherList(listOf(createMockSdkCipher(1)))
|
||||
} returns listOf(createMockCipherView(1)).asSuccess()
|
||||
|
|
Loading…
Add table
Reference in a new issue