diff options
author | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-18 09:52:31 +0000 |
---|---|---|
committer | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-18 09:52:31 +0000 |
commit | db6e45f29e74f0f8c2c2ea76941ab9b63cf81e66 (patch) | |
tree | d05ad702f995e7ab03451f7628b2bff2375e2d09 /components | |
parent | 218b6266d93006d9c63679363347492c0ddb2004 (diff) | |
download | chromium_src-db6e45f29e74f0f8c2c2ea76941ab9b63cf81e66.zip chromium_src-db6e45f29e74f0f8c2c2ea76941ab9b63cf81e66.tar.gz chromium_src-db6e45f29e74f0f8c2c2ea76941ab9b63cf81e66.tar.bz2 |
[Autofill] Add support for three pairs of new server field types.
The field types included are "home" and "billing" variants of street address,
sorting code, and dependent locality. Support for these has already been added
to the server.
BUG=299154, 280499
TEST=unit_tests
R=estade@chromium.org
Review URL: https://codereview.chromium.org/27069006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229340 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
-rw-r--r-- | components/autofill/core/browser/address.cc | 66 | ||||
-rw-r--r-- | components/autofill/core/browser/address_unittest.cc | 87 | ||||
-rw-r--r-- | components/autofill/core/browser/autofill_type.cc | 39 | ||||
-rw-r--r-- | components/autofill/core/browser/autofill_type.h | 4 | ||||
-rw-r--r-- | components/autofill/core/browser/field_types.h | 31 |
5 files changed, 190 insertions, 37 deletions
diff --git a/components/autofill/core/browser/address.cc b/components/autofill/core/browser/address.cc index 238cb24..43052bd 100644 --- a/components/autofill/core/browser/address.cc +++ b/components/autofill/core/browser/address.cc @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/logging.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" @@ -58,7 +59,20 @@ base::string16 Address::GetRawInfo(ServerFieldType type) const { case ADDRESS_HOME_COUNTRY: return ASCIIToUTF16(country_code_); + case ADDRESS_HOME_STREET_ADDRESS: { + base::string16 address = line1_; + if (!line2_.empty()) + address += ASCIIToUTF16("\n") + line2_; + return address; + } + + // TODO(isherman): Add support for these field types in support of i18n. + case ADDRESS_HOME_SORTING_CODE: + case ADDRESS_HOME_DEPENDENT_LOCALITY: + return base::string16(); + default: + NOTREACHED(); return base::string16(); } } @@ -92,6 +106,27 @@ void Address::SetRawInfo(ServerFieldType type, const base::string16& value) { zip_code_ = value; break; + case ADDRESS_HOME_STREET_ADDRESS: { + // Clear any stale values, which might or might not get overwritten below. + line1_.clear(); + line2_.clear(); + + std::vector<base::string16> lines; + base::SplitString(value, char16('\n'), &lines); + if (lines.size() > 0) + line1_ = lines[0]; + if (lines.size() > 1) + line2_ = lines[1]; + + // TODO(isherman): Add support for additional address lines. + break; + } + + // TODO(isherman): Add support for these field types in support of i18n. + case ADDRESS_HOME_SORTING_CODE: + case ADDRESS_HOME_DEPENDENT_LOCALITY: + break; + default: NOTREACHED(); } @@ -99,19 +134,21 @@ void Address::SetRawInfo(ServerFieldType type, const base::string16& value) { base::string16 Address::GetInfo(const AutofillType& type, const std::string& app_locale) const { - if (type.html_type() == HTML_TYPE_COUNTRY_CODE) { + if (type.html_type() == HTML_TYPE_COUNTRY_CODE) return ASCIIToUTF16(country_code_); - } else if (type.html_type() == HTML_TYPE_STREET_ADDRESS) { + + ServerFieldType storable_type = type.GetStorableType(); + if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty()) + return AutofillCountry(country_code_, app_locale).name(); + + if (storable_type == ADDRESS_HOME_STREET_ADDRESS) { + // TODO(isherman): Remove this special-case. base::string16 address = line1_; if (!line2_.empty()) address += ASCIIToUTF16(", ") + line2_; return address; } - ServerFieldType storable_type = type.GetStorableType(); - if (storable_type == ADDRESS_HOME_COUNTRY && !country_code_.empty()) - return AutofillCountry(country_code_, app_locale).name(); - return GetRawInfo(storable_type); } @@ -126,13 +163,6 @@ bool Address::SetInfo(const AutofillType& type, country_code_ = StringToUpperASCII(UTF16ToASCII(value)); return true; - } else if (type.html_type() == HTML_TYPE_STREET_ADDRESS) { - // Don't attempt to parse the address into lines, since this is potentially - // a user-entered address in the user's own format, so the code would have - // to rely on iffy heuristics at best. Instead, just give up when importing - // addresses like this. - line1_ = line2_ = base::string16(); - return false; } ServerFieldType storable_type = type.GetStorableType(); @@ -141,6 +171,16 @@ bool Address::SetInfo(const AutofillType& type, return !country_code_.empty(); } + // If the address doesn't have any newlines, don't attempt to parse it into + // lines, since this is potentially a user-entered address in the user's own + // format, so the code would have to rely on iffy heuristics at best. + // Instead, just give up when importing addresses like this. + if (storable_type == ADDRESS_HOME_STREET_ADDRESS && !value.empty() && + value.find(char16('\n')) == base::string16::npos) { + line1_ = line2_ = base::string16(); + return false; + } + SetRawInfo(storable_type, value); return true; } diff --git a/components/autofill/core/browser/address_unittest.cc b/components/autofill/core/browser/address_unittest.cc index b5bcfaf..26d1faf 100644 --- a/components/autofill/core/browser/address_unittest.cc +++ b/components/autofill/core/browser/address_unittest.cc @@ -149,50 +149,105 @@ TEST(AddressTest, IsCountry) { EXPECT_EQ(0U, matching_types.size()); } -// Verifies that Address::GetInfo() can correctly return a concatenated full -// street address. +// Verifies that Address::GetInfo() correctly combines address lines. TEST(AddressTest, GetStreetAddress) { + const AutofillType type = AutofillType(ADDRESS_HOME_STREET_ADDRESS); + // Address has no address lines. Address address; EXPECT_TRUE(address.GetRawInfo(ADDRESS_HOME_LINE1).empty()); EXPECT_TRUE(address.GetRawInfo(ADDRESS_HOME_LINE2).empty()); - - AutofillType type = AutofillType(HTML_TYPE_STREET_ADDRESS, HTML_MODE_NONE); EXPECT_EQ(base::string16(), address.GetInfo(type, "en-US")); // Address has only line 1. address.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("123 Example Ave.")); EXPECT_FALSE(address.GetRawInfo(ADDRESS_HOME_LINE1).empty()); EXPECT_TRUE(address.GetRawInfo(ADDRESS_HOME_LINE2).empty()); - - EXPECT_EQ(ASCIIToUTF16("123 Example Ave."), - address.GetInfo(type, "en-US")); + EXPECT_EQ(ASCIIToUTF16("123 Example Ave."), address.GetInfo(type, "en-US")); // Address has lines 1 and 2. address.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("Apt. 42")); EXPECT_FALSE(address.GetRawInfo(ADDRESS_HOME_LINE1).empty()); EXPECT_FALSE(address.GetRawInfo(ADDRESS_HOME_LINE2).empty()); - + EXPECT_EQ(ASCIIToUTF16("123 Example Ave.\n" + "Apt. 42"), + address.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS)); EXPECT_EQ(ASCIIToUTF16("123 Example Ave., Apt. 42"), address.GetInfo(type, "en-US")); } +// Verifies that Address::SetRawInfo() is able to split address lines correctly. +TEST(AddressTest, SetRawStreetAddress) { + const base::string16 empty_street_address; + const base::string16 short_street_address = ASCIIToUTF16("456 Nowhere Ln."); + const base::string16 long_street_address = + ASCIIToUTF16("123 Example Ave.\n" + "Apt. 42\n" + "(The one with the blue door)"); + + Address address; + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE1)); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE2)); + + // Address lines beyond the first two are simply dropped. + address.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, long_street_address); + EXPECT_EQ(ASCIIToUTF16("123 Example Ave."), + address.GetRawInfo(ADDRESS_HOME_LINE1)); + EXPECT_EQ(ASCIIToUTF16("Apt. 42"), address.GetRawInfo(ADDRESS_HOME_LINE2)); + + // A short address should clear out unused address lines. + address.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, short_street_address); + EXPECT_EQ(ASCIIToUTF16("456 Nowhere Ln."), + address.GetRawInfo(ADDRESS_HOME_LINE1)); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE2)); + + // An empty address should clear out all address lines. + address.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, long_street_address); + address.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS, empty_street_address); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE1)); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE2)); +} + // Verifies that Address::SetInfo() rejects setting data for -// HTML_TYPE_STREET_ADDRESS, as there is no good general way to parse that data -// into the consituent address lines. +// ADDRESS_HOME_STREET_ADDRESS without newlines, as there is no good general way +// to parse that data into the consituent address lines. Addresses without +// newlines should be set properly. TEST(AddressTest, SetStreetAddress) { - // Address has no address lines. + const base::string16 empty_street_address; + const base::string16 one_line_street_address = + ASCIIToUTF16("456 New St., Apt. 17"); + const base::string16 multi_line_street_address = + ASCIIToUTF16("789 Fancy Pkwy.\n" + "Unit 3.14"); + const AutofillType type = AutofillType(ADDRESS_HOME_STREET_ADDRESS); + + // Start with a non-empty address. Address address; address.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("123 Example Ave.")); address.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("Apt. 42")); EXPECT_FALSE(address.GetRawInfo(ADDRESS_HOME_LINE1).empty()); EXPECT_FALSE(address.GetRawInfo(ADDRESS_HOME_LINE2).empty()); - AutofillType type = AutofillType(HTML_TYPE_STREET_ADDRESS, HTML_MODE_NONE); - base::string16 street_address = ASCIIToUTF16("456 New St., Apt. 17"); - EXPECT_FALSE(address.SetInfo(type, street_address, "en-US")); - EXPECT_TRUE(address.GetRawInfo(ADDRESS_HOME_LINE1).empty()); - EXPECT_TRUE(address.GetRawInfo(ADDRESS_HOME_LINE2).empty()); + // Attempting to set a one-line address should fail, as the single line might + // actually represent multiple logical lines, combined into one due to the + // user having to work around constraints imposed by the website. + EXPECT_FALSE(address.SetInfo(type, one_line_street_address, "en-US")); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE1)); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE2)); + + // Attempting to set a multi-line address should succeed. + EXPECT_TRUE(address.SetInfo(type, multi_line_street_address, "en-US")); + EXPECT_EQ(ASCIIToUTF16("789 Fancy Pkwy."), + address.GetRawInfo(ADDRESS_HOME_LINE1)); + EXPECT_EQ(ASCIIToUTF16("Unit 3.14"), address.GetRawInfo(ADDRESS_HOME_LINE2)); + + // Attempting to set an empty address should also succeed, and clear out the + // previously stored data. + EXPECT_FALSE(address.GetRawInfo(ADDRESS_HOME_LINE1).empty()); + EXPECT_FALSE(address.GetRawInfo(ADDRESS_HOME_LINE2).empty()); + EXPECT_TRUE(address.SetInfo(type, empty_street_address, "en-US")); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE1)); + EXPECT_EQ(base::string16(), address.GetRawInfo(ADDRESS_HOME_LINE2)); } } // namespace autofill diff --git a/components/autofill/core/browser/autofill_type.cc b/components/autofill/core/browser/autofill_type.cc index 97168ac..2341d94 100644 --- a/components/autofill/core/browser/autofill_type.cc +++ b/components/autofill/core/browser/autofill_type.cc @@ -83,6 +83,9 @@ FieldTypeGroup AutofillType::group() const { case ADDRESS_HOME_STATE: case ADDRESS_HOME_ZIP: case ADDRESS_HOME_COUNTRY: + case ADDRESS_HOME_STREET_ADDRESS: + case ADDRESS_HOME_SORTING_CODE: + case ADDRESS_HOME_DEPENDENT_LOCALITY: return ADDRESS_HOME; case ADDRESS_BILLING_LINE1: @@ -92,6 +95,9 @@ FieldTypeGroup AutofillType::group() const { case ADDRESS_BILLING_STATE: case ADDRESS_BILLING_ZIP: case ADDRESS_BILLING_COUNTRY: + case ADDRESS_BILLING_STREET_ADDRESS: + case ADDRESS_BILLING_SORTING_CODE: + case ADDRESS_BILLING_DEPENDENT_LOCALITY: return ADDRESS_BILLING; case CREDIT_CARD_NAME: @@ -246,6 +252,15 @@ ServerFieldType AutofillType::GetStorableType() const { case NAME_BILLING_SUFFIX: return NAME_SUFFIX; + case ADDRESS_BILLING_STREET_ADDRESS: + return ADDRESS_HOME_STREET_ADDRESS; + + case ADDRESS_BILLING_SORTING_CODE: + return ADDRESS_HOME_SORTING_CODE; + + case ADDRESS_BILLING_DEPENDENT_LOCALITY: + return ADDRESS_HOME_DEPENDENT_LOCALITY; + case UNKNOWN_TYPE: break; // Try to parse HTML types instead. @@ -273,7 +288,7 @@ ServerFieldType AutofillType::GetStorableType() const { return COMPANY_NAME; case HTML_TYPE_STREET_ADDRESS: - return ADDRESS_HOME_LINE1; + return ADDRESS_HOME_STREET_ADDRESS; case HTML_TYPE_ADDRESS_LINE1: return ADDRESS_HOME_LINE1; @@ -380,6 +395,15 @@ ServerFieldType AutofillType::GetEquivalentBillingFieldType( case ADDRESS_HOME_COUNTRY: return ADDRESS_BILLING_COUNTRY; + case ADDRESS_HOME_STREET_ADDRESS: + return ADDRESS_BILLING_STREET_ADDRESS; + + case ADDRESS_HOME_SORTING_CODE: + return ADDRESS_BILLING_SORTING_CODE; + + case ADDRESS_HOME_DEPENDENT_LOCALITY: + return ADDRESS_BILLING_DEPENDENT_LOCALITY; + case PHONE_HOME_WHOLE_NUMBER: return PHONE_BILLING_WHOLE_NUMBER; @@ -543,6 +567,19 @@ std::string AutofillType::ToString() const { return "PASSWORD"; case ACCOUNT_CREATION_PASSWORD: return "ACCOUNT_CREATION_PASSWORD"; + case ADDRESS_HOME_STREET_ADDRESS: + return "ADDRESS_HOME_STREET_ADDRESS"; + case ADDRESS_BILLING_STREET_ADDRESS: + return "ADDRESS_BILLING_STREET_ADDRESS"; + case ADDRESS_HOME_SORTING_CODE: + return "ADDRESS_HOME_SORTING_CODE"; + case ADDRESS_BILLING_SORTING_CODE: + return "ADDRESS_BILLING_SORTING_CODE"; + case ADDRESS_HOME_DEPENDENT_LOCALITY: + return "ADDRESS_HOME_DEPENDENT_LOCALITY"; + case ADDRESS_BILLING_DEPENDENT_LOCALITY: + return "ADDRESS_BILLING_DEPENDENT_LOCALITY"; + case MAX_VALID_FIELD_TYPE: return std::string(); } diff --git a/components/autofill/core/browser/autofill_type.h b/components/autofill/core/browser/autofill_type.h index 41fa613..70668ae 100644 --- a/components/autofill/core/browser/autofill_type.h +++ b/components/autofill/core/browser/autofill_type.h @@ -32,8 +32,8 @@ class AutofillType { // data model (in the sense that it makes sense to call // |AutofillDataModel::SetRawInfo()| with the returned field type as the first // parameter). Note that the returned type might not be exactly equivalent to - // |this| type. For example, there is no exact analogue to the - // 'street-address' HTML type hint among the storable field types. + // |this| type. For example, the HTML types 'country' and 'country-name' both + // map to ADDRESS_HOME_COUNTRY. ServerFieldType GetStorableType() const; // Serializes |this| type to a string. diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h index 0eda2e2..279e087 100644 --- a/components/autofill/core/browser/field_types.h +++ b/components/autofill/core/browser/field_types.h @@ -12,10 +12,11 @@ namespace autofill { -// NOTE: This list MUST not be modified. The server aggregates and stores these -// types over several versions, so we must remain fully compatible with the -// Autofill server, which is itself backward-compatible. The list must be kept -// up to date with the Autofill server list. +// NOTE: This list MUST not be modified except to keep it synchronized with the +// Autofill server's version. The server aggregates and stores these types over +// several versions, so we must remain fully compatible with the Autofill +// server, which is itself backward-compatible. The list must be kept up to +// date with the Autofill server list. // // The list of all field types natively understood by the Autofill server. A // subset of these types is used to store Autofill data in the user's profile. @@ -111,10 +112,30 @@ enum ServerFieldType { PASSWORD = 75, ACCOUNT_CREATION_PASSWORD = 76, + // Includes all of the lines of a street address, including newlines, e.g. + // 123 Main Street, + // Apt. #42 + ADDRESS_HOME_STREET_ADDRESS = 77, + ADDRESS_BILLING_STREET_ADDRESS = 78, + + // A sorting code is similar to a postal code. However, whereas a postal code + // normally refers to a single geographical location, a sorting code often + // does not. Instead, a sorting code is assigned to an organization, which + // might be geographically distributed. The most prominent example of a + // sorting code system is CEDEX in France. + ADDRESS_HOME_SORTING_CODE = 79, + ADDRESS_BILLING_SORTING_CODE = 80, + + // A dependent locality is a subunit of a locality, where a "locality" is + // roughly equivalent to a city. Examples of dependent localities include + // inner-city districts and suburbs. + ADDRESS_HOME_DEPENDENT_LOCALITY = 81, + ADDRESS_BILLING_DEPENDENT_LOCALITY = 82, + // No new types can be added without a corresponding change to the Autofill // server. - MAX_VALID_FIELD_TYPE = 77, + MAX_VALID_FIELD_TYPE = 83, }; // The list of all HTML autocomplete field type hints supported by Chrome. |