From 1083634245edb5b4cf3d9d2cb73e684bfe1442b2 Mon Sep 17 00:00:00 2001 From: Dwight Watson Date: Fri, 22 Dec 2023 19:05:54 +1100 Subject: [PATCH] Allow rejecting certain phone number types (#238) * Allow rejecting certain phone number types * Throw custom exception if allowed and blocked types are both provided --- src/Exceptions/IncompatibleTypesException.php | 11 ++++ src/Rules/Phone.php | 30 ++++++++-- tests/PhoneRuleValidatorTest.php | 55 +++++++++++++++++++ 3 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 src/Exceptions/IncompatibleTypesException.php create mode 100644 tests/PhoneRuleValidatorTest.php diff --git a/src/Exceptions/IncompatibleTypesException.php b/src/Exceptions/IncompatibleTypesException.php new file mode 100644 index 0000000..26eed5c --- /dev/null +++ b/src/Exceptions/IncompatibleTypesException.php @@ -0,0 +1,11 @@ +countries, ]); - $types = PhoneNumberType::sanitize($this->types); + $allowedTypes = PhoneNumberType::sanitize($this->allowedTypes); + $blockedTypes = PhoneNumberType::sanitize($this->blockedTypes); try { $phone = (new PhoneNumber($value, $countries))->lenient($this->lenient); @@ -43,8 +47,17 @@ public function passes($attribute, $value) return false; } + if (! empty($allowedTypes) && ! empty($blockedTypes)) { + throw IncompatibleTypesException::invalid(); + } + // Is the type within the allowed list (if applicable)? - if (! empty($types) && ! $phone->isOfType($types)) { + if (! empty($allowedTypes) && ! $phone->isOfType($allowedTypes)) { + return false; + } + + // Is the type within the blocked list (if applicable)? + if (! empty($blockedTypes) && $phone->isOfType($blockedTypes)) { return false; } @@ -74,7 +87,16 @@ public function type($type) { $types = is_array($type) ? $type : func_get_args(); - $this->types = array_merge($this->types, $types); + $this->allowedTypes = array_merge($this->allowedTypes, $types); + + return $this; + } + + public function notType($type) + { + $types = is_array($type) ? $type : func_get_args(); + + $this->blockedTypes = array_merge($this->blockedTypes, $types); return $this; } diff --git a/tests/PhoneRuleValidatorTest.php b/tests/PhoneRuleValidatorTest.php new file mode 100644 index 0000000..018d4fe --- /dev/null +++ b/tests/PhoneRuleValidatorTest.php @@ -0,0 +1,55 @@ +app['validator']->make($data, $rules); + } + + /** @test */ + public function it_validates_type() + { + $this->assertTrue($this->validate( + ['field' => '+32470123456'], + ['field' => (new Phone)->type(PhoneNumberType::MOBILE)] + )->passes()); + + $this->assertFalse($this->validate( + ['field' => '+3212345678'], + ['field' => (new Phone)->type(PhoneNumberType::MOBILE)] + )->passes()); + } + + /** @test */ + public function it_validates_negative_type() + { + $this->assertFalse($this->validate( + ['field' => '+32470123456'], + ['field' => (new Phone)->notType(PhoneNumberType::MOBILE)] + )->passes()); + + $this->assertTrue($this->validate( + ['field' => '+3212345678'], + ['field' => (new Phone)->notType(PhoneNumberType::MOBILE)] + )->passes()); + } + + /** @test */ + public function it_doesnt_allow_type_and_not_type() + { + $this->expectException(IncompatibleTypesException::class); + + $this->validate( + ['field' => '+3212345678'], + ['field' => (new Phone)->type(PhoneNumberType::MOBILE)->notType(PhoneNumberType::MOBILE)] + )->passes(); + } +} \ No newline at end of file