mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 07:05:35 +03:00
BIT-2129 Show descriptive error message when Send creation fails (#1186)
This commit is contained in:
parent
90ff2897f5
commit
1150f01666
14 changed files with 277 additions and 101 deletions
|
@ -1,7 +1,7 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.api
|
||||
|
||||
import androidx.annotation.Keep
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendFileResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import okhttp3.MultipartBody
|
||||
|
@ -28,7 +28,7 @@ interface SendsApi {
|
|||
* Create a file send.
|
||||
*/
|
||||
@POST("sends/file/v2")
|
||||
suspend fun createFileSend(@Body body: SendJsonRequest): Result<SendFileResponseJson>
|
||||
suspend fun createFileSend(@Body body: SendJsonRequest): Result<CreateFileSendResponseJson>
|
||||
|
||||
/**
|
||||
* Updates a send.
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents a response from create file send.
|
||||
*/
|
||||
sealed class CreateFileSendResponse {
|
||||
|
||||
/**
|
||||
* Represents the response from a successful create file send request.
|
||||
*
|
||||
* @property createFileJsonResponse Response JSON received from create file send request.
|
||||
*/
|
||||
data class Success(
|
||||
val createFileJsonResponse: CreateFileSendResponseJson,
|
||||
) : CreateFileSendResponse()
|
||||
|
||||
/**
|
||||
* Represents the json body of an invalid create request.
|
||||
*
|
||||
* @property message A general, user-displayable error message.
|
||||
* @property validationErrors a map where each value is a list of error messages for each
|
||||
* key. The values in the array should be used for display to the user, since the keys tend
|
||||
* to come back as nonsense. (eg: empty string key)
|
||||
*/
|
||||
@Serializable
|
||||
data class Invalid(
|
||||
@SerialName("message")
|
||||
override val message: String,
|
||||
|
||||
@SerialName("validationErrors")
|
||||
override val validationErrors: Map<String, List<String>>?,
|
||||
) : CreateFileSendResponse(), InvalidJsonResponse
|
||||
}
|
|
@ -7,7 +7,7 @@ import kotlinx.serialization.Serializable
|
|||
* Represents the JSON response from creating a new file send.
|
||||
*/
|
||||
@Serializable
|
||||
data class SendFileResponseJson(
|
||||
data class CreateFileSendResponseJson(
|
||||
@SerialName("url")
|
||||
val url: String,
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Models a response from either "create text send" or "create file send" requests.
|
||||
*/
|
||||
sealed class CreateSendJsonResponse {
|
||||
/**
|
||||
* Represents a successful response from either "create text send" or "create file send"
|
||||
* request.
|
||||
*
|
||||
* @property send The created send object.
|
||||
*/
|
||||
data class Success(val send: SyncResponseJson.Send) : CreateSendJsonResponse()
|
||||
|
||||
/**
|
||||
* Represents the json body of an invalid create request.
|
||||
*
|
||||
* @property message A general, user-displayable error message.
|
||||
* @property validationErrors a map where each value is a list of error messages for each
|
||||
* key. The values in the array should be used for display to the user, since the keys tend
|
||||
* to come back as nonsense. (eg: empty string key)
|
||||
*/
|
||||
@Serializable
|
||||
data class Invalid(
|
||||
@SerialName("message")
|
||||
override val message: String,
|
||||
|
||||
@SerialName("validationErrors")
|
||||
override val validationErrors: Map<String, List<String>>?,
|
||||
) : CreateSendJsonResponse(), InvalidJsonResponse
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.model
|
||||
|
||||
/**
|
||||
* Represents the json body of an invalid send json request.
|
||||
*/
|
||||
sealed interface InvalidJsonResponse {
|
||||
|
||||
/**
|
||||
* A general, user-displayable error message.
|
||||
*/
|
||||
val message: String
|
||||
|
||||
/**
|
||||
* a map where each value is a list of error messages for each key.
|
||||
* The values in the array should be used for display to the user, since the keys tend to come
|
||||
* back as nonsense. (eg: empty string key)
|
||||
*/
|
||||
val validationErrors: Map<String, List<String>>?
|
||||
|
||||
/**
|
||||
* Returns the first error message found in [validationErrors], or [message] if there are no
|
||||
* [validationErrors] present.
|
||||
*/
|
||||
val firstValidationErrorMessage: String?
|
||||
get() = validationErrors
|
||||
?.flatMap { it.value }
|
||||
?.first()
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package com.x8bit.bitwarden.data.vault.datasource.network.service
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendFileResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateSendJsonResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateSendResponseJson
|
||||
|
@ -14,20 +16,20 @@ interface SendsService {
|
|||
*/
|
||||
suspend fun createTextSend(
|
||||
body: SendJsonRequest,
|
||||
): Result<SyncResponseJson.Send>
|
||||
): Result<CreateSendJsonResponse>
|
||||
|
||||
/**
|
||||
* Attempt to create a file send.
|
||||
*/
|
||||
suspend fun createFileSend(
|
||||
body: SendJsonRequest,
|
||||
): Result<SendFileResponseJson>
|
||||
): Result<CreateFileSendResponse>
|
||||
|
||||
/**
|
||||
* Attempt to upload the given [encryptedFile] associated with the [sendFileResponse].
|
||||
*/
|
||||
suspend fun uploadFile(
|
||||
sendFileResponse: SendFileResponseJson,
|
||||
sendFileResponse: CreateFileSendResponseJson,
|
||||
encryptedFile: ByteArray,
|
||||
): Result<SyncResponseJson.Send>
|
||||
|
||||
|
|
|
@ -5,8 +5,10 @@ import com.x8bit.bitwarden.data.platform.datasource.network.model.toBitwardenErr
|
|||
import com.x8bit.bitwarden.data.platform.datasource.network.util.parseErrorBodyOrNull
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.api.AzureApi
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.api.SendsApi
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateSendJsonResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.FileUploadType
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendFileResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateSendResponseJson
|
||||
|
@ -28,11 +30,33 @@ class SendsServiceImpl(
|
|||
private val clock: Clock,
|
||||
private val json: Json,
|
||||
) : SendsService {
|
||||
override suspend fun createTextSend(body: SendJsonRequest): Result<SyncResponseJson.Send> =
|
||||
override suspend fun createTextSend(
|
||||
body: SendJsonRequest,
|
||||
): Result<CreateSendJsonResponse> =
|
||||
sendsApi.createTextSend(body = body)
|
||||
.map { CreateSendJsonResponse.Success(send = it) }
|
||||
.recoverCatching { throwable ->
|
||||
throwable.toBitwardenError()
|
||||
.parseErrorBodyOrNull<CreateSendJsonResponse.Invalid>(
|
||||
code = 400,
|
||||
json = json,
|
||||
)
|
||||
?: throw throwable
|
||||
}
|
||||
|
||||
override suspend fun createFileSend(body: SendJsonRequest): Result<SendFileResponseJson> =
|
||||
override suspend fun createFileSend(
|
||||
body: SendJsonRequest,
|
||||
): Result<CreateFileSendResponse> =
|
||||
sendsApi.createFileSend(body = body)
|
||||
.map { CreateFileSendResponse.Success(it) }
|
||||
.recoverCatching { throwable ->
|
||||
throwable.toBitwardenError()
|
||||
.parseErrorBodyOrNull<CreateFileSendResponse.Invalid>(
|
||||
code = 400,
|
||||
json = json,
|
||||
)
|
||||
?: throw throwable
|
||||
}
|
||||
|
||||
override suspend fun updateSend(
|
||||
sendId: String,
|
||||
|
@ -55,7 +79,7 @@ class SendsServiceImpl(
|
|||
}
|
||||
|
||||
override suspend fun uploadFile(
|
||||
sendFileResponse: SendFileResponseJson,
|
||||
sendFileResponse: CreateFileSendResponseJson,
|
||||
encryptedFile: ByteArray,
|
||||
): Result<SyncResponseJson.Send> {
|
||||
val send = sendFileResponse.sendResponse
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.bitwarden.core.ExportFormat
|
|||
import com.bitwarden.core.FolderView
|
||||
import com.bitwarden.core.InitOrgCryptoRequest
|
||||
import com.bitwarden.core.InitUserCryptoMethod
|
||||
import com.bitwarden.core.Send
|
||||
import com.bitwarden.core.SendType
|
||||
import com.bitwarden.core.SendView
|
||||
import com.bitwarden.crypto.Kdf
|
||||
|
@ -35,10 +36,13 @@ 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.asFailure
|
||||
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||
import com.x8bit.bitwarden.data.platform.util.flatMap
|
||||
import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.AttachmentJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateCipherInOrganizationJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateSendJsonResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.ShareCipherJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherCollectionsJsonRequest
|
||||
|
@ -980,11 +984,12 @@ class VaultRepositoryImpl(
|
|||
)
|
||||
}
|
||||
|
||||
@Suppress("ReturnCount")
|
||||
override suspend fun createSend(
|
||||
sendView: SendView,
|
||||
fileUri: Uri?,
|
||||
): CreateSendResult {
|
||||
val userId = activeUserId ?: return CreateSendResult.Error
|
||||
val userId = activeUserId ?: return CreateSendResult.Error(message = null)
|
||||
return vaultSdkSource
|
||||
.encryptSend(
|
||||
userId = userId,
|
||||
|
@ -992,54 +997,33 @@ class VaultRepositoryImpl(
|
|||
)
|
||||
.flatMap { send ->
|
||||
when (send.type) {
|
||||
SendType.TEXT -> {
|
||||
sendsService.createTextSend(body = send.toEncryptedNetworkSend())
|
||||
SendType.TEXT -> sendsService.createTextSend(send.toEncryptedNetworkSend())
|
||||
SendType.FILE -> createFileSend(fileUri, userId, send)
|
||||
}
|
||||
}
|
||||
.map { createSendResponse ->
|
||||
when (createSendResponse) {
|
||||
is CreateSendJsonResponse.Invalid -> {
|
||||
return CreateSendResult.Error(
|
||||
message = createSendResponse.firstValidationErrorMessage,
|
||||
)
|
||||
}
|
||||
|
||||
SendType.FILE -> {
|
||||
val uri = fileUri ?: return@flatMap IllegalArgumentException(
|
||||
"File URI must be present to create a File Send.",
|
||||
)
|
||||
.asFailure()
|
||||
|
||||
fileManager
|
||||
.uriToByteArray(fileUri = uri)
|
||||
.flatMap {
|
||||
vaultSdkSource.encryptBuffer(
|
||||
userId = userId,
|
||||
send = send,
|
||||
fileBuffer = it,
|
||||
)
|
||||
}
|
||||
.flatMap { encryptedFile ->
|
||||
sendsService
|
||||
.createFileSend(
|
||||
body = send.toEncryptedNetworkSend(
|
||||
fileLength = encryptedFile.size,
|
||||
),
|
||||
)
|
||||
.flatMap { sendFileResponse ->
|
||||
sendsService.uploadFile(
|
||||
sendFileResponse = sendFileResponse,
|
||||
encryptedFile = encryptedFile,
|
||||
)
|
||||
}
|
||||
}
|
||||
is CreateSendJsonResponse.Success -> {
|
||||
// Save the send immediately, regardless of whether the decrypt succeeds
|
||||
vaultDiskSource.saveSend(userId = userId, send = createSendResponse.send)
|
||||
createSendResponse
|
||||
}
|
||||
}
|
||||
}
|
||||
.onSuccess {
|
||||
// Save the send immediately, regardless of whether the decrypt succeeds
|
||||
vaultDiskSource.saveSend(userId = userId, send = it)
|
||||
}
|
||||
.flatMap {
|
||||
.flatMap { createSendSuccessResponse ->
|
||||
vaultSdkSource.decryptSend(
|
||||
userId = userId,
|
||||
send = it.toEncryptedSdkSend(),
|
||||
send = createSendSuccessResponse.send.toEncryptedSdkSend(),
|
||||
)
|
||||
}
|
||||
.fold(
|
||||
onFailure = { CreateSendResult.Error },
|
||||
onFailure = { CreateSendResult.Error(message = null) },
|
||||
onSuccess = { CreateSendResult.Success(it) },
|
||||
)
|
||||
}
|
||||
|
@ -1594,6 +1578,56 @@ class VaultRepositoryImpl(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun createFileSend(
|
||||
uri: Uri?,
|
||||
userId: String,
|
||||
send: Send,
|
||||
): Result<CreateSendJsonResponse> {
|
||||
uri ?: return IllegalArgumentException(
|
||||
"File URI must be present to create a File Send.",
|
||||
)
|
||||
.asFailure()
|
||||
|
||||
return fileManager
|
||||
.uriToByteArray(fileUri = uri)
|
||||
.flatMap {
|
||||
vaultSdkSource.encryptBuffer(
|
||||
userId = userId,
|
||||
send = send,
|
||||
fileBuffer = it,
|
||||
)
|
||||
}
|
||||
.flatMap { encryptedFile ->
|
||||
sendsService
|
||||
.createFileSend(
|
||||
body = send.toEncryptedNetworkSend(
|
||||
fileLength = encryptedFile.size,
|
||||
),
|
||||
)
|
||||
.flatMap { sendFileResponse ->
|
||||
when (sendFileResponse) {
|
||||
is CreateFileSendResponse.Invalid -> {
|
||||
CreateSendJsonResponse
|
||||
.Invalid(
|
||||
message = sendFileResponse.message,
|
||||
validationErrors = sendFileResponse.validationErrors,
|
||||
)
|
||||
.asSuccess()
|
||||
}
|
||||
|
||||
is CreateFileSendResponse.Success -> {
|
||||
sendsService
|
||||
.uploadFile(
|
||||
sendFileResponse = sendFileResponse.createFileJsonResponse,
|
||||
encryptedFile = encryptedFile,
|
||||
)
|
||||
.map { CreateSendJsonResponse.Success(it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the send specified by [syncSendDeleteData] from disk.
|
||||
*/
|
||||
|
|
|
@ -15,5 +15,5 @@ sealed class CreateSendResult {
|
|||
/**
|
||||
* Generic error while creating a send.
|
||||
*/
|
||||
data object Error : CreateSendResult()
|
||||
data class Error(val message: String?) : CreateSendResult()
|
||||
}
|
||||
|
|
|
@ -184,12 +184,13 @@ class AddSendViewModel @Inject constructor(
|
|||
action: AddSendAction.Internal.CreateSendResultReceive,
|
||||
) {
|
||||
when (val result = action.result) {
|
||||
CreateSendResult.Error -> {
|
||||
is CreateSendResult.Error -> {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = AddSendState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
message = result.message?.asText()
|
||||
?: R.string.generic_error_message.asText(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -2,6 +2,13 @@ package com.x8bit.bitwarden.data.vault.datasource.network.model
|
|||
|
||||
import java.time.ZonedDateTime
|
||||
|
||||
fun createMockFileSendResponseJson(number: Int, type: SendTypeJson = SendTypeJson.FILE) =
|
||||
CreateFileSendResponseJson(
|
||||
url = "www.test.com",
|
||||
fileUploadType = FileUploadType.AZURE,
|
||||
sendResponse = createMockSend(number = number, type = type),
|
||||
)
|
||||
|
||||
fun createMockSend(
|
||||
number: Int,
|
||||
type: SendTypeJson = SendTypeJson.FILE,
|
||||
|
|
|
@ -4,10 +4,11 @@ import android.net.Uri
|
|||
import com.x8bit.bitwarden.data.platform.base.BaseServiceTest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.api.AzureApi
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.api.SendsApi
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.FileUploadType
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendFileResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateSendJsonResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendTypeJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateSendResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockFileSendResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockSend
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockSendJsonRequest
|
||||
import io.mockk.every
|
||||
|
@ -52,16 +53,18 @@ class SendsServiceTest : BaseServiceTest() {
|
|||
|
||||
@Test
|
||||
fun `createFileSend should return the correct response`() = runTest {
|
||||
val response = SendFileResponseJson(
|
||||
url = "www.test.com",
|
||||
fileUploadType = FileUploadType.AZURE,
|
||||
sendResponse = createMockSend(number = 1, type = SendTypeJson.FILE),
|
||||
val sendFileResponse = CreateFileSendResponse.Success(
|
||||
createFileJsonResponse = createMockFileSendResponseJson(number = 1),
|
||||
)
|
||||
server.enqueue(MockResponse().setBody(CREATE_FILE_SEND_SUCCESS_JSON))
|
||||
val result = sendsService.createFileSend(
|
||||
body = createMockSendJsonRequest(number = 1, type = SendTypeJson.FILE),
|
||||
)
|
||||
assertEquals(response, result.getOrThrow())
|
||||
|
||||
assertEquals(
|
||||
sendFileResponse,
|
||||
result.getOrThrow(),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -71,7 +74,7 @@ class SendsServiceTest : BaseServiceTest() {
|
|||
body = createMockSendJsonRequest(number = 1, type = SendTypeJson.TEXT),
|
||||
)
|
||||
assertEquals(
|
||||
createMockSend(number = 1),
|
||||
CreateSendJsonResponse.Success(createMockSend(number = 1)),
|
||||
result.getOrThrow(),
|
||||
)
|
||||
}
|
||||
|
@ -113,13 +116,9 @@ class SendsServiceTest : BaseServiceTest() {
|
|||
fun `uploadFile with Azure uploadFile success should return send`() = runTest {
|
||||
val url = "www.test.com"
|
||||
setupMockUri(url = url, queryParams = mapOf("sv" to "2024-04-03"))
|
||||
val mockSend = createMockSend(number = 1, type = SendTypeJson.FILE)
|
||||
val sendFileResponse = SendFileResponseJson(
|
||||
url = url,
|
||||
fileUploadType = FileUploadType.AZURE,
|
||||
sendResponse = mockSend,
|
||||
)
|
||||
val sendFileResponse = createMockFileSendResponseJson(number = 1)
|
||||
val encryptedFile = byteArrayOf()
|
||||
|
||||
server.enqueue(MockResponse().setResponseCode(201))
|
||||
|
||||
val result = sendsService.uploadFile(
|
||||
|
@ -127,17 +126,14 @@ class SendsServiceTest : BaseServiceTest() {
|
|||
encryptedFile = encryptedFile,
|
||||
)
|
||||
|
||||
assertEquals(mockSend, result.getOrThrow())
|
||||
assertEquals(sendFileResponse.sendResponse, result.getOrThrow())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `uploadFile with Direct uploadFile success should return send`() = runTest {
|
||||
val mockSend = createMockSend(number = 1, type = SendTypeJson.FILE)
|
||||
val sendFileResponse = SendFileResponseJson(
|
||||
url = "www.test.com",
|
||||
fileUploadType = FileUploadType.DIRECT,
|
||||
sendResponse = mockSend,
|
||||
)
|
||||
val url = "www.test.com"
|
||||
setupMockUri(url = url, queryParams = mapOf("sv" to "2024-04-03"))
|
||||
val sendFileResponse = createMockFileSendResponseJson(number = 1)
|
||||
val encryptedFile = byteArrayOf()
|
||||
server.enqueue(MockResponse().setResponseCode(201))
|
||||
|
||||
|
@ -146,7 +142,7 @@ class SendsServiceTest : BaseServiceTest() {
|
|||
encryptedFile = encryptedFile,
|
||||
)
|
||||
|
||||
assertEquals(mockSend, result.getOrThrow())
|
||||
assertEquals(sendFileResponse.sendResponse, result.getOrThrow())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -39,9 +39,9 @@ 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.AttachmentJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateCipherInOrganizationJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.FileUploadType
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateFileSendResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateSendJsonResponse
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.FolderJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendFileResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SendTypeJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.ShareCipherJsonRequest
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.SyncResponseJson
|
||||
|
@ -55,6 +55,7 @@ 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.createMockDomains
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockFileSendResponseJson
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockFolder
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockOrganization
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockOrganizationKeys
|
||||
|
@ -2430,7 +2431,7 @@ class VaultRepositoryTest {
|
|||
)
|
||||
|
||||
assertEquals(
|
||||
CreateSendResult.Error,
|
||||
CreateSendResult.Error(message = null),
|
||||
result,
|
||||
)
|
||||
}
|
||||
|
@ -2447,7 +2448,7 @@ class VaultRepositoryTest {
|
|||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = null)
|
||||
|
||||
assertEquals(CreateSendResult.Error, result)
|
||||
assertEquals(CreateSendResult.Error(message = null), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2469,7 +2470,7 @@ class VaultRepositoryTest {
|
|||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = null)
|
||||
|
||||
assertEquals(CreateSendResult.Error, result)
|
||||
assertEquals(CreateSendResult.Error(IllegalStateException().message), result)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
|
@ -2482,6 +2483,7 @@ class VaultRepositoryTest {
|
|||
val mockSdkSend = createMockSdkSend(number = 1, type = SendType.TEXT)
|
||||
val mockSend = createMockSend(number = 1, type = SendTypeJson.TEXT)
|
||||
val mockSendViewResult = createMockSendView(number = 2)
|
||||
val sendTextResponse = CreateSendJsonResponse.Success(send = mockSend)
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns mockSdkSend.asSuccess()
|
||||
|
@ -2490,7 +2492,7 @@ class VaultRepositoryTest {
|
|||
body = createMockSendJsonRequest(number = 1, type = SendTypeJson.TEXT)
|
||||
.copy(fileLength = null),
|
||||
)
|
||||
} returns mockSend.asSuccess()
|
||||
} returns sendTextResponse.asSuccess()
|
||||
coEvery { vaultDiskSource.saveSend(userId, mockSend) } just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSend(userId, mockSdkSend)
|
||||
|
@ -2529,7 +2531,7 @@ class VaultRepositoryTest {
|
|||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = uri)
|
||||
|
||||
assertEquals(CreateSendResult.Error, result)
|
||||
assertEquals(CreateSendResult.Error(IllegalStateException().message), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2544,14 +2546,18 @@ class VaultRepositoryTest {
|
|||
val mockSdkSend = createMockSdkSend(number = 1)
|
||||
val byteArray = byteArrayOf(1)
|
||||
val encryptedByteArray = byteArrayOf(2)
|
||||
val sendFileResponse = SendFileResponseJson(
|
||||
url = url,
|
||||
fileUploadType = FileUploadType.AZURE,
|
||||
sendResponse = createMockSend(number = 1, type = SendTypeJson.FILE),
|
||||
val sendFileResponse = CreateFileSendResponse.Success(
|
||||
createMockFileSendResponseJson(
|
||||
number = 1,
|
||||
type = SendTypeJson.FILE,
|
||||
),
|
||||
)
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns mockSdkSend.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSend(userId, mockSdkSend)
|
||||
} returns mockSendView.asSuccess()
|
||||
coEvery { fileManager.uriToByteArray(any()) } returns byteArray.asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.encryptBuffer(
|
||||
|
@ -2560,19 +2566,25 @@ class VaultRepositoryTest {
|
|||
fileBuffer = byteArray,
|
||||
)
|
||||
} returns encryptedByteArray.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.saveSend(
|
||||
userId,
|
||||
sendFileResponse.createFileJsonResponse.sendResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
sendsService.createFileSend(body = createMockSendJsonRequest(number = 1))
|
||||
} returns sendFileResponse.asSuccess()
|
||||
coEvery {
|
||||
sendsService.uploadFile(
|
||||
sendFileResponse = sendFileResponse,
|
||||
sendFileResponse = sendFileResponse.createFileJsonResponse,
|
||||
encryptedFile = encryptedByteArray,
|
||||
)
|
||||
} returns Throwable("Fail").asFailure()
|
||||
} returns Throwable().asFailure()
|
||||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = uri)
|
||||
|
||||
assertEquals(CreateSendResult.Error, result)
|
||||
assertEquals(CreateSendResult.Error(null), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2588,11 +2600,11 @@ class VaultRepositoryTest {
|
|||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns mockSdkSend.asSuccess()
|
||||
coEvery { fileManager.uriToByteArray(any()) } returns Throwable("Fail").asFailure()
|
||||
coEvery { fileManager.uriToByteArray(any()) } returns Throwable().asFailure()
|
||||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = uri)
|
||||
|
||||
assertEquals(CreateSendResult.Error, result)
|
||||
assertEquals(CreateSendResult.Error(message = null), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2607,11 +2619,8 @@ class VaultRepositoryTest {
|
|||
val mockSdkSend = createMockSdkSend(number = 1)
|
||||
val byteArray = byteArrayOf(1)
|
||||
val encryptedByteArray = byteArrayOf(2)
|
||||
val sendResponse = createMockSend(number = 1)
|
||||
val sendFileResponse = SendFileResponseJson(
|
||||
url = url,
|
||||
fileUploadType = FileUploadType.AZURE,
|
||||
sendResponse = sendResponse,
|
||||
val sendFileResponse = CreateFileSendResponse.Success(
|
||||
createMockFileSendResponseJson(number = 1),
|
||||
)
|
||||
val mockSendViewResult = createMockSendView(number = 1)
|
||||
coEvery {
|
||||
|
@ -2630,11 +2639,16 @@ class VaultRepositoryTest {
|
|||
} returns sendFileResponse.asSuccess()
|
||||
coEvery {
|
||||
sendsService.uploadFile(
|
||||
sendFileResponse = sendFileResponse,
|
||||
sendFileResponse = sendFileResponse.createFileJsonResponse,
|
||||
encryptedFile = encryptedByteArray,
|
||||
)
|
||||
} returns sendResponse.asSuccess()
|
||||
coEvery { vaultDiskSource.saveSend(userId, sendResponse) } just runs
|
||||
} returns sendFileResponse.createFileJsonResponse.sendResponse.asSuccess()
|
||||
coEvery {
|
||||
vaultDiskSource.saveSend(
|
||||
userId,
|
||||
sendFileResponse.createFileJsonResponse.sendResponse,
|
||||
)
|
||||
} just runs
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSend(userId, mockSdkSend)
|
||||
} returns mockSendViewResult.asSuccess()
|
||||
|
|
|
@ -259,7 +259,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
|||
every { viewState.toSendView(clock) } returns mockSendView
|
||||
coEvery {
|
||||
vaultRepository.createSend(sendView = mockSendView, fileUri = null)
|
||||
} returns CreateSendResult.Error
|
||||
} returns CreateSendResult.Error("Fail")
|
||||
val viewModel = createViewModel(initialState)
|
||||
|
||||
viewModel.stateFlow.test {
|
||||
|
@ -277,7 +277,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
|||
initialState.copy(
|
||||
dialogState = AddSendState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
message = "Fail".asText(),
|
||||
),
|
||||
),
|
||||
awaitItem(),
|
||||
|
|
Loading…
Reference in a new issue