autofill_field_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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 "components/autofill/core/browser/autofill_field.h"
6
7#include "base/format_macros.h"
8#include "base/strings/string_util.h"
9#include "base/strings/stringprintf.h"
10#include "base/strings/utf_string_conversions.h"
11#include "components/autofill/core/browser/autofill_type.h"
12#include "components/autofill/core/browser/field_types.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15using base::ASCIIToUTF16;
16using base::UTF8ToUTF16;
17
18namespace autofill {
19namespace {
20
21// Returns a FormFieldData object corresponding to a <select> field populated
22// with the given |options|.
23FormFieldData GenerateSelectFieldWithOptions(const char* const* options,
24                                             size_t options_size) {
25  std::vector<base::string16> options16(options_size);
26  for (size_t i = 0; i < options_size; ++i) {
27    options16[i] = ASCIIToUTF16(options[i]);
28  }
29
30  FormFieldData form_field;
31  form_field.form_control_type = "select-one";
32  form_field.option_values = options16;
33  form_field.option_contents = options16;
34  return form_field;
35}
36
37TEST(AutofillFieldTest, Type) {
38  AutofillField field;
39  ASSERT_EQ(NO_SERVER_DATA, field.server_type());
40  ASSERT_EQ(UNKNOWN_TYPE, field.heuristic_type());
41
42  // |server_type_| is NO_SERVER_DATA, so |heuristic_type_| is returned.
43  EXPECT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType());
44
45  // Set the heuristic type and check it.
46  field.set_heuristic_type(NAME_FIRST);
47  EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType());
48  EXPECT_EQ(NAME, field.Type().group());
49
50  // Set the server type and check it.
51  field.set_server_type(ADDRESS_BILLING_LINE1);
52  EXPECT_EQ(ADDRESS_HOME_LINE1, field.Type().GetStorableType());
53  EXPECT_EQ(ADDRESS_BILLING, field.Type().group());
54
55  // Remove the server type to make sure the heuristic type is preserved.
56  field.set_server_type(NO_SERVER_DATA);
57  EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType());
58  EXPECT_EQ(NAME, field.Type().group());
59}
60
61TEST(AutofillFieldTest, IsEmpty) {
62  AutofillField field;
63  ASSERT_EQ(base::string16(), field.value);
64
65  // Field value is empty.
66  EXPECT_TRUE(field.IsEmpty());
67
68  // Field value is non-empty.
69  field.value = ASCIIToUTF16("Value");
70  EXPECT_FALSE(field.IsEmpty());
71}
72
73TEST(AutofillFieldTest, FieldSignature) {
74  AutofillField field;
75  ASSERT_EQ(base::string16(), field.name);
76  ASSERT_EQ(std::string(), field.form_control_type);
77
78  // Signature is empty.
79  EXPECT_EQ("2085434232", field.FieldSignature());
80
81  // Field name is set.
82  field.name = ASCIIToUTF16("Name");
83  EXPECT_EQ("1606968241", field.FieldSignature());
84
85  // Field form control type is set.
86  field.form_control_type = "text";
87  EXPECT_EQ("502192749", field.FieldSignature());
88
89  // Heuristic type does not affect FieldSignature.
90  field.set_heuristic_type(NAME_FIRST);
91  EXPECT_EQ("502192749", field.FieldSignature());
92
93  // Server type does not affect FieldSignature.
94  field.set_server_type(NAME_LAST);
95  EXPECT_EQ("502192749", field.FieldSignature());
96}
97
98TEST(AutofillFieldTest, IsFieldFillable) {
99  AutofillField field;
100  ASSERT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType());
101
102  // Type is unknown.
103  EXPECT_FALSE(field.IsFieldFillable());
104
105  // Only heuristic type is set.
106  field.set_heuristic_type(NAME_FIRST);
107  EXPECT_TRUE(field.IsFieldFillable());
108
109  // Only server type is set.
110  field.set_heuristic_type(UNKNOWN_TYPE);
111  field.set_server_type(NAME_LAST);
112  EXPECT_TRUE(field.IsFieldFillable());
113
114  // Both types set.
115  field.set_heuristic_type(NAME_FIRST);
116  field.set_server_type(NAME_LAST);
117  EXPECT_TRUE(field.IsFieldFillable());
118
119  // Field has autocomplete="off" set.
120  field.should_autocomplete = false;
121  EXPECT_FALSE(field.IsFieldFillable());
122}
123
124TEST(AutofillFieldTest, FillPhoneNumber) {
125  AutofillField field;
126  field.SetHtmlType(HTML_TYPE_TEL_LOCAL_PREFIX, HtmlFieldMode());
127
128  // Fill with a non-phone number; should fill normally.
129  AutofillField::FillFormField(
130      field, ASCIIToUTF16("Oh hai"), "en-US", "en-US", &field);
131  EXPECT_EQ(ASCIIToUTF16("Oh hai"), field.value);
132
133  // Fill with a phone number; should fill just the prefix.
134  AutofillField::FillFormField(
135      field, ASCIIToUTF16("5551234"), "en-US", "en-US", &field);
136  EXPECT_EQ(ASCIIToUTF16("555"), field.value);
137
138  // Now reset the type, and set a max-length instead.
139  field.SetHtmlType(HTML_TYPE_UNKNOWN, HtmlFieldMode());
140  field.set_heuristic_type(PHONE_HOME_NUMBER);
141  field.max_length = 4;
142
143  // Fill with a phone-number; should fill just the suffix.
144  AutofillField::FillFormField(
145      field, ASCIIToUTF16("5551234"), "en-US", "en-US", &field);
146  EXPECT_EQ(ASCIIToUTF16("1234"), field.value);
147}
148
149TEST(AutofillFieldTest, FillSelectControlByValue) {
150  const char* const kOptions[] = {
151    "Eenie", "Meenie", "Miney", "Mo",
152  };
153  AutofillField field(
154      GenerateSelectFieldWithOptions(kOptions, arraysize(kOptions)),
155      base::string16());
156
157  // Set semantically empty contents for each option, so that only the values
158  // can be used for matching.
159  for (size_t i = 0; i < field.option_contents.size(); ++i) {
160    field.option_contents[i] = ASCIIToUTF16(base::StringPrintf("%" PRIuS, i));
161  }
162
163  AutofillField::FillFormField(
164      field, ASCIIToUTF16("Meenie"), "en-US", "en-US", &field);
165  EXPECT_EQ(ASCIIToUTF16("Meenie"), field.value);
166}
167
168TEST(AutofillFieldTest, FillSelectControlByContents) {
169  const char* const kOptions[] = {
170    "Eenie", "Meenie", "Miney", "Mo",
171  };
172  AutofillField field(
173      GenerateSelectFieldWithOptions(kOptions, arraysize(kOptions)),
174      base::string16());
175
176  // Set semantically empty values for each option, so that only the contents
177  // can be used for matching.
178  for (size_t i = 0; i < field.option_values.size(); ++i) {
179    field.option_values[i] = ASCIIToUTF16(base::StringPrintf("%" PRIuS, i));
180  }
181
182  AutofillField::FillFormField(
183      field, ASCIIToUTF16("Miney"), "en-US", "en-US", &field);
184  EXPECT_EQ(ASCIIToUTF16("2"), field.value);  // Corresponds to "Miney".
185}
186
187TEST(AutofillFieldTest, FillSelectControlWithFullCountryNames) {
188  const char* const kCountries[] = {
189    "Albania", "Canada"
190  };
191  AutofillField field(
192      GenerateSelectFieldWithOptions(kCountries, arraysize(kCountries)),
193      base::string16());
194  field.set_heuristic_type(ADDRESS_HOME_COUNTRY);
195
196  AutofillField::FillFormField(
197      field, ASCIIToUTF16("CA"), "en-US", "en-US", &field);
198  EXPECT_EQ(ASCIIToUTF16("Canada"), field.value);
199}
200
201TEST(AutofillFieldTest, FillSelectControlWithAbbreviatedCountryNames) {
202  const char* const kCountries[] = {
203    "AL", "CA"
204  };
205  AutofillField field(
206      GenerateSelectFieldWithOptions(kCountries, arraysize(kCountries)),
207      base::string16());
208  field.set_heuristic_type(ADDRESS_HOME_COUNTRY);
209
210  AutofillField::FillFormField(
211      field, ASCIIToUTF16("Canada"), "en-US", "en-US", &field);
212  EXPECT_EQ(ASCIIToUTF16("CA"), field.value);
213}
214
215TEST(AutofillFieldTest, FillSelectControlWithFullStateNames) {
216  const char* const kStates[] = {
217    "Alabama", "California"
218  };
219  AutofillField field(
220      GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
221      base::string16());
222  field.set_heuristic_type(ADDRESS_HOME_STATE);
223
224  AutofillField::FillFormField(
225      field, ASCIIToUTF16("CA"), "en-US", "en-US", &field);
226  EXPECT_EQ(ASCIIToUTF16("California"), field.value);
227}
228
229TEST(AutofillFieldTest, FillSelectControlWithAbbreviateStateNames) {
230  const char* const kStates[] = {
231    "AL", "CA"
232  };
233  AutofillField field(
234      GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
235      base::string16());
236  field.set_heuristic_type(ADDRESS_HOME_STATE);
237
238  AutofillField::FillFormField(
239      field, ASCIIToUTF16("California"), "en-US", "en-US", &field);
240  EXPECT_EQ(ASCIIToUTF16("CA"), field.value);
241}
242
243TEST(AutofillFieldTest, FillSelectControlWithInexactFullStateNames) {
244  {
245    const char* const kStates[] = {
246      "SC - South Carolina", "CA - California", "NC - North Carolina",
247    };
248    AutofillField field(
249        GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
250        base::string16());
251    field.set_heuristic_type(ADDRESS_HOME_STATE);
252
253    AutofillField::FillFormField(
254        field, ASCIIToUTF16("California"), "en-US", "en-US", &field);
255    EXPECT_EQ(ASCIIToUTF16("CA - California"), field.value);
256  }
257
258  // Don't accidentally match "Virginia" to "West Virginia".
259  {
260    const char* const kStates[] = {
261      "WV - West Virginia", "VA - Virginia", "NV - North Virginia",
262    };
263    AutofillField field(
264        GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
265        base::string16());
266    field.set_heuristic_type(ADDRESS_HOME_STATE);
267
268    AutofillField::FillFormField(
269        field, ASCIIToUTF16("Virginia"), "en-US", "en-US", &field);
270    EXPECT_EQ(ASCIIToUTF16("VA - Virginia"), field.value);
271  }
272
273  // Do accidentally match "Virginia" to "West Virginia". NB: Ideally, Chrome
274  // would fail this test. It's here to document behavior rather than enforce
275  // it.
276  {
277    const char* const kStates[] = {
278      "WV - West Virginia", "TX - Texas",
279    };
280    AutofillField field(
281        GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
282        base::string16());
283    field.set_heuristic_type(ADDRESS_HOME_STATE);
284
285    AutofillField::FillFormField(
286        field, ASCIIToUTF16("Virginia"), "en-US", "en-US", &field);
287    EXPECT_EQ(ASCIIToUTF16("WV - West Virginia"), field.value);
288  }
289
290  // Tests that substring matches work for full state names (a full token
291  // match isn't required). Also tests that matches work for states with
292  // whitespace in the middle.
293  {
294    const char* const kStates[] = {
295      "California.", "North Carolina.",
296    };
297    AutofillField field(
298        GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
299        base::string16());
300    field.set_heuristic_type(ADDRESS_HOME_STATE);
301
302    AutofillField::FillFormField(
303        field, ASCIIToUTF16("North Carolina"), "en-US", "en-US", &field);
304    EXPECT_EQ(ASCIIToUTF16("North Carolina."), field.value);
305  }
306}
307
308TEST(AutofillFieldTest, FillSelectControlWithInexactAbbreviations) {
309  {
310    const char* const kStates[] = {
311      "NC - North Carolina", "CA - California",
312    };
313    AutofillField field(
314        GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
315        base::string16());
316    field.set_heuristic_type(ADDRESS_HOME_STATE);
317
318    AutofillField::FillFormField(
319        field, ASCIIToUTF16("CA"), "en-US", "en-US", &field);
320    EXPECT_EQ(ASCIIToUTF16("CA - California"), field.value);
321  }
322
323  {
324    const char* const kNotStates[] = {
325      "NCNCA", "SCNCA",
326    };
327    AutofillField field(
328        GenerateSelectFieldWithOptions(kNotStates, arraysize(kNotStates)),
329        base::string16());
330    field.set_heuristic_type(ADDRESS_HOME_STATE);
331
332    AutofillField::FillFormField(
333        field, ASCIIToUTF16("NC"), "en-US", "en-US", &field);
334    EXPECT_EQ(base::string16(), field.value);
335  }
336}
337
338TEST(AutofillFieldTest, FillSelectControlWithNumericMonth) {
339  const char* const kMonthsNumeric[] = {
340    "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12",
341  };
342  AutofillField field(
343      GenerateSelectFieldWithOptions(kMonthsNumeric, arraysize(kMonthsNumeric)),
344      base::string16());
345  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
346
347  // Try with a leading zero.
348  AutofillField::FillFormField(
349      field, ASCIIToUTF16("03"), "en-US", "en-US", &field);
350  EXPECT_EQ(ASCIIToUTF16("03"), field.value);
351
352  // Try without a leading zero.
353  AutofillField::FillFormField(
354      field, ASCIIToUTF16("4"), "en-US", "en-US", &field);
355  EXPECT_EQ(ASCIIToUTF16("04"), field.value);
356
357  // Try a two-digit month.
358  AutofillField::FillFormField(
359      field, ASCIIToUTF16("11"), "en-US", "en-US", &field);
360  EXPECT_EQ(ASCIIToUTF16("11"), field.value);
361}
362
363TEST(AutofillFieldTest, FillSelectControlWithAbbreviatedMonthName) {
364  const char* const kMonthsAbbreviated[] = {
365    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
366    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
367  };
368  AutofillField field(
369      GenerateSelectFieldWithOptions(
370          kMonthsAbbreviated, arraysize(kMonthsAbbreviated)),
371      base::string16());
372  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
373
374  AutofillField::FillFormField(
375      field, ASCIIToUTF16("04"), "en-US", "en-US", &field);
376  EXPECT_EQ(ASCIIToUTF16("Apr"), field.value);
377}
378
379TEST(AutofillFieldTest, FillSelectControlWithFullMonthName) {
380  const char* const kMonthsFull[] = {
381    "January","February", "March", "April", "May", "June",
382    "July", "August", "September", "October", "November", "December",
383  };
384  AutofillField field(
385      GenerateSelectFieldWithOptions(kMonthsFull, arraysize(kMonthsFull)),
386      base::string16());
387  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
388
389  AutofillField::FillFormField(
390      field, ASCIIToUTF16("04"), "en-US", "en-US", &field);
391  EXPECT_EQ(ASCIIToUTF16("April"), field.value);
392}
393
394TEST(AutofillFieldTest, FillSelectControlWithNumericMonthSansLeadingZero) {
395  const char* const kMonthsNumeric[] = {
396    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
397  };
398  AutofillField field(
399      GenerateSelectFieldWithOptions(kMonthsNumeric, arraysize(kMonthsNumeric)),
400      base::string16());
401  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
402
403  AutofillField::FillFormField(
404      field, ASCIIToUTF16("04"), "en-US", "en-US", &field);
405  EXPECT_EQ(ASCIIToUTF16("4"), field.value);
406}
407
408TEST(AutofillFieldTest, FillSelectControlWithTwoDigitCreditCardYear) {
409  const char* const kYears[] = {
410    "12", "13", "14", "15", "16", "17", "18", "19"
411  };
412  AutofillField field(GenerateSelectFieldWithOptions(kYears, arraysize(kYears)),
413                      base::string16());
414  field.set_heuristic_type(CREDIT_CARD_EXP_2_DIGIT_YEAR);
415
416  AutofillField::FillFormField(
417      field, ASCIIToUTF16("2017"), "en-US", "en-US", &field);
418  EXPECT_EQ(ASCIIToUTF16("17"), field.value);
419}
420
421TEST(AutofillFieldTest, FillSelectControlWithCreditCardType) {
422  const char* const kCreditCardTypes[] = {
423    "Visa", "Master Card", "AmEx", "discover"
424  };
425  AutofillField field(
426      GenerateSelectFieldWithOptions(
427          kCreditCardTypes, arraysize(kCreditCardTypes)),
428      base::string16());
429  field.set_heuristic_type(CREDIT_CARD_TYPE);
430
431  // Normal case:
432  AutofillField::FillFormField(
433      field, ASCIIToUTF16("Visa"), "en-US", "en-US", &field);
434  EXPECT_EQ(ASCIIToUTF16("Visa"), field.value);
435
436  // Filling should be able to handle intervening whitespace:
437  AutofillField::FillFormField(
438      field, ASCIIToUTF16("MasterCard"), "en-US", "en-US", &field);
439  EXPECT_EQ(ASCIIToUTF16("Master Card"), field.value);
440
441  // American Express is sometimes abbreviated as AmEx:
442  AutofillField::FillFormField(
443      field, ASCIIToUTF16("American Express"), "en-US", "en-US", &field);
444  EXPECT_EQ(ASCIIToUTF16("AmEx"), field.value);
445
446  // Case insensitivity:
447  AutofillField::FillFormField(
448      field, ASCIIToUTF16("Discover"), "en-US", "en-US", &field);
449  EXPECT_EQ(ASCIIToUTF16("discover"), field.value);
450}
451
452TEST(AutofillFieldTest, FillMonthControl) {
453  AutofillField field;
454  field.form_control_type = "month";
455
456  // Try a month with two digits.
457  AutofillField::FillFormField(
458      field, ASCIIToUTF16("12/2017"), "en-US", "en-US", &field);
459  EXPECT_EQ(ASCIIToUTF16("2017-12"), field.value);
460
461  // Try a month with a leading zero.
462  AutofillField::FillFormField(
463      field, ASCIIToUTF16("03/2019"), "en-US", "en-US", &field);
464  EXPECT_EQ(ASCIIToUTF16("2019-03"), field.value);
465
466  // Try a month without a leading zero.
467  AutofillField::FillFormField(
468      field, ASCIIToUTF16("4/2018"), "en-US", "en-US", &field);
469  EXPECT_EQ(ASCIIToUTF16("2018-04"), field.value);
470}
471
472TEST(AutofillFieldTest, FillStreetAddressTextArea) {
473  AutofillField field;
474  field.form_control_type = "textarea";
475
476  base::string16 value = ASCIIToUTF16("123 Fake St.\n"
477                                      "Apt. 42");
478  AutofillField::FillFormField(field, value, "en-US", "en-US", &field);
479  EXPECT_EQ(value, field.value);
480
481  base::string16 ja_value = UTF8ToUTF16("桜丘町26-1\n"
482                                        "セルリアンタワー6階");
483  AutofillField::FillFormField(field, ja_value, "ja-JP", "en-US", &field);
484  EXPECT_EQ(ja_value, field.value);
485}
486
487TEST(AutofillFieldTest, FillStreetAddressTextField) {
488  AutofillField field;
489  field.form_control_type = "text";
490  field.set_server_type(ADDRESS_HOME_STREET_ADDRESS);
491
492  base::string16 value = ASCIIToUTF16("123 Fake St.\n"
493                                      "Apt. 42");
494  AutofillField::FillFormField(field, value, "en-US", "en-US", &field);
495  EXPECT_EQ(ASCIIToUTF16("123 Fake St., Apt. 42"), field.value);
496
497  AutofillField::FillFormField(field,
498                               UTF8ToUTF16("桜丘町26-1\n"
499                                           "セルリアンタワー6階"),
500                               "ja-JP",
501                               "en-US",
502                               &field);
503  EXPECT_EQ(UTF8ToUTF16("桜丘町26-1セルリアンタワー6階"), field.value);
504}
505
506}  // namespace
507}  // namespace autofill
508