Add support for retrieving a single send by ID from the VaultRepository (#564)

This commit is contained in:
David Perez 2024-01-10 13:31:31 -06:00 committed by Álison Fernandes
parent 75a08e72a6
commit f8ff7c225d
3 changed files with 89 additions and 0 deletions

View file

@ -93,6 +93,12 @@ interface VaultRepository : VaultLockManager {
*/
fun getVaultFolderStateFlow(folderId: String): StateFlow<DataState<FolderView?>>
/**
* Flow that represents the data for a specific send as found by ID. This may emit `null` if
* the send cannot be found.
*/
fun getSendStateFlow(sendId: String): StateFlow<DataState<SendView?>>
/**
* Emits the totp code result flow to listeners.
*/

View file

@ -263,6 +263,19 @@ class VaultRepositoryImpl(
initialValue = DataState.Loading,
)
override fun getSendStateFlow(sendId: String): StateFlow<DataState<SendView?>> =
sendDataStateFlow
.map { dataState ->
dataState.map { sendData ->
sendData.sendViewList.find { it.id == sendId }
}
}
.stateIn(
scope = unconfinedScope,
started = SharingStarted.Lazily,
initialValue = DataState.Loading,
)
override fun emitTotpCodeResult(totpCodeResult: TotpCodeResult) {
mutableTotpCodeResultFlow.tryEmit(totpCodeResult)
}

View file

@ -8,6 +8,7 @@ import com.bitwarden.core.InitOrgCryptoRequest
import com.bitwarden.core.InitUserCryptoMethod
import com.bitwarden.core.InitUserCryptoRequest
import com.bitwarden.core.Kdf
import com.bitwarden.core.SendView
import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountJson
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
import com.x8bit.bitwarden.data.auth.datasource.disk.util.FakeAuthDiskSource
@ -1113,6 +1114,75 @@ class VaultRepositoryTest {
}
}
@Test
fun `getSendStateFlow should update emit SendView when present`() = runTest {
val sendId = 1
fakeAuthDiskSource.userState = MOCK_USER_STATE
val sendView = createMockSendView(number = sendId)
coEvery {
vaultSdkSource.decryptSendList(
userId = MOCK_USER_STATE.activeUserId,
sendList = emptyList(),
)
} returns emptyList<SendView>().asSuccess()
coEvery {
vaultSdkSource.decryptSendList(
userId = MOCK_USER_STATE.activeUserId,
sendList = listOf(createMockSdkSend(number = sendId)),
)
} returns listOf(sendView).asSuccess()
val sendsFlow = bufferedMutableSharedFlow<List<SyncResponseJson.Send>>()
setupVaultDiskSourceFlows(sendsFlow = sendsFlow)
vaultRepository.getSendStateFlow("mockId-$sendId").test {
assertEquals(DataState.Loading, awaitItem())
sendsFlow.tryEmit(emptyList())
assertEquals(DataState.Loaded<SendView?>(null), awaitItem())
sendsFlow.tryEmit(listOf(createMockSend(number = sendId)))
assertEquals(DataState.Loaded<SendView?>(sendView), awaitItem())
}
}
@Test
fun `getSendStateFlow should update to NoNetwork when a sync fails from no network`() =
runTest {
val sendId = 1234
fakeAuthDiskSource.userState = MOCK_USER_STATE
coEvery { syncService.sync() } returns UnknownHostException().asFailure()
setupVaultDiskSourceFlows()
vaultRepository.getSendStateFlow("mockId-$sendId").test {
assertEquals(DataState.Loading, awaitItem())
vaultRepository.sync()
assertEquals(DataState.NoNetwork<SendView?>(), awaitItem())
}
coVerify(exactly = 1) {
syncService.sync()
}
}
@Test
fun `getSendStateFlow should update to Error when a sync fails generically`() =
runTest {
val sendId = 1234
val throwable = Throwable("Fail")
fakeAuthDiskSource.userState = MOCK_USER_STATE
coEvery { syncService.sync() } returns throwable.asFailure()
setupVaultDiskSourceFlows()
vaultRepository.getSendStateFlow("mockId-$sendId").test {
assertEquals(DataState.Loading, awaitItem())
vaultRepository.sync()
assertEquals(DataState.Error<SendView?>(throwable), awaitItem())
}
coVerify(exactly = 1) {
syncService.sync()
}
}
@Test
fun `createCipher with encryptCipher failure should return CreateCipherResult failure`() =
runTest {