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. This should not be considered a
130 field.label = ASCIIToUTF16("address1");
131 field.name = ASCIIToUTF16("address1");
132 field.form_control_type = "text";
133 field.should_autocomplete = false;
134 form.fields.push_back(field);
136 form_structure.reset(new FormStructure(form));
137 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
138 EXPECT_EQ(1U, form_structure->autofill_count());
141 TEST(FormStructureTest, SourceURL) {
143 form.origin = GURL("http://www.foo.com/");
144 form.method = ASCIIToUTF16("post");
145 FormStructure form_structure(form);
147 EXPECT_EQ(form.origin, form_structure.source_url());
150 TEST(FormStructureTest, IsAutofillable) {
151 scoped_ptr<FormStructure> form_structure;
154 // We need at least three text fields to be auto-fillable.
155 form.method = ASCIIToUTF16("post");
159 field.label = ASCIIToUTF16("username");
160 field.name = ASCIIToUTF16("username");
161 field.form_control_type = "text";
162 form.fields.push_back(field);
164 field.label = ASCIIToUTF16("password");
165 field.name = ASCIIToUTF16("password");
166 field.form_control_type = "password";
167 form.fields.push_back(field);
169 field.label = base::string16();
170 field.name = ASCIIToUTF16("Submit");
171 field.form_control_type = "submit";
172 form.fields.push_back(field);
174 form_structure.reset(new FormStructure(form));
175 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
176 EXPECT_FALSE(form_structure->IsAutofillable(true));
178 // We now have three text fields, but only two auto-fillable fields.
179 field.label = ASCIIToUTF16("First Name");
180 field.name = ASCIIToUTF16("firstname");
181 field.form_control_type = "text";
182 form.fields.push_back(field);
184 field.label = ASCIIToUTF16("Last Name");
185 field.name = ASCIIToUTF16("lastname");
186 field.form_control_type = "text";
187 form.fields.push_back(field);
189 form_structure.reset(new FormStructure(form));
190 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
191 EXPECT_FALSE(form_structure->IsAutofillable(true));
193 // We now have three auto-fillable fields.
194 field.label = ASCIIToUTF16("Email");
195 field.name = ASCIIToUTF16("email");
196 field.form_control_type = "email";
197 form.fields.push_back(field);
199 form_structure.reset(new FormStructure(form));
200 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
201 EXPECT_TRUE(form_structure->IsAutofillable(true));
203 // The method must be 'post', though we can intentionally ignore this
204 // criterion for the sake of providing a helpful warning message to the user.
205 form.method = ASCIIToUTF16("get");
206 form_structure.reset(new FormStructure(form));
207 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
208 EXPECT_FALSE(form_structure->IsAutofillable(true));
209 EXPECT_TRUE(form_structure->IsAutofillable(false));
211 // The target cannot include http(s)://*/search...
212 form.method = ASCIIToUTF16("post");
213 form.action = GURL("http://google.com/search?q=hello");
214 form_structure.reset(new FormStructure(form));
215 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
216 EXPECT_FALSE(form_structure->IsAutofillable(true));
218 // But search can be in the URL.
219 form.action = GURL("http://search.com/?q=hello");
220 form_structure.reset(new FormStructure(form));
221 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
222 EXPECT_TRUE(form_structure->IsAutofillable(true));
225 TEST(FormStructureTest, ShouldBeParsed) {
226 scoped_ptr<FormStructure> form_structure;
229 // We need at least three text fields to be parseable.
230 form.method = ASCIIToUTF16("post");
233 field.label = ASCIIToUTF16("username");
234 field.name = ASCIIToUTF16("username");
235 field.form_control_type = "text";
236 form.fields.push_back(field);
238 FormFieldData checkable_field;
239 checkable_field.is_checkable = true;
240 checkable_field.name = ASCIIToUTF16("radiobtn");
241 checkable_field.form_control_type = "radio";
242 form.fields.push_back(checkable_field);
244 checkable_field.name = ASCIIToUTF16("checkbox");
245 checkable_field.form_control_type = "checkbox";
246 form.fields.push_back(checkable_field);
248 // We have only one text field, should not be parsed.
249 form_structure.reset(new FormStructure(form));
250 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
252 // We now have three text fields, though only two are auto-fillable.
253 field.label = ASCIIToUTF16("First Name");
254 field.name = ASCIIToUTF16("firstname");
255 field.form_control_type = "text";
256 form.fields.push_back(field);
258 field.label = ASCIIToUTF16("Last Name");
259 field.name = ASCIIToUTF16("lastname");
260 field.form_control_type = "text";
261 form.fields.push_back(field);
263 form_structure.reset(new FormStructure(form));
264 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
266 // The method must be 'post', though we can intentionally ignore this
267 // criterion for the sake of providing a helpful warning message to the user.
268 form.method = ASCIIToUTF16("get");
269 form_structure.reset(new FormStructure(form));
270 EXPECT_FALSE(form_structure->IsAutofillable(true));
271 EXPECT_TRUE(form_structure->ShouldBeParsed(false));
273 // The target cannot include http(s)://*/search...
274 form.method = ASCIIToUTF16("post");
275 form.action = GURL("http://google.com/search?q=hello");
276 form_structure.reset(new FormStructure(form));
277 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
279 // But search can be in the URL.
280 form.action = GURL("http://search.com/?q=hello");
281 form_structure.reset(new FormStructure(form));
282 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
284 // The form need only have three fields, but at least one must be a text
288 field.label = ASCIIToUTF16("Email");
289 field.name = ASCIIToUTF16("email");
290 field.form_control_type = "email";
291 form.fields.push_back(field);
293 field.label = ASCIIToUTF16("State");
294 field.name = ASCIIToUTF16("state");
295 field.form_control_type = "select-one";
296 form.fields.push_back(field);
298 field.label = ASCIIToUTF16("Country");
299 field.name = ASCIIToUTF16("country");
300 field.form_control_type = "select-one";
301 form.fields.push_back(field);
303 form_structure.reset(new FormStructure(form));
304 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
306 form.fields[0].form_control_type = "select-one";
307 // Now, no text fields.
308 form_structure.reset(new FormStructure(form));
309 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
312 TEST(FormStructureTest, HeuristicsContactInfo) {
313 scoped_ptr<FormStructure> form_structure;
315 form.method = ASCIIToUTF16("post");
318 field.form_control_type = "text";
320 field.label = ASCIIToUTF16("First Name");
321 field.name = ASCIIToUTF16("firstname");
322 form.fields.push_back(field);
324 field.label = ASCIIToUTF16("Last Name");
325 field.name = ASCIIToUTF16("lastname");
326 form.fields.push_back(field);
328 field.label = ASCIIToUTF16("Email");
329 field.name = ASCIIToUTF16("email");
330 form.fields.push_back(field);
332 field.label = ASCIIToUTF16("Phone");
333 field.name = ASCIIToUTF16("phone");
334 form.fields.push_back(field);
336 field.label = ASCIIToUTF16("Address");
337 field.name = ASCIIToUTF16("address");
338 form.fields.push_back(field);
340 field.label = ASCIIToUTF16("City");
341 field.name = ASCIIToUTF16("city");
342 form.fields.push_back(field);
344 field.label = ASCIIToUTF16("Zip code");
345 field.name = ASCIIToUTF16("zipcode");
346 form.fields.push_back(field);
348 field.label = base::string16();
349 field.name = ASCIIToUTF16("Submit");
350 field.form_control_type = "submit";
351 form.fields.push_back(field);
353 form_structure.reset(new FormStructure(form));
354 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
355 EXPECT_TRUE(form_structure->IsAutofillable(true));
357 // Expect the correct number of fields.
358 ASSERT_EQ(8U, form_structure->field_count());
359 ASSERT_EQ(7U, form_structure->autofill_count());
362 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
364 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
366 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
368 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
369 form_structure->field(3)->heuristic_type());
371 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type());
373 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type());
375 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
377 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
380 // Verify that we can correctly process the |autocomplete| attribute.
381 TEST(FormStructureTest, HeuristicsAutocompleteAttribute) {
382 scoped_ptr<FormStructure> form_structure;
384 form.method = ASCIIToUTF16("post");
387 field.form_control_type = "text";
389 field.label = base::string16();
390 field.name = ASCIIToUTF16("field1");
391 field.autocomplete_attribute = "given-name";
392 form.fields.push_back(field);
394 field.label = base::string16();
395 field.name = ASCIIToUTF16("field2");
396 field.autocomplete_attribute = "family-name";
397 form.fields.push_back(field);
399 field.label = base::string16();
400 field.name = ASCIIToUTF16("field3");
401 field.autocomplete_attribute = "email";
402 form.fields.push_back(field);
404 form_structure.reset(new FormStructure(form));
405 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
406 EXPECT_TRUE(form_structure->IsAutofillable(true));
408 // Expect the correct number of fields.
409 ASSERT_EQ(3U, form_structure->field_count());
410 ASSERT_EQ(3U, form_structure->autofill_count());
412 EXPECT_EQ(HTML_TYPE_GIVEN_NAME, form_structure->field(0)->html_type());
413 EXPECT_EQ(HTML_TYPE_FAMILY_NAME, form_structure->field(1)->html_type());
414 EXPECT_EQ(HTML_TYPE_EMAIL, form_structure->field(2)->html_type());
415 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type());
416 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
417 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
420 // Verify that we can correctly process the 'autocomplete' attribute for phone
421 // number types (especially phone prefixes and suffixes).
422 TEST(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
423 scoped_ptr<FormStructure> form_structure;
425 form.method = ASCIIToUTF16("post");
428 field.form_control_type = "text";
430 field.label = base::string16();
431 field.name = ASCIIToUTF16("field1");
432 field.autocomplete_attribute = "tel-local";
433 form.fields.push_back(field);
435 field.label = base::string16();
436 field.name = ASCIIToUTF16("field2");
437 field.autocomplete_attribute = "tel-local-prefix";
438 form.fields.push_back(field);
440 field.label = base::string16();
441 field.name = ASCIIToUTF16("field3");
442 field.autocomplete_attribute = "tel-local-suffix";
443 form.fields.push_back(field);
445 form_structure.reset(new FormStructure(form));
446 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
447 EXPECT_TRUE(form_structure->IsAutofillable(true));
449 // Expect the correct number of fields.
450 ASSERT_EQ(3U, form_structure->field_count());
451 EXPECT_EQ(3U, form_structure->autofill_count());
453 EXPECT_EQ(HTML_TYPE_TEL_LOCAL, form_structure->field(0)->html_type());
454 EXPECT_EQ(AutofillField::IGNORED, form_structure->field(0)->phone_part());
455 EXPECT_EQ(HTML_TYPE_TEL_LOCAL_PREFIX, form_structure->field(1)->html_type());
456 EXPECT_EQ(AutofillField::PHONE_PREFIX,
457 form_structure->field(1)->phone_part());
458 EXPECT_EQ(HTML_TYPE_TEL_LOCAL_SUFFIX, form_structure->field(2)->html_type());
459 EXPECT_EQ(AutofillField::PHONE_SUFFIX,
460 form_structure->field(2)->phone_part());
463 // If at least one field includes type hints in the 'autocomplete' attribute, we
464 // should not try to apply any other heuristics.
465 TEST(FormStructureTest, AutocompleteAttributeOverridesOtherHeuristics) {
466 scoped_ptr<FormStructure> form_structure;
468 form.method = ASCIIToUTF16("post");
470 // Start with a regular contact form.
472 field.form_control_type = "text";
474 field.label = ASCIIToUTF16("First Name");
475 field.name = ASCIIToUTF16("firstname");
476 form.fields.push_back(field);
478 field.label = ASCIIToUTF16("Last Name");
479 field.name = ASCIIToUTF16("lastname");
480 form.fields.push_back(field);
482 field.label = ASCIIToUTF16("Email");
483 field.name = ASCIIToUTF16("email");
484 form.fields.push_back(field);
486 form_structure.reset(new FormStructure(form));
487 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
488 EXPECT_TRUE(form_structure->IsAutofillable(true));
489 EXPECT_TRUE(form_structure->ShouldBeCrowdsourced());
491 ASSERT_EQ(3U, form_structure->field_count());
492 ASSERT_EQ(3U, form_structure->autofill_count());
494 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
495 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
496 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
498 // Now update the first form field to include an 'autocomplete' attribute.
499 form.fields.front().autocomplete_attribute = "x-other";
500 form_structure.reset(new FormStructure(form));
501 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
502 EXPECT_FALSE(form_structure->IsAutofillable(true));
503 EXPECT_FALSE(form_structure->ShouldBeCrowdsourced());
505 ASSERT_EQ(3U, form_structure->field_count());
506 ASSERT_EQ(0U, form_structure->autofill_count());
508 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type());
509 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
510 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
513 // Verify that we can correctly process sections listed in the |autocomplete|
515 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) {
517 form.method = ASCIIToUTF16("post");
520 field.form_control_type = "text";
522 // Some fields will have no section specified. These fall into the default
524 field.autocomplete_attribute = "email";
525 form.fields.push_back(field);
527 // We allow arbitrary section names.
528 field.autocomplete_attribute = "section-foo email";
529 form.fields.push_back(field);
531 // "shipping" and "billing" are special section tokens that don't require the
532 // "section-" prefix.
533 field.autocomplete_attribute = "shipping email";
534 form.fields.push_back(field);
535 field.autocomplete_attribute = "billing email";
536 form.fields.push_back(field);
538 // "shipping" and "billing" can be combined with other section names.
539 field.autocomplete_attribute = "section-foo shipping email";
540 form.fields.push_back(field);
541 field.autocomplete_attribute = "section-foo billing email";
542 form.fields.push_back(field);
544 // We don't do anything clever to try to coalesce sections; it's up to site
545 // authors to avoid typos.
546 field.autocomplete_attribute = "section--foo email";
547 form.fields.push_back(field);
549 // "shipping email" and "section--shipping" email should be parsed as
550 // different sections. This is only an interesting test due to how we
551 // implement implicit section names from attributes like "shipping email"; see
552 // the implementation for more details.
553 field.autocomplete_attribute = "section--shipping email";
554 form.fields.push_back(field);
556 // Credit card fields are implicitly in a separate section from other fields.
557 field.autocomplete_attribute = "section-foo cc-number";
558 form.fields.push_back(field);
560 FormStructure form_structure(form);
561 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
562 EXPECT_TRUE(form_structure.IsAutofillable(true));
564 // Expect the correct number of fields.
565 ASSERT_EQ(9U, form_structure.field_count());
566 EXPECT_EQ(9U, form_structure.autofill_count());
568 // All of the fields in this form should be parsed as belonging to different
570 std::set<std::string> section_names;
571 for (size_t i = 0; i < 9; ++i) {
572 section_names.insert(form_structure.field(i)->section());
574 EXPECT_EQ(9U, section_names.size());
577 // Verify that we can correctly process a degenerate section listed in the
578 // |autocomplete| attribute.
579 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsDegenerate) {
581 form.method = ASCIIToUTF16("post");
584 field.form_control_type = "text";
586 // Some fields will have no section specified. These fall into the default
588 field.autocomplete_attribute = "email";
589 form.fields.push_back(field);
591 // Specifying "section-" is equivalent to not specifying a section.
592 field.autocomplete_attribute = "section- email";
593 form.fields.push_back(field);
595 // Invalid tokens should prevent us from setting a section name.
596 field.autocomplete_attribute = "garbage section-foo email";
597 form.fields.push_back(field);
598 field.autocomplete_attribute = "garbage section-bar email";
599 form.fields.push_back(field);
600 field.autocomplete_attribute = "garbage shipping email";
601 form.fields.push_back(field);
602 field.autocomplete_attribute = "garbage billing email";
603 form.fields.push_back(field);
605 FormStructure form_structure(form);
606 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
608 // Expect the correct number of fields.
609 ASSERT_EQ(6U, form_structure.field_count());
610 EXPECT_EQ(2U, form_structure.autofill_count());
612 // All of the fields in this form should be parsed as belonging to the same
614 std::set<std::string> section_names;
615 for (size_t i = 0; i < 6; ++i) {
616 section_names.insert(form_structure.field(i)->section());
618 EXPECT_EQ(1U, section_names.size());
621 // Verify that we can correctly process repeated sections listed in the
622 // |autocomplete| attribute.
623 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsRepeated) {
625 form.method = ASCIIToUTF16("post");
628 field.form_control_type = "text";
630 field.autocomplete_attribute = "section-foo email";
631 form.fields.push_back(field);
632 field.autocomplete_attribute = "section-foo address-line1";
633 form.fields.push_back(field);
635 FormStructure form_structure(form);
636 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
638 // Expect the correct number of fields.
639 ASSERT_EQ(2U, form_structure.field_count());
640 EXPECT_EQ(2U, form_structure.autofill_count());
642 // All of the fields in this form should be parsed as belonging to the same
644 std::set<std::string> section_names;
645 for (size_t i = 0; i < 2; ++i) {
646 section_names.insert(form_structure.field(i)->section());
648 EXPECT_EQ(1U, section_names.size());
651 // Verify that we do not override the author-specified sections from a form with
653 TEST(FormStructureTest, HeuristicsDontOverrideAutocompleteAttributeSections) {
655 form.method = ASCIIToUTF16("post");
658 field.form_control_type = "text";
660 field.name = ASCIIToUTF16("one");
661 field.autocomplete_attribute = "address-line1";
662 form.fields.push_back(field);
663 field.name = base::string16();
664 field.autocomplete_attribute = "section-foo email";
665 form.fields.push_back(field);
666 field.name = base::string16();
667 field.autocomplete_attribute = "name";
668 form.fields.push_back(field);
669 field.name = ASCIIToUTF16("two");
670 field.autocomplete_attribute = "address-line1";
671 form.fields.push_back(field);
673 FormStructure form_structure(form);
674 form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
676 // Expect the correct number of fields.
677 ASSERT_EQ(4U, form_structure.field_count());
678 EXPECT_EQ(4U, form_structure.autofill_count());
680 // Normally, the two separate address fields would cause us to detect two
681 // separate sections; but because there is an author-specified section in this
682 // form, we do not apply these usual heuristics.
683 EXPECT_EQ(ASCIIToUTF16("one"), form_structure.field(0)->name);
684 EXPECT_EQ(ASCIIToUTF16("two"), form_structure.field(3)->name);
685 EXPECT_EQ(form_structure.field(0)->section(),
686 form_structure.field(3)->section());
689 TEST(FormStructureTest, HeuristicsSample8) {
690 scoped_ptr<FormStructure> form_structure;
692 form.method = ASCIIToUTF16("post");
695 field.form_control_type = "text";
697 field.label = ASCIIToUTF16("Your First Name:");
698 field.name = ASCIIToUTF16("bill.first");
699 form.fields.push_back(field);
701 field.label = ASCIIToUTF16("Your Last Name:");
702 field.name = ASCIIToUTF16("bill.last");
703 form.fields.push_back(field);
705 field.label = ASCIIToUTF16("Street Address Line 1:");
706 field.name = ASCIIToUTF16("bill.street1");
707 form.fields.push_back(field);
709 field.label = ASCIIToUTF16("Street Address Line 2:");
710 field.name = ASCIIToUTF16("bill.street2");
711 form.fields.push_back(field);
713 field.label = ASCIIToUTF16("City");
714 field.name = ASCIIToUTF16("bill.city");
715 form.fields.push_back(field);
717 field.label = ASCIIToUTF16("State (U.S.):");
718 field.name = ASCIIToUTF16("bill.state");
719 form.fields.push_back(field);
721 field.label = ASCIIToUTF16("Zip/Postal Code:");
722 field.name = ASCIIToUTF16("BillTo.PostalCode");
723 form.fields.push_back(field);
725 field.label = ASCIIToUTF16("Country:");
726 field.name = ASCIIToUTF16("bill.country");
727 form.fields.push_back(field);
729 field.label = ASCIIToUTF16("Phone Number:");
730 field.name = ASCIIToUTF16("BillTo.Phone");
731 form.fields.push_back(field);
733 field.label = base::string16();
734 field.name = ASCIIToUTF16("Submit");
735 field.form_control_type = "submit";
736 form.fields.push_back(field);
738 form_structure.reset(new FormStructure(form));
739 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
740 EXPECT_TRUE(form_structure->IsAutofillable(true));
741 ASSERT_EQ(10U, form_structure->field_count());
742 ASSERT_EQ(9U, form_structure->autofill_count());
745 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
747 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
749 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(2)->heuristic_type());
751 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(3)->heuristic_type());
753 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
755 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(5)->heuristic_type());
757 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
759 EXPECT_EQ(ADDRESS_HOME_COUNTRY, form_structure->field(7)->heuristic_type());
761 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
762 form_structure->field(8)->heuristic_type());
764 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type());
767 TEST(FormStructureTest, HeuristicsSample6) {
768 scoped_ptr<FormStructure> form_structure;
770 form.method = ASCIIToUTF16("post");
773 field.form_control_type = "text";
775 field.label = ASCIIToUTF16("E-mail address");
776 field.name = ASCIIToUTF16("email");
777 form.fields.push_back(field);
779 field.label = ASCIIToUTF16("Full name");
780 field.name = ASCIIToUTF16("name");
781 form.fields.push_back(field);
783 field.label = ASCIIToUTF16("Company");
784 field.name = ASCIIToUTF16("company");
785 form.fields.push_back(field);
787 field.label = ASCIIToUTF16("Address");
788 field.name = ASCIIToUTF16("address");
789 form.fields.push_back(field);
791 field.label = ASCIIToUTF16("City");
792 field.name = ASCIIToUTF16("city");
793 form.fields.push_back(field);
795 field.label = ASCIIToUTF16("Zip Code");
796 field.name = ASCIIToUTF16("Home.PostalCode");
797 form.fields.push_back(field);
799 field.label = base::string16();
800 field.name = ASCIIToUTF16("Submit");
801 field.value = ASCIIToUTF16("continue");
802 field.form_control_type = "submit";
803 form.fields.push_back(field);
805 form_structure.reset(new FormStructure(form));
806 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
807 EXPECT_TRUE(form_structure->IsAutofillable(true));
808 ASSERT_EQ(7U, form_structure->field_count());
809 ASSERT_EQ(6U, form_structure->autofill_count());
812 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(0)->heuristic_type());
814 EXPECT_EQ(NAME_FULL, form_structure->field(1)->heuristic_type());
816 EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
818 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type());
820 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
822 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(5)->heuristic_type());
824 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
827 // Tests a sequence of FormFields where only labels are supplied to heuristics
828 // for matching. This works because FormFieldData labels are matched in the
829 // case that input element ids (or |name| fields) are missing.
830 TEST(FormStructureTest, HeuristicsLabelsOnly) {
831 scoped_ptr<FormStructure> form_structure;
833 form.method = ASCIIToUTF16("post");
836 field.form_control_type = "text";
838 field.label = ASCIIToUTF16("First Name");
839 field.name = base::string16();
840 form.fields.push_back(field);
842 field.label = ASCIIToUTF16("Last Name");
843 field.name = base::string16();
844 form.fields.push_back(field);
846 field.label = ASCIIToUTF16("Email");
847 field.name = base::string16();
848 form.fields.push_back(field);
850 field.label = ASCIIToUTF16("Phone");
851 field.name = base::string16();
852 form.fields.push_back(field);
854 field.label = ASCIIToUTF16("Address");
855 field.name = base::string16();
856 form.fields.push_back(field);
858 field.label = ASCIIToUTF16("Address");
859 field.name = base::string16();
860 form.fields.push_back(field);
862 field.label = ASCIIToUTF16("Zip code");
863 field.name = base::string16();
864 form.fields.push_back(field);
866 field.label = base::string16();
867 field.name = ASCIIToUTF16("Submit");
868 field.form_control_type = "submit";
869 form.fields.push_back(field);
871 form_structure.reset(new FormStructure(form));
872 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
873 EXPECT_TRUE(form_structure->IsAutofillable(true));
874 ASSERT_EQ(8U, form_structure->field_count());
875 ASSERT_EQ(7U, form_structure->autofill_count());
878 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
880 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
882 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
884 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
885 form_structure->field(3)->heuristic_type());
887 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type());
889 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(5)->heuristic_type());
891 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
893 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
896 TEST(FormStructureTest, HeuristicsCreditCardInfo) {
897 scoped_ptr<FormStructure> form_structure;
899 form.method = ASCIIToUTF16("post");
902 field.form_control_type = "text";
904 field.label = ASCIIToUTF16("Name on Card");
905 field.name = ASCIIToUTF16("name_on_card");
906 form.fields.push_back(field);
908 field.label = ASCIIToUTF16("Card Number");
909 field.name = ASCIIToUTF16("card_number");
910 form.fields.push_back(field);
912 field.label = ASCIIToUTF16("Exp Month");
913 field.name = ASCIIToUTF16("ccmonth");
914 form.fields.push_back(field);
916 field.label = ASCIIToUTF16("Exp Year");
917 field.name = ASCIIToUTF16("ccyear");
918 form.fields.push_back(field);
920 field.label = ASCIIToUTF16("Verification");
921 field.name = ASCIIToUTF16("verification");
922 form.fields.push_back(field);
924 field.label = base::string16();
925 field.name = ASCIIToUTF16("Submit");
926 field.form_control_type = "submit";
927 form.fields.push_back(field);
929 form_structure.reset(new FormStructure(form));
930 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
931 EXPECT_TRUE(form_structure->IsAutofillable(true));
932 ASSERT_EQ(6U, form_structure->field_count());
933 ASSERT_EQ(5U, form_structure->autofill_count());
936 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
937 // Credit card number.
938 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type());
939 // Credit card expiration month.
940 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(2)->heuristic_type());
941 // Credit card expiration year.
942 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
943 form_structure->field(3)->heuristic_type());
945 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
946 form_structure->field(4)->heuristic_type());
948 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
951 TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
952 scoped_ptr<FormStructure> form_structure;
954 form.method = ASCIIToUTF16("post");
957 field.form_control_type = "text";
959 field.label = ASCIIToUTF16("Name on Card");
960 field.name = ASCIIToUTF16("name_on_card");
961 form.fields.push_back(field);
963 // This is not a field we know how to process. But we should skip over it
964 // and process the other fields in the card block.
965 field.label = ASCIIToUTF16("Card image");
966 field.name = ASCIIToUTF16("card_image");
967 form.fields.push_back(field);
969 field.label = ASCIIToUTF16("Card Number");
970 field.name = ASCIIToUTF16("card_number");
971 form.fields.push_back(field);
973 field.label = ASCIIToUTF16("Exp Month");
974 field.name = ASCIIToUTF16("ccmonth");
975 form.fields.push_back(field);
977 field.label = ASCIIToUTF16("Exp Year");
978 field.name = ASCIIToUTF16("ccyear");
979 form.fields.push_back(field);
981 field.label = ASCIIToUTF16("Verification");
982 field.name = ASCIIToUTF16("verification");
983 form.fields.push_back(field);
985 field.label = base::string16();
986 field.name = ASCIIToUTF16("Submit");
987 field.form_control_type = "submit";
988 form.fields.push_back(field);
990 form_structure.reset(new FormStructure(form));
991 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
992 EXPECT_TRUE(form_structure->IsAutofillable(true));
993 ASSERT_EQ(7U, form_structure->field_count());
994 ASSERT_EQ(5U, form_structure->autofill_count());
997 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
998 // Credit card type. This is an unknown type but related to the credit card.
999 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
1000 // Credit card number.
1001 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type());
1002 // Credit card expiration month.
1003 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1004 // Credit card expiration year.
1005 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1006 form_structure->field(4)->heuristic_type());
1008 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
1009 form_structure->field(5)->heuristic_type());
1011 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
1014 TEST(FormStructureTest, ThreeAddressLines) {
1015 scoped_ptr<FormStructure> form_structure;
1017 form.method = ASCIIToUTF16("post");
1019 FormFieldData field;
1020 field.form_control_type = "text";
1022 field.label = ASCIIToUTF16("Address Line1");
1023 field.name = ASCIIToUTF16("Address");
1024 form.fields.push_back(field);
1026 field.label = ASCIIToUTF16("Address Line2");
1027 field.name = ASCIIToUTF16("Address");
1028 form.fields.push_back(field);
1030 field.label = ASCIIToUTF16("Address Line3");
1031 field.name = ASCIIToUTF16("Address");
1032 form.fields.push_back(field);
1034 field.label = ASCIIToUTF16("City");
1035 field.name = ASCIIToUTF16("city");
1036 form.fields.push_back(field);
1038 form_structure.reset(new FormStructure(form));
1039 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1040 EXPECT_TRUE(form_structure->IsAutofillable(true));
1041 ASSERT_EQ(4U, form_structure->field_count());
1042 ASSERT_EQ(3U, form_structure->autofill_count());
1045 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1047 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1049 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1051 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
1054 // Numbered address lines after line two are ignored.
1055 TEST(FormStructureTest, SurplusAddressLinesIgnored) {
1056 scoped_ptr<FormStructure> form_structure;
1058 form.method = ASCIIToUTF16("post");
1060 FormFieldData field;
1061 field.form_control_type = "text";
1063 field.label = ASCIIToUTF16("Address Line1");
1064 field.name = ASCIIToUTF16("shipping.address.addressLine1");
1065 form.fields.push_back(field);
1067 field.label = ASCIIToUTF16("Address Line2");
1068 field.name = ASCIIToUTF16("shipping.address.addressLine2");
1069 form.fields.push_back(field);
1071 field.label = ASCIIToUTF16("Address Line3");
1072 field.name = ASCIIToUTF16("billing.address.addressLine3");
1073 form.fields.push_back(field);
1075 field.label = ASCIIToUTF16("Address Line4");
1076 field.name = ASCIIToUTF16("billing.address.addressLine4");
1077 form.fields.push_back(field);
1079 form_structure.reset(new FormStructure(form));
1080 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1081 ASSERT_EQ(4U, form_structure->field_count());
1082 ASSERT_EQ(2U, form_structure->autofill_count());
1085 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1087 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1088 // Address Line 3 (ignored).
1089 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1090 // Address Line 4 (ignored).
1091 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
1094 // This example comes from expedia.com where they use a "Suite" label to
1095 // indicate a suite or apartment number. We interpret this as address line 2.
1096 // And the following "Street address second line" we interpret as address line
1098 // See http://crbug.com/48197 for details.
1099 TEST(FormStructureTest, ThreeAddressLinesExpedia) {
1100 scoped_ptr<FormStructure> form_structure;
1102 form.method = ASCIIToUTF16("post");
1104 FormFieldData field;
1105 field.form_control_type = "text";
1107 field.label = ASCIIToUTF16("Street:");
1108 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1");
1109 form.fields.push_back(field);
1111 field.label = ASCIIToUTF16("Suite or Apt:");
1112 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap");
1113 form.fields.push_back(field);
1115 field.label = ASCIIToUTF16("Street address second line");
1116 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads2");
1117 form.fields.push_back(field);
1119 field.label = ASCIIToUTF16("City:");
1120 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adct");
1121 form.fields.push_back(field);
1123 form_structure.reset(new FormStructure(form));
1124 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1125 EXPECT_TRUE(form_structure->IsAutofillable(true));
1126 ASSERT_EQ(4U, form_structure->field_count());
1127 EXPECT_EQ(3U, form_structure->autofill_count());
1130 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1132 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1134 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1136 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
1139 // This example comes from ebay.com where the word "suite" appears in the label
1140 // and the name "address2" clearly indicates that this is the address line 2.
1141 // See http://crbug.com/48197 for details.
1142 TEST(FormStructureTest, TwoAddressLinesEbay) {
1143 scoped_ptr<FormStructure> form_structure;
1145 form.method = ASCIIToUTF16("post");
1147 FormFieldData field;
1148 field.form_control_type = "text";
1150 field.label = ASCIIToUTF16("Address Line1");
1151 field.name = ASCIIToUTF16("address1");
1152 form.fields.push_back(field);
1154 field.label = ASCIIToUTF16("Floor number, suite number, etc");
1155 field.name = ASCIIToUTF16("address2");
1156 form.fields.push_back(field);
1158 field.label = ASCIIToUTF16("City:");
1159 field.name = ASCIIToUTF16("city");
1160 form.fields.push_back(field);
1162 form_structure.reset(new FormStructure(form));
1163 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1164 EXPECT_TRUE(form_structure->IsAutofillable(true));
1165 ASSERT_EQ(3U, form_structure->field_count());
1166 ASSERT_EQ(3U, form_structure->autofill_count());
1169 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1171 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1173 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(2)->heuristic_type());
1176 TEST(FormStructureTest, HeuristicsStateWithProvince) {
1177 scoped_ptr<FormStructure> form_structure;
1179 form.method = ASCIIToUTF16("post");
1181 FormFieldData field;
1182 field.form_control_type = "text";
1184 field.label = ASCIIToUTF16("Address Line1");
1185 field.name = ASCIIToUTF16("Address");
1186 form.fields.push_back(field);
1188 field.label = ASCIIToUTF16("Address Line2");
1189 field.name = ASCIIToUTF16("Address");
1190 form.fields.push_back(field);
1192 field.label = ASCIIToUTF16("State/Province/Region");
1193 field.name = ASCIIToUTF16("State");
1194 form.fields.push_back(field);
1196 form_structure.reset(new FormStructure(form));
1197 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1198 EXPECT_TRUE(form_structure->IsAutofillable(true));
1199 ASSERT_EQ(3U, form_structure->field_count());
1200 ASSERT_EQ(3U, form_structure->autofill_count());
1203 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1205 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1207 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(2)->heuristic_type());
1210 // This example comes from lego.com's checkout page.
1211 TEST(FormStructureTest, HeuristicsWithBilling) {
1212 scoped_ptr<FormStructure> form_structure;
1214 form.method = ASCIIToUTF16("post");
1216 FormFieldData field;
1217 field.form_control_type = "text";
1219 field.label = ASCIIToUTF16("First Name*:");
1220 field.name = ASCIIToUTF16("editBillingAddress$firstNameBox");
1221 form.fields.push_back(field);
1223 field.label = ASCIIToUTF16("Last Name*:");
1224 field.name = ASCIIToUTF16("editBillingAddress$lastNameBox");
1225 form.fields.push_back(field);
1227 field.label = ASCIIToUTF16("Company Name:");
1228 field.name = ASCIIToUTF16("editBillingAddress$companyBox");
1229 form.fields.push_back(field);
1231 field.label = ASCIIToUTF16("Address*:");
1232 field.name = ASCIIToUTF16("editBillingAddress$addressLine1Box");
1233 form.fields.push_back(field);
1235 field.label = ASCIIToUTF16("Apt/Suite :");
1236 field.name = ASCIIToUTF16("editBillingAddress$addressLine2Box");
1237 form.fields.push_back(field);
1239 field.label = ASCIIToUTF16("City*:");
1240 field.name = ASCIIToUTF16("editBillingAddress$cityBox");
1241 form.fields.push_back(field);
1243 field.label = ASCIIToUTF16("State/Province*:");
1244 field.name = ASCIIToUTF16("editBillingAddress$stateDropDown");
1245 form.fields.push_back(field);
1247 field.label = ASCIIToUTF16("Country*:");
1248 field.name = ASCIIToUTF16("editBillingAddress$countryDropDown");
1249 form.fields.push_back(field);
1251 field.label = ASCIIToUTF16("Postal Code*:");
1252 field.name = ASCIIToUTF16("editBillingAddress$zipCodeBox");
1253 form.fields.push_back(field);
1255 field.label = ASCIIToUTF16("Phone*:");
1256 field.name = ASCIIToUTF16("editBillingAddress$phoneBox");
1257 form.fields.push_back(field);
1259 field.label = ASCIIToUTF16("Email Address*:");
1260 field.name = ASCIIToUTF16("email$emailBox");
1261 form.fields.push_back(field);
1263 form_structure.reset(new FormStructure(form));
1264 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1265 EXPECT_TRUE(form_structure->IsAutofillable(true));
1266 ASSERT_EQ(11U, form_structure->field_count());
1267 ASSERT_EQ(11U, form_structure->autofill_count());
1269 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
1270 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
1271 EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
1272 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type());
1273 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(4)->heuristic_type());
1274 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type());
1275 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(6)->heuristic_type());
1276 EXPECT_EQ(ADDRESS_HOME_COUNTRY, form_structure->field(7)->heuristic_type());
1277 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(8)->heuristic_type());
1278 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
1279 form_structure->field(9)->heuristic_type());
1280 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(10)->heuristic_type());
1283 TEST(FormStructureTest, ThreePartPhoneNumber) {
1284 scoped_ptr<FormStructure> form_structure;
1286 form.method = ASCIIToUTF16("post");
1288 FormFieldData field;
1289 field.form_control_type = "text";
1291 field.label = ASCIIToUTF16("Phone:");
1292 field.name = ASCIIToUTF16("dayphone1");
1293 field.max_length = 0;
1294 form.fields.push_back(field);
1296 field.label = ASCIIToUTF16("-");
1297 field.name = ASCIIToUTF16("dayphone2");
1298 field.max_length = 3; // Size of prefix is 3.
1299 form.fields.push_back(field);
1301 field.label = ASCIIToUTF16("-");
1302 field.name = ASCIIToUTF16("dayphone3");
1303 field.max_length = 4; // Size of suffix is 4. If unlimited size is
1304 // passed, phone will be parsed as
1305 // <country code> - <area code> - <phone>.
1306 form.fields.push_back(field);
1308 field.label = ASCIIToUTF16("ext.:");
1309 field.name = ASCIIToUTF16("dayphone4");
1310 field.max_length = 0;
1311 form.fields.push_back(field);
1313 form_structure.reset(new FormStructure(form));
1314 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1315 EXPECT_TRUE(form_structure->IsAutofillable(true));
1316 ASSERT_EQ(4U, form_structure->field_count());
1317 ASSERT_EQ(3U, form_structure->autofill_count());
1320 EXPECT_EQ(PHONE_HOME_CITY_CODE, form_structure->field(0)->heuristic_type());
1321 // Phone number suffix.
1322 EXPECT_EQ(PHONE_HOME_NUMBER,
1323 form_structure->field(1)->heuristic_type());
1324 // Phone number suffix.
1325 EXPECT_EQ(PHONE_HOME_NUMBER,
1326 form_structure->field(2)->heuristic_type());
1328 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
1331 TEST(FormStructureTest, HeuristicsInfernoCC) {
1332 scoped_ptr<FormStructure> form_structure;
1334 form.method = ASCIIToUTF16("post");
1336 FormFieldData field;
1337 field.form_control_type = "text";
1339 field.label = ASCIIToUTF16("Name on Card");
1340 field.name = ASCIIToUTF16("name_on_card");
1341 form.fields.push_back(field);
1343 field.label = ASCIIToUTF16("Address");
1344 field.name = ASCIIToUTF16("billing_address");
1345 form.fields.push_back(field);
1347 field.label = ASCIIToUTF16("Card Number");
1348 field.name = ASCIIToUTF16("card_number");
1349 form.fields.push_back(field);
1351 field.label = ASCIIToUTF16("Expiration Date");
1352 field.name = ASCIIToUTF16("expiration_month");
1353 form.fields.push_back(field);
1355 field.label = ASCIIToUTF16("Expiration Year");
1356 field.name = ASCIIToUTF16("expiration_year");
1357 form.fields.push_back(field);
1359 form_structure.reset(new FormStructure(form));
1360 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1361 EXPECT_TRUE(form_structure->IsAutofillable(true));
1363 // Expect the correct number of fields.
1364 ASSERT_EQ(5U, form_structure->field_count());
1365 EXPECT_EQ(5U, form_structure->autofill_count());
1368 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
1370 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(1)->heuristic_type());
1372 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type());
1374 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1376 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1377 form_structure->field(4)->heuristic_type());
1380 TEST(FormStructureTest, CVCCodeClash) {
1381 scoped_ptr<FormStructure> form_structure;
1383 form.method = ASCIIToUTF16("post");
1385 FormFieldData field;
1386 field.form_control_type = "text";
1388 field.label = ASCIIToUTF16("Card number");
1389 field.name = ASCIIToUTF16("ccnumber");
1390 form.fields.push_back(field);
1392 field.label = ASCIIToUTF16("First name");
1393 field.name = ASCIIToUTF16("first_name");
1394 form.fields.push_back(field);
1396 field.label = ASCIIToUTF16("Last name");
1397 field.name = ASCIIToUTF16("last_name");
1398 form.fields.push_back(field);
1400 field.label = ASCIIToUTF16("Expiration date");
1401 field.name = ASCIIToUTF16("ccexpiresmonth");
1402 form.fields.push_back(field);
1404 field.label = base::string16();
1405 field.name = ASCIIToUTF16("ccexpiresyear");
1406 form.fields.push_back(field);
1408 field.label = ASCIIToUTF16("cvc number");
1409 field.name = ASCIIToUTF16("csc");
1410 form.fields.push_back(field);
1412 form_structure.reset(new FormStructure(form));
1413 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1414 EXPECT_TRUE(form_structure->IsAutofillable(true));
1416 // Expect the correct number of fields.
1417 ASSERT_EQ(6U, form_structure->field_count());
1418 ASSERT_EQ(5U, form_structure->autofill_count());
1421 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(0)->heuristic_type());
1422 // First name, taken as name on card.
1423 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(1)->heuristic_type());
1424 // Last name is not merged.
1425 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1427 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1429 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1430 form_structure->field(4)->heuristic_type());
1432 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
1433 form_structure->field(5)->heuristic_type());
1436 TEST(FormStructureTest, EncodeQueryRequest) {
1438 form.method = ASCIIToUTF16("post");
1440 FormFieldData field;
1441 field.form_control_type = "text";
1443 field.label = ASCIIToUTF16("Name on Card");
1444 field.name = ASCIIToUTF16("name_on_card");
1445 form.fields.push_back(field);
1447 field.label = ASCIIToUTF16("Address");
1448 field.name = ASCIIToUTF16("billing_address");
1449 form.fields.push_back(field);
1451 field.label = ASCIIToUTF16("Card Number");
1452 field.name = ASCIIToUTF16("card_number");
1453 form.fields.push_back(field);
1455 field.label = ASCIIToUTF16("Expiration Date");
1456 field.name = ASCIIToUTF16("expiration_month");
1457 form.fields.push_back(field);
1459 field.label = ASCIIToUTF16("Expiration Year");
1460 field.name = ASCIIToUTF16("expiration_year");
1461 form.fields.push_back(field);
1463 // Add checkable field.
1464 FormFieldData checkable_field;
1465 checkable_field.is_checkable = true;
1466 checkable_field.label = ASCIIToUTF16("Checkable1");
1467 checkable_field.name = ASCIIToUTF16("Checkable1");
1468 form.fields.push_back(checkable_field);
1470 ScopedVector<FormStructure> forms;
1471 forms.push_back(new FormStructure(form));
1472 std::vector<std::string> encoded_signatures;
1473 std::string encoded_xml;
1474 const char kSignature1[] = "11337937696949187602";
1475 const char kResponse1[] =
1476 "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1477 "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
1478 "<form signature=\"11337937696949187602\">"
1479 "<field signature=\"412125936\"/>"
1480 "<field signature=\"1917667676\"/>"
1481 "<field signature=\"2226358947\"/>"
1482 "<field signature=\"747221617\"/>"
1483 "<field signature=\"4108155786\"/>"
1486 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1487 &encoded_signatures,
1489 ASSERT_EQ(1U, encoded_signatures.size());
1490 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1491 EXPECT_EQ(kResponse1, encoded_xml);
1493 // Add the same form, only one will be encoded, so EncodeQueryRequest() should
1494 // return the same data.
1495 forms.push_back(new FormStructure(form));
1496 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1497 &encoded_signatures,
1499 ASSERT_EQ(1U, encoded_signatures.size());
1500 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1501 EXPECT_EQ(kResponse1, encoded_xml);
1502 // Add 5 address fields - this should be still a valid form.
1503 for (size_t i = 0; i < 5; ++i) {
1504 field.label = ASCIIToUTF16("Address");
1505 field.name = ASCIIToUTF16("address");
1506 form.fields.push_back(field);
1509 forms.push_back(new FormStructure(form));
1510 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1511 &encoded_signatures,
1513 ASSERT_EQ(2U, encoded_signatures.size());
1514 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1515 const char kSignature2[] = "8308881815906226214";
1516 EXPECT_EQ(kSignature2, encoded_signatures[1]);
1517 const char kResponse2[] =
1518 "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1519 "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
1520 "<form signature=\"11337937696949187602\">"
1521 "<field signature=\"412125936\"/>"
1522 "<field signature=\"1917667676\"/>"
1523 "<field signature=\"2226358947\"/>"
1524 "<field signature=\"747221617\"/>"
1525 "<field signature=\"4108155786\"/>"
1527 "<form signature=\"8308881815906226214\">"
1528 "<field signature=\"412125936\"/>"
1529 "<field signature=\"1917667676\"/>"
1530 "<field signature=\"2226358947\"/>"
1531 "<field signature=\"747221617\"/>"
1532 "<field signature=\"4108155786\"/>"
1533 "<field signature=\"509334676\"/>"
1534 "<field signature=\"509334676\"/>"
1535 "<field signature=\"509334676\"/>"
1536 "<field signature=\"509334676\"/>"
1537 "<field signature=\"509334676\"/>"
1540 EXPECT_EQ(kResponse2, encoded_xml);
1542 FormData malformed_form(form);
1543 // Add 50 address fields - the form is not valid anymore, but previous ones
1544 // are. The result should be the same as in previous test.
1545 for (size_t i = 0; i < 50; ++i) {
1546 field.label = ASCIIToUTF16("Address");
1547 field.name = ASCIIToUTF16("address");
1548 malformed_form.fields.push_back(field);
1551 forms.push_back(new FormStructure(malformed_form));
1552 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1553 &encoded_signatures,
1555 ASSERT_EQ(2U, encoded_signatures.size());
1556 EXPECT_EQ(kSignature1, encoded_signatures[0]);
1557 EXPECT_EQ(kSignature2, encoded_signatures[1]);
1558 EXPECT_EQ(kResponse2, encoded_xml);
1560 // Check that we fail if there are only bad form(s).
1561 ScopedVector<FormStructure> bad_forms;
1562 bad_forms.push_back(new FormStructure(malformed_form));
1563 EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms.get(),
1564 &encoded_signatures,
1566 EXPECT_EQ(0U, encoded_signatures.size());
1567 EXPECT_EQ("", encoded_xml);
1570 TEST(FormStructureTest, EncodeUploadRequest) {
1571 scoped_ptr<FormStructure> form_structure;
1572 std::vector<ServerFieldTypeSet> possible_field_types;
1574 form.method = ASCIIToUTF16("post");
1575 form_structure.reset(new FormStructure(form));
1576 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1578 FormFieldData field;
1579 field.form_control_type = "text";
1581 field.label = ASCIIToUTF16("First Name");
1582 field.name = ASCIIToUTF16("firstname");
1583 form.fields.push_back(field);
1584 possible_field_types.push_back(ServerFieldTypeSet());
1585 possible_field_types.back().insert(NAME_FIRST);
1587 field.label = ASCIIToUTF16("Last Name");
1588 field.name = ASCIIToUTF16("lastname");
1589 form.fields.push_back(field);
1590 possible_field_types.push_back(ServerFieldTypeSet());
1591 possible_field_types.back().insert(NAME_LAST);
1593 field.label = ASCIIToUTF16("Email");
1594 field.name = ASCIIToUTF16("email");
1595 field.form_control_type = "email";
1596 form.fields.push_back(field);
1597 possible_field_types.push_back(ServerFieldTypeSet());
1598 possible_field_types.back().insert(EMAIL_ADDRESS);
1600 field.label = ASCIIToUTF16("Phone");
1601 field.name = ASCIIToUTF16("phone");
1602 field.form_control_type = "number";
1603 form.fields.push_back(field);
1604 possible_field_types.push_back(ServerFieldTypeSet());
1605 possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
1607 field.label = ASCIIToUTF16("Country");
1608 field.name = ASCIIToUTF16("country");
1609 field.form_control_type = "select-one";
1610 form.fields.push_back(field);
1611 possible_field_types.push_back(ServerFieldTypeSet());
1612 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1614 // Add checkable field.
1615 FormFieldData checkable_field;
1616 checkable_field.is_checkable = true;
1617 checkable_field.label = ASCIIToUTF16("Checkable1");
1618 checkable_field.name = ASCIIToUTF16("Checkable1");
1619 form.fields.push_back(checkable_field);
1620 possible_field_types.push_back(ServerFieldTypeSet());
1621 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1623 form_structure.reset(new FormStructure(form));
1625 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1626 for (size_t i = 0; i < form_structure->field_count(); ++i)
1627 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1629 ServerFieldTypeSet available_field_types;
1630 available_field_types.insert(NAME_FIRST);
1631 available_field_types.insert(NAME_LAST);
1632 available_field_types.insert(ADDRESS_HOME_LINE1);
1633 available_field_types.insert(ADDRESS_HOME_LINE2);
1634 available_field_types.insert(ADDRESS_HOME_COUNTRY);
1635 available_field_types.insert(ADDRESS_BILLING_LINE1);
1636 available_field_types.insert(ADDRESS_BILLING_LINE2);
1637 available_field_types.insert(EMAIL_ADDRESS);
1638 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1640 std::string encoded_xml;
1641 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
1643 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1644 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1645 "formsignature=\"8736493185895608956\" autofillused=\"false\" "
1646 "datapresent=\"144200030e\">"
1647 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1648 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1649 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1650 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1651 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1652 "</autofillupload>",
1654 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
1656 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1657 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1658 "formsignature=\"8736493185895608956\" autofillused=\"true\" "
1659 "datapresent=\"144200030e\">"
1660 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1661 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1662 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1663 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1664 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1665 "</autofillupload>",
1668 // Add 2 address fields - this should be still a valid form.
1669 for (size_t i = 0; i < 2; ++i) {
1670 field.label = ASCIIToUTF16("Address");
1671 field.name = ASCIIToUTF16("address");
1672 field.form_control_type = "text";
1673 form.fields.push_back(field);
1674 possible_field_types.push_back(ServerFieldTypeSet());
1675 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1676 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1677 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1678 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1681 form_structure.reset(new FormStructure(form));
1682 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1683 for (size_t i = 0; i < form_structure->field_count(); ++i)
1684 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1686 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
1688 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1689 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1690 "formsignature=\"7816485729218079147\" autofillused=\"false\" "
1691 "datapresent=\"144200030e\">"
1692 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1693 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1694 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1695 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1696 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1697 "<field signature=\"509334676\" autofilltype=\"30\"/>"
1698 "<field signature=\"509334676\" autofilltype=\"31\"/>"
1699 "<field signature=\"509334676\" autofilltype=\"37\"/>"
1700 "<field signature=\"509334676\" autofilltype=\"38\"/>"
1701 "<field signature=\"509334676\" autofilltype=\"30\"/>"
1702 "<field signature=\"509334676\" autofilltype=\"31\"/>"
1703 "<field signature=\"509334676\" autofilltype=\"37\"/>"
1704 "<field signature=\"509334676\" autofilltype=\"38\"/>"
1705 "</autofillupload>",
1708 // Add 50 address fields - now the form is invalid, as it has too many fields.
1709 for (size_t i = 0; i < 50; ++i) {
1710 field.label = ASCIIToUTF16("Address");
1711 field.name = ASCIIToUTF16("address");
1712 field.form_control_type = "text";
1713 form.fields.push_back(field);
1714 possible_field_types.push_back(ServerFieldTypeSet());
1715 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1716 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1717 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1718 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1720 form_structure.reset(new FormStructure(form));
1721 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1722 for (size_t i = 0; i < form_structure->field_count(); ++i)
1723 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1724 EXPECT_FALSE(form_structure->EncodeUploadRequest(available_field_types, false,
1728 TEST(FormStructureTest, EncodeFieldAssignments) {
1729 scoped_ptr<FormStructure> form_structure;
1730 std::vector<ServerFieldTypeSet> possible_field_types;
1732 form.method = ASCIIToUTF16("post");
1733 form_structure.reset(new FormStructure(form));
1734 form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1736 FormFieldData field;
1737 field.form_control_type = "text";
1739 field.label = ASCIIToUTF16("First Name");
1740 field.name = ASCIIToUTF16("firstname");
1741 form.fields.push_back(field);
1742 possible_field_types.push_back(ServerFieldTypeSet());
1743 possible_field_types.back().insert(NAME_FIRST);
1745 field.label = ASCIIToUTF16("Last Name");
1746 field.name = ASCIIToUTF16("lastname");
1747 form.fields.push_back(field);
1748 possible_field_types.push_back(ServerFieldTypeSet());
1749 possible_field_types.back().insert(NAME_LAST);
1751 field.label = ASCIIToUTF16("Email");
1752 field.name = ASCIIToUTF16("email");
1753 field.form_control_type = "email";
1754 form.fields.push_back(field);
1755 possible_field_types.push_back(ServerFieldTypeSet());
1756 possible_field_types.back().insert(EMAIL_ADDRESS);
1758 field.label = ASCIIToUTF16("Phone");
1759 field.name = ASCIIToUTF16("phone");
1760 field.form_control_type = "number";
1761 form.fields.push_back(field);
1762 possible_field_types.push_back(ServerFieldTypeSet());
1763 possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
1765 field.label = ASCIIToUTF16("Country");
1766 field.name = ASCIIToUTF16("country");
1767 field.form_control_type = "select-one";
1768 form.fields.push_back(field);
1769 possible_field_types.push_back(ServerFieldTypeSet());
1770 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1772 // Add checkable field.
1773 FormFieldData checkable_field;
1774 checkable_field.is_checkable = true;
1775 checkable_field.label = ASCIIToUTF16("Checkable1");
1776 checkable_field.name = ASCIIToUTF16("Checkable1");
1777 form.fields.push_back(checkable_field);
1778 possible_field_types.push_back(ServerFieldTypeSet());
1779 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1781 form_structure.reset(new FormStructure(form));
1783 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1784 for (size_t i = 0; i < form_structure->field_count(); ++i)
1785 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1787 ServerFieldTypeSet available_field_types;
1788 available_field_types.insert(NAME_FIRST);
1789 available_field_types.insert(NAME_LAST);
1790 available_field_types.insert(ADDRESS_HOME_LINE1);
1791 available_field_types.insert(ADDRESS_HOME_LINE2);
1792 available_field_types.insert(ADDRESS_HOME_COUNTRY);
1793 available_field_types.insert(ADDRESS_BILLING_LINE1);
1794 available_field_types.insert(ADDRESS_BILLING_LINE2);
1795 available_field_types.insert(EMAIL_ADDRESS);
1796 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1798 std::string encoded_xml;
1799 EXPECT_TRUE(form_structure->EncodeFieldAssignments(
1800 available_field_types, &encoded_xml));
1802 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1803 "<fieldassignments formsignature=\"8736493185895608956\">"
1804 "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1805 "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1806 "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1807 "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1808 "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1809 "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
1810 "</fieldassignments>",
1813 // Add 2 address fields - this should be still a valid form.
1814 for (size_t i = 0; i < 2; ++i) {
1815 field.label = ASCIIToUTF16("Address");
1816 field.name = ASCIIToUTF16("address");
1817 field.form_control_type = "text";
1818 form.fields.push_back(field);
1819 possible_field_types.push_back(ServerFieldTypeSet());
1820 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1821 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1822 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1823 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1826 form_structure.reset(new FormStructure(form));
1827 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1828 for (size_t i = 0; i < form_structure->field_count(); ++i)
1829 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1831 EXPECT_TRUE(form_structure->EncodeFieldAssignments(
1832 available_field_types, &encoded_xml));
1834 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1835 "<fieldassignments formsignature=\"7816485729218079147\">"
1836 "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1837 "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1838 "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1839 "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1840 "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1841 "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
1842 "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>"
1843 "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
1844 "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
1845 "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
1846 "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>"
1847 "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
1848 "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
1849 "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
1850 "</fieldassignments>",
1854 // Check that we compute the "datapresent" string correctly for the given
1855 // |available_types|.
1856 TEST(FormStructureTest, CheckDataPresence) {
1858 form.method = ASCIIToUTF16("post");
1860 FormFieldData field;
1861 field.form_control_type = "text";
1863 field.label = ASCIIToUTF16("First Name");
1864 field.name = ASCIIToUTF16("first");
1865 form.fields.push_back(field);
1867 field.label = ASCIIToUTF16("Last Name");
1868 field.name = ASCIIToUTF16("last");
1869 form.fields.push_back(field);
1871 field.label = ASCIIToUTF16("Email");
1872 field.name = ASCIIToUTF16("email");
1873 form.fields.push_back(field);
1875 FormStructure form_structure(form);
1877 ServerFieldTypeSet unknown_type;
1878 unknown_type.insert(UNKNOWN_TYPE);
1879 for (size_t i = 0; i < form_structure.field_count(); ++i)
1880 form_structure.field(i)->set_possible_types(unknown_type);
1882 // No available types.
1883 // datapresent should be "" == trimmmed(0x0000000000000000) ==
1884 // 0b0000000000000000000000000000000000000000000000000000000000000000
1885 ServerFieldTypeSet available_field_types;
1887 std::string encoded_xml;
1888 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1890 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1891 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1892 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1893 " datapresent=\"\">"
1894 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1895 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1896 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1897 "</autofillupload>",
1900 // Only a few types available.
1901 // datapresent should be "1540000240" == trimmmed(0x1540000240000000) ==
1902 // 0b0001010101000000000000000000001001000000000000000000000000000000
1903 // The set bits are:
1907 // 9 == EMAIL_ADDRESS
1908 // 30 == ADDRESS_HOME_LINE1
1909 // 33 == ADDRESS_HOME_CITY
1910 available_field_types.clear();
1911 available_field_types.insert(NAME_FIRST);
1912 available_field_types.insert(NAME_LAST);
1913 available_field_types.insert(NAME_FULL);
1914 available_field_types.insert(EMAIL_ADDRESS);
1915 available_field_types.insert(ADDRESS_HOME_LINE1);
1916 available_field_types.insert(ADDRESS_HOME_CITY);
1918 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1920 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1921 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1922 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1923 " datapresent=\"1540000240\">"
1924 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1925 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1926 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1927 "</autofillupload>",
1930 // All supported non-credit card types available.
1931 // datapresent should be "1f7e000378000008" == trimmmed(0x1f7e000378000008) ==
1932 // 0b0001111101111110000000000000001101111000000000000000000000001000
1933 // The set bits are:
1937 // 6 == NAME_MIDDLE_INITIAL
1939 // 9 == EMAIL_ADDRESS
1940 // 10 == PHONE_HOME_NUMBER,
1941 // 11 == PHONE_HOME_CITY_CODE,
1942 // 12 == PHONE_HOME_COUNTRY_CODE,
1943 // 13 == PHONE_HOME_CITY_AND_NUMBER,
1944 // 14 == PHONE_HOME_WHOLE_NUMBER,
1945 // 30 == ADDRESS_HOME_LINE1
1946 // 31 == ADDRESS_HOME_LINE2
1947 // 33 == ADDRESS_HOME_CITY
1948 // 34 == ADDRESS_HOME_STATE
1949 // 35 == ADDRESS_HOME_ZIP
1950 // 36 == ADDRESS_HOME_COUNTRY
1951 // 60 == COMPANY_NAME
1952 available_field_types.clear();
1953 available_field_types.insert(NAME_FIRST);
1954 available_field_types.insert(NAME_MIDDLE);
1955 available_field_types.insert(NAME_LAST);
1956 available_field_types.insert(NAME_MIDDLE_INITIAL);
1957 available_field_types.insert(NAME_FULL);
1958 available_field_types.insert(EMAIL_ADDRESS);
1959 available_field_types.insert(PHONE_HOME_NUMBER);
1960 available_field_types.insert(PHONE_HOME_CITY_CODE);
1961 available_field_types.insert(PHONE_HOME_COUNTRY_CODE);
1962 available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER);
1963 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1964 available_field_types.insert(ADDRESS_HOME_LINE1);
1965 available_field_types.insert(ADDRESS_HOME_LINE2);
1966 available_field_types.insert(ADDRESS_HOME_CITY);
1967 available_field_types.insert(ADDRESS_HOME_STATE);
1968 available_field_types.insert(ADDRESS_HOME_ZIP);
1969 available_field_types.insert(ADDRESS_HOME_COUNTRY);
1970 available_field_types.insert(COMPANY_NAME);
1972 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1974 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1975 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1976 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1977 " datapresent=\"1f7e000378000008\">"
1978 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1979 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1980 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1981 "</autofillupload>",
1984 // All supported credit card types available.
1985 // datapresent should be "0000000000001fc0" == trimmmed(0x0000000000001fc0) ==
1986 // 0b0000000000000000000000000000000000000000000000000001111111000000
1987 // The set bits are:
1988 // 51 == CREDIT_CARD_NAME
1989 // 52 == CREDIT_CARD_NUMBER
1990 // 53 == CREDIT_CARD_EXP_MONTH
1991 // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
1992 // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
1993 // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
1994 // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
1995 available_field_types.clear();
1996 available_field_types.insert(CREDIT_CARD_NAME);
1997 available_field_types.insert(CREDIT_CARD_NUMBER);
1998 available_field_types.insert(CREDIT_CARD_EXP_MONTH);
1999 available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
2000 available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
2001 available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
2002 available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
2004 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
2006 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2007 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2008 " formsignature=\"6402244543831589061\" autofillused=\"false\""
2009 " datapresent=\"0000000000001fc0\">"
2010 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
2011 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2012 "<field signature=\"420638584\" autofilltype=\"1\"/>"
2013 "</autofillupload>",
2016 // All supported types available.
2017 // datapresent should be "1f7e000378001fc8" == trimmmed(0x1f7e000378001fc8) ==
2018 // 0b0001111101111110000000000000001101111000000000000001111111001000
2019 // The set bits are:
2023 // 6 == NAME_MIDDLE_INITIAL
2025 // 9 == EMAIL_ADDRESS
2026 // 10 == PHONE_HOME_NUMBER,
2027 // 11 == PHONE_HOME_CITY_CODE,
2028 // 12 == PHONE_HOME_COUNTRY_CODE,
2029 // 13 == PHONE_HOME_CITY_AND_NUMBER,
2030 // 14 == PHONE_HOME_WHOLE_NUMBER,
2031 // 30 == ADDRESS_HOME_LINE1
2032 // 31 == ADDRESS_HOME_LINE2
2033 // 33 == ADDRESS_HOME_CITY
2034 // 34 == ADDRESS_HOME_STATE
2035 // 35 == ADDRESS_HOME_ZIP
2036 // 36 == ADDRESS_HOME_COUNTRY
2037 // 51 == CREDIT_CARD_NAME
2038 // 52 == CREDIT_CARD_NUMBER
2039 // 53 == CREDIT_CARD_EXP_MONTH
2040 // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
2041 // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
2042 // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
2043 // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
2044 // 60 == COMPANY_NAME
2045 available_field_types.clear();
2046 available_field_types.insert(NAME_FIRST);
2047 available_field_types.insert(NAME_MIDDLE);
2048 available_field_types.insert(NAME_LAST);
2049 available_field_types.insert(NAME_MIDDLE_INITIAL);
2050 available_field_types.insert(NAME_FULL);
2051 available_field_types.insert(EMAIL_ADDRESS);
2052 available_field_types.insert(PHONE_HOME_NUMBER);
2053 available_field_types.insert(PHONE_HOME_CITY_CODE);
2054 available_field_types.insert(PHONE_HOME_COUNTRY_CODE);
2055 available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER);
2056 available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
2057 available_field_types.insert(ADDRESS_HOME_LINE1);
2058 available_field_types.insert(ADDRESS_HOME_LINE2);
2059 available_field_types.insert(ADDRESS_HOME_CITY);
2060 available_field_types.insert(ADDRESS_HOME_STATE);
2061 available_field_types.insert(ADDRESS_HOME_ZIP);
2062 available_field_types.insert(ADDRESS_HOME_COUNTRY);
2063 available_field_types.insert(CREDIT_CARD_NAME);
2064 available_field_types.insert(CREDIT_CARD_NUMBER);
2065 available_field_types.insert(CREDIT_CARD_EXP_MONTH);
2066 available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
2067 available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
2068 available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
2069 available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
2070 available_field_types.insert(COMPANY_NAME);
2072 EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
2074 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2075 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2076 " formsignature=\"6402244543831589061\" autofillused=\"false\""
2077 " datapresent=\"1f7e000378001fc8\">"
2078 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
2079 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2080 "<field signature=\"420638584\" autofilltype=\"1\"/>"
2081 "</autofillupload>",
2085 TEST(FormStructureTest, CheckMultipleTypes) {
2086 // Throughout this test, datapresent should be
2087 // 0x1440000360000008 ==
2088 // 0b0001010001000000000000000000001101100000000000000000000000001000
2089 // The set bits are:
2092 // 9 == EMAIL_ADDRESS
2093 // 30 == ADDRESS_HOME_LINE1
2094 // 31 == ADDRESS_HOME_LINE2
2095 // 33 == ADDRESS_HOME_CITY
2096 // 34 == ADDRESS_HOME_STATE
2097 // 60 == COMPANY_NAME
2098 ServerFieldTypeSet available_field_types;
2099 available_field_types.insert(NAME_FIRST);
2100 available_field_types.insert(NAME_LAST);
2101 available_field_types.insert(EMAIL_ADDRESS);
2102 available_field_types.insert(ADDRESS_HOME_LINE1);
2103 available_field_types.insert(ADDRESS_HOME_LINE2);
2104 available_field_types.insert(ADDRESS_HOME_CITY);
2105 available_field_types.insert(ADDRESS_HOME_STATE);
2106 available_field_types.insert(COMPANY_NAME);
2108 // Check that multiple types for the field are processed correctly.
2109 scoped_ptr<FormStructure> form_structure;
2110 std::vector<ServerFieldTypeSet> possible_field_types;
2112 form.method = ASCIIToUTF16("post");
2114 FormFieldData field;
2115 field.form_control_type = "text";
2117 field.label = ASCIIToUTF16("email");
2118 field.name = ASCIIToUTF16("email");
2119 form.fields.push_back(field);
2120 possible_field_types.push_back(ServerFieldTypeSet());
2121 possible_field_types.back().insert(EMAIL_ADDRESS);
2123 field.label = ASCIIToUTF16("First Name");
2124 field.name = ASCIIToUTF16("first");
2125 form.fields.push_back(field);
2126 possible_field_types.push_back(ServerFieldTypeSet());
2127 possible_field_types.back().insert(NAME_FIRST);
2129 field.label = ASCIIToUTF16("Last Name");
2130 field.name = ASCIIToUTF16("last");
2131 form.fields.push_back(field);
2132 possible_field_types.push_back(ServerFieldTypeSet());
2133 possible_field_types.back().insert(NAME_LAST);
2135 field.label = ASCIIToUTF16("Address");
2136 field.name = ASCIIToUTF16("address");
2137 form.fields.push_back(field);
2138 possible_field_types.push_back(ServerFieldTypeSet());
2139 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
2141 form_structure.reset(new FormStructure(form));
2143 for (size_t i = 0; i < form_structure->field_count(); ++i)
2144 form_structure->field(i)->set_possible_types(possible_field_types[i]);
2145 std::string encoded_xml;
2147 // Now we matched both fields singularly.
2148 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2150 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2151 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2152 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2153 " datapresent=\"1440000360000008\">"
2154 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2155 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2156 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2157 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2158 "</autofillupload>",
2160 // Match third field as both first and last.
2161 possible_field_types[2].insert(NAME_FIRST);
2162 form_structure->field(2)->set_possible_types(possible_field_types[2]);
2163 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2165 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2166 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2167 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2168 " datapresent=\"1440000360000008\">"
2169 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2170 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2171 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2172 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2173 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2174 "</autofillupload>",
2176 possible_field_types[3].insert(ADDRESS_HOME_LINE2);
2177 form_structure->field(form_structure->field_count() - 1)->set_possible_types(
2178 possible_field_types[form_structure->field_count() - 1]);
2179 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2181 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2182 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2183 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2184 " datapresent=\"1440000360000008\">"
2185 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2186 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2187 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2188 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2189 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2190 "<field signature=\"509334676\" autofilltype=\"31\"/>"
2191 "</autofillupload>",
2193 possible_field_types[3].clear();
2194 possible_field_types[3].insert(ADDRESS_HOME_LINE1);
2195 possible_field_types[3].insert(COMPANY_NAME);
2196 form_structure->field(form_structure->field_count() - 1)->set_possible_types(
2197 possible_field_types[form_structure->field_count() - 1]);
2198 EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2200 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2201 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2202 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2203 " datapresent=\"1440000360000008\">"
2204 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2205 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2206 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2207 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2208 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2209 "<field signature=\"509334676\" autofilltype=\"60\"/>"
2210 "</autofillupload>",
2214 TEST(FormStructureTest, CheckFormSignature) {
2215 // Check that form signature is created correctly.
2216 scoped_ptr<FormStructure> form_structure;
2218 form.method = ASCIIToUTF16("post");
2220 FormFieldData field;
2221 field.form_control_type = "text";
2223 field.label = ASCIIToUTF16("email");
2224 field.name = ASCIIToUTF16("email");
2225 form.fields.push_back(field);
2227 field.label = ASCIIToUTF16("First Name");
2228 field.name = ASCIIToUTF16("first");
2229 form.fields.push_back(field);
2231 // Checkable fields shouldn't affect the signature.
2232 field.label = ASCIIToUTF16("Select");
2233 field.name = ASCIIToUTF16("Select");
2234 field.form_control_type = "checkbox";
2235 field.is_checkable = true;
2236 form.fields.push_back(field);
2238 form_structure.reset(new FormStructure(form));
2240 EXPECT_EQ(FormStructureTest::Hash64Bit(
2241 std::string("://&&email&first")),
2242 form_structure->FormSignature());
2244 form.origin = GURL(std::string("http://www.facebook.com"));
2245 form_structure.reset(new FormStructure(form));
2246 EXPECT_EQ(FormStructureTest::Hash64Bit(
2247 std::string("http://www.facebook.com&&email&first")),
2248 form_structure->FormSignature());
2250 form.action = GURL(std::string("https://login.facebook.com/path"));
2251 form_structure.reset(new FormStructure(form));
2252 EXPECT_EQ(FormStructureTest::Hash64Bit(
2253 std::string("https://login.facebook.com&&email&first")),
2254 form_structure->FormSignature());
2256 form.name = ASCIIToUTF16("login_form");
2257 form_structure.reset(new FormStructure(form));
2258 EXPECT_EQ(FormStructureTest::Hash64Bit(
2259 std::string("https://login.facebook.com&login_form&email&first")),
2260 form_structure->FormSignature());
2262 field.is_checkable = false;
2263 field.label = ASCIIToUTF16("Random Field label");
2264 field.name = ASCIIToUTF16("random1234");
2265 field.form_control_type = "text";
2266 form.fields.push_back(field);
2267 field.label = ASCIIToUTF16("Random Field label2");
2268 field.name = ASCIIToUTF16("random12345");
2269 form.fields.push_back(field);
2270 field.label = ASCIIToUTF16("Random Field label3");
2271 field.name = ASCIIToUTF16("1random12345678");
2272 form.fields.push_back(field);
2273 field.label = ASCIIToUTF16("Random Field label3");
2274 field.name = ASCIIToUTF16("12345random");
2275 form.fields.push_back(field);
2276 form_structure.reset(new FormStructure(form));
2277 EXPECT_EQ(FormStructureTest::Hash64Bit(
2278 std::string("https://login.facebook.com&login_form&email&first&"
2279 "random1234&random&1random&random")),
2280 form_structure->FormSignature());
2284 TEST(FormStructureTest, ToFormData) {
2286 form.name = ASCIIToUTF16("the-name");
2287 form.method = ASCIIToUTF16("POST");
2288 form.origin = GURL("http://cool.com");
2289 form.action = form.origin.Resolve("/login");
2291 FormFieldData field;
2292 field.label = ASCIIToUTF16("username");
2293 field.name = ASCIIToUTF16("username");
2294 field.form_control_type = "text";
2295 form.fields.push_back(field);
2297 field.label = ASCIIToUTF16("password");
2298 field.name = ASCIIToUTF16("password");
2299 field.form_control_type = "password";
2300 form.fields.push_back(field);
2302 field.label = base::string16();
2303 field.name = ASCIIToUTF16("Submit");
2304 field.form_control_type = "submit";
2305 form.fields.push_back(field);
2307 EXPECT_EQ(form, FormStructure(form).ToFormData());
2309 // Currently |FormStructure(form_data)ToFormData().user_submitted| is always
2310 // false. This forces a future author that changes this to update this test.
2311 form.user_submitted = true;
2312 EXPECT_NE(form, FormStructure(form).ToFormData());
2315 TEST(FormStructureTest, SkipFieldTest) {
2317 form.name = ASCIIToUTF16("the-name");
2318 form.method = ASCIIToUTF16("POST");
2319 form.origin = GURL("http://cool.com");
2320 form.action = form.origin.Resolve("/login");
2322 FormFieldData field;
2323 field.label = ASCIIToUTF16("username");
2324 field.name = ASCIIToUTF16("username");
2325 field.form_control_type = "text";
2326 form.fields.push_back(field);
2328 field.label = ASCIIToUTF16("select");
2329 field.name = ASCIIToUTF16("select");
2330 field.form_control_type = "checkbox";
2331 field.is_checkable = true;
2332 form.fields.push_back(field);
2334 field.label = base::string16();
2335 field.name = ASCIIToUTF16("email");
2336 field.form_control_type = "text";
2337 field.is_checkable = false;
2338 form.fields.push_back(field);
2340 ScopedVector<FormStructure> forms;
2341 forms.push_back(new FormStructure(form));
2342 std::vector<std::string> encoded_signatures;
2343 std::string encoded_xml;
2345 const char kSignature[] = "18006745212084723782";
2346 const char kResponse[] =
2347 "<\?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2348 "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
2349 "<form signature=\"18006745212084723782\">"
2350 "<field signature=\"239111655\"/>"
2351 "<field signature=\"420638584\"/>"
2354 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
2355 &encoded_signatures,
2357 ASSERT_EQ(1U, encoded_signatures.size());
2358 EXPECT_EQ(kSignature, encoded_signatures[0]);
2359 EXPECT_EQ(kResponse, encoded_xml);
2362 TEST(FormStructureTest, PossibleValues) {
2364 FormFieldData field;
2365 field.autocomplete_attribute = "billing country";
2366 field.option_contents.push_back(ASCIIToUTF16("Down Under"));
2367 field.option_values.push_back(ASCIIToUTF16("AU"));
2368 field.option_contents.push_back(ASCIIToUTF16("Fr"));
2369 field.option_values.push_back(ASCIIToUTF16(""));
2370 field.option_contents.push_back(ASCIIToUTF16("Germany"));
2371 field.option_values.push_back(ASCIIToUTF16("GRMNY"));
2372 form_data.fields.push_back(field);
2373 FormStructure form_structure(form_data);
2376 form_structure.ParseFieldTypesFromAutocompleteAttributes(&unused, &unused);
2378 // All values in <option> value= or contents are returned, set to upper case.
2379 std::set<base::string16> possible_values =
2380 form_structure.PossibleValues(ADDRESS_BILLING_COUNTRY);
2381 EXPECT_EQ(5U, possible_values.size());
2382 EXPECT_EQ(1U, possible_values.count(ASCIIToUTF16("AU")));
2383 EXPECT_EQ(1U, possible_values.count(ASCIIToUTF16("FR")));
2384 EXPECT_EQ(1U, possible_values.count(ASCIIToUTF16("DOWN UNDER")));
2385 EXPECT_EQ(1U, possible_values.count(ASCIIToUTF16("GERMANY")));
2386 EXPECT_EQ(1U, possible_values.count(ASCIIToUTF16("GRMNY")));
2387 EXPECT_EQ(0U, possible_values.count(ASCIIToUTF16("Fr")));
2388 EXPECT_EQ(0U, possible_values.count(ASCIIToUTF16("DE")));
2390 // No field for the given type; empty value set.
2391 EXPECT_EQ(0U, form_structure.PossibleValues(ADDRESS_HOME_COUNTRY).size());
2393 // A freeform input (<input>) allows any value (overriding other <select>s).
2394 FormFieldData freeform_field;
2395 freeform_field.autocomplete_attribute = "billing country";
2396 form_data.fields.push_back(freeform_field);
2397 FormStructure form_structure2(form_data);
2398 form_structure2.ParseFieldTypesFromAutocompleteAttributes(&unused, &unused);
2399 EXPECT_EQ(0U, form_structure2.PossibleValues(ADDRESS_BILLING_COUNTRY).size());
2402 } // namespace autofill