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/format_macros.h"
6#include "base/strings/string_util.h"
7#include "base/strings/stringprintf.h"
8#include "base/strings/utf_string_conversions.h"
9#include "components/autofill/core/browser/autofill_field.h"
10#include "components/autofill/core/browser/autofill_type.h"
11#include "components/autofill/core/browser/field_types.h"
12#include "testing/gtest/include/gtest/gtest.h"
13
14using base::ASCIIToUTF16;
15
16namespace autofill {
17namespace {
18
19// Returns a FormFieldData object corresponding to a <select> field populated
20// with the given |options|.
21FormFieldData GenerateSelectFieldWithOptions(const char* const* options,
22                                             size_t options_size) {
23  std::vector<base::string16> options16(options_size);
24  for (size_t i = 0; i < options_size; ++i) {
25    options16[i] = ASCIIToUTF16(options[i]);
26  }
27
28  FormFieldData form_field;
29  form_field.form_control_type = "select-one";
30  form_field.option_values = options16;
31  form_field.option_contents = options16;
32  return form_field;
33}
34
35TEST(AutofillFieldTest, Type) {
36  AutofillField field;
37  ASSERT_EQ(NO_SERVER_DATA, field.server_type());
38  ASSERT_EQ(UNKNOWN_TYPE, field.heuristic_type());
39
40  // |server_type_| is NO_SERVER_DATA, so |heuristic_type_| is returned.
41  EXPECT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType());
42
43  // Set the heuristic type and check it.
44  field.set_heuristic_type(NAME_FIRST);
45  EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType());
46  EXPECT_EQ(NAME, field.Type().group());
47
48  // Set the server type and check it.
49  field.set_server_type(ADDRESS_BILLING_LINE1);
50  EXPECT_EQ(ADDRESS_HOME_LINE1, field.Type().GetStorableType());
51  EXPECT_EQ(ADDRESS_BILLING, field.Type().group());
52
53  // Remove the server type to make sure the heuristic type is preserved.
54  field.set_server_type(NO_SERVER_DATA);
55  EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType());
56  EXPECT_EQ(NAME, field.Type().group());
57}
58
59TEST(AutofillFieldTest, IsEmpty) {
60  AutofillField field;
61  ASSERT_EQ(base::string16(), field.value);
62
63  // Field value is empty.
64  EXPECT_TRUE(field.IsEmpty());
65
66  // Field value is non-empty.
67  field.value = ASCIIToUTF16("Value");
68  EXPECT_FALSE(field.IsEmpty());
69}
70
71TEST(AutofillFieldTest, FieldSignature) {
72  AutofillField field;
73  ASSERT_EQ(base::string16(), field.name);
74  ASSERT_EQ(std::string(), field.form_control_type);
75
76  // Signature is empty.
77  EXPECT_EQ("2085434232", field.FieldSignature());
78
79  // Field name is set.
80  field.name = ASCIIToUTF16("Name");
81  EXPECT_EQ("1606968241", field.FieldSignature());
82
83  // Field form control type is set.
84  field.form_control_type = "text";
85  EXPECT_EQ("502192749", field.FieldSignature());
86
87  // Heuristic type does not affect FieldSignature.
88  field.set_heuristic_type(NAME_FIRST);
89  EXPECT_EQ("502192749", field.FieldSignature());
90
91  // Server type does not affect FieldSignature.
92  field.set_server_type(NAME_LAST);
93  EXPECT_EQ("502192749", field.FieldSignature());
94}
95
96TEST(AutofillFieldTest, IsFieldFillable) {
97  AutofillField field;
98  ASSERT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType());
99
100  // Type is unknown.
101  EXPECT_FALSE(field.IsFieldFillable());
102
103  // Only heuristic type is set.
104  field.set_heuristic_type(NAME_FIRST);
105  EXPECT_TRUE(field.IsFieldFillable());
106
107  // Only server type is set.
108  field.set_heuristic_type(UNKNOWN_TYPE);
109  field.set_server_type(NAME_LAST);
110  EXPECT_TRUE(field.IsFieldFillable());
111
112  // Both types set.
113  field.set_heuristic_type(NAME_FIRST);
114  field.set_server_type(NAME_LAST);
115  EXPECT_TRUE(field.IsFieldFillable());
116
117  // Field has autocomplete="off" set.
118  field.should_autocomplete = false;
119  EXPECT_FALSE(field.IsFieldFillable());
120}
121
122TEST(AutofillFieldTest, FillPhoneNumber) {
123  AutofillField field;
124  field.SetHtmlType(HTML_TYPE_TEL_LOCAL_PREFIX, HtmlFieldMode());
125
126  // Fill with a non-phone number; should fill normally.
127  AutofillField::FillFormField(field, ASCIIToUTF16("Oh hai"), "en-US", &field);
128  EXPECT_EQ(ASCIIToUTF16("Oh hai"), field.value);
129
130  // Fill with a phone number; should fill just the prefix.
131  AutofillField::FillFormField(field, ASCIIToUTF16("5551234"), "en-US", &field);
132  EXPECT_EQ(ASCIIToUTF16("555"), field.value);
133
134  // Now reset the type, and set a max-length instead.
135  field.SetHtmlType(HTML_TYPE_UNKNOWN, HtmlFieldMode());
136  field.set_heuristic_type(PHONE_HOME_NUMBER);
137  field.max_length = 4;
138
139  // Fill with a phone-number; should fill just the suffix.
140  AutofillField::FillFormField(field, ASCIIToUTF16("5551234"), "en-US", &field);
141  EXPECT_EQ(ASCIIToUTF16("1234"), field.value);
142}
143
144TEST(AutofillFieldTest, FillSelectControlByValue) {
145  const char* const kOptions[] = {
146    "Eenie", "Meenie", "Miney", "Mo",
147  };
148  AutofillField field(
149      GenerateSelectFieldWithOptions(kOptions, arraysize(kOptions)),
150      base::string16());
151
152  // Set semantically empty contents for each option, so that only the values
153  // can be used for matching.
154  for (size_t i = 0; i < field.option_contents.size(); ++i) {
155    field.option_contents[i] = ASCIIToUTF16(base::StringPrintf("%" PRIuS, i));
156  }
157
158  AutofillField::FillFormField(field, ASCIIToUTF16("Meenie"), "en-US",
159                               &field);
160  EXPECT_EQ(ASCIIToUTF16("Meenie"), field.value);
161}
162
163TEST(AutofillFieldTest, FillSelectControlByContents) {
164  const char* const kOptions[] = {
165    "Eenie", "Meenie", "Miney", "Mo",
166  };
167  AutofillField field(
168      GenerateSelectFieldWithOptions(kOptions, arraysize(kOptions)),
169      base::string16());
170
171  // Set semantically empty values for each option, so that only the contents
172  // can be used for matching.
173  for (size_t i = 0; i < field.option_values.size(); ++i) {
174    field.option_values[i] = ASCIIToUTF16(base::StringPrintf("%" PRIuS, i));
175  }
176
177  AutofillField::FillFormField(field, ASCIIToUTF16("Miney"), "en-US",
178                               &field);
179  EXPECT_EQ(ASCIIToUTF16("2"), field.value);  // Corresponds to "Miney".
180}
181
182TEST(AutofillFieldTest, FillSelectControlWithFullCountryNames) {
183  const char* const kCountries[] = {
184    "Albania", "Canada"
185  };
186  AutofillField field(
187      GenerateSelectFieldWithOptions(kCountries, arraysize(kCountries)),
188      base::string16());
189  field.set_heuristic_type(ADDRESS_HOME_COUNTRY);
190
191  AutofillField::FillFormField(field, ASCIIToUTF16("CA"), "en-US", &field);
192  EXPECT_EQ(ASCIIToUTF16("Canada"), field.value);
193}
194
195TEST(AutofillFieldTest, FillSelectControlWithAbbreviatedCountryNames) {
196  const char* const kCountries[] = {
197    "AL", "CA"
198  };
199  AutofillField field(
200      GenerateSelectFieldWithOptions(kCountries, arraysize(kCountries)),
201      base::string16());
202  field.set_heuristic_type(ADDRESS_HOME_COUNTRY);
203
204  AutofillField::FillFormField(field, ASCIIToUTF16("Canada"), "en-US", &field);
205  EXPECT_EQ(ASCIIToUTF16("CA"), field.value);
206}
207
208TEST(AutofillFieldTest, FillSelectControlWithFullStateNames) {
209  const char* const kStates[] = {
210    "Alabama", "California"
211  };
212  AutofillField field(
213      GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
214      base::string16());
215  field.set_heuristic_type(ADDRESS_HOME_STATE);
216
217  AutofillField::FillFormField(field, ASCIIToUTF16("CA"), "en-US", &field);
218  EXPECT_EQ(ASCIIToUTF16("California"), field.value);
219}
220
221TEST(AutofillFieldTest, FillSelectControlWithWithAbbreviateStateNames) {
222  const char* const kStates[] = {
223    "AL", "CA"
224  };
225  AutofillField field(
226      GenerateSelectFieldWithOptions(kStates, arraysize(kStates)),
227      base::string16());
228  field.set_heuristic_type(ADDRESS_HOME_STATE);
229
230  AutofillField::FillFormField(field, ASCIIToUTF16("California"), "en-US",
231                               &field);
232  EXPECT_EQ(ASCIIToUTF16("CA"), field.value);
233}
234
235TEST(AutofillFieldTest, FillSelectControlWithNumericMonth) {
236  const char* const kMonthsNumeric[] = {
237    "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12",
238  };
239  AutofillField field(
240      GenerateSelectFieldWithOptions(kMonthsNumeric, arraysize(kMonthsNumeric)),
241      base::string16());
242  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
243
244  // Try with a leading zero.
245  AutofillField::FillFormField(field, ASCIIToUTF16("03"), "en-US", &field);
246  EXPECT_EQ(ASCIIToUTF16("03"), field.value);
247
248  // Try without a leading zero.
249  AutofillField::FillFormField(field, ASCIIToUTF16("4"), "en-US", &field);
250  EXPECT_EQ(ASCIIToUTF16("04"), field.value);
251
252  // Try a two-digit month.
253  AutofillField::FillFormField(field, ASCIIToUTF16("11"), "en-US", &field);
254  EXPECT_EQ(ASCIIToUTF16("11"), field.value);
255}
256
257TEST(AutofillFieldTest, FillSelectControlWithAbbreviatedMonthName) {
258  const char* const kMonthsAbbreviated[] = {
259    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
260    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
261  };
262  AutofillField field(
263      GenerateSelectFieldWithOptions(
264          kMonthsAbbreviated, arraysize(kMonthsAbbreviated)),
265      base::string16());
266  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
267
268  AutofillField::FillFormField(field, ASCIIToUTF16("04"), "en-US", &field);
269  EXPECT_EQ(ASCIIToUTF16("Apr"), field.value);
270}
271
272TEST(AutofillFieldTest, FillSelectControlWithFullMonthName) {
273  const char* const kMonthsFull[] = {
274    "January", "February", "March", "April", "May", "June",
275    "July", "August", "September", "October", "November", "December",
276  };
277  AutofillField field(
278      GenerateSelectFieldWithOptions(kMonthsFull, arraysize(kMonthsFull)),
279      base::string16());
280  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
281
282  AutofillField::FillFormField(field, ASCIIToUTF16("04"), "en-US", &field);
283  EXPECT_EQ(ASCIIToUTF16("April"), field.value);
284}
285
286TEST(AutofillFieldTest, FillSelectControlWithNumericMonthSansLeadingZero) {
287  const char* const kMonthsNumeric[] = {
288    "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
289  };
290  AutofillField field(
291      GenerateSelectFieldWithOptions(kMonthsNumeric, arraysize(kMonthsNumeric)),
292      base::string16());
293  field.set_heuristic_type(CREDIT_CARD_EXP_MONTH);
294
295  AutofillField::FillFormField(field, ASCIIToUTF16("04"), "en-US", &field);
296  EXPECT_EQ(ASCIIToUTF16("4"), field.value);
297}
298
299TEST(AutofillFieldTest, FillSelectControlWithTwoDigitCreditCardYear) {
300  const char* const kYears[] = {
301    "12", "13", "14", "15", "16", "17", "18", "19"
302  };
303  AutofillField field(GenerateSelectFieldWithOptions(kYears, arraysize(kYears)),
304                      base::string16());
305  field.set_heuristic_type(CREDIT_CARD_EXP_2_DIGIT_YEAR);
306
307  AutofillField::FillFormField(field, ASCIIToUTF16("2017"), "en-US", &field);
308  EXPECT_EQ(ASCIIToUTF16("17"), field.value);
309}
310
311TEST(AutofillFieldTest, FillSelectControlWithCreditCardType) {
312  const char* const kCreditCardTypes[] = {
313    "Visa", "Master Card", "AmEx", "discover"
314  };
315  AutofillField field(
316      GenerateSelectFieldWithOptions(
317          kCreditCardTypes, arraysize(kCreditCardTypes)),
318      base::string16());
319  field.set_heuristic_type(CREDIT_CARD_TYPE);
320
321  // Normal case:
322  AutofillField::FillFormField(field, ASCIIToUTF16("Visa"), "en-US", &field);
323  EXPECT_EQ(ASCIIToUTF16("Visa"), field.value);
324
325  // Filling should be able to handle intervening whitespace:
326  AutofillField::FillFormField(field, ASCIIToUTF16("MasterCard"), "en-US",
327                               &field);
328  EXPECT_EQ(ASCIIToUTF16("Master Card"), field.value);
329
330  // American Express is sometimes abbreviated as AmEx:
331  AutofillField::FillFormField(field, ASCIIToUTF16("American Express"), "en-US",
332                               &field);
333  EXPECT_EQ(ASCIIToUTF16("AmEx"), field.value);
334
335  // Case insensitivity:
336  AutofillField::FillFormField(field, ASCIIToUTF16("Discover"), "en-US",
337                               &field);
338  EXPECT_EQ(ASCIIToUTF16("discover"), field.value);
339}
340
341TEST(AutofillFieldTest, FillMonthControl) {
342  AutofillField field;
343  field.form_control_type = "month";
344
345  // Try a month with two digits.
346  AutofillField::FillFormField(field, ASCIIToUTF16("12/2017"), "en-US", &field);
347  EXPECT_EQ(ASCIIToUTF16("2017-12"), field.value);
348
349  // Try a month with a leading zero.
350  AutofillField::FillFormField(field, ASCIIToUTF16("03/2019"), "en-US", &field);
351  EXPECT_EQ(ASCIIToUTF16("2019-03"), field.value);
352
353  // Try a month without a leading zero.
354  AutofillField::FillFormField(field, ASCIIToUTF16("4/2018"), "en-US", &field);
355  EXPECT_EQ(ASCIIToUTF16("2018-04"), field.value);
356}
357
358TEST(AutofillFieldTest, FillStreetAddressTextArea) {
359  AutofillField field;
360  field.form_control_type = "textarea";
361
362  base::string16 value = ASCIIToUTF16("123 Fake St.\n"
363                                      "Apt. 42");
364  AutofillField::FillFormField(field, value, "en-US", &field);
365  EXPECT_EQ(value, field.value);
366}
367
368TEST(AutofillFieldTest, FillStreetAddressTextField) {
369  AutofillField field;
370  field.form_control_type = "text";
371  field.set_server_type(ADDRESS_HOME_STREET_ADDRESS);
372
373  base::string16 value = ASCIIToUTF16("123 Fake St.\n"
374                                      "Apt. 42");
375  AutofillField::FillFormField(field, value, "en-US", &field);
376  EXPECT_EQ(ASCIIToUTF16("123 Fake St., Apt. 42"), field.value);
377}
378
379}  // namespace
380}  // namespace autofill
381