| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/format_macros.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "components/autofill/core/browser/autofill_field.h" |
| #include "components/autofill/core/browser/autofill_type.h" |
| #include "components/autofill/core/browser/field_types.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace autofill { |
| namespace { |
| |
| // Returns a FormFieldData object corresponding to a <select> field populated |
| // with the given |options|. |
| FormFieldData GenerateSelectFieldWithOptions(const char* const* options, |
| size_t options_size) { |
| std::vector<base::string16> options16(options_size); |
| for (size_t i = 0; i < options_size; ++i) { |
| options16[i] = ASCIIToUTF16(options[i]); |
| } |
| |
| FormFieldData form_field; |
| form_field.form_control_type = "select-one"; |
| form_field.option_values = options16; |
| form_field.option_contents = options16; |
| return form_field; |
| } |
| |
| TEST(AutofillFieldTest, Type) { |
| AutofillField field; |
| ASSERT_EQ(NO_SERVER_DATA, field.server_type()); |
| ASSERT_EQ(UNKNOWN_TYPE, field.heuristic_type()); |
| |
| // |server_type_| is NO_SERVER_DATA, so |heuristic_type_| is returned. |
| EXPECT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType()); |
| |
| // Set the heuristic type and check it. |
| field.set_heuristic_type(NAME_FIRST); |
| EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType()); |
| EXPECT_EQ(NAME, field.Type().group()); |
| |
| // Set the server type and check it. |
| field.set_server_type(ADDRESS_BILLING_LINE1); |
| EXPECT_EQ(ADDRESS_HOME_LINE1, field.Type().GetStorableType()); |
| EXPECT_EQ(ADDRESS_BILLING, field.Type().group()); |
| |
| // Remove the server type to make sure the heuristic type is preserved. |
| field.set_server_type(NO_SERVER_DATA); |
| EXPECT_EQ(NAME_FIRST, field.Type().GetStorableType()); |
| EXPECT_EQ(NAME, field.Type().group()); |
| } |
| |
| TEST(AutofillFieldTest, IsEmpty) { |
| AutofillField field; |
| ASSERT_EQ(base::string16(), field.value); |
| |
| // Field value is empty. |
| EXPECT_TRUE(field.IsEmpty()); |
| |
| // Field value is non-empty. |
| field.value = ASCIIToUTF16("Value"); |
| EXPECT_FALSE(field.IsEmpty()); |
| } |
| |
| TEST(AutofillFieldTest, FieldSignature) { |
| AutofillField field; |
| ASSERT_EQ(base::string16(), field.name); |
| ASSERT_EQ(std::string(), field.form_control_type); |
| |
| // Signature is empty. |
| EXPECT_EQ("2085434232", field.FieldSignature()); |
| |
| // Field name is set. |
| field.name = ASCIIToUTF16("Name"); |
| EXPECT_EQ("1606968241", field.FieldSignature()); |
| |
| // Field form control type is set. |
| field.form_control_type = "text"; |
| EXPECT_EQ("502192749", field.FieldSignature()); |
| |
| // Heuristic type does not affect FieldSignature. |
| field.set_heuristic_type(NAME_FIRST); |
| EXPECT_EQ("502192749", field.FieldSignature()); |
| |
| // Server type does not affect FieldSignature. |
| field.set_server_type(NAME_LAST); |
| EXPECT_EQ("502192749", field.FieldSignature()); |
| } |
| |
| TEST(AutofillFieldTest, IsFieldFillable) { |
| AutofillField field; |
| ASSERT_EQ(UNKNOWN_TYPE, field.Type().GetStorableType()); |
| |
| // Type is unknown. |
| EXPECT_FALSE(field.IsFieldFillable()); |
| |
| // Only heuristic type is set. |
| field.set_heuristic_type(NAME_FIRST); |
| EXPECT_TRUE(field.IsFieldFillable()); |
| |
| // Only server type is set. |
| field.set_heuristic_type(UNKNOWN_TYPE); |
| field.set_server_type(NAME_LAST); |
| EXPECT_TRUE(field.IsFieldFillable()); |
| |
| // Both types set. |
| field.set_heuristic_type(NAME_FIRST); |
| field.set_server_type(NAME_LAST); |
| EXPECT_TRUE(field.IsFieldFillable()); |
| } |
| |
| TEST(AutofillFieldTest, FillPhoneNumber) { |
| AutofillField field; |
| field.SetHtmlType(HTML_TYPE_TEL_LOCAL_PREFIX, HtmlFieldMode()); |
| |
| // Fill with a non-phone number; should fill normally. |
| AutofillField::FillFormField(field, ASCIIToUTF16("Oh hai"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("Oh hai"), field.value); |
| |
| // Fill with a phone number; should fill just the prefix. |
| AutofillField::FillFormField(field, ASCIIToUTF16("5551234"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("555"), field.value); |
| |
| // Now reset the type, and set a max-length instead. |
| field.SetHtmlType(HTML_TYPE_UNKNOWN, HtmlFieldMode()); |
| field.set_heuristic_type(PHONE_HOME_NUMBER); |
| field.max_length = 4; |
| |
| // Fill with a phone-number; should fill just the suffix. |
| AutofillField::FillFormField(field, ASCIIToUTF16("5551234"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("1234"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlByValue) { |
| const char* const kOptions[] = { |
| "Eenie", "Meenie", "Miney", "Mo", |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kOptions, arraysize(kOptions)), |
| base::string16()); |
| |
| // Set semantically empty contents for each option, so that only the values |
| // can be used for matching. |
| for (size_t i = 0; i < field.option_contents.size(); ++i) { |
| field.option_contents[i] = ASCIIToUTF16(base::StringPrintf("%" PRIuS, i)); |
| } |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("Meenie"), "en-US", |
| &field); |
| EXPECT_EQ(ASCIIToUTF16("Meenie"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlByContents) { |
| const char* const kOptions[] = { |
| "Eenie", "Meenie", "Miney", "Mo", |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kOptions, arraysize(kOptions)), |
| base::string16()); |
| |
| // Set semantically empty values for each option, so that only the contents |
| // can be used for matching. |
| for (size_t i = 0; i < field.option_values.size(); ++i) { |
| field.option_values[i] = ASCIIToUTF16(base::StringPrintf("%" PRIuS, i)); |
| } |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("Miney"), "en-US", |
| &field); |
| EXPECT_EQ(ASCIIToUTF16("2"), field.value); // Corresponds to "Miney". |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithFullCountryNames) { |
| const char* const kCountries[] = { |
| "Albania", "Canada" |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kCountries, arraysize(kCountries)), |
| base::string16()); |
| field.set_heuristic_type(ADDRESS_HOME_COUNTRY); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("CA"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("Canada"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithAbbreviatedCountryNames) { |
| const char* const kCountries[] = { |
| "AL", "CA" |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kCountries, arraysize(kCountries)), |
| base::string16()); |
| field.set_heuristic_type(ADDRESS_HOME_COUNTRY); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("Canada"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("CA"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithFullStateNames) { |
| const char* const kStates[] = { |
| "Alabama", "California" |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kStates, arraysize(kStates)), |
| base::string16()); |
| field.set_heuristic_type(ADDRESS_HOME_STATE); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("CA"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("California"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithWithAbbreviateStateNames) { |
| const char* const kStates[] = { |
| "AL", "CA" |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kStates, arraysize(kStates)), |
| base::string16()); |
| field.set_heuristic_type(ADDRESS_HOME_STATE); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("California"), "en-US", |
| &field); |
| EXPECT_EQ(ASCIIToUTF16("CA"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithNumericMonth) { |
| const char* const kMonthsNumeric[] = { |
| "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kMonthsNumeric, arraysize(kMonthsNumeric)), |
| base::string16()); |
| field.set_heuristic_type(CREDIT_CARD_EXP_MONTH); |
| |
| // Try with a leading zero. |
| AutofillField::FillFormField(field, ASCIIToUTF16("03"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("03"), field.value); |
| |
| // Try without a leading zero. |
| AutofillField::FillFormField(field, ASCIIToUTF16("4"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("04"), field.value); |
| |
| // Try a two-digit month. |
| AutofillField::FillFormField(field, ASCIIToUTF16("11"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("11"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithAbbreviatedMonthName) { |
| const char* const kMonthsAbbreviated[] = { |
| "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
| "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions( |
| kMonthsAbbreviated, arraysize(kMonthsAbbreviated)), |
| base::string16()); |
| field.set_heuristic_type(CREDIT_CARD_EXP_MONTH); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("04"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("Apr"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithFullMonthName) { |
| const char* const kMonthsFull[] = { |
| "January", "February", "March", "April", "May", "June", |
| "July", "August", "September", "October", "November", "December", |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kMonthsFull, arraysize(kMonthsFull)), |
| base::string16()); |
| field.set_heuristic_type(CREDIT_CARD_EXP_MONTH); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("04"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("April"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithNumericMonthSansLeadingZero) { |
| const char* const kMonthsNumeric[] = { |
| "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions(kMonthsNumeric, arraysize(kMonthsNumeric)), |
| base::string16()); |
| field.set_heuristic_type(CREDIT_CARD_EXP_MONTH); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("04"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("4"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithTwoDigitCreditCardYear) { |
| const char* const kYears[] = { |
| "12", "13", "14", "15", "16", "17", "18", "19" |
| }; |
| AutofillField field(GenerateSelectFieldWithOptions(kYears, arraysize(kYears)), |
| base::string16()); |
| field.set_heuristic_type(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| |
| AutofillField::FillFormField(field, ASCIIToUTF16("2017"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("17"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillSelectControlWithCreditCardType) { |
| const char* const kCreditCardTypes[] = { |
| "Visa", "Master Card", "AmEx", "discover" |
| }; |
| AutofillField field( |
| GenerateSelectFieldWithOptions( |
| kCreditCardTypes, arraysize(kCreditCardTypes)), |
| base::string16()); |
| field.set_heuristic_type(CREDIT_CARD_TYPE); |
| |
| // Normal case: |
| AutofillField::FillFormField(field, ASCIIToUTF16("Visa"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("Visa"), field.value); |
| |
| // Filling should be able to handle intervening whitespace: |
| AutofillField::FillFormField(field, ASCIIToUTF16("MasterCard"), "en-US", |
| &field); |
| EXPECT_EQ(ASCIIToUTF16("Master Card"), field.value); |
| |
| // American Express is sometimes abbreviated as AmEx: |
| AutofillField::FillFormField(field, ASCIIToUTF16("American Express"), "en-US", |
| &field); |
| EXPECT_EQ(ASCIIToUTF16("AmEx"), field.value); |
| |
| // Case insensitivity: |
| AutofillField::FillFormField(field, ASCIIToUTF16("Discover"), "en-US", |
| &field); |
| EXPECT_EQ(ASCIIToUTF16("discover"), field.value); |
| } |
| |
| TEST(AutofillFieldTest, FillMonthControl) { |
| AutofillField field; |
| field.form_control_type = "month"; |
| |
| // Try a month with two digits. |
| AutofillField::FillFormField(field, ASCIIToUTF16("12/2017"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("2017-12"), field.value); |
| |
| // Try a month with a leading zero. |
| AutofillField::FillFormField(field, ASCIIToUTF16("03/2019"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("2019-03"), field.value); |
| |
| // Try a month without a leading zero. |
| AutofillField::FillFormField(field, ASCIIToUTF16("4/2018"), "en-US", &field); |
| EXPECT_EQ(ASCIIToUTF16("2018-04"), field.value); |
| } |
| |
| } // namespace |
| } // namespace autofill |