mirror of
https://github.com/bitwarden/android.git
synced 2026-08-25 17:09:55 -05:00
PM-19243 send result errors propagated to UI (#4872)
This commit is contained in:
+39
-16
@@ -21,6 +21,7 @@ import com.x8bit.bitwarden.data.auth.repository.util.toUpdatedUserStateJson
|
||||
import com.x8bit.bitwarden.data.auth.repository.util.userSwitchingChangesFlow
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.util.isNoConnectionError
|
||||
import com.x8bit.bitwarden.data.platform.error.NoActiveUserException
|
||||
import com.x8bit.bitwarden.data.platform.manager.DatabaseSchemeManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.PushManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.ReviewPromptManager
|
||||
@@ -622,7 +623,8 @@ class VaultRepositoryImpl(
|
||||
sendView: SendView,
|
||||
fileUri: Uri?,
|
||||
): CreateSendResult {
|
||||
val userId = activeUserId ?: return CreateSendResult.Error(message = null)
|
||||
val userId = activeUserId
|
||||
?: return CreateSendResult.Error(message = null, error = NoActiveUserException())
|
||||
return vaultSdkSource
|
||||
.encryptSend(
|
||||
userId = userId,
|
||||
@@ -639,6 +641,7 @@ class VaultRepositoryImpl(
|
||||
is CreateSendJsonResponse.Invalid -> {
|
||||
return CreateSendResult.Error(
|
||||
message = createSendResponse.firstValidationErrorMessage,
|
||||
error = null,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -656,7 +659,7 @@ class VaultRepositoryImpl(
|
||||
)
|
||||
}
|
||||
.fold(
|
||||
onFailure = { CreateSendResult.Error(message = null) },
|
||||
onFailure = { CreateSendResult.Error(message = null, error = it) },
|
||||
onSuccess = {
|
||||
reviewPromptManager.registerCreateSendAction()
|
||||
CreateSendResult.Success(it)
|
||||
@@ -668,7 +671,11 @@ class VaultRepositoryImpl(
|
||||
sendId: String,
|
||||
sendView: SendView,
|
||||
): UpdateSendResult {
|
||||
val userId = activeUserId ?: return UpdateSendResult.Error(null)
|
||||
val userId = activeUserId
|
||||
?: return UpdateSendResult.Error(
|
||||
errorMessage = null,
|
||||
error = NoActiveUserException(),
|
||||
)
|
||||
return vaultSdkSource
|
||||
.encryptSend(
|
||||
userId = userId,
|
||||
@@ -681,11 +688,11 @@ class VaultRepositoryImpl(
|
||||
)
|
||||
}
|
||||
.fold(
|
||||
onFailure = { UpdateSendResult.Error(errorMessage = null) },
|
||||
onFailure = { UpdateSendResult.Error(errorMessage = null, error = it) },
|
||||
onSuccess = { response ->
|
||||
when (response) {
|
||||
is UpdateSendResponseJson.Invalid -> {
|
||||
UpdateSendResult.Error(errorMessage = response.message)
|
||||
UpdateSendResult.Error(errorMessage = response.message, error = null)
|
||||
}
|
||||
|
||||
is UpdateSendResponseJson.Success -> {
|
||||
@@ -695,9 +702,12 @@ class VaultRepositoryImpl(
|
||||
userId = userId,
|
||||
send = response.send.toEncryptedSdkSend(),
|
||||
)
|
||||
.getOrNull()
|
||||
?.let { UpdateSendResult.Success(sendView = it) }
|
||||
?: UpdateSendResult.Error(errorMessage = null)
|
||||
.fold(
|
||||
onSuccess = { UpdateSendResult.Success(sendView = it) },
|
||||
onFailure = {
|
||||
UpdateSendResult.Error(errorMessage = null, error = it)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -705,14 +715,21 @@ class VaultRepositoryImpl(
|
||||
}
|
||||
|
||||
override suspend fun removePasswordSend(sendId: String): RemovePasswordSendResult {
|
||||
val userId = activeUserId ?: return RemovePasswordSendResult.Error(null)
|
||||
val userId = activeUserId
|
||||
?: return RemovePasswordSendResult.Error(
|
||||
errorMessage = null,
|
||||
error = NoActiveUserException(),
|
||||
)
|
||||
return sendsService
|
||||
.removeSendPassword(sendId = sendId)
|
||||
.fold(
|
||||
onSuccess = { response ->
|
||||
when (response) {
|
||||
is UpdateSendResponseJson.Invalid -> {
|
||||
RemovePasswordSendResult.Error(errorMessage = response.message)
|
||||
RemovePasswordSendResult.Error(
|
||||
errorMessage = response.message,
|
||||
error = null,
|
||||
)
|
||||
}
|
||||
|
||||
is UpdateSendResponseJson.Success -> {
|
||||
@@ -722,24 +739,30 @@ class VaultRepositoryImpl(
|
||||
userId = userId,
|
||||
send = response.send.toEncryptedSdkSend(),
|
||||
)
|
||||
.getOrNull()
|
||||
?.let { RemovePasswordSendResult.Success(sendView = it) }
|
||||
?: RemovePasswordSendResult.Error(errorMessage = null)
|
||||
.fold(
|
||||
onSuccess = { RemovePasswordSendResult.Success(sendView = it) },
|
||||
onFailure = {
|
||||
RemovePasswordSendResult.Error(
|
||||
errorMessage = null,
|
||||
error = it,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
onFailure = { RemovePasswordSendResult.Error(errorMessage = null) },
|
||||
onFailure = { RemovePasswordSendResult.Error(errorMessage = null, error = it) },
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun deleteSend(sendId: String): DeleteSendResult {
|
||||
val userId = activeUserId ?: return DeleteSendResult.Error
|
||||
val userId = activeUserId ?: return DeleteSendResult.Error(error = NoActiveUserException())
|
||||
return sendsService
|
||||
.deleteSend(sendId)
|
||||
.onSuccess { vaultDiskSource.deleteSend(userId, sendId) }
|
||||
.fold(
|
||||
onSuccess = { DeleteSendResult.Success },
|
||||
onFailure = { DeleteSendResult.Error },
|
||||
onFailure = { DeleteSendResult.Error(error = it) },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -15,5 +15,5 @@ sealed class CreateSendResult {
|
||||
/**
|
||||
* Generic error while creating a send.
|
||||
*/
|
||||
data class Error(val message: String?) : CreateSendResult()
|
||||
data class Error(val message: String?, val error: Throwable?) : CreateSendResult()
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,5 +13,5 @@ sealed class DeleteSendResult {
|
||||
/**
|
||||
* Generic error while deleting a send.
|
||||
*/
|
||||
data object Error : DeleteSendResult()
|
||||
data class Error(val error: Throwable) : DeleteSendResult()
|
||||
}
|
||||
|
||||
+1
-1
@@ -17,5 +17,5 @@ sealed class RemovePasswordSendResult {
|
||||
* Generic error while removing the password protection from a send. The optional
|
||||
* [errorMessage] may be displayed directly in the UI when present.
|
||||
*/
|
||||
data class Error(val errorMessage: String?) : RemovePasswordSendResult()
|
||||
data class Error(val errorMessage: String?, val error: Throwable?) : RemovePasswordSendResult()
|
||||
}
|
||||
|
||||
+1
-1
@@ -16,5 +16,5 @@ sealed class UpdateSendResult {
|
||||
* Generic error while updating a send. The optional [errorMessage] may be displayed directly
|
||||
* in the UI when present.
|
||||
*/
|
||||
data class Error(val errorMessage: String?) : UpdateSendResult()
|
||||
data class Error(val errorMessage: String?, val error: Throwable?) : UpdateSendResult()
|
||||
}
|
||||
|
||||
@@ -186,6 +186,7 @@ private fun SearchDialogs(
|
||||
title = dialogState.title?.invoke(),
|
||||
message = dialogState.message(),
|
||||
onDismissRequest = onDismissRequest,
|
||||
throwable = dialogState.throwable,
|
||||
)
|
||||
|
||||
is SearchState.DialogState.Loading -> BitwardenLoadingDialog(
|
||||
|
||||
@@ -474,13 +474,14 @@ class SearchViewModel @Inject constructor(
|
||||
private fun handleDeleteSendResultReceive(
|
||||
action: SearchAction.Internal.DeleteSendResultReceive,
|
||||
) {
|
||||
when (action.result) {
|
||||
DeleteSendResult.Error -> {
|
||||
when (val result = action.result) {
|
||||
is DeleteSendResult.Error -> {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = SearchState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -857,6 +858,7 @@ data class SearchState(
|
||||
data class Error(
|
||||
val title: Text?,
|
||||
val message: Text,
|
||||
val throwable: Throwable? = null,
|
||||
) : DialogState()
|
||||
|
||||
/**
|
||||
|
||||
@@ -212,6 +212,7 @@ private fun SendDialogs(
|
||||
title = dialogState.title?.invoke(),
|
||||
message = dialogState.message(),
|
||||
onDismissRequest = onDismissRequest,
|
||||
throwable = dialogState.throwable,
|
||||
)
|
||||
|
||||
is SendState.DialogState.Loading -> BitwardenLoadingDialog(
|
||||
|
||||
@@ -140,13 +140,14 @@ class SendViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
private fun handleDeleteSendResultReceive(action: SendAction.Internal.DeleteSendResultReceive) {
|
||||
when (action.result) {
|
||||
DeleteSendResult.Error -> {
|
||||
when (val result = action.result) {
|
||||
is DeleteSendResult.Error -> {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = SendState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -465,6 +466,7 @@ data class SendState(
|
||||
data class Error(
|
||||
val title: Text?,
|
||||
val message: Text,
|
||||
val throwable: Throwable? = null,
|
||||
) : DialogState()
|
||||
|
||||
/**
|
||||
|
||||
@@ -255,6 +255,7 @@ private fun AddSendDialogs(
|
||||
title = dialogState.title?.invoke(),
|
||||
message = dialogState.message(),
|
||||
onDismissRequest = onDismissRequest,
|
||||
throwable = dialogState.throwable,
|
||||
)
|
||||
|
||||
is AddSendState.DialogState.Loading -> BitwardenLoadingDialog(
|
||||
|
||||
+6
-1
@@ -192,6 +192,7 @@ class AddSendViewModel @Inject constructor(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = result.message?.asText()
|
||||
?: R.string.generic_error_message.asText(),
|
||||
throwable = result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -222,6 +223,7 @@ class AddSendViewModel @Inject constructor(
|
||||
.errorMessage
|
||||
?.asText()
|
||||
?: R.string.generic_error_message.asText(),
|
||||
throwable = result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -242,13 +244,14 @@ class AddSendViewModel @Inject constructor(
|
||||
private fun handleDeleteSendResultReceive(
|
||||
action: AddSendAction.Internal.DeleteSendResultReceive,
|
||||
) {
|
||||
when (action.result) {
|
||||
when (val result = action.result) {
|
||||
is DeleteSendResult.Error -> {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = AddSendState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -275,6 +278,7 @@ class AddSendViewModel @Inject constructor(
|
||||
.errorMessage
|
||||
?.asText()
|
||||
?: R.string.generic_error_message.asText(),
|
||||
result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -836,6 +840,7 @@ data class AddSendState(
|
||||
data class Error(
|
||||
val title: Text?,
|
||||
val message: Text,
|
||||
val throwable: Throwable? = null,
|
||||
) : DialogState()
|
||||
|
||||
/**
|
||||
|
||||
+1
@@ -317,6 +317,7 @@ private fun VaultItemListingDialogs(
|
||||
title = dialogState.title?.invoke(),
|
||||
message = dialogState.message(),
|
||||
onDismissRequest = onDismissRequest,
|
||||
throwable = dialogState.throwable,
|
||||
)
|
||||
|
||||
is VaultItemListingState.DialogState.Loading -> BitwardenLoadingDialog(
|
||||
|
||||
+9
-2
@@ -1206,13 +1206,14 @@ class VaultItemListingViewModel @Inject constructor(
|
||||
private fun handleDeleteSendResultReceive(
|
||||
action: VaultItemListingsAction.Internal.DeleteSendResultReceive,
|
||||
) {
|
||||
when (action.result) {
|
||||
DeleteSendResult.Error -> {
|
||||
when (val result = action.result) {
|
||||
is DeleteSendResult.Error -> {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
dialogState = VaultItemListingState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -1238,6 +1239,7 @@ class VaultItemListingViewModel @Inject constructor(
|
||||
.errorMessage
|
||||
?.asText()
|
||||
?: R.string.generic_error_message.asText(),
|
||||
throwable = result.error,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -1310,6 +1312,8 @@ class VaultItemListingViewModel @Inject constructor(
|
||||
dialogState = VaultItemListingState.DialogState.Error(
|
||||
title = null,
|
||||
message = R.string.generic_error_message.asText(),
|
||||
// TODO PM-19425 update ValidatePasswordResult to propagate error.
|
||||
throwable = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -1322,6 +1326,8 @@ class VaultItemListingViewModel @Inject constructor(
|
||||
dialogState = VaultItemListingState.DialogState.Error(
|
||||
title = null,
|
||||
message = R.string.invalid_master_password.asText(),
|
||||
// TODO PM-19425 update ValidatePasswordResult to propagate error.
|
||||
throwable = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -2025,6 +2031,7 @@ data class VaultItemListingState(
|
||||
data class Error(
|
||||
val title: Text?,
|
||||
val message: Text,
|
||||
val throwable: Throwable? = null,
|
||||
) : DialogState()
|
||||
|
||||
/**
|
||||
|
||||
+49
-26
@@ -25,6 +25,7 @@ import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
|
||||
import com.x8bit.bitwarden.data.auth.repository.util.toSdkParams
|
||||
import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
|
||||
import com.x8bit.bitwarden.data.platform.error.NoActiveUserException
|
||||
import com.x8bit.bitwarden.data.platform.manager.DatabaseSchemeManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.PushManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.ReviewPromptManager
|
||||
@@ -109,8 +110,10 @@ import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkConstructor
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.runs
|
||||
import io.mockk.unmockkConstructor
|
||||
import io.mockk.unmockkStatic
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@@ -248,6 +251,10 @@ class VaultRepositoryTest {
|
||||
mockkStatic(Uri::class)
|
||||
mockkStatic(MessageDigest::class)
|
||||
mockkStatic(Base64::class)
|
||||
mockkConstructor(NoActiveUserException::class)
|
||||
every {
|
||||
anyConstructed<NoActiveUserException>() == any<NoActiveUserException>()
|
||||
} returns true
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@@ -256,6 +263,7 @@ class VaultRepositoryTest {
|
||||
unmockkStatic(Uri::class)
|
||||
unmockkStatic(MessageDigest::class)
|
||||
unmockkStatic(Base64::class)
|
||||
unmockkConstructor(NoActiveUserException::class)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2116,7 +2124,7 @@ class VaultRepositoryTest {
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
CreateSendResult.Error(message = null),
|
||||
CreateSendResult.Error(message = null, error = NoActiveUserException()),
|
||||
result,
|
||||
)
|
||||
}
|
||||
@@ -2127,13 +2135,14 @@ class VaultRepositoryTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val userId = "mockId-1"
|
||||
val mockSendView = createMockSendView(number = 1)
|
||||
val error = IllegalStateException()
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns IllegalStateException().asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = null)
|
||||
|
||||
assertEquals(CreateSendResult.Error(message = null), result)
|
||||
assertEquals(CreateSendResult.Error(message = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2143,6 +2152,7 @@ class VaultRepositoryTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val userId = "mockId-1"
|
||||
val mockSendView = createMockSendView(number = 1, type = SendType.TEXT)
|
||||
val error = IllegalStateException()
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns createMockSdkSend(number = 1, type = SendType.TEXT).asSuccess()
|
||||
@@ -2151,11 +2161,11 @@ class VaultRepositoryTest {
|
||||
body = createMockSendJsonRequest(number = 1, type = SendTypeJson.TEXT)
|
||||
.copy(fileLength = null),
|
||||
)
|
||||
} returns IllegalStateException().asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = null)
|
||||
|
||||
assertEquals(CreateSendResult.Error(IllegalStateException().message), result)
|
||||
assertEquals(CreateSendResult.Error(message = error.message, error = error), result)
|
||||
}
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
@@ -2219,13 +2229,14 @@ class VaultRepositoryTest {
|
||||
destinationFilePath = "mockAbsolutePath",
|
||||
)
|
||||
} returns encryptedFile.asSuccess()
|
||||
val error = IllegalStateException()
|
||||
coEvery {
|
||||
sendsService.createFileSend(body = createMockSendJsonRequest(number = 1))
|
||||
} returns IllegalStateException().asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = uri)
|
||||
|
||||
assertEquals(CreateSendResult.Error(IllegalStateException().message), result)
|
||||
assertEquals(CreateSendResult.Error(message = error.message, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2254,6 +2265,7 @@ class VaultRepositoryTest {
|
||||
type = SendTypeJson.FILE,
|
||||
),
|
||||
)
|
||||
val error = Throwable()
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns mockSdkSend.asSuccess()
|
||||
@@ -2284,11 +2296,11 @@ class VaultRepositoryTest {
|
||||
sendFileResponse = sendFileResponse.createFileJsonResponse,
|
||||
encryptedFile = encryptedFile,
|
||||
)
|
||||
} returns Throwable().asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = uri)
|
||||
|
||||
assertEquals(CreateSendResult.Error(null), result)
|
||||
assertEquals(CreateSendResult.Error(message = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2301,14 +2313,15 @@ class VaultRepositoryTest {
|
||||
val uri = setupMockUri(url = url)
|
||||
val mockSendView = createMockSendView(number = 1)
|
||||
val mockSdkSend = createMockSdkSend(number = 1)
|
||||
val error = Throwable()
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns mockSdkSend.asSuccess()
|
||||
coEvery { fileManager.writeUriToCache(any()) } returns Throwable().asFailure()
|
||||
coEvery { fileManager.writeUriToCache(any()) } returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.createSend(sendView = mockSendView, fileUri = uri)
|
||||
|
||||
assertEquals(CreateSendResult.Error(message = null), result)
|
||||
assertEquals(CreateSendResult.Error(message = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2381,7 +2394,7 @@ class VaultRepositoryTest {
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
UpdateSendResult.Error(null),
|
||||
UpdateSendResult.Error(errorMessage = null, error = NoActiveUserException()),
|
||||
result,
|
||||
)
|
||||
}
|
||||
@@ -2393,16 +2406,17 @@ class VaultRepositoryTest {
|
||||
val userId = "mockId-1"
|
||||
val sendId = "sendId1234"
|
||||
val mockSendView = createMockSendView(number = 1)
|
||||
val error = IllegalStateException()
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns IllegalStateException().asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.updateSend(
|
||||
sendId = sendId,
|
||||
sendView = mockSendView,
|
||||
)
|
||||
|
||||
assertEquals(UpdateSendResult.Error(errorMessage = null), result)
|
||||
assertEquals(UpdateSendResult.Error(errorMessage = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2416,20 +2430,21 @@ class VaultRepositoryTest {
|
||||
coEvery {
|
||||
vaultSdkSource.encryptSend(userId = userId, sendView = mockSendView)
|
||||
} returns createMockSdkSend(number = 1, type = SendType.TEXT).asSuccess()
|
||||
val error = IllegalStateException()
|
||||
coEvery {
|
||||
sendsService.updateSend(
|
||||
sendId = sendId,
|
||||
body = createMockSendJsonRequest(number = 1, type = SendTypeJson.TEXT)
|
||||
.copy(fileLength = null),
|
||||
)
|
||||
} returns IllegalStateException().asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.updateSend(
|
||||
sendId = sendId,
|
||||
sendView = mockSendView,
|
||||
)
|
||||
|
||||
assertEquals(UpdateSendResult.Error(errorMessage = null), result)
|
||||
assertEquals(UpdateSendResult.Error(errorMessage = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2464,6 +2479,7 @@ class VaultRepositoryTest {
|
||||
assertEquals(
|
||||
UpdateSendResult.Error(
|
||||
errorMessage = "You do not have permission to edit this.",
|
||||
error = null,
|
||||
),
|
||||
result,
|
||||
)
|
||||
@@ -2488,11 +2504,12 @@ class VaultRepositoryTest {
|
||||
.copy(fileLength = null),
|
||||
)
|
||||
} returns UpdateSendResponseJson.Success(send = mockSend).asSuccess()
|
||||
val error = Throwable("Fail")
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSend(
|
||||
userId = userId, send = createMockSdkSend(number = 1, type = SendType.TEXT),
|
||||
)
|
||||
} returns Throwable("Fail").asFailure()
|
||||
} returns error.asFailure()
|
||||
coEvery { vaultDiskSource.saveSend(userId = userId, send = mockSend) } just runs
|
||||
|
||||
val result = vaultRepository.updateSend(
|
||||
@@ -2500,7 +2517,7 @@ class VaultRepositoryTest {
|
||||
sendView = mockSendView,
|
||||
)
|
||||
|
||||
assertEquals(UpdateSendResult.Error(errorMessage = null), result)
|
||||
assertEquals(UpdateSendResult.Error(errorMessage = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2549,7 +2566,10 @@ class VaultRepositoryTest {
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
RemovePasswordSendResult.Error(null),
|
||||
RemovePasswordSendResult.Error(
|
||||
errorMessage = null,
|
||||
error = NoActiveUserException(),
|
||||
),
|
||||
result,
|
||||
)
|
||||
}
|
||||
@@ -2560,13 +2580,14 @@ class VaultRepositoryTest {
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val sendId = "sendId1234"
|
||||
val error = Throwable("Fail")
|
||||
coEvery {
|
||||
sendsService.removeSendPassword(sendId = sendId)
|
||||
} returns Throwable("Fail").asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.removePasswordSend(sendId = sendId)
|
||||
|
||||
assertEquals(RemovePasswordSendResult.Error(errorMessage = null), result)
|
||||
assertEquals(RemovePasswordSendResult.Error(errorMessage = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2577,17 +2598,18 @@ class VaultRepositoryTest {
|
||||
val userId = "mockId-1"
|
||||
val sendId = "sendId1234"
|
||||
val mockSend = createMockSend(number = 1)
|
||||
val error = Throwable("Fail")
|
||||
coEvery {
|
||||
sendsService.removeSendPassword(sendId = sendId)
|
||||
} returns UpdateSendResponseJson.Success(send = mockSend).asSuccess()
|
||||
coEvery {
|
||||
vaultSdkSource.decryptSend(userId = userId, send = createMockSdkSend(number = 1))
|
||||
} returns Throwable("Fail").asFailure()
|
||||
} returns error.asFailure()
|
||||
coEvery { vaultDiskSource.saveSend(userId = userId, send = mockSend) } just runs
|
||||
|
||||
val result = vaultRepository.removePasswordSend(sendId = sendId)
|
||||
|
||||
assertEquals(RemovePasswordSendResult.Error(errorMessage = null), result)
|
||||
assertEquals(RemovePasswordSendResult.Error(errorMessage = null, error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2622,7 +2644,7 @@ class VaultRepositoryTest {
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
DeleteSendResult.Error,
|
||||
DeleteSendResult.Error(error = NoActiveUserException()),
|
||||
result,
|
||||
)
|
||||
}
|
||||
@@ -2632,13 +2654,14 @@ class VaultRepositoryTest {
|
||||
runTest {
|
||||
fakeAuthDiskSource.userState = MOCK_USER_STATE
|
||||
val sendId = "mockId-1"
|
||||
val error = Throwable("Fail")
|
||||
coEvery {
|
||||
sendsService.deleteSend(sendId = sendId)
|
||||
} returns Throwable("Fail").asFailure()
|
||||
} returns error.asFailure()
|
||||
|
||||
val result = vaultRepository.deleteSend(sendId)
|
||||
|
||||
assertEquals(DeleteSendResult.Error, result)
|
||||
assertEquals(DeleteSendResult.Error(error = error), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+6
-2
@@ -715,8 +715,11 @@ class SearchViewModelTest : BaseViewModelTest() {
|
||||
@Test
|
||||
fun `OverflowOptionClick Send DeleteClick with deleteSend error should display error dialog`() =
|
||||
runTest {
|
||||
val error = Throwable("Ahhh")
|
||||
val sendId = "sendId1234"
|
||||
coEvery { vaultRepository.deleteSend(sendId) } returns DeleteSendResult.Error
|
||||
coEvery {
|
||||
vaultRepository.deleteSend(sendId)
|
||||
} returns DeleteSendResult.Error(error = error)
|
||||
val viewModel = createViewModel()
|
||||
|
||||
viewModel.stateFlow.test {
|
||||
@@ -739,6 +742,7 @@ class SearchViewModelTest : BaseViewModelTest() {
|
||||
dialogState = SearchState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = error,
|
||||
),
|
||||
),
|
||||
awaitItem(),
|
||||
@@ -787,7 +791,7 @@ class SearchViewModelTest : BaseViewModelTest() {
|
||||
val sendId = "sendId1234"
|
||||
coEvery {
|
||||
vaultRepository.removePasswordSend(sendId)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null, error = null)
|
||||
|
||||
val viewModel = createViewModel()
|
||||
viewModel.stateFlow.test {
|
||||
|
||||
@@ -138,7 +138,8 @@ class SendViewModelTest : BaseViewModelTest() {
|
||||
val sendItem = mockk<SendState.ViewState.Content.SendItem> {
|
||||
every { id } returns sendId
|
||||
}
|
||||
coEvery { vaultRepo.deleteSend(sendId) } returns DeleteSendResult.Error
|
||||
val error = Throwable("Oops")
|
||||
coEvery { vaultRepo.deleteSend(sendId) } returns DeleteSendResult.Error(error = error)
|
||||
|
||||
val viewModel = createViewModel()
|
||||
viewModel.stateFlow.test {
|
||||
@@ -155,6 +156,7 @@ class SendViewModelTest : BaseViewModelTest() {
|
||||
dialogState = SendState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = error,
|
||||
),
|
||||
),
|
||||
awaitItem(),
|
||||
@@ -186,7 +188,7 @@ class SendViewModelTest : BaseViewModelTest() {
|
||||
}
|
||||
coEvery {
|
||||
vaultRepo.removePasswordSend(sendId)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null, error = null)
|
||||
|
||||
val viewModel = createViewModel()
|
||||
viewModel.stateFlow.test {
|
||||
|
||||
+9
-5
@@ -242,7 +242,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
||||
every { viewState.toSendView(clock) } returns mockSendView
|
||||
coEvery {
|
||||
vaultRepository.createSend(sendView = mockSendView, fileUri = null)
|
||||
} returns CreateSendResult.Error("Fail")
|
||||
} returns CreateSendResult.Error(message = "Fail", error = null)
|
||||
val viewModel = createViewModel(initialState)
|
||||
|
||||
viewModel.stateFlow.test {
|
||||
@@ -337,7 +337,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
||||
every { viewState.toSendView(clock) } returns mockSendView
|
||||
coEvery {
|
||||
vaultRepository.updateSend(sendId = sendId, sendView = mockSendView)
|
||||
} returns UpdateSendResult.Error(errorMessage = errorMessage)
|
||||
} returns UpdateSendResult.Error(errorMessage = errorMessage, error = null)
|
||||
mutableSendDataStateFlow.value = DataState.Loaded(mockSendView)
|
||||
val viewModel = createViewModel(initialState, AddSendType.EditItem(sendId))
|
||||
|
||||
@@ -493,7 +493,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
||||
val sendId = "mockId-1"
|
||||
coEvery {
|
||||
vaultRepository.removePasswordSend(sendId)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null, error = null)
|
||||
val initialState = DEFAULT_STATE.copy(
|
||||
addSendType = AddSendType.EditItem(sendItemId = sendId),
|
||||
)
|
||||
@@ -542,7 +542,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
||||
val errorMessage = "Fail"
|
||||
coEvery {
|
||||
vaultRepository.removePasswordSend(sendId)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = errorMessage)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = errorMessage, error = null)
|
||||
val mockSendView = createMockSendView(number = 1)
|
||||
every {
|
||||
mockSendView.toViewState(
|
||||
@@ -608,8 +608,11 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `DeleteClick vaultRepository deleteSend Error should show error dialog`() = runTest {
|
||||
val error = Throwable("Ooops")
|
||||
val sendId = "mockId-1"
|
||||
coEvery { vaultRepository.deleteSend(sendId) } returns DeleteSendResult.Error
|
||||
coEvery { vaultRepository.deleteSend(sendId) } returns DeleteSendResult.Error(
|
||||
error = error,
|
||||
)
|
||||
val initialState = DEFAULT_STATE.copy(
|
||||
addSendType = AddSendType.EditItem(sendItemId = sendId),
|
||||
)
|
||||
@@ -643,6 +646,7 @@ class AddSendViewModelTest : BaseViewModelTest() {
|
||||
dialogState = AddSendState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = error,
|
||||
),
|
||||
),
|
||||
awaitItem(),
|
||||
|
||||
+8
-2
@@ -1232,7 +1232,10 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
fun `OverflowOptionClick Send DeleteClick with deleteSend error should display error dialog`() =
|
||||
runTest {
|
||||
val sendId = "sendId1234"
|
||||
coEvery { vaultRepository.deleteSend(sendId) } returns DeleteSendResult.Error
|
||||
val error = Throwable("Oops")
|
||||
coEvery { vaultRepository.deleteSend(sendId) } returns DeleteSendResult.Error(
|
||||
error = error,
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
viewModel.stateFlow.test {
|
||||
@@ -1255,6 +1258,7 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
dialogState = VaultItemListingState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = error,
|
||||
),
|
||||
),
|
||||
awaitItem(),
|
||||
@@ -1301,9 +1305,10 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
fun `OverflowOptionClick Send RemovePasswordClick with removePasswordSend error should display error dialog`() =
|
||||
runTest {
|
||||
val sendId = "sendId1234"
|
||||
val error = Throwable("Oops")
|
||||
coEvery {
|
||||
vaultRepository.removePasswordSend(sendId)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null)
|
||||
} returns RemovePasswordSendResult.Error(errorMessage = null, error = error)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
viewModel.stateFlow.test {
|
||||
@@ -1326,6 +1331,7 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
dialogState = VaultItemListingState.DialogState.Error(
|
||||
title = R.string.an_error_has_occurred.asText(),
|
||||
message = R.string.generic_error_message.asText(),
|
||||
throwable = error,
|
||||
),
|
||||
),
|
||||
awaitItem(),
|
||||
|
||||
Reference in New Issue
Block a user