|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Egulias\Tests\EmailValidator\Validation; |
|
4
|
|
|
|
|
5
|
|
|
use Egulias\EmailValidator\EmailLexer; |
|
6
|
|
|
use Egulias\EmailValidator\Validation\RFCValidation; |
|
7
|
|
|
use Egulias\EmailValidator\Exception\AtextAfterCFWS; |
|
8
|
|
|
use Egulias\EmailValidator\Exception\ConsecutiveAt; |
|
9
|
|
|
use Egulias\EmailValidator\Exception\ConsecutiveDot; |
|
10
|
|
|
use Egulias\EmailValidator\Exception\CRNoLF; |
|
11
|
|
|
use Egulias\EmailValidator\Exception\DomainHyphened; |
|
12
|
|
|
use Egulias\EmailValidator\Exception\DotAtEnd; |
|
13
|
|
|
use Egulias\EmailValidator\Exception\DotAtStart; |
|
14
|
|
|
use Egulias\EmailValidator\Exception\ExpectingATEXT; |
|
15
|
|
|
use Egulias\EmailValidator\Exception\ExpectingDTEXT; |
|
16
|
|
|
use Egulias\EmailValidator\Exception\NoDomainPart; |
|
17
|
|
|
use Egulias\EmailValidator\Exception\NoLocalPart; |
|
18
|
|
|
use Egulias\EmailValidator\Exception\UnclosedComment; |
|
19
|
|
|
use Egulias\EmailValidator\Exception\UnclosedQuotedString; |
|
20
|
|
|
use Egulias\EmailValidator\Exception\UnopenedComment; |
|
21
|
|
|
use Egulias\EmailValidator\Warning\AddressLiteral; |
|
22
|
|
|
use Egulias\EmailValidator\Warning\CFWSNearAt; |
|
23
|
|
|
use Egulias\EmailValidator\Warning\CFWSWithFWS; |
|
24
|
|
|
use Egulias\EmailValidator\Warning\Comment; |
|
25
|
|
|
use Egulias\EmailValidator\Warning\DomainLiteral; |
|
26
|
|
|
use Egulias\EmailValidator\Warning\DomainTooLong; |
|
27
|
|
|
use Egulias\EmailValidator\Warning\IPV6BadChar; |
|
28
|
|
|
use Egulias\EmailValidator\Warning\IPV6ColonEnd; |
|
29
|
|
|
use Egulias\EmailValidator\Warning\IPV6ColonStart; |
|
30
|
|
|
use Egulias\EmailValidator\Warning\IPV6Deprecated; |
|
31
|
|
|
use Egulias\EmailValidator\Warning\IPV6DoubleColon; |
|
32
|
|
|
use Egulias\EmailValidator\Warning\IPV6GroupCount; |
|
33
|
|
|
use Egulias\EmailValidator\Warning\IPV6MaxGroups; |
|
34
|
|
|
use Egulias\EmailValidator\Warning\LabelTooLong; |
|
35
|
|
|
use Egulias\EmailValidator\Warning\LocalTooLong; |
|
36
|
|
|
use Egulias\EmailValidator\Warning\ObsoleteDTEXT; |
|
37
|
|
|
use Egulias\EmailValidator\Warning\QuotedString; |
|
38
|
|
|
use PHPUnit\Framework\TestCase; |
|
39
|
|
|
|
|
40
|
|
|
class RFCValidationTest extends TestCase |
|
41
|
|
|
{ |
|
42
|
|
|
/** |
|
43
|
|
|
* @var RFCValidation |
|
44
|
|
|
*/ |
|
45
|
|
|
protected $validator; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* @var EmailLexer |
|
49
|
|
|
*/ |
|
50
|
|
|
protected $lexer; |
|
51
|
|
|
|
|
52
|
|
|
protected function setUp() |
|
53
|
|
|
{ |
|
54
|
|
|
$this->validator = new RFCValidation(); |
|
55
|
|
|
$this->lexer = new EmailLexer(); |
|
56
|
|
|
} |
|
57
|
|
|
|
|
58
|
|
|
protected function tearDown() |
|
59
|
|
|
{ |
|
60
|
|
|
$this->validator = null; |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* @dataProvider getValidEmails |
|
65
|
|
|
*/ |
|
66
|
|
|
public function testValidEmails($email) |
|
67
|
|
|
{ |
|
68
|
|
|
$this->assertTrue($this->validator->isValid($email, $this->lexer)); |
|
69
|
|
|
} |
|
70
|
|
|
|
|
71
|
|
|
public function getValidEmails() |
|
72
|
|
|
{ |
|
73
|
|
|
return array( |
|
74
|
|
|
['â@iana.org'], |
|
75
|
|
|
['[email protected]'], |
|
76
|
|
|
['[email protected]'], |
|
77
|
|
|
['[email protected]'], |
|
78
|
|
|
['example@localhost'], |
|
79
|
|
|
['fab\'[email protected]'], |
|
80
|
|
|
['fab\ [email protected]'], |
|
81
|
|
|
['example((example))@fakedfake.co.uk'], |
|
82
|
|
|
['example@faked(fake).co.uk'], |
|
83
|
|
|
['[email protected]'], |
|
84
|
|
|
['инфо@письмо.рф'], |
|
85
|
|
|
['"username"@example.com'], |
|
86
|
|
|
['"user,name"@example.com'], |
|
87
|
|
|
['"user name"@example.com'], |
|
88
|
|
|
['"user@name"@example.com'], |
|
89
|
|
|
['"user\"name"@example.com'], |
|
90
|
|
|
['"\a"@iana.org'], |
|
91
|
|
|
['"test\ test"@iana.org'], |
|
92
|
|
|
['""@iana.org'], |
|
93
|
|
|
['"\""@iana.org'], |
|
94
|
|
|
['müller@möller.de'], |
|
95
|
|
|
['test@email*'], |
|
96
|
|
|
['test@email!'], |
|
97
|
|
|
['test@email&'], |
|
98
|
|
|
['test@email^'], |
|
99
|
|
|
['test@email%'], |
|
100
|
|
|
['test@email$'], |
|
101
|
|
|
["1500111@профи-инвест.рф"], |
|
102
|
|
|
); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
public function testInvalidUTF8Email() |
|
106
|
|
|
{ |
|
107
|
|
|
$email = "\x80\x81\x82@\x83\x84\x85.\x86\x87\x88"; |
|
108
|
|
|
$this->assertFalse($this->validator->isValid($email, $this->lexer)); |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* @dataProvider getInvalidEmails |
|
113
|
|
|
*/ |
|
114
|
|
|
public function testInvalidEmails($email) |
|
115
|
|
|
{ |
|
116
|
|
|
$this->assertFalse($this->validator->isValid($email, $this->lexer)); |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
public function getInvalidEmails() |
|
120
|
|
|
{ |
|
121
|
|
|
return [ |
|
122
|
|
|
['[email protected] test'], |
|
123
|
|
|
['user [email protected]'], |
|
124
|
|
|
['user [email protected]'], |
|
125
|
|
|
['[email protected]'], |
|
126
|
|
|
['example@[email protected]'], |
|
127
|
|
|
['([email protected]]'], |
|
128
|
|
|
['example(example][email protected]'], |
|
129
|
|
|
['.example@localhost'], |
|
130
|
|
|
['ex\ample@localhost'], |
|
131
|
|
|
['example@local\host'], |
|
132
|
|
|
['example@localhost\\'], |
|
133
|
|
|
['example@localhost.'], |
|
134
|
|
|
['user [email protected]'], |
|
135
|
|
|
['username@ example . com'], |
|
136
|
|
|
['example@(fake].com'], |
|
137
|
|
|
['example@(fake.com'], |
|
138
|
|
|
['username@example,com'], |
|
139
|
|
|
['usern,[email protected]'], |
|
140
|
|
|
['user[na][email protected]'], |
|
141
|
|
|
['"""@iana.org'], |
|
142
|
|
|
['"\"@iana.org'], |
|
143
|
|
|
['"test"[email protected]'], |
|
144
|
|
|
['"test""test"@iana.org'], |
|
145
|
|
|
['"test"."test"@iana.org'], |
|
146
|
|
|
['"test"[email protected]'], |
|
147
|
|
|
['"test"' . chr(0) . '@iana.org'], |
|
148
|
|
|
['"test\"@iana.org'], |
|
149
|
|
|
[chr(226) . '@iana.org'], |
|
150
|
|
|
['test@' . chr(226) . '.org'], |
|
151
|
|
|
['\r\[email protected]'], |
|
152
|
|
|
['\r\n [email protected]'], |
|
153
|
|
|
['\r\n \r\[email protected]'], |
|
154
|
|
|
['\r\n \r\[email protected]'], |
|
155
|
|
|
['\r\n \r\n [email protected]'], |
|
156
|
|
|
['[email protected] \r\n'], |
|
157
|
|
|
['[email protected] \r\n '], |
|
158
|
|
|
['[email protected] \r\n \r\n'], |
|
159
|
|
|
['[email protected] \r\n\r\n'], |
|
160
|
|
|
['[email protected] \r\n\r\n '], |
|
161
|
|
|
['test@iana/icann.org'], |
|
162
|
|
|
['test@foo;bar.com'], |
|
163
|
|
|
['test;[email protected]'], |
|
164
|
|
|
['[email protected]'], |
|
165
|
|
|
['email.email@email."'], |
|
166
|
|
|
['test@email>'], |
|
167
|
|
|
['test@email<'], |
|
168
|
|
|
['test@email{'], |
|
169
|
|
|
['test@ '], |
|
170
|
|
|
]; |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
/** |
|
174
|
|
|
* @dataProvider getInvalidEmailsWithErrors |
|
175
|
|
|
*/ |
|
176
|
|
|
public function testInvalidEmailsWithErrorsCheck($error, $email) |
|
177
|
|
|
{ |
|
178
|
|
|
$this->assertFalse($this->validator->isValid($email, $this->lexer)); |
|
179
|
|
|
$this->assertEquals($error, $this->validator->getError()); |
|
180
|
|
|
} |
|
181
|
|
|
|
|
182
|
|
|
public function getInvalidEmailsWithErrors() |
|
183
|
|
|
{ |
|
184
|
|
|
return [ |
|
185
|
|
|
[new NoLocalPart(), '@example.co.uk'], |
|
186
|
|
|
[new NoDomainPart(), 'example@'], |
|
187
|
|
|
[new DomainHyphened(), '[email protected]'], |
|
188
|
|
|
[new DomainHyphened(), 'example@example-'], |
|
189
|
|
|
[new ConsecutiveAt(), 'example@@example.co.uk'], |
|
190
|
|
|
[new ConsecutiveDot(), '[email protected]'], |
|
191
|
|
|
[new ConsecutiveDot(), '[email protected]'], |
|
192
|
|
|
[new ExpectingATEXT(), '<example_example>@example.fr'], |
|
193
|
|
|
[new DotAtStart(), '.example@localhost'], |
|
194
|
|
|
[new DotAtStart(), '[email protected]'], |
|
195
|
|
|
[new DotAtEnd(), 'example@localhost.'], |
|
196
|
|
|
[new DotAtEnd(), '[email protected]'], |
|
197
|
|
|
[new UnclosedComment(), '(example@localhost'], |
|
198
|
|
|
[new UnclosedQuotedString(), '"example@localhost'], |
|
199
|
|
|
[new ExpectingATEXT(), 'exa"mple@localhost'], |
|
200
|
|
|
[new UnclosedComment(), '(example@localhost'], |
|
201
|
|
|
[new UnopenedComment(), 'comment)example@localhost'], |
|
202
|
|
|
[new UnopenedComment(), 'example(comment))@localhost'], |
|
203
|
|
|
[new UnopenedComment(), 'example@comment)localhost'], |
|
204
|
|
|
[new UnopenedComment(), 'example@localhost(comment))'], |
|
205
|
|
|
[new UnopenedComment(), 'example@(comment))example.com'], |
|
206
|
|
|
//This was the original. But atext is not allowed after \n |
|
207
|
|
|
//array(EmailValidator::ERR_EXPECTING_ATEXT, "exampl\[email protected]"), |
|
208
|
|
|
[new AtextAfterCFWS(), "exampl\[email protected]"], |
|
209
|
|
|
[new ExpectingDTEXT(), "example@[[]"], |
|
210
|
|
|
[new AtextAfterCFWS(), "exampl\[email protected]"], |
|
211
|
|
|
[new CRNoLF(), "example@exa\rmple.co.uk"], |
|
212
|
|
|
[new CRNoLF(), "example@[\r]"], |
|
213
|
|
|
[new CRNoLF(), "exam\[email protected]"], |
|
214
|
|
|
]; |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
/** |
|
218
|
|
|
* @dataProvider getInvalidEmailsWithWarnings |
|
219
|
|
|
*/ |
|
220
|
|
|
public function testInvalidEmailsWithWarningsCheck($expectedWarnings, $email) |
|
221
|
|
|
{ |
|
222
|
|
|
$this->assertTrue($this->validator->isValid($email, $this->lexer)); |
|
223
|
|
|
$warnings = $this->validator->getWarnings(); |
|
224
|
|
|
$this->assertCount( |
|
225
|
|
|
count($warnings), $expectedWarnings, |
|
226
|
|
|
"Expected: " . implode(",", $expectedWarnings) . " and got " . implode(",", $warnings) |
|
227
|
|
|
); |
|
228
|
|
|
|
|
229
|
|
|
foreach ($warnings as $warning) { |
|
230
|
|
|
$this->assertArrayHasKey($warning->code(), $expectedWarnings); |
|
231
|
|
|
} |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
public function getInvalidEmailsWithWarnings() |
|
235
|
|
|
{ |
|
236
|
|
|
return [ |
|
237
|
|
|
[[CFWSNearAt::CODE], 'example @invalid.example.com'], |
|
238
|
|
|
[[CFWSNearAt::CODE], 'example@ invalid.example.com'], |
|
239
|
|
|
[[Comment::CODE], '[email protected](examplecomment).com'], |
|
240
|
|
|
[[Comment::CODE,CFWSNearAt::CODE], 'example(examplecomment)@invalid.example.com'], |
|
241
|
|
|
[[QuotedString::CODE, CFWSWithFWS::CODE,], "\"\t\"@invalid.example.com"], |
|
242
|
|
|
[[QuotedString::CODE, CFWSWithFWS::CODE,], "\"\r\"@invalid.example.com"], |
|
243
|
|
|
[[AddressLiteral::CODE,], 'example@[127.0.0.1]'], |
|
244
|
|
|
[[AddressLiteral::CODE,], 'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334]'], |
|
245
|
|
|
[[AddressLiteral::CODE, IPV6Deprecated::CODE], 'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370::]'], |
|
246
|
|
|
[[AddressLiteral::CODE, IPV6MaxGroups::CODE,], 'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334::]'], |
|
247
|
|
|
[[AddressLiteral::CODE, IPV6DoubleColon::CODE,], 'example@[IPv6:1::1::1]'], |
|
248
|
|
|
[[ObsoleteDTEXT::CODE, DomainLiteral::CODE,], "example@[\n]"], |
|
249
|
|
|
[[DomainLiteral::CODE,], 'example@[::1]'], |
|
250
|
|
|
[[DomainLiteral::CODE,], 'example@[::123.45.67.178]'], |
|
251
|
|
|
[ |
|
252
|
|
|
[IPV6ColonStart::CODE, AddressLiteral::CODE, IPV6GroupCount::CODE,], |
|
253
|
|
|
'example@[IPv6::2001:0db8:85a3:0000:0000:8a2e:0370:7334]' |
|
254
|
|
|
], |
|
255
|
|
|
[ |
|
256
|
|
|
[AddressLiteral::CODE, IPV6BadChar::CODE,], |
|
257
|
|
|
'example@[IPv6:z001:0db8:85a3:0000:0000:8a2e:0370:7334]' |
|
258
|
|
|
], |
|
259
|
|
|
[ |
|
260
|
|
|
[AddressLiteral::CODE, IPV6ColonEnd::CODE,], |
|
261
|
|
|
'example@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:]' |
|
262
|
|
|
], |
|
263
|
|
|
[[QuotedString::CODE,], '"example"@invalid.example.com'], |
|
264
|
|
|
[ |
|
265
|
|
|
[LocalTooLong::CODE,], |
|
266
|
|
|
'too_long_localpart_too_long_localpart_too_long_localpart_too_long_localpart@invalid.example.com' |
|
267
|
|
|
], |
|
268
|
|
|
[ |
|
269
|
|
|
[LocalTooLong::CODE], |
|
270
|
|
|
'too_long_localpart_too_long_localpart_123_too_long_localpart_too_long_localpart@example.com' |
|
271
|
|
|
], |
|
272
|
|
|
[ |
|
273
|
|
|
[LabelTooLong::CODE,], |
|
274
|
|
|
'example@toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart.co.uk' |
|
275
|
|
|
], |
|
276
|
|
|
[ |
|
277
|
|
|
[DomainTooLong::CODE, LabelTooLong::CODE,], |
|
278
|
|
|
'example2@toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocal'. |
|
279
|
|
|
'parttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart'. |
|
280
|
|
|
'toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart' |
|
281
|
|
|
], |
|
282
|
|
|
[ |
|
283
|
|
|
[DomainTooLong::CODE, LabelTooLong::CODE,], |
|
284
|
|
|
'example@toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocal'. |
|
285
|
|
|
'parttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpart'. |
|
286
|
|
|
'toolonglocalparttoolonglocalparttoolonglocalparttoolonglocalpar' |
|
287
|
|
|
], |
|
288
|
|
|
]; |
|
289
|
|
|
} |
|
290
|
|
|
} |
|
291
|
|
|
|