credit_card_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
6#include "base/guid.h"
7#include "base/strings/utf_string_conversions.h"
8#include "components/autofill/core/browser/autofill_common_test.h"
9#include "components/autofill/core/browser/credit_card.h"
10#include "components/autofill/core/browser/validation.h"
11#include "components/autofill/core/common/form_field_data.h"
12#include "grit/webkit_resources.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace autofill {
16namespace {
17
18// From https://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
19const char* const kValidNumbers[] = {
20  "378282246310005",
21  "3714 4963 5398 431",
22  "3787-3449-3671-000",
23  "5610591081018250",
24  "3056 9309 0259 04",
25  "3852-0000-0232-37",
26  "6011111111111117",
27  "6011 0009 9013 9424",
28  "3530-1113-3330-0000",
29  "3566002020360505",
30  "5555 5555 5555 4444",
31  "5105-1051-0510-5100",
32  "4111111111111111",
33  "4012 8888 8888 1881",
34  "4222-2222-2222-2",
35  "5019717010103742",
36  "6331101999990016",
37};
38const char* const kInvalidNumbers[] = {
39  "4111 1111 112", /* too short */
40  "41111111111111111115", /* too long */
41  "4111-1111-1111-1110", /* wrong Luhn checksum */
42  "3056 9309 0259 04aa", /* non-digit characters */
43};
44
45}  // namespace
46
47// Tests credit card summary string generation.  This test simulates a variety
48// of different possible summary strings.  Variations occur based on the
49// existence of credit card number, month, and year fields.
50TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) {
51  // Case 0: empty credit card.
52  CreditCard credit_card0(base::GenerateGUID(), "https://www.example.com/");
53  base::string16 summary0 = credit_card0.Label();
54  EXPECT_EQ(base::string16(), summary0);
55  base::string16 obfuscated0 = credit_card0.ObfuscatedNumber();
56  EXPECT_EQ(base::string16(), obfuscated0);
57
58  // Case 00: Empty credit card with empty strings.
59  CreditCard credit_card00(base::GenerateGUID(), "https://www.example.com/");
60  test::SetCreditCardInfo(&credit_card00,"John Dillinger", "", "", "");
61  base::string16 summary00 = credit_card00.Label();
62  EXPECT_EQ(base::string16(ASCIIToUTF16("John Dillinger")), summary00);
63  base::string16 obfuscated00 = credit_card00.ObfuscatedNumber();
64  EXPECT_EQ(base::string16(), obfuscated00);
65
66  // Case 1: No credit card number.
67  CreditCard credit_card1(base::GenerateGUID(), "https://www.example.com/");
68  test::SetCreditCardInfo(&credit_card1,"John Dillinger", "", "01", "2010");
69  base::string16 summary1 = credit_card1.Label();
70  EXPECT_EQ(base::string16(ASCIIToUTF16("John Dillinger")), summary1);
71  base::string16 obfuscated1 = credit_card1.ObfuscatedNumber();
72  EXPECT_EQ(base::string16(), obfuscated1);
73
74  // Case 2: No month.
75  CreditCard credit_card2(base::GenerateGUID(), "https://www.example.com/");
76  test::SetCreditCardInfo(
77      &credit_card2, "John Dillinger", "5105 1051 0510 5100", "", "2010");
78  base::string16 summary2 = credit_card2.Label();
79  EXPECT_EQ(ASCIIToUTF16("************5100"), summary2);
80  base::string16 obfuscated2 = credit_card2.ObfuscatedNumber();
81  EXPECT_EQ(ASCIIToUTF16("************5100"), obfuscated2);
82
83  // Case 3: No year.
84  CreditCard credit_card3(base::GenerateGUID(), "https://www.example.com/");
85  test::SetCreditCardInfo(
86      &credit_card3, "John Dillinger", "5105 1051 0510 5100", "01", "");
87  base::string16 summary3 = credit_card3.Label();
88  EXPECT_EQ(ASCIIToUTF16("************5100"), summary3);
89  base::string16 obfuscated3 = credit_card3.ObfuscatedNumber();
90  EXPECT_EQ(ASCIIToUTF16("************5100"), obfuscated3);
91
92  // Case 4: Have everything.
93  CreditCard credit_card4(base::GenerateGUID(), "https://www.example.com/");
94  test::SetCreditCardInfo(
95      &credit_card4, "John Dillinger", "5105 1051 0510 5100", "01", "2010");
96  base::string16 summary4 = credit_card4.Label();
97  EXPECT_EQ(ASCIIToUTF16("************5100, Exp: 01/2010"), summary4);
98  base::string16 obfuscated4 = credit_card4.ObfuscatedNumber();
99  EXPECT_EQ(ASCIIToUTF16("************5100"), obfuscated4);
100
101  // Case 5: Very long credit card
102  CreditCard credit_card5(base::GenerateGUID(), "https://www.example.com/");
103  test::SetCreditCardInfo(
104      &credit_card5,
105      "John Dillinger",
106      "0123456789 0123456789 0123456789 5105 1051 0510 5100", "01", "2010");
107  base::string16 summary5 = credit_card5.Label();
108  EXPECT_EQ(ASCIIToUTF16("********************5100, Exp: 01/2010"), summary5);
109  base::string16 obfuscated5 = credit_card5.ObfuscatedNumber();
110  EXPECT_EQ(ASCIIToUTF16("********************5100"), obfuscated5);
111}
112
113TEST(CreditCardTest, AssignmentOperator) {
114  CreditCard a(base::GenerateGUID(), "some origin");
115  test::SetCreditCardInfo(&a, "John Dillinger", "123456789012", "01", "2010");
116
117  // Result of assignment should be logically equal to the original profile.
118  CreditCard b(base::GenerateGUID(), "some other origin");
119  b = a;
120  EXPECT_TRUE(a == b);
121
122  // Assignment to self should not change the profile value.
123  a = a;
124  EXPECT_TRUE(a == b);
125}
126
127TEST(CreditCardTest, Copy) {
128  CreditCard a(base::GenerateGUID(), "https://www.example.com");
129  test::SetCreditCardInfo(&a, "John Dillinger", "123456789012", "01", "2010");
130
131  // Clone should be logically equal to the original.
132  CreditCard b(a);
133  EXPECT_TRUE(a == b);
134}
135
136TEST(CreditCardTest, Compare) {
137  CreditCard a(base::GenerateGUID(), std::string());
138  CreditCard b(base::GenerateGUID(), std::string());
139
140  // Empty cards are the same.
141  EXPECT_EQ(0, a.Compare(b));
142
143  // GUIDs don't count.
144  a.set_guid(base::GenerateGUID());
145  b.set_guid(base::GenerateGUID());
146  EXPECT_EQ(0, a.Compare(b));
147
148  // Origins don't count.
149  a.set_origin("apple");
150  b.set_origin("banana");
151  EXPECT_EQ(0, a.Compare(b));
152
153  // Different values produce non-zero results.
154  test::SetCreditCardInfo(&a, "Jimmy", NULL, NULL, NULL);
155  test::SetCreditCardInfo(&b, "Ringo", NULL, NULL, NULL);
156  EXPECT_GT(0, a.Compare(b));
157  EXPECT_LT(0, b.Compare(a));
158}
159
160// Test we get the correct icon for each card type.
161TEST(CreditCardTest, IconResourceId) {
162  EXPECT_EQ(IDR_AUTOFILL_CC_AMEX,
163            CreditCard::IconResourceId(kAmericanExpressCard));
164  EXPECT_EQ(IDR_AUTOFILL_CC_DINERS,
165            CreditCard::IconResourceId(kDinersCard));
166  EXPECT_EQ(IDR_AUTOFILL_CC_DISCOVER,
167            CreditCard::IconResourceId(kDiscoverCard));
168  EXPECT_EQ(IDR_AUTOFILL_CC_JCB,
169            CreditCard::IconResourceId(kJCBCard));
170  EXPECT_EQ(IDR_AUTOFILL_CC_MASTERCARD,
171            CreditCard::IconResourceId(kMasterCard));
172  EXPECT_EQ(IDR_AUTOFILL_CC_VISA,
173            CreditCard::IconResourceId(kVisaCard));
174}
175
176TEST(CreditCardTest, UpdateFromImportedCard) {
177  CreditCard original_card(base::GenerateGUID(), "https://www.example.com");
178  test::SetCreditCardInfo(
179      &original_card, "John Dillinger", "123456789012", "09", "2017");
180
181  CreditCard a = original_card;
182
183  // The new card has a different name, expiration date, and origin.
184  CreditCard b = a;
185  b.set_guid(base::GenerateGUID());
186  b.set_origin("https://www.example.org");
187  b.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("J. Dillinger"));
188  b.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("08"));
189  b.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2019"));
190
191  EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
192  EXPECT_EQ("https://www.example.org", a.origin());
193  EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME));
194  EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
195  EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
196
197  // Try again, but with no name set for |b|.
198  a = original_card;
199  b.SetRawInfo(CREDIT_CARD_NAME, base::string16());
200
201  EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
202  EXPECT_EQ("https://www.example.org", a.origin());
203  EXPECT_EQ(ASCIIToUTF16("John Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME));
204  EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
205  EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
206
207  // Try again, but with only the original card having a verified origin.
208  // |a| should be unchanged.
209  a = original_card;
210  a.set_origin("Chrome settings");
211  b.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("J. Dillinger"));
212
213  EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
214  EXPECT_EQ("Chrome settings", a.origin());
215  EXPECT_EQ(ASCIIToUTF16("John Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME));
216  EXPECT_EQ(ASCIIToUTF16("09"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
217  EXPECT_EQ(ASCIIToUTF16("2017"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
218
219  // Try again, but with only the new card having a verified origin.
220  a = original_card;
221  b.set_origin("Chrome settings");
222
223  EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
224  EXPECT_EQ("Chrome settings", a.origin());
225  EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME));
226  EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
227  EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
228
229  // Try again, with both cards having a verified origin.
230  a = original_card;
231  a.set_origin("Chrome Autofill dialog");
232  b.set_origin("Chrome settings");
233
234  EXPECT_TRUE(a.UpdateFromImportedCard(b, "en-US"));
235  EXPECT_EQ("Chrome settings", a.origin());
236  EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a.GetRawInfo(CREDIT_CARD_NAME));
237  EXPECT_EQ(ASCIIToUTF16("08"), a.GetRawInfo(CREDIT_CARD_EXP_MONTH));
238  EXPECT_EQ(ASCIIToUTF16("2019"), a.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
239
240  // Try again, but with |b| having a different card number.
241  // |a| should be unchanged.
242  a = original_card;
243  b.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
244
245  EXPECT_FALSE(a.UpdateFromImportedCard(b, "en-US"));
246  EXPECT_EQ(original_card, a);
247}
248
249TEST(CreditCardTest, IsComplete) {
250  CreditCard card(base::GenerateGUID(), "https://www.example.com/");
251  EXPECT_FALSE(card.IsComplete());
252  card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Wally T. Walrus"));
253  EXPECT_FALSE(card.IsComplete());
254  card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
255  EXPECT_FALSE(card.IsComplete());
256  card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2014"));
257
258  for (size_t i = 0; i < arraysize(kValidNumbers); ++i) {
259    SCOPED_TRACE(kValidNumbers[i]);
260    card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16(kValidNumbers[i]));
261    EXPECT_TRUE(card.IsComplete());
262  }
263  for (size_t i = 0; i < arraysize(kInvalidNumbers); ++i) {
264    SCOPED_TRACE(kInvalidNumbers[i]);
265    card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16(kInvalidNumbers[i]));
266    EXPECT_FALSE(card.IsComplete());
267  }
268}
269
270TEST(CreditCardTest, IsValid) {
271  CreditCard card;
272  // Invalid because expired
273  card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("1"));
274  card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2010"));
275  card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
276  EXPECT_FALSE(card.IsValid());
277
278  // Invalid because card number is not complete
279  card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("12"));
280  card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("9999"));
281  card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("41111"));
282  EXPECT_FALSE(card.IsValid());
283
284  // Valid
285  card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("12"));
286  card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("9999"));
287  card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111111111111111"));
288  EXPECT_TRUE(card.IsValid());
289}
290
291TEST(CreditCardTest, InvalidMastercardNumber) {
292  CreditCard card(base::GenerateGUID(), "https://www.example.com/");
293
294  test::SetCreditCardInfo(&card, "Baby Face Nelson",
295                          "5200000000000004", "01", "2010");
296  EXPECT_EQ(kMasterCard, card.type());
297  EXPECT_FALSE(card.IsComplete());
298}
299
300// Verify that we preserve exactly what the user typed for credit card numbers.
301TEST(CreditCardTest, SetRawInfoCreditCardNumber) {
302  CreditCard card(base::GenerateGUID(), "https://www.example.com/");
303
304  test::SetCreditCardInfo(&card, "Bob Dylan",
305                          "4321-5432-6543-xxxx", "07", "2013");
306  EXPECT_EQ(ASCIIToUTF16("4321-5432-6543-xxxx"),
307            card.GetRawInfo(CREDIT_CARD_NUMBER));
308}
309
310// Verify that we can handle both numeric and named months.
311TEST(CreditCardTest, SetExpirationMonth) {
312  CreditCard card(base::GenerateGUID(), "https://www.example.com/");
313
314  card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("05"));
315  EXPECT_EQ(ASCIIToUTF16("05"), card.GetRawInfo(CREDIT_CARD_EXP_MONTH));
316  EXPECT_EQ(5, card.expiration_month());
317
318  card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("7"));
319  EXPECT_EQ(ASCIIToUTF16("07"), card.GetRawInfo(CREDIT_CARD_EXP_MONTH));
320  EXPECT_EQ(7, card.expiration_month());
321
322  // This should fail, and preserve the previous value.
323  card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("January"));
324  EXPECT_EQ(ASCIIToUTF16("07"), card.GetRawInfo(CREDIT_CARD_EXP_MONTH));
325  EXPECT_EQ(7, card.expiration_month());
326
327  card.SetInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("January"), "en-US");
328  EXPECT_EQ(ASCIIToUTF16("01"), card.GetRawInfo(CREDIT_CARD_EXP_MONTH));
329  EXPECT_EQ(1, card.expiration_month());
330
331  card.SetInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("Apr"), "en-US");
332  EXPECT_EQ(ASCIIToUTF16("04"), card.GetRawInfo(CREDIT_CARD_EXP_MONTH));
333  EXPECT_EQ(4, card.expiration_month());
334}
335
336TEST(CreditCardTest, CreditCardType) {
337  CreditCard card(base::GenerateGUID(), "https://www.example.com/");
338
339  // The card type cannot be set directly.
340  card.SetRawInfo(CREDIT_CARD_TYPE, ASCIIToUTF16("Visa"));
341  EXPECT_EQ(base::string16(), card.GetRawInfo(CREDIT_CARD_TYPE));
342
343  // Setting the number should implicitly set the type.
344  card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("4111 1111 1111 1111"));
345  EXPECT_EQ(ASCIIToUTF16("Visa"), card.GetRawInfo(CREDIT_CARD_TYPE));
346}
347
348TEST(CreditCardTest, CreditCardVerificationCode) {
349  CreditCard card(base::GenerateGUID(), "https://www.example.com/");
350
351  // The verification code cannot be set, as Chrome does not store this data.
352  card.SetRawInfo(CREDIT_CARD_VERIFICATION_CODE, ASCIIToUTF16("999"));
353  EXPECT_EQ(base::string16(), card.GetRawInfo(CREDIT_CARD_VERIFICATION_CODE));
354}
355
356
357TEST(CreditCardTest, CreditCardMonthExact) {
358  const char* const kMonthsNumeric[] = {
359    "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12",
360  };
361  std::vector<base::string16> options(arraysize(kMonthsNumeric));
362  for (size_t i = 0; i < arraysize(kMonthsNumeric); ++i) {
363    options[i] = ASCIIToUTF16(kMonthsNumeric[i]);
364  }
365
366  FormFieldData field;
367  field.form_control_type = "select-one";
368  field.option_values = options;
369  field.option_contents = options;
370
371  CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
372  credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
373  credit_card.FillSelectControl(CREDIT_CARD_EXP_MONTH, "en-US", &field);
374  EXPECT_EQ(ASCIIToUTF16("01"), field.value);
375}
376
377TEST(CreditCardTest, CreditCardMonthAbbreviated) {
378  const char* const kMonthsAbbreviated[] = {
379    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
380    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
381  };
382  std::vector<base::string16> options(arraysize(kMonthsAbbreviated));
383  for (size_t i = 0; i < arraysize(kMonthsAbbreviated); ++i) {
384    options[i] = ASCIIToUTF16(kMonthsAbbreviated[i]);
385  }
386
387  FormFieldData field;
388  field.form_control_type = "select-one";
389  field.option_values = options;
390  field.option_contents = options;
391
392  CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
393  credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
394  credit_card.FillSelectControl(CREDIT_CARD_EXP_MONTH, "en-US", &field);
395  EXPECT_EQ(ASCIIToUTF16("Jan"), field.value);
396}
397
398TEST(CreditCardTest, CreditCardMonthFull) {
399  const char* const kMonthsFull[] = {
400    "January", "February", "March", "April", "May", "June",
401    "July", "August", "September", "October", "November", "December",
402  };
403  std::vector<base::string16> options(arraysize(kMonthsFull));
404  for (size_t i = 0; i < arraysize(kMonthsFull); ++i) {
405    options[i] = ASCIIToUTF16(kMonthsFull[i]);
406  }
407
408  FormFieldData field;
409  field.form_control_type = "select-one";
410  field.option_values = options;
411  field.option_contents = options;
412
413  CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
414  credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
415  credit_card.FillSelectControl(CREDIT_CARD_EXP_MONTH, "en-US", &field);
416  EXPECT_EQ(ASCIIToUTF16("January"), field.value);
417}
418
419TEST(CreditCardTest, CreditCardMonthNumeric) {
420  const char* const kMonthsNumeric[] = {
421    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
422  };
423  std::vector<base::string16> options(arraysize(kMonthsNumeric));
424  for (size_t i = 0; i < arraysize(kMonthsNumeric); ++i) {
425    options[i] = ASCIIToUTF16(kMonthsNumeric[i]);
426  }
427
428  FormFieldData field;
429  field.form_control_type = "select-one";
430  field.option_values = options;
431  field.option_contents = options;
432
433  CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
434  credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
435  credit_card.FillSelectControl(CREDIT_CARD_EXP_MONTH, "en-US", &field);
436  EXPECT_EQ(ASCIIToUTF16("1"), field.value);
437}
438
439TEST(CreditCardTest, CreditCardTwoDigitYear) {
440  const char* const kYears[] = {
441    "12", "13", "14", "15", "16", "17", "18", "19"
442  };
443  std::vector<base::string16> options(arraysize(kYears));
444  for (size_t i = 0; i < arraysize(kYears); ++i) {
445    options[i] = ASCIIToUTF16(kYears[i]);
446  }
447
448  FormFieldData field;
449  field.form_control_type = "select-one";
450  field.option_values = options;
451  field.option_contents = options;
452
453  CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
454  credit_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2017"));
455  credit_card.FillSelectControl(CREDIT_CARD_EXP_4_DIGIT_YEAR, "en-US", &field);
456  EXPECT_EQ(ASCIIToUTF16("17"), field.value);
457  EXPECT_EQ(2017, credit_card.expiration_year());
458}
459
460TEST(CreditCardTest, CreditCardTypeSelectControl) {
461  const char* const kCreditCardTypes[] = {
462    "Visa", "Master Card", "AmEx", "discover"
463  };
464  std::vector<base::string16> options(arraysize(kCreditCardTypes));
465  for (size_t i = 0; i < arraysize(kCreditCardTypes); ++i) {
466    options[i] = ASCIIToUTF16(kCreditCardTypes[i]);
467  }
468
469  FormFieldData field;
470  field.form_control_type = "select-one";
471  field.option_values = options;
472  field.option_contents = options;
473
474  // Credit card types are inferred from the numbers, so we use test numbers for
475  // each card type. Test card numbers are drawn from
476  // http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
477
478  {
479    // Normal case:
480    CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
481    credit_card.SetRawInfo(CREDIT_CARD_NUMBER,
482                           ASCIIToUTF16("4111111111111111"));
483    credit_card.FillSelectControl(CREDIT_CARD_TYPE, "en-US", &field);
484    EXPECT_EQ(ASCIIToUTF16("Visa"), field.value);
485  }
486
487  {
488    // Filling should be able to handle intervening whitespace:
489    CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
490    credit_card.SetRawInfo(CREDIT_CARD_NUMBER,
491                           ASCIIToUTF16("5105105105105100"));
492    credit_card.FillSelectControl(CREDIT_CARD_TYPE, "en-US", &field);
493    EXPECT_EQ(ASCIIToUTF16("Master Card"), field.value);
494  }
495
496  {
497    // American Express is sometimes abbreviated as AmEx:
498    CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
499    credit_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("371449635398431"));
500    credit_card.FillSelectControl(CREDIT_CARD_TYPE, "en-US", &field);
501    EXPECT_EQ(ASCIIToUTF16("AmEx"), field.value);
502  }
503
504  {
505    // Case insensitivity:
506    CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
507    credit_card.SetRawInfo(CREDIT_CARD_NUMBER,
508                           ASCIIToUTF16("6011111111111117"));
509    credit_card.FillSelectControl(CREDIT_CARD_TYPE, "en-US", &field);
510    EXPECT_EQ(ASCIIToUTF16("discover"), field.value);
511  }
512}
513
514TEST(CreditCardTest, GetCreditCardType) {
515  struct {
516    std::string card_number;
517    std::string type;
518    bool is_valid;
519  } test_cases[] = {
520    // The relevant sample numbers from
521    // http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
522    { "378282246310005", kAmericanExpressCard, true },
523    { "371449635398431", kAmericanExpressCard, true },
524    { "378734493671000", kAmericanExpressCard, true },
525    { "30569309025904", kDinersCard, true },
526    { "38520000023237", kDinersCard, true },
527    { "6011111111111117", kDiscoverCard, true },
528    { "6011000990139424", kDiscoverCard, true },
529    { "3530111333300000", kJCBCard, true },
530    { "3566002020360505", kJCBCard, true },
531    { "5555555555554444", kMasterCard, true },
532    { "5105105105105100", kMasterCard, true },
533    { "4111111111111111", kVisaCard, true },
534    { "4012888888881881", kVisaCard, true },
535    { "4222222222222", kVisaCard, true },
536
537    // The relevant sample numbers from
538    // http://auricsystems.com/support-center/sample-credit-card-numbers/
539    { "343434343434343", kAmericanExpressCard, true },
540    { "371144371144376", kAmericanExpressCard, true },
541    { "341134113411347", kAmericanExpressCard, true },
542    { "36438936438936", kDinersCard, true },
543    { "36110361103612", kDinersCard, true },
544    { "36111111111111", kDinersCard, true },
545    { "6011016011016011", kDiscoverCard, true },
546    { "6011000990139424", kDiscoverCard, true },
547    { "6011000000000004", kDiscoverCard, true },
548    { "6011000995500000", kDiscoverCard, true },
549    { "6500000000000002", kDiscoverCard, true },
550    { "3566002020360505", kJCBCard, true },
551    { "3528000000000007", kJCBCard, true },
552    { "5500005555555559", kMasterCard, true },
553    { "5555555555555557", kMasterCard, true },
554    { "5454545454545454", kMasterCard, true },
555    { "5555515555555551", kMasterCard, true },
556    { "5405222222222226", kMasterCard, true },
557    { "5478050000000007", kMasterCard, true },
558    { "5111005111051128", kMasterCard, true },
559    { "5112345112345114", kMasterCard, true },
560    { "5115915115915118", kMasterCard, true },
561
562    // Empty string
563    { std::string(), kGenericCard, false },
564
565    // Non-numeric
566    { "garbage", kGenericCard, false },
567    { "4garbage", kVisaCard, false },
568
569    // Fails Luhn check.
570    { "4111111111111112", kVisaCard, false },
571
572    // Invalid length.
573    { "3434343434343434", kAmericanExpressCard, false },
574    { "411111111111116", kVisaCard, false },
575
576    // Issuer Identification Numbers (IINs) that Chrome recognizes.
577    { "4", kVisaCard, false },
578    { "34", kAmericanExpressCard, false },
579    { "37", kAmericanExpressCard, false },
580    { "300", kDinersCard, false },
581    { "301", kDinersCard, false },
582    { "302", kDinersCard, false },
583    { "303", kDinersCard, false },
584    { "304", kDinersCard, false },
585    { "305", kDinersCard, false },
586    { "3095", kDinersCard, false },
587    { "36", kDinersCard, false },
588    { "38", kDinersCard, false },
589    { "39", kDinersCard, false },
590    { "6011", kDiscoverCard, false },
591    { "644", kDiscoverCard, false },
592    { "645", kDiscoverCard, false },
593    { "646", kDiscoverCard, false },
594    { "647", kDiscoverCard, false },
595    { "648", kDiscoverCard, false },
596    { "649", kDiscoverCard, false },
597    { "65", kDiscoverCard, false },
598    { "3528", kJCBCard, false },
599    { "3531", kJCBCard, false },
600    { "3589", kJCBCard, false },
601    { "51", kMasterCard, false },
602    { "52", kMasterCard, false },
603    { "53", kMasterCard, false },
604    { "54", kMasterCard, false },
605    { "55", kMasterCard, false },
606
607    // Not enough data to determine an IIN uniquely.
608    { "3", kGenericCard, false },
609    { "30", kGenericCard, false },
610    { "309", kGenericCard, false },
611    { "35", kGenericCard, false },
612    { "5", kGenericCard, false },
613    { "6", kGenericCard, false },
614    { "60", kGenericCard, false },
615    { "601", kGenericCard, false },
616    { "64", kGenericCard, false },
617
618    // Unknown IINs.
619    { "0", kGenericCard, false },
620    { "1", kGenericCard, false },
621    { "2", kGenericCard, false },
622    { "306", kGenericCard, false },
623    { "307", kGenericCard, false },
624    { "308", kGenericCard, false },
625    { "3091", kGenericCard, false },
626    { "3094", kGenericCard, false },
627    { "3096", kGenericCard, false },
628    { "31", kGenericCard, false },
629    { "32", kGenericCard, false },
630    { "33", kGenericCard, false },
631    { "351", kGenericCard, false },
632    { "3527", kGenericCard, false },
633    { "359", kGenericCard, false },
634    { "50", kGenericCard, false },
635    { "56", kGenericCard, false },
636    { "57", kGenericCard, false },
637    { "58", kGenericCard, false },
638    { "59", kGenericCard, false },
639    { "600", kGenericCard, false },
640    { "602", kGenericCard, false },
641    { "603", kGenericCard, false },
642    { "604", kGenericCard, false },
643    { "605", kGenericCard, false },
644    { "606", kGenericCard, false },
645    { "607", kGenericCard, false },
646    { "608", kGenericCard, false },
647    { "609", kGenericCard, false },
648    { "61", kGenericCard, false },
649    { "62", kGenericCard, false },
650    { "63", kGenericCard, false },
651    { "640", kGenericCard, false },
652    { "641", kGenericCard, false },
653    { "642", kGenericCard, false },
654    { "643", kGenericCard, false },
655    { "66", kGenericCard, false },
656    { "67", kGenericCard, false },
657    { "68", kGenericCard, false },
658    { "69", kGenericCard, false },
659    { "7", kGenericCard, false },
660    { "8", kGenericCard, false },
661    { "9", kGenericCard, false },
662
663    // Oddball case: Unknown issuer, but valid Luhn check and plausible length.
664    { "7000700070007000", kGenericCard, true },
665  };
666
667  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
668    base::string16 card_number = ASCIIToUTF16(test_cases[i].card_number);
669    SCOPED_TRACE(card_number);
670    EXPECT_EQ(test_cases[i].type, CreditCard::GetCreditCardType(card_number));
671    EXPECT_EQ(test_cases[i].is_valid, IsValidCreditCardNumber(card_number));
672  }
673}
674
675}  // namespace autofill
676