Index: components/autofill/browser/form_structure_unittest.cc |
diff --git a/components/autofill/browser/form_structure_unittest.cc b/components/autofill/browser/form_structure_unittest.cc |
deleted file mode 100644 |
index 6d90d6cee9c9f478210d258e4147b6d8a655a6b7..0000000000000000000000000000000000000000 |
--- a/components/autofill/browser/form_structure_unittest.cc |
+++ /dev/null |
@@ -1,2443 +0,0 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "components/autofill/browser/form_structure.h" |
- |
-#include "base/memory/scoped_ptr.h" |
-#include "base/strings/string_util.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "components/autofill/browser/autofill_metrics.h" |
-#include "components/autofill/content/browser/autocheckout_page_meta_data.h" |
-#include "components/autofill/core/common/form_data.h" |
-#include "components/autofill/core/common/form_field_data.h" |
-#include "googleurl/src/gurl.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h" |
- |
-using WebKit::WebInputElement; |
- |
-namespace autofill { |
-namespace { |
- |
-// Unlike the base AutofillMetrics, exposes copy and assignment constructors, |
-// which are handy for briefer test code. The AutofillMetrics class is |
-// stateless, so this is safe. |
-class TestAutofillMetrics : public AutofillMetrics { |
- public: |
- TestAutofillMetrics() {} |
- virtual ~TestAutofillMetrics() {} |
-}; |
- |
-} // anonymous namespace |
- |
- |
-namespace content { |
- |
-std::ostream& operator<<(std::ostream& os, const FormData& form) { |
- os << UTF16ToUTF8(form.name) |
- << " " |
- << UTF16ToUTF8(form.method) |
- << " " |
- << form.origin.spec() |
- << " " |
- << form.action.spec() |
- << " "; |
- |
- for (std::vector<FormFieldData>::const_iterator iter = |
- form.fields.begin(); |
- iter != form.fields.end(); ++iter) { |
- os << *iter |
- << " "; |
- } |
- |
- return os; |
-} |
- |
-} // namespace content |
- |
-class FormStructureTest { |
- public: |
- static std::string Hash64Bit(const std::string& str) { |
- return FormStructure::Hash64Bit(str); |
- } |
-}; |
- |
-TEST(FormStructureTest, FieldCount) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.label = ASCIIToUTF16("username"); |
- field.name = ASCIIToUTF16("username"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("password"); |
- field.name = ASCIIToUTF16("password"); |
- field.form_control_type = "password"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("address1"); |
- field.name = ASCIIToUTF16("address1"); |
- field.form_control_type = "text"; |
- field.should_autocomplete = false; |
- form.fields.push_back(field); |
- |
- // The render process sends all fields to browser including fields with |
- // autocomplete=off |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_EQ(4U, form_structure->field_count()); |
- |
- // We expect the same count when autocheckout is enabled. |
- form_structure.reset(new FormStructure(form, "http://fake_url")); |
- EXPECT_EQ(4U, form_structure->field_count()); |
-} |
- |
-TEST(FormStructureTest, AutofillCount) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.label = ASCIIToUTF16("username"); |
- field.name = ASCIIToUTF16("username"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("password"); |
- field.name = ASCIIToUTF16("password"); |
- field.form_control_type = "password"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("state"); |
- field.name = ASCIIToUTF16("state"); |
- field.form_control_type = "select-one"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- // Only text and select fields that are heuristically matched are counted. |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_EQ(1U, form_structure->autofill_count()); |
- |
- // Add a field with should_autocomplete=false. |
- field.label = ASCIIToUTF16("address1"); |
- field.name = ASCIIToUTF16("address1"); |
- field.form_control_type = "text"; |
- field.should_autocomplete = false; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- // DetermineHeuristicTypes also assign field type for fields with |
- // autocomplete=off thus autofill_count includes them. This is a bug, |
- // and they should not be counted. See http://crbug.com/176432 for details. |
- // TODO(benquan): change it to EXPECT_EQ(1U, ... when the bug is fixed. |
- EXPECT_EQ(2U, form_structure->autofill_count()); |
- |
- // All fields should be counted when Autocheckout is enabled. |
- form_structure.reset(new FormStructure(form, "http://fake_url")); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_EQ(2U, form_structure->autofill_count()); |
-} |
- |
-TEST(FormStructureTest, SourceURL) { |
- FormData form; |
- form.origin = GURL("http://www.foo.com/"); |
- form.method = ASCIIToUTF16("post"); |
- FormStructure form_structure(form, std::string()); |
- |
- EXPECT_EQ(form.origin, form_structure.source_url()); |
-} |
- |
-TEST(FormStructureTest, IsAutofillable) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- |
- // We need at least three text fields to be auto-fillable. |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- // When autocheckout is enabled, we enable autofill even the form has |
- // no fields |
- form_structure.reset(new FormStructure(form, "http://fake_url")); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- field.label = ASCIIToUTF16("username"); |
- field.name = ASCIIToUTF16("username"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("password"); |
- field.name = ASCIIToUTF16("password"); |
- field.form_control_type = "password"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_FALSE(form_structure->IsAutofillable(true)); |
- |
- // We do not limit to three text fields when autocheckout is enabled. |
- form_structure.reset(new FormStructure(form, "http://fake_url")); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- // We now have three text fields, but only two auto-fillable fields. |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("firstname"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("lastname"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_FALSE(form_structure->IsAutofillable(true)); |
- |
- // We now have three auto-fillable fields. |
- field.label = ASCIIToUTF16("Email"); |
- field.name = ASCIIToUTF16("email"); |
- field.form_control_type = "email"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- // The method must be 'post', though we can intentionally ignore this |
- // criterion for the sake of providing a helpful warning message to the user. |
- form.method = ASCIIToUTF16("get"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_FALSE(form_structure->IsAutofillable(true)); |
- EXPECT_TRUE(form_structure->IsAutofillable(false)); |
- |
- // The target cannot include http(s)://*/search... |
- form.method = ASCIIToUTF16("post"); |
- form.action = GURL("http://google.com/search?q=hello"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_FALSE(form_structure->IsAutofillable(true)); |
- |
- // But search can be in the URL. |
- form.action = GURL("http://search.com/?q=hello"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
-} |
- |
-TEST(FormStructureTest, ShouldBeParsed) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- |
- // We need at least three text fields to be parseable. |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.label = ASCIIToUTF16("username"); |
- field.name = ASCIIToUTF16("username"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- FormFieldData checkable_field; |
- checkable_field.is_checkable = true; |
- checkable_field.name = ASCIIToUTF16("radiobtn"); |
- checkable_field.form_control_type = "radio"; |
- form.fields.push_back(checkable_field); |
- |
- checkable_field.name = ASCIIToUTF16("checkbox"); |
- checkable_field.form_control_type = "checkbox"; |
- form.fields.push_back(checkable_field); |
- |
- // We have only one text field, should not be parsed. |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_FALSE(form_structure->ShouldBeParsed(true)); |
- |
- // The form should be parsed for autocheckout even it has less than three |
- // text fields. |
- form_structure.reset(new FormStructure(form, "http://fake_url")); |
- EXPECT_TRUE(form_structure->ShouldBeParsed(true)); |
- |
- // We now have three text fields, though only two are auto-fillable. |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("firstname"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("lastname"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_TRUE(form_structure->ShouldBeParsed(true)); |
- |
- // The method must be 'post', though we can intentionally ignore this |
- // criterion for the sake of providing a helpful warning message to the user. |
- form.method = ASCIIToUTF16("get"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_FALSE(form_structure->IsAutofillable(true)); |
- EXPECT_TRUE(form_structure->ShouldBeParsed(false)); |
- |
- // The target cannot include http(s)://*/search... |
- form.method = ASCIIToUTF16("post"); |
- form.action = GURL("http://google.com/search?q=hello"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_FALSE(form_structure->ShouldBeParsed(true)); |
- |
- // But search can be in the URL. |
- form.action = GURL("http://search.com/?q=hello"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_TRUE(form_structure->ShouldBeParsed(true)); |
- |
- // The form need only have three fields, but at least one must be a text |
- // field. |
- form.fields.clear(); |
- |
- field.label = ASCIIToUTF16("Email"); |
- field.name = ASCIIToUTF16("email"); |
- field.form_control_type = "email"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("State"); |
- field.name = ASCIIToUTF16("state"); |
- field.form_control_type = "select-one"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Country"); |
- field.name = ASCIIToUTF16("country"); |
- field.form_control_type = "select-one"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_TRUE(form_structure->ShouldBeParsed(true)); |
- |
- form.fields[0].form_control_type = "select-one"; |
- // Now, no text fields. |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_FALSE(form_structure->ShouldBeParsed(true)); |
- |
- // It should be parsed when autocheckout is enabled. |
- form_structure.reset(new FormStructure(form, "http://fake_url")); |
- EXPECT_TRUE(form_structure->ShouldBeParsed(true)); |
-} |
- |
-TEST(FormStructureTest, HeuristicsContactInfo) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("firstname"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("lastname"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Email"); |
- field.name = ASCIIToUTF16("email"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Phone"); |
- field.name = ASCIIToUTF16("phone"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("City"); |
- field.name = ASCIIToUTF16("city"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Zip code"); |
- field.name = ASCIIToUTF16("zipcode"); |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- // Expect the correct number of fields. |
- ASSERT_EQ(8U, form_structure->field_count()); |
- ASSERT_EQ(7U, form_structure->autofill_count()); |
- |
- // First name. |
- EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); |
- // Last name. |
- EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); |
- // Email. |
- EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type()); |
- // Phone. |
- EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, |
- form_structure->field(3)->heuristic_type()); |
- // Address. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type()); |
- // City. |
- EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type()); |
- // Zip. |
- EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type()); |
- // Submit. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type()); |
-} |
- |
-// Verify that we can correctly process the |autocomplete| attribute. |
-TEST(FormStructureTest, HeuristicsAutocompleteAttribute) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("field1"); |
- field.autocomplete_attribute = "given-name"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("field2"); |
- field.autocomplete_attribute = "family-name"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("field3"); |
- field.autocomplete_attribute = "email"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- // Expect the correct number of fields. |
- ASSERT_EQ(3U, form_structure->field_count()); |
- ASSERT_EQ(3U, form_structure->autofill_count()); |
- |
- EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); |
- EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); |
- EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type()); |
-} |
- |
-// 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"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("field1"); |
- field.autocomplete_attribute = "tel-local"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("field2"); |
- field.autocomplete_attribute = "tel-local-prefix"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("field3"); |
- field.autocomplete_attribute = "tel-local-suffix"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- // Expect the correct number of fields. |
- ASSERT_EQ(3U, form_structure->field_count()); |
- EXPECT_EQ(3U, form_structure->autofill_count()); |
- |
- EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(0)->heuristic_type()); |
- EXPECT_EQ(AutofillField::IGNORED, form_structure->field(0)->phone_part()); |
- EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(1)->heuristic_type()); |
- EXPECT_EQ(AutofillField::PHONE_PREFIX, |
- form_structure->field(1)->phone_part()); |
- EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(2)->heuristic_type()); |
- EXPECT_EQ(AutofillField::PHONE_SUFFIX, |
- form_structure->field(2)->phone_part()); |
-} |
- |
-// 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"); |
- |
- // Start with a regular contact form. |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("firstname"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("lastname"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Email"); |
- field.name = ASCIIToUTF16("email"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- EXPECT_TRUE(form_structure->ShouldBeCrowdsourced()); |
- |
- ASSERT_EQ(3U, form_structure->field_count()); |
- ASSERT_EQ(3U, form_structure->autofill_count()); |
- |
- EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); |
- 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 'autocomplete' attribute. |
- form.fields.front().autocomplete_attribute = "x-other"; |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_FALSE(form_structure->IsAutofillable(true)); |
- EXPECT_FALSE(form_structure->ShouldBeCrowdsourced()); |
- |
- ASSERT_EQ(3U, form_structure->field_count()); |
- ASSERT_EQ(0U, form_structure->autofill_count()); |
- |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type()); |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type()); |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type()); |
- |
- // When Autocheckout is enabled, we should ignore 'autocomplete' attribute |
- // when deciding to crowdsource. |
- form_structure.reset(new FormStructure(form, "http://fake.url")); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- EXPECT_TRUE(form_structure->ShouldBeCrowdsourced()); |
- |
- ASSERT_EQ(3U, form_structure->field_count()); |
- ASSERT_EQ(0U, form_structure->autofill_count()); |
- |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type()); |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type()); |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type()); |
-} |
- |
-// Verify that we can correctly process sections listed in the |autocomplete| |
-// attribute. |
-TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) { |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- // Some fields will have no section specified. These fall into the default |
- // section. |
- field.autocomplete_attribute = "email"; |
- form.fields.push_back(field); |
- |
- // We allow arbitrary section names. |
- field.autocomplete_attribute = "section-foo email"; |
- form.fields.push_back(field); |
- |
- // "shipping" and "billing" are special section tokens that don't require the |
- // "section-" prefix. |
- field.autocomplete_attribute = "shipping email"; |
- form.fields.push_back(field); |
- field.autocomplete_attribute = "billing email"; |
- form.fields.push_back(field); |
- |
- // "shipping" and "billing" can be combined with other section names. |
- field.autocomplete_attribute = "section-foo shipping email"; |
- form.fields.push_back(field); |
- field.autocomplete_attribute = "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.autocomplete_attribute = "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 = "section--shipping email"; |
- form.fields.push_back(field); |
- |
- // Credit card fields are implicitly in a separate section from other fields. |
- field.autocomplete_attribute = "section-foo cc-number"; |
- form.fields.push_back(field); |
- |
- FormStructure form_structure(form, std::string()); |
- form_structure.DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure.IsAutofillable(true)); |
- |
- // Expect the correct number of fields. |
- 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<std::string> 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 a degenerate section listed in the |
-// |autocomplete| attribute. |
-TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsDegenerate) { |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- // Some fields will have no section specified. These fall into the default |
- // section. |
- field.autocomplete_attribute = "email"; |
- form.fields.push_back(field); |
- |
- // Specifying "section-" is equivalent to not specifying a section. |
- field.autocomplete_attribute = "section- email"; |
- form.fields.push_back(field); |
- |
- // Invalid tokens should prevent us from setting a section name. |
- field.autocomplete_attribute = "garbage section-foo email"; |
- form.fields.push_back(field); |
- field.autocomplete_attribute = "garbage section-bar email"; |
- form.fields.push_back(field); |
- field.autocomplete_attribute = "garbage shipping email"; |
- form.fields.push_back(field); |
- field.autocomplete_attribute = "garbage billing email"; |
- form.fields.push_back(field); |
- |
- FormStructure form_structure(form, std::string()); |
- form_structure.DetermineHeuristicTypes(TestAutofillMetrics()); |
- |
- // Expect the correct number of fields. |
- ASSERT_EQ(6U, 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 |
- // section. |
- std::set<std::string> section_names; |
- for (size_t i = 0; i < 6; ++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 = "text"; |
- |
- field.autocomplete_attribute = "section-foo email"; |
- form.fields.push_back(field); |
- field.autocomplete_attribute = "section-foo street-address"; |
- form.fields.push_back(field); |
- |
- FormStructure form_structure(form, std::string()); |
- form_structure.DetermineHeuristicTypes(TestAutofillMetrics()); |
- |
- // 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 |
- // section. |
- std::set<std::string> 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 = "text"; |
- |
- field.name = ASCIIToUTF16("one"); |
- field.autocomplete_attribute = "street-address"; |
- form.fields.push_back(field); |
- field.name = base::string16(); |
- field.autocomplete_attribute = "section-foo email"; |
- form.fields.push_back(field); |
- field.name = base::string16(); |
- field.autocomplete_attribute = "name"; |
- form.fields.push_back(field); |
- field.name = ASCIIToUTF16("two"); |
- field.autocomplete_attribute = "street-address"; |
- form.fields.push_back(field); |
- |
- FormStructure form_structure(form, std::string()); |
- form_structure.DetermineHeuristicTypes(TestAutofillMetrics()); |
- |
- // 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) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Your First Name:"); |
- field.name = ASCIIToUTF16("bill.first"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Your Last Name:"); |
- field.name = ASCIIToUTF16("bill.last"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Street Address Line 1:"); |
- field.name = ASCIIToUTF16("bill.street1"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Street Address Line 2:"); |
- field.name = ASCIIToUTF16("bill.street2"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("City"); |
- field.name = ASCIIToUTF16("bill.city"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("State (U.S.):"); |
- field.name = ASCIIToUTF16("bill.state"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Zip/Postal Code:"); |
- field.name = ASCIIToUTF16("BillTo.PostalCode"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Country:"); |
- field.name = ASCIIToUTF16("bill.country"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Phone Number:"); |
- field.name = ASCIIToUTF16("BillTo.Phone"); |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(10U, form_structure->field_count()); |
- ASSERT_EQ(9U, form_structure->autofill_count()); |
- |
- // First name. |
- EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); |
- // Last name. |
- EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); |
- // Address. |
- EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(2)->heuristic_type()); |
- // Address. |
- EXPECT_EQ(ADDRESS_BILLING_LINE2, form_structure->field(3)->heuristic_type()); |
- // City. |
- EXPECT_EQ(ADDRESS_BILLING_CITY, form_structure->field(4)->heuristic_type()); |
- // State. |
- EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure->field(5)->heuristic_type()); |
- // Zip. |
- EXPECT_EQ(ADDRESS_BILLING_ZIP, form_structure->field(6)->heuristic_type()); |
- // Country. |
- EXPECT_EQ(ADDRESS_BILLING_COUNTRY, |
- form_structure->field(7)->heuristic_type()); |
- // Phone. |
- EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, |
- form_structure->field(8)->heuristic_type()); |
- // Submit. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, HeuristicsSample6) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("E-mail address"); |
- field.name = ASCIIToUTF16("email"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Full name"); |
- field.name = ASCIIToUTF16("name"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Company"); |
- field.name = ASCIIToUTF16("company"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("City"); |
- field.name = ASCIIToUTF16("city"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Zip Code"); |
- field.name = ASCIIToUTF16("Home.PostalCode"); |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.value = ASCIIToUTF16("continue"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(7U, form_structure->field_count()); |
- ASSERT_EQ(6U, form_structure->autofill_count()); |
- |
- // Email. |
- EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(0)->heuristic_type()); |
- // Full name. |
- EXPECT_EQ(NAME_FULL, form_structure->field(1)->heuristic_type()); |
- // Company |
- EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type()); |
- // Address. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type()); |
- // City. |
- EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type()); |
- // Zip. |
- EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(5)->heuristic_type()); |
- // Submit. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type()); |
-} |
- |
-// Tests a sequence of FormFields where only labels are supplied to heuristics |
-// for matching. This works because FormFieldData labels are matched in the |
-// case that input element ids (or |name| fields) are missing. |
-TEST(FormStructureTest, HeuristicsLabelsOnly) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = base::string16(); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = base::string16(); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Email"); |
- field.name = base::string16(); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Phone"); |
- field.name = base::string16(); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address"); |
- field.name = base::string16(); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address"); |
- field.name = base::string16(); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Zip code"); |
- field.name = base::string16(); |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(8U, form_structure->field_count()); |
- ASSERT_EQ(7U, form_structure->autofill_count()); |
- |
- // First name. |
- EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); |
- // Last name. |
- EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); |
- // Email. |
- EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type()); |
- // Phone. |
- EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, |
- form_structure->field(3)->heuristic_type()); |
- // Address. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type()); |
- // Address Line 2. |
- EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(5)->heuristic_type()); |
- // Zip. |
- EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type()); |
- // Submit. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, HeuristicsCreditCardInfo) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Name on Card"); |
- field.name = ASCIIToUTF16("name_on_card"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Card Number"); |
- field.name = ASCIIToUTF16("card_number"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Exp Month"); |
- field.name = ASCIIToUTF16("ccmonth"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Exp Year"); |
- field.name = ASCIIToUTF16("ccyear"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Verification"); |
- field.name = ASCIIToUTF16("verification"); |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(6U, form_structure->field_count()); |
- ASSERT_EQ(5U, form_structure->autofill_count()); |
- |
- // Credit card name. |
- EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); |
- // Credit card number. |
- EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type()); |
- // Credit card expiration month. |
- EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(2)->heuristic_type()); |
- // Credit card expiration year. |
- EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, |
- form_structure->field(3)->heuristic_type()); |
- // CVV. |
- EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, |
- form_structure->field(4)->heuristic_type()); |
- // Submit. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Name on Card"); |
- field.name = ASCIIToUTF16("name_on_card"); |
- form.fields.push_back(field); |
- |
- // This is not a field we know how to process. But we should skip over it |
- // and process the other fields in the card block. |
- field.label = ASCIIToUTF16("Card image"); |
- field.name = ASCIIToUTF16("card_image"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Card Number"); |
- field.name = ASCIIToUTF16("card_number"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Exp Month"); |
- field.name = ASCIIToUTF16("ccmonth"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Exp Year"); |
- field.name = ASCIIToUTF16("ccyear"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Verification"); |
- field.name = ASCIIToUTF16("verification"); |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(7U, form_structure->field_count()); |
- ASSERT_EQ(5U, form_structure->autofill_count()); |
- |
- // Credit card name. |
- EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); |
- // Credit card type. This is an unknown type but related to the credit card. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type()); |
- // Credit card number. |
- EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type()); |
- // Credit card expiration month. |
- EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type()); |
- // Credit card expiration year. |
- EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, |
- form_structure->field(4)->heuristic_type()); |
- // CVV. |
- EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, |
- form_structure->field(5)->heuristic_type()); |
- // Submit. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, ThreeAddressLines) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Address Line1"); |
- field.name = ASCIIToUTF16("Address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line2"); |
- field.name = ASCIIToUTF16("Address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line3"); |
- field.name = ASCIIToUTF16("Address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("City"); |
- field.name = ASCIIToUTF16("city"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(4U, form_structure->field_count()); |
- ASSERT_EQ(3U, form_structure->autofill_count()); |
- |
- // Address Line 1. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type()); |
- // Address Line 2. |
- EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type()); |
- // Address Line 3. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type()); |
- // City. |
- EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type()); |
-} |
- |
-// This test verifies that "addressLine1" and "addressLine2" matches heuristics. |
-// This occured in https://www.gorillaclothing.com/. http://crbug.com/52126. |
-TEST(FormStructureTest, BillingAndShippingAddresses) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Address Line1"); |
- field.name = ASCIIToUTF16("shipping.address.addressLine1"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line2"); |
- field.name = ASCIIToUTF16("shipping.address.addressLine2"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line1"); |
- field.name = ASCIIToUTF16("billing.address.addressLine1"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line2"); |
- field.name = ASCIIToUTF16("billing.address.addressLine2"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(4U, form_structure->field_count()); |
- ASSERT_EQ(4U, form_structure->autofill_count()); |
- |
- // Address Line 1. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type()); |
- // Address Line 2. |
- EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type()); |
- // Address Line 1. |
- EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(2)->heuristic_type()); |
- // Address Line 2. |
- EXPECT_EQ(ADDRESS_BILLING_LINE2, form_structure->field(3)->heuristic_type()); |
-} |
- |
-// Numbered address lines after line two are ignored. |
-TEST(FormStructureTest, SurplusAddressLinesIgnored) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Address Line1"); |
- field.name = ASCIIToUTF16("shipping.address.addressLine1"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line2"); |
- field.name = ASCIIToUTF16("shipping.address.addressLine2"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line3"); |
- field.name = ASCIIToUTF16("billing.address.addressLine3"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line4"); |
- field.name = ASCIIToUTF16("billing.address.addressLine4"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- ASSERT_EQ(4U, form_structure->field_count()); |
- ASSERT_EQ(2U, form_structure->autofill_count()); |
- |
- // Address Line 1. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type()); |
- // Address Line 2. |
- EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type()); |
- // Address Line 3 (ignored). |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type()); |
- // Address Line 4 (ignored). |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type()); |
-} |
- |
-// This example comes from expedia.com where they use a "Suite" label to |
-// indicate a suite or apartment number. We interpret this as address line 2. |
-// And the following "Street address second line" we interpret as address line |
-// 3 and discard. |
-// See http://crbug.com/48197 for details. |
-TEST(FormStructureTest, ThreeAddressLinesExpedia) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Street:"); |
- field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Suite or Apt:"); |
- field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Street address second line"); |
- field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads2"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("City:"); |
- field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adct"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(4U, form_structure->field_count()); |
- EXPECT_EQ(3U, form_structure->autofill_count()); |
- |
- // Address Line 1. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type()); |
- // Suite / Apt. |
- EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type()); |
- // Address Line 3. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type()); |
- // City. |
- EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type()); |
-} |
- |
-// This example comes from ebay.com where the word "suite" appears in the label |
-// and the name "address2" clearly indicates that this is the address line 2. |
-// See http://crbug.com/48197 for details. |
-TEST(FormStructureTest, TwoAddressLinesEbay) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Address Line1"); |
- field.name = ASCIIToUTF16("address1"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Floor number, suite number, etc"); |
- field.name = ASCIIToUTF16("address2"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("City:"); |
- field.name = ASCIIToUTF16("city"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(3U, form_structure->field_count()); |
- ASSERT_EQ(3U, form_structure->autofill_count()); |
- |
- // Address Line 1. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type()); |
- // Address Line 2. |
- EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type()); |
- // City. |
- EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(2)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, HeuristicsStateWithProvince) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Address Line1"); |
- field.name = ASCIIToUTF16("Address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address Line2"); |
- field.name = ASCIIToUTF16("Address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("State/Province/Region"); |
- field.name = ASCIIToUTF16("State"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(3U, form_structure->field_count()); |
- ASSERT_EQ(3U, form_structure->autofill_count()); |
- |
- // Address Line 1. |
- EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type()); |
- // Address Line 2. |
- EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type()); |
- // State. |
- EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(2)->heuristic_type()); |
-} |
- |
-// This example comes from lego.com's checkout page. |
-TEST(FormStructureTest, HeuristicsWithBilling) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("First Name*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$firstNameBox"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last Name*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$lastNameBox"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Company Name:"); |
- field.name = ASCIIToUTF16("editBillingAddress$companyBox"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$addressLine1Box"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Apt/Suite :"); |
- field.name = ASCIIToUTF16("editBillingAddress$addressLine2Box"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("City*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$cityBox"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("State/Province*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$stateDropDown"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Country*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$countryDropDown"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Postal Code*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$zipCodeBox"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Phone*:"); |
- field.name = ASCIIToUTF16("editBillingAddress$phoneBox"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Email Address*:"); |
- field.name = ASCIIToUTF16("email$emailBox"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(11U, form_structure->field_count()); |
- ASSERT_EQ(11U, form_structure->autofill_count()); |
- |
- EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); |
- EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); |
- EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type()); |
- EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(3)->heuristic_type()); |
- EXPECT_EQ(ADDRESS_BILLING_LINE2, form_structure->field(4)->heuristic_type()); |
- EXPECT_EQ(ADDRESS_BILLING_CITY, form_structure->field(5)->heuristic_type()); |
- EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure->field(6)->heuristic_type()); |
- EXPECT_EQ(ADDRESS_BILLING_COUNTRY, |
- form_structure->field(7)->heuristic_type()); |
- EXPECT_EQ(ADDRESS_BILLING_ZIP, form_structure->field(8)->heuristic_type()); |
- EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, |
- form_structure->field(9)->heuristic_type()); |
- EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(10)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, ThreePartPhoneNumber) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Phone:"); |
- field.name = ASCIIToUTF16("dayphone1"); |
- field.max_length = 0; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("-"); |
- field.name = ASCIIToUTF16("dayphone2"); |
- field.max_length = 3; // Size of prefix is 3. |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("-"); |
- field.name = ASCIIToUTF16("dayphone3"); |
- field.max_length = 4; // Size of suffix is 4. If unlimited size is |
- // passed, phone will be parsed as |
- // <country code> - <area code> - <phone>. |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("ext.:"); |
- field.name = ASCIIToUTF16("dayphone4"); |
- field.max_length = 0; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- ASSERT_EQ(4U, form_structure->field_count()); |
- ASSERT_EQ(3U, form_structure->autofill_count()); |
- |
- // Area code. |
- EXPECT_EQ(PHONE_HOME_CITY_CODE, form_structure->field(0)->heuristic_type()); |
- // Phone number suffix. |
- EXPECT_EQ(PHONE_HOME_NUMBER, |
- form_structure->field(1)->heuristic_type()); |
- // Phone number suffix. |
- EXPECT_EQ(PHONE_HOME_NUMBER, |
- form_structure->field(2)->heuristic_type()); |
- // Unknown. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, HeuristicsInfernoCC) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Name on Card"); |
- field.name = ASCIIToUTF16("name_on_card"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("billing_address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Card Number"); |
- field.name = ASCIIToUTF16("card_number"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Expiration Date"); |
- field.name = ASCIIToUTF16("expiration_month"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Expiration Year"); |
- field.name = ASCIIToUTF16("expiration_year"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- // Expect the correct number of fields. |
- ASSERT_EQ(5U, form_structure->field_count()); |
- EXPECT_EQ(5U, form_structure->autofill_count()); |
- |
- // Name on Card. |
- EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); |
- // Address. |
- EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(1)->heuristic_type()); |
- // Card Number. |
- EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type()); |
- // Expiration Date. |
- EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type()); |
- // Expiration Year. |
- EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, |
- form_structure->field(4)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, CVCCodeClash) { |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Card number"); |
- field.name = ASCIIToUTF16("ccnumber"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("First name"); |
- field.name = ASCIIToUTF16("first_name"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last name"); |
- field.name = ASCIIToUTF16("last_name"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Expiration date"); |
- field.name = ASCIIToUTF16("ccexpiresmonth"); |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("ccexpiresyear"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("cvc number"); |
- field.name = ASCIIToUTF16("csc"); |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- EXPECT_TRUE(form_structure->IsAutofillable(true)); |
- |
- // Expect the correct number of fields. |
- ASSERT_EQ(6U, form_structure->field_count()); |
- ASSERT_EQ(5U, form_structure->autofill_count()); |
- |
- // Card Number. |
- EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(0)->heuristic_type()); |
- // First name, taken as name on card. |
- EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(1)->heuristic_type()); |
- // Last name is not merged. |
- EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type()); |
- // Expiration Date. |
- EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type()); |
- // Expiration Year. |
- EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, |
- form_structure->field(4)->heuristic_type()); |
- // CVC code. |
- EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE, |
- form_structure->field(5)->heuristic_type()); |
-} |
- |
-TEST(FormStructureTest, EncodeQueryRequest) { |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("Name on Card"); |
- field.name = ASCIIToUTF16("name_on_card"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("billing_address"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Card Number"); |
- field.name = ASCIIToUTF16("card_number"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Expiration Date"); |
- field.name = ASCIIToUTF16("expiration_month"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Expiration Year"); |
- field.name = ASCIIToUTF16("expiration_year"); |
- form.fields.push_back(field); |
- |
- // Add checkable field. |
- FormFieldData checkable_field; |
- checkable_field.is_checkable = true; |
- checkable_field.label = ASCIIToUTF16("Checkable1"); |
- checkable_field.name = ASCIIToUTF16("Checkable1"); |
- form.fields.push_back(checkable_field); |
- |
- ScopedVector<FormStructure> forms; |
- forms.push_back(new FormStructure(form, std::string())); |
- std::vector<std::string> encoded_signatures; |
- std::string encoded_xml; |
- const char * const kSignature1 = "11337937696949187602"; |
- const char * const kResponse1 = |
- "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery " |
- "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form " |
- "signature=\"11337937696949187602\"><field signature=\"412125936\"/>" |
- "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>" |
- "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>" |
- "</autofillquery>"; |
- ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), |
- &encoded_signatures, |
- &encoded_xml)); |
- ASSERT_EQ(1U, encoded_signatures.size()); |
- EXPECT_EQ(kSignature1, encoded_signatures[0]); |
- EXPECT_EQ(kResponse1, encoded_xml); |
- |
- // Add the same form, only one will be encoded, so EncodeQueryRequest() should |
- // return the same data. |
- forms.push_back(new FormStructure(form, std::string())); |
- ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), |
- &encoded_signatures, |
- &encoded_xml)); |
- ASSERT_EQ(1U, encoded_signatures.size()); |
- EXPECT_EQ(kSignature1, encoded_signatures[0]); |
- EXPECT_EQ(kResponse1, encoded_xml); |
- // Add 5 address fields - this should be still a valid form. |
- for (size_t i = 0; i < 5; ++i) { |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- form.fields.push_back(field); |
- } |
- |
- forms.push_back(new FormStructure(form, std::string())); |
- ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), |
- &encoded_signatures, |
- &encoded_xml)); |
- ASSERT_EQ(2U, encoded_signatures.size()); |
- EXPECT_EQ(kSignature1, encoded_signatures[0]); |
- const char * const kSignature2 = "8308881815906226214"; |
- EXPECT_EQ(kSignature2, encoded_signatures[1]); |
- const char * const kResponse2 = |
- "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery " |
- "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form " |
- "signature=\"11337937696949187602\"><field signature=\"412125936\"/>" |
- "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>" |
- "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>" |
- "<form signature=\"8308881815906226214\"><field signature=\"412125936\"/>" |
- "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>" |
- "<field signature=\"747221617\"/><field signature=\"4108155786\"/><field " |
- "signature=\"509334676\"/><field signature=\"509334676\"/><field " |
- "signature=\"509334676\"/><field signature=\"509334676\"/><field " |
- "signature=\"509334676\"/></form></autofillquery>"; |
- EXPECT_EQ(kResponse2, encoded_xml); |
- |
- FormData malformed_form(form); |
- // Add 50 address fields - the form is not valid anymore, but previous ones |
- // are. The result should be the same as in previous test. |
- for (size_t i = 0; i < 50; ++i) { |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- malformed_form.fields.push_back(field); |
- } |
- |
- forms.push_back(new FormStructure(malformed_form, std::string())); |
- ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), |
- &encoded_signatures, |
- &encoded_xml)); |
- ASSERT_EQ(2U, encoded_signatures.size()); |
- EXPECT_EQ(kSignature1, encoded_signatures[0]); |
- EXPECT_EQ(kSignature2, encoded_signatures[1]); |
- EXPECT_EQ(kResponse2, encoded_xml); |
- |
- // Check that we fail if there are only bad form(s). |
- ScopedVector<FormStructure> bad_forms; |
- bad_forms.push_back(new FormStructure(malformed_form, std::string())); |
- EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms.get(), |
- &encoded_signatures, |
- &encoded_xml)); |
- EXPECT_EQ(0U, encoded_signatures.size()); |
- EXPECT_EQ("", encoded_xml); |
- |
- // Check the behaviour with autocheckout enabled. |
- ScopedVector<FormStructure> checkable_forms; |
- checkable_forms.push_back( |
- new FormStructure(form, "https://www.sample1.com/query/path")); |
- |
- ASSERT_TRUE(FormStructure::EncodeQueryRequest(checkable_forms.get(), |
- &encoded_signatures, |
- &encoded_xml)); |
- const char * const kSignature3 = "7747357776717901584"; |
- const char * const kResponse3 = |
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?><autofillquery " |
- "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"a,e\" " |
- "urlprefixsignature=\"7648393911063090788\">" |
- "<form signature=\"7747357776717901584\">" |
- "<field signature=\"412125936\"/>" |
- "<field signature=\"1917667676\"/><field signature=\"2226358947\"/><field" |
- " signature=\"747221617\"/><field signature=\"4108155786\"/><field " |
- "signature=\"3410250678\"/><field signature=\"509334676\"/><field " |
- "signature=\"509334676\"/><field signature=\"509334676\"/><field " |
- "signature=\"509334676\"/><field signature=\"509334676\"/></form>" |
- "</autofillquery>"; |
- ASSERT_EQ(1U, encoded_signatures.size()); |
- EXPECT_EQ(kSignature3, encoded_signatures[0]); |
- EXPECT_EQ(kResponse3, encoded_xml); |
-} |
- |
-TEST(FormStructureTest, EncodeUploadRequest) { |
- scoped_ptr<FormStructure> form_structure; |
- std::vector<FieldTypeSet> possible_field_types; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("firstname"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(NAME_FIRST); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("lastname"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(NAME_LAST); |
- |
- field.label = ASCIIToUTF16("Email"); |
- field.name = ASCIIToUTF16("email"); |
- field.form_control_type = "email"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(EMAIL_ADDRESS); |
- |
- field.label = ASCIIToUTF16("Phone"); |
- field.name = ASCIIToUTF16("phone"); |
- field.form_control_type = "number"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER); |
- |
- field.label = ASCIIToUTF16("Country"); |
- field.name = ASCIIToUTF16("country"); |
- field.form_control_type = "select-one"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_COUNTRY); |
- |
- // Add checkable field. |
- FormFieldData checkable_field; |
- checkable_field.is_checkable = true; |
- checkable_field.label = ASCIIToUTF16("Checkable1"); |
- checkable_field.name = ASCIIToUTF16("Checkable1"); |
- form.fields.push_back(checkable_field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_COUNTRY); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- |
- ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); |
- for (size_t i = 0; i < form_structure->field_count(); ++i) |
- form_structure->field(i)->set_possible_types(possible_field_types[i]); |
- |
- FieldTypeSet available_field_types; |
- available_field_types.insert(NAME_FIRST); |
- available_field_types.insert(NAME_LAST); |
- available_field_types.insert(ADDRESS_HOME_LINE1); |
- available_field_types.insert(ADDRESS_HOME_LINE2); |
- available_field_types.insert(ADDRESS_HOME_COUNTRY); |
- available_field_types.insert(ADDRESS_BILLING_LINE1); |
- available_field_types.insert(ADDRESS_BILLING_LINE2); |
- available_field_types.insert(EMAIL_ADDRESS); |
- available_field_types.insert(PHONE_HOME_WHOLE_NUMBER); |
- |
- std::string encoded_xml; |
- EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" " |
- "formsignature=\"8736493185895608956\" autofillused=\"false\" " |
- "datapresent=\"144200030e\">" |
- "<field signature=\"3763331450\" autofilltype=\"3\"/>" |
- "<field signature=\"3494530716\" autofilltype=\"5\"/>" |
- "<field signature=\"1029417091\" autofilltype=\"9\"/>" |
- "<field signature=\"466116101\" autofilltype=\"14\"/>" |
- "<field signature=\"2799270304\" autofilltype=\"36\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" " |
- "formsignature=\"8736493185895608956\" autofillused=\"true\" " |
- "datapresent=\"144200030e\">" |
- "<field signature=\"3763331450\" autofilltype=\"3\"/>" |
- "<field signature=\"3494530716\" autofilltype=\"5\"/>" |
- "<field signature=\"1029417091\" autofilltype=\"9\"/>" |
- "<field signature=\"466116101\" autofilltype=\"14\"/>" |
- "<field signature=\"2799270304\" autofilltype=\"36\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- |
- // Add 2 address fields - this should be still a valid form. |
- for (size_t i = 0; i < 2; ++i) { |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_LINE1); |
- possible_field_types.back().insert(ADDRESS_HOME_LINE2); |
- possible_field_types.back().insert(ADDRESS_BILLING_LINE1); |
- possible_field_types.back().insert(ADDRESS_BILLING_LINE2); |
- } |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); |
- for (size_t i = 0; i < form_structure->field_count(); ++i) |
- form_structure->field(i)->set_possible_types(possible_field_types[i]); |
- |
- EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" " |
- "formsignature=\"7816485729218079147\" autofillused=\"false\" " |
- "datapresent=\"144200030e\">" |
- "<field signature=\"3763331450\" autofilltype=\"3\"/>" |
- "<field signature=\"3494530716\" autofilltype=\"5\"/>" |
- "<field signature=\"1029417091\" autofilltype=\"9\"/>" |
- "<field signature=\"466116101\" autofilltype=\"14\"/>" |
- "<field signature=\"2799270304\" autofilltype=\"36\"/>" |
- "<field signature=\"509334676\" autofilltype=\"30\"/>" |
- "<field signature=\"509334676\" autofilltype=\"31\"/>" |
- "<field signature=\"509334676\" autofilltype=\"37\"/>" |
- "<field signature=\"509334676\" autofilltype=\"38\"/>" |
- "<field signature=\"509334676\" autofilltype=\"30\"/>" |
- "<field signature=\"509334676\" autofilltype=\"31\"/>" |
- "<field signature=\"509334676\" autofilltype=\"37\"/>" |
- "<field signature=\"509334676\" autofilltype=\"38\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- |
- // Add 50 address fields - now the form is invalid, as it has too many fields. |
- for (size_t i = 0; i < 50; ++i) { |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_LINE1); |
- possible_field_types.back().insert(ADDRESS_HOME_LINE2); |
- possible_field_types.back().insert(ADDRESS_BILLING_LINE1); |
- possible_field_types.back().insert(ADDRESS_BILLING_LINE2); |
- } |
- form_structure.reset(new FormStructure(form, std::string())); |
- ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); |
- for (size_t i = 0; i < form_structure->field_count(); ++i) |
- form_structure->field(i)->set_possible_types(possible_field_types[i]); |
- EXPECT_FALSE(form_structure->EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
-} |
- |
-TEST(FormStructureTest, EncodeFieldAssignments) { |
- scoped_ptr<FormStructure> form_structure; |
- std::vector<FieldTypeSet> possible_field_types; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- form_structure->DetermineHeuristicTypes(TestAutofillMetrics()); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("firstname"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(NAME_FIRST); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("lastname"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(NAME_LAST); |
- |
- field.label = ASCIIToUTF16("Email"); |
- field.name = ASCIIToUTF16("email"); |
- field.form_control_type = "email"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(EMAIL_ADDRESS); |
- |
- field.label = ASCIIToUTF16("Phone"); |
- field.name = ASCIIToUTF16("phone"); |
- field.form_control_type = "number"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER); |
- |
- field.label = ASCIIToUTF16("Country"); |
- field.name = ASCIIToUTF16("country"); |
- field.form_control_type = "select-one"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_COUNTRY); |
- |
- // Add checkable field. |
- FormFieldData checkable_field; |
- checkable_field.is_checkable = true; |
- checkable_field.label = ASCIIToUTF16("Checkable1"); |
- checkable_field.name = ASCIIToUTF16("Checkable1"); |
- form.fields.push_back(checkable_field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_COUNTRY); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- |
- ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); |
- for (size_t i = 0; i < form_structure->field_count(); ++i) |
- form_structure->field(i)->set_possible_types(possible_field_types[i]); |
- |
- FieldTypeSet available_field_types; |
- available_field_types.insert(NAME_FIRST); |
- available_field_types.insert(NAME_LAST); |
- available_field_types.insert(ADDRESS_HOME_LINE1); |
- available_field_types.insert(ADDRESS_HOME_LINE2); |
- available_field_types.insert(ADDRESS_HOME_COUNTRY); |
- available_field_types.insert(ADDRESS_BILLING_LINE1); |
- available_field_types.insert(ADDRESS_BILLING_LINE2); |
- available_field_types.insert(EMAIL_ADDRESS); |
- available_field_types.insert(PHONE_HOME_WHOLE_NUMBER); |
- |
- std::string encoded_xml; |
- EXPECT_TRUE(form_structure->EncodeFieldAssignments( |
- available_field_types, &encoded_xml)); |
- EXPECT_EQ( |
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" |
- "<fieldassignments formsignature=\"8736493185895608956\">" |
- "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>" |
- "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>" |
- "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>" |
- "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>" |
- "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>" |
- "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>" |
- "</fieldassignments>", |
- encoded_xml); |
- |
- // Add 2 address fields - this should be still a valid form. |
- for (size_t i = 0; i < 2; ++i) { |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_LINE1); |
- possible_field_types.back().insert(ADDRESS_HOME_LINE2); |
- possible_field_types.back().insert(ADDRESS_BILLING_LINE1); |
- possible_field_types.back().insert(ADDRESS_BILLING_LINE2); |
- } |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); |
- for (size_t i = 0; i < form_structure->field_count(); ++i) |
- form_structure->field(i)->set_possible_types(possible_field_types[i]); |
- |
- EXPECT_TRUE(form_structure->EncodeFieldAssignments( |
- available_field_types, &encoded_xml)); |
- EXPECT_EQ( |
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" |
- "<fieldassignments formsignature=\"7816485729218079147\">" |
- "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>" |
- "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>" |
- "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>" |
- "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>" |
- "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>" |
- "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>" |
- "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>" |
- "</fieldassignments>", |
- encoded_xml); |
-} |
- |
-// Check that we compute the "datapresent" string correctly for the given |
-// |available_types|. |
-TEST(FormStructureTest, CheckDataPresence) { |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("first"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("last"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("Email"); |
- field.name = ASCIIToUTF16("email"); |
- form.fields.push_back(field); |
- |
- FormStructure form_structure(form, std::string()); |
- |
- FieldTypeSet unknown_type; |
- unknown_type.insert(UNKNOWN_TYPE); |
- for (size_t i = 0; i < form_structure.field_count(); ++i) |
- form_structure.field(i)->set_possible_types(unknown_type); |
- |
- // No available types. |
- // datapresent should be "" == trimmmed(0x0000000000000000) == |
- // 0b0000000000000000000000000000000000000000000000000000000000000000 |
- FieldTypeSet available_field_types; |
- |
- std::string encoded_xml; |
- EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"6402244543831589061\" autofillused=\"false\"" |
- " datapresent=\"\">" |
- "<field signature=\"1089846351\" autofilltype=\"1\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"1\"/>" |
- "<field signature=\"420638584\" autofilltype=\"1\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- |
- // Only a few types available. |
- // datapresent should be "1540000240" == trimmmed(0x1540000240000000) == |
- // 0b0001010101000000000000000000001001000000000000000000000000000000 |
- // The set bits are: |
- // 3 == NAME_FIRST |
- // 5 == NAME_LAST |
- // 7 == NAME_FULL |
- // 9 == EMAIL_ADDRESS |
- // 30 == ADDRESS_HOME_LINE1 |
- // 33 == ADDRESS_HOME_CITY |
- available_field_types.clear(); |
- available_field_types.insert(NAME_FIRST); |
- available_field_types.insert(NAME_LAST); |
- available_field_types.insert(NAME_FULL); |
- available_field_types.insert(EMAIL_ADDRESS); |
- available_field_types.insert(ADDRESS_HOME_LINE1); |
- available_field_types.insert(ADDRESS_HOME_CITY); |
- |
- EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"6402244543831589061\" autofillused=\"false\"" |
- " datapresent=\"1540000240\">" |
- "<field signature=\"1089846351\" autofilltype=\"1\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"1\"/>" |
- "<field signature=\"420638584\" autofilltype=\"1\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- |
- // All supported non-credit card types available. |
- // datapresent should be "1f7e000378000008" == trimmmed(0x1f7e000378000008) == |
- // 0b0001111101111110000000000000001101111000000000000000000000001000 |
- // The set bits are: |
- // 3 == NAME_FIRST |
- // 4 == NAME_MIDDLE |
- // 5 == NAME_LAST |
- // 6 == NAME_MIDDLE_INITIAL |
- // 7 == NAME_FULL |
- // 9 == EMAIL_ADDRESS |
- // 10 == PHONE_HOME_NUMBER, |
- // 11 == PHONE_HOME_CITY_CODE, |
- // 12 == PHONE_HOME_COUNTRY_CODE, |
- // 13 == PHONE_HOME_CITY_AND_NUMBER, |
- // 14 == PHONE_HOME_WHOLE_NUMBER, |
- // 30 == ADDRESS_HOME_LINE1 |
- // 31 == ADDRESS_HOME_LINE2 |
- // 33 == ADDRESS_HOME_CITY |
- // 34 == ADDRESS_HOME_STATE |
- // 35 == ADDRESS_HOME_ZIP |
- // 36 == ADDRESS_HOME_COUNTRY |
- // 60 == COMPANY_NAME |
- available_field_types.clear(); |
- available_field_types.insert(NAME_FIRST); |
- available_field_types.insert(NAME_MIDDLE); |
- available_field_types.insert(NAME_LAST); |
- available_field_types.insert(NAME_MIDDLE_INITIAL); |
- available_field_types.insert(NAME_FULL); |
- available_field_types.insert(EMAIL_ADDRESS); |
- available_field_types.insert(PHONE_HOME_NUMBER); |
- available_field_types.insert(PHONE_HOME_CITY_CODE); |
- available_field_types.insert(PHONE_HOME_COUNTRY_CODE); |
- available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER); |
- available_field_types.insert(PHONE_HOME_WHOLE_NUMBER); |
- available_field_types.insert(ADDRESS_HOME_LINE1); |
- available_field_types.insert(ADDRESS_HOME_LINE2); |
- available_field_types.insert(ADDRESS_HOME_CITY); |
- available_field_types.insert(ADDRESS_HOME_STATE); |
- available_field_types.insert(ADDRESS_HOME_ZIP); |
- available_field_types.insert(ADDRESS_HOME_COUNTRY); |
- available_field_types.insert(COMPANY_NAME); |
- |
- EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"6402244543831589061\" autofillused=\"false\"" |
- " datapresent=\"1f7e000378000008\">" |
- "<field signature=\"1089846351\" autofilltype=\"1\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"1\"/>" |
- "<field signature=\"420638584\" autofilltype=\"1\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- |
- // All supported credit card types available. |
- // datapresent should be "0000000000001fc0" == trimmmed(0x0000000000001fc0) == |
- // 0b0000000000000000000000000000000000000000000000000001111111000000 |
- // The set bits are: |
- // 51 == CREDIT_CARD_NAME |
- // 52 == CREDIT_CARD_NUMBER |
- // 53 == CREDIT_CARD_EXP_MONTH |
- // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR |
- // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR |
- // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR |
- // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR |
- available_field_types.clear(); |
- available_field_types.insert(CREDIT_CARD_NAME); |
- available_field_types.insert(CREDIT_CARD_NUMBER); |
- available_field_types.insert(CREDIT_CARD_EXP_MONTH); |
- available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
- available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR); |
- available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR); |
- available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR); |
- |
- EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"6402244543831589061\" autofillused=\"false\"" |
- " datapresent=\"0000000000001fc0\">" |
- "<field signature=\"1089846351\" autofilltype=\"1\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"1\"/>" |
- "<field signature=\"420638584\" autofilltype=\"1\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- |
- // All supported types available. |
- // datapresent should be "1f7e000378001fc8" == trimmmed(0x1f7e000378001fc8) == |
- // 0b0001111101111110000000000000001101111000000000000001111111001000 |
- // The set bits are: |
- // 3 == NAME_FIRST |
- // 4 == NAME_MIDDLE |
- // 5 == NAME_LAST |
- // 6 == NAME_MIDDLE_INITIAL |
- // 7 == NAME_FULL |
- // 9 == EMAIL_ADDRESS |
- // 10 == PHONE_HOME_NUMBER, |
- // 11 == PHONE_HOME_CITY_CODE, |
- // 12 == PHONE_HOME_COUNTRY_CODE, |
- // 13 == PHONE_HOME_CITY_AND_NUMBER, |
- // 14 == PHONE_HOME_WHOLE_NUMBER, |
- // 30 == ADDRESS_HOME_LINE1 |
- // 31 == ADDRESS_HOME_LINE2 |
- // 33 == ADDRESS_HOME_CITY |
- // 34 == ADDRESS_HOME_STATE |
- // 35 == ADDRESS_HOME_ZIP |
- // 36 == ADDRESS_HOME_COUNTRY |
- // 51 == CREDIT_CARD_NAME |
- // 52 == CREDIT_CARD_NUMBER |
- // 53 == CREDIT_CARD_EXP_MONTH |
- // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR |
- // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR |
- // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR |
- // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR |
- // 60 == COMPANY_NAME |
- available_field_types.clear(); |
- available_field_types.insert(NAME_FIRST); |
- available_field_types.insert(NAME_MIDDLE); |
- available_field_types.insert(NAME_LAST); |
- available_field_types.insert(NAME_MIDDLE_INITIAL); |
- available_field_types.insert(NAME_FULL); |
- available_field_types.insert(EMAIL_ADDRESS); |
- available_field_types.insert(PHONE_HOME_NUMBER); |
- available_field_types.insert(PHONE_HOME_CITY_CODE); |
- available_field_types.insert(PHONE_HOME_COUNTRY_CODE); |
- available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER); |
- available_field_types.insert(PHONE_HOME_WHOLE_NUMBER); |
- available_field_types.insert(ADDRESS_HOME_LINE1); |
- available_field_types.insert(ADDRESS_HOME_LINE2); |
- available_field_types.insert(ADDRESS_HOME_CITY); |
- available_field_types.insert(ADDRESS_HOME_STATE); |
- available_field_types.insert(ADDRESS_HOME_ZIP); |
- available_field_types.insert(ADDRESS_HOME_COUNTRY); |
- available_field_types.insert(CREDIT_CARD_NAME); |
- available_field_types.insert(CREDIT_CARD_NUMBER); |
- available_field_types.insert(CREDIT_CARD_EXP_MONTH); |
- available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
- available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR); |
- available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR); |
- available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR); |
- available_field_types.insert(COMPANY_NAME); |
- |
- EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"6402244543831589061\" autofillused=\"false\"" |
- " datapresent=\"1f7e000378001fc8\">" |
- "<field signature=\"1089846351\" autofilltype=\"1\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"1\"/>" |
- "<field signature=\"420638584\" autofilltype=\"1\"/>" |
- "</autofillupload>", |
- encoded_xml); |
-} |
- |
-TEST(FormStructureTest, CheckMultipleTypes) { |
- // Throughout this test, datapresent should be |
- // 0x1440000360000008 == |
- // 0b0001010001000000000000000000001101100000000000000000000000001000 |
- // The set bits are: |
- // 3 == NAME_FIRST |
- // 5 == NAME_LAST |
- // 9 == EMAIL_ADDRESS |
- // 30 == ADDRESS_HOME_LINE1 |
- // 31 == ADDRESS_HOME_LINE2 |
- // 33 == ADDRESS_HOME_CITY |
- // 34 == ADDRESS_HOME_STATE |
- // 60 == COMPANY_NAME |
- FieldTypeSet available_field_types; |
- available_field_types.insert(NAME_FIRST); |
- available_field_types.insert(NAME_LAST); |
- available_field_types.insert(EMAIL_ADDRESS); |
- available_field_types.insert(ADDRESS_HOME_LINE1); |
- available_field_types.insert(ADDRESS_HOME_LINE2); |
- available_field_types.insert(ADDRESS_HOME_CITY); |
- available_field_types.insert(ADDRESS_HOME_STATE); |
- available_field_types.insert(COMPANY_NAME); |
- |
- // Check that multiple types for the field are processed correctly. |
- scoped_ptr<FormStructure> form_structure; |
- std::vector<FieldTypeSet> possible_field_types; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("email"); |
- field.name = ASCIIToUTF16("email"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(EMAIL_ADDRESS); |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("first"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(NAME_FIRST); |
- |
- field.label = ASCIIToUTF16("Last Name"); |
- field.name = ASCIIToUTF16("last"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(NAME_LAST); |
- |
- field.label = ASCIIToUTF16("Address"); |
- field.name = ASCIIToUTF16("address"); |
- form.fields.push_back(field); |
- possible_field_types.push_back(FieldTypeSet()); |
- possible_field_types.back().insert(ADDRESS_HOME_LINE1); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- |
- for (size_t i = 0; i < form_structure->field_count(); ++i) |
- form_structure->field(i)->set_possible_types(possible_field_types[i]); |
- std::string encoded_xml; |
- |
- // Now we matched both fields singularly. |
- EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"18062476096658145866\" autofillused=\"false\"" |
- " datapresent=\"1440000360000008\">" |
- "<field signature=\"420638584\" autofilltype=\"9\"/>" |
- "<field signature=\"1089846351\" autofilltype=\"3\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"5\"/>" |
- "<field signature=\"509334676\" autofilltype=\"30\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- // Match third field as both first and last. |
- possible_field_types[2].insert(NAME_FIRST); |
- form_structure->field(2)->set_possible_types(possible_field_types[2]); |
- EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"18062476096658145866\" autofillused=\"false\"" |
- " datapresent=\"1440000360000008\">" |
- "<field signature=\"420638584\" autofilltype=\"9\"/>" |
- "<field signature=\"1089846351\" autofilltype=\"3\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"3\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"5\"/>" |
- "<field signature=\"509334676\" autofilltype=\"30\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- possible_field_types[3].insert(ADDRESS_HOME_LINE2); |
- form_structure->field(form_structure->field_count() - 1)->set_possible_types( |
- possible_field_types[form_structure->field_count() - 1]); |
- EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"18062476096658145866\" autofillused=\"false\"" |
- " datapresent=\"1440000360000008\">" |
- "<field signature=\"420638584\" autofilltype=\"9\"/>" |
- "<field signature=\"1089846351\" autofilltype=\"3\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"3\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"5\"/>" |
- "<field signature=\"509334676\" autofilltype=\"30\"/>" |
- "<field signature=\"509334676\" autofilltype=\"31\"/>" |
- "</autofillupload>", |
- encoded_xml); |
- possible_field_types[3].clear(); |
- possible_field_types[3].insert(ADDRESS_HOME_LINE1); |
- possible_field_types[3].insert(COMPANY_NAME); |
- form_structure->field(form_structure->field_count() - 1)->set_possible_types( |
- possible_field_types[form_structure->field_count() - 1]); |
- EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false, |
- &encoded_xml)); |
- EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>" |
- "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\"" |
- " formsignature=\"18062476096658145866\" autofillused=\"false\"" |
- " datapresent=\"1440000360000008\">" |
- "<field signature=\"420638584\" autofilltype=\"9\"/>" |
- "<field signature=\"1089846351\" autofilltype=\"3\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"3\"/>" |
- "<field signature=\"2404144663\" autofilltype=\"5\"/>" |
- "<field signature=\"509334676\" autofilltype=\"30\"/>" |
- "<field signature=\"509334676\" autofilltype=\"60\"/>" |
- "</autofillupload>", |
- encoded_xml); |
-} |
- |
-TEST(FormStructureTest, CheckFormSignature) { |
- // Check that form signature is created correctly. |
- scoped_ptr<FormStructure> form_structure; |
- FormData form; |
- form.method = ASCIIToUTF16("post"); |
- |
- FormFieldData field; |
- field.form_control_type = "text"; |
- |
- field.label = ASCIIToUTF16("email"); |
- field.name = ASCIIToUTF16("email"); |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("First Name"); |
- field.name = ASCIIToUTF16("first"); |
- form.fields.push_back(field); |
- |
- // Password fields shouldn't affect the signature. |
- field.label = ASCIIToUTF16("Password"); |
- field.name = ASCIIToUTF16("password"); |
- field.form_control_type = "password"; |
- form.fields.push_back(field); |
- |
- form_structure.reset(new FormStructure(form, std::string())); |
- |
- EXPECT_EQ(FormStructureTest::Hash64Bit( |
- std::string("://&&email&first")), |
- form_structure->FormSignature()); |
- |
- form.origin = GURL(std::string("http://www.facebook.com")); |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_EQ(FormStructureTest::Hash64Bit( |
- std::string("http://www.facebook.com&&email&first")), |
- form_structure->FormSignature()); |
- |
- form.action = GURL(std::string("https://login.facebook.com/path")); |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_EQ(FormStructureTest::Hash64Bit( |
- std::string("https://login.facebook.com&&email&first")), |
- form_structure->FormSignature()); |
- |
- form.name = ASCIIToUTF16("login_form"); |
- form_structure.reset(new FormStructure(form, std::string())); |
- EXPECT_EQ(FormStructureTest::Hash64Bit( |
- std::string("https://login.facebook.com&login_form&email&first")), |
- form_structure->FormSignature()); |
-} |
- |
-TEST(FormStructureTest, ToFormData) { |
- FormData form; |
- form.name = ASCIIToUTF16("the-name"); |
- form.method = ASCIIToUTF16("POST"); |
- form.origin = GURL("http://cool.com"); |
- form.action = form.origin.Resolve("/login"); |
- |
- FormFieldData field; |
- field.label = ASCIIToUTF16("username"); |
- field.name = ASCIIToUTF16("username"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("password"); |
- field.name = ASCIIToUTF16("password"); |
- field.form_control_type = "password"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("Submit"); |
- field.form_control_type = "submit"; |
- form.fields.push_back(field); |
- |
- EXPECT_EQ(form, FormStructure(form, std::string()).ToFormData()); |
- |
- // Currently |FormStructure(form_data)ToFormData().user_submitted| is always |
- // false. This forces a future author that changes this to update this test. |
- form.user_submitted = true; |
- EXPECT_NE(form, FormStructure(form, std::string()).ToFormData()); |
-} |
- |
-TEST(FormStructureTest, SkipFieldTest) { |
- FormData form; |
- form.name = ASCIIToUTF16("the-name"); |
- form.method = ASCIIToUTF16("POST"); |
- form.origin = GURL("http://cool.com"); |
- form.action = form.origin.Resolve("/login"); |
- |
- FormFieldData field; |
- field.label = ASCIIToUTF16("username"); |
- field.name = ASCIIToUTF16("username"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- field.label = ASCIIToUTF16("password"); |
- field.name = ASCIIToUTF16("password"); |
- field.form_control_type = "password"; |
- form.fields.push_back(field); |
- |
- field.label = base::string16(); |
- field.name = ASCIIToUTF16("email"); |
- field.form_control_type = "text"; |
- form.fields.push_back(field); |
- |
- ScopedVector<FormStructure> forms; |
- forms.push_back(new FormStructure(form, std::string())); |
- std::vector<std::string> encoded_signatures; |
- std::string encoded_xml; |
- |
- const char * const kSignature = "18006745212084723782"; |
- const char * const kResponse = |
- "<\?xml version=\"1.0\" encoding=\"UTF-8\"?><autofillquery " |
- "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form " |
- "signature=\"18006745212084723782\"><field signature=\"239111655\"/>" |
- "<field signature=\"420638584\"/></form></autofillquery>"; |
- ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(), |
- &encoded_signatures, |
- &encoded_xml)); |
- ASSERT_EQ(1U, encoded_signatures.size()); |
- EXPECT_EQ(kSignature, encoded_signatures[0]); |
- EXPECT_EQ(kResponse, encoded_xml); |
- |
- AutocheckoutPageMetaData page_meta_data; |
- const char * const kServerResponse = |
- "<autofillqueryresponse><field autofilltype=\"3\" />" |
- "<field autofilltype=\"9\" /></autofillqueryresponse>"; |
- FormStructure::ParseQueryResponse(kServerResponse, forms.get(), |
- &page_meta_data, TestAutofillMetrics()); |
- ASSERT_EQ(NAME_FIRST, forms[0]->field(0)->server_type()); |
- ASSERT_EQ(NO_SERVER_DATA, forms[0]->field(1)->server_type()); |
- ASSERT_EQ(EMAIL_ADDRESS, forms[0]->field(2)->server_type()); |
-} |
- |
-} // namespace autofill |