1   /*
2    * $Id: EmailTest.java 329871 2005-10-31 17:50:55Z niallp $
3    * $Rev: 329871 $
4    * $Date: 2005-10-31 17:50:55 +0000 (Mon, 31 Oct 2005) $
5    *
6    * ====================================================================
7    * Copyright 2001-2005 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      * Write this test according to parts of RFC, as opposed to the type of character
208      * that is being tested.
209      *
210      * <p><b>FIXME</b>: This test fails so disable it with a leading _ for 1.1.4 release.
211      * The real solution is to fix the email parsing.
212      *
213      * @throws ValidatorException
214      */
215     public void _testEmailUserName() throws ValidatorException {
216         ValueBean info = new ValueBean();
217         info.setValue("joe1blow@apache.org");
218         valueTest(info, true);
219         info.setValue("joe$blow@apache.org");
220         valueTest(info, true);
221         info.setValue("joe-@apache.org");
222         valueTest(info, true);
223         info.setValue("joe_@apache.org");
224         valueTest(info, true);
225 
226         //UnQuoted Special characters are invalid
227 
228         info.setValue("joe.@apache.org");
229         valueTest(info, false);
230         info.setValue("joe+@apache.org");
231         valueTest(info, false);
232         info.setValue("joe!@apache.org");
233         valueTest(info, false);
234         info.setValue("joe*@apache.org");
235         valueTest(info, false);
236         info.setValue("joe'@apache.org");
237         valueTest(info, false);
238         info.setValue("joe(@apache.org");
239         valueTest(info, false);
240         info.setValue("joe)@apache.org");
241         valueTest(info, false);
242         info.setValue("joe,@apache.org");
243         valueTest(info, false);
244         info.setValue("joe%45@apache.org");
245         valueTest(info, false);
246         info.setValue("joe;@apache.org");
247         valueTest(info, false);
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 
255         //Quoted Special characters are valid
256         info.setValue("\"joe.\"@apache.org");
257         valueTest(info, true);
258         info.setValue("\"joe+\"@apache.org");
259         valueTest(info, true);
260         info.setValue("\"joe!\"@apache.org");
261         valueTest(info, true);
262         info.setValue("\"joe*\"@apache.org");
263         valueTest(info, true);
264         info.setValue("\"joe'\"@apache.org");
265         valueTest(info, true);
266         info.setValue("\"joe(\"@apache.org");
267         valueTest(info, true);
268         info.setValue("\"joe)\"@apache.org");
269         valueTest(info, true);
270         info.setValue("\"joe,\"@apache.org");
271         valueTest(info, true);
272         info.setValue("\"joe%45\"@apache.org");
273         valueTest(info, true);
274         info.setValue("\"joe;\"@apache.org");
275         valueTest(info, true);
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 
283     }
284 
285     /***
286      * These test values derive directly from RFC 822 &
287      * Mail::RFC822::Address & RFC::RFC822::Address perl test.pl
288      * For traceability don't combine these test values with other tests.
289      */
290     TestPair[] testEmailFromPerl = {
291         new TestPair("abigail@example.com", true),
292         new TestPair("abigail@example.com ", true),
293         new TestPair(" abigail@example.com", true),
294         new TestPair("abigail @example.com ", true),
295         new TestPair("*@example.net", true),
296         new TestPair("\"//\"\"@foo.bar", true),
297         new TestPair("fred&barny@example.com", true),
298         new TestPair("---@example.com", true),
299         new TestPair("foo-bar@example.net", true),
300         new TestPair("\"127.0.0.1\"@[127.0.0.1]", true),
301         new TestPair("Abigail <abigail@example.com>", true),
302         new TestPair("Abigail<abigail@example.com>", true),
303         new TestPair("Abigail<@a,@b,@c:abigail@example.com>", true),
304         new TestPair("\"This is a phrase\"<abigail@example.com>", true),
305         new TestPair("\"Abigail \"<abigail@example.com>", true),
306         new TestPair("\"Joe & J. Harvey\" <example @Org>", true),
307         new TestPair("Abigail <abigail @ example.com>", true),
308         new TestPair("Abigail made this <  abigail   @   example  .    com    >", true),
309         new TestPair("Abigail(the bitch)@example.com", true),
310         new TestPair("Abigail <abigail @ example . (bar) com >", true),
311         new TestPair("Abigail < (one)  abigail (two) @(three)example . (bar) com (quz) >", true),
312         new TestPair("Abigail (foo) (((baz)(nested) (comment)) ! ) < (one)  abigail (two) @(three)example . (bar) com (quz) >", true),
313         new TestPair("Abigail <abigail(fo//(o)@example.com>", true),
314         new TestPair("Abigail <abigail(fo//)o)@example.com> ", true),
315         new TestPair("(foo) abigail@example.com", true),
316         new TestPair("abigail@example.com (foo)", true),
317         new TestPair("\"Abi//\"gail\" <abigail@example.com>", true),
318         new TestPair("abigail@[example.com]", true),
319         new TestPair("abigail@[exa//[ple.com]", true),
320         new TestPair("abigail@[exa//]ple.com]", true),
321         new TestPair("\":sysmail\"@  Some-Group. Some-Org", true),
322         new TestPair("Muhammed.(I am  the greatest) Ali @(the)Vegas.WBA", true),
323         new TestPair("mailbox.sub1.sub2@this-domain", true),
324         new TestPair("sub-net.mailbox@sub-domain.domain", true),
325         new TestPair("name:;", true),
326         new TestPair("':;", true),
327         new TestPair("name:   ;", true),
328         new TestPair("Alfred Neuman <Neuman@BBN-TENEXA>", true),
329         new TestPair("Neuman@BBN-TENEXA", true),
330         new TestPair("\"George, Ted\" <Shared@Group.Arpanet>", true),
331         new TestPair("Wilt . (the  Stilt) Chamberlain@NBA.US", true),
332         new TestPair("Cruisers:  Port@Portugal, Jones@SEA;", true),
333         new TestPair("$@[]", true),
334         new TestPair("*()@[]", true),
335         new TestPair("\"quoted ( brackets\" ( a comment )@example.com", true),
336         new TestPair("\"Joe & J. Harvey\"//x0D//x0A     <ddd//@ Org>", true),
337         new TestPair("\"Joe &//x0D//x0A J. Harvey\" <ddd //@ Org>", true),
338         new TestPair("Gourmets:  Pompous Person <WhoZiWhatZit//@Cordon-Bleu>,//x0D//x0A" +
339             "        Childs//@WGBH.Boston, \"Galloping Gourmet\"//@//x0D//x0A" +
340             "        ANT.Down-Under (Australian National Television),//x0D//x0A" +
341             "        Cheapie//@Discount-Liquors;", true),
342         new TestPair("   Just a string", false),
343         new TestPair("string", false),
344         new TestPair("(comment)", false),
345         new TestPair("()@example.com", false),
346         new TestPair("fred(&)barny@example.com", false),
347         new TestPair("fred// barny@example.com", false),
348         new TestPair("Abigail <abi gail @ example.com>", false),
349         new TestPair("Abigail <abigail(fo(o)@example.com>", false),
350         new TestPair("Abigail <abigail(fo)o)@example.com>", false),
351         new TestPair("\"Abi\"gail\" <abigail@example.com>", false),
352         new TestPair("abigail@[exa]ple.com]", false),
353         new TestPair("abigail@[exa[ple.com]", false),
354         new TestPair("abigail@[exaple].com]", false),
355         new TestPair("abigail@", false),
356         new TestPair("@example.com", false),
357         new TestPair("phrase: abigail@example.com abigail@example.com ;", false),
358         new TestPair("invalid£char@example.com", false)
359     };
360 
361     /***
362      * Write this test based on perl Mail::RFC822::Address
363      * which takes its example email address directly from RFC822
364      * 
365      * @throws ValidatorException
366      * 
367      * FIXME This test fails so disable it with a leading _ for 1.1.4 release.
368      * The real solution is to fix the email parsing.
369      */
370     public void _testEmailFromPerl() throws ValidatorException {
371         ValueBean info = new ValueBean();
372         for (int index = 0; index < testEmailFromPerl.length; index++) {
373             info.setValue(testEmailFromPerl[index].item);
374             valueTest(info, testEmailFromPerl[index].valid);
375         }
376     }
377 
378    /***
379     * Utlity class to run a test on a value.
380     *
381     * @param info	Value to run test on.
382     * @param passed	Whether or not the test is expected to pass.
383     */
384    private void valueTest(ValueBean info, boolean passed) throws ValidatorException {
385       // Construct validator based on the loaded resources 
386       // and the form key
387       Validator validator = new Validator(resources, FORM_KEY);
388       // add the name bean to the validator as a resource 
389       // for the validations to be performed on.
390       validator.setParameter(Validator.BEAN_PARAM, info);
391 
392       // Get results of the validation.
393       ValidatorResults results = null;
394       
395       // throws ValidatorException, 
396       // but we aren't catching for testing 
397       // since no validation methods we use 
398       // throw this
399       results = validator.validate();
400       
401       assertNotNull("Results are null.", results);
402       
403       ValidatorResult result = results.getValidatorResult("value");
404 
405       assertNotNull(ACTION + " value ValidatorResult should not be null.", result);
406       assertTrue("Value "+info.getValue()+" ValidatorResult should contain the '" + ACTION +"' action.", result.containsAction(ACTION));
407       assertTrue("Value "+info.getValue()+"ValidatorResult for the '" + ACTION +"' action should have " + (passed ? "passed" : "failed") + ".", (passed ? result.isValid(ACTION) : !result.isValid(ACTION)));
408     }
409 }