summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorisherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-23 07:08:26 +0000
committerisherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-23 07:08:26 +0000
commite001d11bebcb4739282c4bf365fe53a5fb847424 (patch)
treeb660f5fc5c79447c0fadbb145ef07147e79965b3 /components
parentd6d06a3517f9549488826a9f5faac5cdb678e992 (diff)
downloadchromium_src-e001d11bebcb4739282c4bf365fe53a5fb847424.zip
chromium_src-e001d11bebcb4739282c4bf365fe53a5fb847424.tar.gz
chromium_src-e001d11bebcb4739282c4bf365fe53a5fb847424.tar.bz2
[Autofill] Refactor FillFormField to be shared between local Autofill and Wallet.
BUG=263705 TEST=unit_tests R=estade@chromium.org Review URL: https://codereview.chromium.org/26320010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@230359 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
-rw-r--r--components/autofill/core/browser/autofill_data_model.cc170
-rw-r--r--components/autofill/core/browser/autofill_data_model.h30
-rw-r--r--components/autofill/core/browser/autofill_data_model_unittest.cc4
-rw-r--r--components/autofill/core/browser/autofill_field.cc293
-rw-r--r--components/autofill/core/browser/autofill_field.h8
-rw-r--r--components/autofill/core/browser/autofill_field_unittest.cc254
-rw-r--r--components/autofill/core/browser/autofill_manager.cc14
-rw-r--r--components/autofill/core/browser/autofill_profile.cc90
-rw-r--r--components/autofill/core/browser/autofill_profile.h19
-rw-r--r--components/autofill/core/browser/autofill_profile_unittest.cc127
-rw-r--r--components/autofill/core/browser/credit_card.cc25
-rw-r--r--components/autofill/core/browser/credit_card.h6
-rw-r--r--components/autofill/core/browser/credit_card_field.cc7
-rw-r--r--components/autofill/core/browser/credit_card_field.h10
-rw-r--r--components/autofill/core/browser/credit_card_field_unittest.cc92
-rw-r--r--components/autofill/core/browser/credit_card_unittest.cc166
-rw-r--r--components/autofill/core/browser/personal_data_manager.cc2
17 files changed, 655 insertions, 662 deletions
diff --git a/components/autofill/core/browser/autofill_data_model.cc b/components/autofill/core/browser/autofill_data_model.cc
index 2d1edcf..48b818d 100644
--- a/components/autofill/core/browser/autofill_data_model.cc
+++ b/components/autofill/core/browser/autofill_data_model.cc
@@ -4,119 +4,10 @@
#include "components/autofill/core/browser/autofill_data_model.h"
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "components/autofill/core/browser/autofill_country.h"
-#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/browser/autofill_type.h"
-#include "components/autofill/core/browser/state_names.h"
-#include "components/autofill/core/browser/validation.h"
-#include "components/autofill/core/common/form_field_data.h"
-#include "grit/component_strings.h"
-#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
namespace autofill {
-namespace {
-
-const char* const kMonthsAbbreviated[] = {
- NULL, // Padding so index 1 = month 1 = January.
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
-};
-
-const char* const kMonthsFull[] = {
- NULL, // Padding so index 1 = month 1 = January.
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December",
-};
-
-const char* const kMonthsNumeric[] = {
- NULL, // Padding so index 1 = month 1 = January.
- "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
-};
-
-// Returns true if the value was successfully set, meaning |value| was found in
-// the list of select options in |field|.
-bool SetSelectControlValue(const base::string16& value,
- FormFieldData* field) {
- base::string16 value_lowercase = StringToLowerASCII(value);
-
- DCHECK_EQ(field->option_values.size(), field->option_contents.size());
- for (size_t i = 0; i < field->option_values.size(); ++i) {
- if (value_lowercase == StringToLowerASCII(field->option_values[i]) ||
- value_lowercase == StringToLowerASCII(field->option_contents[i])) {
- field->value = field->option_values[i];
- return true;
- }
- }
-
- return false;
-}
-
-bool FillStateSelectControl(const base::string16& value,
- FormFieldData* field) {
- base::string16 full, abbreviation;
- state_names::GetNameAndAbbreviation(value, &full, &abbreviation);
-
- // Try the abbreviation first.
- if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field))
- return true;
-
- return !full.empty() && SetSelectControlValue(full, field);
-}
-
-bool FillExpirationMonthSelectControl(const base::string16& value,
- FormFieldData* field) {
- int index = 0;
- if (!base::StringToInt(value, &index) ||
- index <= 0 ||
- static_cast<size_t>(index) >= arraysize(kMonthsFull))
- return false;
-
- bool filled =
- SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) ||
- SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) ||
- SetSelectControlValue(ASCIIToUTF16(kMonthsNumeric[index]), field);
- return filled;
-}
-
-// Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the
-// given |field|.
-bool FillCreditCardTypeSelectControl(const base::string16& value,
- FormFieldData* field) {
- // Try stripping off spaces.
- base::string16 value_stripped;
- RemoveChars(StringToLowerASCII(value), kWhitespaceUTF16, &value_stripped);
-
- for (size_t i = 0; i < field->option_values.size(); ++i) {
- base::string16 option_value_lowercase;
- RemoveChars(StringToLowerASCII(field->option_values[i]), kWhitespaceUTF16,
- &option_value_lowercase);
- base::string16 option_contents_lowercase;
- RemoveChars(StringToLowerASCII(field->option_contents[i]), kWhitespaceUTF16,
- &option_contents_lowercase);
-
- // Perform a case-insensitive comparison; but fill the form with the
- // original text, not the lowercased version.
- if (value_stripped == option_value_lowercase ||
- value_stripped == option_contents_lowercase) {
- field->value = field->option_values[i];
- return true;
- }
- }
-
- // For American Express, also try filling as "AmEx".
- if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX))
- return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field);
-
- return false;
-}
-
-} // namespace
AutofillDataModel::AutofillDataModel(const std::string& guid,
const std::string& origin)
@@ -124,62 +15,11 @@ AutofillDataModel::AutofillDataModel(const std::string& guid,
origin_(origin) {}
AutofillDataModel::~AutofillDataModel() {}
-void AutofillDataModel::FillSelectControl(const AutofillType& type,
- const std::string& app_locale,
- FormFieldData* field) const {
- DCHECK(field);
- DCHECK_EQ("select-one", field->form_control_type);
- DCHECK_EQ(field->option_values.size(), field->option_contents.size());
-
- base::string16 field_text = GetInfo(type, app_locale);
- base::string16 field_text_lower = StringToLowerASCII(field_text);
- if (field_text.empty())
- return;
-
- base::string16 value;
- for (size_t i = 0; i < field->option_values.size(); ++i) {
- if (field_text == field->option_values[i] ||
- field_text == field->option_contents[i]) {
- // An exact match, use it.
- value = field->option_values[i];
- break;
- }
-
- if (field_text_lower == StringToLowerASCII(field->option_values[i]) ||
- field_text_lower == StringToLowerASCII(field->option_contents[i])) {
- // A match, but not in the same case. Save it in case an exact match is
- // not found.
- value = field->option_values[i];
- }
- }
-
- if (!value.empty()) {
- field->value = value;
- return;
- }
-
- ServerFieldType storable_type = type.GetStorableType();
- if (storable_type == ADDRESS_HOME_STATE) {
- FillStateSelectControl(field_text, field);
- } else if (storable_type == ADDRESS_HOME_COUNTRY) {
- FillCountrySelectControl(app_locale, field);
- } else if (storable_type == CREDIT_CARD_EXP_MONTH) {
- FillExpirationMonthSelectControl(field_text, field);
- } else if (storable_type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
- // Attempt to fill the year as a 2-digit year. This compensates for the
- // fact that our heuristics do not always correctly detect when a website
- // requests a 2-digit rather than a 4-digit year.
- FillSelectControl(AutofillType(CREDIT_CARD_EXP_2_DIGIT_YEAR), app_locale,
- field);
- } else if (storable_type == CREDIT_CARD_TYPE) {
- FillCreditCardTypeSelectControl(field_text, field);
- }
-}
-
-bool AutofillDataModel::FillCountrySelectControl(
- const std::string& app_locale,
- FormFieldData* field_data) const {
- return false;
+base::string16 AutofillDataModel::GetInfoForVariant(
+ const AutofillType& type,
+ size_t variant,
+ const std::string& app_locale) const {
+ return GetInfo(type, app_locale);
}
bool AutofillDataModel::IsVerified() const {
diff --git a/components/autofill/core/browser/autofill_data_model.h b/components/autofill/core/browser/autofill_data_model.h
index 0f2cd33..04499f3 100644
--- a/components/autofill/core/browser/autofill_data_model.h
+++ b/components/autofill/core/browser/autofill_data_model.h
@@ -7,13 +7,12 @@
#include <string>
-#include "components/autofill/core/browser/field_types.h"
+#include "base/strings/string16.h"
#include "components/autofill/core/browser/form_group.h"
namespace autofill {
-class AutofillField;
-struct FormFieldData;
+class AutofillType;
// This class is an interface for the primary data models that back Autofill.
// The information in objects of this class is managed by the
@@ -23,18 +22,13 @@ class AutofillDataModel : public FormGroup {
AutofillDataModel(const std::string& guid, const std::string& origin);
virtual ~AutofillDataModel();
- // Set |field_data|'s value based on |field| and contents of |this| (using
- // data variant |variant|).
- virtual void FillFormField(const AutofillField& field,
- size_t variant,
- const std::string& app_locale,
- FormFieldData* field_data) const = 0;
-
- // Fills in select control with data matching |type| from |this|.
- // Public for testing purposes.
- void FillSelectControl(const AutofillType& type,
- const std::string& app_locale,
- FormFieldData* field_data) const;
+ // Returns the string that should be auto-filled into a text field given the
+ // |type| of that field, localized to the given |app_locale| if appropriate.
+ // If the data model supports multiple values for the given |type|, returns
+ // the |variant|th value for the |type|.
+ virtual base::string16 GetInfoForVariant(const AutofillType& type,
+ size_t variant,
+ const std::string& app_locale) const;
// Returns true if the data in this model was entered directly by the user,
// rather than automatically aggregated.
@@ -46,12 +40,6 @@ class AutofillDataModel : public FormGroup {
std::string origin() const { return origin_; }
void set_origin(const std::string& origin) { origin_ = origin; }
- protected:
- // Fills in a select control for a country from data in |this|. Returns true
- // for success.
- virtual bool FillCountrySelectControl(const std::string& app_locale,
- FormFieldData* field_data) const;
-
private:
// A globally unique ID for this object.
std::string guid_;
diff --git a/components/autofill/core/browser/autofill_data_model_unittest.cc b/components/autofill/core/browser/autofill_data_model_unittest.cc
index 8004df4..8540ecf 100644
--- a/components/autofill/core/browser/autofill_data_model_unittest.cc
+++ b/components/autofill/core/browser/autofill_data_model_unittest.cc
@@ -26,10 +26,6 @@ class TestAutofillDataModel : public AutofillDataModel {
const base::string16& value) OVERRIDE {}
virtual void GetSupportedTypes(
ServerFieldTypeSet* supported_types) const OVERRIDE {}
- virtual void FillFormField(const AutofillField& field,
- size_t variant,
- const std::string& app_locale,
- FormFieldData* field_data) const OVERRIDE {}
DISALLOW_COPY_AND_ASSIGN(TestAutofillDataModel);
};
diff --git a/components/autofill/core/browser/autofill_field.cc b/components/autofill/core/browser/autofill_field.cc
index 4bcb118..56f7204 100644
--- a/components/autofill/core/browser/autofill_field.cc
+++ b/components/autofill/core/browser/autofill_field.cc
@@ -7,12 +7,278 @@
#include "base/logging.h"
#include "base/sha1.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_type.h"
+#include "components/autofill/core/browser/phone_number.h"
+#include "components/autofill/core/browser/state_names.h"
+#include "grit/component_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+using base::StringToInt;
+
+namespace autofill {
namespace {
-static std::string Hash32Bit(const std::string& str) {
+const char* const kMonthsAbbreviated[] = {
+ NULL, // Padding so index 1 = month 1 = January.
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+};
+
+const char* const kMonthsFull[] = {
+ NULL, // Padding so index 1 = month 1 = January.
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December",
+};
+
+// Returns true if the value was successfully set, meaning |value| was found in
+// the list of select options in |field|.
+bool SetSelectControlValue(const base::string16& value,
+ FormFieldData* field) {
+ base::string16 value_lowercase = StringToLowerASCII(value);
+
+ DCHECK_EQ(field->option_values.size(), field->option_contents.size());
+ base::string16 best_match;
+ for (size_t i = 0; i < field->option_values.size(); ++i) {
+ if (value == field->option_values[i] ||
+ value == field->option_contents[i]) {
+ // An exact match, use it.
+ best_match = field->option_values[i];
+ break;
+ }
+
+ if (value_lowercase == StringToLowerASCII(field->option_values[i]) ||
+ value_lowercase == StringToLowerASCII(field->option_contents[i])) {
+ // A match, but not in the same case. Save it in case an exact match is
+ // not found.
+ best_match = field->option_values[i];
+ }
+ }
+
+ if (best_match.empty())
+ return false;
+
+ field->value = best_match;
+ return true;
+}
+
+
+// Try to fill a numeric |value| into the given |field|.
+bool FillNumericSelectControl(int value,
+ FormFieldData* field) {
+ DCHECK_EQ(field->option_values.size(), field->option_contents.size());
+ for (size_t i = 0; i < field->option_values.size(); ++i) {
+ int option;
+ if ((StringToInt(field->option_values[i], &option) && option == value) ||
+ (StringToInt(field->option_contents[i], &option) && option == value)) {
+ field->value = field->option_values[i];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool FillStateSelectControl(const base::string16& value,
+ FormFieldData* field) {
+ base::string16 full, abbreviation;
+ state_names::GetNameAndAbbreviation(value, &full, &abbreviation);
+
+ // Try the abbreviation first.
+ if (!abbreviation.empty() && SetSelectControlValue(abbreviation, field))
+ return true;
+
+ return !full.empty() && SetSelectControlValue(full, field);
+}
+
+bool FillCountrySelectControl(const base::string16& value,
+ const std::string& app_locale,
+ FormFieldData* field_data) {
+ std::string country_code = AutofillCountry::GetCountryCode(value, app_locale);
+ if (country_code.empty())
+ return false;
+
+ DCHECK_EQ(field_data->option_values.size(),
+ field_data->option_contents.size());
+ for (size_t i = 0; i < field_data->option_values.size(); ++i) {
+ // Canonicalize each <option> value to a country code, and compare to the
+ // target country code.
+ base::string16 value = field_data->option_values[i];
+ base::string16 contents = field_data->option_contents[i];
+ if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
+ country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
+ field_data->value = value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool FillExpirationMonthSelectControl(const base::string16& value,
+ FormFieldData* field) {
+ int index = 0;
+ if (!StringToInt(value, &index) ||
+ index <= 0 ||
+ static_cast<size_t>(index) >= arraysize(kMonthsFull))
+ return false;
+
+ bool filled =
+ SetSelectControlValue(ASCIIToUTF16(kMonthsAbbreviated[index]), field) ||
+ SetSelectControlValue(ASCIIToUTF16(kMonthsFull[index]), field) ||
+ FillNumericSelectControl(index, field);
+ return filled;
+}
+
+// Returns true if the last two digits in |year| match those in |str|.
+bool LastTwoDigitsMatch(const base::string16& year,
+ const base::string16& str) {
+ int year_int;
+ int str_int;
+ if (!StringToInt(year, &year_int) || !StringToInt(str, &str_int))
+ return false;
+
+ return (year_int % 100) == (str_int % 100);
+}
+
+// Try to fill a year |value| into the given |field| by comparing the last two
+// digits of the year to the field's options.
+bool FillYearSelectControl(const base::string16& value,
+ FormFieldData* field) {
+ if (value.size() != 2U && value.size() != 4U)
+ return false;
+
+ DCHECK_EQ(field->option_values.size(), field->option_contents.size());
+ for (size_t i = 0; i < field->option_values.size(); ++i) {
+ if (LastTwoDigitsMatch(value, field->option_values[i]) ||
+ LastTwoDigitsMatch(value, field->option_contents[i])) {
+ field->value = field->option_values[i];
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Try to fill a credit card type |value| (Visa, MasterCard, etc.) into the
+// given |field|.
+bool FillCreditCardTypeSelectControl(const base::string16& value,
+ FormFieldData* field) {
+ // Try stripping off spaces.
+ base::string16 value_stripped;
+ RemoveChars(StringToLowerASCII(value), kWhitespaceUTF16, &value_stripped);
+
+ for (size_t i = 0; i < field->option_values.size(); ++i) {
+ base::string16 option_value_lowercase;
+ RemoveChars(StringToLowerASCII(field->option_values[i]), kWhitespaceUTF16,
+ &option_value_lowercase);
+ base::string16 option_contents_lowercase;
+ RemoveChars(StringToLowerASCII(field->option_contents[i]), kWhitespaceUTF16,
+ &option_contents_lowercase);
+
+ // Perform a case-insensitive comparison; but fill the form with the
+ // original text, not the lowercased version.
+ if (value_stripped == option_value_lowercase ||
+ value_stripped == option_contents_lowercase) {
+ field->value = field->option_values[i];
+ return true;
+ }
+ }
+
+ // For American Express, also try filling as "AmEx".
+ if (value == l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX))
+ return FillCreditCardTypeSelectControl(ASCIIToUTF16("AmEx"), field);
+
+ return false;
+}
+
+// Set |field_data|'s value to |number|, or possibly an appropriate substring of
+// |number|. The |field| specifies the type of the phone and whether this is a
+// phone prefix or suffix.
+void FillPhoneNumberField(const AutofillField& field,
+ const base::string16& number,
+ FormFieldData* field_data) {
+ // Check to see if the size field matches the "prefix" or "suffix" sizes and
+ // fill accordingly.
+ base::string16 value = number;
+ if (number.length() ==
+ PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
+ if (field.phone_part() == AutofillField::PHONE_PREFIX ||
+ field_data->max_length == PhoneNumber::kPrefixLength) {
+ value = number.substr(PhoneNumber::kPrefixOffset,
+ PhoneNumber::kPrefixLength);
+ } else if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
+ field_data->max_length == PhoneNumber::kSuffixLength) {
+ value = number.substr(PhoneNumber::kSuffixOffset,
+ PhoneNumber::kSuffixLength);
+ }
+ }
+
+ field_data->value = value;
+}
+
+// Fills in the select control |field| with |value|. If an exact match is not
+// found, falls back to alternate filling strategies based on the |type|.
+void FillSelectControl(const AutofillType& type,
+ const base::string16& value,
+ const std::string& app_locale,
+ FormFieldData* field) {
+ DCHECK_EQ("select-one", field->form_control_type);
+
+ // Guard against corrupted values passed over IPC.
+ if (field->option_values.size() != field->option_contents.size())
+ return;
+
+ if (value.empty())
+ return;
+
+ // First, search for exact matches.
+ if (SetSelectControlValue(value, field))
+ return;
+
+ // If that fails, try specific fallbacks based on the field type.
+ ServerFieldType storable_type = type.GetStorableType();
+ if (storable_type == ADDRESS_HOME_STATE) {
+ FillStateSelectControl(value, field);
+ } else if (storable_type == ADDRESS_HOME_COUNTRY) {
+ FillCountrySelectControl(value, app_locale, field);
+ } else if (storable_type == CREDIT_CARD_EXP_MONTH) {
+ FillExpirationMonthSelectControl(value, field);
+ } else if (storable_type == CREDIT_CARD_EXP_2_DIGIT_YEAR ||
+ storable_type == CREDIT_CARD_EXP_4_DIGIT_YEAR) {
+ FillYearSelectControl(value, field);
+ } else if (storable_type == CREDIT_CARD_TYPE) {
+ FillCreditCardTypeSelectControl(value, field);
+ }
+}
+
+// Fills in the month control |field| with |value|. |value| should be a date
+// formatted as MM/YYYY. If it isn't, filling will fail.
+bool FillMonthControl(const base::string16& value, FormFieldData* field) {
+ // Autofill formats a combined date as month/year.
+ std::vector<base::string16> pieces;
+ base::SplitString(value, char16('/'), &pieces);
+ if (pieces.size() != 2)
+ return false;
+
+ // HTML5 input="month" is formatted as year-month.
+ base::string16 month = pieces[0];
+ base::string16 year = pieces[1];
+ if ((month.size() != 1 && month.size() != 2) || year.size() != 4)
+ return false;
+
+ // HTML5 input="month" expects zero-padded months.
+ if (month.size() == 1)
+ month = ASCIIToUTF16("0") + month;
+
+ field->value = year + ASCIIToUTF16("-") + month;
+ return true;
+}
+
+std::string Hash32Bit(const std::string& str) {
std::string hash_bin = base::SHA1HashString(str);
DCHECK_EQ(20U, hash_bin.length());
@@ -26,8 +292,6 @@ static std::string Hash32Bit(const std::string& str) {
} // namespace
-namespace autofill {
-
AutofillField::AutofillField()
: server_type_(NO_SERVER_DATA),
heuristic_type_(UNKNOWN_TYPE),
@@ -74,9 +338,11 @@ void AutofillField::SetHtmlType(HtmlFieldType type, HtmlFieldMode mode) {
html_mode_ = mode;
if (type == HTML_TYPE_TEL_LOCAL_PREFIX)
- phone_part_ = AutofillField::PHONE_PREFIX;
+ phone_part_ = PHONE_PREFIX;
else if (type == HTML_TYPE_TEL_LOCAL_SUFFIX)
- phone_part_ = AutofillField::PHONE_SUFFIX;
+ phone_part_ = PHONE_SUFFIX;
+ else
+ phone_part_ = IGNORED;
}
AutofillType AutofillField::Type() const {
@@ -103,4 +369,21 @@ bool AutofillField::IsFieldFillable() const {
return !Type().IsUnknown();
}
+// static
+void AutofillField::FillFormField(const AutofillField& field,
+ const base::string16& value,
+ const std::string& app_locale,
+ FormFieldData* field_data) {
+ AutofillType type = field.Type();
+
+ if (type.GetStorableType() == PHONE_HOME_NUMBER)
+ FillPhoneNumberField(field, value, field_data);
+ else if (field_data->form_control_type == "select-one")
+ FillSelectControl(type, value, app_locale, field_data);
+ else if (field_data->form_control_type == "month")
+ FillMonthControl(value, field_data);
+ else
+ field_data->value = value;
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/autofill_field.h b/components/autofill/core/browser/autofill_field.h
index 6f57484..38aeaea 100644
--- a/components/autofill/core/browser/autofill_field.h
+++ b/components/autofill/core/browser/autofill_field.h
@@ -65,6 +65,14 @@ class AutofillField : public FormFieldData {
void set_default_value(const std::string& value) { default_value_ = value; }
const std::string& default_value() const { return default_value_; }
+ // Set |field_data|'s value to |value|. Uses |field| and |app_locale| as
+ // hints when filling exceptional cases like phone number values and <select>
+ // fields.
+ static void FillFormField(const AutofillField& field,
+ const base::string16& value,
+ const std::string& app_locale,
+ FormFieldData* field_data);
+
private:
// The unique name of this field, generated by Autofill.
base::string16 unique_name_;
diff --git a/components/autofill/core/browser/autofill_field_unittest.cc b/components/autofill/core/browser/autofill_field_unittest.cc
index 3c26302..b7daedae 100644
--- a/components/autofill/core/browser/autofill_field_unittest.cc
+++ b/components/autofill/core/browser/autofill_field_unittest.cc
@@ -2,7 +2,9 @@
// 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"
@@ -12,6 +14,22 @@
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());
@@ -95,5 +113,241 @@ TEST(AutofillFieldTest, IsFieldFillable) {
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
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index d6d55df..4c76295 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -483,8 +483,10 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
for (std::vector<FormFieldData>::iterator iter = result.fields.begin();
iter != result.fields.end(); ++iter) {
if ((*iter) == field) {
- data_model->FillFormField(
- *autofill_field, variant, app_locale_, &(*iter));
+ base::string16 value = data_model->GetInfoForVariant(
+ autofill_field->Type(), variant, app_locale_);
+ AutofillField::FillFormField(*autofill_field, value, app_locale_,
+ &(*iter));
// Mark the cached field as autofilled, so that we can detect when a
// user edits an autofilled field (for metrics).
autofill_field->is_autofilled = true;
@@ -518,10 +520,10 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
field_group_type == initiating_group_type) {
use_variant = variant;
}
- data_model->FillFormField(*cached_field,
- use_variant,
- app_locale_,
- &result.fields[i]);
+ base::string16 value = data_model->GetInfoForVariant(
+ cached_field->Type(), use_variant, app_locale_);
+ AutofillField::FillFormField(*cached_field, value, app_locale_,
+ &result.fields[i]);
// Mark the cached field as autofilled, so that we can detect when a user
// edits an autofilled field (for metrics).
form_structure->field(i)->is_autofilled = true;
diff --git a/components/autofill/core/browser/autofill_profile.cc b/components/autofill/core/browser/autofill_profile.cc
index 735549f..53a056f 100644
--- a/components/autofill/core/browser/autofill_profile.cc
+++ b/components/autofill/core/browser/autofill_profile.cc
@@ -309,6 +309,22 @@ bool AutofillProfile::SetInfo(const AutofillType& type,
form_group->SetInfo(type, CollapseWhitespace(value, false), app_locale);
}
+base::string16 AutofillProfile::GetInfoForVariant(
+ const AutofillType& type,
+ size_t variant,
+ const std::string& app_locale) const {
+ std::vector<base::string16> values;
+ GetMultiInfo(type, app_locale, &values);
+
+ if (variant >= values.size()) {
+ // If the variant is unavailable, bail. This case is reachable, for
+ // example if Sync updates a profile during the filling process.
+ return base::string16();
+ }
+
+ return values[variant];
+}
+
void AutofillProfile::SetRawMultiInfo(
ServerFieldType type,
const std::vector<base::string16>& values) {
@@ -352,58 +368,6 @@ void AutofillProfile::GetMultiInfo(const AutofillType& type,
GetMultiInfoImpl(type, app_locale, values);
}
-void AutofillProfile::FillFormField(const AutofillField& field,
- size_t variant,
- const std::string& app_locale,
- FormFieldData* field_data) const {
- AutofillType type = field.Type();
- DCHECK_NE(CREDIT_CARD, type.group());
- DCHECK(field_data);
-
- if (type.GetStorableType() == PHONE_HOME_NUMBER) {
- FillPhoneNumberField(field, variant, app_locale, field_data);
- } else if (field_data->form_control_type == "select-one") {
- FillSelectControl(type, app_locale, field_data);
- } else {
- std::vector<base::string16> values;
- GetMultiInfo(type, app_locale, &values);
- if (variant >= values.size()) {
- // If the variant is unavailable, bail. This case is reachable, for
- // example if Sync updates a profile during the filling process.
- return;
- }
-
- field_data->value = values[variant];
- }
-}
-
-void AutofillProfile::FillPhoneNumberField(const AutofillField& field,
- size_t variant,
- const std::string& app_locale,
- FormFieldData* field_data) const {
- std::vector<base::string16> values;
- GetMultiInfo(field.Type(), app_locale, &values);
- DCHECK(variant < values.size());
-
- // If we are filling a phone number, check to see if the size field
- // matches the "prefix" or "suffix" sizes and fill accordingly.
- base::string16 number = values[variant];
- if (number.length() ==
- PhoneNumber::kPrefixLength + PhoneNumber::kSuffixLength) {
- if (field.phone_part() == AutofillField::PHONE_PREFIX ||
- field_data->max_length == PhoneNumber::kPrefixLength) {
- number = number.substr(PhoneNumber::kPrefixOffset,
- PhoneNumber::kPrefixLength);
- } else if (field.phone_part() == AutofillField::PHONE_SUFFIX ||
- field_data->max_length == PhoneNumber::kSuffixLength) {
- number = number.substr(PhoneNumber::kSuffixOffset,
- PhoneNumber::kSuffixLength);
- }
- }
-
- field_data->value = number;
-}
-
const base::string16 AutofillProfile::Label() const {
return label_;
}
@@ -661,28 +625,6 @@ void AutofillProfile::GetSupportedTypes(
(*it)->GetSupportedTypes(supported_types);
}
-bool AutofillProfile::FillCountrySelectControl(
- const std::string& app_locale,
- FormFieldData* field_data) const {
- std::string country_code = UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY));
-
- DCHECK_EQ(field_data->option_values.size(),
- field_data->option_contents.size());
- for (size_t i = 0; i < field_data->option_values.size(); ++i) {
- // Canonicalize each <option> value to a country code, and compare to the
- // target country code.
- base::string16 value = field_data->option_values[i];
- base::string16 contents = field_data->option_contents[i];
- if (country_code == AutofillCountry::GetCountryCode(value, app_locale) ||
- country_code == AutofillCountry::GetCountryCode(contents, app_locale)) {
- field_data->value = value;
- return true;
- }
- }
-
- return false;
-}
-
void AutofillProfile::GetMultiInfoImpl(
const AutofillType& type,
const std::string& app_locale,
diff --git a/components/autofill/core/browser/autofill_profile.h b/components/autofill/core/browser/autofill_profile.h
index 5a3f65c..0611fd3 100644
--- a/components/autofill/core/browser/autofill_profile.h
+++ b/components/autofill/core/browser/autofill_profile.h
@@ -54,10 +54,10 @@ class AutofillProfile : public AutofillDataModel {
const std::string& app_locale) OVERRIDE;
// AutofillDataModel:
- virtual void FillFormField(const AutofillField& field,
- size_t variant,
- const std::string& app_locale,
- FormFieldData* field_data) const OVERRIDE;
+ virtual base::string16 GetInfoForVariant(
+ const AutofillType& type,
+ size_t variant,
+ const std::string& app_locale) const OVERRIDE;
// Multi-value equivalents to |GetInfo| and |SetInfo|.
void SetRawMultiInfo(ServerFieldType type,
@@ -68,15 +68,6 @@ class AutofillProfile : public AutofillDataModel {
const std::string& app_locale,
std::vector<base::string16>* values) const;
- // Set |field_data|'s value for phone number based on contents of |this|.
- // The |field| specifies the type of the phone and whether this is a
- // phone prefix or suffix. The |variant| parameter specifies which value in a
- // multi-valued profile.
- void FillPhoneNumberField(const AutofillField& field,
- size_t variant,
- const std::string& app_locale,
- FormFieldData* field_data) const;
-
// The user-visible label of the profile, generated in relation to other
// profiles. Shows at least 2 fields that differentiate profile from other
// profiles. See AdjustInferredLabels() further down for more description.
@@ -153,8 +144,6 @@ class AutofillProfile : public AutofillDataModel {
typedef std::vector<const FormGroup*> FormGroupList;
// FormGroup:
- virtual bool FillCountrySelectControl(const std::string& app_locale,
- FormFieldData* field) const OVERRIDE;
virtual void GetSupportedTypes(
ServerFieldTypeSet* supported_types) const OVERRIDE;
diff --git a/components/autofill/core/browser/autofill_profile_unittest.cc b/components/autofill/core/browser/autofill_profile_unittest.cc
index f67c536..e652fdf 100644
--- a/components/autofill/core/browser/autofill_profile_unittest.cc
+++ b/components/autofill/core/browser/autofill_profile_unittest.cc
@@ -8,7 +8,6 @@
#include "base/memory/scoped_vector.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
-#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_common_test.h"
#include "components/autofill/core/browser/autofill_profile.h"
@@ -772,132 +771,6 @@ TEST(AutofillProfileTest, MultiValuePhone) {
EXPECT_EQ(base::string16(), p.GetRawInfo(PHONE_HOME_WHOLE_NUMBER));
}
-TEST(AutofillProfileTest, AddressCountryFull) {
- const char* const kCountries[] = {
- "Albania", "Canada"
- };
- std::vector<base::string16> options(arraysize(kCountries));
- for (size_t i = 0; i < arraysize(kCountries); ++i) {
- options[i] = ASCIIToUTF16(kCountries[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
- profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("CA"));
- profile.FillSelectControl(
- AutofillType(ADDRESS_HOME_COUNTRY), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("Canada"), field.value);
-}
-
-TEST(AutofillProfileTest, AddressCountryAbbrev) {
- const char* const kCountries[] = {
- "AL", "CA"
- };
- std::vector<base::string16> options(arraysize(kCountries));
- for (size_t i = 0; i < arraysize(kCountries); ++i) {
- options[i] = ASCIIToUTF16(kCountries[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
- profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("CA"));
- profile.FillSelectControl(
- AutofillType(ADDRESS_HOME_COUNTRY), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("CA"), field.value);
-}
-
-TEST(AutofillProfileTest, AddressStateFull) {
- const char* const kStates[] = {
- "Alabama", "California"
- };
- std::vector<base::string16> options(arraysize(kStates));
- for (size_t i = 0; i < arraysize(kStates); ++i) {
- options[i] = ASCIIToUTF16(kStates[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
- profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA"));
- profile.FillSelectControl(AutofillType(ADDRESS_HOME_STATE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("California"), field.value);
-}
-
-TEST(AutofillProfileTest, AddressStateAbbrev) {
- const char* const kStates[] = {
- "AL", "CA"
- };
- std::vector<base::string16> options(arraysize(kStates));
- for (size_t i = 0; i < arraysize(kStates); ++i) {
- options[i] = ASCIIToUTF16(kStates[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
- profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("California"));
- profile.FillSelectControl(AutofillType(ADDRESS_HOME_STATE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("CA"), field.value);
-}
-
-TEST(AutofillProfileTest, FillByValue) {
- const char* const kStates[] = {
- "Alabama", "California"
- };
- std::vector<base::string16> values(arraysize(kStates));
- std::vector<base::string16> contents(arraysize(kStates));
- for (unsigned int i = 0; i < arraysize(kStates); ++i) {
- values[i] = ASCIIToUTF16(kStates[i]);
- contents[i] = ASCIIToUTF16(base::StringPrintf("%u", i));
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = values;
- field.option_contents = contents;
-
- AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
- profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("California"));
- profile.FillSelectControl(AutofillType(ADDRESS_HOME_STATE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("California"), field.value);
-}
-
-TEST(AutofillProfileTest, FillByContents) {
- const char* const kStates[] = {
- "Alabama", "California"
- };
- std::vector<base::string16> values(arraysize(kStates));
- std::vector<base::string16> contents(arraysize(kStates));
- for (unsigned int i = 0; i < arraysize(kStates); ++i) {
- values[i] = ASCIIToUTF16(base::StringPrintf("%u", i + 1));
- contents[i] = ASCIIToUTF16(kStates[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = values;
- field.option_contents = contents;
-
- AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
- profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("California"));
- profile.FillSelectControl(AutofillType(ADDRESS_HOME_STATE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("2"), field.value);
-}
-
TEST(AutofillProfileTest, IsPresentButInvalid) {
AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
EXPECT_FALSE(profile.IsPresentButInvalid(ADDRESS_HOME_STATE));
diff --git a/components/autofill/core/browser/credit_card.cc b/components/autofill/core/browser/credit_card.cc
index a3e3044..9617798 100644
--- a/components/autofill/core/browser/credit_card.cc
+++ b/components/autofill/core/browser/credit_card.cc
@@ -534,31 +534,6 @@ bool CreditCard::UpdateFromImportedCard(const CreditCard& imported_card,
return true;
}
-void CreditCard::FillFormField(const AutofillField& field,
- size_t /*variant*/,
- const std::string& app_locale,
- FormFieldData* field_data) const {
- DCHECK_EQ(CREDIT_CARD, field.Type().group());
- DCHECK(field_data);
-
- if (field_data->form_control_type == "select-one") {
- FillSelectControl(field.Type(), app_locale, field_data);
- } else if (field_data->form_control_type == "month") {
- // HTML5 input="month" consists of year-month.
- base::string16 year =
- GetInfo(AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), app_locale);
- base::string16 month =
- GetInfo(AutofillType(CREDIT_CARD_EXP_MONTH), app_locale);
- if (!year.empty() && !month.empty()) {
- // Fill the value only if |this| includes both year and month
- // information.
- field_data->value = year + ASCIIToUTF16("-") + month;
- }
- } else {
- field_data->value = GetInfo(field.Type(), app_locale);
- }
-}
-
int CreditCard::Compare(const CreditCard& credit_card) const {
// The following CreditCard field types are the only types we store in the
// WebDB so far, so we're only concerned with matching these types in the
diff --git a/components/autofill/core/browser/credit_card.h b/components/autofill/core/browser/credit_card.h
index d5bf1a0..4c92e62 100644
--- a/components/autofill/core/browser/credit_card.h
+++ b/components/autofill/core/browser/credit_card.h
@@ -59,12 +59,6 @@ class CreditCard : public AutofillDataModel {
const base::string16& value,
const std::string& app_locale) OVERRIDE;
- // AutofillDataModel:
- virtual void FillFormField(const AutofillField& field,
- size_t variant,
- const std::string& app_locale,
- FormFieldData* field_data) const OVERRIDE;
-
// Credit card preview summary, for example: ******1234, Exp: 01/2020
const base::string16 Label() const;
diff --git a/components/autofill/core/browser/credit_card_field.cc b/components/autofill/core/browser/credit_card_field.cc
index bba804c..f9012ca 100644
--- a/components/autofill/core/browser/credit_card_field.cc
+++ b/components/autofill/core/browser/credit_card_field.cc
@@ -95,7 +95,7 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
}
if (LowerCaseEqualsASCII(scanner->Cursor()->form_control_type, "month")) {
- credit_card_field->expiration_month_ = scanner->Cursor();
+ credit_card_field->expiration_date_ = scanner->Cursor();
scanner->Advance();
} else {
// First try to parse split month/year expiration fields.
@@ -170,10 +170,7 @@ FormField* CreditCardField::Parse(AutofillScanner* scanner) {
if ((credit_card_field->number_ || credit_card_field->verification_) &&
(credit_card_field->expiration_date_ ||
(credit_card_field->expiration_month_ &&
- (credit_card_field->expiration_year_ ||
- (LowerCaseEqualsASCII(
- credit_card_field->expiration_month_->form_control_type,
- "month")))))) {
+ credit_card_field->expiration_year_))) {
return credit_card_field.release();
}
diff --git a/components/autofill/core/browser/credit_card_field.h b/components/autofill/core/browser/credit_card_field.h
index 119e1ab..bf45e7e 100644
--- a/components/autofill/core/browser/credit_card_field.h
+++ b/components/autofill/core/browser/credit_card_field.h
@@ -27,15 +27,7 @@ class CreditCardField : public FormField {
virtual bool ClassifyField(ServerFieldTypeMap* map) const OVERRIDE;
private:
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest, ParseMiniumCreditCard);
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest, ParseFullCreditCard);
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest, ParseCreditCardType);
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest, ParseExpMonthYear);
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest, ParseExpMonthYear2);
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest, ParseExpField);
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest, ParseExpField2DigitYear);
- FRIEND_TEST_ALL_PREFIXES(CreditCardFieldTest,
- ParseCreditCardHolderNameWithCCFullName);
+ friend class CreditCardFieldTest;
CreditCardField();
diff --git a/components/autofill/core/browser/credit_card_field_unittest.cc b/components/autofill/core/browser/credit_card_field_unittest.cc
index 9f60a1d..073e5d7 100644
--- a/components/autofill/core/browser/credit_card_field_unittest.cc
+++ b/components/autofill/core/browser/credit_card_field_unittest.cc
@@ -16,15 +16,25 @@ namespace autofill {
class CreditCardFieldTest : public testing::Test {
public:
CreditCardFieldTest() {}
+ virtual ~CreditCardFieldTest() {}
protected:
ScopedVector<const AutofillField> list_;
- scoped_ptr<CreditCardField> field_;
+ scoped_ptr<const CreditCardField> field_;
ServerFieldTypeMap field_type_map_;
- // Downcast for tests.
- static CreditCardField* Parse(AutofillScanner* scanner) {
- return static_cast<CreditCardField*>(CreditCardField::Parse(scanner));
+ // Parses the contents of |list_| as a form, and stores the result into
+ // |field_|.
+ void Parse() {
+ AutofillScanner scanner(list_.get());
+ field_.reset(
+ static_cast<const CreditCardField*>(CreditCardField::Parse(&scanner)));
+ }
+
+ // Associates fields with their corresponding types, based on the previous
+ // call to Parse().
+ bool ClassifyField() {
+ return field_->ClassifyField(&field_type_map_);
}
private:
@@ -32,15 +42,13 @@ class CreditCardFieldTest : public testing::Test {
};
TEST_F(CreditCardFieldTest, Empty) {
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_EQ(static_cast<CreditCardField*>(NULL), field_.get());
}
TEST_F(CreditCardFieldTest, NonParse) {
list_.push_back(new AutofillField);
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_EQ(static_cast<CreditCardField*>(NULL), field_.get());
}
@@ -56,8 +64,7 @@ TEST_F(CreditCardFieldTest, ParseCreditCardNoNumber) {
field.name = ASCIIToUTF16("ccyear");
list_.push_back(new AutofillField(field, ASCIIToUTF16("year2")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_EQ(static_cast<CreditCardField*>(NULL), field_.get());
}
@@ -69,8 +76,7 @@ TEST_F(CreditCardFieldTest, ParseCreditCardNoDate) {
field.name = ASCIIToUTF16("card_number");
list_.push_back(new AutofillField(field, ASCIIToUTF16("number1")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_EQ(static_cast<CreditCardField*>(NULL), field_.get());
}
@@ -90,10 +96,9 @@ TEST_F(CreditCardFieldTest, ParseMiniumCreditCard) {
field.name = ASCIIToUTF16("ccyear");
list_.push_back(new AutofillField(field, ASCIIToUTF16("year3")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
- ASSERT_TRUE(field_->ClassifyField(&field_type_map_));
+ EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(
field_type_map_.find(ASCIIToUTF16("number1")) != field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NUMBER, field_type_map_[ASCIIToUTF16("number1")]);
@@ -134,10 +139,9 @@ TEST_F(CreditCardFieldTest, ParseFullCreditCard) {
field.name = ASCIIToUTF16("verification");
list_.push_back(new AutofillField(field, ASCIIToUTF16("cvc")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
- ASSERT_TRUE(field_->ClassifyField(&field_type_map_));
+ EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(
field_type_map_.find(ASCIIToUTF16("type")) != field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_TYPE, field_type_map_[ASCIIToUTF16("type")]);
@@ -180,10 +184,9 @@ TEST_F(CreditCardFieldTest, ParseExpMonthYear) {
field.name = ASCIIToUTF16("ExpDate");
list_.push_back(new AutofillField(field, ASCIIToUTF16("year4")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
- ASSERT_TRUE(field_->ClassifyField(&field_type_map_));
+ EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(
field_type_map_.find(ASCIIToUTF16("name1")) != field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NAME, field_type_map_[ASCIIToUTF16("name1")]);
@@ -219,10 +222,9 @@ TEST_F(CreditCardFieldTest, ParseExpMonthYear2) {
field.name = ASCIIToUTF16("ExpDate");
list_.push_back(new AutofillField(field, ASCIIToUTF16("year4")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
- ASSERT_TRUE(field_->ClassifyField(&field_type_map_));
+ EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(
field_type_map_.find(ASCIIToUTF16("name1")) != field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NAME, field_type_map_[ASCIIToUTF16("name1")]);
@@ -254,10 +256,9 @@ TEST_F(CreditCardFieldTest, ParseExpField) {
field.name = ASCIIToUTF16("cc_exp");
list_.push_back(new AutofillField(field, ASCIIToUTF16("exp3")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
- ASSERT_TRUE(field_->ClassifyField(&field_type_map_));
+ EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(
field_type_map_.find(ASCIIToUTF16("name1")) != field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NAME, field_type_map_[ASCIIToUTF16("name1")]);
@@ -286,10 +287,9 @@ TEST_F(CreditCardFieldTest, ParseExpField2DigitYear) {
field.name = ASCIIToUTF16("cc_exp");
list_.push_back(new AutofillField(field, ASCIIToUTF16("exp3")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
- ASSERT_TRUE(field_->ClassifyField(&field_type_map_));
+ EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(
field_type_map_.find(ASCIIToUTF16("name1")) != field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NAME, field_type_map_[ASCIIToUTF16("name1")]);
@@ -310,13 +310,39 @@ TEST_F(CreditCardFieldTest, ParseCreditCardHolderNameWithCCFullName) {
field.name = ASCIIToUTF16("ccfullname");
list_.push_back(new AutofillField(field, ASCIIToUTF16("name1")));
- AutofillScanner scanner(list_.get());
- field_.reset(Parse(&scanner));
+ Parse();
ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
- ASSERT_TRUE(field_->ClassifyField(&field_type_map_));
+ EXPECT_TRUE(ClassifyField());
ASSERT_TRUE(
field_type_map_.find(ASCIIToUTF16("name1")) != field_type_map_.end());
EXPECT_EQ(CREDIT_CARD_NAME, field_type_map_[ASCIIToUTF16("name1")]);
}
+// Verifies that <input type="month"> controls are able to be parsed correctly.
+TEST_F(CreditCardFieldTest, ParseMonthControl) {
+ FormFieldData field;
+
+ field.form_control_type = "text";
+ field.label = ASCIIToUTF16("Card number:");
+ field.name = ASCIIToUTF16("ccnumber");
+ list_.push_back(new AutofillField(field, ASCIIToUTF16("number1")));
+
+ field.form_control_type = "month";
+ field.label = ASCIIToUTF16("Expiration date:");
+ field.name = ASCIIToUTF16("ccexp");
+ list_.push_back(new AutofillField(field, ASCIIToUTF16("date2")));
+
+ Parse();
+ ASSERT_NE(static_cast<CreditCardField*>(NULL), field_.get());
+ EXPECT_TRUE(ClassifyField());
+ ASSERT_TRUE(
+ field_type_map_.find(ASCIIToUTF16("number1")) != field_type_map_.end());
+ EXPECT_EQ(CREDIT_CARD_NUMBER,
+ field_type_map_[ASCIIToUTF16("number1")]);
+ ASSERT_TRUE(
+ field_type_map_.find(ASCIIToUTF16("date2")) != field_type_map_.end());
+ EXPECT_EQ(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR,
+ field_type_map_[ASCIIToUTF16("date2")]);
+}
+
} // namespace autofill
diff --git a/components/autofill/core/browser/credit_card_unittest.cc b/components/autofill/core/browser/credit_card_unittest.cc
index 837d729..ee3b7d9 100644
--- a/components/autofill/core/browser/credit_card_unittest.cc
+++ b/components/autofill/core/browser/credit_card_unittest.cc
@@ -360,172 +360,6 @@ TEST(CreditCardTest, CreditCardVerificationCode) {
}
-TEST(CreditCardTest, CreditCardMonthExact) {
- const char* const kMonthsNumeric[] = {
- "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12",
- };
- std::vector<base::string16> options(arraysize(kMonthsNumeric));
- for (size_t i = 0; i < arraysize(kMonthsNumeric); ++i) {
- options[i] = ASCIIToUTF16(kMonthsNumeric[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_EXP_MONTH), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("01"), field.value);
-}
-
-TEST(CreditCardTest, CreditCardMonthAbbreviated) {
- const char* const kMonthsAbbreviated[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
- std::vector<base::string16> options(arraysize(kMonthsAbbreviated));
- for (size_t i = 0; i < arraysize(kMonthsAbbreviated); ++i) {
- options[i] = ASCIIToUTF16(kMonthsAbbreviated[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_EXP_MONTH), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("Jan"), field.value);
-}
-
-TEST(CreditCardTest, CreditCardMonthFull) {
- const char* const kMonthsFull[] = {
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December",
- };
- std::vector<base::string16> options(arraysize(kMonthsFull));
- for (size_t i = 0; i < arraysize(kMonthsFull); ++i) {
- options[i] = ASCIIToUTF16(kMonthsFull[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_EXP_MONTH), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("January"), field.value);
-}
-
-TEST(CreditCardTest, CreditCardMonthNumeric) {
- const char* const kMonthsNumeric[] = {
- "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12",
- };
- std::vector<base::string16> options(arraysize(kMonthsNumeric));
- for (size_t i = 0; i < arraysize(kMonthsNumeric); ++i) {
- options[i] = ASCIIToUTF16(kMonthsNumeric[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("01"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_EXP_MONTH), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("1"), field.value);
-}
-
-TEST(CreditCardTest, CreditCardTwoDigitYear) {
- const char* const kYears[] = {
- "12", "13", "14", "15", "16", "17", "18", "19"
- };
- std::vector<base::string16> options(arraysize(kYears));
- for (size_t i = 0; i < arraysize(kYears); ++i) {
- options[i] = ASCIIToUTF16(kYears[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2017"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_EXP_4_DIGIT_YEAR), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("17"), field.value);
- EXPECT_EQ(2017, credit_card.expiration_year());
-}
-
-TEST(CreditCardTest, CreditCardTypeSelectControl) {
- const char* const kCreditCardTypes[] = {
- "Visa", "Master Card", "AmEx", "discover"
- };
- std::vector<base::string16> options(arraysize(kCreditCardTypes));
- for (size_t i = 0; i < arraysize(kCreditCardTypes); ++i) {
- options[i] = ASCIIToUTF16(kCreditCardTypes[i]);
- }
-
- FormFieldData field;
- field.form_control_type = "select-one";
- field.option_values = options;
- field.option_contents = options;
-
- // Credit card types are inferred from the numbers, so we use test numbers for
- // each card type. Test card numbers are drawn from
- // http://www.paypalobjects.com/en_US/vhelp/paypalmanager_help/credit_card_numbers.htm
-
- {
- // Normal case:
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_NUMBER,
- ASCIIToUTF16("4111111111111111"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_TYPE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("Visa"), field.value);
- }
-
- {
- // Filling should be able to handle intervening whitespace:
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_NUMBER,
- ASCIIToUTF16("5105105105105100"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_TYPE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("Master Card"), field.value);
- }
-
- {
- // American Express is sometimes abbreviated as AmEx:
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("371449635398431"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_TYPE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("AmEx"), field.value);
- }
-
- {
- // Case insensitivity:
- CreditCard credit_card(base::GenerateGUID(), "https://www.example.com/");
- credit_card.SetRawInfo(CREDIT_CARD_NUMBER,
- ASCIIToUTF16("6011111111111117"));
- credit_card.FillSelectControl(
- AutofillType(CREDIT_CARD_TYPE), "en-US", &field);
- EXPECT_EQ(ASCIIToUTF16("discover"), field.value);
- }
-}
-
TEST(CreditCardTest, GetCreditCardType) {
struct {
std::string card_number;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 5c9c80c..9298047 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -291,7 +291,7 @@ bool PersonalDataManager::ImportFormData(
if (group == CREDIT_CARD) {
if (LowerCaseEqualsASCII(field->form_control_type, "month")) {
- DCHECK_EQ(CREDIT_CARD_EXP_MONTH, server_field_type);
+ DCHECK_EQ(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, server_field_type);
local_imported_credit_card->SetInfoForMonthInputType(value);
} else {
local_imported_credit_card->SetInfo(field_type, value, app_locale_);