| Index: chrome/browser/autofill/form_structure_unittest.cc
|
| diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc
|
| index 64c8e17c46d07a8480dd903258ae42d320bdc42f..ca40e2416d37c99f5e7200ca38311f9dab186488 100644
|
| --- a/chrome/browser/autofill/form_structure_unittest.cc
|
| +++ b/chrome/browser/autofill/form_structure_unittest.cc
|
| @@ -329,8 +329,8 @@ TEST(FormStructureTest, HeuristicsContactInfo) {
|
| EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
|
| }
|
|
|
| -// Verify that we can correctly process the |autocompletetype| attribute.
|
| -TEST(FormStructureTest, HeuristicsAutocompletetype) {
|
| +// Verify that we can correctly process the |autocomplete| attribute.
|
| +TEST(FormStructureTest, HeuristicsAutocompleteAttribute) {
|
| scoped_ptr<FormStructure> form_structure;
|
| FormData form;
|
| form.method = ASCIIToUTF16("post");
|
| @@ -340,17 +340,17 @@ TEST(FormStructureTest, HeuristicsAutocompletetype) {
|
|
|
| field.label = string16();
|
| field.name = ASCIIToUTF16("field1");
|
| - field.autocomplete_type = ASCIIToUTF16("given-name");
|
| + field.autocomplete_attribute = ASCIIToUTF16("given-name");
|
| form.fields.push_back(field);
|
|
|
| field.label = string16();
|
| field.name = ASCIIToUTF16("field2");
|
| - field.autocomplete_type = ASCIIToUTF16("surname");
|
| + field.autocomplete_attribute = ASCIIToUTF16("family-name");
|
| form.fields.push_back(field);
|
|
|
| field.label = string16();
|
| field.name = ASCIIToUTF16("field3");
|
| - field.autocomplete_type = ASCIIToUTF16("email");
|
| + field.autocomplete_attribute = ASCIIToUTF16("email");
|
| form.fields.push_back(field);
|
|
|
| form_structure.reset(new FormStructure(form));
|
| @@ -366,9 +366,9 @@ TEST(FormStructureTest, HeuristicsAutocompletetype) {
|
| EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
|
| }
|
|
|
| -// Verify that we can correctly process the |autocompletetype| attribute for
|
| -// phone number types (especially phone prefixes and suffixes).
|
| -TEST(FormStructureTest, HeuristicsAutocompletetypePhones) {
|
| +// Verify that we can correctly process the 'autocomplete' attribute for phone
|
| +// number types (especially phone prefixes and suffixes).
|
| +TEST(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
|
| scoped_ptr<FormStructure> form_structure;
|
| FormData form;
|
| form.method = ASCIIToUTF16("post");
|
| @@ -378,17 +378,17 @@ TEST(FormStructureTest, HeuristicsAutocompletetypePhones) {
|
|
|
| field.label = string16();
|
| field.name = ASCIIToUTF16("field1");
|
| - field.autocomplete_type = ASCIIToUTF16("phone-local");
|
| + field.autocomplete_attribute = ASCIIToUTF16("tel-local");
|
| form.fields.push_back(field);
|
|
|
| field.label = string16();
|
| field.name = ASCIIToUTF16("field2");
|
| - field.autocomplete_type = ASCIIToUTF16("phone-local-prefix");
|
| + field.autocomplete_attribute = ASCIIToUTF16("tel-local-prefix");
|
| form.fields.push_back(field);
|
|
|
| field.label = string16();
|
| field.name = ASCIIToUTF16("field3");
|
| - field.autocomplete_type = ASCIIToUTF16("phone-local-suffix");
|
| + field.autocomplete_attribute = ASCIIToUTF16("tel-local-suffix");
|
| form.fields.push_back(field);
|
|
|
| form_structure.reset(new FormStructure(form));
|
| @@ -409,9 +409,9 @@ TEST(FormStructureTest, HeuristicsAutocompletetypePhones) {
|
| form_structure->field(2)->phone_part());
|
| }
|
|
|
| -// If at least one field includes the |autocompletetype| attribute, we should
|
| -// not try to apply any other heuristics.
|
| -TEST(FormStructureTest, AutocompletetypeOverridesOtherHeuristics) {
|
| +// If at least one field includes type hints in the 'autocomplete' attribute, we
|
| +// should not try to apply any other heuristics.
|
| +TEST(FormStructureTest, AutocompleteAttributeOverridesOtherHeuristics) {
|
| scoped_ptr<FormStructure> form_structure;
|
| FormData form;
|
| form.method = ASCIIToUTF16("post");
|
| @@ -444,8 +444,8 @@ TEST(FormStructureTest, AutocompletetypeOverridesOtherHeuristics) {
|
| EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
|
| EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
|
|
|
| - // Now update the first form field to include an 'autocompletetype' attribute.
|
| - form.fields.front().autocomplete_type = ASCIIToUTF16("x-other");
|
| + // Now update the first form field to include an 'autocomplete' attribute.
|
| + form.fields.front().autocomplete_attribute = ASCIIToUTF16("x-other");
|
| form_structure.reset(new FormStructure(form));
|
| form_structure->DetermineHeuristicTypes();
|
| EXPECT_FALSE(form_structure->IsAutofillable(true));
|
| @@ -461,124 +461,168 @@ TEST(FormStructureTest, AutocompletetypeOverridesOtherHeuristics) {
|
|
|
| // Verify that we can correctly process sections listed in the |autocomplete|
|
| // attribute.
|
| -TEST(FormStructureTest, HeuristicsAutocompletetypeWithSections) {
|
| - scoped_ptr<FormStructure> form_structure;
|
| +TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) {
|
| FormData form;
|
| form.method = ASCIIToUTF16("post");
|
|
|
| FormFieldData field;
|
| field.form_control_type = ASCIIToUTF16("text");
|
|
|
| - // We expect "shipping" and "billing" to be the most common sections.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field1");
|
| - field.autocomplete_type = ASCIIToUTF16("section-shipping given-name");
|
| + // Some fields will have no section specified. These fall into the default
|
| + // section.
|
| + field.autocomplete_attribute = ASCIIToUTF16("email");
|
| form.fields.push_back(field);
|
|
|
| - // Some field will have no section specified. These fall into the default
|
| - // section, with an empty name.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field2");
|
| - field.autocomplete_type = ASCIIToUTF16("surname");
|
| + // We allow arbitrary section names.
|
| + field.autocomplete_attribute = ASCIIToUTF16("section-foo email");
|
| form.fields.push_back(field);
|
|
|
| - // We allow arbitrary section names.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field3");
|
| - field.autocomplete_type = ASCIIToUTF16("section-foo address-line1");
|
| + // "shipping" and "billing" are special section tokens that don't require the
|
| + // "section-" prefix.
|
| + field.autocomplete_attribute = ASCIIToUTF16("shipping email");
|
| + form.fields.push_back(field);
|
| + field.autocomplete_attribute = ASCIIToUTF16("billing email");
|
| form.fields.push_back(field);
|
|
|
| - // Specifying "section-" is equivalent to not specifying a section.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field4");
|
| - field.autocomplete_type = ASCIIToUTF16("section- address-line2");
|
| + // "shipping" and "billing" can be combined with other section names.
|
| + field.autocomplete_attribute = ASCIIToUTF16("section-foo shipping email");
|
| + form.fields.push_back(field);
|
| + field.autocomplete_attribute = ASCIIToUTF16("section-foo billing email");
|
| form.fields.push_back(field);
|
|
|
| // We don't do anything clever to try to coalesce sections; it's up to site
|
| // authors to avoid typos.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field5");
|
| - field.autocomplete_type = ASCIIToUTF16("section--shipping locality");
|
| + field.autocomplete_attribute = ASCIIToUTF16("section--foo email");
|
| + form.fields.push_back(field);
|
| +
|
| + // "shipping email" and "section--shipping" email should be parsed as
|
| + // different sections. This is only an interesting test due to how we
|
| + // implement implicit section names from attributes like "shipping email"; see
|
| + // the implementation for more details.
|
| + field.autocomplete_attribute = ASCIIToUTF16("section--shipping email");
|
| form.fields.push_back(field);
|
|
|
| // Credit card fields are implicitly in a separate section from other fields.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field6");
|
| - field.autocomplete_type = ASCIIToUTF16("section-shipping cc-number");
|
| + field.autocomplete_attribute = ASCIIToUTF16("section-foo cc-number");
|
| form.fields.push_back(field);
|
|
|
| - form_structure.reset(new FormStructure(form));
|
| - form_structure->DetermineHeuristicTypes();
|
| - EXPECT_TRUE(form_structure->IsAutofillable(true));
|
| + FormStructure form_structure(form);
|
| + form_structure.DetermineHeuristicTypes();
|
| + EXPECT_TRUE(form_structure.IsAutofillable(true));
|
|
|
| // Expect the correct number of fields.
|
| - ASSERT_EQ(6U, form_structure->field_count());
|
| - ASSERT_EQ(6U, form_structure->autofill_count());
|
| -
|
| - EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("shipping-default"),
|
| - form_structure->field(0)->section());
|
| - EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("-default"), form_structure->field(1)->section());
|
| - EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(2)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("foo-default"), form_structure->field(2)->section());
|
| - EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(3)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("-default"), form_structure->field(3)->section());
|
| - EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("-shipping-default"),
|
| - form_structure->field(4)->section());
|
| - EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(5)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("shipping-cc"), form_structure->field(5)->section());
|
| + ASSERT_EQ(9U, form_structure.field_count());
|
| + EXPECT_EQ(9U, form_structure.autofill_count());
|
| +
|
| + // All of the fields in this form should be parsed as belonging to different
|
| + // sections.
|
| + std::set<string16> section_names;
|
| + for (size_t i = 0; i < 9; ++i) {
|
| + section_names.insert(form_structure.field(i)->section());
|
| + }
|
| + EXPECT_EQ(9U, section_names.size());
|
| }
|
|
|
| -// Verify that we can correctly process fallback types listed in the
|
| -// |autocompletetype| attribute.
|
| -TEST(FormStructureTest, HeuristicsAutocompletetypeWithFallbacks) {
|
| - scoped_ptr<FormStructure> form_structure;
|
| +// Verify that we can correctly process a degenerate section listed in the
|
| +// |autocomplete| attribute.
|
| +TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsDegenerate) {
|
| FormData form;
|
| form.method = ASCIIToUTF16("post");
|
|
|
| FormFieldData field;
|
| field.form_control_type = ASCIIToUTF16("text");
|
|
|
| - // Skip over any sections and "x"-prefixed types.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field1");
|
| - field.autocomplete_type =
|
| - ASCIIToUTF16("section-full-name x-given-name-initial given-name");
|
| + // Some fields will have no section specified. These fall into the default
|
| + // section.
|
| + field.autocomplete_attribute = ASCIIToUTF16("email");
|
| form.fields.push_back(field);
|
|
|
| - // Stop processing once we see a known type.
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field2");
|
| - field.autocomplete_type = ASCIIToUTF16("section-full-name surname full-name");
|
| + // Specifying "section-" is equivalent to not specifying a section.
|
| + field.autocomplete_attribute = ASCIIToUTF16("section- email");
|
| form.fields.push_back(field);
|
|
|
| - // Skip over unknown types even if they are not prefixed with "x-".
|
| - field.label = string16();
|
| - field.name = ASCIIToUTF16("field3");
|
| - field.autocomplete_type =
|
| - ASCIIToUTF16("section-shipping mobile-phone-full phone-full");
|
| + FormStructure form_structure(form);
|
| + form_structure.DetermineHeuristicTypes();
|
| +
|
| + // Expect the correct number of fields.
|
| + ASSERT_EQ(2U, form_structure.field_count());
|
| + EXPECT_EQ(2U, form_structure.autofill_count());
|
| +
|
| + // All of the fields in this form should be parsed as belonging to the same
|
| + // sections.
|
| + std::set<string16> section_names;
|
| + for (size_t i = 0; i < 2; ++i) {
|
| + section_names.insert(form_structure.field(i)->section());
|
| + }
|
| + EXPECT_EQ(1U, section_names.size());
|
| +}
|
| +
|
| +// Verify that we can correctly process repeated sections listed in the
|
| +// |autocomplete| attribute.
|
| +TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsRepeated) {
|
| + FormData form;
|
| + form.method = ASCIIToUTF16("post");
|
| +
|
| + FormFieldData field;
|
| + field.form_control_type = ASCIIToUTF16("text");
|
| +
|
| + field.autocomplete_attribute = ASCIIToUTF16("section-foo email");
|
| + form.fields.push_back(field);
|
| + field.autocomplete_attribute = ASCIIToUTF16("section-foo street-address");
|
| form.fields.push_back(field);
|
|
|
| - form_structure.reset(new FormStructure(form));
|
| - form_structure->DetermineHeuristicTypes();
|
| - EXPECT_TRUE(form_structure->IsAutofillable(true));
|
| + FormStructure form_structure(form);
|
| + form_structure.DetermineHeuristicTypes();
|
|
|
| // Expect the correct number of fields.
|
| - ASSERT_EQ(3U, form_structure->field_count());
|
| - ASSERT_EQ(3U, form_structure->autofill_count());
|
| + ASSERT_EQ(2U, form_structure.field_count());
|
| + EXPECT_EQ(2U, form_structure.autofill_count());
|
|
|
| - EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("full-name-default"),
|
| - form_structure->field(0)->section());
|
| - EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("full-name-default"),
|
| - form_structure->field(1)->section());
|
| - EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
|
| - form_structure->field(2)->heuristic_type());
|
| - EXPECT_EQ(ASCIIToUTF16("shipping-default"),
|
| - form_structure->field(2)->section());
|
| + // All of the fields in this form should be parsed as belonging to the same
|
| + // sections.
|
| + std::set<string16> section_names;
|
| + for (size_t i = 0; i < 2; ++i) {
|
| + section_names.insert(form_structure.field(i)->section());
|
| + }
|
| + EXPECT_EQ(1U, section_names.size());
|
| +}
|
| +
|
| +// Verify that we do not override the author-specified sections from a form with
|
| +// local heuristics.
|
| +TEST(FormStructureTest, HeuristicsDontOverrideAutocompleteAttributeSections) {
|
| + FormData form;
|
| + form.method = ASCIIToUTF16("post");
|
| +
|
| + FormFieldData field;
|
| + field.form_control_type = ASCIIToUTF16("text");
|
| +
|
| + field.name = ASCIIToUTF16("one");
|
| + field.autocomplete_attribute = ASCIIToUTF16("street-address");
|
| + form.fields.push_back(field);
|
| + field.name = string16();
|
| + field.autocomplete_attribute = ASCIIToUTF16("section-foo email");
|
| + form.fields.push_back(field);
|
| + field.name = string16();
|
| + field.autocomplete_attribute = ASCIIToUTF16("name");
|
| + form.fields.push_back(field);
|
| + field.name = ASCIIToUTF16("two");
|
| + field.autocomplete_attribute = ASCIIToUTF16("street-address");
|
| + form.fields.push_back(field);
|
| +
|
| + FormStructure form_structure(form);
|
| + form_structure.DetermineHeuristicTypes();
|
| +
|
| + // Expect the correct number of fields.
|
| + ASSERT_EQ(4U, form_structure.field_count());
|
| + EXPECT_EQ(4U, form_structure.autofill_count());
|
| +
|
| + // Normally, the two separate address fields would cause us to detect two
|
| + // separate sections; but because there is an author-specified section in this
|
| + // form, we do not apply these usual heuristics.
|
| + EXPECT_EQ(ASCIIToUTF16("one"), form_structure.field(0)->name);
|
| + EXPECT_EQ(ASCIIToUTF16("two"), form_structure.field(3)->name);
|
| + EXPECT_EQ(form_structure.field(0)->section(),
|
| + form_structure.field(3)->section());
|
| }
|
|
|
| TEST(FormStructureTest, HeuristicsSample8) {
|
|
|