diff --git a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt index 7f176eb3ff..16de6cefe0 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryImpl.kt @@ -900,7 +900,10 @@ class AuthRepositoryImpl( is RegisterResponseJson.CaptchaRequired -> { it.validationErrors.captchaKeys.firstOrNull() ?.let { key -> RegisterResult.CaptchaRequired(captchaId = key) } - ?: RegisterResult.Error(errorMessage = null) + ?: RegisterResult.Error( + errorMessage = null, + error = MissingPropertyException("Captcha ID"), + ) } is RegisterResponseJson.Success -> { @@ -909,11 +912,11 @@ class AuthRepositoryImpl( } is RegisterResponseJson.Invalid -> { - RegisterResult.Error(errorMessage = it.message) + RegisterResult.Error(errorMessage = it.message, error = null) } } }, - onFailure = { RegisterResult.Error(errorMessage = null) }, + onFailure = { RegisterResult.Error(errorMessage = null, error = it) }, ) } diff --git a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/RegisterResult.kt b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/RegisterResult.kt index 5182e5d289..f49f2cdc67 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/RegisterResult.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/auth/repository/model/RegisterResult.kt @@ -23,7 +23,10 @@ sealed class RegisterResult { * * @param errorMessage a message describing the error. */ - data class Error(val errorMessage: String?) : RegisterResult() + data class Error( + val errorMessage: String?, + val error: Throwable?, + ) : RegisterResult() /** * Password hash was found in a data breach. diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationScreen.kt index 8bb32ecf05..760ce8ab18 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationScreen.kt @@ -108,6 +108,7 @@ fun CompleteRegistrationScreen( BitwardenBasicDialog( title = dialog.title?.invoke(), message = dialog.message(), + throwable = dialog.error, onDismissRequest = handler.onDismissErrorDialog, ) } @@ -141,7 +142,8 @@ fun CompleteRegistrationScreen( title = stringResource( id = R.string.create_account .takeIf { state.onboardingEnabled } - ?: R.string.set_password), + ?: R.string.set_password, + ), scrollBehavior = scrollBehavior, navigationIcon = rememberVectorPainter(id = R.drawable.ic_back), navigationIconContentDescription = stringResource(id = R.string.back), diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModel.kt index daf6f53f2d..1e2721128b 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModel.kt @@ -210,6 +210,7 @@ class CompleteRegistrationViewModel @Inject constructor( title = R.string.an_error_has_occurred.asText(), message = registerAccountResult.errorMessage?.asText() ?: R.string.generic_error_message.asText(), + error = registerAccountResult.error, ), ) } @@ -525,6 +526,7 @@ sealed class CompleteRegistrationDialog : Parcelable { data class Error( val title: Text?, val message: Text, + val error: Throwable? = null, ) : CompleteRegistrationDialog() } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountScreen.kt index 58768f67c2..b271ef6863 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountScreen.kt @@ -116,6 +116,7 @@ fun CreateAccountScreen( BitwardenBasicDialog( title = dialog.title?.invoke(), message = dialog.message(), + throwable = dialog.error, onDismissRequest = remember(viewModel) { { viewModel.trySendAction(ErrorDialogDismiss) } }, diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModel.kt index 5ff48cfe49..a2ce58891c 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModel.kt @@ -180,6 +180,7 @@ class CreateAccountViewModel @Inject constructor( title = R.string.an_error_has_occurred.asText(), message = registerAccountResult.errorMessage?.asText() ?: R.string.generic_error_message.asText(), + error = registerAccountResult.error, ), ) } @@ -464,6 +465,7 @@ sealed class CreateAccountDialog : Parcelable { data class Error( val title: Text?, val message: Text, + val error: Throwable? = null, ) : CreateAccountDialog() } diff --git a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt index adde4a5150..d6f4462bd6 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/auth/repository/AuthRepositoryTest.kt @@ -4276,7 +4276,13 @@ class AuthRepositoryTest { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - assertEquals(RegisterResult.Error(errorMessage = null), result) + assertEquals( + RegisterResult.Error( + errorMessage = null, + error = MissingPropertyException("Captcha ID"), + ), + result, + ) } @Test @@ -4322,6 +4328,7 @@ class AuthRepositoryTest { @Test fun `register Failure should return Error with no message`() = runTest { + val error = RuntimeException() coEvery { identityService.preLogin(EMAIL) } returns PRE_LOGIN_SUCCESS.asSuccess() coEvery { identityService.register( @@ -4339,7 +4346,7 @@ class AuthRepositoryTest { kdfIterations = DEFAULT_KDF_ITERATIONS.toUInt(), ), ) - } returns RuntimeException().asFailure() + } returns error.asFailure() val result = repository.register( email = EMAIL, @@ -4349,7 +4356,7 @@ class AuthRepositoryTest { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - assertEquals(RegisterResult.Error(errorMessage = null), result) + assertEquals(RegisterResult.Error(errorMessage = null, error = error), result) } @Test @@ -4383,7 +4390,7 @@ class AuthRepositoryTest { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - assertEquals(RegisterResult.Error(errorMessage = "message"), result) + assertEquals(RegisterResult.Error(errorMessage = "message", error = null), result) } @Test @@ -4420,7 +4427,7 @@ class AuthRepositoryTest { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - assertEquals(RegisterResult.Error(errorMessage = "expected"), result) + assertEquals(RegisterResult.Error(errorMessage = "expected", error = null), result) } @Test diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModelTest.kt index d411a8685d..24ba610e6b 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/completeregistration/CompleteRegistrationViewModelTest.kt @@ -178,6 +178,7 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() { @Test fun `CallToActionClick register returns error should update errorDialogState`() = runTest { + val error = Throwable("Fail!") coEvery { mockAuthRepository.register( email = EMAIL, @@ -188,7 +189,7 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - } returns RegisterResult.Error(errorMessage = "mock_error") + } returns RegisterResult.Error(errorMessage = "mock_error", error = error) val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE) viewModel.stateFlow.test { assertEquals(VALID_INPUT_STATE, awaitItem()) @@ -202,6 +203,7 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() { dialog = CompleteRegistrationDialog.Error( title = R.string.an_error_has_occurred.asText(), message = "mock_error".asText(), + error = error, ), ), awaitItem(), @@ -273,7 +275,7 @@ class CompleteRegistrationViewModelTest : BaseViewModelTest() { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - } returns RegisterResult.Error(null) + } returns RegisterResult.Error(errorMessage = null, error = null) val viewModel = createCompleteRegistrationViewModel(VALID_INPUT_STATE) viewModel.trySendAction(CompleteRegistrationAction.ContinueWithBreachedPasswordClick) coVerify { diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModelTest.kt index cbdd366b13..c4035ea9f9 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/auth/feature/createaccount/CreateAccountViewModelTest.kt @@ -252,6 +252,7 @@ class CreateAccountViewModelTest : BaseViewModelTest() { @Test fun `SubmitClick register returns error should update errorDialogState`() = runTest { + val error = Throwable("Fail!") val repo = mockk { every { captchaTokenResultFlow } returns flowOf() coEvery { @@ -263,7 +264,7 @@ class CreateAccountViewModelTest : BaseViewModelTest() { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - } returns RegisterResult.Error(errorMessage = "mock_error") + } returns RegisterResult.Error(errorMessage = "mock_error", error = error) } val viewModel = CreateAccountViewModel( savedStateHandle = validInputHandle, @@ -281,6 +282,7 @@ class CreateAccountViewModelTest : BaseViewModelTest() { dialog = CreateAccountDialog.Error( title = R.string.an_error_has_occurred.asText(), message = "mock_error".asText(), + error = error, ), ), awaitItem(), @@ -368,7 +370,7 @@ class CreateAccountViewModelTest : BaseViewModelTest() { shouldCheckDataBreaches = false, isMasterPasswordStrong = true, ) - } returns RegisterResult.Error(null) + } returns RegisterResult.Error(errorMessage = null, error = null) } val viewModel = CreateAccountViewModel( savedStateHandle = validInputHandle,