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