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/memory/scoped_ptr.h"
6 #include "base/memory/scoped_vector.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "components/autofill/core/browser/autofill_field.h"
9 #include "components/autofill/core/browser/autofill_scanner.h"
10 #include "components/autofill/core/browser/credit_card_field.h"
11 #include "components/autofill/core/common/form_field_data.h"
12 #include "testing/gtest/include/gtest/gtest.h"
14 using base::ASCIIToUTF16
;
18 class CreditCardFieldTest
: public testing::Test
{
20 CreditCardFieldTest() {}
21 ~CreditCardFieldTest() override
{}
24 ScopedVector
<AutofillField
> list_
;
25 scoped_ptr
<const CreditCardField
> field_
;
26 ServerFieldTypeMap field_type_map_
;
28 // Parses the contents of |list_| as a form, and stores the result into
31 AutofillScanner
scanner(list_
.get());
32 scoped_ptr
<FormField
> field
= CreditCardField::Parse(&scanner
);
33 field_
= make_scoped_ptr(static_cast<CreditCardField
*>(field
.release()));
36 // Associates fields with their corresponding types, based on the previous
38 bool ClassifyField() {
39 return field_
->ClassifyField(&field_type_map_
);
43 DISALLOW_COPY_AND_ASSIGN(CreditCardFieldTest
);
46 TEST_F(CreditCardFieldTest
, Empty
) {
48 ASSERT_EQ(nullptr, field_
.get());
51 TEST_F(CreditCardFieldTest
, NonParse
) {
52 list_
.push_back(new AutofillField
);
54 ASSERT_EQ(nullptr, field_
.get());
57 TEST_F(CreditCardFieldTest
, ParseCreditCardNoNumber
) {
59 field
.form_control_type
= "text";
61 field
.label
= ASCIIToUTF16("Exp Month");
62 field
.name
= ASCIIToUTF16("ccmonth");
63 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month1")));
65 field
.label
= ASCIIToUTF16("Exp Year");
66 field
.name
= ASCIIToUTF16("ccyear");
67 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year2")));
70 ASSERT_EQ(nullptr, field_
.get());
73 TEST_F(CreditCardFieldTest
, ParseCreditCardNoDate
) {
75 field
.form_control_type
= "text";
77 field
.label
= ASCIIToUTF16("Card Number");
78 field
.name
= ASCIIToUTF16("card_number");
79 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number1")));
82 ASSERT_EQ(nullptr, field_
.get());
85 TEST_F(CreditCardFieldTest
, ParseMiniumCreditCard
) {
87 field
.form_control_type
= "text";
89 field
.label
= ASCIIToUTF16("Card Number");
90 field
.name
= ASCIIToUTF16("card_number");
91 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number1")));
93 field
.label
= ASCIIToUTF16("Exp Month");
94 field
.name
= ASCIIToUTF16("ccmonth");
95 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month2")));
97 field
.label
= ASCIIToUTF16("Exp Year");
98 field
.name
= ASCIIToUTF16("ccyear");
99 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year3")));
102 ASSERT_NE(nullptr, field_
.get());
103 EXPECT_TRUE(ClassifyField());
105 field_type_map_
.find(ASCIIToUTF16("number1")) != field_type_map_
.end());
106 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number1")]);
108 field_type_map_
.find(ASCIIToUTF16("month2")) != field_type_map_
.end());
109 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, field_type_map_
[ASCIIToUTF16("month2")]);
111 field_type_map_
.find(ASCIIToUTF16("year3")) != field_type_map_
.end());
112 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
113 field_type_map_
[ASCIIToUTF16("year3")]);
116 TEST_F(CreditCardFieldTest
, ParseFullCreditCard
) {
118 field
.form_control_type
= "text";
120 field
.label
= ASCIIToUTF16("Card Type");
121 field
.name
= ASCIIToUTF16("card_type");
122 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("type")));
124 field
.label
= ASCIIToUTF16("Name on Card");
125 field
.name
= ASCIIToUTF16("name_on_card");
126 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("name")));
128 field
.label
= ASCIIToUTF16("Card Number");
129 field
.name
= ASCIIToUTF16("card_number");
130 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number")));
132 field
.label
= ASCIIToUTF16("Exp Month");
133 field
.name
= ASCIIToUTF16("ccmonth");
134 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month")));
136 field
.label
= ASCIIToUTF16("Exp Year");
137 field
.name
= ASCIIToUTF16("ccyear");
138 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year")));
140 field
.label
= ASCIIToUTF16("Verification");
141 field
.name
= ASCIIToUTF16("verification");
142 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("cvc")));
145 ASSERT_NE(nullptr, field_
.get());
146 EXPECT_TRUE(ClassifyField());
148 field_type_map_
.find(ASCIIToUTF16("type")) != field_type_map_
.end());
149 EXPECT_EQ(CREDIT_CARD_TYPE
, field_type_map_
[ASCIIToUTF16("type")]);
151 field_type_map_
.find(ASCIIToUTF16("name")) != field_type_map_
.end());
152 EXPECT_EQ(CREDIT_CARD_NAME
, field_type_map_
[ASCIIToUTF16("name")]);
154 field_type_map_
.find(ASCIIToUTF16("number")) != field_type_map_
.end());
155 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number")]);
157 field_type_map_
.find(ASCIIToUTF16("month")) != field_type_map_
.end());
158 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, field_type_map_
[ASCIIToUTF16("month")]);
160 field_type_map_
.find(ASCIIToUTF16("year")) != field_type_map_
.end());
161 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
162 field_type_map_
[ASCIIToUTF16("year")]);
164 field_type_map_
.find(ASCIIToUTF16("cvc")) != field_type_map_
.end());
165 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE
,
166 field_type_map_
[ASCIIToUTF16("cvc")]);
169 TEST_F(CreditCardFieldTest
, ParseExpMonthYear
) {
171 field
.form_control_type
= "text";
173 field
.label
= ASCIIToUTF16("Name on Card");
174 field
.name
= ASCIIToUTF16("name_on_card");
175 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("name1")));
177 field
.label
= ASCIIToUTF16("Card Number");
178 field
.name
= ASCIIToUTF16("card_number");
179 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number2")));
181 field
.label
= ASCIIToUTF16("ExpDate Month / Year");
182 field
.name
= ASCIIToUTF16("ExpDate");
183 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month3")));
185 field
.label
= ASCIIToUTF16("ExpDate Month / Year");
186 field
.name
= ASCIIToUTF16("ExpDate");
187 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year4")));
190 ASSERT_NE(nullptr, field_
.get());
191 EXPECT_TRUE(ClassifyField());
193 field_type_map_
.find(ASCIIToUTF16("name1")) != field_type_map_
.end());
194 EXPECT_EQ(CREDIT_CARD_NAME
, field_type_map_
[ASCIIToUTF16("name1")]);
196 field_type_map_
.find(ASCIIToUTF16("number2")) != field_type_map_
.end());
197 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number2")]);
199 field_type_map_
.find(ASCIIToUTF16("month3")) != field_type_map_
.end());
200 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, field_type_map_
[ASCIIToUTF16("month3")]);
202 field_type_map_
.find(ASCIIToUTF16("year4")) != field_type_map_
.end());
203 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
204 field_type_map_
[ASCIIToUTF16("year4")]);
207 TEST_F(CreditCardFieldTest
, ParseExpMonthYear2
) {
209 field
.form_control_type
= "text";
211 field
.label
= ASCIIToUTF16("Name on Card");
212 field
.name
= ASCIIToUTF16("name_on_card");
213 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("name1")));
215 field
.label
= ASCIIToUTF16("Card Number");
216 field
.name
= ASCIIToUTF16("card_number");
217 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number2")));
219 field
.label
= ASCIIToUTF16("Expiration date Month / Year");
220 field
.name
= ASCIIToUTF16("ExpDate");
221 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month3")));
223 field
.label
= ASCIIToUTF16("Expiration date Month / Year");
224 field
.name
= ASCIIToUTF16("ExpDate");
225 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year4")));
228 ASSERT_NE(nullptr, field_
.get());
229 EXPECT_TRUE(ClassifyField());
231 field_type_map_
.find(ASCIIToUTF16("name1")) != field_type_map_
.end());
232 EXPECT_EQ(CREDIT_CARD_NAME
, field_type_map_
[ASCIIToUTF16("name1")]);
234 field_type_map_
.find(ASCIIToUTF16("number2")) != field_type_map_
.end());
235 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number2")]);
237 field_type_map_
.find(ASCIIToUTF16("month3")) != field_type_map_
.end());
238 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, field_type_map_
[ASCIIToUTF16("month3")]);
240 field_type_map_
.find(ASCIIToUTF16("year4")) != field_type_map_
.end());
241 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
242 field_type_map_
[ASCIIToUTF16("year4")]);
245 TEST_F(CreditCardFieldTest
, ParseExpField
) {
247 field
.form_control_type
= "text";
249 field
.label
= ASCIIToUTF16("Name on Card");
250 field
.name
= ASCIIToUTF16("name_on_card");
251 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("name1")));
253 field
.label
= ASCIIToUTF16("Card Number");
254 field
.name
= ASCIIToUTF16("card_number");
255 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number2")));
257 field
.label
= ASCIIToUTF16("Expiration Date (MM/YYYY)");
258 field
.name
= ASCIIToUTF16("cc_exp");
259 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("exp3")));
262 ASSERT_NE(nullptr, field_
.get());
263 EXPECT_TRUE(ClassifyField());
265 field_type_map_
.find(ASCIIToUTF16("name1")) != field_type_map_
.end());
266 EXPECT_EQ(CREDIT_CARD_NAME
, field_type_map_
[ASCIIToUTF16("name1")]);
268 field_type_map_
.find(ASCIIToUTF16("number2")) != field_type_map_
.end());
269 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number2")]);
271 field_type_map_
.find(ASCIIToUTF16("exp3")) != field_type_map_
.end());
272 EXPECT_EQ(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
,
273 field_type_map_
[ASCIIToUTF16("exp3")]);
276 TEST_F(CreditCardFieldTest
, ParseExpField2DigitYear
) {
278 field
.form_control_type
= "text";
280 field
.label
= ASCIIToUTF16("Name on Card");
281 field
.name
= ASCIIToUTF16("name_on_card");
282 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("name1")));
284 field
.label
= ASCIIToUTF16("Card Number");
285 field
.name
= ASCIIToUTF16("card_number");
286 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number2")));
288 field
.label
= ASCIIToUTF16("Expiration Date (MM/YY)");
289 field
.name
= ASCIIToUTF16("cc_exp");
290 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("exp3")));
293 ASSERT_NE(nullptr, field_
.get());
294 EXPECT_TRUE(ClassifyField());
296 field_type_map_
.find(ASCIIToUTF16("name1")) != field_type_map_
.end());
297 EXPECT_EQ(CREDIT_CARD_NAME
, field_type_map_
[ASCIIToUTF16("name1")]);
299 field_type_map_
.find(ASCIIToUTF16("number2")) != field_type_map_
.end());
300 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number2")]);
302 field_type_map_
.find(ASCIIToUTF16("exp3")) != field_type_map_
.end());
303 EXPECT_EQ(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
,
304 field_type_map_
[ASCIIToUTF16("exp3")]);
307 TEST_F(CreditCardFieldTest
, ParseCreditCardHolderNameWithCCFullName
) {
309 field
.form_control_type
= "text";
311 field
.label
= ASCIIToUTF16("Name");
312 field
.name
= ASCIIToUTF16("ccfullname");
313 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("name1")));
316 ASSERT_NE(nullptr, field_
.get());
317 EXPECT_TRUE(ClassifyField());
319 field_type_map_
.find(ASCIIToUTF16("name1")) != field_type_map_
.end());
320 EXPECT_EQ(CREDIT_CARD_NAME
, field_type_map_
[ASCIIToUTF16("name1")]);
323 // Verifies that <input type="month"> controls are able to be parsed correctly.
324 TEST_F(CreditCardFieldTest
, ParseMonthControl
) {
327 field
.form_control_type
= "text";
328 field
.label
= ASCIIToUTF16("Card number:");
329 field
.name
= ASCIIToUTF16("ccnumber");
330 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number1")));
332 field
.form_control_type
= "month";
333 field
.label
= ASCIIToUTF16("Expiration date:");
334 field
.name
= ASCIIToUTF16("ccexp");
335 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("date2")));
338 ASSERT_NE(nullptr, field_
.get());
339 EXPECT_TRUE(ClassifyField());
341 field_type_map_
.find(ASCIIToUTF16("number1")) != field_type_map_
.end());
342 EXPECT_EQ(CREDIT_CARD_NUMBER
,
343 field_type_map_
[ASCIIToUTF16("number1")]);
345 field_type_map_
.find(ASCIIToUTF16("date2")) != field_type_map_
.end());
346 EXPECT_EQ(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
,
347 field_type_map_
[ASCIIToUTF16("date2")]);
350 // Verify that heuristics <input name="ccyear" maxlength="2"/> considers
351 // *maxlength* attribute while parsing 2 Digit expiration year.
352 TEST_F(CreditCardFieldTest
, ParseCreditCardExpYear_2DigitMaxLength
) {
354 field
.form_control_type
= "text";
356 field
.label
= ASCIIToUTF16("Card Number");
357 field
.name
= ASCIIToUTF16("card_number");
358 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number")));
360 field
.label
= ASCIIToUTF16("Expiration Date");
361 field
.name
= ASCIIToUTF16("ccmonth");
362 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month")));
364 field
.name
= ASCIIToUTF16("ccyear");
365 field
.max_length
= 2;
366 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year")));
369 ASSERT_NE(nullptr, field_
.get());
370 EXPECT_TRUE(ClassifyField());
371 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("number")) !=
372 field_type_map_
.end());
373 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number")]);
374 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("month")) !=
375 field_type_map_
.end());
376 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, field_type_map_
[ASCIIToUTF16("month")]);
377 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("year")) !=
378 field_type_map_
.end());
379 EXPECT_EQ(CREDIT_CARD_EXP_2_DIGIT_YEAR
,
380 field_type_map_
[ASCIIToUTF16("year")]);
383 TEST_F(CreditCardFieldTest
, ParseCreditCardNumberWithSplit
) {
385 field
.form_control_type
= "text";
387 field
.label
= ASCIIToUTF16("Card Number");
388 field
.name
= ASCIIToUTF16("card_number_q1");
389 field
.max_length
= 4;
390 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number1")));
392 field
.label
= ASCIIToUTF16("Card Number");
393 field
.name
= ASCIIToUTF16("card_number_q2");
394 field
.max_length
= 4;
395 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number2")));
397 field
.label
= ASCIIToUTF16("Card Number");
398 field
.name
= ASCIIToUTF16("card_number_q3");
399 field
.max_length
= 4;
400 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number3")));
402 // For last credit card number input field it simply ignores the |max_length|
403 // attribute. So even having a very big number, does not conside it an invalid
404 // split for autofilling.
405 field
.label
= ASCIIToUTF16("Card Number");
406 field
.name
= ASCIIToUTF16("card_number_q4");
407 field
.max_length
= 20;
408 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number4")));
410 field
.label
= ASCIIToUTF16("Exp Month");
411 field
.name
= ASCIIToUTF16("ccmonth");
412 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month5")));
414 field
.label
= ASCIIToUTF16("Exp Year");
415 field
.name
= ASCIIToUTF16("ccyear");
416 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year6")));
419 ASSERT_NE(nullptr, field_
.get());
420 EXPECT_TRUE(ClassifyField());
422 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("number1")) !=
423 field_type_map_
.end());
424 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number1")]);
425 EXPECT_EQ(0U, list_
[0]->credit_card_number_offset());
427 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("number2")) !=
428 field_type_map_
.end());
429 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number2")]);
430 EXPECT_EQ(4U, list_
[1]->credit_card_number_offset());
432 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("number3")) !=
433 field_type_map_
.end());
434 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number3")]);
435 EXPECT_EQ(8U, list_
[2]->credit_card_number_offset());
437 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("number4")) !=
438 field_type_map_
.end());
439 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number4")]);
440 EXPECT_EQ(12U, list_
[3]->credit_card_number_offset());
442 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("month5")) !=
443 field_type_map_
.end());
444 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, field_type_map_
[ASCIIToUTF16("month5")]);
445 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("year6")) !=
446 field_type_map_
.end());
447 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
448 field_type_map_
[ASCIIToUTF16("year6")]);
451 TEST_F(CreditCardFieldTest
, ParseMultipleCreditCardNumbers
) {
453 field
.form_control_type
= "text";
455 field
.label
= ASCIIToUTF16("Name on Card");
456 field
.name
= ASCIIToUTF16("name_on_card");
457 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("name1")));
459 field
.label
= ASCIIToUTF16("Card Number");
460 field
.name
= ASCIIToUTF16("card_number");
461 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number2")));
463 field
.label
= ASCIIToUTF16("Confirm Card Number");
464 field
.name
= ASCIIToUTF16("confirm_card_number");
465 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("number3")));
467 field
.label
= ASCIIToUTF16("Exp Month");
468 field
.name
= ASCIIToUTF16("ccmonth");
469 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("month4")));
471 field
.label
= ASCIIToUTF16("Exp Year");
472 field
.name
= ASCIIToUTF16("ccyear");
473 list_
.push_back(new AutofillField(field
, ASCIIToUTF16("year5")));
476 ASSERT_NE(nullptr, field_
.get());
477 EXPECT_TRUE(ClassifyField());
479 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("name1")) !=
480 field_type_map_
.end());
481 EXPECT_EQ(CREDIT_CARD_NAME
, field_type_map_
[ASCIIToUTF16("name1")]);
482 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("number2")) !=
483 field_type_map_
.end());
484 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number2")]);
485 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("number3")) !=
486 field_type_map_
.end());
487 EXPECT_EQ(CREDIT_CARD_NUMBER
, field_type_map_
[ASCIIToUTF16("number3")]);
488 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("month4")) !=
489 field_type_map_
.end());
490 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, field_type_map_
[ASCIIToUTF16("month4")]);
491 ASSERT_TRUE(field_type_map_
.find(ASCIIToUTF16("year5")) !=
492 field_type_map_
.end());
493 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
494 field_type_map_
[ASCIIToUTF16("year5")]);
497 } // namespace autofill