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.
5 #include "base/basictypes.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"
16 using base::ASCIIToUTF16
;
20 const CreditCard::RecordType LOCAL_CARD
= CreditCard::LOCAL_CARD
;
21 const CreditCard::RecordType MASKED_SERVER_CARD
=
22 CreditCard::MASKED_SERVER_CARD
;
23 const CreditCard::RecordType FULL_SERVER_CARD
= CreditCard::FULL_SERVER_CARD
;
27 // From https://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
28 const char* const kValidNumbers
[] = {
36 "6011 0009 9013 9424",
37 "3530-1113-3330-0000",
39 "5555 5555 5555 4444",
40 "5105-1051-0510-5100",
42 "4012 8888 8888 1881",
47 // A UnionPay card that doesn't pass the Luhn checksum
50 const char* const kInvalidNumbers
[] = {
51 "4111 1111 112", /* too short */
52 "41111111111111111115", /* too long */
53 "4111-1111-1111-1110", /* wrong Luhn checksum */
54 "3056 9309 0259 04aa", /* non-digit characters */
59 // Tests credit card summary string generation. This test simulates a variety
60 // of different possible summary strings. Variations occur based on the
61 // existence of credit card number, month, and year fields.
62 TEST(CreditCardTest
, PreviewSummaryAndTypeAndLastFourDigitsStrings
) {
63 // Case 0: empty credit card.
64 CreditCard
credit_card0(base::GenerateGUID(), "https://www.example.com/");
65 base::string16 summary0
= credit_card0
.Label();
66 EXPECT_EQ(base::string16(), summary0
);
67 base::string16 obfuscated0
= credit_card0
.TypeAndLastFourDigits();
68 EXPECT_EQ(ASCIIToUTF16("Card"), obfuscated0
);
70 // Case 00: Empty credit card with empty strings.
71 CreditCard
credit_card00(base::GenerateGUID(), "https://www.example.com/");
72 test::SetCreditCardInfo(&credit_card00
,"John Dillinger", "", "", "");
73 base::string16 summary00
= credit_card00
.Label();
74 EXPECT_EQ(base::string16(ASCIIToUTF16("John Dillinger")), summary00
);
75 base::string16 obfuscated00
= credit_card00
.TypeAndLastFourDigits();
76 EXPECT_EQ(ASCIIToUTF16("Card"), obfuscated00
);
78 // Case 1: No credit card number.
79 CreditCard
credit_card1(base::GenerateGUID(), "https://www.example.com/");
80 test::SetCreditCardInfo(&credit_card1
,"John Dillinger", "", "01", "2010");
81 base::string16 summary1
= credit_card1
.Label();
82 EXPECT_EQ(base::string16(ASCIIToUTF16("John Dillinger")), summary1
);
83 base::string16 obfuscated1
= credit_card1
.TypeAndLastFourDigits();
84 EXPECT_EQ(ASCIIToUTF16("Card"), obfuscated1
);
87 CreditCard
credit_card2(base::GenerateGUID(), "https://www.example.com/");
88 test::SetCreditCardInfo(
89 &credit_card2
, "John Dillinger", "5105 1051 0510 5100", "", "2010");
90 base::string16 summary2
= credit_card2
.Label();
91 EXPECT_EQ(ASCIIToUTF16("MasterCard - 5100"), summary2
);
92 base::string16 obfuscated2
= credit_card2
.TypeAndLastFourDigits();
93 EXPECT_EQ(ASCIIToUTF16("MasterCard - 5100"), obfuscated2
);
96 CreditCard
credit_card3(base::GenerateGUID(), "https://www.example.com/");
97 test::SetCreditCardInfo(
98 &credit_card3
, "John Dillinger", "5105 1051 0510 5100", "01", "");
99 base::string16 summary3
= credit_card3
.Label();
100 EXPECT_EQ(ASCIIToUTF16("MasterCard - 5100"), summary3
);
101 base::string16 obfuscated3
= credit_card3
.TypeAndLastFourDigits();
102 EXPECT_EQ(ASCIIToUTF16("MasterCard - 5100"), obfuscated3
);
104 // Case 4: Have everything.
105 CreditCard
credit_card4(base::GenerateGUID(), "https://www.example.com/");
106 test::SetCreditCardInfo(
107 &credit_card4
, "John Dillinger", "5105 1051 0510 5100", "01", "2010");
108 base::string16 summary4
= credit_card4
.Label();
109 EXPECT_EQ(ASCIIToUTF16("MasterCard - 5100, Exp: 01/2010"), summary4
);
110 base::string16 obfuscated4
= credit_card4
.TypeAndLastFourDigits();
111 EXPECT_EQ(ASCIIToUTF16("MasterCard - 5100"), obfuscated4
);
113 // Case 5: Very long credit card
114 CreditCard
credit_card5(base::GenerateGUID(), "https://www.example.com/");
115 test::SetCreditCardInfo(
118 "0123456789 0123456789 0123456789 5105 1051 0510 5100", "01", "2010");
119 base::string16 summary5
= credit_card5
.Label();
120 EXPECT_EQ(ASCIIToUTF16("Card - 5100, Exp: 01/2010"), summary5
);
121 base::string16 obfuscated5
= credit_card5
.TypeAndLastFourDigits();
122 EXPECT_EQ(ASCIIToUTF16("Card - 5100"), obfuscated5
);
125 TEST(CreditCardTest
, AssignmentOperator
) {
126 CreditCard
a(base::GenerateGUID(), "some origin");
127 test::SetCreditCardInfo(&a
, "John Dillinger", "123456789012", "01", "2010");
129 // Result of assignment should be logically equal to the original profile.
130 CreditCard
b(base::GenerateGUID(), "some other origin");
134 // Assignment to self should not change the profile value.
139 TEST(CreditCardTest
, Copy
) {
140 CreditCard
a(base::GenerateGUID(), "https://www.example.com");
141 test::SetCreditCardInfo(&a
, "John Dillinger", "123456789012", "01", "2010");
143 // Clone should be logically equal to the original.
148 TEST(CreditCardTest
, IsLocalDuplicateOfServerCard
) {
150 CreditCard::RecordType first_card_record_type
;
151 const char* first_card_name
;
152 const char* first_card_number
;
153 const char* first_card_exp_mo
;
154 const char* first_card_exp_yr
;
156 CreditCard::RecordType second_card_record_type
;
157 const char* second_card_name
;
158 const char* second_card_number
;
159 const char* second_card_exp_mo
;
160 const char* second_card_exp_yr
;
161 const char* second_card_type
;
163 bool is_local_duplicate
;
165 { LOCAL_CARD
, "", "", "", "",
166 LOCAL_CARD
, "", "", "", "", nullptr, false },
167 { LOCAL_CARD
, "", "", "", "",
168 FULL_SERVER_CARD
, "", "", "", "", nullptr, true},
169 { FULL_SERVER_CARD
, "", "", "", "",
170 FULL_SERVER_CARD
, "", "", "", "", nullptr, false},
171 { LOCAL_CARD
, "John Dillinger", "423456789012", "01", "2010",
172 FULL_SERVER_CARD
, "John Dillinger", "423456789012", "01", "2010", nullptr,
174 { LOCAL_CARD
, "J Dillinger", "423456789012", "01", "2010",
175 FULL_SERVER_CARD
, "John Dillinger", "423456789012", "01", "2010", nullptr,
177 { LOCAL_CARD
, "", "423456789012", "01", "2010",
178 FULL_SERVER_CARD
, "John Dillinger", "423456789012", "01", "2010", nullptr,
180 { LOCAL_CARD
, "", "423456789012", "", "",
181 FULL_SERVER_CARD
, "John Dillinger", "423456789012", "01", "2010", nullptr,
183 { LOCAL_CARD
, "", "423456789012", "", "",
184 MASKED_SERVER_CARD
, "John Dillinger", "9012", "01", "2010", kVisaCard
,
186 { LOCAL_CARD
, "", "423456789012", "", "",
187 MASKED_SERVER_CARD
, "John Dillinger", "9012", "01", "2010", kMasterCard
,
189 { LOCAL_CARD
, "John Dillinger", "4234-5678-9012", "01", "2010",
190 FULL_SERVER_CARD
, "John Dillinger", "423456789012", "01", "2010", nullptr,
194 for (size_t i
= 0; i
< arraysize(test_cases
); ++i
) {
195 CreditCard
a(base::GenerateGUID(), std::string());
196 a
.set_record_type(test_cases
[i
].first_card_record_type
);
197 test::SetCreditCardInfo(&a
,
198 test_cases
[i
].first_card_name
,
199 test_cases
[i
].first_card_number
,
200 test_cases
[i
].first_card_exp_mo
,
201 test_cases
[i
].first_card_exp_yr
);
203 CreditCard
b(base::GenerateGUID(), std::string());
204 b
.set_record_type(test_cases
[i
].second_card_record_type
);
205 test::SetCreditCardInfo(&b
,
206 test_cases
[i
].second_card_name
,
207 test_cases
[i
].second_card_number
,
208 test_cases
[i
].second_card_exp_mo
,
209 test_cases
[i
].second_card_exp_yr
);
211 if (test_cases
[i
].second_card_record_type
== CreditCard::MASKED_SERVER_CARD
)
212 b
.SetTypeForMaskedCard(test_cases
[i
].second_card_type
);
214 EXPECT_EQ(test_cases
[i
].is_local_duplicate
,
215 a
.IsLocalDuplicateOfServerCard(b
)) << " when comparing cards "
216 << a
.Label() << " and " << b
.Label();
220 TEST(CreditCardTest
, Compare
) {
221 CreditCard
a(base::GenerateGUID(), std::string());
222 CreditCard
b(base::GenerateGUID(), std::string());
224 // Empty cards are the same.
225 EXPECT_EQ(0, a
.Compare(b
));
227 // GUIDs don't count.
228 a
.set_guid(base::GenerateGUID());
229 b
.set_guid(base::GenerateGUID());
230 EXPECT_EQ(0, a
.Compare(b
));
232 // Origins don't count.
233 a
.set_origin("apple");
234 b
.set_origin("banana");
235 EXPECT_EQ(0, a
.Compare(b
));
237 // Different values produce non-zero results.
238 test::SetCreditCardInfo(&a
, "Jimmy", NULL
, NULL
, NULL
);
239 test::SetCreditCardInfo(&b
, "Ringo", NULL
, NULL
, NULL
);
240 EXPECT_GT(0, a
.Compare(b
));
241 EXPECT_LT(0, b
.Compare(a
));
244 // This method is not compiled for iOS because these resources are not used and
245 // should not be shipped.
247 // Test we get the correct icon for each card type.
248 TEST(CreditCardTest
, IconResourceId
) {
249 EXPECT_EQ(IDR_AUTOFILL_CC_AMEX
,
250 CreditCard::IconResourceId(kAmericanExpressCard
));
251 EXPECT_EQ(IDR_AUTOFILL_CC_GENERIC
,
252 CreditCard::IconResourceId(kDinersCard
));
253 EXPECT_EQ(IDR_AUTOFILL_CC_DISCOVER
,
254 CreditCard::IconResourceId(kDiscoverCard
));
255 EXPECT_EQ(IDR_AUTOFILL_CC_GENERIC
,
256 CreditCard::IconResourceId(kJCBCard
));
257 EXPECT_EQ(IDR_AUTOFILL_CC_MASTERCARD
,
258 CreditCard::IconResourceId(kMasterCard
));
259 EXPECT_EQ(IDR_AUTOFILL_CC_VISA
,
260 CreditCard::IconResourceId(kVisaCard
));
262 #endif // #if !defined(OS_IOS)
264 TEST(CreditCardTest
, UpdateFromImportedCard
) {
265 CreditCard
original_card(base::GenerateGUID(), "https://www.example.com");
266 test::SetCreditCardInfo(
267 &original_card
, "John Dillinger", "123456789012", "09", "2017");
269 CreditCard a
= original_card
;
271 // The new card has a different name, expiration date, and origin.
273 b
.set_guid(base::GenerateGUID());
274 b
.set_origin("https://www.example.org");
275 b
.SetRawInfo(CREDIT_CARD_NAME
, ASCIIToUTF16("J. Dillinger"));
276 b
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("08"));
277 b
.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
, ASCIIToUTF16("2019"));
279 EXPECT_TRUE(a
.UpdateFromImportedCard(b
, "en-US"));
280 EXPECT_EQ("https://www.example.org", a
.origin());
281 EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a
.GetRawInfo(CREDIT_CARD_NAME
));
282 EXPECT_EQ(ASCIIToUTF16("08"), a
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
283 EXPECT_EQ(ASCIIToUTF16("2019"), a
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
));
285 // Try again, but with no name set for |b|.
287 b
.SetRawInfo(CREDIT_CARD_NAME
, base::string16());
289 EXPECT_TRUE(a
.UpdateFromImportedCard(b
, "en-US"));
290 EXPECT_EQ("https://www.example.org", a
.origin());
291 EXPECT_EQ(ASCIIToUTF16("John Dillinger"), a
.GetRawInfo(CREDIT_CARD_NAME
));
292 EXPECT_EQ(ASCIIToUTF16("08"), a
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
293 EXPECT_EQ(ASCIIToUTF16("2019"), a
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
));
295 // Try again, but with only the original card having a verified origin.
296 // |a| should be unchanged.
298 a
.set_origin("Chrome settings");
299 b
.SetRawInfo(CREDIT_CARD_NAME
, ASCIIToUTF16("J. Dillinger"));
301 EXPECT_TRUE(a
.UpdateFromImportedCard(b
, "en-US"));
302 EXPECT_EQ("Chrome settings", a
.origin());
303 EXPECT_EQ(ASCIIToUTF16("John Dillinger"), a
.GetRawInfo(CREDIT_CARD_NAME
));
304 EXPECT_EQ(ASCIIToUTF16("09"), a
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
305 EXPECT_EQ(ASCIIToUTF16("2017"), a
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
));
307 // Try again, but with only the new card having a verified origin.
309 b
.set_origin("Chrome settings");
311 EXPECT_TRUE(a
.UpdateFromImportedCard(b
, "en-US"));
312 EXPECT_EQ("Chrome settings", a
.origin());
313 EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a
.GetRawInfo(CREDIT_CARD_NAME
));
314 EXPECT_EQ(ASCIIToUTF16("08"), a
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
315 EXPECT_EQ(ASCIIToUTF16("2019"), a
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
));
317 // Try again, with both cards having a verified origin.
319 a
.set_origin("Chrome Autofill dialog");
320 b
.set_origin("Chrome settings");
322 EXPECT_TRUE(a
.UpdateFromImportedCard(b
, "en-US"));
323 EXPECT_EQ("Chrome settings", a
.origin());
324 EXPECT_EQ(ASCIIToUTF16("J. Dillinger"), a
.GetRawInfo(CREDIT_CARD_NAME
));
325 EXPECT_EQ(ASCIIToUTF16("08"), a
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
326 EXPECT_EQ(ASCIIToUTF16("2019"), a
.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
));
328 // Try again, but with |b| having a different card number.
329 // |a| should be unchanged.
331 b
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16("4111111111111111"));
333 EXPECT_FALSE(a
.UpdateFromImportedCard(b
, "en-US"));
334 EXPECT_EQ(original_card
, a
);
337 TEST(CreditCardTest
, IsComplete
) {
338 CreditCard
card(base::GenerateGUID(), "https://www.example.com/");
339 EXPECT_FALSE(card
.IsComplete());
340 card
.SetRawInfo(CREDIT_CARD_NAME
, ASCIIToUTF16("Wally T. Walrus"));
341 EXPECT_FALSE(card
.IsComplete());
342 card
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("01"));
343 EXPECT_FALSE(card
.IsComplete());
344 card
.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
, ASCIIToUTF16("2014"));
346 for (size_t i
= 0; i
< arraysize(kValidNumbers
); ++i
) {
347 SCOPED_TRACE(kValidNumbers
[i
]);
348 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16(kValidNumbers
[i
]));
349 EXPECT_TRUE(card
.IsComplete());
351 for (size_t i
= 0; i
< arraysize(kInvalidNumbers
); ++i
) {
352 SCOPED_TRACE(kInvalidNumbers
[i
]);
353 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16(kInvalidNumbers
[i
]));
354 EXPECT_FALSE(card
.IsComplete());
358 TEST(CreditCardTest
, IsValid
) {
360 // Invalid because expired
361 card
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("1"));
362 card
.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
, ASCIIToUTF16("2010"));
363 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16("4111111111111111"));
364 EXPECT_FALSE(card
.IsValid());
366 // Invalid because card number is not complete
367 card
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("12"));
368 card
.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
, ASCIIToUTF16("9999"));
369 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16("41111"));
370 EXPECT_FALSE(card
.IsValid());
373 card
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("12"));
374 card
.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR
, ASCIIToUTF16("9999"));
375 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16("4111111111111111"));
376 EXPECT_TRUE(card
.IsValid());
379 TEST(CreditCardTest
, InvalidMastercardNumber
) {
380 CreditCard
card(base::GenerateGUID(), "https://www.example.com/");
382 test::SetCreditCardInfo(&card
, "Baby Face Nelson",
383 "5200000000000004", "01", "2010");
384 EXPECT_EQ(kMasterCard
, card
.type());
385 EXPECT_FALSE(card
.IsComplete());
388 // Verify that we preserve exactly what the user typed for credit card numbers.
389 TEST(CreditCardTest
, SetRawInfoCreditCardNumber
) {
390 CreditCard
card(base::GenerateGUID(), "https://www.example.com/");
392 test::SetCreditCardInfo(&card
, "Bob Dylan",
393 "4321-5432-6543-xxxx", "07", "2013");
394 EXPECT_EQ(ASCIIToUTF16("4321-5432-6543-xxxx"),
395 card
.GetRawInfo(CREDIT_CARD_NUMBER
));
398 // Verify that we can handle both numeric and named months.
399 TEST(CreditCardTest
, SetExpirationMonth
) {
400 CreditCard
card(base::GenerateGUID(), "https://www.example.com/");
402 card
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("05"));
403 EXPECT_EQ(ASCIIToUTF16("05"), card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
404 EXPECT_EQ(5, card
.expiration_month());
406 card
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("7"));
407 EXPECT_EQ(ASCIIToUTF16("07"), card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
408 EXPECT_EQ(7, card
.expiration_month());
410 // This should fail, and preserve the previous value.
411 card
.SetRawInfo(CREDIT_CARD_EXP_MONTH
, ASCIIToUTF16("January"));
412 EXPECT_EQ(ASCIIToUTF16("07"), card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
413 EXPECT_EQ(7, card
.expiration_month());
416 AutofillType(CREDIT_CARD_EXP_MONTH
), ASCIIToUTF16("January"), "en-US");
417 EXPECT_EQ(ASCIIToUTF16("01"), card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
418 EXPECT_EQ(1, card
.expiration_month());
421 AutofillType(CREDIT_CARD_EXP_MONTH
), ASCIIToUTF16("Apr"), "en-US");
422 EXPECT_EQ(ASCIIToUTF16("04"), card
.GetRawInfo(CREDIT_CARD_EXP_MONTH
));
423 EXPECT_EQ(4, card
.expiration_month());
426 TEST(CreditCardTest
, CreditCardType
) {
427 CreditCard
card(base::GenerateGUID(), "https://www.example.com/");
429 // The card type cannot be set directly.
430 card
.SetRawInfo(CREDIT_CARD_TYPE
, ASCIIToUTF16("Visa"));
431 EXPECT_EQ(base::string16(), card
.GetRawInfo(CREDIT_CARD_TYPE
));
433 // Setting the number should implicitly set the type.
434 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16("4111 1111 1111 1111"));
435 EXPECT_EQ(ASCIIToUTF16("Visa"), card
.GetRawInfo(CREDIT_CARD_TYPE
));
438 TEST(CreditCardTest
, CreditCardVerificationCode
) {
439 CreditCard
card(base::GenerateGUID(), "https://www.example.com/");
441 // The verification code cannot be set, as Chrome does not store this data.
442 card
.SetRawInfo(CREDIT_CARD_VERIFICATION_CODE
, ASCIIToUTF16("999"));
443 EXPECT_EQ(base::string16(), card
.GetRawInfo(CREDIT_CARD_VERIFICATION_CODE
));
447 TEST(CreditCardTest
, GetCreditCardType
) {
449 std::string card_number
;
453 // The relevant sample numbers from
454 // http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
455 { "378282246310005", kAmericanExpressCard
, true },
456 { "371449635398431", kAmericanExpressCard
, true },
457 { "378734493671000", kAmericanExpressCard
, true },
458 { "30569309025904", kDinersCard
, true },
459 { "38520000023237", kDinersCard
, true },
460 { "6011111111111117", kDiscoverCard
, true },
461 { "6011000990139424", kDiscoverCard
, true },
462 { "3530111333300000", kJCBCard
, true },
463 { "3566002020360505", kJCBCard
, true },
464 { "5555555555554444", kMasterCard
, true },
465 { "5105105105105100", kMasterCard
, true },
466 { "4111111111111111", kVisaCard
, true },
467 { "4012888888881881", kVisaCard
, true },
468 { "4222222222222", kVisaCard
, true },
470 // The relevant sample numbers from
471 // http://auricsystems.com/support-center/sample-credit-card-numbers/
472 { "343434343434343", kAmericanExpressCard
, true },
473 { "371144371144376", kAmericanExpressCard
, true },
474 { "341134113411347", kAmericanExpressCard
, true },
475 { "36438936438936", kDinersCard
, true },
476 { "36110361103612", kDinersCard
, true },
477 { "36111111111111", kDinersCard
, true },
478 { "6011016011016011", kDiscoverCard
, true },
479 { "6011000990139424", kDiscoverCard
, true },
480 { "6011000000000004", kDiscoverCard
, true },
481 { "6011000995500000", kDiscoverCard
, true },
482 { "6500000000000002", kDiscoverCard
, true },
483 { "3566002020360505", kJCBCard
, true },
484 { "3528000000000007", kJCBCard
, true },
485 { "5500005555555559", kMasterCard
, true },
486 { "5555555555555557", kMasterCard
, true },
487 { "5454545454545454", kMasterCard
, true },
488 { "5555515555555551", kMasterCard
, true },
489 { "5405222222222226", kMasterCard
, true },
490 { "5478050000000007", kMasterCard
, true },
491 { "5111005111051128", kMasterCard
, true },
492 { "5112345112345114", kMasterCard
, true },
493 { "5115915115915118", kMasterCard
, true },
495 // A UnionPay card that doesn't pass the Luhn checksum
496 { "6200000000000000", kUnionPay
, true },
499 { std::string(), kGenericCard
, false },
502 { "garbage", kGenericCard
, false },
503 { "4garbage", kVisaCard
, false },
506 { "4111111111111112", kVisaCard
, false },
509 { "3434343434343434", kAmericanExpressCard
, false },
510 { "411111111111116", kVisaCard
, false },
512 // Issuer Identification Numbers (IINs) that Chrome recognizes.
513 { "4", kVisaCard
, false },
514 { "34", kAmericanExpressCard
, false },
515 { "37", kAmericanExpressCard
, false },
516 { "300", kDinersCard
, false },
517 { "301", kDinersCard
, false },
518 { "302", kDinersCard
, false },
519 { "303", kDinersCard
, false },
520 { "304", kDinersCard
, false },
521 { "305", kDinersCard
, false },
522 { "3095", kDinersCard
, false },
523 { "36", kDinersCard
, false },
524 { "38", kDinersCard
, false },
525 { "39", kDinersCard
, false },
526 { "6011", kDiscoverCard
, false },
527 { "644", kDiscoverCard
, false },
528 { "645", kDiscoverCard
, false },
529 { "646", kDiscoverCard
, false },
530 { "647", kDiscoverCard
, false },
531 { "648", kDiscoverCard
, false },
532 { "649", kDiscoverCard
, false },
533 { "65", kDiscoverCard
, false },
534 { "3528", kJCBCard
, false },
535 { "3531", kJCBCard
, false },
536 { "3589", kJCBCard
, false },
537 { "51", kMasterCard
, false },
538 { "52", kMasterCard
, false },
539 { "53", kMasterCard
, false },
540 { "54", kMasterCard
, false },
541 { "55", kMasterCard
, false },
542 { "62", kUnionPay
, false },
544 // Not enough data to determine an IIN uniquely.
545 { "3", kGenericCard
, false },
546 { "30", kGenericCard
, false },
547 { "309", kGenericCard
, false },
548 { "35", kGenericCard
, false },
549 { "5", kGenericCard
, false },
550 { "6", kGenericCard
, false },
551 { "60", kGenericCard
, false },
552 { "601", kGenericCard
, false },
553 { "64", kGenericCard
, false },
556 { "0", kGenericCard
, false },
557 { "1", kGenericCard
, false },
558 { "2", kGenericCard
, false },
559 { "306", kGenericCard
, false },
560 { "307", kGenericCard
, false },
561 { "308", kGenericCard
, false },
562 { "3091", kGenericCard
, false },
563 { "3094", kGenericCard
, false },
564 { "3096", kGenericCard
, false },
565 { "31", kGenericCard
, false },
566 { "32", kGenericCard
, false },
567 { "33", kGenericCard
, false },
568 { "351", kGenericCard
, false },
569 { "3527", kGenericCard
, false },
570 { "359", kGenericCard
, false },
571 { "50", kGenericCard
, false },
572 { "56", kGenericCard
, false },
573 { "57", kGenericCard
, false },
574 { "58", kGenericCard
, false },
575 { "59", kGenericCard
, false },
576 { "600", kGenericCard
, false },
577 { "602", kGenericCard
, false },
578 { "603", kGenericCard
, false },
579 { "604", kGenericCard
, false },
580 { "605", kGenericCard
, false },
581 { "606", kGenericCard
, false },
582 { "607", kGenericCard
, false },
583 { "608", kGenericCard
, false },
584 { "609", kGenericCard
, false },
585 { "61", kGenericCard
, false },
586 { "63", kGenericCard
, false },
587 { "640", kGenericCard
, false },
588 { "641", kGenericCard
, false },
589 { "642", kGenericCard
, false },
590 { "643", kGenericCard
, false },
591 { "66", kGenericCard
, false },
592 { "67", kGenericCard
, false },
593 { "68", kGenericCard
, false },
594 { "69", kGenericCard
, false },
595 { "7", kGenericCard
, false },
596 { "8", kGenericCard
, false },
597 { "9", kGenericCard
, false },
599 // Oddball case: Unknown issuer, but valid Luhn check and plausible length.
600 { "7000700070007000", kGenericCard
, true },
603 for (size_t i
= 0; i
< arraysize(test_cases
); ++i
) {
604 base::string16 card_number
= ASCIIToUTF16(test_cases
[i
].card_number
);
605 SCOPED_TRACE(card_number
);
606 EXPECT_EQ(test_cases
[i
].type
, CreditCard::GetCreditCardType(card_number
));
607 EXPECT_EQ(test_cases
[i
].is_valid
, IsValidCreditCardNumber(card_number
));
611 TEST(CreditCardTest
, LastFourDigits
) {
612 CreditCard
card(base::GenerateGUID(), "https://www.example.com/");
613 ASSERT_EQ(base::string16(), card
.LastFourDigits());
615 test::SetCreditCardInfo(&card
, "Baby Face Nelson",
616 "5212341234123489", "01", "2010");
617 ASSERT_EQ(base::ASCIIToUTF16("3489"), card
.LastFourDigits());
619 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16("3489"));
620 ASSERT_EQ(base::ASCIIToUTF16("3489"), card
.LastFourDigits());
622 card
.SetRawInfo(CREDIT_CARD_NUMBER
, ASCIIToUTF16("489"));
623 ASSERT_EQ(base::ASCIIToUTF16("489"), card
.LastFourDigits());
626 TEST(CreditCardTest
, CanBuildFromCardNumberAndExpirationDate
) {
627 base::string16 card_number
= base::ASCIIToUTF16("test");
630 CreditCard
card(card_number
, month
, year
);
631 EXPECT_EQ(card_number
, card
.number());
632 EXPECT_EQ(month
, card
.expiration_month());
633 EXPECT_EQ(year
, card
.expiration_year());
636 } // namespace autofill