From 819c8d14ed32785995ba8a42bdac80a8d9f2c557 Mon Sep 17 00:00:00 2001 From: Zach Smith Date: Thu, 19 Jul 2018 15:57:53 +0800 Subject: Validate phone numbers when parsing from JSON (#183) * Validate phone numbers when parsing from JSON * Change to intercept for test --- src/main/scala/xyz/driver/core/domain.scala | 10 ++-------- src/main/scala/xyz/driver/core/json.scala | 8 +++++++- src/test/scala/xyz/driver/core/JsonTest.scala | 8 ++++++++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/scala/xyz/driver/core/domain.scala b/src/main/scala/xyz/driver/core/domain.scala index fa3b5c4..59bed54 100644 --- a/src/main/scala/xyz/driver/core/domain.scala +++ b/src/main/scala/xyz/driver/core/domain.scala @@ -32,14 +32,8 @@ object domain { private val phoneUtil = PhoneNumberUtil.getInstance() def parse(phoneNumber: String): Option[PhoneNumber] = { - val phone = scala.util.Try(phoneUtil.parseAndKeepRawInput(phoneNumber, "US")).toOption - - val validated = phone match { - case None => None - case Some(pn) => - if (!phoneUtil.isValidNumber(pn)) None - else Some(pn) - } + val validated = + util.Try(phoneUtil.parseAndKeepRawInput(phoneNumber, "US")).toOption.filter(phoneUtil.isValidNumber) validated.map(pn => PhoneNumber(pn.getCountryCode.toString, pn.getNationalNumber.toString)) } } diff --git a/src/main/scala/xyz/driver/core/json.scala b/src/main/scala/xyz/driver/core/json.scala index de1df31..959239e 100644 --- a/src/main/scala/xyz/driver/core/json.scala +++ b/src/main/scala/xyz/driver/core/json.scala @@ -186,7 +186,13 @@ object json { } } - implicit val phoneNumberFormat = jsonFormat2(PhoneNumber.apply) + implicit object phoneNumberFormat extends RootJsonFormat[PhoneNumber] { + private val basicFormat = jsonFormat2(PhoneNumber.apply) + override def write(obj: PhoneNumber): JsValue = basicFormat.write(obj) + override def read(json: JsValue): PhoneNumber = { + PhoneNumber.parse(basicFormat.read(json).toString).getOrElse(deserializationError("Invalid phone number")) + } + } implicit val authCredentialsFormat = new RootJsonFormat[AuthCredentials] { override def read(json: JsValue): AuthCredentials = { diff --git a/src/test/scala/xyz/driver/core/JsonTest.scala b/src/test/scala/xyz/driver/core/JsonTest.scala index fed2a9d..2c85560 100644 --- a/src/test/scala/xyz/driver/core/JsonTest.scala +++ b/src/test/scala/xyz/driver/core/JsonTest.scala @@ -135,6 +135,14 @@ class JsonTest extends FlatSpec with Matchers { parsedPhoneNumber should be(referencePhoneNumber) } + it should "reject an invalid phone number" in { + val phoneJson = """{"countryCode":"1","number":"111-111-1113"}""".parseJson + + intercept[DeserializationException] { + json.phoneNumberFormat.read(phoneJson) + }.getMessage shouldBe "Invalid phone number" + } + "Json format for ADT mappings" should "read and write correct JSON" in { sealed trait EnumVal -- cgit v1.2.3