mirror of
https://github.com/bitwarden/android.git
synced 2024-11-21 08:55:48 +03:00
PM-15025: Update sendVerificationEmail to handle error responses (#4336)
This commit is contained in:
parent
d418444dc0
commit
5ea17700b3
5 changed files with 62 additions and 10 deletions
|
@ -9,6 +9,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequ
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorDataModel
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorDataModel
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenResponseJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenResponseJson
|
||||||
|
@ -68,7 +69,7 @@ interface IdentityService {
|
||||||
*/
|
*/
|
||||||
suspend fun sendVerificationEmail(
|
suspend fun sendVerificationEmail(
|
||||||
body: SendVerificationEmailRequestJson,
|
body: SendVerificationEmailRequestJson,
|
||||||
): Result<String?>
|
): Result<SendVerificationEmailResponseJson>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a new account to Bitwarden using email verification flow.
|
* Register a new account to Bitwarden using email verification flow.
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequ
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorDataModel
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorDataModel
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenResponseJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyEmailTokenResponseJson
|
||||||
|
@ -132,11 +133,20 @@ class IdentityServiceImpl(
|
||||||
|
|
||||||
override suspend fun sendVerificationEmail(
|
override suspend fun sendVerificationEmail(
|
||||||
body: SendVerificationEmailRequestJson,
|
body: SendVerificationEmailRequestJson,
|
||||||
): Result<String?> {
|
): Result<SendVerificationEmailResponseJson> {
|
||||||
return unauthenticatedIdentityApi
|
return unauthenticatedIdentityApi
|
||||||
.sendVerificationEmail(body = body)
|
.sendVerificationEmail(body = body)
|
||||||
.toResult()
|
.toResult()
|
||||||
.map { it?.content }
|
.map { SendVerificationEmailResponseJson.Success(it?.content) }
|
||||||
|
.recoverCatching { throwable ->
|
||||||
|
throwable
|
||||||
|
.toBitwardenError()
|
||||||
|
.parseErrorBodyOrNull<SendVerificationEmailResponseJson.Invalid>(
|
||||||
|
code = 400,
|
||||||
|
json = json,
|
||||||
|
)
|
||||||
|
?: throw throwable
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun verifyEmailRegistrationToken(
|
override suspend fun verifyEmailRegistrationToken(
|
||||||
|
|
|
@ -22,6 +22,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJs
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
|
||||||
|
@ -1282,7 +1283,15 @@ class AuthRepositoryImpl(
|
||||||
)
|
)
|
||||||
.fold(
|
.fold(
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
SendVerificationEmailResult.Success(it)
|
when (it) {
|
||||||
|
is SendVerificationEmailResponseJson.Invalid -> {
|
||||||
|
SendVerificationEmailResult.Error(it.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
is SendVerificationEmailResponseJson.Success -> {
|
||||||
|
SendVerificationEmailResult.Success(it.emailVerificationToken)
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onFailure = {
|
onFailure = {
|
||||||
SendVerificationEmailResult.Error(null)
|
SendVerificationEmailResult.Error(null)
|
||||||
|
|
|
@ -13,6 +13,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterFinishRequ
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.UserDecryptionOptionsJson
|
||||||
|
@ -370,14 +371,19 @@ class IdentityServiceTest : BaseServiceTest() {
|
||||||
runTest {
|
runTest {
|
||||||
server.enqueue(MockResponse().setResponseCode(200).setBody(EMAIL_TOKEN))
|
server.enqueue(MockResponse().setResponseCode(200).setBody(EMAIL_TOKEN))
|
||||||
val result = identityService.sendVerificationEmail(SEND_VERIFICATION_EMAIL_REQUEST)
|
val result = identityService.sendVerificationEmail(SEND_VERIFICATION_EMAIL_REQUEST)
|
||||||
assertEquals(JsonPrimitive(EMAIL_TOKEN).content.asSuccess(), result)
|
assertEquals(
|
||||||
|
SendVerificationEmailResponseJson
|
||||||
|
.Success(JsonPrimitive(EMAIL_TOKEN).content)
|
||||||
|
.asSuccess(),
|
||||||
|
result,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `sendVerificationEmail should return null when response is empty success`() = runTest {
|
fun `sendVerificationEmail should return null when response is empty success`() = runTest {
|
||||||
server.enqueue(MockResponse().setResponseCode(204))
|
server.enqueue(MockResponse().setResponseCode(204))
|
||||||
val result = identityService.sendVerificationEmail(SEND_VERIFICATION_EMAIL_REQUEST)
|
val result = identityService.sendVerificationEmail(SEND_VERIFICATION_EMAIL_REQUEST)
|
||||||
assertEquals(null.asSuccess(), result)
|
assertEquals(SendVerificationEmailResponseJson.Success(null).asSuccess(), result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -422,7 +428,6 @@ class IdentityServiceTest : BaseServiceTest() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("MaxLineLength")
|
|
||||||
@Test
|
@Test
|
||||||
fun `verifyEmailToken should return Invalid when response message is non expired error`() =
|
fun `verifyEmailToken should return Invalid when response message is non expired error`() =
|
||||||
runTest {
|
runTest {
|
||||||
|
|
|
@ -38,6 +38,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.RegisterResponseJs
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SendVerificationEmailResponseJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TrustedDeviceUserDecryptionOptionsJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.TwoFactorAuthMethod
|
||||||
|
@ -6043,7 +6044,7 @@ class AuthRepositoryTest {
|
||||||
receiveMarketingEmails = true,
|
receiveMarketingEmails = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} returns EMAIL_VERIFICATION_TOKEN.asSuccess()
|
} returns SendVerificationEmailResponseJson.Success(EMAIL_VERIFICATION_TOKEN).asSuccess()
|
||||||
|
|
||||||
val result = repository.sendVerificationEmail(
|
val result = repository.sendVerificationEmail(
|
||||||
email = EMAIL,
|
email = EMAIL,
|
||||||
|
@ -6056,6 +6057,32 @@ class AuthRepositoryTest {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `sendVerificationEmail success with invalid email should return error`() = runTest {
|
||||||
|
val errorMessage = "Failure"
|
||||||
|
coEvery {
|
||||||
|
identityService.sendVerificationEmail(
|
||||||
|
SendVerificationEmailRequestJson(
|
||||||
|
email = EMAIL,
|
||||||
|
name = NAME,
|
||||||
|
receiveMarketingEmails = true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns SendVerificationEmailResponseJson
|
||||||
|
.Invalid(invalidMessage = errorMessage, validationErrors = null)
|
||||||
|
.asSuccess()
|
||||||
|
|
||||||
|
val result = repository.sendVerificationEmail(
|
||||||
|
email = EMAIL,
|
||||||
|
name = NAME,
|
||||||
|
receiveMarketingEmails = true,
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
SendVerificationEmailResult.Error(errorMessage = errorMessage),
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `sendVerificationEmail failure should return success if body null`() = runTest {
|
fun `sendVerificationEmail failure should return success if body null`() = runTest {
|
||||||
coEvery {
|
coEvery {
|
||||||
|
@ -6066,7 +6093,7 @@ class AuthRepositoryTest {
|
||||||
receiveMarketingEmails = true,
|
receiveMarketingEmails = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} returns null.asSuccess()
|
} returns SendVerificationEmailResponseJson.Success(null).asSuccess()
|
||||||
|
|
||||||
val result = repository.sendVerificationEmail(
|
val result = repository.sendVerificationEmail(
|
||||||
email = EMAIL,
|
email = EMAIL,
|
||||||
|
@ -6089,7 +6116,7 @@ class AuthRepositoryTest {
|
||||||
receiveMarketingEmails = true,
|
receiveMarketingEmails = true,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
} returns EMAIL_VERIFICATION_TOKEN.asSuccess()
|
} returns SendVerificationEmailResponseJson.Success(EMAIL_VERIFICATION_TOKEN).asSuccess()
|
||||||
|
|
||||||
val result = repository.sendVerificationEmail(
|
val result = repository.sendVerificationEmail(
|
||||||
email = EMAIL,
|
email = EMAIL,
|
||||||
|
|
Loading…
Reference in a new issue