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