1   /*
2    * $Id: EmailTest.java 367161 2006-01-09 02:19:23Z niallp $
3    * $Rev: 367161 $
4    * $Date: 2006-01-09 02:19:23 +0000 (Mon, 09 Jan 2006) $
5    *
6    * ====================================================================
7    * Copyright 2001-2006 The Apache Software Foundation
8    *
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   *
13   *     http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   */
21  
22  package org.apache.commons.validator;
23  
24  import java.io.IOException;
25  
26  import junit.framework.Test;
27  import junit.framework.TestSuite;
28  
29  import org.xml.sax.SAXException;
30  
31  /***                                                       
32   * Performs Validation Test for e-mail validations.
33   */                                                       
34  public class EmailTest extends TestCommon {
35  
36      /***
37       * The key used to retrieve the set of validation
38       * rules from the xml file.
39       */
40      protected static String FORM_KEY = "emailForm";
41  
42     /***
43      * The key used to retrieve the validator action.
44      */
45     protected static String ACTION = "email";
46  
47  
48     public EmailTest(String name) {                  
49         super(name);                                      
50     }                                                     
51  
52     /***
53      * Start the tests.
54      *
55      * @param theArgs the arguments. Not used
56      */
57     public static void main(String[] theArgs) {
58         junit.awtui.TestRunner.main(new String[] {EmailTest.class.getName()});
59     }
60  
61     /***
62      * @return a test suite (<code>TestSuite</code>) that includes all methods
63      *         starting with "test"
64      */
65     public static Test suite() {
66         // All methods starting with "test" will be executed in the test suite.
67         return new TestSuite(EmailTest.class);
68     }
69  
70     /***
71      * Load <code>ValidatorResources</code> from 
72      * validator-regexp.xml.
73      */
74     protected void setUp() throws IOException, SAXException {
75        loadResources("EmailTest-config.xml");
76     }
77  
78     protected void tearDown() {
79     }
80  
81     /***
82      * Tests the e-mail validation.
83      */
84     public void testEmail() throws ValidatorException {
85        // Create bean to run test on.
86        ValueBean info = new ValueBean();
87  
88        info.setValue("jsmith@apache.org");
89        valueTest(info, true);
90     }
91      
92     /***
93      * Tests the email validation with numeric domains.
94      */
95      public void testEmailWithNumericAddress() throws ValidatorException {
96          ValueBean info = new ValueBean();
97          info.setValue("someone@[216.109.118.76]");
98          valueTest(info, true);
99          info.setValue("someone@yahoo.com");
100         valueTest(info, true);
101     }
102 
103     /***
104      * Tests the e-mail validation.
105      */
106     public void testEmailExtension() throws ValidatorException {
107         // Create bean to run test on.
108         ValueBean info = new ValueBean();
109 
110         info.setValue("jsmith@apache.org");
111         valueTest(info, true);
112 
113         info.setValue("jsmith@apache.com");
114         valueTest(info, true);
115 
116         info.setValue("jsmith@apache.net");
117         valueTest(info, true);
118 
119         info.setValue("jsmith@apache.info");
120         valueTest(info, true);
121 
122         info.setValue("jsmith@apache.");
123         valueTest(info, false);
124 
125         info.setValue("jsmith@apache.c");
126         valueTest(info, false);
127         
128         info.setValue("someone@yahoo.museum");
129         valueTest(info, true);
130         
131         info.setValue("someone@yahoo.mu-seum");
132         valueTest(info, false);
133     }
134 
135    /***
136     * <p>Tests the e-mail validation with a dash in 
137     * the address.</p>
138     */
139    public void testEmailWithDash() throws ValidatorException {
140       // Create bean to run test on.
141       ValueBean info = new ValueBean();
142 
143       info.setValue("andy.noble@data-workshop.com");
144       valueTest(info, true);
145 
146       info.setValue("andy-noble@data-workshop.-com");
147        valueTest(info, false);
148        info.setValue("andy-noble@data-workshop.c-om");
149        valueTest(info,false);
150        info.setValue("andy-noble@data-workshop.co-m");
151        valueTest(info, false);
152 
153 
154    }
155 
156    /***
157     * Tests the e-mail validation with a dot at the end of 
158     * the address.
159     */
160    public void testEmailWithDotEnd() throws ValidatorException {
161       // Create bean to run test on.
162       ValueBean info = new ValueBean();
163 
164       info.setValue("andy.noble@data-workshop.com.");
165       valueTest(info, false);
166 
167    }
168 
169     /***
170      * Tests the e-mail validation with an RCS-noncompliant character in
171      * the address.
172      */
173     public void testEmailWithBogusCharacter() throws ValidatorException {
174         // Create bean to run test on.
175         ValueBean info = new ValueBean();
176 
177         info.setValue("andy.noble@\u008fdata-workshop.com");
178         valueTest(info, false);
179     
180         // The ' character is valid in an email username.
181         info.setValue("andy.o'reilly@data-workshop.com");
182         valueTest(info, true);
183         
184         // But not in the domain name.
185         info.setValue("andy@o'reilly.data-workshop.com");
186         valueTest(info, false);
187 
188         info.setValue("foo+bar@i.am.not.in.us.example.com");
189         valueTest(info, true);
190     }
191    
192    /***
193     * Tests the email validation with commas.
194     */
195     public void testEmailWithCommas() throws ValidatorException {
196         ValueBean info = new ValueBean();
197         info.setValue("joeblow@apa,che.org");
198         valueTest(info, false);
199         info.setValue("joeblow@apache.o,rg");
200         valueTest(info, false);
201         info.setValue("joeblow@apache,org");
202         valueTest(info, false);
203 
204     }
205    
206    /***
207     * Tests the email validation with spaces.
208     */
209     public void testEmailWithSpaces() throws ValidatorException {
210         ValueBean info = new ValueBean();
211         info.setValue("joeblow @apache.org");
212         valueTest(info, false);
213         info.setValue("joeblow@ apache.org");
214         valueTest(info, false);
215         info.setValue(" joeblow@apache.org");
216         valueTest(info, true);
217         info.setValue("joeblow@apache.org ");
218         valueTest(info, true);
219         info.setValue("joe blow@apache.org ");
220         valueTest(info, false);
221         info.setValue("joeblow@apa che.org ");
222         valueTest(info, false);
223 
224     }
225 
226     /***
227      * Write this test according to parts of RFC, as opposed to the type of character
228      * that is being tested.
229      *
230      * <p><b>FIXME</b>: This test fails so disable it with a leading _ for 1.1.4 release.
231      * The real solution is to fix the email parsing.
232      *
233      * @throws ValidatorException
234      */
235     public void _testEmailUserName() throws ValidatorException {
236         ValueBean info = new ValueBean();
237         info.setValue("joe1blow@apache.org");
238         valueTest(info, true);
239         info.setValue("joe$blow@apache.org");
240         valueTest(info, true);
241         info.setValue("joe-@apache.org");
242         valueTest(info, true);
243         info.setValue("joe_@apache.org");
244         valueTest(info, true);
245 
246         //UnQuoted Special characters are invalid
247 
248         info.setValue("joe.@apache.org");
249         valueTest(info, false);
250         info.setValue("joe+@apache.org");
251         valueTest(info, false);
252         info.setValue("joe!@apache.org");
253         valueTest(info, false);
254         info.setValue("joe*@apache.org");
255         valueTest(info, false);
256         info.setValue("joe'@apache.org");
257         valueTest(info, false);
258         info.setValue("joe(@apache.org");
259         valueTest(info, false);
260         info.setValue("joe)@apache.org");
261         valueTest(info, false);
262         info.setValue("joe,@apache.org");
263         valueTest(info, false);
264         info.setValue("joe%45@apache.org");
265         valueTest(info, false);
266         info.setValue("joe;@apache.org");
267         valueTest(info, false);
268         info.setValue("joe?@apache.org");
269         valueTest(info, false);
270         info.setValue("joe&@apache.org");
271         valueTest(info, false);
272         info.setValue("joe=@apache.org");
273         valueTest(info, false);
274 
275         //Quoted Special characters are valid
276         info.setValue("\"joe.\"@apache.org");
277         valueTest(info, true);
278         info.setValue("\"joe+\"@apache.org");
279         valueTest(info, true);
280         info.setValue("\"joe!\"@apache.org");
281         valueTest(info, true);
282         info.setValue("\"joe*\"@apache.org");
283         valueTest(info, true);
284         info.setValue("\"joe'\"@apache.org");
285         valueTest(info, true);
286         info.setValue("\"joe(\"@apache.org");
287         valueTest(info, true);
288         info.setValue("\"joe)\"@apache.org");
289         valueTest(info, true);
290         info.setValue("\"joe,\"@apache.org");
291         valueTest(info, true);
292         info.setValue("\"joe%45\"@apache.org");
293         valueTest(info, true);
294         info.setValue("\"joe;\"@apache.org");
295         valueTest(info, true);
296         info.setValue("\"joe?\"@apache.org");
297         valueTest(info, true);
298         info.setValue("\"joe&\"@apache.org");
299         valueTest(info, true);
300         info.setValue("\"joe=\"@apache.org");
301         valueTest(info, true);
302 
303     }
304 
305     /***
306      * These test values derive directly from RFC 822 &
307      * Mail::RFC822::Address & RFC::RFC822::Address perl test.pl
308      * For traceability don't combine these test values with other tests.
309      */
310     TestPair[] testEmailFromPerl = {
311         new TestPair("abigail@example.com", true),
312         new TestPair("abigail@example.com ", true),
313         new TestPair(" abigail@example.com", true),
314         new TestPair("abigail @example.com ", true),
315         new TestPair("*@example.net", true),
316         new TestPair("\"//\"\"@foo.bar", true),
317         new TestPair("fred&barny@example.com", true),
318         new TestPair("---@example.com", true),
319         new TestPair("foo-bar@example.net", true),
320         new TestPair("\"127.0.0.1\"@[127.0.0.1]", true),
321         new TestPair("Abigail <abigail@example.com>", true),
322         new TestPair("Abigail<abigail@example.com>", true),
323         new TestPair("Abigail<@a,@b,@c:abigail@example.com>", true),
324         new TestPair("\"This is a phrase\"<abigail@example.com>", true),
325         new TestPair("\"Abigail \"<abigail@example.com>", true),
326         new TestPair("\"Joe & J. Harvey\" <example @Org>", true),
327         new TestPair("Abigail <abigail @ example.com>", true),
328         new TestPair("Abigail made this <  abigail   @   example  .    com    >", true),
329         new TestPair("Abigail(the bitch)@example.com", true),
330         new TestPair("Abigail <abigail @ example . (bar) com >", true),
331         new TestPair("Abigail < (one)  abigail (two) @(three)example . (bar) com (quz) >", true),
332         new TestPair("Abigail (foo) (((baz)(nested) (comment)) ! ) < (one)  abigail (two) @(three)example . (bar) com (quz) >", true),
333         new TestPair("Abigail <abigail(fo//(o)@example.com>", true),
334         new TestPair("Abigail <abigail(fo//)o)@example.com> ", true),
335         new TestPair("(foo) abigail@example.com", true),
336         new TestPair("abigail@example.com (foo)", true),
337         new TestPair("\"Abi//\"gail\" <abigail@example.com>", true),
338         new TestPair("abigail@[example.com]", true),
339         new TestPair("abigail@[exa//[ple.com]", true),
340         new TestPair("abigail@[exa//]ple.com]", true),
341         new TestPair("\":sysmail\"@  Some-Group. Some-Org", true),
342         new TestPair("Muhammed.(I am  the greatest) Ali @(the)Vegas.WBA", true),
343         new TestPair("mailbox.sub1.sub2@this-domain", true),
344         new TestPair("sub-net.mailbox@sub-domain.domain", true),
345         new TestPair("name:;", true),
346         new TestPair("':;", true),
347         new TestPair("name:   ;", true),
348         new TestPair("Alfred Neuman <Neuman@BBN-TENEXA>", true),
349         new TestPair("Neuman@BBN-TENEXA", true),
350         new TestPair("\"George, Ted\" <Shared@Group.Arpanet>", true),
351         new TestPair("Wilt . (the  Stilt) Chamberlain@NBA.US", true),
352         new TestPair("Cruisers:  Port@Portugal, Jones@SEA;", true),
353         new TestPair("$@[]", true),
354         new TestPair("*()@[]", true),
355         new TestPair("\"quoted ( brackets\" ( a comment )@example.com", true),
356         new TestPair("\"Joe & J. Harvey\"//x0D//x0A     <ddd//@ Org>", true),
357         new TestPair("\"Joe &//x0D//x0A J. Harvey\" <ddd //@ Org>", true),
358         new TestPair("Gourmets:  Pompous Person <WhoZiWhatZit//@Cordon-Bleu>,//x0D//x0A" +
359             "        Childs//@WGBH.Boston, \"Galloping Gourmet\"//@//x0D//x0A" +
360             "        ANT.Down-Under (Australian National Television),//x0D//x0A" +
361             "        Cheapie//@Discount-Liquors;", true),
362         new TestPair("   Just a string", false),
363         new TestPair("string", false),
364         new TestPair("(comment)", false),
365         new TestPair("()@example.com", false),
366         new TestPair("fred(&)barny@example.com", false),
367         new TestPair("fred// barny@example.com", false),
368         new TestPair("Abigail <abi gail @ example.com>", false),
369         new TestPair("Abigail <abigail(fo(o)@example.com>", false),
370         new TestPair("Abigail <abigail(fo)o)@example.com>", false),
371         new TestPair("\"Abi\"gail\" <abigail@example.com>", false),
372         new TestPair("abigail@[exa]ple.com]", false),
373         new TestPair("abigail@[exa[ple.com]", false),
374         new TestPair("abigail@[exaple].com]", false),
375         new TestPair("abigail@", false),
376         new TestPair("@example.com", false),
377         new TestPair("phrase: abigail@example.com abigail@example.com ;", false),
378         new TestPair("invalid£char@example.com", false)
379     };
380 
381     /***
382      * Write this test based on perl Mail::RFC822::Address
383      * which takes its example email address directly from RFC822
384      * 
385      * @throws ValidatorException
386      * 
387      * FIXME This test fails so disable it with a leading _ for 1.1.4 release.
388      * The real solution is to fix the email parsing.
389      */
390     public void _testEmailFromPerl() throws ValidatorException {
391         ValueBean info = new ValueBean();
392         for (int index = 0; index < testEmailFromPerl.length; index++) {
393             info.setValue(testEmailFromPerl[index].item);
394             valueTest(info, testEmailFromPerl[index].valid);
395         }
396     }
397 
398    /***
399     * Utlity class to run a test on a value.
400     *
401     * @param info	Value to run test on.
402     * @param passed	Whether or not the test is expected to pass.
403     */
404    private void valueTest(ValueBean info, boolean passed) throws ValidatorException {
405       // Construct validator based on the loaded resources 
406       // and the form key
407       Validator validator = new Validator(resources, FORM_KEY);
408       // add the name bean to the validator as a resource 
409       // for the validations to be performed on.
410       validator.setParameter(Validator.BEAN_PARAM, info);
411 
412       // Get results of the validation.
413       ValidatorResults results = null;
414       
415       // throws ValidatorException, 
416       // but we aren't catching for testing 
417       // since no validation methods we use 
418       // throw this
419       results = validator.validate();
420       
421       assertNotNull("Results are null.", results);
422       
423       ValidatorResult result = results.getValidatorResult("value");
424 
425       assertNotNull(ACTION + " value ValidatorResult should not be null.", result);
426       assertTrue("Value "+info.getValue()+" ValidatorResult should contain the '" + ACTION +"' action.", result.containsAction(ACTION));
427       assertTrue("Value "+info.getValue()+"ValidatorResult for the '" + ACTION +"' action should have " + (passed ? "passed" : "failed") + ".", (passed ? result.isValid(ACTION) : !result.isValid(ACTION)));
428     }
429 }