Compare commits

...

25 Commits

Author SHA1 Message Date
Lode Claassen 8790f59415 DNS check should convert unicode domains first (#166)
* fix checkdnsrr not handling unicode domains properly

* fix for php7.2
2018-04-10 12:11:19 +02:00
masterwto 114b663f20 Update SpoofCheckValidation.php (#163)
removing spaces
2018-01-16 18:13:22 +01:00
Gabriel Caruso a0e0fadfce Use dedicated PHPUnit assertion methods (#159) 2018-01-05 23:47:59 +01:00
Robbert 74c0f07434 Clarification fix (#162)
You implement an interface.
2018-01-05 23:40:27 +01:00
Rotzbua ad1a0e9773 Update README.md (#157)
changed links from http to https if supported
2017-11-23 01:15:37 +01:00
Rotzbua aeb6851388 Update Other.md (#158)
change links from http to https if supported
2017-11-23 01:15:20 +01:00
Remi Collet a23fcc1315 Improve test requirements and add versions to test matrix
* allow phpunit 5.7 and 6

* add PHP 7.1 and 7.2 to travis
2017-11-17 00:41:28 +01:00
Gabriel Caruso 1bec00a100 Use PHPUnit\Framework\TestCase instead of PHPUnit_Framework_TestCase (#155)
* Use PHPUnit\Framework\TestCase instead of PHPUnit_Framework_TestCase

* Use installed PHPUnit version not global
2017-11-16 00:40:40 +01:00
Santiago Castro 3abad65421 Fix broken Markdown headings (#149) 2017-04-18 23:06:35 +02:00
Dany Maillard 3fdfa261ad Remove duplicat < and > char value (#147) 2017-04-13 10:55:46 +02:00
Christian Flothmann 14ca3785c1 improve feedback on missing Intl extension (#143) 2017-03-02 11:09:01 +01:00
Eduardo Gulias Davis bc31baa11e Le shadow master (#139)
* Compatibility with RFC 2181

According to RFC2181, every DNS query needs to have a . at the end of
the name record you are requesting.

This will show that that name record is the root of the domain you are
asking
In some cases, when the . is missing, the hostname of the server the
code is running on will be appended to the name record when
checkdnsrr() is being executed and this will in turn return a false
positive when there is a wildcard DNS record for the root domain of the
hostname of the server.

* Test deprecation warnings removed
2017-01-30 23:07:36 +01:00
Simone c0c888ae10 removes trailing spaces (#136) 2017-01-25 22:45:20 +01:00
gjenjoying 181a2fc726 update readme (#135)
* update readme

use Egulias\EmailValidator\Validation\RFCValidation  is required.
2016-12-15 20:18:15 +01:00
Alf Eaton a1e85fa9fb Fix NoRFCWarningsValidation name in README (#134) 2016-11-10 20:04:43 +01:00
BradChesney79 7ff8caaae5 Update composer.json to use the right extension string (#127)
By using
"ext-intl": "*"
in the require block, the suggestion will be hidden if it is already available. ext/php-intl has few google search results and will confuse less knowledgeable users.
2016-08-16 00:24:12 +02:00
Eduardo Gulias Davis 5d56347ddf Typo 2016-08-07 23:26:30 +02:00
Eduardo Gulias Davis 80ad87acdd Update composer instructions 2016-08-07 23:25:34 +02:00
Eduardo Gulias Davis 30562b69fc Merge branch 'taz77-correct-readme-php-example-code-php-dependencies' 2016-08-07 23:18:59 +02:00
Eduardo Gulias Davis cbb8b9e152 PHPStorm help and composer suggestion 2016-08-07 23:16:06 +02:00
Eduardo Gulias Davis cf670406e5 Merge branch 'correct-readme-php-example-code-php-dependencies' of https://github.com/taz77/EmailValidator into taz77-correct-readme-php-example-code-php-dependencies 2016-08-07 23:11:36 +02:00
Issei.M 4d446bf971 NoRFCWarningsValidation now has an InvalidEmail instance if invalid email is passed (#126)
* NoRFCWarningsValidation now has an InvalidEmail instance if invalid email is passed

* fix mentioned point
2016-08-03 22:42:12 +02:00
Issei.M 4f0f9023f0 MultipleValidationWithAnd::getError() now returns NULL if no errors (#124)
* MultipleValidationWithAnd::getError() now returns NULL if no errors

* improve adding error logic

* reword something, add tips

* fix CS
remove wrong tips
2016-07-29 22:43:15 +02:00
Brady 9160e26b13 List and links
Turned requirements into an unordered list. Removed the PHPstorm logo as it doesn't exist and could not find one to replace it.
2016-07-19 06:49:04 +02:00
Brady eb036b7d1c Correct PHP example. Add a requirements section.
Corrected PHP example for missing semi-colons. Added a new requirements section that explains the need for composer and the need of the PHP Intl library to use the spoof validation.
2016-07-18 11:55:21 +02:00
28 changed files with 234 additions and 1779 deletions
+1
View File
@@ -1,2 +1,3 @@
report/ report/
vendor/ vendor/
.idea
+3 -2
View File
@@ -6,6 +6,8 @@ php:
- 5.5 - 5.5
- 5.6 - 5.6
- 7.0 - 7.0
- 7.1
- 7.2
- hhvm - hhvm
env: env:
@@ -27,8 +29,7 @@ install:
script: script:
- mkdir -p build/logs - mkdir -p build/logs
- phpunit --coverage-clover build/logs/clover.xml - vendor/bin/phpunit --coverage-clover build/logs/clover.xml
after_script: after_script:
- php vendor/bin/coveralls - php vendor/bin/coveralls
-2
View File
@@ -67,8 +67,6 @@ class EmailLexer extends AbstractLexer
"\n" => self::S_LF, "\n" => self::S_LF,
"\r\n" => self::CRLF, "\r\n" => self::CRLF,
'IPv6' => self::S_IPV6TAG, 'IPv6' => self::S_IPV6TAG,
'<' => self::S_LOWERTHAN,
'>' => self::S_GREATERTHAN,
'{' => self::S_OPENQBRACKET, '{' => self::S_OPENQBRACKET,
'}' => self::S_CLOSEQBRACKET, '}' => self::S_CLOSEQBRACKET,
'' => self::S_EMPTY, '' => self::S_EMPTY,
+3 -3
View File
@@ -11,7 +11,7 @@ class EmailValidator
* @var EmailLexer * @var EmailLexer
*/ */
private $lexer; private $lexer;
/** /**
* @var array * @var array
*/ */
@@ -21,7 +21,7 @@ class EmailValidator
* @var InvalidEmail * @var InvalidEmail
*/ */
protected $error; protected $error;
public function __construct() public function __construct()
{ {
$this->lexer = new EmailLexer(); $this->lexer = new EmailLexer();
@@ -37,7 +37,7 @@ class EmailValidator
$isValid = $emailValidation->isValid($email, $this->lexer); $isValid = $emailValidation->isValid($email, $this->lexer);
$this->warnings = $emailValidation->getWarnings(); $this->warnings = $emailValidation->getWarnings();
$this->error = $emailValidation->getError(); $this->error = $emailValidation->getError();
return $isValid; return $isValid;
} }
+1 -1
View File
@@ -6,7 +6,7 @@ abstract class InvalidEmail extends \InvalidArgumentException
{ {
const REASON = "Invalid email"; const REASON = "Invalid email";
const CODE = 0; const CODE = 0;
public function __construct() public function __construct()
{ {
parent::__construct(static::REASON, static::CODE); parent::__construct(static::REASON, static::CODE);
+1 -1
View File
@@ -170,7 +170,7 @@ class DomainPart extends Parser
return $domain; return $domain;
} }
private function checkNotAllowedChars($token) private function checkNotAllowedChars($token)
{ {
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true]; $notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
@@ -44,9 +44,11 @@ class DNSCheckValidation implements EmailValidation
protected function checkDNS($host) protected function checkDNS($host)
{ {
$host = rtrim(idn_to_ascii($host, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46), '.') . '.';
$Aresult = true; $Aresult = true;
$MXresult = checkdnsrr($host, 'MX'); $MXresult = checkdnsrr($host, 'MX');
if (!$MXresult) { if (!$MXresult) {
$this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord(); $this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord();
$Aresult = checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA'); $Aresult = checkdnsrr($host, 'A') || checkdnsrr($host, 'AAAA');
+15 -2
View File
@@ -4,18 +4,31 @@ namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\InvalidEmail; use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Warning\Warning;
interface EmailValidation interface EmailValidation
{ {
/**
* Returns true if the given email is valid.
*
* @param string $email The email you want to validate.
* @param EmailLexer $emailLexer The email lexer.
*
* @return bool
*/
public function isValid($email, EmailLexer $emailLexer); public function isValid($email, EmailLexer $emailLexer);
/** /**
* @return InvalidEmail * Returns the validation error.
*
* @return InvalidEmail|null
*/ */
public function getError(); public function getError();
/** /**
* @return array of Warning * Returns the validation warnings.
*
* @return Warning[]
*/ */
public function getWarnings(); public function getWarnings();
} }
@@ -0,0 +1,11 @@
<?php
namespace Egulias\EmailValidator\Validation\Error;
use Egulias\EmailValidator\Exception\InvalidEmail;
class RFCWarnings extends InvalidEmail
{
const CODE = 997;
const REASON = 'Warnings were found.';
}
+2 -2
View File
@@ -12,13 +12,13 @@ class MultipleErrors extends InvalidEmail
* @var array * @var array
*/ */
private $errors = []; private $errors = [];
public function __construct(array $errors) public function __construct(array $errors)
{ {
$this->errors = $errors; $this->errors = $errors;
parent::__construct(); parent::__construct();
} }
public function getErrors() public function getErrors()
{ {
return $this->errors; return $this->errors;
@@ -3,7 +3,6 @@
namespace Egulias\EmailValidator\Validation; namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Validation\Exception\EmptyValidationList; use Egulias\EmailValidator\Validation\Exception\EmptyValidationList;
class MultipleValidationWithAnd implements EmailValidation class MultipleValidationWithAnd implements EmailValidation
@@ -49,7 +48,7 @@ class MultipleValidationWithAnd implements EmailValidation
if (count($validations) == 0) { if (count($validations) == 0) {
throw new EmptyValidationList(); throw new EmptyValidationList();
} }
$this->validations = $validations; $this->validations = $validations;
$this->mode = $mode; $this->mode = $mode;
} }
@@ -65,17 +64,29 @@ class MultipleValidationWithAnd implements EmailValidation
$emailLexer->reset(); $emailLexer->reset();
$result = $result && $validation->isValid($email, $emailLexer); $result = $result && $validation->isValid($email, $emailLexer);
$this->warnings = array_merge($this->warnings, $validation->getWarnings()); $this->warnings = array_merge($this->warnings, $validation->getWarnings());
$errors[] = $validation->getError(); $errors = $this->addNewError($validation->getError(), $errors);
if ($this->shouldStop($result)) { if ($this->shouldStop($result)) {
break; break;
} }
} }
$this->error = new MultipleErrors($errors);
if (!empty($errors)) {
$this->error = new MultipleErrors($errors);
}
return $result; return $result;
} }
private function addNewError($possibleError, array $errors)
{
if (null !== $possibleError) {
$errors[] = $possibleError;
}
return $errors;
}
private function shouldStop($result) private function shouldStop($result)
{ {
return !$result && $this->mode === self::STOP_ON_ERROR; return !$result && $this->mode === self::STOP_ON_ERROR;
@@ -3,11 +3,39 @@
namespace Egulias\EmailValidator\Validation; namespace Egulias\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\InvalidEmail;
use Egulias\EmailValidator\Validation\Error\RFCWarnings;
class NoRFCWarningsValidation extends RFCValidation class NoRFCWarningsValidation extends RFCValidation
{ {
/**
* @var InvalidEmail
*/
private $error;
/**
* {@inheritdoc}
*/
public function isValid($email, EmailLexer $emailLexer) public function isValid($email, EmailLexer $emailLexer)
{ {
return parent::isValid($email, $emailLexer) && empty($this->getWarnings()); if (!parent::isValid($email, $emailLexer)) {
return false;
}
if (empty($this->getWarnings())) {
return true;
}
$this->error = new RFCWarnings();
return false;
}
/**
* {@inheritdoc}
*/
public function getError()
{
return $this->error ?: parent::getError();
} }
} }
+2 -2
View File
@@ -22,7 +22,7 @@ class RFCValidation implements EmailValidation
* @var InvalidEmail * @var InvalidEmail
*/ */
private $error; private $error;
public function isValid($email, EmailLexer $emailLexer) public function isValid($email, EmailLexer $emailLexer)
{ {
$this->parser = new EmailParser($emailLexer); $this->parser = new EmailParser($emailLexer);
@@ -32,7 +32,7 @@ class RFCValidation implements EmailValidation
$this->error = $invalid; $this->error = $invalid;
return false; return false;
} }
$this->warnings = $this->parser->getWarnings(); $this->warnings = $this->parser->getWarnings();
return true; return true;
} }
@@ -14,15 +14,22 @@ class SpoofCheckValidation implements EmailValidation
*/ */
private $error; private $error;
public function __construct()
{
if (!class_exists(Spoofchecker::class)) {
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
}
}
public function isValid($email, EmailLexer $emailLexer) public function isValid($email, EmailLexer $emailLexer)
{ {
$checker = new Spoofchecker(); $checker = new Spoofchecker();
$checker->setChecks(Spoofchecker::SINGLE_SCRIPT); $checker->setChecks(Spoofchecker::SINGLE_SCRIPT);
if ($checker->isSuspicious($email)) { if ($checker->isSuspicious($email)) {
$this->error = new SpoofEmail(); $this->error = new SpoofEmail();
} }
return $this->error === null; return $this->error === null;
} }
+1 -1
View File
@@ -22,7 +22,7 @@ abstract class Warning
{ {
return $this->rfcNumber; return $this->rfcNumber;
} }
public function __toString() public function __toString()
{ {
return $this->message() . " rfc: " . $this->rfcNumber . "interal code: " . static::CODE; return $this->message() . " rfc: " . $this->rfcNumber . "interal code: " . static::CODE;
+23 -18
View File
@@ -1,18 +1,22 @@
#EmailValidator # EmailValidator
[![Build Status](https://travis-ci.org/egulias/EmailValidator.png?branch=master)](https://travis-ci.org/egulias/EmailValidator) [![Coverage Status](https://coveralls.io/repos/egulias/EmailValidator/badge.png?branch=master)](https://coveralls.io/r/egulias/EmailValidator?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6/small.png)](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6) [![Build Status](https://travis-ci.org/egulias/EmailValidator.png?branch=master)](https://travis-ci.org/egulias/EmailValidator) [![Coverage Status](https://coveralls.io/repos/egulias/EmailValidator/badge.png?branch=master)](https://coveralls.io/r/egulias/EmailValidator?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/egulias/EmailValidator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/egulias/EmailValidator/?branch=master) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6/small.png)](https://insight.sensiolabs.com/projects/22ba6692-9c02-42e5-a65d-1c5696bfffc6)
============================= =============================
With the help of With the help of [PHPStorm](https://www.jetbrains.com/phpstorm/)
![Powered by PhpStorm](https://www.jetbrains.com/phpstorm/documentation/docs/logo_phpstorm.png) ## Requirements ##
##Installation##
* [Composer](https://getcomposer.org) is required for installation
* [Spoofchecking](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/SpoofCheckValidation.php) validation requires that your PHP system have the [PHP Internationalization Libraries](https://php.net/manual/en/book.intl.php) (also known as PHP Intl)
## Installation ##
Run the command below to install via Composer Run the command below to install via Composer
```shell ```shell
composer require egulias/email-validator "~2.0" composer require egulias/email-validator "~2.1"
``` ```
##Getting Started## ## Getting Started ##
`EmailValidator`requires you to decide which (or combination of them) validation/s strategy/ies you'd like to follow for each [validation](#available-validations). `EmailValidator`requires you to decide which (or combination of them) validation/s strategy/ies you'd like to follow for each [validation](#available-validations).
A basic example with the RFC validation A basic example with the RFC validation
@@ -20,16 +24,17 @@ A basic example with the RFC validation
<?php <?php
use Egulias\EmailValidator\EmailValidator; use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\RFCValidation;
$validator = new EmailValidator(); $validator = new EmailValidator();
$validator->isValid("example@example.com", new RFCValidation()) //true $validator->isValid("example@example.com", new RFCValidation()); //true
``` ```
###Available validations### ### Available validations ###
1. [RFCValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/RFCValidation.php) 1. [RFCValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/RFCValidation.php)
2. [NoWarningsRFCValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/NoRFCWarningsValidation.php) 2. [NoRFCWarningsValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/NoRFCWarningsValidation.php)
3. [DNSCheckValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/DNSCheckValidation.php) 3. [DNSCheckValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/DNSCheckValidation.php)
4. [SpoofCheckValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/SpoofCheckValidation.php) 4. [SpoofCheckValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/SpoofCheckValidation.php)
5. [MultipleValidationWithAnd](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/MultipleValidationWithAnd.php) 5. [MultipleValidationWithAnd](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/MultipleValidationWithAnd.php)
@@ -51,24 +56,24 @@ $validator = new EmailValidator();
$multipleValidations = new MultipleValidationWithAnd([ $multipleValidations = new MultipleValidationWithAnd([
new RFCValidation(), new RFCValidation(),
new DNSCheckValidation() new DNSCheckValidation()
]) ]);
$validator->isValid("example@example.com", $multipleValidations) //true $validator->isValid("example@example.com", $multipleValidations); //true
``` ```
###How to extend### ### How to extend ###
It's easy! You just need to extend [EmailValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/EmailValidation.php) and you can use your own validation. It's easy! You just need to implement [EmailValidation](https://github.com/egulias/EmailValidator/blob/master/EmailValidator/Validation/EmailValidation.php) and you can use your own validation.
##Other Contributors## ## Other Contributors ##
(You can find current contributors [here](https://github.com/egulias/EmailValidator/graphs/contributors)) (You can find current contributors [here](https://github.com/egulias/EmailValidator/graphs/contributors))
As this is a port from another library and work, here are other people related to the previous one: As this is a port from another library and work, here are other people related to the previous one:
* Ricard Clau [@ricardclau](http://github.com/ricardclau): Performance against PHP built-in filter_var * Ricard Clau [@ricardclau](https://github.com/ricardclau): Performance against PHP built-in filter_var
* Josepf Bielawski [@stloyd](http://github.com/stloyd): For its first re-work of Dominic's lib * Josepf Bielawski [@stloyd](https://github.com/stloyd): For its first re-work of Dominic's lib
* Dominic Sayers [@dominicsayers](http://github.com/dominicsayers): The original isemail function * Dominic Sayers [@dominicsayers](https://github.com/dominicsayers): The original isemail function
##License## ## License ##
Released under the MIT License attached with this code. Released under the MIT License attached with this code.
+2 -1
View File
@@ -3,8 +3,9 @@
namespace Egulias\Tests\EmailValidator; namespace Egulias\Tests\EmailValidator;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use PHPUnit\Framework\TestCase;
class EmailLexerTests extends \PHPUnit_Framework_TestCase class EmailLexerTests extends TestCase
{ {
public function testLexerExtendsLib() public function testLexerExtendsLib()
+5 -4
View File
@@ -4,24 +4,25 @@ namespace Egulias\Tests\EmailValidator;
use Egulias\EmailValidator\EmailValidator; use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd; use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
use PHPUnit\Framework\TestCase;
class EmailValidatorTest extends \PHPUnit_Framework_TestCase class EmailValidatorTest extends TestCase
{ {
public function testValidationIsUsed() public function testValidationIsUsed()
{ {
$validator = new EmailValidator(); $validator = new EmailValidator();
$validation = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation->expects($this->once())->method("isValid")->willReturn(true); $validation->expects($this->once())->method("isValid")->willReturn(true);
$validation->expects($this->once())->method("getWarnings")->willReturn([]); $validation->expects($this->once())->method("getWarnings")->willReturn([]);
$validation->expects($this->once())->method("getError")->willReturn(null); $validation->expects($this->once())->method("getError")->willReturn(null);
$this->assertTrue($validator->isValid("example@example.com", $validation)); $this->assertTrue($validator->isValid("example@example.com", $validation));
} }
public function testMultipleValidation() public function testMultipleValidation()
{ {
$validator = new EmailValidator(); $validator = new EmailValidator();
$validation = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation->expects($this->once())->method("isValid")->willReturn(true); $validation->expects($this->once())->method("isValid")->willReturn(true);
$validation->expects($this->once())->method("getWarnings")->willReturn([]); $validation->expects($this->once())->method("getWarnings")->willReturn([]);
$validation->expects($this->once())->method("getError")->willReturn(null); $validation->expects($this->once())->method("getError")->willReturn(null);
@@ -6,8 +6,9 @@ use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\NoDNSRecord; use Egulias\EmailValidator\Exception\NoDNSRecord;
use Egulias\EmailValidator\Validation\DNSCheckValidation; use Egulias\EmailValidator\Validation\DNSCheckValidation;
use Egulias\EmailValidator\Warning\NoDNSMXRecord; use Egulias\EmailValidator\Warning\NoDNSMXRecord;
use PHPUnit\Framework\TestCase;
class DNSCheckValidationTest extends \PHPUnit_Framework_TestCase class DNSCheckValidationTest extends TestCase
{ {
public function validEmailsProvider() public function validEmailsProvider()
{ {
@@ -23,6 +24,9 @@ class DNSCheckValidationTest extends \PHPUnit_Framework_TestCase
['"Abc@def"@example.com'], ['"Abc@def"@example.com'],
['"Fred\ Bloggs"@example.com'], ['"Fred\ Bloggs"@example.com'],
['"Joe.\\Blow"@example.com'], ['"Joe.\\Blow"@example.com'],
// unicide
['ñandu.cl'],
]; ];
} }
@@ -34,13 +38,13 @@ class DNSCheckValidationTest extends \PHPUnit_Framework_TestCase
$validation = new DNSCheckValidation(); $validation = new DNSCheckValidation();
$this->assertTrue($validation->isValid($validEmail, new EmailLexer())); $this->assertTrue($validation->isValid($validEmail, new EmailLexer()));
} }
public function testInvalidDNS() public function testInvalidDNS()
{ {
$validation = new DNSCheckValidation(); $validation = new DNSCheckValidation();
$this->assertFalse($validation->isValid("example@invalid.example.com", new EmailLexer())); $this->assertFalse($validation->isValid("example@invalid.example.com", new EmailLexer()));
} }
public function testDNSWarnings() public function testDNSWarnings()
{ {
$validation = new DNSCheckValidation(); $validation = new DNSCheckValidation();
@@ -48,7 +52,7 @@ class DNSCheckValidationTest extends \PHPUnit_Framework_TestCase
$validation->isValid("example@invalid.example.com", new EmailLexer()); $validation->isValid("example@invalid.example.com", new EmailLexer());
$this->assertEquals($expectedWarnings, $validation->getWarnings()); $this->assertEquals($expectedWarnings, $validation->getWarnings());
} }
public function testNoDNSError() public function testNoDNSError()
{ {
$validation = new DNSCheckValidation(); $validation = new DNSCheckValidation();
@@ -7,8 +7,9 @@ use Egulias\EmailValidator\Validation\DNSCheckValidation;
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd; use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation; use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
use Egulias\EmailValidator\Validation\RFCValidation; use Egulias\EmailValidator\Validation\RFCValidation;
use PHPUnit\Framework\TestCase;
class IsEmailFunctionTests extends \PHPUnit_Framework_TestCase class IsEmailFunctionTests extends TestCase
{ {
/** /**
* @dataProvider isEmailTestSuite * @dataProvider isEmailTestSuite
@@ -28,8 +29,8 @@ class IsEmailFunctionTests extends \PHPUnit_Framework_TestCase
public function isEmailTestSuite() public function isEmailTestSuite()
{ {
$testSuite = dirname(__FILE__) . '/../../resources/is_email_tests.xml'; $testSuite = dirname(__FILE__) . '/../../resources/is_email_tests.xml';
$document = new \DOMDocument(); $document = new \DOMDocument();
$document->load($testSuite); $document->load($testSuite);
$elements = $document->getElementsByTagName('test'); $elements = $document->getElementsByTagName('test');
$tests = []; $tests = [];
@@ -40,5 +41,4 @@ class IsEmailFunctionTests extends \PHPUnit_Framework_TestCase
return $tests; return $tests;
} }
} }
@@ -8,16 +8,17 @@ use Egulias\EmailValidator\Validation\MultipleErrors;
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd; use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
use Egulias\EmailValidator\Warning\AddressLiteral; use Egulias\EmailValidator\Warning\AddressLiteral;
use Egulias\EmailValidator\Warning\DomainLiteral; use Egulias\EmailValidator\Warning\DomainLiteral;
use PHPUnit\Framework\TestCase;
class MultipleValidationWitAndTest extends \PHPUnit_Framework_TestCase class MultipleValidationWitAndTest extends TestCase
{ {
public function testUsesAndLogicalOperation() public function testUsesAndLogicalOperation()
{ {
$lexer = $this->getMock("Egulias\\EmailValidator\\EmailLexer"); $lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock();
$validationTrue = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validationTrue = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validationTrue->expects($this->any())->method("isValid")->willReturn(true); $validationTrue->expects($this->any())->method("isValid")->willReturn(true);
$validationTrue->expects($this->any())->method("getWarnings")->willReturn([]); $validationTrue->expects($this->any())->method("getWarnings")->willReturn([]);
$validationFalse = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validationFalse = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validationFalse->expects($this->any())->method("isValid")->willReturn(false); $validationFalse->expects($this->any())->method("isValid")->willReturn(false);
$validationFalse->expects($this->any())->method("getWarnings")->willReturn([]); $validationFalse->expects($this->any())->method("getWarnings")->willReturn([]);
$multipleValidation = new MultipleValidationWithAnd([$validationTrue, $validationFalse]); $multipleValidation = new MultipleValidationWithAnd([$validationTrue, $validationFalse]);
@@ -32,6 +33,19 @@ class MultipleValidationWitAndTest extends \PHPUnit_Framework_TestCase
new MultipleValidationWithAnd([]); new MultipleValidationWithAnd([]);
} }
public function testValidationIsValid()
{
$lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock();
$validation = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation->expects($this->any())->method("isValid")->willReturn(true);
$validation->expects($this->once())->method("getWarnings")->willReturn([]);
$multipleValidation = new MultipleValidationWithAnd([$validation]);
$this->assertTrue($multipleValidation->isValid("example@example.com", $lexer));
$this->assertNull($multipleValidation->getError());
}
public function testAccumulatesWarnings() public function testAccumulatesWarnings()
{ {
$warnings1 = [ $warnings1 = [
@@ -41,16 +55,17 @@ class MultipleValidationWitAndTest extends \PHPUnit_Framework_TestCase
DomainLiteral::CODE => new DomainLiteral() DomainLiteral::CODE => new DomainLiteral()
]; ];
$expectedResult = array_merge($warnings1, $warnings2); $expectedResult = array_merge($warnings1, $warnings2);
$lexer = $this->getMock("Egulias\\EmailValidator\\EmailLexer"); $lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock();
$validation1 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation1->expects($this->any())->method("isValid")->willReturn(true); $validation1->expects($this->any())->method("isValid")->willReturn(true);
$validation1->expects($this->once())->method("getWarnings")->willReturn($warnings1); $validation1->expects($this->once())->method("getWarnings")->willReturn($warnings1);
$validation2 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation2 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation2->expects($this->any())->method("isValid")->willReturn(false); $validation2->expects($this->any())->method("isValid")->willReturn(false);
$validation2->expects($this->once())->method("getWarnings")->willReturn($warnings2); $validation2->expects($this->once())->method("getWarnings")->willReturn($warnings2);
$multipleValidation = new MultipleValidationWithAnd([$validation1, $validation2]); $multipleValidation = new MultipleValidationWithAnd([$validation1, $validation2]);
$multipleValidation->isValid("example@example.com", $lexer); $multipleValidation->isValid("example@example.com", $lexer);
$this->assertEquals($expectedResult, $multipleValidation->getWarnings()); $this->assertEquals($expectedResult, $multipleValidation->getWarnings());
@@ -60,17 +75,17 @@ class MultipleValidationWitAndTest extends \PHPUnit_Framework_TestCase
{ {
$error1 = new CommaInDomain(); $error1 = new CommaInDomain();
$error2 = new NoDomainPart(); $error2 = new NoDomainPart();
$expectedResult = new MultipleErrors([$error1, $error2]); $expectedResult = new MultipleErrors([$error1, $error2]);
$lexer = $this->getMock("Egulias\\EmailValidator\\EmailLexer"); $lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock();
$validation1 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation1->expects($this->any())->method("isValid")->willReturn(true); $validation1->expects($this->any())->method("isValid")->willReturn(true);
$validation1->expects($this->once())->method("getWarnings")->willReturn([]); $validation1->expects($this->once())->method("getWarnings")->willReturn([]);
$validation1->expects($this->once())->method("getError")->willReturn($error1); $validation1->expects($this->once())->method("getError")->willReturn($error1);
$validation2 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation2 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation2->expects($this->any())->method("isValid")->willReturn(false); $validation2->expects($this->any())->method("isValid")->willReturn(false);
$validation2->expects($this->once())->method("getWarnings")->willReturn([]); $validation2->expects($this->once())->method("getWarnings")->willReturn([]);
$validation2->expects($this->once())->method("getError")->willReturn($error2); $validation2->expects($this->once())->method("getError")->willReturn($error2);
@@ -86,14 +101,14 @@ class MultipleValidationWitAndTest extends \PHPUnit_Framework_TestCase
$expectedResult = new MultipleErrors([$error]); $expectedResult = new MultipleErrors([$error]);
$lexer = $this->getMock("Egulias\\EmailValidator\\EmailLexer"); $lexer = $this->getMockBuilder("Egulias\\EmailValidator\\EmailLexer")->getMock();
$validation1 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation1 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation1->expects($this->any())->method("isValid")->willReturn(false); $validation1->expects($this->any())->method("isValid")->willReturn(false);
$validation1->expects($this->once())->method("getWarnings")->willReturn([]); $validation1->expects($this->once())->method("getWarnings")->willReturn([]);
$validation1->expects($this->once())->method("getError")->willReturn($error); $validation1->expects($this->once())->method("getError")->willReturn($error);
$validation2 = $this->getMock("Egulias\\EmailValidator\\Validation\\EmailValidation"); $validation2 = $this->getMockBuilder("Egulias\\EmailValidator\\Validation\\EmailValidation")->getMock();
$validation2->expects($this->never())->method("isValid"); $validation2->expects($this->never())->method("isValid");
$validation2->expects($this->never())->method("getWarnings"); $validation2->expects($this->never())->method("getWarnings");
$validation2->expects($this->never())->method("getError"); $validation2->expects($this->never())->method("getError");
@@ -0,0 +1,36 @@
<?php
namespace Egulias\Tests\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Exception\NoDomainPart;
use Egulias\EmailValidator\Validation\Error\RFCWarnings;
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
use PHPUnit\Framework\TestCase;
class NoRFCWarningsValidationTest extends TestCase
{
public function testInvalidEmailIsInvalid()
{
$validation = new NoRFCWarningsValidation();
$this->assertFalse($validation->isValid('non-email-string', new EmailLexer()));
$this->assertInstanceOf(NoDomainPart::class, $validation->getError());
}
public function testEmailWithWarningsIsInvalid()
{
$validation = new NoRFCWarningsValidation();
$this->assertFalse($validation->isValid(str_repeat('x', 254).'@example.com', new EmailLexer())); // too long email
$this->assertInstanceOf(RFCWarnings::class, $validation->getError());
}
public function testEmailWithoutWarningsIsValid()
{
$validation = new NoRFCWarningsValidation();
$this->assertTrue($validation->isValid('example@example.com', new EmailLexer()));
$this->assertNull($validation->getError());
}
}
@@ -1,23 +0,0 @@
<?php
namespace Egulias\Tests\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
class NoWarningsRFCValidationTest extends \PHPUnit_Framework_TestCase
{
public function testEmailWithWarningsIsInvalid()
{
$validation = new NoRFCWarningsValidation();
$this->assertFalse($validation->isValid('examp"l"e@example.com', new EmailLexer()));
}
public function testEmailWithoutWarningsIsValid()
{
$validation = new NoRFCWarningsValidation();
$this->assertTrue($validation->isValid('example@example.com', new EmailLexer()));
}
}
@@ -35,8 +35,9 @@ use Egulias\EmailValidator\Warning\LabelTooLong;
use Egulias\EmailValidator\Warning\LocalTooLong; use Egulias\EmailValidator\Warning\LocalTooLong;
use Egulias\EmailValidator\Warning\ObsoleteDTEXT; use Egulias\EmailValidator\Warning\ObsoleteDTEXT;
use Egulias\EmailValidator\Warning\QuotedString; use Egulias\EmailValidator\Warning\QuotedString;
use PHPUnit\Framework\TestCase;
class RFCValidationTest extends \PHPUnit_Framework_TestCase class RFCValidationTest extends TestCase
{ {
/** /**
* @var RFCValidation * @var RFCValidation
@@ -47,7 +48,7 @@ class RFCValidationTest extends \PHPUnit_Framework_TestCase
* @var EmailLexer * @var EmailLexer
*/ */
protected $lexer; protected $lexer;
protected function setUp() protected function setUp()
{ {
$this->validator = new RFCValidation(); $this->validator = new RFCValidation();
@@ -106,7 +107,7 @@ class RFCValidationTest extends \PHPUnit_Framework_TestCase
$email = "\x80\x81\x82@\x83\x84\x85.\x86\x87\x88"; $email = "\x80\x81\x82@\x83\x84\x85.\x86\x87\x88";
$this->assertFalse($this->validator->isValid($email, $this->lexer)); $this->assertFalse($this->validator->isValid($email, $this->lexer));
} }
/** /**
* @dataProvider getInvalidEmails * @dataProvider getInvalidEmails
*/ */
@@ -219,16 +220,16 @@ class RFCValidationTest extends \PHPUnit_Framework_TestCase
{ {
$this->assertTrue($this->validator->isValid($email, $this->lexer)); $this->assertTrue($this->validator->isValid($email, $this->lexer));
$warnings = $this->validator->getWarnings(); $warnings = $this->validator->getWarnings();
$this->assertTrue( $this->assertCount(
count($warnings) === count($expectedWarnings), count($warnings), $expectedWarnings,
"Expected: " . implode(",", $expectedWarnings) . " and got " . implode(",", $warnings) "Expected: " . implode(",", $expectedWarnings) . " and got " . implode(",", $warnings)
); );
foreach ($warnings as $warning) { foreach ($warnings as $warning) {
$this->assertTrue(isset($expectedWarnings[$warning->code()])); $this->assertArrayHasKey($warning->code(), $expectedWarnings);
} }
} }
public function getInvalidEmailsWithWarnings() public function getInvalidEmailsWithWarnings()
{ {
return [ return [
@@ -4,8 +4,9 @@ namespace Egulias\Tests\EmailValidator\Validation;
use Egulias\EmailValidator\EmailLexer; use Egulias\EmailValidator\EmailLexer;
use Egulias\EmailValidator\Validation\SpoofCheckValidation; use Egulias\EmailValidator\Validation\SpoofCheckValidation;
use PHPUnit\Framework\TestCase;
class SpoofCheckValidationTest extends \PHPUnit_Framework_TestCase class SpoofCheckValidationTest extends TestCase
{ {
/** /**
* @dataProvider validUTF8EmailsProvider * @dataProvider validUTF8EmailsProvider
@@ -14,17 +15,17 @@ class SpoofCheckValidationTest extends \PHPUnit_Framework_TestCase
{ {
$this->markTestSkipped("Skipped for Travis CI since it is failing on this test for unknown reasons."); $this->markTestSkipped("Skipped for Travis CI since it is failing on this test for unknown reasons.");
$validation = new SpoofCheckValidation(); $validation = new SpoofCheckValidation();
$this->assertTrue($validation->isValid($email, new EmailLexer())); $this->assertTrue($validation->isValid($email, new EmailLexer()));
} }
public function testEmailWithSpoofsIsInvalid() public function testEmailWithSpoofsIsInvalid()
{ {
$validation = new SpoofCheckValidation(); $validation = new SpoofCheckValidation();
$this->assertFalse($validation->isValid("Кириллица"."latin漢字"."ひらがな"."カタカナ", new EmailLexer())); $this->assertFalse($validation->isValid("Кириллица"."latin漢字"."ひらがな"."カタカナ", new EmailLexer()));
} }
public function validUTF8EmailsProvider() public function validUTF8EmailsProvider()
{ {
return [ return [
+5 -2
View File
@@ -24,10 +24,13 @@
"doctrine/lexer": "^1.0.1" "doctrine/lexer": "^1.0.1"
}, },
"require-dev" : { "require-dev" : {
"satooshi/php-coveralls": "dev-master", "satooshi/php-coveralls": "^1.0.1",
"phpunit/phpunit": "^4.8.0", "phpunit/phpunit": "^4.8.35||^5.7||^6.0",
"dominicsayers/isemail": "dev-master" "dominicsayers/isemail": "dev-master"
}, },
"suggest": {
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
},
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Egulias\\EmailValidator\\": "EmailValidator" "Egulias\\EmailValidator\\": "EmailValidator"
Generated
-1661
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -1,23 +1,23 @@
Email length Email length
------------ ------------
http://tools.ietf.org/html/rfc5321#section-4.1.2 https://tools.ietf.org/html/rfc5321#section-4.1.2
Forward-path = Path Forward-path = Path
Path = "<" [ A-d-l ":" ] Mailbox ">" Path = "<" [ A-d-l ":" ] Mailbox ">"
http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3 https://tools.ietf.org/html/rfc5321#section-4.5.3.1.3
http://tools.ietf.org/html/rfc1035#section-2.3.4 https://tools.ietf.org/html/rfc1035#section-2.3.4
DNS DNS
--- ---
http://tools.ietf.org/html/rfc5321#section-2.3.5 https://tools.ietf.org/html/rfc5321#section-2.3.5
Names that can Names that can
be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed be resolved to MX RRs or address (i.e., A or AAAA) RRs (as discussed
in Section 5) are permitted, as are CNAME RRs whose targets can be in Section 5) are permitted, as are CNAME RRs whose targets can be
resolved, in turn, to MX or address RRs. resolved, in turn, to MX or address RRs.
http://tools.ietf.org/html/rfc5321#section-5.1 https://tools.ietf.org/html/rfc5321#section-5.1
The lookup first attempts to locate an MX record associated with the The lookup first attempts to locate an MX record associated with the
name. If a CNAME record is found, the resulting name is processed as name. If a CNAME record is found, the resulting name is processed as
if it were the initial name. ... If an empty list of MXs is returned, if it were the initial name. ... If an empty list of MXs is returned,
@@ -37,7 +37,7 @@ status to these addresses on the basis that they are more likely
to be typos than genuine addresses (unless we've already to be typos than genuine addresses (unless we've already
established that the domain does have an MX record) established that the domain does have an MX record)
http://tools.ietf.org/html/rfc5321#section-2.3.5 https://tools.ietf.org/html/rfc5321#section-2.3.5
In the case In the case
of a top-level domain used by itself in an email address, a single of a top-level domain used by itself in an email address, a single
string is used without any dots. This makes the requirement, string is used without any dots. This makes the requirement,
@@ -57,7 +57,7 @@ an ambiguity. The most authoritative statement on TLD formats that
the author can find is in a (rejected!) erratum to RFC 1123 the author can find is in a (rejected!) erratum to RFC 1123
submitted by John Klensin, the author of RFC 5321: submitted by John Klensin, the author of RFC 5321:
http://www.rfc-editor.org/errata_search.php?rfc=1123&eid=1353 https://www.rfc-editor.org/errata_search.php?rfc=1123&eid=1353
However, a valid host name can never have the dotted-decimal However, a valid host name can never have the dotted-decimal
form #.#.#.#, since this change does not permit the highest-level form #.#.#.#, since this change does not permit the highest-level
component label to start with a digit even if it is not all-numeric. component label to start with a digit even if it is not all-numeric.
@@ -66,4 +66,4 @@ Comments
-------- --------
Comments at the start of the domain are deprecated in the text Comments at the start of the domain are deprecated in the text
Comments at the start of a subdomain are obs-domain Comments at the start of a subdomain are obs-domain
(http://tools.ietf.org/html/rfc5322#section-3.4.1) (https://tools.ietf.org/html/rfc5322#section-3.4.1)