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    *      http://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 junit.framework.TestCase;
20  import org.apache.commons.validator.routines.checkdigit.LuhnCheckDigit;
21  import org.apache.commons.validator.routines.CreditCardValidator.CreditCardRange;
22  
23  /**
24   * Test the CreditCardValidator class.
25   *
26   * @version $Revision$
27   */
28  public class CreditCardValidatorTest extends TestCase {
29      
30      private static final String VALID_VISA       = "4417123456789113"; // 16
31      private static final String ERROR_VISA       = "4417123456789112"; 
32      private static final String VALID_SHORT_VISA = "4222222222222"; // 13
33      private static final String ERROR_SHORT_VISA = "4222222222229";
34      private static final String VALID_AMEX       = "378282246310005"; // 15
35      private static final String ERROR_AMEX       = "378282246310001";
36      private static final String VALID_MASTERCARD = "5105105105105100";
37      private static final String ERROR_MASTERCARD = "5105105105105105";
38      private static final String VALID_DISCOVER   = "6011000990139424";
39      private static final String ERROR_DISCOVER   = "6011000990139421";
40      private static final String VALID_DISCOVER65 = "6534567890123458"; // FIXME need verified test data for Discover with "65" prefix
41      private static final String ERROR_DISCOVER65 = "6534567890123450"; // FIXME need verified test data for Discover with "65" prefix
42      private static final String VALID_DINERS     = "30569309025904"; // 14
43      private static final String ERROR_DINERS     = "30569309025901";
44      private static final String VALID_VPAY       = "4370000000000061"; // 16
45      private static final String VALID_VPAY2      = "4370000000000012";
46      private static final String ERROR_VPAY       = "4370000000000069";
47  
48      private static final String [] VALID_CARDS = {
49          VALID_VISA,
50          VALID_SHORT_VISA,
51          VALID_AMEX,
52          VALID_MASTERCARD,
53          VALID_DISCOVER,
54          VALID_DISCOVER65,
55          VALID_DINERS,
56          VALID_VPAY,
57          VALID_VPAY2,
58          "60115564485789458", // VALIDATOR-403
59      };
60  
61      private static final String [] ERROR_CARDS = {
62          ERROR_VISA,
63          ERROR_SHORT_VISA,
64          ERROR_AMEX,
65          ERROR_MASTERCARD,
66          ERROR_DISCOVER,
67          ERROR_DISCOVER65,
68          ERROR_DINERS,
69          ERROR_VPAY,
70  //        ERROR_VPAY2,
71          "",
72          "12345678901", // too short (11)
73          "12345678901234567890", // too long (20)
74          "4417123456789112", // invalid check digit
75      };
76  
77      /**
78       * Constructor for CreditCardValidatorTest.
79       */
80      public CreditCardValidatorTest(String name) {
81          super(name);
82      }
83  
84      public void testIsValid() {
85          CreditCardValidator ccv = new CreditCardValidator();
86          
87          assertNull(ccv.validate(null));
88  
89          assertFalse(ccv.isValid(null));
90          assertFalse(ccv.isValid(""));
91          assertFalse(ccv.isValid("123456789012"));   // too short
92          assertFalse(ccv.isValid("12345678901234567890"));   // too long
93          assertFalse(ccv.isValid("4417123456789112"));
94          assertFalse(ccv.isValid("4417q23456w89113"));
95          assertTrue(ccv.isValid(VALID_VISA));
96          assertTrue(ccv.isValid(VALID_SHORT_VISA));
97          assertTrue(ccv.isValid(VALID_AMEX));
98          assertTrue(ccv.isValid(VALID_MASTERCARD));
99          assertTrue(ccv.isValid(VALID_DISCOVER));
100         assertTrue(ccv.isValid(VALID_DISCOVER65));
101 
102         assertFalse(ccv.isValid(ERROR_VISA));
103         assertFalse(ccv.isValid(ERROR_SHORT_VISA));
104         assertFalse(ccv.isValid(ERROR_AMEX));
105         assertFalse(ccv.isValid(ERROR_MASTERCARD));
106         assertFalse(ccv.isValid(ERROR_DISCOVER));
107         assertFalse(ccv.isValid(ERROR_DISCOVER65));
108         
109         // disallow Visa so it should fail even with good number
110         ccv = new CreditCardValidator(CreditCardValidator.AMEX);
111         assertFalse(ccv.isValid("4417123456789113"));
112     }
113     
114     public void testAddAllowedCardType() {
115         CreditCardValidator ccv = new CreditCardValidator(CreditCardValidator.NONE);
116         // Turned off all cards so even valid numbers should fail
117         assertFalse(ccv.isValid(VALID_VISA));
118         assertFalse(ccv.isValid(VALID_AMEX));
119         assertFalse(ccv.isValid(VALID_MASTERCARD));
120         assertFalse(ccv.isValid(VALID_DISCOVER));
121         assertFalse(ccv.isValid(VALID_DINERS));
122     }
123 
124     /**
125      * Test the CodeValidator array constructor
126      */    
127     public void testArrayConstructor() {
128         CreditCardValidator ccv = new CreditCardValidator(new CodeValidator[]
129                {CreditCardValidator.VISA_VALIDATOR, CreditCardValidator.AMEX_VALIDATOR});
130         
131         assertTrue(ccv.isValid(VALID_VISA));
132         assertTrue(ccv.isValid(VALID_SHORT_VISA));
133         assertTrue(ccv.isValid(VALID_AMEX));
134         assertFalse(ccv.isValid(VALID_MASTERCARD));
135         assertFalse(ccv.isValid(VALID_DISCOVER));
136 
137         assertFalse(ccv.isValid(ERROR_VISA));
138         assertFalse(ccv.isValid(ERROR_SHORT_VISA));
139         assertFalse(ccv.isValid(ERROR_AMEX));
140         assertFalse(ccv.isValid(ERROR_MASTERCARD));
141         assertFalse(ccv.isValid(ERROR_DISCOVER));
142 
143         try {
144             new CreditCardValidator((CodeValidator[]) null);
145             fail("Expected IllegalArgumentException");
146         } catch(IllegalArgumentException iae) {
147             // expected result
148         }
149     }
150 
151     /**
152      * Test the Amex Card validator
153      */    
154     public void testAmexValidator() {
155 
156         CodeValidator validator = CreditCardValidator.AMEX_VALIDATOR;
157         RegexValidator regex    = validator.getRegexValidator();
158 
159         // ****** Test Regular Expression ******
160         // length 15 and start with a "34" or "37"
161         assertFalse("Length 12",      regex.isValid("343456789012"));
162         assertFalse("Length 13",      regex.isValid("3434567890123"));
163         assertFalse("Length 14",      regex.isValid("34345678901234"));
164         assertTrue("Length 15",       regex.isValid("343456789012345"));
165         assertFalse("Length 16",      regex.isValid("3434567890123456"));
166         assertFalse("Length 17",      regex.isValid("34345678901234567"));
167         assertFalse("Length 18",      regex.isValid("343456789012345678"));
168         assertFalse("Prefix 33",      regex.isValid("333456789012345"));
169         assertTrue("Prefix 34",       regex.isValid("343456789012345"));
170         assertFalse("Prefix 35",      regex.isValid("353456789012345"));
171         assertFalse("Prefix 36",      regex.isValid("363456789012345"));
172         assertTrue("Prefix 37",       regex.isValid("373456789012345"));
173         assertFalse("Prefix 38",      regex.isValid("383456789012345"));
174         assertFalse("Prefix 41",      regex.isValid("413456789012345"));
175         assertFalse("Invalid Char",   regex.isValid("3434567x9012345"));
176 
177         // *********** Test Validator **********
178         assertTrue("Valid regex",     regex.isValid(ERROR_AMEX));
179         assertFalse("Invalid",        validator.isValid(ERROR_AMEX));
180         assertNull("validate()",      validator.validate(ERROR_AMEX));
181         assertEquals(VALID_AMEX,      validator.validate(VALID_AMEX));
182 
183         assertTrue("Amex",            validator.isValid(VALID_AMEX));
184         assertFalse("Diners",         validator.isValid(VALID_DINERS));
185         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
186         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
187         assertFalse("Visa",           validator.isValid(VALID_VISA));
188         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
189         
190         assertTrue("Valid-A",         validator.isValid("371449635398431"));
191         assertTrue("Valid-B",         validator.isValid("340000000000009"));
192         assertTrue("Valid-C",         validator.isValid("370000000000002"));
193         assertTrue("Valid-D",         validator.isValid("378734493671000"));
194     }
195 
196     /**
197      * Test the Amex Card option
198      */    
199     public void testAmexOption() {
200         CreditCardValidator validator = new CreditCardValidator(CreditCardValidator.AMEX);
201         assertFalse("Invalid",        validator.isValid(ERROR_AMEX));
202         assertNull("validate()",      validator.validate(ERROR_AMEX));
203         assertEquals(VALID_AMEX,      validator.validate(VALID_AMEX));
204 
205         assertTrue("Amex",            validator.isValid(VALID_AMEX));
206         assertFalse("Diners",         validator.isValid(VALID_DINERS));
207         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
208         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
209         assertFalse("Visa",           validator.isValid(VALID_VISA));
210         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
211     }
212 
213     /**
214      * Test the Diners Card validator
215      */    
216     public void testDinersValidator() {
217 
218         CodeValidator validator = CreditCardValidator.DINERS_VALIDATOR;
219         RegexValidator regex    = validator.getRegexValidator();
220 
221         // ****** Test Regular Expression ******
222         // length 14 and start with a "300-305" or "3095" or "36" or "38" or "39"
223         assertFalse("Length 12-300",  regex.isValid("300456789012"));
224         assertFalse("Length 12-36",   regex.isValid("363456789012"));
225         assertFalse("Length 13-300",  regex.isValid("3004567890123"));
226         assertFalse("Length 13-36",   regex.isValid("3634567890123"));
227         assertTrue("Length 14-300",   regex.isValid("30045678901234"));
228         assertTrue("Length 14-36",    regex.isValid("36345678901234"));
229         assertFalse("Length 15-300",  regex.isValid("300456789012345"));
230         assertFalse("Length 15-36",   regex.isValid("363456789012345"));
231         assertFalse("Length 16-300",  regex.isValid("3004567890123456"));
232         assertFalse("Length 16-36",   regex.isValid("3634567890123456"));
233         assertFalse("Length 17-300",  regex.isValid("30045678901234567"));
234         assertFalse("Length 17-36",   regex.isValid("36345678901234567"));
235         assertFalse("Length 18-300",  regex.isValid("300456789012345678"));
236         assertFalse("Length 18-36",   regex.isValid("363456789012345678"));
237 
238         assertTrue("Prefix 300",      regex.isValid("30045678901234"));
239         assertTrue("Prefix 301",      regex.isValid("30145678901234"));
240         assertTrue("Prefix 302",      regex.isValid("30245678901234"));
241         assertTrue("Prefix 303",      regex.isValid("30345678901234"));
242         assertTrue("Prefix 304",      regex.isValid("30445678901234"));
243         assertTrue("Prefix 305",      regex.isValid("30545678901234"));
244         assertFalse("Prefix 306",     regex.isValid("30645678901234"));
245         assertFalse("Prefix 3094",    regex.isValid("30945678901234"));
246         assertTrue( "Prefix 3095",    regex.isValid("30955678901234"));
247         assertFalse("Prefix 3096",    regex.isValid("30965678901234"));
248         assertFalse("Prefix 35",      regex.isValid("35345678901234"));
249         assertTrue("Prefix 36",       regex.isValid("36345678901234"));
250         assertFalse("Prefix 37",      regex.isValid("37345678901234"));
251         assertTrue("Prefix 38",       regex.isValid("38345678901234"));
252         assertTrue("Prefix 39",       regex.isValid("39345678901234"));
253 
254         assertFalse("Invalid Char-A", regex.isValid("3004567x901234"));
255         assertFalse("Invalid Char-B", regex.isValid("3634567x901234"));
256 
257         // *********** Test Validator **********
258         assertTrue("Valid regex",     regex.isValid(ERROR_DINERS));
259         assertFalse("Invalid",        validator.isValid(ERROR_DINERS));
260         assertNull("validate()",      validator.validate(ERROR_DINERS));
261         assertEquals(VALID_DINERS,    validator.validate(VALID_DINERS));
262 
263         assertFalse("Amex",           validator.isValid(VALID_AMEX));
264         assertTrue("Diners",          validator.isValid(VALID_DINERS));
265         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
266         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
267         assertFalse("Visa",           validator.isValid(VALID_VISA));
268         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
269         
270         assertTrue("Valid-A",         validator.isValid("30000000000004"));
271         assertTrue("Valid-B",         validator.isValid("30123456789019"));
272         assertTrue("Valid-C",         validator.isValid("36432685260294"));
273 
274     }
275 
276     /**
277      * Test the Diners Card option
278      */    
279     public void testDinersOption() {
280         CreditCardValidator validator = new CreditCardValidator(CreditCardValidator.DINERS);
281         assertFalse("Invalid",        validator.isValid(ERROR_DINERS));
282         assertNull("validate()",      validator.validate(ERROR_DINERS));
283         assertEquals(VALID_DINERS,    validator.validate(VALID_DINERS));
284 
285         assertFalse("Amex",           validator.isValid(VALID_AMEX));
286         assertTrue("Diners",          validator.isValid(VALID_DINERS));
287         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
288         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
289         assertFalse("Visa",           validator.isValid(VALID_VISA));
290         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
291     }
292 
293     /**
294      * Test the Discover Card validator
295      */    
296     public void testDiscoverValidator() {
297 
298         CodeValidator validator = CreditCardValidator.DISCOVER_VALIDATOR;
299         RegexValidator regex    = validator.getRegexValidator();
300 
301         // ****** Test Regular Expression ******
302         // length 16 and start with either "6011" or or "64[4-9]" or "65"
303         assertFalse("Length 12-6011", regex.isValid("601156789012"));
304         assertFalse("Length 12-65",   regex.isValid("653456789012"));
305         assertFalse("Length 13-6011", regex.isValid("6011567890123"));
306         assertFalse("Length 13-65",   regex.isValid("6534567890123"));
307         assertFalse("Length 14-6011", regex.isValid("60115678901234"));
308         assertFalse("Length 14-65",   regex.isValid("65345678901234"));
309         assertFalse("Length 15-6011", regex.isValid("601156789012345"));
310         assertFalse("Length 15-65",   regex.isValid("653456789012345"));
311         assertTrue("Length 16-6011",  regex.isValid("6011567890123456"));
312         assertTrue("Length 16-644",   regex.isValid("6444567890123456"));
313         assertTrue("Length 16-648",   regex.isValid("6484567890123456"));
314         assertTrue("Length 16-65",    regex.isValid("6534567890123456"));
315         assertFalse("Length 17-65",   regex.isValid("65345678901234567"));
316         assertFalse("Length 18-6011", regex.isValid("601156789012345678"));
317         assertFalse("Length 18-65",   regex.isValid("653456789012345678"));
318 
319         assertFalse("Prefix 640",     regex.isValid("6404567890123456"));
320         assertFalse("Prefix 641",     regex.isValid("6414567890123456"));
321         assertFalse("Prefix 642",     regex.isValid("6424567890123456"));
322         assertFalse("Prefix 643",     regex.isValid("6434567890123456"));
323         assertFalse("Prefix 6010",    regex.isValid("6010567890123456"));
324         assertFalse("Prefix 6012",    regex.isValid("6012567890123456"));
325         assertFalse("Invalid Char",   regex.isValid("6011567x90123456"));
326 
327         // *********** Test Validator **********
328         assertTrue("Valid regex",     regex.isValid(ERROR_DISCOVER));
329         assertTrue("Valid regex65",   regex.isValid(ERROR_DISCOVER65));
330         assertFalse("Invalid",        validator.isValid(ERROR_DISCOVER));
331         assertFalse("Invalid65",      validator.isValid(ERROR_DISCOVER65));
332         assertNull("validate()",      validator.validate(ERROR_DISCOVER));
333         assertEquals(VALID_DISCOVER,  validator.validate(VALID_DISCOVER));
334         assertEquals(VALID_DISCOVER65, validator.validate(VALID_DISCOVER65));
335 
336         assertFalse("Amex",           validator.isValid(VALID_AMEX));
337         assertFalse("Diners",         validator.isValid(VALID_DINERS));
338         assertTrue("Discover",        validator.isValid(VALID_DISCOVER));
339         assertTrue("Discover",        validator.isValid(VALID_DISCOVER65));
340         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
341         assertFalse("Visa",           validator.isValid(VALID_VISA));
342         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
343         
344         assertTrue("Valid-A",         validator.isValid("6011111111111117"));
345         assertTrue("Valid-B",         validator.isValid("6011000000000004"));
346         assertTrue("Valid-C",         validator.isValid("6011000000000012"));
347 
348     }
349 
350     /**
351      * Test the Discover Card option
352      */    
353     public void testDiscoverOption() {
354         CreditCardValidator validator = new CreditCardValidator(CreditCardValidator.DISCOVER);
355         assertFalse("Invalid",        validator.isValid(ERROR_DISCOVER));
356         assertFalse("Invalid65",      validator.isValid(ERROR_DISCOVER65));
357         assertNull("validate()",      validator.validate(ERROR_DISCOVER));
358         assertEquals(VALID_DISCOVER,  validator.validate(VALID_DISCOVER));
359         assertEquals(VALID_DISCOVER65, validator.validate(VALID_DISCOVER65));
360 
361         assertFalse("Amex",           validator.isValid(VALID_AMEX));
362         assertFalse("Diners",         validator.isValid(VALID_DINERS));
363         assertTrue("Discover",        validator.isValid(VALID_DISCOVER));
364         assertTrue("Discover",        validator.isValid(VALID_DISCOVER65));
365         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
366         assertFalse("Visa",           validator.isValid(VALID_VISA));
367         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
368     }
369 
370     /**
371      * Test the Mastercard Card validator
372      */    
373     public void testMastercardValidator() {
374 
375         CodeValidator validator = CreditCardValidator.MASTERCARD_VALIDATOR;
376         RegexValidator regex    = validator.getRegexValidator();
377 
378         // ****** Test Regular Expression ******
379         // length 16 and start with a "51-55"
380         assertFalse("Length 12",      regex.isValid("513456789012"));
381         assertFalse("Length 13",      regex.isValid("5134567890123"));
382         assertFalse("Length 14",      regex.isValid("51345678901234"));
383         assertFalse("Length 15",      regex.isValid("513456789012345"));
384         assertTrue("Length 16",       regex.isValid("5134567890123456"));
385         assertFalse("Length 17",      regex.isValid("51345678901234567"));
386         assertFalse("Length 18",      regex.isValid("513456789012345678"));
387         assertFalse("Prefix 41",      regex.isValid("4134567890123456"));
388         assertFalse("Prefix 50",      regex.isValid("5034567890123456"));
389         assertTrue("Prefix 51",       regex.isValid("5134567890123456"));
390         assertTrue("Prefix 52",       regex.isValid("5234567890123456"));
391         assertTrue("Prefix 53",       regex.isValid("5334567890123456"));
392         assertTrue("Prefix 54",       regex.isValid("5434567890123456"));
393         assertTrue("Prefix 55",       regex.isValid("5534567890123456"));
394         assertFalse("Prefix 56",      regex.isValid("5634567890123456"));
395         assertFalse("Prefix 61",      regex.isValid("6134567890123456"));
396         assertFalse("Invalid Char",   regex.isValid("5134567x90123456"));
397 
398         // *********** Test Validator **********
399         assertTrue("Valid regex",     regex.isValid(ERROR_MASTERCARD));
400         assertFalse("Invalid",        validator.isValid(ERROR_MASTERCARD));
401         assertNull("validate()",      validator.validate(ERROR_MASTERCARD));
402         assertEquals(VALID_MASTERCARD, validator.validate(VALID_MASTERCARD));
403 
404         assertFalse("Amex",           validator.isValid(VALID_AMEX));
405         assertFalse("Diners",         validator.isValid(VALID_DINERS));
406         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
407         assertTrue("Mastercard",      validator.isValid(VALID_MASTERCARD));
408         assertFalse("Visa",           validator.isValid(VALID_VISA));
409         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
410         
411         assertTrue("Valid-A",         validator.isValid("5500000000000004"));
412         assertTrue("Valid-B",         validator.isValid("5424000000000015"));
413         assertTrue("Valid-C",         validator.isValid("5301250070000191"));
414         assertTrue("Valid-D",         validator.isValid("5123456789012346"));
415         assertTrue("Valid-E",         validator.isValid("5555555555554444"));
416         
417         RegexValidator rev = validator.getRegexValidator();
418         final String PAD = "0000000000";
419         assertFalse("222099",rev.isValid("222099"+PAD));
420         for(int i=222100; i <= 272099; i++) {
421             String j = Integer.toString(i)+PAD;
422             assertTrue(j, rev.isValid(j));
423         }
424         assertFalse("272100",rev.isValid("272100"+PAD));
425     }
426 
427     /**
428      * Test the Mastercard Card option
429      */    
430     public void testMastercardOption() {
431         CreditCardValidator validator = new CreditCardValidator(CreditCardValidator.MASTERCARD);
432         assertFalse("Invalid",        validator.isValid(ERROR_MASTERCARD));
433         assertNull("validate()",      validator.validate(ERROR_MASTERCARD));
434         assertEquals(VALID_MASTERCARD, validator.validate(VALID_MASTERCARD));
435 
436         assertFalse("Amex",           validator.isValid(VALID_AMEX));
437         assertFalse("Diners",         validator.isValid(VALID_DINERS));
438         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
439         assertTrue("Mastercard",      validator.isValid(VALID_MASTERCARD));
440         assertFalse("Visa",           validator.isValid(VALID_VISA));
441         assertFalse("Visa Short",     validator.isValid(VALID_SHORT_VISA));
442     }
443 
444     /**
445      * Test the Visa Card validator
446      */    
447     public void testVisaValidator() {
448 
449         CodeValidator validator = CreditCardValidator.VISA_VALIDATOR;
450         RegexValidator regex    = validator.getRegexValidator();
451 
452         // ****** Test Regular Expression ******
453         // length 13 or 16, must start with a "4"
454         assertFalse("Length 12",      regex.isValid("423456789012"));
455         assertTrue("Length 13",       regex.isValid("4234567890123"));
456         assertFalse("Length 14",      regex.isValid("42345678901234"));
457         assertFalse("Length 15",      regex.isValid("423456789012345"));
458         assertTrue("Length 16",       regex.isValid("4234567890123456"));
459         assertFalse("Length 17",      regex.isValid("42345678901234567"));
460         assertFalse("Length 18",      regex.isValid("423456789012345678"));
461         assertFalse("Invalid Pref-A", regex.isValid("3234567890123"));
462         assertFalse("Invalid Pref-B", regex.isValid("3234567890123456"));
463         assertFalse("Invalid Char-A", regex.isValid("4234567x90123"));
464         assertFalse("Invalid Char-B", regex.isValid("4234567x90123456"));
465 
466         // *********** Test Validator **********
467         assertTrue("Valid regex",     regex.isValid(ERROR_VISA));
468         assertTrue("Valid regex-S",   regex.isValid(ERROR_SHORT_VISA));
469         assertFalse("Invalid",        validator.isValid(ERROR_VISA));
470         assertFalse("Invalid-S",      validator.isValid(ERROR_SHORT_VISA));
471         assertNull("validate()",      validator.validate(ERROR_VISA));
472         assertEquals(VALID_VISA,      validator.validate(VALID_VISA));
473         assertEquals(VALID_SHORT_VISA, validator.validate(VALID_SHORT_VISA));
474 
475         assertFalse("Amex",           validator.isValid(VALID_AMEX));
476         assertFalse("Diners",         validator.isValid(VALID_DINERS));
477         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
478         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
479         assertTrue("Visa",            validator.isValid(VALID_VISA));
480         assertTrue("Visa Short",      validator.isValid(VALID_SHORT_VISA));
481         
482         assertTrue("Valid-A",         validator.isValid("4111111111111111"));
483         assertTrue("Valid-C",         validator.isValid("4543059999999982"));
484         assertTrue("Valid-B",         validator.isValid("4462000000000003"));
485         assertTrue("Valid-D",         validator.isValid("4508750000000009")); // Electron
486         assertTrue("Valid-E",         validator.isValid("4012888888881881"));
487     }
488 
489     /**
490      * Test the Visa Card option
491      */    
492     public void testVisaOption() {
493         CreditCardValidator validator = new CreditCardValidator(CreditCardValidator.VISA);
494         assertFalse("Invalid",        validator.isValid(ERROR_VISA));
495         assertFalse("Invalid-S",      validator.isValid(ERROR_SHORT_VISA));
496         assertNull("validate()",      validator.validate(ERROR_VISA));
497         assertEquals(VALID_VISA,      validator.validate(VALID_VISA));
498         assertEquals(VALID_SHORT_VISA, validator.validate(VALID_SHORT_VISA));
499 
500         assertFalse("Amex",           validator.isValid(VALID_AMEX));
501         assertFalse("Diners",         validator.isValid(VALID_DINERS));
502         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
503         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
504         assertTrue("Visa",            validator.isValid(VALID_VISA));
505         assertTrue("Visa Short",      validator.isValid(VALID_SHORT_VISA));
506     }
507 
508     public void testVPayOption() {
509         CreditCardValidator validator = new CreditCardValidator(CreditCardValidator.VPAY);
510         assertTrue("Valid",           validator.isValid(VALID_VPAY));
511         assertTrue("Valid",           validator.isValid(VALID_VPAY2));
512         assertFalse("Invalid",        validator.isValid(ERROR_VPAY));
513         assertEquals(VALID_VPAY,      validator.validate(VALID_VPAY));
514         assertEquals(VALID_VPAY2,      validator.validate(VALID_VPAY2));
515 
516         assertFalse("Amex",           validator.isValid(VALID_AMEX));
517         assertFalse("Diners",         validator.isValid(VALID_DINERS));
518         assertFalse("Discover",       validator.isValid(VALID_DISCOVER));
519         assertFalse("Mastercard",     validator.isValid(VALID_MASTERCARD));
520         assertTrue("Visa",            validator.isValid(VALID_VISA));
521         assertTrue("Visa Short",      validator.isValid(VALID_SHORT_VISA));        
522     }
523 
524     /**
525      * Test using separators
526      */    
527     public void testMastercardUsingSeparators() {
528 
529         String MASTERCARD_REGEX_SEP = "^(5[1-5]\\d{2})(?:[- ])?(\\d{4})(?:[- ])?(\\d{4})(?:[- ])?(\\d{4})$";
530         CodeValidator validator = new CodeValidator(MASTERCARD_REGEX_SEP, LuhnCheckDigit.LUHN_CHECK_DIGIT);
531         RegexValidator regex    = validator.getRegexValidator();
532 
533         // ****** Test Regular Expression ******
534         // length 16 and start with a "51-55"
535         assertEquals("Number",  "5134567890123456", regex.validate("5134567890123456"));
536         assertEquals("Hyphen",  "5134567890123456", regex.validate("5134-5678-9012-3456"));
537         assertEquals("Space",   "5134567890123456", regex.validate("5134 5678 9012 3456"));
538         assertEquals("MixedA",  "5134567890123456", regex.validate("5134-5678 9012-3456"));
539         assertEquals("MixedB",  "5134567890123456", regex.validate("5134 5678-9012 3456"));
540 
541         assertFalse("Invalid Separator A",  regex.isValid("5134.5678.9012.3456"));
542         assertFalse("Invalid Separator B",  regex.isValid("5134_5678_9012_3456"));
543         assertFalse("Invalid Grouping A",   regex.isValid("513-45678-9012-3456"));
544         assertFalse("Invalid Grouping B",   regex.isValid("5134-567-89012-3456"));
545         assertFalse("Invalid Grouping C",   regex.isValid("5134-5678-901-23456"));
546 
547         // *********** Test Validator **********
548         assertEquals("Valid-A", "5500000000000004", validator.validate("5500-0000-0000-0004"));
549         assertEquals("Valid-B", "5424000000000015", validator.validate("5424 0000 0000 0015"));
550         assertEquals("Valid-C", "5301250070000191", validator.validate("5301-250070000191"));
551         assertEquals("Valid-D", "5123456789012346", validator.validate("5123456789012346"));
552     }
553 
554     public void testGeneric() {
555         CreditCardValidator ccv = CreditCardValidator.genericCreditCardValidator();
556         for(String s : VALID_CARDS) {
557             assertTrue(s, ccv.isValid(s));
558         }
559         for(String s : ERROR_CARDS) {
560             assertFalse(s, ccv.isValid(s));
561         }
562     }
563 
564     public void testRangeGeneratorNoLuhn() {
565         CodeValidator cv = CreditCardValidator.createRangeValidator(
566             new CreditCardRange[]{
567                 new CreditCardRange("1",null,6,7),
568                 new CreditCardRange("644","65", 8, 8)
569             }, 
570             null);
571         assertTrue(cv.isValid("1990000"));
572         assertTrue(cv.isValid("199000"));
573         assertFalse(cv.isValid("000000"));
574         assertFalse(cv.isValid("099999"));
575         assertFalse(cv.isValid("200000"));
576 
577         assertFalse(cv.isValid("64399999"));
578         assertTrue(cv.isValid("64400000"));
579         assertTrue(cv.isValid("64900000"));
580         assertTrue(cv.isValid("65000000"));
581         assertTrue(cv.isValid("65999999"));
582         assertFalse(cv.isValid("66000000"));
583     }
584 
585     public void testRangeGenerator() {
586         CreditCardValidator ccv = new CreditCardValidator(
587             new CodeValidator[] {
588                 CreditCardValidator.AMEX_VALIDATOR,
589                 CreditCardValidator.VISA_VALIDATOR,
590                 CreditCardValidator.MASTERCARD_VALIDATOR,
591                 CreditCardValidator.DISCOVER_VALIDATOR,
592             },
593             // Add missing validator
594             new CreditCardRange[]{
595                 new CreditCardRange("300", "305", 14, 14), // Diners
596                 new CreditCardRange("3095", null, 14, 14), // Diners
597                 new CreditCardRange("36",   null, 14, 14), // Diners
598                 new CreditCardRange("38",   "39", 14, 14), // Diners
599             }
600             // we don't have any VPAY examples yet that aren't handled by VISA
601             );
602         for(String s : VALID_CARDS) {
603             assertTrue(s, ccv.isValid(s));
604         }
605         for(String s : ERROR_CARDS) {
606             assertFalse(s, ccv.isValid(s));
607         }
608     }
609 
610     public void testValidLength() {
611         assertTrue(CreditCardValidator.validLength(14, new CreditCardRange("", "", 14, 14)));
612         assertFalse(CreditCardValidator.validLength(15, new CreditCardRange("", "", 14, 14)));
613         assertFalse(CreditCardValidator.validLength(13, new CreditCardRange("", "", 14, 14)));
614 
615         assertFalse(CreditCardValidator.validLength(14, new CreditCardRange("", "", 15, 17)));
616         assertTrue(CreditCardValidator.validLength(15, new CreditCardRange("", "", 15, 17)));
617         assertTrue(CreditCardValidator.validLength(16, new CreditCardRange("", "", 15, 17)));
618         assertTrue(CreditCardValidator.validLength(17, new CreditCardRange("", "", 15, 17)));
619         assertFalse(CreditCardValidator.validLength(18, new CreditCardRange("", "", 15, 17)));
620 
621         assertFalse(CreditCardValidator.validLength(14, new CreditCardRange("", "", new int[]{15, 17})));
622         assertTrue(CreditCardValidator.validLength(15, new CreditCardRange("", "", new int[]{15, 17})));
623         assertFalse(CreditCardValidator.validLength(16, new CreditCardRange("", "", new int[]{15, 17})));
624         assertTrue(CreditCardValidator.validLength(17, new CreditCardRange("", "", new int[]{15, 17})));
625         assertFalse(CreditCardValidator.validLength(18, new CreditCardRange("", "", new int[]{15, 17})));
626     }
627 
628     public void testDisjointRange() {
629         CreditCardValidator ccv = new CreditCardValidator(
630             new CreditCardRange[]{
631                     new CreditCardRange("305", "4", new int[]{13, 16}),
632                 }
633             );
634         assertEquals(13, VALID_SHORT_VISA.length());
635         assertEquals(16, VALID_VISA.length());
636         assertEquals(14, VALID_DINERS.length());
637         assertTrue(ccv.isValid(VALID_SHORT_VISA));
638         assertTrue(ccv.isValid(VALID_VISA));
639         assertFalse(ccv.isValid(ERROR_SHORT_VISA));
640         assertFalse(ccv.isValid(ERROR_VISA));
641         assertFalse(ccv.isValid(VALID_DINERS));
642         ccv = new CreditCardValidator(
643             new CreditCardRange[]{
644                     // add 14 as a valid length
645                     new CreditCardRange("305", "4", new int[]{13, 14, 16}),
646                 }
647             );
648         assertTrue(ccv.isValid(VALID_DINERS));
649     }
650 }