aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Nastich <nastich@users.noreply.github.com>2018-03-28 18:10:50 -0400
committerGitHub <noreply@github.com>2018-03-28 18:10:50 -0400
commit322bbc9010e20195e5b0bb58e703961738ffb89d (patch)
treeb02f345abd0fb1447b171e6df81b3b3dd883bbd6
parentfc6ecfe212c84271a3454617054aaf25890e886a (diff)
parentd35332b7e67d6ae6bea3fd50b9405b554a18b491 (diff)
downloaddriver-core-322bbc9010e20195e5b0bb58e703961738ffb89d.tar.gz
driver-core-322bbc9010e20195e5b0bb58e703961738ffb89d.tar.bz2
driver-core-322bbc9010e20195e5b0bb58e703961738ffb89d.zip
Merge pull request #143 from drivergroup/improve-phone-number-parsing
SCALA-20 Add ability to parse and store chinese phone numbers (and other countries)
-rw-r--r--build.sbt37
-rw-r--r--src/main/scala/xyz/driver/core/domain.scala18
-rw-r--r--src/test/scala/xyz/driver/core/PhoneNumberTest.scala79
3 files changed, 106 insertions, 28 deletions
diff --git a/build.sbt b/build.sbt
index 9f878f1..88e4582 100644
--- a/build.sbt
+++ b/build.sbt
@@ -7,22 +7,23 @@ lazy val core = (project in file("."))
.driverLibrary("core")
.settings(lintingSettings ++ formatSettings)
.settings(libraryDependencies ++= Seq(
- "xyz.driver" %% "tracing" % "0.0.2",
- "com.typesafe.akka" %% "akka-http-core" % akkaHttpV,
- "com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpV,
- "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpV,
- "com.pauldijou" %% "jwt-core" % "0.14.0",
- "org.scalatest" %% "scalatest" % "3.0.2" % "test",
- "org.scalacheck" %% "scalacheck" % "1.13.4" % "test",
- "org.scalaz" %% "scalaz-core" % "7.2.19",
- "org.mockito" % "mockito-core" % "1.9.5" % "test",
- "com.github.swagger-akka-http" %% "swagger-akka-http" % "0.11.2",
- "com.amazonaws" % "aws-java-sdk-s3" % "1.11.26",
- "com.google.cloud" % "google-cloud-pubsub" % "0.25.0-beta",
- "com.google.cloud" % "google-cloud-storage" % "1.7.0",
- "com.typesafe.slick" %% "slick" % "3.2.1",
- "com.typesafe" % "config" % "1.3.1",
- "com.typesafe.scala-logging" %% "scala-logging" % "3.5.0",
- "eu.timepit" %% "refined" % "0.8.4",
- "ch.qos.logback" % "logback-classic" % "1.1.11"
+ "xyz.driver" %% "tracing" % "0.0.2",
+ "com.typesafe.akka" %% "akka-http-core" % akkaHttpV,
+ "com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpV,
+ "com.typesafe.akka" %% "akka-http-testkit" % akkaHttpV,
+ "com.pauldijou" %% "jwt-core" % "0.14.0",
+ "org.scalatest" %% "scalatest" % "3.0.2" % "test",
+ "org.scalacheck" %% "scalacheck" % "1.13.4" % "test",
+ "org.scalaz" %% "scalaz-core" % "7.2.19",
+ "com.github.swagger-akka-http" %% "swagger-akka-http" % "0.11.2",
+ "com.typesafe.scala-logging" %% "scala-logging" % "3.5.0",
+ "eu.timepit" %% "refined" % "0.8.4",
+ "com.typesafe.slick" %% "slick" % "3.2.1",
+ "org.mockito" % "mockito-core" % "1.9.5" % "test",
+ "com.amazonaws" % "aws-java-sdk-s3" % "1.11.26",
+ "com.google.cloud" % "google-cloud-pubsub" % "0.25.0-beta",
+ "com.google.cloud" % "google-cloud-storage" % "1.7.0",
+ "com.typesafe" % "config" % "1.3.1",
+ "ch.qos.logback" % "logback-classic" % "1.1.11",
+ "com.googlecode.libphonenumber" % "libphonenumber" % "8.9.2"
))
diff --git a/src/main/scala/xyz/driver/core/domain.scala b/src/main/scala/xyz/driver/core/domain.scala
index 48943a7..7731345 100644
--- a/src/main/scala/xyz/driver/core/domain.scala
+++ b/src/main/scala/xyz/driver/core/domain.scala
@@ -1,13 +1,14 @@
package xyz.driver.core
+import com.google.i18n.phonenumbers.PhoneNumberUtil
import scalaz.Equal
-import scalaz.syntax.equal._
import scalaz.std.string._
+import scalaz.syntax.equal._
object domain {
final case class Email(username: String, domain: String) {
- override def toString = username + "@" + domain
+ override def toString: String = username + "@" + domain
}
object Email {
@@ -27,16 +28,13 @@ object domain {
}
object PhoneNumber {
- def parse(phoneNumberString: String): Option[PhoneNumber] = {
- val onlyDigits = phoneNumberString.replaceAll("[^\\d.]", "")
- if (onlyDigits.length < 10) None
- else {
- val tenDigitNumber = onlyDigits.takeRight(10)
- val countryCode = Option(onlyDigits.dropRight(10)).filter(_.nonEmpty).getOrElse("1")
+ private val phoneUtil = PhoneNumberUtil.getInstance()
- Some(PhoneNumber(countryCode, tenDigitNumber))
- }
+ def parse(phoneNumber: String): Option[PhoneNumber] = {
+ val phone = phoneUtil.parseAndKeepRawInput(phoneNumber, "US")
+ if (!phoneUtil.isValidNumber(phone)) None
+ else Some(PhoneNumber(phone.getCountryCode.toString, phone.getNationalNumber.toString))
}
}
}
diff --git a/src/test/scala/xyz/driver/core/PhoneNumberTest.scala b/src/test/scala/xyz/driver/core/PhoneNumberTest.scala
new file mode 100644
index 0000000..384c7be
--- /dev/null
+++ b/src/test/scala/xyz/driver/core/PhoneNumberTest.scala
@@ -0,0 +1,79 @@
+package xyz.driver.core
+
+import org.scalatest.{FlatSpec, Matchers}
+import xyz.driver.core.domain.PhoneNumber
+
+class PhoneNumberTest extends FlatSpec with Matchers {
+
+ "PhoneNumber.parse" should "recognize US numbers in international format, ignoring non-digits" in {
+ // format: off
+ val numbers = List(
+ "+18005252225",
+ "+1 800 525 2225",
+ "+1 (800) 525-2225",
+ "+1.800.525.2225")
+ // format: on
+
+ val parsed = numbers.flatMap(PhoneNumber.parse)
+
+ parsed should have size numbers.size
+ parsed should contain only PhoneNumber("1", "8005252225")
+ }
+
+ it should "recognize US numbers without the plus sign" in {
+ PhoneNumber.parse("18005252225") shouldBe Some(PhoneNumber("1", "8005252225"))
+ }
+
+ it should "recognize US numbers without country code" in {
+ // format: off
+ val numbers = List(
+ "8005252225",
+ "800 525 2225",
+ "(800) 525-2225",
+ "800.525.2225")
+ // format: on
+
+ val parsed = numbers.flatMap(PhoneNumber.parse)
+
+ parsed should have size numbers.size
+ parsed should contain only PhoneNumber("1", "8005252225")
+ }
+
+ it should "recognize CN numbers in international format" in {
+ PhoneNumber.parse("+868005252225") shouldBe Some(PhoneNumber("86", "8005252225"))
+ PhoneNumber.parse("+86 134 52 52 2256") shouldBe Some(PhoneNumber("86", "13452522256"))
+ }
+
+ it should "return None on numbers that are shorter than the minimum number of digits for the country (i.e. US - 10, AR - 11)" in {
+ withClue("US and CN numbers are 10 digits - 9 digit (and shorter) numbers should not fit") {
+ // format: off
+ val numbers = List(
+ "+1 800 525-222",
+ "+1 800 525-2",
+ "+86 800 525-222",
+ "+86 800 525-2")
+ // format: on
+
+ numbers.flatMap(PhoneNumber.parse) shouldBe empty
+ }
+
+ withClue("Argentinian numbers are 11 digits (when prefixed with 0) - 10 digit numbers shouldn't fit") {
+ // format: off
+ val numbers = List(
+ "+54 011 525-22256",
+ "+54 011 525-2225",
+ "+54 011 525-222")
+ // format: on
+
+ numbers.flatMap(PhoneNumber.parse) should contain theSameElementsAs List(PhoneNumber("54", "1152522256"))
+ }
+ }
+
+ it should "return None on numbers that are longer than the maximum number of digits for the country (i.e. DK - 8, CN - 11)" in {
+ val numbers = List("+45 27 45 25 22", "+45 135 525 223", "+86 134 525 22256", "+86 135 525 22256 7")
+
+ numbers.flatMap(PhoneNumber.parse) should contain theSameElementsAs
+ List(PhoneNumber("45", "27452522"), PhoneNumber("86", "13452522256"))
+ }
+
+}