1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.validator.routines;
18
19 import static org.hamcrest.MatcherAssert.assertThat;
20 import static org.hamcrest.core.Is.is;
21 import static org.hamcrest.core.IsEqual.equalTo;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import org.apache.commons.lang3.SystemProperties;
31 import org.apache.commons.validator.ResultPair;
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Disabled;
34 import org.junit.jupiter.api.Test;
35
36
37
38
39 public class EmailValidatorTest {
40
41
42
43
44 protected static final String FORM_KEY = "emailForm";
45
46
47
48
49 protected static final String ACTION = "email";
50
51
52
53
54
55 private static final ResultPair[] TEST_EMAIL_FROM_PERL = {
56
57 new ResultPair("abigail@example.com", true),
58 new ResultPair("abigail@example.com ", true),
59 new ResultPair(" abigail@example.com", true),
60 new ResultPair("abigail @example.com ", true),
61 new ResultPair("*@example.net", true),
62 new ResultPair("\"\\\"\"@foo.bar", true),
63 new ResultPair("fred&barny@example.com", true),
64 new ResultPair("---@example.com", true),
65 new ResultPair("foo-bar@example.net", true),
66 new ResultPair("\"127.0.0.1\"@[127.0.0.1]", true),
67 new ResultPair("Abigail <abigail@example.com>", true),
68 new ResultPair("Abigail<abigail@example.com>", true),
69 new ResultPair("Abigail<@a,@b,@c:abigail@example.com>", true),
70 new ResultPair("\"This is a phrase\"<abigail@example.com>", true),
71 new ResultPair("\"Abigail \"<abigail@example.com>", true),
72 new ResultPair("\"Joe & J. Harvey\" <example @Org>", true),
73 new ResultPair("Abigail <abigail @ example.com>", true),
74 new ResultPair("Abigail made this < abigail @ example . com >", true),
75 new ResultPair("Abigail(the bitch)@example.com", true),
76 new ResultPair("Abigail <abigail @ example . (bar) com >", true),
77 new ResultPair("Abigail < (one) abigail (two) @(three) example . (bar) com (quz) >", true),
78 new ResultPair("Abigail (foo) (((baz)(nested) (comment)) ! ) < (one) abigail (two) @(three) example . (bar) com (quz) >", true),
79 new ResultPair("Abigail <abigail(fo\\(o)@example.com>", true),
80 new ResultPair("Abigail <abigail(fo\\)o)@example.com> ", true),
81 new ResultPair("(foo) abigail@example.com", true),
82 new ResultPair("abigail@example.com (foo)", true),
83 new ResultPair("\"Abi\\\"gail\" <abigail@example.com>", true),
84 new ResultPair("abigail@[example.com]", true),
85 new ResultPair("abigail@[exa\\[ple.com]", true),
86 new ResultPair("abigail@[exa\\]ple.com]", true),
87 new ResultPair("\":sysmail\"@ Some-Group. Some-Org", true),
88 new ResultPair("Muhammed.(I am the greatest) Ali @(the) Vegas.WBA", true),
89 new ResultPair("mailbox.sub1.sub2@this-domain", true),
90 new ResultPair("sub-net.mailbox@sub-domain.domain", true),
91 new ResultPair("name:;", true),
92 new ResultPair("':;", true),
93 new ResultPair("name: ;", true),
94 new ResultPair("Alfred Neuman <Neuman@BBN-TENEXA>", true),
95 new ResultPair("Neuman@BBN-TENEXA", true),
96 new ResultPair("\"George, Ted\" <Shared@Group.Arpanet>", true),
97 new ResultPair("Wilt . (the Stilt) Chamberlain@NBA.US", true),
98 new ResultPair("Cruisers: Port@Portugal, Jones@SEA;", true),
99 new ResultPair("$@[]", true),
100 new ResultPair("*()@[]", true),
101 new ResultPair("\"quoted ( brackets\" ( a comment )@example.com", true),
102 new ResultPair("\"Joe & J. Harvey\"\\x0D\\x0A <ddd\\@ Org>", true),
103 new ResultPair("\"Joe &\\x0D\\x0A J. Harvey\" <ddd \\@ Org>", true),
104 new ResultPair("Gourmets: Pompous Person <WhoZiWhatZit\\@Cordon-Bleu>,\\x0D\\x0A" +
105 " Childs\\@WGBH.Boston, \"Galloping Gourmet\"\\@\\x0D\\x0A" +
106 " ANT.Down-Under (Australian National Television),\\x0D\\x0A" +
107 " Cheapie\\@Discount-Liquors;", true),
108 new ResultPair(" Just a string", false),
109 new ResultPair("string", false),
110 new ResultPair("(comment)", false),
111 new ResultPair("()@example.com", false),
112 new ResultPair("fred(&)barny@example.com", false),
113 new ResultPair("fred\\ barny@example.com", false),
114 new ResultPair("Abigail <abi gail @ example.com>", false),
115 new ResultPair("Abigail <abigail(fo(o)@example.com>", false),
116 new ResultPair("Abigail <abigail(fo) o)@example.com>", false),
117 new ResultPair("\"Abi\"gail\" <abigail@example.com>", false),
118 new ResultPair("abigail@[exa]ple.com]", false),
119 new ResultPair("abigail@[exa[ple.com]", false),
120 new ResultPair("abigail@[exaple].com]", false),
121 new ResultPair("abigail@", false),
122 new ResultPair("@example.com", false),
123 new ResultPair("phrase: abigail@example.com abigail@example.com ;", false),
124 new ResultPair("invalid�char@example.com", false)
125
126 };
127
128 public static void main(final String[] args) {
129 final EmailValidator validator = EmailValidator.getInstance();
130 for (final String arg : args) {
131 System.out.printf("%s: %s%n", arg, validator.isValid(arg));
132 }
133 }
134
135 private EmailValidator validator;
136
137 @BeforeEach
138 public void setUp() {
139 validator = EmailValidator.getInstance();
140 }
141
142
143
144
145 @Test
146 public void testEmail() {
147 assertTrue(validator.isValid("jsmith@apache.org"));
148 }
149
150
151
152
153
154
155
156 @Test
157 public void testEmailAtTLD() {
158 final EmailValidator val = EmailValidator.getInstance(false, true);
159 assertTrue(val.isValid("test@com"));
160 }
161
162
163
164
165 @Test
166 public void testEmailExtension() {
167 assertTrue(validator.isValid("jsmith@apache.org"));
168
169 assertTrue(validator.isValid("jsmith@apache.com"));
170
171 assertTrue(validator.isValid("jsmith@apache.net"));
172
173 assertTrue(validator.isValid("jsmith@apache.info"));
174
175 assertFalse(validator.isValid("jsmith@apache."));
176
177 assertFalse(validator.isValid("jsmith@apache.c"));
178
179 assertTrue(validator.isValid("someone@yahoo.museum"));
180
181 assertFalse(validator.isValid("someone@yahoo.mu-seum"));
182 }
183
184
185
186
187
188
189 @Disabled("VALIDATOR-267")
190 @Test
191 public void testEmailFromPerl() {
192 int errors = 0;
193 for (final ResultPair element : TEST_EMAIL_FROM_PERL) {
194 final String item = element.item;
195 final boolean exp = element.valid;
196 final boolean act = validator.isValid(item);
197 if (act != exp) {
198 System.out.printf("%s: expected %s actual %s%n", item, exp, act);
199 errors += 1;
200 }
201 }
202 assertEquals(0, errors, "Expected 0 errors");
203 }
204
205
206
207
208 @Test
209 public void testEmailLocalhost() {
210
211 final EmailValidator noLocal = EmailValidator.getInstance(false);
212 final EmailValidator allowLocal = EmailValidator.getInstance(true);
213 assertEquals(validator, noLocal);
214
215
216 assertTrue(allowLocal.isValid("joe@localhost.localdomain"), "@localhost.localdomain should be accepted but wasn't");
217 assertTrue(allowLocal.isValid("joe@localhost"), "@localhost should be accepted but wasn't");
218
219 assertFalse(noLocal.isValid("joe@localhost.localdomain"), "@localhost.localdomain should be accepted but wasn't");
220 assertFalse(noLocal.isValid("joe@localhost"), "@localhost should be accepted but wasn't");
221 }
222
223
224
225
226 @Test
227 public void testEmailUserName() {
228
229 assertTrue(validator.isValid("joe1blow@apache.org"));
230
231 assertTrue(validator.isValid("joe$blow@apache.org"));
232
233 assertTrue(validator.isValid("joe-@apache.org"));
234
235 assertTrue(validator.isValid("joe_@apache.org"));
236
237 assertTrue(validator.isValid("joe+@apache.org"));
238
239 assertTrue(validator.isValid("joe!@apache.org"));
240
241 assertTrue(validator.isValid("joe*@apache.org"));
242
243 assertTrue(validator.isValid("joe'@apache.org"));
244
245 assertTrue(validator.isValid("joe%45@apache.org"));
246
247 assertTrue(validator.isValid("joe?@apache.org"));
248
249 assertTrue(validator.isValid("joe&@apache.org"));
250
251 assertTrue(validator.isValid("joe=@apache.org"));
252
253 assertTrue(validator.isValid("+joe@apache.org"));
254
255 assertTrue(validator.isValid("!joe@apache.org"));
256
257 assertTrue(validator.isValid("*joe@apache.org"));
258
259 assertTrue(validator.isValid("'joe@apache.org"));
260
261 assertTrue(validator.isValid("%joe45@apache.org"));
262
263 assertTrue(validator.isValid("?joe@apache.org"));
264
265 assertTrue(validator.isValid("&joe@apache.org"));
266
267 assertTrue(validator.isValid("=joe@apache.org"));
268
269 assertTrue(validator.isValid("+@apache.org"));
270
271 assertTrue(validator.isValid("!@apache.org"));
272
273 assertTrue(validator.isValid("*@apache.org"));
274
275 assertTrue(validator.isValid("'@apache.org"));
276
277 assertTrue(validator.isValid("%@apache.org"));
278
279 assertTrue(validator.isValid("?@apache.org"));
280
281 assertTrue(validator.isValid("&@apache.org"));
282
283 assertTrue(validator.isValid("=@apache.org"));
284
285
286
287 assertFalse(validator.isValid("joe.@apache.org"));
288
289 assertFalse(validator.isValid(".joe@apache.org"));
290
291 assertFalse(validator.isValid(".@apache.org"));
292
293 assertTrue(validator.isValid("joe.ok@apache.org"));
294
295 assertFalse(validator.isValid("joe..ok@apache.org"));
296
297 assertFalse(validator.isValid("..@apache.org"));
298
299 assertFalse(validator.isValid("joe(@apache.org"));
300
301 assertFalse(validator.isValid("joe)@apache.org"));
302
303 assertFalse(validator.isValid("joe,@apache.org"));
304
305 assertFalse(validator.isValid("joe;@apache.org"));
306
307
308 assertTrue(validator.isValid("\"joe.\"@apache.org"));
309
310 assertTrue(validator.isValid("\".joe\"@apache.org"));
311
312 assertTrue(validator.isValid("\"joe+\"@apache.org"));
313
314 assertTrue(validator.isValid("\"joe@\"@apache.org"));
315
316 assertTrue(validator.isValid("\"joe!\"@apache.org"));
317
318 assertTrue(validator.isValid("\"joe*\"@apache.org"));
319
320 assertTrue(validator.isValid("\"joe'\"@apache.org"));
321
322 assertTrue(validator.isValid("\"joe(\"@apache.org"));
323
324 assertTrue(validator.isValid("\"joe)\"@apache.org"));
325
326 assertTrue(validator.isValid("\"joe,\"@apache.org"));
327
328 assertTrue(validator.isValid("\"joe%45\"@apache.org"));
329
330 assertTrue(validator.isValid("\"joe;\"@apache.org"));
331
332 assertTrue(validator.isValid("\"joe?\"@apache.org"));
333
334 assertTrue(validator.isValid("\"joe&\"@apache.org"));
335
336 assertTrue(validator.isValid("\"joe=\"@apache.org"));
337
338 assertTrue(validator.isValid("\"..\"@apache.org"));
339
340
341 assertTrue(validator.isValid("\"john\\\"doe\"@apache.org"));
342
343 assertTrue(validator.isValid("john56789.john56789.john56789.john56789.john56789.john56789.john@example.com"));
344
345 assertFalse(validator.isValid("john56789.john56789.john56789.john56789.john56789.john56789.john5@example.com"));
346
347 assertTrue(validator.isValid("\\>escape\\\\special\\^characters\\<@example.com"));
348
349 assertTrue(validator.isValid("Abc\\@def@example.com"));
350
351 assertFalse(validator.isValid("Abc@def@example.com"));
352
353 assertTrue(validator.isValid("space\\ monkey@example.com"));
354 }
355
356
357
358
359 @Test
360 public void testEmailWithBogusCharacter() {
361
362 assertFalse(validator.isValid("andy.noble@\u008fdata-workshop.com"));
363
364
365 assertTrue(validator.isValid("andy.o'reilly@data-workshop.com"));
366
367
368 assertFalse(validator.isValid("andy@o'reilly.data-workshop.com"));
369
370
371 assertTrue(validator.isValid("foo+bar@i.am.not.in.us.example.com"));
372
373
374 assertFalse(validator.isValid("foo+bar@example+3.com"));
375
376
377 assertFalse(validator.isValid("test@%*.com"));
378 assertFalse(validator.isValid("test@^&#.com"));
379
380 }
381
382
383
384
385 @Test
386 public void testEmailWithCommas() {
387 assertFalse(validator.isValid("joeblow@apa,che.org"));
388
389 assertFalse(validator.isValid("joeblow@apache.o,rg"));
390
391 assertFalse(validator.isValid("joeblow@apache,org"));
392
393 }
394
395
396
397
398 @Test
399 public void testEmailWithControlChars() {
400 for (char c = 0; c < 32; c++) {
401 assertFalse(validator.isValid("foo" + c + "bar@domain.com"), "Test control char " + (int) c);
402 }
403 assertFalse(validator.isValid("foo" + (char) 127 + "bar@domain.com"), "Test control char 127");
404 }
405
406
407
408
409
410
411 @Test
412 public void testEmailWithDash() {
413 assertTrue(validator.isValid("andy.noble@data-workshop.com"));
414
415 assertFalse(validator.isValid("andy-noble@data-workshop.-com"));
416
417 assertFalse(validator.isValid("andy-noble@data-workshop.c-om"));
418
419 assertFalse(validator.isValid("andy-noble@data-workshop.co-m"));
420 }
421
422
423
424
425 @Test
426 public void testEmailWithDotEnd() {
427 assertFalse(validator.isValid("andy.noble@data-workshop.com."));
428 }
429
430
431
432
433 @Test
434 public void testEmailWithNumericAddress() {
435 assertTrue(validator.isValid("someone@[216.109.118.76]"));
436 assertTrue(validator.isValid("someone@yahoo.com"));
437 }
438
439
440
441
442 @Test
443 public void testEmailWithSlashes() {
444 assertTrue(validator.isValid("joe!/blow@apache.org"), "/ and ! valid in username");
445 assertFalse(validator.isValid("joe@ap/ache.org"), "/ not valid in domain");
446 assertFalse(validator.isValid("joe@apac!he.org"), "! not valid in domain");
447 }
448
449
450
451
452 @Test
453 public void testEmailWithSpaces() {
454 assertFalse(validator.isValid("joeblow @apache.org"));
455
456 assertFalse(validator.isValid("joeblow@ apache.org"));
457
458 assertFalse(validator.isValid(" joeblow@apache.org"));
459
460 assertFalse(validator.isValid("joeblow@apache.org "));
461
462 assertFalse(validator.isValid("joe blow@apache.org "));
463
464 assertFalse(validator.isValid("joeblow@apa che.org "));
465
466 assertTrue(validator.isValid("\"joeblow \"@apache.org"));
467
468 assertTrue(validator.isValid("\" joeblow\"@apache.org"));
469
470 assertTrue(validator.isValid("\" joe blow \"@apache.org"));
471
472 }
473
474 @Test
475 public void testValidator235() {
476 final String version = SystemProperties.getJavaVersion();
477 if (version.compareTo("1.6") < 0) {
478 System.out.println("Cannot run Unicode IDN tests");
479 return;
480 }
481 assertTrue(validator.isValid("someone@xn--d1abbgf6aiiy.xn--p1ai"), "xn--d1abbgf6aiiy.xn--p1ai should validate");
482 assertTrue(validator.isValid("someone@президент.рф"), "президент.рф should validate");
483 assertTrue(validator.isValid("someone@www.b\u00fccher.ch"), "www.b\u00fccher.ch should validate");
484 assertFalse(validator.isValid("someone@www.\uFFFD.ch"), "www.\uFFFD.ch FFFD should fail");
485 assertTrue(validator.isValid("someone@www.b\u00fccher.ch"), "www.b\u00fccher.ch should validate");
486 assertFalse(validator.isValid("someone@www.\uFFFD.ch"), "www.\uFFFD.ch FFFD should fail");
487 }
488
489 @Test
490 public void testValidator278() {
491 assertFalse(validator.isValid("someone@-test.com"));
492 assertFalse(validator.isValid("someone@test-.com"));
493 }
494
495 @Test
496 public void testValidator293() {
497 assertTrue(validator.isValid("abc-@abc.com"));
498 assertTrue(validator.isValid("abc_@abc.com"));
499 assertTrue(validator.isValid("abc-def@abc.com"));
500 assertTrue(validator.isValid("abc_def@abc.com"));
501 assertFalse(validator.isValid("abc@abc_def.com"));
502 }
503
504 @Test
505 public void testValidator315() {
506 assertFalse(validator.isValid("me@at&t.net"));
507 assertTrue(validator.isValid("me@att.net"));
508 }
509
510 @Test
511 public void testValidator359() {
512 final EmailValidator val = EmailValidator.getInstance(false, true);
513 assertFalse(val.isValid("test@.com"));
514 }
515
516 @Test
517 public void testValidator365() {
518 assertFalse(validator.isValid("Loremipsumdolorsitametconsecteturadipiscingelit.Nullavitaeligulamattisrhoncusnuncegestasmattisleo."
519 + "Donecnonsapieninmagnatristiquedictumaacturpis.Fusceorciduifacilisisutsapieneuconsequatpharetralectus."
520 + "Quisqueenimestpulvinarutquamvitaeportamattisex.Nullamquismaurisplaceratconvallisjustoquisportamauris."
521 + "Innullalacusconvalliseufringillautvenenatissitametdiam.Maecenasluctusligulascelerisquepulvinarfeugiat."
522 + "Sedmolestienullaaliquetorciluctusidpharetranislfinibus.Suspendissemalesuadatinciduntduisitametportaarcusollicitudinnec."
523 + "Donecetmassamagna.Curabitururnadiampretiumveldignissimporttitorfringillaeuneque."
524 + "Duisantetelluspharetraidtinciduntinterdummolestiesitametfelis.Utquisquamsitametantesagittisdapibusacnonodio."
525 + "Namrutrummolestiediamidmattis.Cumsociisnatoquepenatibusetmagnisdisparturientmontesnasceturridiculusmus."
526 + "Morbiposueresedmetusacconsectetur.Etiamquisipsumvitaejustotempusmaximus.Sedultriciesplaceratvolutpat."
527 + "Integerlacuslectusmaximusacornarequissagittissitametjusto."
528 + "Cumsociisnatoquepenatibusetmagnisdisparturientmontesnasceturridiculusmus.Maecenasindictumpurussedrutrumex.Nullafacilisi."
529 + "Integerfinibusfinibusmietpharetranislfaucibusvel.Maecenasegetdolorlacinialobortisjustovelullamcorpersem."
530 + "Vivamusaliquetpurusidvariusornaresapienrisusrutrumnisitinciduntmollissemnequeidmetus."
531 + "Etiamquiseleifendpurus.Nuncfelisnuncscelerisqueiddignissimnecfinibusalibero."
532 + "Nuncsemperenimnequesitamethendreritpurusfacilisisac.Maurisdapibussemperfelisdignissimgravida."
533 + "Aeneanultricesblanditnequealiquamfinibusodioscelerisqueac.Aliquamnecmassaeumaurisfaucibusfringilla."
534 + "Etiamconsequatligulanisisitametaliquamnibhtemporquis.Nuncinterdumdignissimnullaatsodalesarcusagittiseu."
535 + "Proinpharetrametusneclacuspulvinarsedvolutpatliberoornare.Sedligulanislpulvinarnonlectuseublanditfacilisisante."
536 + "Sedmollisnislalacusauctorsuscipit.Inhachabitasseplateadictumst.Phasellussitametvelittemporvenenatisfeliseuegestasrisus."
537 + "Aliquameteratsitametnibhcommodofinibus.Morbiefficiturodiovelpulvinariaculis."
538 + "Aeneantemporipsummassaaconsecteturturpisfaucibusultrices.Praesentsodalesmaurisquisportafermentum."
539 + "Etiamnisinislvenenatisvelauctorutullamcorperinjusto.Proinvelligulaerat.Phasellusvestibulumgravidamassanonfeugiat."
540 + "Maecenaspharetraeuismodmetusegetefficitur.Suspendisseamet@gmail.com"));
541 }
542
543 @Test
544 public void testValidator374() {
545 assertTrue(validator.isValid("abc@school.school"));
546 }
547
548 @Test
549 public void testValidator473Part1() {
550 final IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class, () -> new EmailValidator(false, false, null));
551 assertThat(thrown.getMessage(), is(equalTo("DomainValidator cannot be null")));
552 }
553
554 @Test
555 public void testValidator473Part2() {
556 final List<DomainValidator.Item> items = new ArrayList<>();
557 final IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
558 () -> new EmailValidator(false, false, DomainValidator.getInstance(true, items)));
559 assertThat(thrown.getMessage(), is(equalTo("DomainValidator must agree with allowLocal setting")));
560 }
561
562 @Test
563 public void testValidator473Part3() {
564 final List<DomainValidator.Item> items = new ArrayList<>();
565 final IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
566 () -> new EmailValidator(true, false, DomainValidator.getInstance(false, items)));
567 assertThat(thrown.getMessage(), is(equalTo("DomainValidator must agree with allowLocal setting")));
568 }
569
570 @Test
571 public void testValidator473Part4() {
572 assertFalse(validator.isValidDomain("test.local"));
573 final List<DomainValidator.Item> items = new ArrayList<>();
574 items.add(new DomainValidator.Item(DomainValidator.ArrayType.GENERIC_PLUS, "local"));
575 final EmailValidator val = new EmailValidator(true, false, DomainValidator.getInstance(true, items));
576 assertTrue(val.isValidDomain("test.local"));
577 }
578 }