1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/autofill/core/browser/form_structure.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "components/autofill/core/browser/autofill_metrics.h"
11 #include "components/autofill/core/common/form_data.h"
12 #include "components/autofill/core/common/form_field_data.h"
13 #include "testing/gtest/include/gtest/gtest.h"
16 using base::ASCIIToUTF16;
21 // Unlike the base AutofillMetrics, exposes copy and assignment constructors,
22 // which are handy for briefer test code. The AutofillMetrics class is
23 // stateless, so this is safe.
24 class TestAutofillMetrics : public AutofillMetrics {
26 TestAutofillMetrics() {}
27 virtual ~TestAutofillMetrics() {}
30 } // anonymous namespace
35 std::ostream& operator<<(std::ostream& os, const FormData& form) {
36 os << base::UTF16ToUTF8(form.name)
38 << base::UTF16ToUTF8(form.method)
45 for (std::vector<FormFieldData>::const_iterator iter =
47 iter != form.fields.end(); ++iter) {
55 } // namespace content
57 class FormStructureTest {
59 static std::string Hash64Bit(const std::string& str) {
60 return FormStructure::Hash64Bit(str);
64 TEST(FormStructureTest, FieldCount) {
65 scoped_ptr<FormStructure> form_structure;
67 form.method = ASCIIToUTF16("post");
70 field.label = ASCIIToUTF16("username");
71 field.name = ASCIIToUTF16("username");
72 field.form_control_type = "text";
73 form.fields.push_back(field);
75 field.label = ASCIIToUTF16("password");
76 field.name = ASCIIToUTF16("password");
77 field.form_control_type = "password";
78 form.fields.push_back(field);
80 field.label = base::string16();
81 field.name = ASCIIToUTF16("Submit");
82 field.form_control_type = "submit";
83 form.fields.push_back(field);
85 field.label = ASCIIToUTF16("address1");
86 field.name = ASCIIToUTF16("address1");
87 field.form_control_type = "text";
88 field.should_autocomplete = false;
89 form.fields.push_back(field);
91 // The render process sends all fields to browser including fields with
93 form_structure.reset(new FormStructure(form));
94 EXPECT_EQ(4U, form_structure->field_count());
97 TEST(FormStructureTest, AutofillCount) {
98 scoped_ptr<FormStructure> form_structure;
100 form.method = ASCIIToUTF16("post");
103 field.label = ASCIIToUTF16("username");
104 field.name = ASCIIToUTF16("username");
105 field.form_control_type = "text";
106 form.fields.push_back(field);
108 field.label = ASCIIToUTF16("password");
109 field.name = ASCIIToUTF16("password");
110 field.form_control_type = "password";
111 form.fields.push_back(field);
113 field.label = ASCIIToUTF16("state");
114 field.name = ASCIIToUTF16("state");
115 field.form_control_type = "select-one";
116 form.fields.push_back(field);
118 field.label = base::string16();
119 field.name = ASCIIToUTF16("Submit");
120 field.form_control_type = "submit";
121 form.fields.push_back(field);
123 // Only text and select fields that are heuristically matched are counted.
124 form_structure.reset(new FormStructure(form));
125 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
126 EXPECT_EQ(1U, form_structure->autofill_count());
128 // Add a field with should_autocomplete=false.
129 field.label = ASCIIToUTF16("address1");
130 field.name = ASCIIToUTF16("address1");
131 field.form_control_type = "text";
132 field.should_autocomplete = false;
133 form.fields.push_back(field);
135 form_structure.reset(new FormStructure(form));
136 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
137 // DetermineHeuristicTypes also assign field type for fields with
138 // autocomplete=off thus autofill_count includes them. This is a bug,
139 // and they should not be counted. See http://crbug.com/176432 for details.
140 // TODO(benquan): change it to EXPECT_EQ(1U, ... when the bug is fixed.
141 EXPECT_EQ(2U, form_structure->autofill_count());
144 TEST(FormStructureTest, SourceURL) {
146 form.origin = GURL("http://www.foo.com/");
147 form.method = ASCIIToUTF16("post");
148 FormStructure form_structure(form);
150 EXPECT_EQ(form.origin, form_structure.source_url());
153 TEST(FormStructureTest, IsAutofillable) {
154 scoped_ptr<FormStructure> form_structure;
157 // We need at least three text fields to be auto-fillable.
158 form.method = ASCIIToUTF16("post");
162 field.label = ASCIIToUTF16("username");
163 field.name = ASCIIToUTF16("username");
164 field.form_control_type = "text";
165 form.fields.push_back(field);
167 field.label = ASCIIToUTF16("password");
168 field.name = ASCIIToUTF16("password");
169 field.form_control_type = "password";
170 form.fields.push_back(field);
172 field.label = base::string16();
173 field.name = ASCIIToUTF16("Submit");
174 field.form_control_type = "submit";
175 form.fields.push_back(field);
177 form_structure.reset(new FormStructure(form));
178 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
179 EXPECT_FALSE(form_structure->IsAutofillable(true));
181 // We now have three text fields, but only two auto-fillable fields.
182 field.label = ASCIIToUTF16("First Name");
183 field.name = ASCIIToUTF16("firstname");
184 field.form_control_type = "text";
185 form.fields.push_back(field);
187 field.label = ASCIIToUTF16("Last Name");
188 field.name = ASCIIToUTF16("lastname");
189 field.form_control_type = "text";
190 form.fields.push_back(field);
192 form_structure.reset(new FormStructure(form));
193 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
194 EXPECT_FALSE(form_structure->IsAutofillable(true));
196 // We now have three auto-fillable fields.
197 field.label = ASCIIToUTF16("Email");
198 field.name = ASCIIToUTF16("email");
199 field.form_control_type = "email";
200 form.fields.push_back(field);
202 form_structure.reset(new FormStructure(form));
203 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
204 EXPECT_TRUE(form_structure->IsAutofillable(true));
206 // The method must be 'post', though we can intentionally ignore this
207 // criterion for the sake of providing a helpful warning message to the user.
208 form.method = ASCIIToUTF16("get");
209 form_structure.reset(new FormStructure(form));
210 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
211 EXPECT_FALSE(form_structure->IsAutofillable(true));
212 EXPECT_TRUE(form_structure->IsAutofillable(false));
214 // The target cannot include http(s)://*/search...
215 form.method = ASCIIToUTF16("post");
216 form.action = GURL("http://google.com/search?q=hello");
217 form_structure.reset(new FormStructure(form));
218 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
219 EXPECT_FALSE(form_structure->IsAutofillable(true));
221 // But search can be in the URL.
222 form.action = GURL("http://search.com/?q=hello");
223 form_structure.reset(new FormStructure(form));
224 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
225 EXPECT_TRUE(form_structure->IsAutofillable(true));
228 TEST(FormStructureTest, ShouldBeParsed) {
229 scoped_ptr<FormStructure> form_structure;
232 // We need at least three text fields to be parseable.
233 form.method = ASCIIToUTF16("post");
236 field.label = ASCIIToUTF16("username");
237 field.name = ASCIIToUTF16("username");
238 field.form_control_type = "text";
239 form.fields.push_back(field);
241 FormFieldData checkable_field;
242 checkable_field.is_checkable = true;
243 checkable_field.name = ASCIIToUTF16("radiobtn");
244 checkable_field.form_control_type = "radio";
245 form.fields.push_back(checkable_field);
247 checkable_field.name = ASCIIToUTF16("checkbox");
248 checkable_field.form_control_type = "checkbox";
249 form.fields.push_back(checkable_field);
251 // We have only one text field, should not be parsed.
252 form_structure.reset(new FormStructure(form));
253 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
255 // We now have three text fields, though only two are auto-fillable.
256 field.label = ASCIIToUTF16("First Name");
257 field.name = ASCIIToUTF16("firstname");
258 field.form_control_type = "text";
259 form.fields.push_back(field);
261 field.label = ASCIIToUTF16("Last Name");
262 field.name = ASCIIToUTF16("lastname");
263 field.form_control_type = "text";
264 form.fields.push_back(field);
266 form_structure.reset(new FormStructure(form));
267 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
269 // The method must be 'post', though we can intentionally ignore this
270 // criterion for the sake of providing a helpful warning message to the user.
271 form.method = ASCIIToUTF16("get");
272 form_structure.reset(new FormStructure(form));
273 EXPECT_FALSE(form_structure->IsAutofillable(true));
274 EXPECT_TRUE(form_structure->ShouldBeParsed(false));
276 // The target cannot include http(s)://*/search...
277 form.method = ASCIIToUTF16("post");
278 form.action = GURL("http://google.com/search?q=hello");
279 form_structure.reset(new FormStructure(form));
280 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
282 // But search can be in the URL.
283 form.action = GURL("http://search.com/?q=hello");
284 form_structure.reset(new FormStructure(form));
285 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
287 // The form need only have three fields, but at least one must be a text
291 field.label = ASCIIToUTF16("Email");
292 field.name = ASCIIToUTF16("email");
293 field.form_control_type = "email";
294 form.fields.push_back(field);
296 field.label = ASCIIToUTF16("State");
297 field.name = ASCIIToUTF16("state");
298 field.form_control_type = "select-one";
299 form.fields.push_back(field);
301 field.label = ASCIIToUTF16("Country");
302 field.name = ASCIIToUTF16("country");
303 field.form_control_type = "select-one";
304 form.fields.push_back(field);
306 form_structure.reset(new FormStructure(form));
307 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
309 form.fields[0].form_control_type = "select-one";
310 // Now, no text fields.
311 form_structure.reset(new FormStructure(form));
312 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
315 TEST(FormStructureTest, HeuristicsContactInfo) {
316 scoped_ptr<FormStructure> form_structure;
318 form.method = ASCIIToUTF16("post");
321 field.form_control_type = "text";
323 field.label = ASCIIToUTF16("First Name");
324 field.name = ASCIIToUTF16("firstname");
325 form.fields.push_back(field);
327 field.label = ASCIIToUTF16("Last Name");
328 field.name = ASCIIToUTF16("lastname");
329 form.fields.push_back(field);
331 field.label = ASCIIToUTF16("Email");
332 field.name = ASCIIToUTF16("email");
333 form.fields.push_back(field);
335 field.label = ASCIIToUTF16("Phone");
336 field.name = ASCIIToUTF16("phone");
337 form.fields.push_back(field);
339 field.label = ASCIIToUTF16("Address");
340 field.name = ASCIIToUTF16("address");
341 form.fields.push_back(field);
343 field.label = ASCIIToUTF16("City");
344 field.name = ASCIIToUTF16("city");
345 form.fields.push_back(field);
347 field.label = ASCIIToUTF16("Zip code");
348 field.name = ASCIIToUTF16("zipcode");
349 form.fields.push_back(field);
351 field.label = base::string16();
352 field.name = ASCIIToUTF16("Submit");
353 field.form_control_type = "submit";
354 form.fields.push_back(field);
356 form_structure.reset(new FormStructure(form));
357 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
358 EXPECT_TRUE(form_structure->IsAutofillable(true));
360 // Expect the correct number of fields.
361 ASSERT_EQ(8U, form_structure->field_count());
362 ASSERT_EQ(7U, form_structure->autofill_count());
365 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
367 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
369 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
371 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
372 form_structure->field(3)->heuristic_type());
374 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type());
376 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type());
378 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
380 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
383 // Verify that we can correctly process the |autocomplete| attribute.
384 TEST(FormStructureTest, HeuristicsAutocompleteAttribute) {
385 scoped_ptr<FormStructure> form_structure;
387 form.method = ASCIIToUTF16("post");
390 field.form_control_type = "text";
392 field.label = base::string16();
393 field.name = ASCIIToUTF16("field1");
394 field.autocomplete_attribute = "given-name";
395 form.fields.push_back(field);
397 field.label = base::string16();
398 field.name = ASCIIToUTF16("field2");
399 field.autocomplete_attribute = "family-name";
400 form.fields.push_back(field);
402 field.label = base::string16();
403 field.name = ASCIIToUTF16("field3");
404 field.autocomplete_attribute = "email";
405 form.fields.push_back(field);
407 form_structure.reset(new FormStructure(form));
408 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
409 EXPECT_TRUE(form_structure->IsAutofillable(true));
411 // Expect the correct number of fields.
412 ASSERT_EQ(3U, form_structure->field_count());
413 ASSERT_EQ(3U, form_structure->autofill_count());
415 EXPECT_EQ(HTML_TYPE_GIVEN_NAME, form_structure->field(0)->html_type());
416 EXPECT_EQ(HTML_TYPE_FAMILY_NAME, form_structure->field(1)->html_type());
417 EXPECT_EQ(HTML_TYPE_EMAIL, form_structure->field(2)->html_type());
418 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type());
419 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
420 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
423 // Verify that we can correctly process the 'autocomplete' attribute for phone
424 // number types (especially phone prefixes and suffixes).
425 TEST(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
426 scoped_ptr<FormStructure> form_structure;
428 form.method = ASCIIToUTF16("post");
431 field.form_control_type = "text";
433 field.label = base::string16();
434 field.name = ASCIIToUTF16("field1");
435 field.autocomplete_attribute = "tel-local";
436 form.fields.push_back(field);
438 field.label = base::string16();
439 field.name = ASCIIToUTF16("field2");
440 field.autocomplete_attribute = "tel-local-prefix";
441 form.fields.push_back(field);
443 field.label = base::string16();
444 field.name = ASCIIToUTF16("field3");
445 field.autocomplete_attribute = "tel-local-suffix";
446 form.fields.push_back(field);
448 form_structure.reset(new FormStructure(form));
449 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
450 EXPECT_TRUE(form_structure->IsAutofillable(true));
452 // Expect the correct number of fields.
453 ASSERT_EQ(3U, form_structure->field_count());
454 EXPECT_EQ(3U, form_structure->autofill_count());
456 EXPECT_EQ(HTML_TYPE_TEL_LOCAL, form_structure->field(0)->html_type());
457 EXPECT_EQ(AutofillField::IGNORED, form_structure->field(0)->phone_part());
458 EXPECT_EQ(HTML_TYPE_TEL_LOCAL_PREFIX, form_structure->field(1)->html_type());
459 EXPECT_EQ(AutofillField::PHONE_PREFIX,
460 form_structure->field(1)->phone_part());
461 EXPECT_EQ(HTML_TYPE_TEL_LOCAL_SUFFIX, form_structure->field(2)->html_type());
462 EXPECT_EQ(AutofillField::PHONE_SUFFIX,
463 form_structure->field(2)->phone_part());
466 // If at least one field includes type hints in the 'autocomplete' attribute, we
467 // should not try to apply any other heuristics.
468 TEST(FormStructureTest, AutocompleteAttributeOverridesOtherHeuristics) {
469 scoped_ptr<FormStructure> form_structure;
471 form.method = ASCIIToUTF16("post");
473 // Start with a regular contact form.
475 field.form_control_type = "text";
477 field.label = ASCIIToUTF16("First Name");
478 field.name = ASCIIToUTF16("firstname");
479 form.fields.push_back(field);
481 field.label = ASCIIToUTF16("Last Name");
482 field.name = ASCIIToUTF16("lastname");
483 form.fields.push_back(field);
485 field.label = ASCIIToUTF16("Email");
486 field.name = ASCIIToUTF16("email");
487 form.fields.push_back(field);
489 form_structure.reset(new FormStructure(form));
490 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
491 EXPECT_TRUE(form_structure->IsAutofillable(true));
492 EXPECT_TRUE(form_structure->ShouldBeCrowdsourced());
494 ASSERT_EQ(3U, form_structure->field_count());
495 ASSERT_EQ(3U, form_structure->autofill_count());
497 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
498 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
499 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
501 // Now update the first form field to include an 'autocomplete' attribute.
502 form.fields.front().autocomplete_attribute = "x-other";
503 form_structure.reset(new FormStructure(form));
504 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
505 EXPECT_FALSE(form_structure->IsAutofillable(true));
506 EXPECT_FALSE(form_structure->ShouldBeCrowdsourced());
508 ASSERT_EQ(3U, form_structure->field_count());
509 ASSERT_EQ(0U, form_structure->autofill_count());
511 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type());
512 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
513 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
516 // Verify that we can correctly process sections listed in the |autocomplete|
518 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) {
520 form.method = ASCIIToUTF16("post");
523 field.form_control_type = "text";
525 // Some fields will have no section specified. These fall into the default
527 field.autocomplete_attribute = "email";
528 form.fields.push_back(field);
530 // We allow arbitrary section names.
531 field.autocomplete_attribute = "section-foo email";
532 form.fields.push_back(field);
534 // "shipping" and "billing" are special section tokens that don't require the
535 // "section-" prefix.
536 field.autocomplete_attribute = "shipping email";
537 form.fields.push_back(field);
538 field.autocomplete_attribute = "billing email";
539 form.fields.push_back(field);
541 // "shipping" and "billing" can be combined with other section names.
542 field.autocomplete_attribute = "section-foo shipping email";
543 form.fields.push_back(field);
544 field.autocomplete_attribute = "section-foo billing email";
545 form.fields.push_back(field);
547 // We don't do anything clever to try to coalesce sections; it's up to site
548 // authors to avoid typos.
549 field.autocomplete_attribute = "section--foo email";
550 form.fields.push_back(field);
552 // "shipping email" and "section--shipping" email should be parsed as
553 // different sections. This is only an interesting test due to how we
554 // implement implicit section names from attributes like "shipping email"; see
555 // the implementation for more details.
556 field.autocomplete_attribute = "section--shipping email";
557 form.fields.push_back(field);
559 // Credit card fields are implicitly in a separate section from other fields.
560 field.autocomplete_attribute = "section-foo cc-number";
561 form.fields.push_back(field);
563 FormStructure form_structure(form);
564 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
565 EXPECT_TRUE(form_structure.IsAutofillable(true));
567 // Expect the correct number of fields.
568 ASSERT_EQ(9U, form_structure.field_count());
569 EXPECT_EQ(9U, form_structure.autofill_count());
571 // All of the fields in this form should be parsed as belonging to different
573 std::set<std::string> section_names;
574 for (size_t i = 0; i < 9; ++i) {
575 section_names.insert(form_structure.field(i)->section());
577 EXPECT_EQ(9U, section_names.size());
580 // Verify that we can correctly process a degenerate section listed in the
581 // |autocomplete| attribute.
582 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsDegenerate) {
584 form.method = ASCIIToUTF16("post");
587 field.form_control_type = "text";
589 // Some fields will have no section specified. These fall into the default
591 field.autocomplete_attribute = "email";
592 form.fields.push_back(field);
594 // Specifying "section-" is equivalent to not specifying a section.
595 field.autocomplete_attribute = "section- email";
596 form.fields.push_back(field);
598 // Invalid tokens should prevent us from setting a section name.
599 field.autocomplete_attribute = "garbage section-foo email";
600 form.fields.push_back(field);
601 field.autocomplete_attribute = "garbage section-bar email";
602 form.fields.push_back(field);
603 field.autocomplete_attribute = "garbage shipping email";
604 form.fields.push_back(field);
605 field.autocomplete_attribute = "garbage billing email";
606 form.fields.push_back(field);
608 FormStructure form_structure(form);
609 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
611 // Expect the correct number of fields.
612 ASSERT_EQ(6U, form_structure.field_count());
613 EXPECT_EQ(2U, form_structure.autofill_count());
615 // All of the fields in this form should be parsed as belonging to the same
617 std::set<std::string> section_names;
618 for (size_t i = 0; i < 6; ++i) {
619 section_names.insert(form_structure.field(i)->section());
621 EXPECT_EQ(1U, section_names.size());
624 // Verify that we can correctly process repeated sections listed in the
625 // |autocomplete| attribute.
626 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsRepeated) {
628 form.method = ASCIIToUTF16("post");
631 field.form_control_type = "text";
633 field.autocomplete_attribute = "section-foo email";
634 form.fields.push_back(field);
635 field.autocomplete_attribute = "section-foo address-line1";
636 form.fields.push_back(field);
638 FormStructure form_structure(form);
639 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
641 // Expect the correct number of fields.
642 ASSERT_EQ(2U, form_structure.field_count());
643 EXPECT_EQ(2U, form_structure.autofill_count());
645 // All of the fields in this form should be parsed as belonging to the same
647 std::set<std::string> section_names;
648 for (size_t i = 0; i < 2; ++i) {
649 section_names.insert(form_structure.field(i)->section());
651 EXPECT_EQ(1U, section_names.size());
654 // Verify that we do not override the author-specified sections from a form with
656 TEST(FormStructureTest, HeuristicsDontOverrideAutocompleteAttributeSections) {
658 form.method = ASCIIToUTF16("post");
661 field.form_control_type = "text";
663 field.name = ASCIIToUTF16("one");
664 field.autocomplete_attribute = "address-line1";
665 form.fields.push_back(field);
666 field.name = base::string16();
667 field.autocomplete_attribute = "section-foo email";
668 form.fields.push_back(field);
669 field.name = base::string16();
670 field.autocomplete_attribute = "name";
671 form.fields.push_back(field);
672 field.name = ASCIIToUTF16("two");
673 field.autocomplete_attribute = "address-line1";
674 form.fields.push_back(field);
676 FormStructure form_structure(form);
677 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
679 // Expect the correct number of fields.
680 ASSERT_EQ(4U, form_structure.field_count());
681 EXPECT_EQ(4U, form_structure.autofill_count());
683 // Normally, the two separate address fields would cause us to detect two
684 // separate sections; but because there is an author-specified section in this
685 // form, we do not apply these usual heuristics.
686 EXPECT_EQ(ASCIIToUTF16("one"), form_structure.field(0)->name);
687 EXPECT_EQ(ASCIIToUTF16("two"), form_structure.field(3)->name);
688 EXPECT_EQ(form_structure.field(0)->section(),
689 form_structure.field(3)->section());
692 TEST(FormStructureTest, HeuristicsSample8) {
693 scoped_ptr<FormStructure> form_structure;
695 form.method = ASCIIToUTF16("post");
698 field.form_control_type = "text";
700 field.label = ASCIIToUTF16("Your First Name:");
701 field.name = ASCIIToUTF16("bill.first");
702 form.fields.push_back(field);
704 field.label = ASCIIToUTF16("Your Last Name:");
705 field.name = ASCIIToUTF16("bill.last");
706 form.fields.push_back(field);
708 field.label = ASCIIToUTF16("Street Address Line 1:");
709 field.name = ASCIIToUTF16("bill.street1");
710 form.fields.push_back(field);
712 field.label = ASCIIToUTF16("Street Address Line 2:");
713 field.name = ASCIIToUTF16("bill.street2");
714 form.fields.push_back(field);
716 field.label = ASCIIToUTF16("City");
717 field.name = ASCIIToUTF16("bill.city");
718 form.fields.push_back(field);
720 field.label = ASCIIToUTF16("State (U.S.):");
721 field.name = ASCIIToUTF16("bill.state");
722 form.fields.push_back(field);
724 field.label = ASCIIToUTF16("Zip/Postal Code:");
725 field.name = ASCIIToUTF16("BillTo.PostalCode");
726 form.fields.push_back(field);
728 field.label = ASCIIToUTF16("Country:");
729 field.name = ASCIIToUTF16("bill.country");
730 form.fields.push_back(field);
732 field.label = ASCIIToUTF16("Phone Number:");
733 field.name = ASCIIToUTF16("BillTo.Phone");
734 form.fields.push_back(field);
736 field.label = base::string16();
737 field.name = ASCIIToUTF16("Submit");
738 field.form_control_type = "submit";
739 form.fields.push_back(field);
741 form_structure.reset(new FormStructure(form));
742 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
743 EXPECT_TRUE(form_structure->IsAutofillable(true));
744 ASSERT_EQ(10U, form_structure->field_count());
745 ASSERT_EQ(9U, form_structure->autofill_count());
748 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
750 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
752 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(2)->heuristic_type());
754 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(3)->heuristic_type());
756 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
758 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(5)->heuristic_type());
760 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
762 EXPECT_EQ(ADDRESS_HOME_COUNTRY, form_structure->field(7)->heuristic_type());
764 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
765 form_structure->field(8)->heuristic_type());
767 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type());
770 TEST(FormStructureTest, HeuristicsSample6) {
771 scoped_ptr<FormStructure> form_structure;
773 form.method = ASCIIToUTF16("post");
776 field.form_control_type = "text";
778 field.label = ASCIIToUTF16("E-mail address");
779 field.name = ASCIIToUTF16("email");
780 form.fields.push_back(field);
782 field.label = ASCIIToUTF16("Full name");
783 field.name = ASCIIToUTF16("name");
784 form.fields.push_back(field);
786 field.label = ASCIIToUTF16("Company");
787 field.name = ASCIIToUTF16("company");
788 form.fields.push_back(field);
790 field.label = ASCIIToUTF16("Address");
791 field.name = ASCIIToUTF16("address");
792 form.fields.push_back(field);
794 field.label = ASCIIToUTF16("City");
795 field.name = ASCIIToUTF16("city");
796 form.fields.push_back(field);
798 field.label = ASCIIToUTF16("Zip Code");
799 field.name = ASCIIToUTF16("Home.PostalCode");
800 form.fields.push_back(field);
802 field.label = base::string16();
803 field.name = ASCIIToUTF16("Submit");
804 field.value = ASCIIToUTF16("continue");
805 field.form_control_type = "submit";
806 form.fields.push_back(field);
808 form_structure.reset(new FormStructure(form));
809 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
810 EXPECT_TRUE(form_structure->IsAutofillable(true));
811 ASSERT_EQ(7U, form_structure->field_count());
812 ASSERT_EQ(6U, form_structure->autofill_count());
815 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(0)->heuristic_type());
817 EXPECT_EQ(NAME_FULL, form_structure->field(1)->heuristic_type());
819 EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
821 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type());
823 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
825 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(5)->heuristic_type());
827 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
830 // Tests a sequence of FormFields where only labels are supplied to heuristics
831 // for matching. This works because FormFieldData labels are matched in the
832 // case that input element ids (or |name| fields) are missing.
833 TEST(FormStructureTest, HeuristicsLabelsOnly) {
834 scoped_ptr<FormStructure> form_structure;
836 form.method = ASCIIToUTF16("post");
839 field.form_control_type = "text";
841 field.label = ASCIIToUTF16("First Name");
842 field.name = base::string16();
843 form.fields.push_back(field);
845 field.label = ASCIIToUTF16("Last Name");
846 field.name = base::string16();
847 form.fields.push_back(field);
849 field.label = ASCIIToUTF16("Email");
850 field.name = base::string16();
851 form.fields.push_back(field);
853 field.label = ASCIIToUTF16("Phone");
854 field.name = base::string16();
855 form.fields.push_back(field);
857 field.label = ASCIIToUTF16("Address");
858 field.name = base::string16();
859 form.fields.push_back(field);
861 field.label = ASCIIToUTF16("Address");
862 field.name = base::string16();
863 form.fields.push_back(field);
865 field.label = ASCIIToUTF16("Zip code");
866 field.name = base::string16();
867 form.fields.push_back(field);
869 field.label = base::string16();
870 field.name = ASCIIToUTF16("Submit");
871 field.form_control_type = "submit";
872 form.fields.push_back(field);
874 form_structure.reset(new FormStructure(form));
875 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
876 EXPECT_TRUE(form_structure->IsAutofillable(true));
877 ASSERT_EQ(8U, form_structure->field_count());
878 ASSERT_EQ(7U, form_structure->autofill_count());
881 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
883 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
885 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
887 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
888 form_structure->field(3)->heuristic_type());
890 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type());
892 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(5)->heuristic_type());
894 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
896 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
899 TEST(FormStructureTest, HeuristicsCreditCardInfo) {
900 scoped_ptr<FormStructure> form_structure;
902 form.method = ASCIIToUTF16("post");
905 field.form_control_type = "text";
907 field.label = ASCIIToUTF16("Name on Card");
908 field.name = ASCIIToUTF16("name_on_card");
909 form.fields.push_back(field);
911 field.label = ASCIIToUTF16("Card Number");
912 field.name = ASCIIToUTF16("card_number");
913 form.fields.push_back(field);
915 field.label = ASCIIToUTF16("Exp Month");
916 field.name = ASCIIToUTF16("ccmonth");
917 form.fields.push_back(field);
919 field.label = ASCIIToUTF16("Exp Year");
920 field.name = ASCIIToUTF16("ccyear");
921 form.fields.push_back(field);
923 field.label = ASCIIToUTF16("Verification");
924 field.name = ASCIIToUTF16("verification");
925 form.fields.push_back(field);
927 field.label = base::string16();
928 field.name = ASCIIToUTF16("Submit");
929 field.form_control_type = "submit";
930 form.fields.push_back(field);
932 form_structure.reset(new FormStructure(form));
933 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
934 EXPECT_TRUE(form_structure->IsAutofillable(true));
935 ASSERT_EQ(6U, form_structure->field_count());
936 ASSERT_EQ(5U, form_structure->autofill_count());
939 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
940 // Credit card number.
941 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type());
942 // Credit card expiration month.
943 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(2)->heuristic_type());
944 // Credit card expiration year.
945 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
946 form_structure->field(3)->heuristic_type());
948 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
949 form_structure->field(4)->heuristic_type());
951 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
954 TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
955 scoped_ptr<FormStructure> form_structure;
957 form.method = ASCIIToUTF16("post");
960 field.form_control_type = "text";
962 field.label = ASCIIToUTF16("Name on Card");
963 field.name = ASCIIToUTF16("name_on_card");
964 form.fields.push_back(field);
966 // This is not a field we know how to process. But we should skip over it
967 // and process the other fields in the card block.
968 field.label = ASCIIToUTF16("Card image");
969 field.name = ASCIIToUTF16("card_image");
970 form.fields.push_back(field);
972 field.label = ASCIIToUTF16("Card Number");
973 field.name = ASCIIToUTF16("card_number");
974 form.fields.push_back(field);
976 field.label = ASCIIToUTF16("Exp Month");
977 field.name = ASCIIToUTF16("ccmonth");
978 form.fields.push_back(field);
980 field.label = ASCIIToUTF16("Exp Year");
981 field.name = ASCIIToUTF16("ccyear");
982 form.fields.push_back(field);
984 field.label = ASCIIToUTF16("Verification");
985 field.name = ASCIIToUTF16("verification");
986 form.fields.push_back(field);
988 field.label = base::string16();
989 field.name = ASCIIToUTF16("Submit");
990 field.form_control_type = "submit";
991 form.fields.push_back(field);
993 form_structure.reset(new FormStructure(form));
994 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
995 EXPECT_TRUE(form_structure->IsAutofillable(true));
996 ASSERT_EQ(7U, form_structure->field_count());
997 ASSERT_EQ(5U, form_structure->autofill_count());
1000 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
1001 // Credit card type. This is an unknown type but related to the credit card.
1002 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
1003 // Credit card number.
1004 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type());
1005 // Credit card expiration month.
1006 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1007 // Credit card expiration year.
1008 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1009 form_structure->field(4)->heuristic_type());
1011 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
1012 form_structure->field(5)->heuristic_type());
1014 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
1017 TEST(FormStructureTest, ThreeAddressLines) {
1018 scoped_ptr<FormStructure> form_structure;
1020 form.method = ASCIIToUTF16("post");
1022 FormFieldData field;
1023 field.form_control_type = "text";
1025 field.label = ASCIIToUTF16("Address Line1");
1026 field.name = ASCIIToUTF16("Address");
1027 form.fields.push_back(field);
1029 field.label = ASCIIToUTF16("Address Line2");
1030 field.name = ASCIIToUTF16("Address");
1031 form.fields.push_back(field);
1033 field.label = ASCIIToUTF16("Address Line3");
1034 field.name = ASCIIToUTF16("Address");
1035 form.fields.push_back(field);
1037 field.label = ASCIIToUTF16("City");
1038 field.name = ASCIIToUTF16("city");
1039 form.fields.push_back(field);
1041 form_structure.reset(new FormStructure(form));
1042 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1043 EXPECT_TRUE(form_structure->IsAutofillable(true));
1044 ASSERT_EQ(4U, form_structure->field_count());
1045 ASSERT_EQ(3U, form_structure->autofill_count());
1048 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1050 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1052 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1054 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
1057 // Numbered address lines after line two are ignored.
1058 TEST(FormStructureTest, SurplusAddressLinesIgnored) {
1059 scoped_ptr<FormStructure> form_structure;
1061 form.method = ASCIIToUTF16("post");
1063 FormFieldData field;
1064 field.form_control_type = "text";
1066 field.label = ASCIIToUTF16("Address Line1");
1067 field.name = ASCIIToUTF16("shipping.address.addressLine1");
1068 form.fields.push_back(field);
1070 field.label = ASCIIToUTF16("Address Line2");
1071 field.name = ASCIIToUTF16("shipping.address.addressLine2");
1072 form.fields.push_back(field);
1074 field.label = ASCIIToUTF16("Address Line3");
1075 field.name = ASCIIToUTF16("billing.address.addressLine3");
1076 form.fields.push_back(field);
1078 field.label = ASCIIToUTF16("Address Line4");
1079 field.name = ASCIIToUTF16("billing.address.addressLine4");
1080 form.fields.push_back(field);
1082 form_structure.reset(new FormStructure(form));
1083 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1084 ASSERT_EQ(4U, form_structure->field_count());
1085 ASSERT_EQ(2U, form_structure->autofill_count());
1088 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1090 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1091 // Address Line 3 (ignored).
1092 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1093 // Address Line 4 (ignored).
1094 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
1097 // This example comes from expedia.com where they use a "Suite" label to
1098 // indicate a suite or apartment number. We interpret this as address line 2.
1099 // And the following "Street address second line" we interpret as address line
1101 // See http://crbug.com/48197 for details.
1102 TEST(FormStructureTest, ThreeAddressLinesExpedia) {
1103 scoped_ptr<FormStructure> form_structure;
1105 form.method = ASCIIToUTF16("post");
1107 FormFieldData field;
1108 field.form_control_type = "text";
1110 field.label = ASCIIToUTF16("Street:");
1111 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1");
1112 form.fields.push_back(field);
1114 field.label = ASCIIToUTF16("Suite or Apt:");
1115 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap");
1116 form.fields.push_back(field);
1118 field.label = ASCIIToUTF16("Street address second line");
1119 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads2");
1120 form.fields.push_back(field);
1122 field.label = ASCIIToUTF16("City:");
1123 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adct");
1124 form.fields.push_back(field);
1126 form_structure.reset(new FormStructure(form));
1127 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1128 EXPECT_TRUE(form_structure->IsAutofillable(true));
1129 ASSERT_EQ(4U, form_structure->field_count());
1130 EXPECT_EQ(3U, form_structure->autofill_count());
1133 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1135 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1137 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1139 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
1142 // This example comes from ebay.com where the word "suite" appears in the label
1143 // and the name "address2" clearly indicates that this is the address line 2.
1144 // See http://crbug.com/48197 for details.
1145 TEST(FormStructureTest, TwoAddressLinesEbay) {
1146 scoped_ptr<FormStructure> form_structure;
1148 form.method = ASCIIToUTF16("post");
1150 FormFieldData field;
1151 field.form_control_type = "text";
1153 field.label = ASCIIToUTF16("Address Line1");
1154 field.name = ASCIIToUTF16("address1");
1155 form.fields.push_back(field);
1157 field.label = ASCIIToUTF16("Floor number, suite number, etc");
1158 field.name = ASCIIToUTF16("address2");
1159 form.fields.push_back(field);
1161 field.label = ASCIIToUTF16("City:");
1162 field.name = ASCIIToUTF16("city");
1163 form.fields.push_back(field);
1165 form_structure.reset(new FormStructure(form));
1166 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1167 EXPECT_TRUE(form_structure->IsAutofillable(true));
1168 ASSERT_EQ(3U, form_structure->field_count());
1169 ASSERT_EQ(3U, form_structure->autofill_count());
1172 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1174 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1176 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(2)->heuristic_type());
1179 TEST(FormStructureTest, HeuristicsStateWithProvince) {
1180 scoped_ptr<FormStructure> form_structure;
1182 form.method = ASCIIToUTF16("post");
1184 FormFieldData field;
1185 field.form_control_type = "text";
1187 field.label = ASCIIToUTF16("Address Line1");
1188 field.name = ASCIIToUTF16("Address");
1189 form.fields.push_back(field);
1191 field.label = ASCIIToUTF16("Address Line2");
1192 field.name = ASCIIToUTF16("Address");
1193 form.fields.push_back(field);
1195 field.label = ASCIIToUTF16("State/Province/Region");
1196 field.name = ASCIIToUTF16("State");
1197 form.fields.push_back(field);
1199 form_structure.reset(new FormStructure(form));
1200 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1201 EXPECT_TRUE(form_structure->IsAutofillable(true));
1202 ASSERT_EQ(3U, form_structure->field_count());
1203 ASSERT_EQ(3U, form_structure->autofill_count());
1206 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1208 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1210 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(2)->heuristic_type());
1213 // This example comes from lego.com's checkout page.
1214 TEST(FormStructureTest, HeuristicsWithBilling) {
1215 scoped_ptr<FormStructure> form_structure;
1217 form.method = ASCIIToUTF16("post");
1219 FormFieldData field;
1220 field.form_control_type = "text";
1222 field.label = ASCIIToUTF16("First Name*:");
1223 field.name = ASCIIToUTF16("editBillingAddress$firstNameBox");
1224 form.fields.push_back(field);
1226 field.label = ASCIIToUTF16("Last Name*:");
1227 field.name = ASCIIToUTF16("editBillingAddress$lastNameBox");
1228 form.fields.push_back(field);
1230 field.label = ASCIIToUTF16("Company Name:");
1231 field.name = ASCIIToUTF16("editBillingAddress$companyBox");
1232 form.fields.push_back(field);
1234 field.label = ASCIIToUTF16("Address*:");
1235 field.name = ASCIIToUTF16("editBillingAddress$addressLine1Box");
1236 form.fields.push_back(field);
1238 field.label = ASCIIToUTF16("Apt/Suite :");
1239 field.name = ASCIIToUTF16("editBillingAddress$addressLine2Box");
1240 form.fields.push_back(field);
1242 field.label = ASCIIToUTF16("City*:");
1243 field.name = ASCIIToUTF16("editBillingAddress$cityBox");
1244 form.fields.push_back(field);
1246 field.label = ASCIIToUTF16("State/Province*:");
1247 field.name = ASCIIToUTF16("editBillingAddress$stateDropDown");
1248 form.fields.push_back(field);
1250 field.label = ASCIIToUTF16("Country*:");
1251 field.name = ASCIIToUTF16("editBillingAddress$countryDropDown");
1252 form.fields.push_back(field);
1254 field.label = ASCIIToUTF16("Postal Code*:");
1255 field.name = ASCIIToUTF16("editBillingAddress$zipCodeBox");
1256 form.fields.push_back(field);
1258 field.label = ASCIIToUTF16("Phone*:");
1259 field.name = ASCIIToUTF16("editBillingAddress$phoneBox");
1260 form.fields.push_back(field);
1262 field.label = ASCIIToUTF16("Email Address*:");
1263 field.name = ASCIIToUTF16("email$emailBox");
1264 form.fields.push_back(field);
1266 form_structure.reset(new FormStructure(form));
1267 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1268 EXPECT_TRUE(form_structure->IsAutofillable(true));
1269 ASSERT_EQ(11U, form_structure->field_count());
1270 ASSERT_EQ(11U, form_structure->autofill_count());
1272 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
1273 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
1274 EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
1275 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type());
1276 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(4)->heuristic_type());
1277 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type());
1278 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(6)->heuristic_type());
1279 EXPECT_EQ(ADDRESS_HOME_COUNTRY, form_structure->field(7)->heuristic_type());
1280 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(8)->heuristic_type());
1281 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
1282 form_structure->field(9)->heuristic_type());
1283 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(10)->heuristic_type());
1286 TEST(FormStructureTest, ThreePartPhoneNumber) {
1287 scoped_ptr<FormStructure> form_structure;
1289 form.method = ASCIIToUTF16("post");
1291 FormFieldData field;
1292 field.form_control_type = "text";
1294 field.label = ASCIIToUTF16("Phone:");
1295 field.name = ASCIIToUTF16("dayphone1");
1296 field.max_length = 0;
1297 form.fields.push_back(field);
1299 field.label = ASCIIToUTF16("-");
1300 field.name = ASCIIToUTF16("dayphone2");
1301 field.max_length = 3; // Size of prefix is 3.
1302 form.fields.push_back(field);
1304 field.label = ASCIIToUTF16("-");
1305 field.name = ASCIIToUTF16("dayphone3");
1306 field.max_length = 4; // Size of suffix is 4. If unlimited size is
1307 // passed, phone will be parsed as
1308 // <country code> - <area code> - <phone>.
1309 form.fields.push_back(field);
1311 field.label = ASCIIToUTF16("ext.:");
1312 field.name = ASCIIToUTF16("dayphone4");
1313 field.max_length = 0;
1314 form.fields.push_back(field);
1316 form_structure.reset(new FormStructure(form));
1317 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1318 EXPECT_TRUE(form_structure->IsAutofillable(true));
1319 ASSERT_EQ(4U, form_structure->field_count());
1320 ASSERT_EQ(3U, form_structure->autofill_count());
1323 EXPECT_EQ(PHONE_HOME_CITY_CODE, form_structure->field(0)->heuristic_type());
1324 // Phone number suffix.
1325 EXPECT_EQ(PHONE_HOME_NUMBER,
1326 form_structure->field(1)->heuristic_type());
1327 // Phone number suffix.
1328 EXPECT_EQ(PHONE_HOME_NUMBER,
1329 form_structure->field(2)->heuristic_type());
1331 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
1334 TEST(FormStructureTest, HeuristicsInfernoCC) {
1335 scoped_ptr<FormStructure> form_structure;
1337 form.method = ASCIIToUTF16("post");
1339 FormFieldData field;
1340 field.form_control_type = "text";
1342 field.label = ASCIIToUTF16("Name on Card");
1343 field.name = ASCIIToUTF16("name_on_card");
1344 form.fields.push_back(field);
1346 field.label = ASCIIToUTF16("Address");
1347 field.name = ASCIIToUTF16("billing_address");
1348 form.fields.push_back(field);
1350 field.label = ASCIIToUTF16("Card Number");
1351 field.name = ASCIIToUTF16("card_number");
1352 form.fields.push_back(field);
1354 field.label = ASCIIToUTF16("Expiration Date");
1355 field.name = ASCIIToUTF16("expiration_month");
1356 form.fields.push_back(field);
1358 field.label = ASCIIToUTF16("Expiration Year");
1359 field.name = ASCIIToUTF16("expiration_year");
1360 form.fields.push_back(field);
1362 form_structure.reset(new FormStructure(form));
1363 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1364 EXPECT_TRUE(form_structure->IsAutofillable(true));
1366 // Expect the correct number of fields.
1367 ASSERT_EQ(5U, form_structure->field_count());
1368 EXPECT_EQ(5U, form_structure->autofill_count());
1371 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
1373 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(1)->heuristic_type());
1375 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type());
1377 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1379 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1380 form_structure->field(4)->heuristic_type());
1383 TEST(FormStructureTest, CVCCodeClash) {
1384 scoped_ptr<FormStructure> form_structure;
1386 form.method = ASCIIToUTF16("post");
1388 FormFieldData field;
1389 field.form_control_type = "text";
1391 field.label = ASCIIToUTF16("Card number");
1392 field.name = ASCIIToUTF16("ccnumber");
1393 form.fields.push_back(field);
1395 field.label = ASCIIToUTF16("First name");
1396 field.name = ASCIIToUTF16("first_name");
1397 form.fields.push_back(field);
1399 field.label = ASCIIToUTF16("Last name");
1400 field.name = ASCIIToUTF16("last_name");
1401 form.fields.push_back(field);
1403 field.label = ASCIIToUTF16("Expiration date");
1404 field.name = ASCIIToUTF16("ccexpiresmonth");
1405 form.fields.push_back(field);
1407 field.label = base::string16();
1408 field.name = ASCIIToUTF16("ccexpiresyear");
1409 form.fields.push_back(field);
1411 field.label = ASCIIToUTF16("cvc number");
1412 field.name = ASCIIToUTF16("csc");
1413 form.fields.push_back(field);
1415 form_structure.reset(new FormStructure(form));
1416 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1417 EXPECT_TRUE(form_structure->IsAutofillable(true));
1419 // Expect the correct number of fields.
1420 ASSERT_EQ(6U, form_structure->field_count());
1421 ASSERT_EQ(5U, form_structure->autofill_count());
1424 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(0)->heuristic_type());
1425 // First name, taken as name on card.
1426 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(1)->heuristic_type());
1427 // Last name is not merged.
1428 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1430 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1432 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1433 form_structure->field(4)->heuristic_type());
1435 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
1436 form_structure->field(5)->heuristic_type());
1439 TEST(FormStructureTest, EncodeQueryRequest) {
1441 form.method = ASCIIToUTF16("post");
1443 FormFieldData field;
1444 field.form_control_type = "text";
1446 field.label = ASCIIToUTF16("Name on Card");
1447 field.name = ASCIIToUTF16("name_on_card");
1448 form.fields.push_back(field);
1450 field.label = ASCIIToUTF16("Address");
1451 field.name = ASCIIToUTF16("billing_address");
1452 form.fields.push_back(field);
1454 field.label = ASCIIToUTF16("Card Number");
1455 field.name = ASCIIToUTF16("card_number");
1456 form.fields.push_back(field);
1458 field.label = ASCIIToUTF16("Expiration Date");
1459 field.name = ASCIIToUTF16("expiration_month");
1460 form.fields.push_back(field);
1462 field.label = ASCIIToUTF16("Expiration Year");
1463 field.name = ASCIIToUTF16("expiration_year");
1464 form.fields.push_back(field);
1466 // Add checkable field.
1467 FormFieldData checkable_field;
1468 checkable_field.is_checkable = true;
1469 checkable_field.label = ASCIIToUTF16("Checkable1");
1470 checkable_field.name = ASCIIToUTF16("Checkable1");
1471 form.fields.push_back(checkable_field);
1473 ScopedVector<FormStructure> forms;
1474 forms.push_back(new FormStructure(form));
1475 std::vector<std::string> encoded_signatures;
1476 std::string encoded_xml;
1477 const char * const kSignature1 = "11337937696949187602";
1478 const char * const kResponse1 =
1479 "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery "
1480 "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
1481 "signature=\"11337937696949187602\"><field signature=\"412125936\"/>"
1482 "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
1483 "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>"
1485 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1486 &encoded_signatures,
1488 ASSERT_EQ(1U, encoded_signatures.size());
1489 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1490 EXPECT_EQ(kResponse1, encoded_xml);
1492 // Add the same form, only one will be encoded, so EncodeQueryRequest() should
1493 // return the same data.
1494 forms.push_back(new FormStructure(form));
1495 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1496 &encoded_signatures,
1498 ASSERT_EQ(1U, encoded_signatures.size());
1499 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1500 EXPECT_EQ(kResponse1, encoded_xml);
1501 // Add 5 address fields - this should be still a valid form.
1502 for (size_t i = 0; i < 5; ++i) {
1503 field.label = ASCIIToUTF16("Address");
1504 field.name = ASCIIToUTF16("address");
1505 form.fields.push_back(field);
1508 forms.push_back(new FormStructure(form));
1509 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1510 &encoded_signatures,
1512 ASSERT_EQ(2U, encoded_signatures.size());
1513 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1514 const char * const kSignature2 = "8308881815906226214";
1515 EXPECT_EQ(kSignature2, encoded_signatures[1]);
1516 const char * const kResponse2 =
1517 "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery "
1518 "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
1519 "signature=\"11337937696949187602\"><field signature=\"412125936\"/>"
1520 "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
1521 "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>"
1522 "<form signature=\"8308881815906226214\"><field signature=\"412125936\"/>"
1523 "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
1524 "<field signature=\"747221617\"/><field signature=\"4108155786\"/><field "
1525 "signature=\"509334676\"/><field signature=\"509334676\"/><field "
1526 "signature=\"509334676\"/><field signature=\"509334676\"/><field "
1527 "signature=\"509334676\"/></form></autofillquery>";
1528 EXPECT_EQ(kResponse2, encoded_xml);
1530 FormData malformed_form(form);
1531 // Add 50 address fields - the form is not valid anymore, but previous ones
1532 // are. The result should be the same as in previous test.
1533 for (size_t i = 0; i < 50; ++i) {
1534 field.label = ASCIIToUTF16("Address");
1535 field.name = ASCIIToUTF16("address");
1536 malformed_form.fields.push_back(field);
1539 forms.push_back(new FormStructure(malformed_form));
1540 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1541 &encoded_signatures,
1543 ASSERT_EQ(2U, encoded_signatures.size());
1544 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1545 EXPECT_EQ(kSignature2, encoded_signatures[1]);
1546 EXPECT_EQ(kResponse2, encoded_xml);
1548 // Check that we fail if there are only bad form(s).
1549 ScopedVector<FormStructure> bad_forms;
1550 bad_forms.push_back(new FormStructure(malformed_form));
1551 EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms.get(),
1552 &encoded_signatures,
1554 EXPECT_EQ(0U, encoded_signatures.size());
1555 EXPECT_EQ("", encoded_xml);
1558 TEST(FormStructureTest, EncodeUploadRequest) {
1559 scoped_ptr<FormStructure> form_structure;
1560 std::vector<ServerFieldTypeSet> possible_field_types;
1562 form.method = ASCIIToUTF16("post");
1563 form_structure.reset(new FormStructure(form));
1564 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1566 FormFieldData field;
1567 field.form_control_type = "text";
1569 field.label = ASCIIToUTF16("First Name");
1570 field.name = ASCIIToUTF16("firstname");
1571 form.fields.push_back(field);
1572 possible_field_types.push_back(ServerFieldTypeSet());
1573 possible_field_types.back().insert(NAME_FIRST);
1575 field.label = ASCIIToUTF16("Last Name");
1576 field.name = ASCIIToUTF16("lastname");
1577 form.fields.push_back(field);
1578 possible_field_types.push_back(ServerFieldTypeSet());
1579 possible_field_types.back().insert(NAME_LAST);
1581 field.label = ASCIIToUTF16("Email");
1582 field.name = ASCIIToUTF16("email");
1583 field.form_control_type = "email";
1584 form.fields.push_back(field);
1585 possible_field_types.push_back(ServerFieldTypeSet());
1586 possible_field_types.back().insert(EMAIL_ADDRESS);
1588 field.label = ASCIIToUTF16("Phone");
1589 field.name = ASCIIToUTF16("phone");
1590 field.form_control_type = "number";
1591 form.fields.push_back(field);
1592 possible_field_types.push_back(ServerFieldTypeSet());
1593 possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
1595 field.label = ASCIIToUTF16("Country");
1596 field.name = ASCIIToUTF16("country");
1597 field.form_control_type = "select-one";
1598 form.fields.push_back(field);
1599 possible_field_types.push_back(ServerFieldTypeSet());
1600 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1602 // Add checkable field.
1603 FormFieldData checkable_field;
1604 checkable_field.is_checkable = true;
1605 checkable_field.label = ASCIIToUTF16("Checkable1");
1606 checkable_field.name = ASCIIToUTF16("Checkable1");
1607 form.fields.push_back(checkable_field);
1608 possible_field_types.push_back(ServerFieldTypeSet());
1609 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1611 form_structure.reset(new FormStructure(form));
1613 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1614 for (size_t i = 0; i < form_structure->field_count(); ++i)
1615 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1617 ServerFieldTypeSet available_field_types;
1618 available_field_types.insert(NAME_FIRST);
1619 available_field_types.insert(NAME_LAST);
1620 available_field_types.insert(ADDRESS_HOME_LINE1);
1621 available_field_types.insert(ADDRESS_HOME_LINE2);
1622 available_field_types.insert(ADDRESS_HOME_COUNTRY);
1623 available_field_types.insert(ADDRESS_BILLING_LINE1);
1624 available_field_types.insert(ADDRESS_BILLING_LINE2);
1625 available_field_types.insert(EMAIL_ADDRESS);
1626 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1628 std::string encoded_xml;
1629 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
1631 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1632 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1633 "formsignature=\"8736493185895608956\" autofillused=\"false\" "
1634 "datapresent=\"144200030e\">"
1635 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1636 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1637 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1638 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1639 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1640 "</autofillupload>",
1642 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
1644 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1645 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1646 "formsignature=\"8736493185895608956\" autofillused=\"true\" "
1647 "datapresent=\"144200030e\">"
1648 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1649 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1650 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1651 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1652 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1653 "</autofillupload>",
1656 // Add 2 address fields - this should be still a valid form.
1657 for (size_t i = 0; i < 2; ++i) {
1658 field.label = ASCIIToUTF16("Address");
1659 field.name = ASCIIToUTF16("address");
1660 field.form_control_type = "text";
1661 form.fields.push_back(field);
1662 possible_field_types.push_back(ServerFieldTypeSet());
1663 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1664 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1665 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1666 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1669 form_structure.reset(new FormStructure(form));
1670 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1671 for (size_t i = 0; i < form_structure->field_count(); ++i)
1672 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1674 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
1676 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1677 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1678 "formsignature=\"7816485729218079147\" autofillused=\"false\" "
1679 "datapresent=\"144200030e\">"
1680 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1681 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1682 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1683 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1684 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1685 "<field signature=\"509334676\" autofilltype=\"30\"/>"
1686 "<field signature=\"509334676\" autofilltype=\"31\"/>"
1687 "<field signature=\"509334676\" autofilltype=\"37\"/>"
1688 "<field signature=\"509334676\" autofilltype=\"38\"/>"
1689 "<field signature=\"509334676\" autofilltype=\"30\"/>"
1690 "<field signature=\"509334676\" autofilltype=\"31\"/>"
1691 "<field signature=\"509334676\" autofilltype=\"37\"/>"
1692 "<field signature=\"509334676\" autofilltype=\"38\"/>"
1693 "</autofillupload>",
1696 // Add 50 address fields - now the form is invalid, as it has too many fields.
1697 for (size_t i = 0; i < 50; ++i) {
1698 field.label = ASCIIToUTF16("Address");
1699 field.name = ASCIIToUTF16("address");
1700 field.form_control_type = "text";
1701 form.fields.push_back(field);
1702 possible_field_types.push_back(ServerFieldTypeSet());
1703 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1704 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1705 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1706 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1708 form_structure.reset(new FormStructure(form));
1709 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1710 for (size_t i = 0; i < form_structure->field_count(); ++i)
1711 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1712 EXPECT_FALSE(form_structure->EncodeUploadRequest(available_field_types, false,
1716 TEST(FormStructureTest, EncodeFieldAssignments) {
1717 scoped_ptr<FormStructure> form_structure;
1718 std::vector<ServerFieldTypeSet> possible_field_types;
1720 form.method = ASCIIToUTF16("post");
1721 form_structure.reset(new FormStructure(form));
1722 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1724 FormFieldData field;
1725 field.form_control_type = "text";
1727 field.label = ASCIIToUTF16("First Name");
1728 field.name = ASCIIToUTF16("firstname");
1729 form.fields.push_back(field);
1730 possible_field_types.push_back(ServerFieldTypeSet());
1731 possible_field_types.back().insert(NAME_FIRST);
1733 field.label = ASCIIToUTF16("Last Name");
1734 field.name = ASCIIToUTF16("lastname");
1735 form.fields.push_back(field);
1736 possible_field_types.push_back(ServerFieldTypeSet());
1737 possible_field_types.back().insert(NAME_LAST);
1739 field.label = ASCIIToUTF16("Email");
1740 field.name = ASCIIToUTF16("email");
1741 field.form_control_type = "email";
1742 form.fields.push_back(field);
1743 possible_field_types.push_back(ServerFieldTypeSet());
1744 possible_field_types.back().insert(EMAIL_ADDRESS);
1746 field.label = ASCIIToUTF16("Phone");
1747 field.name = ASCIIToUTF16("phone");
1748 field.form_control_type = "number";
1749 form.fields.push_back(field);
1750 possible_field_types.push_back(ServerFieldTypeSet());
1751 possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
1753 field.label = ASCIIToUTF16("Country");
1754 field.name = ASCIIToUTF16("country");
1755 field.form_control_type = "select-one";
1756 form.fields.push_back(field);
1757 possible_field_types.push_back(ServerFieldTypeSet());
1758 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1760 // Add checkable field.
1761 FormFieldData checkable_field;
1762 checkable_field.is_checkable = true;
1763 checkable_field.label = ASCIIToUTF16("Checkable1");
1764 checkable_field.name = ASCIIToUTF16("Checkable1");
1765 form.fields.push_back(checkable_field);
1766 possible_field_types.push_back(ServerFieldTypeSet());
1767 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1769 form_structure.reset(new FormStructure(form));
1771 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1772 for (size_t i = 0; i < form_structure->field_count(); ++i)
1773 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1775 ServerFieldTypeSet available_field_types;
1776 available_field_types.insert(NAME_FIRST);
1777 available_field_types.insert(NAME_LAST);
1778 available_field_types.insert(ADDRESS_HOME_LINE1);
1779 available_field_types.insert(ADDRESS_HOME_LINE2);
1780 available_field_types.insert(ADDRESS_HOME_COUNTRY);
1781 available_field_types.insert(ADDRESS_BILLING_LINE1);
1782 available_field_types.insert(ADDRESS_BILLING_LINE2);
1783 available_field_types.insert(EMAIL_ADDRESS);
1784 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1786 std::string encoded_xml;
1787 EXPECT_TRUE(form_structure->EncodeFieldAssignments(
1788 available_field_types, &encoded_xml));
1790 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1791 "<fieldassignments formsignature=\"8736493185895608956\">"
1792 "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1793 "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1794 "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1795 "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1796 "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1797 "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
1798 "</fieldassignments>",
1801 // Add 2 address fields - this should be still a valid form.
1802 for (size_t i = 0; i < 2; ++i) {
1803 field.label = ASCIIToUTF16("Address");
1804 field.name = ASCIIToUTF16("address");
1805 field.form_control_type = "text";
1806 form.fields.push_back(field);
1807 possible_field_types.push_back(ServerFieldTypeSet());
1808 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1809 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1810 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1811 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1814 form_structure.reset(new FormStructure(form));
1815 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1816 for (size_t i = 0; i < form_structure->field_count(); ++i)
1817 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1819 EXPECT_TRUE(form_structure->EncodeFieldAssignments(
1820 available_field_types, &encoded_xml));
1822 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1823 "<fieldassignments formsignature=\"7816485729218079147\">"
1824 "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1825 "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1826 "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1827 "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1828 "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1829 "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
1830 "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>"
1831 "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
1832 "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
1833 "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
1834 "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>"
1835 "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
1836 "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
1837 "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
1838 "</fieldassignments>",
1842 // Check that we compute the "datapresent" string correctly for the given
1843 // |available_types|.
1844 TEST(FormStructureTest, CheckDataPresence) {
1846 form.method = ASCIIToUTF16("post");
1848 FormFieldData field;
1849 field.form_control_type = "text";
1851 field.label = ASCIIToUTF16("First Name");
1852 field.name = ASCIIToUTF16("first");
1853 form.fields.push_back(field);
1855 field.label = ASCIIToUTF16("Last Name");
1856 field.name = ASCIIToUTF16("last");
1857 form.fields.push_back(field);
1859 field.label = ASCIIToUTF16("Email");
1860 field.name = ASCIIToUTF16("email");
1861 form.fields.push_back(field);
1863 FormStructure form_structure(form);
1865 ServerFieldTypeSet unknown_type;
1866 unknown_type.insert(UNKNOWN_TYPE);
1867 for (size_t i = 0; i < form_structure.field_count(); ++i)
1868 form_structure.field(i)->set_possible_types(unknown_type);
1870 // No available types.
1871 // datapresent should be "" == trimmmed(0x0000000000000000) ==
1872 // 0b0000000000000000000000000000000000000000000000000000000000000000
1873 ServerFieldTypeSet available_field_types;
1875 std::string encoded_xml;
1876 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1878 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1879 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1880 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1881 " datapresent=\"\">"
1882 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1883 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1884 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1885 "</autofillupload>",
1888 // Only a few types available.
1889 // datapresent should be "1540000240" == trimmmed(0x1540000240000000) ==
1890 // 0b0001010101000000000000000000001001000000000000000000000000000000
1891 // The set bits are:
1895 // 9 == EMAIL_ADDRESS
1896 // 30 == ADDRESS_HOME_LINE1
1897 // 33 == ADDRESS_HOME_CITY
1898 available_field_types.clear();
1899 available_field_types.insert(NAME_FIRST);
1900 available_field_types.insert(NAME_LAST);
1901 available_field_types.insert(NAME_FULL);
1902 available_field_types.insert(EMAIL_ADDRESS);
1903 available_field_types.insert(ADDRESS_HOME_LINE1);
1904 available_field_types.insert(ADDRESS_HOME_CITY);
1906 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1908 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1909 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1910 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1911 " datapresent=\"1540000240\">"
1912 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1913 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1914 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1915 "</autofillupload>",
1918 // All supported non-credit card types available.
1919 // datapresent should be "1f7e000378000008" == trimmmed(0x1f7e000378000008) ==
1920 // 0b0001111101111110000000000000001101111000000000000000000000001000
1921 // The set bits are:
1925 // 6 == NAME_MIDDLE_INITIAL
1927 // 9 == EMAIL_ADDRESS
1928 // 10 == PHONE_HOME_NUMBER,
1929 // 11 == PHONE_HOME_CITY_CODE,
1930 // 12 == PHONE_HOME_COUNTRY_CODE,
1931 // 13 == PHONE_HOME_CITY_AND_NUMBER,
1932 // 14 == PHONE_HOME_WHOLE_NUMBER,
1933 // 30 == ADDRESS_HOME_LINE1
1934 // 31 == ADDRESS_HOME_LINE2
1935 // 33 == ADDRESS_HOME_CITY
1936 // 34 == ADDRESS_HOME_STATE
1937 // 35 == ADDRESS_HOME_ZIP
1938 // 36 == ADDRESS_HOME_COUNTRY
1939 // 60 == COMPANY_NAME
1940 available_field_types.clear();
1941 available_field_types.insert(NAME_FIRST);
1942 available_field_types.insert(NAME_MIDDLE);
1943 available_field_types.insert(NAME_LAST);
1944 available_field_types.insert(NAME_MIDDLE_INITIAL);
1945 available_field_types.insert(NAME_FULL);
1946 available_field_types.insert(EMAIL_ADDRESS);
1947 available_field_types.insert(PHONE_HOME_NUMBER);
1948 available_field_types.insert(PHONE_HOME_CITY_CODE);
1949 available_field_types.insert(PHONE_HOME_COUNTRY_CODE);
1950 available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER);
1951 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1952 available_field_types.insert(ADDRESS_HOME_LINE1);
1953 available_field_types.insert(ADDRESS_HOME_LINE2);
1954 available_field_types.insert(ADDRESS_HOME_CITY);
1955 available_field_types.insert(ADDRESS_HOME_STATE);
1956 available_field_types.insert(ADDRESS_HOME_ZIP);
1957 available_field_types.insert(ADDRESS_HOME_COUNTRY);
1958 available_field_types.insert(COMPANY_NAME);
1960 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1962 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1963 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1964 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1965 " datapresent=\"1f7e000378000008\">"
1966 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1967 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1968 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1969 "</autofillupload>",
1972 // All supported credit card types available.
1973 // datapresent should be "0000000000001fc0" == trimmmed(0x0000000000001fc0) ==
1974 // 0b0000000000000000000000000000000000000000000000000001111111000000
1975 // The set bits are:
1976 // 51 == CREDIT_CARD_NAME
1977 // 52 == CREDIT_CARD_NUMBER
1978 // 53 == CREDIT_CARD_EXP_MONTH
1979 // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
1980 // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
1981 // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
1982 // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
1983 available_field_types.clear();
1984 available_field_types.insert(CREDIT_CARD_NAME);
1985 available_field_types.insert(CREDIT_CARD_NUMBER);
1986 available_field_types.insert(CREDIT_CARD_EXP_MONTH);
1987 available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
1988 available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
1989 available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
1990 available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
1992 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1994 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1995 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1996 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1997 " datapresent=\"0000000000001fc0\">"
1998 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1999 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2000 "<field signature=\"420638584\" autofilltype=\"1\"/>"
2001 "</autofillupload>",
2004 // All supported types available.
2005 // datapresent should be "1f7e000378001fc8" == trimmmed(0x1f7e000378001fc8) ==
2006 // 0b0001111101111110000000000000001101111000000000000001111111001000
2007 // The set bits are:
2011 // 6 == NAME_MIDDLE_INITIAL
2013 // 9 == EMAIL_ADDRESS
2014 // 10 == PHONE_HOME_NUMBER,
2015 // 11 == PHONE_HOME_CITY_CODE,
2016 // 12 == PHONE_HOME_COUNTRY_CODE,
2017 // 13 == PHONE_HOME_CITY_AND_NUMBER,
2018 // 14 == PHONE_HOME_WHOLE_NUMBER,
2019 // 30 == ADDRESS_HOME_LINE1
2020 // 31 == ADDRESS_HOME_LINE2
2021 // 33 == ADDRESS_HOME_CITY
2022 // 34 == ADDRESS_HOME_STATE
2023 // 35 == ADDRESS_HOME_ZIP
2024 // 36 == ADDRESS_HOME_COUNTRY
2025 // 51 == CREDIT_CARD_NAME
2026 // 52 == CREDIT_CARD_NUMBER
2027 // 53 == CREDIT_CARD_EXP_MONTH
2028 // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
2029 // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
2030 // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
2031 // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
2032 // 60 == COMPANY_NAME
2033 available_field_types.clear();
2034 available_field_types.insert(NAME_FIRST);
2035 available_field_types.insert(NAME_MIDDLE);
2036 available_field_types.insert(NAME_LAST);
2037 available_field_types.insert(NAME_MIDDLE_INITIAL);
2038 available_field_types.insert(NAME_FULL);
2039 available_field_types.insert(EMAIL_ADDRESS);
2040 available_field_types.insert(PHONE_HOME_NUMBER);
2041 available_field_types.insert(PHONE_HOME_CITY_CODE);
2042 available_field_types.insert(PHONE_HOME_COUNTRY_CODE);
2043 available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER);
2044 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
2045 available_field_types.insert(ADDRESS_HOME_LINE1);
2046 available_field_types.insert(ADDRESS_HOME_LINE2);
2047 available_field_types.insert(ADDRESS_HOME_CITY);
2048 available_field_types.insert(ADDRESS_HOME_STATE);
2049 available_field_types.insert(ADDRESS_HOME_ZIP);
2050 available_field_types.insert(ADDRESS_HOME_COUNTRY);
2051 available_field_types.insert(CREDIT_CARD_NAME);
2052 available_field_types.insert(CREDIT_CARD_NUMBER);
2053 available_field_types.insert(CREDIT_CARD_EXP_MONTH);
2054 available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
2055 available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
2056 available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
2057 available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
2058 available_field_types.insert(COMPANY_NAME);
2060 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
2062 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2063 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2064 " formsignature=\"6402244543831589061\" autofillused=\"false\""
2065 " datapresent=\"1f7e000378001fc8\">"
2066 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
2067 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2068 "<field signature=\"420638584\" autofilltype=\"1\"/>"
2069 "</autofillupload>",
2073 TEST(FormStructureTest, CheckMultipleTypes) {
2074 // Throughout this test, datapresent should be
2075 // 0x1440000360000008 ==
2076 // 0b0001010001000000000000000000001101100000000000000000000000001000
2077 // The set bits are:
2080 // 9 == EMAIL_ADDRESS
2081 // 30 == ADDRESS_HOME_LINE1
2082 // 31 == ADDRESS_HOME_LINE2
2083 // 33 == ADDRESS_HOME_CITY
2084 // 34 == ADDRESS_HOME_STATE
2085 // 60 == COMPANY_NAME
2086 ServerFieldTypeSet available_field_types;
2087 available_field_types.insert(NAME_FIRST);
2088 available_field_types.insert(NAME_LAST);
2089 available_field_types.insert(EMAIL_ADDRESS);
2090 available_field_types.insert(ADDRESS_HOME_LINE1);
2091 available_field_types.insert(ADDRESS_HOME_LINE2);
2092 available_field_types.insert(ADDRESS_HOME_CITY);
2093 available_field_types.insert(ADDRESS_HOME_STATE);
2094 available_field_types.insert(COMPANY_NAME);
2096 // Check that multiple types for the field are processed correctly.
2097 scoped_ptr<FormStructure> form_structure;
2098 std::vector<ServerFieldTypeSet> possible_field_types;
2100 form.method = ASCIIToUTF16("post");
2102 FormFieldData field;
2103 field.form_control_type = "text";
2105 field.label = ASCIIToUTF16("email");
2106 field.name = ASCIIToUTF16("email");
2107 form.fields.push_back(field);
2108 possible_field_types.push_back(ServerFieldTypeSet());
2109 possible_field_types.back().insert(EMAIL_ADDRESS);
2111 field.label = ASCIIToUTF16("First Name");
2112 field.name = ASCIIToUTF16("first");
2113 form.fields.push_back(field);
2114 possible_field_types.push_back(ServerFieldTypeSet());
2115 possible_field_types.back().insert(NAME_FIRST);
2117 field.label = ASCIIToUTF16("Last Name");
2118 field.name = ASCIIToUTF16("last");
2119 form.fields.push_back(field);
2120 possible_field_types.push_back(ServerFieldTypeSet());
2121 possible_field_types.back().insert(NAME_LAST);
2123 field.label = ASCIIToUTF16("Address");
2124 field.name = ASCIIToUTF16("address");
2125 form.fields.push_back(field);
2126 possible_field_types.push_back(ServerFieldTypeSet());
2127 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
2129 form_structure.reset(new FormStructure(form));
2131 for (size_t i = 0; i < form_structure->field_count(); ++i)
2132 form_structure->field(i)->set_possible_types(possible_field_types[i]);
2133 std::string encoded_xml;
2135 // Now we matched both fields singularly.
2136 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2138 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2139 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2140 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2141 " datapresent=\"1440000360000008\">"
2142 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2143 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2144 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2145 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2146 "</autofillupload>",
2148 // Match third field as both first and last.
2149 possible_field_types[2].insert(NAME_FIRST);
2150 form_structure->field(2)->set_possible_types(possible_field_types[2]);
2151 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2153 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2154 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2155 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2156 " datapresent=\"1440000360000008\">"
2157 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2158 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2159 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2160 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2161 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2162 "</autofillupload>",
2164 possible_field_types[3].insert(ADDRESS_HOME_LINE2);
2165 form_structure->field(form_structure->field_count() - 1)->set_possible_types(
2166 possible_field_types[form_structure->field_count() - 1]);
2167 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2169 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2170 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2171 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2172 " datapresent=\"1440000360000008\">"
2173 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2174 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2175 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2176 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2177 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2178 "<field signature=\"509334676\" autofilltype=\"31\"/>"
2179 "</autofillupload>",
2181 possible_field_types[3].clear();
2182 possible_field_types[3].insert(ADDRESS_HOME_LINE1);
2183 possible_field_types[3].insert(COMPANY_NAME);
2184 form_structure->field(form_structure->field_count() - 1)->set_possible_types(
2185 possible_field_types[form_structure->field_count() - 1]);
2186 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2188 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2189 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2190 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2191 " datapresent=\"1440000360000008\">"
2192 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2193 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2194 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2195 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2196 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2197 "<field signature=\"509334676\" autofilltype=\"60\"/>"
2198 "</autofillupload>",
2202 TEST(FormStructureTest, CheckFormSignature) {
2203 // Check that form signature is created correctly.
2204 scoped_ptr<FormStructure> form_structure;
2206 form.method = ASCIIToUTF16("post");
2208 FormFieldData field;
2209 field.form_control_type = "text";
2211 field.label = ASCIIToUTF16("email");
2212 field.name = ASCIIToUTF16("email");
2213 form.fields.push_back(field);
2215 field.label = ASCIIToUTF16("First Name");
2216 field.name = ASCIIToUTF16("first");
2217 form.fields.push_back(field);
2219 // Checkable fields shouldn't affect the signature.
2220 field.label = ASCIIToUTF16("Select");
2221 field.name = ASCIIToUTF16("Select");
2222 field.form_control_type = "checkbox";
2223 field.is_checkable = true;
2224 form.fields.push_back(field);
2226 form_structure.reset(new FormStructure(form));
2228 EXPECT_EQ(FormStructureTest::Hash64Bit(
2229 std::string("://&&email&first")),
2230 form_structure->FormSignature());
2232 form.origin = GURL(std::string("http://www.facebook.com"));
2233 form_structure.reset(new FormStructure(form));
2234 EXPECT_EQ(FormStructureTest::Hash64Bit(
2235 std::string("http://www.facebook.com&&email&first")),
2236 form_structure->FormSignature());
2238 form.action = GURL(std::string("https://login.facebook.com/path"));
2239 form_structure.reset(new FormStructure(form));
2240 EXPECT_EQ(FormStructureTest::Hash64Bit(
2241 std::string("https://login.facebook.com&&email&first")),
2242 form_structure->FormSignature());
2244 form.name = ASCIIToUTF16("login_form");
2245 form_structure.reset(new FormStructure(form));
2246 EXPECT_EQ(FormStructureTest::Hash64Bit(
2247 std::string("https://login.facebook.com&login_form&email&first")),
2248 form_structure->FormSignature());
2250 field.is_checkable = false;
2251 field.label = ASCIIToUTF16("Random Field label");
2252 field.name = ASCIIToUTF16("random1234");
2253 field.form_control_type = "text";
2254 form.fields.push_back(field);
2255 field.label = ASCIIToUTF16("Random Field label2");
2256 field.name = ASCIIToUTF16("random12345");
2257 form.fields.push_back(field);
2258 field.label = ASCIIToUTF16("Random Field label3");
2259 field.name = ASCIIToUTF16("1random12345678");
2260 form.fields.push_back(field);
2261 field.label = ASCIIToUTF16("Random Field label3");
2262 field.name = ASCIIToUTF16("12345random");
2263 form.fields.push_back(field);
2264 form_structure.reset(new FormStructure(form));
2265 EXPECT_EQ(FormStructureTest::Hash64Bit(
2266 std::string("https://login.facebook.com&login_form&email&first&"
2267 "random1234&random&1random&random")),
2268 form_structure->FormSignature());
2272 TEST(FormStructureTest, ToFormData) {
2274 form.name = ASCIIToUTF16("the-name");
2275 form.method = ASCIIToUTF16("POST");
2276 form.origin = GURL("http://cool.com");
2277 form.action = form.origin.Resolve("/login");
2279 FormFieldData field;
2280 field.label = ASCIIToUTF16("username");
2281 field.name = ASCIIToUTF16("username");
2282 field.form_control_type = "text";
2283 form.fields.push_back(field);
2285 field.label = ASCIIToUTF16("password");
2286 field.name = ASCIIToUTF16("password");
2287 field.form_control_type = "password";
2288 form.fields.push_back(field);
2290 field.label = base::string16();
2291 field.name = ASCIIToUTF16("Submit");
2292 field.form_control_type = "submit";
2293 form.fields.push_back(field);
2295 EXPECT_EQ(form, FormStructure(form).ToFormData());
2297 // Currently |FormStructure(form_data)ToFormData().user_submitted| is always
2298 // false. This forces a future author that changes this to update this test.
2299 form.user_submitted = true;
2300 EXPECT_NE(form, FormStructure(form).ToFormData());
2303 TEST(FormStructureTest, SkipFieldTest) {
2305 form.name = ASCIIToUTF16("the-name");
2306 form.method = ASCIIToUTF16("POST");
2307 form.origin = GURL("http://cool.com");
2308 form.action = form.origin.Resolve("/login");
2310 FormFieldData field;
2311 field.label = ASCIIToUTF16("username");
2312 field.name = ASCIIToUTF16("username");
2313 field.form_control_type = "text";
2314 form.fields.push_back(field);
2316 field.label = ASCIIToUTF16("select");
2317 field.name = ASCIIToUTF16("select");
2318 field.form_control_type = "checkbox";
2319 field.is_checkable = true;
2320 form.fields.push_back(field);
2322 field.label = base::string16();
2323 field.name = ASCIIToUTF16("email");
2324 field.form_control_type = "text";
2325 field.is_checkable = false;
2326 form.fields.push_back(field);
2328 ScopedVector<FormStructure> forms;
2329 forms.push_back(new FormStructure(form));
2330 std::vector<std::string> encoded_signatures;
2331 std::string encoded_xml;
2333 const char * const kSignature = "18006745212084723782";
2334 const char * const kResponse =
2335 "<\?xml version=\"1.0\" encoding=\"UTF-8\"?><autofillquery "
2336 "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
2337 "signature=\"18006745212084723782\"><field signature=\"239111655\"/>"
2338 "<field signature=\"420638584\"/></form></autofillquery>";
2339 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
2340 &encoded_signatures,
2342 ASSERT_EQ(1U, encoded_signatures.size());
2343 EXPECT_EQ(kSignature, encoded_signatures[0]);
2344 EXPECT_EQ(kResponse, encoded_xml);
2347 } // namespace autofill