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/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "components/autofill/core/common/autofill_switches.h"
12 #include "components/autofill/core/common/form_data.h"
13 #include "components/autofill/core/common/form_field_data.h"
14 #include "testing/gtest/include/gtest/gtest.h"
17 using base::ASCIIToUTF16
;
23 std::ostream
& operator<<(std::ostream
& os
, const FormData
& form
) {
24 os
<< base::UTF16ToUTF8(form
.name
)
31 for (std::vector
<FormFieldData
>::const_iterator iter
=
33 iter
!= form
.fields
.end(); ++iter
) {
41 } // namespace content
43 class FormStructureTest
{
45 static std::string
Hash64Bit(const std::string
& str
) {
46 return FormStructure::Hash64Bit(str
);
50 TEST(FormStructureTest
, FieldCount
) {
51 scoped_ptr
<FormStructure
> form_structure
;
55 field
.label
= ASCIIToUTF16("username");
56 field
.name
= ASCIIToUTF16("username");
57 field
.form_control_type
= "text";
58 form
.fields
.push_back(field
);
60 field
.label
= ASCIIToUTF16("password");
61 field
.name
= ASCIIToUTF16("password");
62 field
.form_control_type
= "password";
63 form
.fields
.push_back(field
);
65 field
.label
= base::string16();
66 field
.name
= ASCIIToUTF16("Submit");
67 field
.form_control_type
= "submit";
68 form
.fields
.push_back(field
);
70 field
.label
= ASCIIToUTF16("address1");
71 field
.name
= ASCIIToUTF16("address1");
72 field
.form_control_type
= "text";
73 field
.should_autocomplete
= false;
74 form
.fields
.push_back(field
);
76 // The render process sends all fields to browser including fields with
78 form_structure
.reset(new FormStructure(form
));
79 EXPECT_EQ(4U, form_structure
->field_count());
82 TEST(FormStructureTest
, AutofillCount
) {
83 scoped_ptr
<FormStructure
> form_structure
;
87 field
.label
= ASCIIToUTF16("username");
88 field
.name
= ASCIIToUTF16("username");
89 field
.form_control_type
= "text";
90 form
.fields
.push_back(field
);
92 field
.label
= ASCIIToUTF16("password");
93 field
.name
= ASCIIToUTF16("password");
94 field
.form_control_type
= "password";
95 form
.fields
.push_back(field
);
97 field
.label
= ASCIIToUTF16("email");
98 field
.name
= ASCIIToUTF16("email");
99 field
.form_control_type
= "text";
100 form
.fields
.push_back(field
);
102 field
.label
= ASCIIToUTF16("city");
103 field
.name
= ASCIIToUTF16("city");
104 field
.form_control_type
= "text";
105 form
.fields
.push_back(field
);
107 field
.label
= ASCIIToUTF16("state");
108 field
.name
= ASCIIToUTF16("state");
109 field
.form_control_type
= "select-one";
110 form
.fields
.push_back(field
);
112 field
.label
= base::string16();
113 field
.name
= ASCIIToUTF16("Submit");
114 field
.form_control_type
= "submit";
115 form
.fields
.push_back(field
);
117 // Only text and select fields that are heuristically matched are counted.
118 form_structure
.reset(new FormStructure(form
));
119 form_structure
->DetermineHeuristicTypes();
120 EXPECT_EQ(3U, form_structure
->autofill_count());
122 // Add a field with should_autocomplete=false. This should not be considered a
124 field
.label
= ASCIIToUTF16("address1");
125 field
.name
= ASCIIToUTF16("address1");
126 field
.form_control_type
= "text";
127 field
.should_autocomplete
= false;
128 form
.fields
.push_back(field
);
130 form_structure
.reset(new FormStructure(form
));
131 form_structure
->DetermineHeuristicTypes();
132 EXPECT_EQ(4U, form_structure
->autofill_count());
134 base::CommandLine::ForCurrentProcess()->AppendSwitch(
135 switches::kRespectAutocompleteOffForAutofill
);
137 form_structure
.reset(new FormStructure(form
));
138 form_structure
->DetermineHeuristicTypes();
139 EXPECT_EQ(3U, form_structure
->autofill_count());
142 TEST(FormStructureTest
, SourceURL
) {
144 form
.origin
= GURL("http://www.foo.com/");
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.
157 field
.label
= ASCIIToUTF16("username");
158 field
.name
= ASCIIToUTF16("username");
159 field
.form_control_type
= "text";
160 form
.fields
.push_back(field
);
162 field
.label
= ASCIIToUTF16("password");
163 field
.name
= ASCIIToUTF16("password");
164 field
.form_control_type
= "password";
165 form
.fields
.push_back(field
);
167 field
.label
= base::string16();
168 field
.name
= ASCIIToUTF16("Submit");
169 field
.form_control_type
= "submit";
170 form
.fields
.push_back(field
);
172 form_structure
.reset(new FormStructure(form
));
173 form_structure
->DetermineHeuristicTypes();
174 EXPECT_FALSE(form_structure
->IsAutofillable());
176 // We now have three text fields, but only two auto-fillable fields.
177 field
.label
= ASCIIToUTF16("First Name");
178 field
.name
= ASCIIToUTF16("firstname");
179 field
.form_control_type
= "text";
180 form
.fields
.push_back(field
);
182 field
.label
= ASCIIToUTF16("Last Name");
183 field
.name
= ASCIIToUTF16("lastname");
184 field
.form_control_type
= "text";
185 form
.fields
.push_back(field
);
187 form_structure
.reset(new FormStructure(form
));
188 form_structure
->DetermineHeuristicTypes();
189 EXPECT_FALSE(form_structure
->IsAutofillable());
191 // We now have three auto-fillable fields.
192 field
.label
= ASCIIToUTF16("Email");
193 field
.name
= ASCIIToUTF16("email");
194 field
.form_control_type
= "email";
195 form
.fields
.push_back(field
);
197 form_structure
.reset(new FormStructure(form
));
198 form_structure
->DetermineHeuristicTypes();
199 EXPECT_TRUE(form_structure
->IsAutofillable());
201 // The target cannot include http(s)://*/search...
202 form
.action
= GURL("http://google.com/search?q=hello");
203 form_structure
.reset(new FormStructure(form
));
204 form_structure
->DetermineHeuristicTypes();
205 EXPECT_FALSE(form_structure
->IsAutofillable());
207 // But search can be in the URL.
208 form
.action
= GURL("http://search.com/?q=hello");
209 form_structure
.reset(new FormStructure(form
));
210 form_structure
->DetermineHeuristicTypes();
211 EXPECT_TRUE(form_structure
->IsAutofillable());
214 TEST(FormStructureTest
, ShouldBeParsed
) {
215 scoped_ptr
<FormStructure
> form_structure
;
218 // We need at least three text fields to be parseable.
220 field
.label
= ASCIIToUTF16("username");
221 field
.name
= ASCIIToUTF16("username");
222 field
.form_control_type
= "text";
223 form
.fields
.push_back(field
);
225 FormFieldData checkable_field
;
226 checkable_field
.is_checkable
= true;
227 checkable_field
.name
= ASCIIToUTF16("radiobtn");
228 checkable_field
.form_control_type
= "radio";
229 form
.fields
.push_back(checkable_field
);
231 checkable_field
.name
= ASCIIToUTF16("checkbox");
232 checkable_field
.form_control_type
= "checkbox";
233 form
.fields
.push_back(checkable_field
);
235 // We have only one text field, should not be parsed.
236 form_structure
.reset(new FormStructure(form
));
237 EXPECT_FALSE(form_structure
->ShouldBeParsed());
239 // We now have three text fields, though only two are auto-fillable.
240 field
.label
= ASCIIToUTF16("First Name");
241 field
.name
= ASCIIToUTF16("firstname");
242 field
.form_control_type
= "text";
243 form
.fields
.push_back(field
);
245 field
.label
= ASCIIToUTF16("Last Name");
246 field
.name
= ASCIIToUTF16("lastname");
247 field
.form_control_type
= "text";
248 form
.fields
.push_back(field
);
250 form_structure
.reset(new FormStructure(form
));
251 EXPECT_TRUE(form_structure
->ShouldBeParsed());
253 form_structure
.reset(new FormStructure(form
));
254 EXPECT_FALSE(form_structure
->IsAutofillable());
255 EXPECT_TRUE(form_structure
->ShouldBeParsed());
257 // The target cannot include http(s)://*/search...
258 form
.action
= GURL("http://google.com/search?q=hello");
259 form_structure
.reset(new FormStructure(form
));
260 EXPECT_FALSE(form_structure
->ShouldBeParsed());
262 // But search can be in the URL.
263 form
.action
= GURL("http://search.com/?q=hello");
264 form_structure
.reset(new FormStructure(form
));
265 EXPECT_TRUE(form_structure
->ShouldBeParsed());
267 // The form need only have three fields, but at least one must be a text
271 field
.label
= ASCIIToUTF16("Email");
272 field
.name
= ASCIIToUTF16("email");
273 field
.form_control_type
= "email";
274 form
.fields
.push_back(field
);
276 field
.label
= ASCIIToUTF16("State");
277 field
.name
= ASCIIToUTF16("state");
278 field
.form_control_type
= "select-one";
279 form
.fields
.push_back(field
);
281 field
.label
= ASCIIToUTF16("Country");
282 field
.name
= ASCIIToUTF16("country");
283 field
.form_control_type
= "select-one";
284 form
.fields
.push_back(field
);
286 form_structure
.reset(new FormStructure(form
));
287 EXPECT_TRUE(form_structure
->ShouldBeParsed());
289 form
.fields
[0].form_control_type
= "select-one";
290 // Now, no text fields.
291 form_structure
.reset(new FormStructure(form
));
292 EXPECT_FALSE(form_structure
->ShouldBeParsed());
295 TEST(FormStructureTest
, HeuristicsContactInfo
) {
296 scoped_ptr
<FormStructure
> form_structure
;
300 field
.form_control_type
= "text";
302 field
.label
= ASCIIToUTF16("First Name");
303 field
.name
= ASCIIToUTF16("firstname");
304 form
.fields
.push_back(field
);
306 field
.label
= ASCIIToUTF16("Last Name");
307 field
.name
= ASCIIToUTF16("lastname");
308 form
.fields
.push_back(field
);
310 field
.label
= ASCIIToUTF16("Email");
311 field
.name
= ASCIIToUTF16("email");
312 form
.fields
.push_back(field
);
314 field
.label
= ASCIIToUTF16("Phone");
315 field
.name
= ASCIIToUTF16("phone");
316 form
.fields
.push_back(field
);
318 field
.label
= ASCIIToUTF16("Address");
319 field
.name
= ASCIIToUTF16("address");
320 form
.fields
.push_back(field
);
322 field
.label
= ASCIIToUTF16("City");
323 field
.name
= ASCIIToUTF16("city");
324 form
.fields
.push_back(field
);
326 field
.label
= ASCIIToUTF16("Zip code");
327 field
.name
= ASCIIToUTF16("zipcode");
328 form
.fields
.push_back(field
);
330 field
.label
= base::string16();
331 field
.name
= ASCIIToUTF16("Submit");
332 field
.form_control_type
= "submit";
333 form
.fields
.push_back(field
);
335 form_structure
.reset(new FormStructure(form
));
336 form_structure
->DetermineHeuristicTypes();
337 EXPECT_TRUE(form_structure
->IsAutofillable());
339 // Expect the correct number of fields.
340 ASSERT_EQ(8U, form_structure
->field_count());
341 ASSERT_EQ(7U, form_structure
->autofill_count());
344 EXPECT_EQ(NAME_FIRST
, form_structure
->field(0)->heuristic_type());
346 EXPECT_EQ(NAME_LAST
, form_structure
->field(1)->heuristic_type());
348 EXPECT_EQ(EMAIL_ADDRESS
, form_structure
->field(2)->heuristic_type());
350 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER
,
351 form_structure
->field(3)->heuristic_type());
353 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(4)->heuristic_type());
355 EXPECT_EQ(ADDRESS_HOME_CITY
, form_structure
->field(5)->heuristic_type());
357 EXPECT_EQ(ADDRESS_HOME_ZIP
, form_structure
->field(6)->heuristic_type());
359 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(7)->heuristic_type());
362 // Verify that we can correctly process the |autocomplete| attribute.
363 TEST(FormStructureTest
, HeuristicsAutocompleteAttribute
) {
364 scoped_ptr
<FormStructure
> form_structure
;
368 field
.form_control_type
= "text";
370 field
.label
= base::string16();
371 field
.name
= ASCIIToUTF16("field1");
372 field
.autocomplete_attribute
= "given-name";
373 form
.fields
.push_back(field
);
375 field
.label
= base::string16();
376 field
.name
= ASCIIToUTF16("field2");
377 field
.autocomplete_attribute
= "family-name";
378 form
.fields
.push_back(field
);
380 field
.label
= base::string16();
381 field
.name
= ASCIIToUTF16("field3");
382 field
.autocomplete_attribute
= "email";
383 form
.fields
.push_back(field
);
385 form_structure
.reset(new FormStructure(form
));
386 form_structure
->DetermineHeuristicTypes();
387 EXPECT_TRUE(form_structure
->IsAutofillable());
389 // Expect the correct number of fields.
390 ASSERT_EQ(3U, form_structure
->field_count());
391 ASSERT_EQ(3U, form_structure
->autofill_count());
393 EXPECT_EQ(HTML_TYPE_GIVEN_NAME
, form_structure
->field(0)->html_type());
394 EXPECT_EQ(HTML_TYPE_FAMILY_NAME
, form_structure
->field(1)->html_type());
395 EXPECT_EQ(HTML_TYPE_EMAIL
, form_structure
->field(2)->html_type());
396 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(0)->heuristic_type());
397 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(1)->heuristic_type());
398 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(2)->heuristic_type());
401 // Verify that we can correctly process the 'autocomplete' attribute for phone
402 // number types (especially phone prefixes and suffixes).
403 TEST(FormStructureTest
, HeuristicsAutocompleteAttributePhoneTypes
) {
404 scoped_ptr
<FormStructure
> form_structure
;
408 field
.form_control_type
= "text";
410 field
.label
= base::string16();
411 field
.name
= ASCIIToUTF16("field1");
412 field
.autocomplete_attribute
= "tel-local";
413 form
.fields
.push_back(field
);
415 field
.label
= base::string16();
416 field
.name
= ASCIIToUTF16("field2");
417 field
.autocomplete_attribute
= "tel-local-prefix";
418 form
.fields
.push_back(field
);
420 field
.label
= base::string16();
421 field
.name
= ASCIIToUTF16("field3");
422 field
.autocomplete_attribute
= "tel-local-suffix";
423 form
.fields
.push_back(field
);
425 form_structure
.reset(new FormStructure(form
));
426 form_structure
->DetermineHeuristicTypes();
427 EXPECT_TRUE(form_structure
->IsAutofillable());
429 // Expect the correct number of fields.
430 ASSERT_EQ(3U, form_structure
->field_count());
431 EXPECT_EQ(3U, form_structure
->autofill_count());
433 EXPECT_EQ(HTML_TYPE_TEL_LOCAL
, form_structure
->field(0)->html_type());
434 EXPECT_EQ(AutofillField::IGNORED
, form_structure
->field(0)->phone_part());
435 EXPECT_EQ(HTML_TYPE_TEL_LOCAL_PREFIX
, form_structure
->field(1)->html_type());
436 EXPECT_EQ(AutofillField::PHONE_PREFIX
,
437 form_structure
->field(1)->phone_part());
438 EXPECT_EQ(HTML_TYPE_TEL_LOCAL_SUFFIX
, form_structure
->field(2)->html_type());
439 EXPECT_EQ(AutofillField::PHONE_SUFFIX
,
440 form_structure
->field(2)->phone_part());
443 // If at least one field includes type hints in the 'autocomplete' attribute, we
444 // should not try to apply any other heuristics.
445 TEST(FormStructureTest
, AutocompleteAttributeOverridesOtherHeuristics
) {
446 scoped_ptr
<FormStructure
> form_structure
;
449 // Start with a regular contact form.
451 field
.form_control_type
= "text";
453 field
.label
= ASCIIToUTF16("First Name");
454 field
.name
= ASCIIToUTF16("firstname");
455 form
.fields
.push_back(field
);
457 field
.label
= ASCIIToUTF16("Last Name");
458 field
.name
= ASCIIToUTF16("lastname");
459 form
.fields
.push_back(field
);
461 field
.label
= ASCIIToUTF16("Email");
462 field
.name
= ASCIIToUTF16("email");
463 form
.fields
.push_back(field
);
465 form_structure
.reset(new FormStructure(form
));
466 form_structure
->DetermineHeuristicTypes();
467 EXPECT_TRUE(form_structure
->IsAutofillable());
468 EXPECT_TRUE(form_structure
->ShouldBeCrowdsourced());
470 ASSERT_EQ(3U, form_structure
->field_count());
471 ASSERT_EQ(3U, form_structure
->autofill_count());
473 EXPECT_EQ(NAME_FIRST
, form_structure
->field(0)->heuristic_type());
474 EXPECT_EQ(NAME_LAST
, form_structure
->field(1)->heuristic_type());
475 EXPECT_EQ(EMAIL_ADDRESS
, form_structure
->field(2)->heuristic_type());
477 // Now update the first form field to include an 'autocomplete' attribute.
478 form
.fields
.front().autocomplete_attribute
= "x-other";
479 form_structure
.reset(new FormStructure(form
));
480 form_structure
->DetermineHeuristicTypes();
481 EXPECT_FALSE(form_structure
->IsAutofillable());
482 EXPECT_FALSE(form_structure
->ShouldBeCrowdsourced());
484 ASSERT_EQ(3U, form_structure
->field_count());
485 ASSERT_EQ(0U, form_structure
->autofill_count());
487 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(0)->heuristic_type());
488 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(1)->heuristic_type());
489 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(2)->heuristic_type());
492 // Even with an 'autocomplete' attribute set, ShouldBeCrowdsourced() should
493 // return true if the structure contains a password field, since there are
494 // no local heuristics to depend upon in this case. Fields will still not be
495 // considered autofillable though.
496 TEST(FormStructureTest
, PasswordFormShouldBeCrowdsourced
) {
499 // Start with a regular contact form.
501 field
.form_control_type
= "text";
503 field
.label
= ASCIIToUTF16("First Name");
504 field
.name
= ASCIIToUTF16("firstname");
505 form
.fields
.push_back(field
);
507 field
.label
= ASCIIToUTF16("Last Name");
508 field
.name
= ASCIIToUTF16("lastname");
509 form
.fields
.push_back(field
);
511 field
.label
= ASCIIToUTF16("Email");
512 field
.name
= ASCIIToUTF16("email");
513 field
.autocomplete_attribute
= "username";
514 form
.fields
.push_back(field
);
516 field
.label
= ASCIIToUTF16("Password");
517 field
.name
= ASCIIToUTF16("Password");
518 field
.form_control_type
= "password";
519 form
.fields
.push_back(field
);
521 FormStructure
form_structure(form
);
522 form_structure
.DetermineHeuristicTypes();
523 EXPECT_TRUE(form_structure
.ShouldBeCrowdsourced());
526 // Verify that we can correctly process sections listed in the |autocomplete|
528 TEST(FormStructureTest
, HeuristicsAutocompleteAttributeWithSections
) {
532 field
.form_control_type
= "text";
534 // Some fields will have no section specified. These fall into the default
536 field
.autocomplete_attribute
= "email";
537 form
.fields
.push_back(field
);
539 // We allow arbitrary section names.
540 field
.autocomplete_attribute
= "section-foo email";
541 form
.fields
.push_back(field
);
543 // "shipping" and "billing" are special section tokens that don't require the
544 // "section-" prefix.
545 field
.autocomplete_attribute
= "shipping email";
546 form
.fields
.push_back(field
);
547 field
.autocomplete_attribute
= "billing email";
548 form
.fields
.push_back(field
);
550 // "shipping" and "billing" can be combined with other section names.
551 field
.autocomplete_attribute
= "section-foo shipping email";
552 form
.fields
.push_back(field
);
553 field
.autocomplete_attribute
= "section-foo billing email";
554 form
.fields
.push_back(field
);
556 // We don't do anything clever to try to coalesce sections; it's up to site
557 // authors to avoid typos.
558 field
.autocomplete_attribute
= "section--foo email";
559 form
.fields
.push_back(field
);
561 // "shipping email" and "section--shipping" email should be parsed as
562 // different sections. This is only an interesting test due to how we
563 // implement implicit section names from attributes like "shipping email"; see
564 // the implementation for more details.
565 field
.autocomplete_attribute
= "section--shipping email";
566 form
.fields
.push_back(field
);
568 // Credit card fields are implicitly in a separate section from other fields.
569 field
.autocomplete_attribute
= "section-foo cc-number";
570 form
.fields
.push_back(field
);
572 FormStructure
form_structure(form
);
573 form_structure
.DetermineHeuristicTypes();
574 EXPECT_TRUE(form_structure
.IsAutofillable());
576 // Expect the correct number of fields.
577 ASSERT_EQ(9U, form_structure
.field_count());
578 EXPECT_EQ(9U, form_structure
.autofill_count());
580 // All of the fields in this form should be parsed as belonging to different
582 std::set
<std::string
> section_names
;
583 for (size_t i
= 0; i
< 9; ++i
) {
584 section_names
.insert(form_structure
.field(i
)->section());
586 EXPECT_EQ(9U, section_names
.size());
589 // Verify that we can correctly process a degenerate section listed in the
590 // |autocomplete| attribute.
591 TEST(FormStructureTest
, HeuristicsAutocompleteAttributeWithSectionsDegenerate
) {
595 field
.form_control_type
= "text";
597 // Some fields will have no section specified. These fall into the default
599 field
.autocomplete_attribute
= "email";
600 form
.fields
.push_back(field
);
602 // Specifying "section-" is equivalent to not specifying a section.
603 field
.autocomplete_attribute
= "section- email";
604 form
.fields
.push_back(field
);
606 // Invalid tokens should prevent us from setting a section name.
607 field
.autocomplete_attribute
= "garbage section-foo email";
608 form
.fields
.push_back(field
);
609 field
.autocomplete_attribute
= "garbage section-bar email";
610 form
.fields
.push_back(field
);
611 field
.autocomplete_attribute
= "garbage shipping email";
612 form
.fields
.push_back(field
);
613 field
.autocomplete_attribute
= "garbage billing email";
614 form
.fields
.push_back(field
);
616 FormStructure
form_structure(form
);
617 form_structure
.DetermineHeuristicTypes();
619 // Expect the correct number of fields.
620 ASSERT_EQ(6U, form_structure
.field_count());
621 EXPECT_EQ(2U, form_structure
.autofill_count());
623 // All of the fields in this form should be parsed as belonging to the same
625 std::set
<std::string
> section_names
;
626 for (size_t i
= 0; i
< 6; ++i
) {
627 section_names
.insert(form_structure
.field(i
)->section());
629 EXPECT_EQ(1U, section_names
.size());
632 // Verify that we can correctly process repeated sections listed in the
633 // |autocomplete| attribute.
634 TEST(FormStructureTest
, HeuristicsAutocompleteAttributeWithSectionsRepeated
) {
638 field
.form_control_type
= "text";
640 field
.autocomplete_attribute
= "section-foo email";
641 form
.fields
.push_back(field
);
642 field
.autocomplete_attribute
= "section-foo address-line1";
643 form
.fields
.push_back(field
);
645 FormStructure
form_structure(form
);
646 form_structure
.DetermineHeuristicTypes();
648 // Expect the correct number of fields.
649 ASSERT_EQ(2U, form_structure
.field_count());
650 EXPECT_EQ(2U, form_structure
.autofill_count());
652 // All of the fields in this form should be parsed as belonging to the same
654 std::set
<std::string
> section_names
;
655 for (size_t i
= 0; i
< 2; ++i
) {
656 section_names
.insert(form_structure
.field(i
)->section());
658 EXPECT_EQ(1U, section_names
.size());
661 // Verify that we do not override the author-specified sections from a form with
663 TEST(FormStructureTest
, HeuristicsDontOverrideAutocompleteAttributeSections
) {
667 field
.form_control_type
= "text";
669 field
.name
= ASCIIToUTF16("one");
670 field
.autocomplete_attribute
= "address-line1";
671 form
.fields
.push_back(field
);
672 field
.name
= base::string16();
673 field
.autocomplete_attribute
= "section-foo email";
674 form
.fields
.push_back(field
);
675 field
.name
= base::string16();
676 field
.autocomplete_attribute
= "name";
677 form
.fields
.push_back(field
);
678 field
.name
= ASCIIToUTF16("two");
679 field
.autocomplete_attribute
= "address-line1";
680 form
.fields
.push_back(field
);
682 FormStructure
form_structure(form
);
683 form_structure
.DetermineHeuristicTypes();
685 // Expect the correct number of fields.
686 ASSERT_EQ(4U, form_structure
.field_count());
687 EXPECT_EQ(4U, form_structure
.autofill_count());
689 // Normally, the two separate address fields would cause us to detect two
690 // separate sections; but because there is an author-specified section in this
691 // form, we do not apply these usual heuristics.
692 EXPECT_EQ(ASCIIToUTF16("one"), form_structure
.field(0)->name
);
693 EXPECT_EQ(ASCIIToUTF16("two"), form_structure
.field(3)->name
);
694 EXPECT_EQ(form_structure
.field(0)->section(),
695 form_structure
.field(3)->section());
698 TEST(FormStructureTest
, HeuristicsSample8
) {
699 scoped_ptr
<FormStructure
> form_structure
;
703 field
.form_control_type
= "text";
705 field
.label
= ASCIIToUTF16("Your First Name:");
706 field
.name
= ASCIIToUTF16("bill.first");
707 form
.fields
.push_back(field
);
709 field
.label
= ASCIIToUTF16("Your Last Name:");
710 field
.name
= ASCIIToUTF16("bill.last");
711 form
.fields
.push_back(field
);
713 field
.label
= ASCIIToUTF16("Street Address Line 1:");
714 field
.name
= ASCIIToUTF16("bill.street1");
715 form
.fields
.push_back(field
);
717 field
.label
= ASCIIToUTF16("Street Address Line 2:");
718 field
.name
= ASCIIToUTF16("bill.street2");
719 form
.fields
.push_back(field
);
721 field
.label
= ASCIIToUTF16("City");
722 field
.name
= ASCIIToUTF16("bill.city");
723 form
.fields
.push_back(field
);
725 field
.label
= ASCIIToUTF16("State (U.S.):");
726 field
.name
= ASCIIToUTF16("bill.state");
727 form
.fields
.push_back(field
);
729 field
.label
= ASCIIToUTF16("Zip/Postal Code:");
730 field
.name
= ASCIIToUTF16("BillTo.PostalCode");
731 form
.fields
.push_back(field
);
733 field
.label
= ASCIIToUTF16("Country:");
734 field
.name
= ASCIIToUTF16("bill.country");
735 form
.fields
.push_back(field
);
737 field
.label
= ASCIIToUTF16("Phone Number:");
738 field
.name
= ASCIIToUTF16("BillTo.Phone");
739 form
.fields
.push_back(field
);
741 field
.label
= base::string16();
742 field
.name
= ASCIIToUTF16("Submit");
743 field
.form_control_type
= "submit";
744 form
.fields
.push_back(field
);
746 form_structure
.reset(new FormStructure(form
));
747 form_structure
->DetermineHeuristicTypes();
748 EXPECT_TRUE(form_structure
->IsAutofillable());
749 ASSERT_EQ(10U, form_structure
->field_count());
750 ASSERT_EQ(9U, form_structure
->autofill_count());
753 EXPECT_EQ(NAME_FIRST
, form_structure
->field(0)->heuristic_type());
755 EXPECT_EQ(NAME_LAST
, form_structure
->field(1)->heuristic_type());
757 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(2)->heuristic_type());
759 EXPECT_EQ(ADDRESS_HOME_LINE2
, form_structure
->field(3)->heuristic_type());
761 EXPECT_EQ(ADDRESS_HOME_CITY
, form_structure
->field(4)->heuristic_type());
763 EXPECT_EQ(ADDRESS_HOME_STATE
, form_structure
->field(5)->heuristic_type());
765 EXPECT_EQ(ADDRESS_HOME_ZIP
, form_structure
->field(6)->heuristic_type());
767 EXPECT_EQ(ADDRESS_HOME_COUNTRY
, form_structure
->field(7)->heuristic_type());
769 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER
,
770 form_structure
->field(8)->heuristic_type());
772 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(9)->heuristic_type());
775 TEST(FormStructureTest
, HeuristicsSample6
) {
776 scoped_ptr
<FormStructure
> form_structure
;
780 field
.form_control_type
= "text";
782 field
.label
= ASCIIToUTF16("E-mail address");
783 field
.name
= ASCIIToUTF16("email");
784 form
.fields
.push_back(field
);
786 field
.label
= ASCIIToUTF16("Full name");
787 field
.name
= ASCIIToUTF16("name");
788 form
.fields
.push_back(field
);
790 field
.label
= ASCIIToUTF16("Company");
791 field
.name
= ASCIIToUTF16("company");
792 form
.fields
.push_back(field
);
794 field
.label
= ASCIIToUTF16("Address");
795 field
.name
= ASCIIToUTF16("address");
796 form
.fields
.push_back(field
);
798 field
.label
= ASCIIToUTF16("City");
799 field
.name
= ASCIIToUTF16("city");
800 form
.fields
.push_back(field
);
802 field
.label
= ASCIIToUTF16("Zip Code");
803 field
.name
= ASCIIToUTF16("Home.PostalCode");
804 form
.fields
.push_back(field
);
806 field
.label
= base::string16();
807 field
.name
= ASCIIToUTF16("Submit");
808 field
.value
= ASCIIToUTF16("continue");
809 field
.form_control_type
= "submit";
810 form
.fields
.push_back(field
);
812 form_structure
.reset(new FormStructure(form
));
813 form_structure
->DetermineHeuristicTypes();
814 EXPECT_TRUE(form_structure
->IsAutofillable());
815 ASSERT_EQ(7U, form_structure
->field_count());
816 ASSERT_EQ(6U, form_structure
->autofill_count());
819 EXPECT_EQ(EMAIL_ADDRESS
, form_structure
->field(0)->heuristic_type());
821 EXPECT_EQ(NAME_FULL
, form_structure
->field(1)->heuristic_type());
823 EXPECT_EQ(COMPANY_NAME
, form_structure
->field(2)->heuristic_type());
825 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(3)->heuristic_type());
827 EXPECT_EQ(ADDRESS_HOME_CITY
, form_structure
->field(4)->heuristic_type());
829 EXPECT_EQ(ADDRESS_HOME_ZIP
, form_structure
->field(5)->heuristic_type());
831 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(6)->heuristic_type());
834 // Tests a sequence of FormFields where only labels are supplied to heuristics
835 // for matching. This works because FormFieldData labels are matched in the
836 // case that input element ids (or |name| fields) are missing.
837 TEST(FormStructureTest
, HeuristicsLabelsOnly
) {
838 scoped_ptr
<FormStructure
> form_structure
;
842 field
.form_control_type
= "text";
844 field
.label
= ASCIIToUTF16("First Name");
845 field
.name
= base::string16();
846 form
.fields
.push_back(field
);
848 field
.label
= ASCIIToUTF16("Last Name");
849 field
.name
= base::string16();
850 form
.fields
.push_back(field
);
852 field
.label
= ASCIIToUTF16("Email");
853 field
.name
= base::string16();
854 form
.fields
.push_back(field
);
856 field
.label
= ASCIIToUTF16("Phone");
857 field
.name
= base::string16();
858 form
.fields
.push_back(field
);
860 field
.label
= ASCIIToUTF16("Address");
861 field
.name
= base::string16();
862 form
.fields
.push_back(field
);
864 field
.label
= ASCIIToUTF16("Address");
865 field
.name
= base::string16();
866 form
.fields
.push_back(field
);
868 field
.label
= ASCIIToUTF16("Zip code");
869 field
.name
= base::string16();
870 form
.fields
.push_back(field
);
872 field
.label
= base::string16();
873 field
.name
= ASCIIToUTF16("Submit");
874 field
.form_control_type
= "submit";
875 form
.fields
.push_back(field
);
877 form_structure
.reset(new FormStructure(form
));
878 form_structure
->DetermineHeuristicTypes();
879 EXPECT_TRUE(form_structure
->IsAutofillable());
880 ASSERT_EQ(8U, form_structure
->field_count());
881 ASSERT_EQ(7U, form_structure
->autofill_count());
884 EXPECT_EQ(NAME_FIRST
, form_structure
->field(0)->heuristic_type());
886 EXPECT_EQ(NAME_LAST
, form_structure
->field(1)->heuristic_type());
888 EXPECT_EQ(EMAIL_ADDRESS
, form_structure
->field(2)->heuristic_type());
890 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER
,
891 form_structure
->field(3)->heuristic_type());
893 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(4)->heuristic_type());
895 EXPECT_EQ(ADDRESS_HOME_LINE2
, form_structure
->field(5)->heuristic_type());
897 EXPECT_EQ(ADDRESS_HOME_ZIP
, form_structure
->field(6)->heuristic_type());
899 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(7)->heuristic_type());
902 TEST(FormStructureTest
, HeuristicsCreditCardInfo
) {
903 scoped_ptr
<FormStructure
> form_structure
;
907 field
.form_control_type
= "text";
909 field
.label
= ASCIIToUTF16("Name on Card");
910 field
.name
= ASCIIToUTF16("name_on_card");
911 form
.fields
.push_back(field
);
913 field
.label
= ASCIIToUTF16("Card Number");
914 field
.name
= ASCIIToUTF16("card_number");
915 form
.fields
.push_back(field
);
917 field
.label
= ASCIIToUTF16("Exp Month");
918 field
.name
= ASCIIToUTF16("ccmonth");
919 form
.fields
.push_back(field
);
921 field
.label
= ASCIIToUTF16("Exp Year");
922 field
.name
= ASCIIToUTF16("ccyear");
923 form
.fields
.push_back(field
);
925 field
.label
= ASCIIToUTF16("Verification");
926 field
.name
= ASCIIToUTF16("verification");
927 form
.fields
.push_back(field
);
929 field
.label
= base::string16();
930 field
.name
= ASCIIToUTF16("Submit");
931 field
.form_control_type
= "submit";
932 form
.fields
.push_back(field
);
934 form_structure
.reset(new FormStructure(form
));
935 form_structure
->DetermineHeuristicTypes();
936 EXPECT_TRUE(form_structure
->IsAutofillable());
937 ASSERT_EQ(6U, form_structure
->field_count());
938 ASSERT_EQ(5U, form_structure
->autofill_count());
941 EXPECT_EQ(CREDIT_CARD_NAME
, form_structure
->field(0)->heuristic_type());
942 // Credit card number.
943 EXPECT_EQ(CREDIT_CARD_NUMBER
, form_structure
->field(1)->heuristic_type());
944 // Credit card expiration month.
945 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, form_structure
->field(2)->heuristic_type());
946 // Credit card expiration year.
947 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
948 form_structure
->field(3)->heuristic_type());
950 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE
,
951 form_structure
->field(4)->heuristic_type());
953 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(5)->heuristic_type());
956 TEST(FormStructureTest
, HeuristicsCreditCardInfoWithUnknownCardField
) {
957 scoped_ptr
<FormStructure
> form_structure
;
961 field
.form_control_type
= "text";
963 field
.label
= ASCIIToUTF16("Name on Card");
964 field
.name
= ASCIIToUTF16("name_on_card");
965 form
.fields
.push_back(field
);
967 // This is not a field we know how to process. But we should skip over it
968 // and process the other fields in the card block.
969 field
.label
= ASCIIToUTF16("Card image");
970 field
.name
= ASCIIToUTF16("card_image");
971 form
.fields
.push_back(field
);
973 field
.label
= ASCIIToUTF16("Card Number");
974 field
.name
= ASCIIToUTF16("card_number");
975 form
.fields
.push_back(field
);
977 field
.label
= ASCIIToUTF16("Exp Month");
978 field
.name
= ASCIIToUTF16("ccmonth");
979 form
.fields
.push_back(field
);
981 field
.label
= ASCIIToUTF16("Exp Year");
982 field
.name
= ASCIIToUTF16("ccyear");
983 form
.fields
.push_back(field
);
985 field
.label
= ASCIIToUTF16("Verification");
986 field
.name
= ASCIIToUTF16("verification");
987 form
.fields
.push_back(field
);
989 field
.label
= base::string16();
990 field
.name
= ASCIIToUTF16("Submit");
991 field
.form_control_type
= "submit";
992 form
.fields
.push_back(field
);
994 form_structure
.reset(new FormStructure(form
));
995 form_structure
->DetermineHeuristicTypes();
996 EXPECT_TRUE(form_structure
->IsAutofillable());
997 ASSERT_EQ(7U, form_structure
->field_count());
998 ASSERT_EQ(5U, form_structure
->autofill_count());
1000 // Credit card name.
1001 EXPECT_EQ(CREDIT_CARD_NAME
, form_structure
->field(0)->heuristic_type());
1002 // Credit card type. This is an unknown type but related to the credit card.
1003 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(1)->heuristic_type());
1004 // Credit card number.
1005 EXPECT_EQ(CREDIT_CARD_NUMBER
, form_structure
->field(2)->heuristic_type());
1006 // Credit card expiration month.
1007 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, form_structure
->field(3)->heuristic_type());
1008 // Credit card expiration year.
1009 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
1010 form_structure
->field(4)->heuristic_type());
1012 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE
,
1013 form_structure
->field(5)->heuristic_type());
1015 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(6)->heuristic_type());
1018 TEST(FormStructureTest
, ThreeAddressLines
) {
1019 scoped_ptr
<FormStructure
> form_structure
;
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();
1043 EXPECT_TRUE(form_structure
->IsAutofillable());
1044 ASSERT_EQ(4U, form_structure
->field_count());
1045 ASSERT_EQ(4U, 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(ADDRESS_HOME_LINE3
, 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
;
1062 FormFieldData field
;
1063 field
.form_control_type
= "text";
1065 field
.label
= ASCIIToUTF16("Address Line1");
1066 field
.name
= ASCIIToUTF16("shipping.address.addressLine1");
1067 form
.fields
.push_back(field
);
1069 field
.label
= ASCIIToUTF16("Address Line2");
1070 field
.name
= ASCIIToUTF16("shipping.address.addressLine2");
1071 form
.fields
.push_back(field
);
1073 field
.label
= ASCIIToUTF16("Address Line3");
1074 field
.name
= ASCIIToUTF16("billing.address.addressLine3");
1075 form
.fields
.push_back(field
);
1077 field
.label
= ASCIIToUTF16("Address Line4");
1078 field
.name
= ASCIIToUTF16("billing.address.addressLine4");
1079 form
.fields
.push_back(field
);
1081 form_structure
.reset(new FormStructure(form
));
1082 form_structure
->DetermineHeuristicTypes();
1083 ASSERT_EQ(4U, form_structure
->field_count());
1084 ASSERT_EQ(3U, form_structure
->autofill_count());
1087 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(0)->heuristic_type());
1089 EXPECT_EQ(ADDRESS_HOME_LINE2
, form_structure
->field(1)->heuristic_type());
1091 EXPECT_EQ(ADDRESS_HOME_LINE3
, form_structure
->field(2)->heuristic_type());
1092 // Address Line 4 (ignored).
1093 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(3)->heuristic_type());
1096 // This example comes from expedia.com where they used to use a "Suite" label
1097 // to indicate a suite or apartment number (the form has changed since this
1098 // test was written). We interpret this as address line 2. And the following
1099 // "Street address second line" we interpret as address line 3.
1100 // See http://crbug.com/48197 for details.
1101 TEST(FormStructureTest
, ThreeAddressLinesExpedia
) {
1102 scoped_ptr
<FormStructure
> form_structure
;
1105 FormFieldData field
;
1106 field
.form_control_type
= "text";
1108 field
.label
= ASCIIToUTF16("Street:");
1109 field
.name
= ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1");
1110 form
.fields
.push_back(field
);
1112 field
.label
= ASCIIToUTF16("Suite or Apt:");
1113 field
.name
= ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap");
1114 form
.fields
.push_back(field
);
1116 field
.label
= ASCIIToUTF16("Street address second line");
1117 field
.name
= ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads2");
1118 form
.fields
.push_back(field
);
1120 field
.label
= ASCIIToUTF16("City:");
1121 field
.name
= ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adct");
1122 form
.fields
.push_back(field
);
1124 form_structure
.reset(new FormStructure(form
));
1125 form_structure
->DetermineHeuristicTypes();
1126 EXPECT_TRUE(form_structure
->IsAutofillable());
1127 ASSERT_EQ(4U, form_structure
->field_count());
1128 EXPECT_EQ(4U, form_structure
->autofill_count());
1131 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(0)->heuristic_type());
1133 EXPECT_EQ(ADDRESS_HOME_LINE2
, form_structure
->field(1)->heuristic_type());
1135 EXPECT_EQ(ADDRESS_HOME_LINE3
, form_structure
->field(2)->heuristic_type());
1137 EXPECT_EQ(ADDRESS_HOME_CITY
, form_structure
->field(3)->heuristic_type());
1140 // This example comes from ebay.com where the word "suite" appears in the label
1141 // and the name "address2" clearly indicates that this is the address line 2.
1142 // See http://crbug.com/48197 for details.
1143 TEST(FormStructureTest
, TwoAddressLinesEbay
) {
1144 scoped_ptr
<FormStructure
> form_structure
;
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();
1164 EXPECT_TRUE(form_structure
->IsAutofillable());
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
;
1180 FormFieldData field
;
1181 field
.form_control_type
= "text";
1183 field
.label
= ASCIIToUTF16("Address Line1");
1184 field
.name
= ASCIIToUTF16("Address");
1185 form
.fields
.push_back(field
);
1187 field
.label
= ASCIIToUTF16("Address Line2");
1188 field
.name
= ASCIIToUTF16("Address");
1189 form
.fields
.push_back(field
);
1191 field
.label
= ASCIIToUTF16("State/Province/Region");
1192 field
.name
= ASCIIToUTF16("State");
1193 form
.fields
.push_back(field
);
1195 form_structure
.reset(new FormStructure(form
));
1196 form_structure
->DetermineHeuristicTypes();
1197 EXPECT_TRUE(form_structure
->IsAutofillable());
1198 ASSERT_EQ(3U, form_structure
->field_count());
1199 ASSERT_EQ(3U, form_structure
->autofill_count());
1202 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(0)->heuristic_type());
1204 EXPECT_EQ(ADDRESS_HOME_LINE2
, form_structure
->field(1)->heuristic_type());
1206 EXPECT_EQ(ADDRESS_HOME_STATE
, form_structure
->field(2)->heuristic_type());
1209 // This example comes from lego.com's checkout page.
1210 TEST(FormStructureTest
, HeuristicsWithBilling
) {
1211 scoped_ptr
<FormStructure
> form_structure
;
1214 FormFieldData field
;
1215 field
.form_control_type
= "text";
1217 field
.label
= ASCIIToUTF16("First Name*:");
1218 field
.name
= ASCIIToUTF16("editBillingAddress$firstNameBox");
1219 form
.fields
.push_back(field
);
1221 field
.label
= ASCIIToUTF16("Last Name*:");
1222 field
.name
= ASCIIToUTF16("editBillingAddress$lastNameBox");
1223 form
.fields
.push_back(field
);
1225 field
.label
= ASCIIToUTF16("Company Name:");
1226 field
.name
= ASCIIToUTF16("editBillingAddress$companyBox");
1227 form
.fields
.push_back(field
);
1229 field
.label
= ASCIIToUTF16("Address*:");
1230 field
.name
= ASCIIToUTF16("editBillingAddress$addressLine1Box");
1231 form
.fields
.push_back(field
);
1233 field
.label
= ASCIIToUTF16("Apt/Suite :");
1234 field
.name
= ASCIIToUTF16("editBillingAddress$addressLine2Box");
1235 form
.fields
.push_back(field
);
1237 field
.label
= ASCIIToUTF16("City*:");
1238 field
.name
= ASCIIToUTF16("editBillingAddress$cityBox");
1239 form
.fields
.push_back(field
);
1241 field
.label
= ASCIIToUTF16("State/Province*:");
1242 field
.name
= ASCIIToUTF16("editBillingAddress$stateDropDown");
1243 form
.fields
.push_back(field
);
1245 field
.label
= ASCIIToUTF16("Country*:");
1246 field
.name
= ASCIIToUTF16("editBillingAddress$countryDropDown");
1247 form
.fields
.push_back(field
);
1249 field
.label
= ASCIIToUTF16("Postal Code*:");
1250 field
.name
= ASCIIToUTF16("editBillingAddress$zipCodeBox");
1251 form
.fields
.push_back(field
);
1253 field
.label
= ASCIIToUTF16("Phone*:");
1254 field
.name
= ASCIIToUTF16("editBillingAddress$phoneBox");
1255 form
.fields
.push_back(field
);
1257 field
.label
= ASCIIToUTF16("Email Address*:");
1258 field
.name
= ASCIIToUTF16("email$emailBox");
1259 form
.fields
.push_back(field
);
1261 form_structure
.reset(new FormStructure(form
));
1262 form_structure
->DetermineHeuristicTypes();
1263 EXPECT_TRUE(form_structure
->IsAutofillable());
1264 ASSERT_EQ(11U, form_structure
->field_count());
1265 ASSERT_EQ(11U, form_structure
->autofill_count());
1267 EXPECT_EQ(NAME_FIRST
, form_structure
->field(0)->heuristic_type());
1268 EXPECT_EQ(NAME_LAST
, form_structure
->field(1)->heuristic_type());
1269 EXPECT_EQ(COMPANY_NAME
, form_structure
->field(2)->heuristic_type());
1270 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(3)->heuristic_type());
1271 EXPECT_EQ(ADDRESS_HOME_LINE2
, form_structure
->field(4)->heuristic_type());
1272 EXPECT_EQ(ADDRESS_HOME_CITY
, form_structure
->field(5)->heuristic_type());
1273 EXPECT_EQ(ADDRESS_HOME_STATE
, form_structure
->field(6)->heuristic_type());
1274 EXPECT_EQ(ADDRESS_HOME_COUNTRY
, form_structure
->field(7)->heuristic_type());
1275 EXPECT_EQ(ADDRESS_HOME_ZIP
, form_structure
->field(8)->heuristic_type());
1276 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER
,
1277 form_structure
->field(9)->heuristic_type());
1278 EXPECT_EQ(EMAIL_ADDRESS
, form_structure
->field(10)->heuristic_type());
1281 TEST(FormStructureTest
, ThreePartPhoneNumber
) {
1282 scoped_ptr
<FormStructure
> form_structure
;
1285 FormFieldData field
;
1286 field
.form_control_type
= "text";
1288 field
.label
= ASCIIToUTF16("Phone:");
1289 field
.name
= ASCIIToUTF16("dayphone1");
1290 field
.max_length
= 0;
1291 form
.fields
.push_back(field
);
1293 field
.label
= ASCIIToUTF16("-");
1294 field
.name
= ASCIIToUTF16("dayphone2");
1295 field
.max_length
= 3; // Size of prefix is 3.
1296 form
.fields
.push_back(field
);
1298 field
.label
= ASCIIToUTF16("-");
1299 field
.name
= ASCIIToUTF16("dayphone3");
1300 field
.max_length
= 4; // Size of suffix is 4. If unlimited size is
1301 // passed, phone will be parsed as
1302 // <country code> - <area code> - <phone>.
1303 form
.fields
.push_back(field
);
1305 field
.label
= ASCIIToUTF16("ext.:");
1306 field
.name
= ASCIIToUTF16("dayphone4");
1307 field
.max_length
= 0;
1308 form
.fields
.push_back(field
);
1310 form_structure
.reset(new FormStructure(form
));
1311 form_structure
->DetermineHeuristicTypes();
1312 EXPECT_TRUE(form_structure
->IsAutofillable());
1313 ASSERT_EQ(4U, form_structure
->field_count());
1314 ASSERT_EQ(3U, form_structure
->autofill_count());
1317 EXPECT_EQ(PHONE_HOME_CITY_CODE
, form_structure
->field(0)->heuristic_type());
1318 // Phone number suffix.
1319 EXPECT_EQ(PHONE_HOME_NUMBER
,
1320 form_structure
->field(1)->heuristic_type());
1321 // Phone number suffix.
1322 EXPECT_EQ(PHONE_HOME_NUMBER
,
1323 form_structure
->field(2)->heuristic_type());
1325 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(3)->heuristic_type());
1328 TEST(FormStructureTest
, HeuristicsInfernoCC
) {
1329 scoped_ptr
<FormStructure
> form_structure
;
1332 FormFieldData field
;
1333 field
.form_control_type
= "text";
1335 field
.label
= ASCIIToUTF16("Name on Card");
1336 field
.name
= ASCIIToUTF16("name_on_card");
1337 form
.fields
.push_back(field
);
1339 field
.label
= ASCIIToUTF16("Address");
1340 field
.name
= ASCIIToUTF16("billing_address");
1341 form
.fields
.push_back(field
);
1343 field
.label
= ASCIIToUTF16("Card Number");
1344 field
.name
= ASCIIToUTF16("card_number");
1345 form
.fields
.push_back(field
);
1347 field
.label
= ASCIIToUTF16("Expiration Date");
1348 field
.name
= ASCIIToUTF16("expiration_month");
1349 form
.fields
.push_back(field
);
1351 field
.label
= ASCIIToUTF16("Expiration Year");
1352 field
.name
= ASCIIToUTF16("expiration_year");
1353 form
.fields
.push_back(field
);
1355 form_structure
.reset(new FormStructure(form
));
1356 form_structure
->DetermineHeuristicTypes();
1357 EXPECT_TRUE(form_structure
->IsAutofillable());
1359 // Expect the correct number of fields.
1360 ASSERT_EQ(5U, form_structure
->field_count());
1361 EXPECT_EQ(5U, form_structure
->autofill_count());
1364 EXPECT_EQ(CREDIT_CARD_NAME
, form_structure
->field(0)->heuristic_type());
1366 EXPECT_EQ(ADDRESS_HOME_LINE1
, form_structure
->field(1)->heuristic_type());
1368 EXPECT_EQ(CREDIT_CARD_NUMBER
, form_structure
->field(2)->heuristic_type());
1370 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, form_structure
->field(3)->heuristic_type());
1372 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
1373 form_structure
->field(4)->heuristic_type());
1376 TEST(FormStructureTest
, CVCCodeClash
) {
1377 scoped_ptr
<FormStructure
> form_structure
;
1380 FormFieldData field
;
1381 field
.form_control_type
= "text";
1383 field
.label
= ASCIIToUTF16("Card number");
1384 field
.name
= ASCIIToUTF16("ccnumber");
1385 form
.fields
.push_back(field
);
1387 field
.label
= ASCIIToUTF16("First name");
1388 field
.name
= ASCIIToUTF16("first_name");
1389 form
.fields
.push_back(field
);
1391 field
.label
= ASCIIToUTF16("Last name");
1392 field
.name
= ASCIIToUTF16("last_name");
1393 form
.fields
.push_back(field
);
1395 field
.label
= ASCIIToUTF16("Expiration date");
1396 field
.name
= ASCIIToUTF16("ccexpiresmonth");
1397 form
.fields
.push_back(field
);
1399 field
.label
= base::string16();
1400 field
.name
= ASCIIToUTF16("ccexpiresyear");
1401 form
.fields
.push_back(field
);
1403 field
.label
= ASCIIToUTF16("cvc number");
1404 field
.name
= ASCIIToUTF16("csc");
1405 form
.fields
.push_back(field
);
1407 form_structure
.reset(new FormStructure(form
));
1408 form_structure
->DetermineHeuristicTypes();
1409 EXPECT_TRUE(form_structure
->IsAutofillable());
1411 // Expect the correct number of fields.
1412 ASSERT_EQ(6U, form_structure
->field_count());
1413 ASSERT_EQ(5U, form_structure
->autofill_count());
1416 EXPECT_EQ(CREDIT_CARD_NUMBER
, form_structure
->field(0)->heuristic_type());
1417 // First name, taken as name on card.
1418 EXPECT_EQ(CREDIT_CARD_NAME
, form_structure
->field(1)->heuristic_type());
1419 // Last name is not merged.
1420 EXPECT_EQ(UNKNOWN_TYPE
, form_structure
->field(2)->heuristic_type());
1422 EXPECT_EQ(CREDIT_CARD_EXP_MONTH
, form_structure
->field(3)->heuristic_type());
1424 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR
,
1425 form_structure
->field(4)->heuristic_type());
1427 EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE
,
1428 form_structure
->field(5)->heuristic_type());
1431 TEST(FormStructureTest
, EncodeQueryRequest
) {
1434 FormFieldData field
;
1435 field
.form_control_type
= "text";
1437 field
.label
= ASCIIToUTF16("Name on Card");
1438 field
.name
= ASCIIToUTF16("name_on_card");
1439 form
.fields
.push_back(field
);
1441 field
.label
= ASCIIToUTF16("Address");
1442 field
.name
= ASCIIToUTF16("billing_address");
1443 form
.fields
.push_back(field
);
1445 field
.label
= ASCIIToUTF16("Card Number");
1446 field
.name
= ASCIIToUTF16("card_number");
1447 form
.fields
.push_back(field
);
1449 field
.label
= ASCIIToUTF16("Expiration Date");
1450 field
.name
= ASCIIToUTF16("expiration_month");
1451 form
.fields
.push_back(field
);
1453 field
.label
= ASCIIToUTF16("Expiration Year");
1454 field
.name
= ASCIIToUTF16("expiration_year");
1455 form
.fields
.push_back(field
);
1457 // Add checkable field.
1458 FormFieldData checkable_field
;
1459 checkable_field
.is_checkable
= true;
1460 checkable_field
.label
= ASCIIToUTF16("Checkable1");
1461 checkable_field
.name
= ASCIIToUTF16("Checkable1");
1462 form
.fields
.push_back(checkable_field
);
1464 ScopedVector
<FormStructure
> forms
;
1465 forms
.push_back(new FormStructure(form
));
1466 std::vector
<std::string
> encoded_signatures
;
1467 std::string encoded_xml
;
1468 const char kSignature1
[] = "11337937696949187602";
1469 const char kResponse1
[] =
1470 "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1471 "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
1472 "<form signature=\"11337937696949187602\">"
1473 "<field signature=\"412125936\"/>"
1474 "<field signature=\"1917667676\"/>"
1475 "<field signature=\"2226358947\"/>"
1476 "<field signature=\"747221617\"/>"
1477 "<field signature=\"4108155786\"/>"
1480 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms
.get(),
1481 &encoded_signatures
,
1483 ASSERT_EQ(1U, encoded_signatures
.size());
1484 EXPECT_EQ(kSignature1
, encoded_signatures
[0]);
1485 EXPECT_EQ(kResponse1
, encoded_xml
);
1487 // Add the same form, only one will be encoded, so EncodeQueryRequest() should
1488 // return the same data.
1489 forms
.push_back(new FormStructure(form
));
1490 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms
.get(),
1491 &encoded_signatures
,
1493 ASSERT_EQ(1U, encoded_signatures
.size());
1494 EXPECT_EQ(kSignature1
, encoded_signatures
[0]);
1495 EXPECT_EQ(kResponse1
, encoded_xml
);
1496 // Add 5 address fields - this should be still a valid form.
1497 for (size_t i
= 0; i
< 5; ++i
) {
1498 field
.label
= ASCIIToUTF16("Address");
1499 field
.name
= ASCIIToUTF16("address");
1500 form
.fields
.push_back(field
);
1503 forms
.push_back(new FormStructure(form
));
1504 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms
.get(),
1505 &encoded_signatures
,
1507 ASSERT_EQ(2U, encoded_signatures
.size());
1508 EXPECT_EQ(kSignature1
, encoded_signatures
[0]);
1509 const char kSignature2
[] = "8308881815906226214";
1510 EXPECT_EQ(kSignature2
, encoded_signatures
[1]);
1511 const char kResponse2
[] =
1512 "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1513 "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
1514 "<form signature=\"11337937696949187602\">"
1515 "<field signature=\"412125936\"/>"
1516 "<field signature=\"1917667676\"/>"
1517 "<field signature=\"2226358947\"/>"
1518 "<field signature=\"747221617\"/>"
1519 "<field signature=\"4108155786\"/>"
1521 "<form signature=\"8308881815906226214\">"
1522 "<field signature=\"412125936\"/>"
1523 "<field signature=\"1917667676\"/>"
1524 "<field signature=\"2226358947\"/>"
1525 "<field signature=\"747221617\"/>"
1526 "<field signature=\"4108155786\"/>"
1527 "<field signature=\"509334676\"/>"
1528 "<field signature=\"509334676\"/>"
1529 "<field signature=\"509334676\"/>"
1530 "<field signature=\"509334676\"/>"
1531 "<field signature=\"509334676\"/>"
1534 EXPECT_EQ(kResponse2
, encoded_xml
);
1536 FormData
malformed_form(form
);
1537 // Add 50 address fields - the form is not valid anymore, but previous ones
1538 // are. The result should be the same as in previous test.
1539 for (size_t i
= 0; i
< 50; ++i
) {
1540 field
.label
= ASCIIToUTF16("Address");
1541 field
.name
= ASCIIToUTF16("address");
1542 malformed_form
.fields
.push_back(field
);
1545 forms
.push_back(new FormStructure(malformed_form
));
1546 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms
.get(),
1547 &encoded_signatures
,
1549 ASSERT_EQ(2U, encoded_signatures
.size());
1550 EXPECT_EQ(kSignature1
, encoded_signatures
[0]);
1551 EXPECT_EQ(kSignature2
, encoded_signatures
[1]);
1552 EXPECT_EQ(kResponse2
, encoded_xml
);
1554 // Check that we fail if there are only bad form(s).
1555 ScopedVector
<FormStructure
> bad_forms
;
1556 bad_forms
.push_back(new FormStructure(malformed_form
));
1557 EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms
.get(),
1558 &encoded_signatures
,
1560 EXPECT_EQ(0U, encoded_signatures
.size());
1561 EXPECT_EQ("", encoded_xml
);
1564 TEST(FormStructureTest
, EncodeUploadRequest
) {
1565 scoped_ptr
<FormStructure
> form_structure
;
1566 std::vector
<ServerFieldTypeSet
> possible_field_types
;
1568 form_structure
.reset(new FormStructure(form
));
1569 form_structure
->DetermineHeuristicTypes();
1571 FormFieldData field
;
1572 field
.form_control_type
= "text";
1574 field
.label
= ASCIIToUTF16("First Name");
1575 field
.name
= ASCIIToUTF16("firstname");
1576 form
.fields
.push_back(field
);
1577 possible_field_types
.push_back(ServerFieldTypeSet());
1578 possible_field_types
.back().insert(NAME_FIRST
);
1580 field
.label
= ASCIIToUTF16("Last Name");
1581 field
.name
= ASCIIToUTF16("lastname");
1582 form
.fields
.push_back(field
);
1583 possible_field_types
.push_back(ServerFieldTypeSet());
1584 possible_field_types
.back().insert(NAME_LAST
);
1586 field
.label
= ASCIIToUTF16("Email");
1587 field
.name
= ASCIIToUTF16("email");
1588 field
.form_control_type
= "email";
1589 form
.fields
.push_back(field
);
1590 possible_field_types
.push_back(ServerFieldTypeSet());
1591 possible_field_types
.back().insert(EMAIL_ADDRESS
);
1593 field
.label
= ASCIIToUTF16("Phone");
1594 field
.name
= ASCIIToUTF16("phone");
1595 field
.form_control_type
= "number";
1596 form
.fields
.push_back(field
);
1597 possible_field_types
.push_back(ServerFieldTypeSet());
1598 possible_field_types
.back().insert(PHONE_HOME_WHOLE_NUMBER
);
1600 field
.label
= ASCIIToUTF16("Country");
1601 field
.name
= ASCIIToUTF16("country");
1602 field
.form_control_type
= "select-one";
1603 form
.fields
.push_back(field
);
1604 possible_field_types
.push_back(ServerFieldTypeSet());
1605 possible_field_types
.back().insert(ADDRESS_HOME_COUNTRY
);
1607 // Add checkable field.
1608 FormFieldData checkable_field
;
1609 checkable_field
.is_checkable
= true;
1610 checkable_field
.label
= ASCIIToUTF16("Checkable1");
1611 checkable_field
.name
= ASCIIToUTF16("Checkable1");
1612 form
.fields
.push_back(checkable_field
);
1613 possible_field_types
.push_back(ServerFieldTypeSet());
1614 possible_field_types
.back().insert(ADDRESS_HOME_COUNTRY
);
1616 form_structure
.reset(new FormStructure(form
));
1618 ASSERT_EQ(form_structure
->field_count(), possible_field_types
.size());
1619 for (size_t i
= 0; i
< form_structure
->field_count(); ++i
)
1620 form_structure
->field(i
)->set_possible_types(possible_field_types
[i
]);
1622 ServerFieldTypeSet available_field_types
;
1623 available_field_types
.insert(NAME_FIRST
);
1624 available_field_types
.insert(NAME_LAST
);
1625 available_field_types
.insert(ADDRESS_HOME_LINE1
);
1626 available_field_types
.insert(ADDRESS_HOME_LINE2
);
1627 available_field_types
.insert(ADDRESS_HOME_COUNTRY
);
1628 available_field_types
.insert(ADDRESS_BILLING_LINE1
);
1629 available_field_types
.insert(ADDRESS_BILLING_LINE2
);
1630 available_field_types
.insert(EMAIL_ADDRESS
);
1631 available_field_types
.insert(PHONE_HOME_WHOLE_NUMBER
);
1633 std::string encoded_xml
;
1634 EXPECT_TRUE(form_structure
->EncodeUploadRequest(available_field_types
, false,
1636 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1637 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1638 "formsignature=\"8736493185895608956\" autofillused=\"false\" "
1639 "datapresent=\"144200030e\">"
1640 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1641 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1642 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1643 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1644 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1645 "</autofillupload>",
1647 EXPECT_TRUE(form_structure
->EncodeUploadRequest(available_field_types
, true,
1649 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1650 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1651 "formsignature=\"8736493185895608956\" autofillused=\"true\" "
1652 "datapresent=\"144200030e\">"
1653 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1654 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1655 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1656 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1657 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1658 "</autofillupload>",
1661 // Add 2 address fields - this should be still a valid form.
1662 for (size_t i
= 0; i
< 2; ++i
) {
1663 field
.label
= ASCIIToUTF16("Address");
1664 field
.name
= ASCIIToUTF16("address");
1665 field
.form_control_type
= "text";
1666 form
.fields
.push_back(field
);
1667 possible_field_types
.push_back(ServerFieldTypeSet());
1668 possible_field_types
.back().insert(ADDRESS_HOME_LINE1
);
1669 possible_field_types
.back().insert(ADDRESS_HOME_LINE2
);
1670 possible_field_types
.back().insert(ADDRESS_BILLING_LINE1
);
1671 possible_field_types
.back().insert(ADDRESS_BILLING_LINE2
);
1674 form_structure
.reset(new FormStructure(form
));
1675 ASSERT_EQ(form_structure
->field_count(), possible_field_types
.size());
1676 for (size_t i
= 0; i
< form_structure
->field_count(); ++i
)
1677 form_structure
->field(i
)->set_possible_types(possible_field_types
[i
]);
1679 EXPECT_TRUE(form_structure
->EncodeUploadRequest(available_field_types
, false,
1681 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1682 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1683 "formsignature=\"7816485729218079147\" autofillused=\"false\" "
1684 "datapresent=\"144200030e\">"
1685 "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1686 "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1687 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1688 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1689 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1690 "<field signature=\"509334676\" autofilltype=\"30\"/>"
1691 "<field signature=\"509334676\" autofilltype=\"31\"/>"
1692 "<field signature=\"509334676\" autofilltype=\"37\"/>"
1693 "<field signature=\"509334676\" autofilltype=\"38\"/>"
1694 "<field signature=\"509334676\" autofilltype=\"30\"/>"
1695 "<field signature=\"509334676\" autofilltype=\"31\"/>"
1696 "<field signature=\"509334676\" autofilltype=\"37\"/>"
1697 "<field signature=\"509334676\" autofilltype=\"38\"/>"
1698 "</autofillupload>",
1701 // Add 50 address fields - now the form is invalid, as it has too many fields.
1702 for (size_t i
= 0; i
< 50; ++i
) {
1703 field
.label
= ASCIIToUTF16("Address");
1704 field
.name
= ASCIIToUTF16("address");
1705 field
.form_control_type
= "text";
1706 form
.fields
.push_back(field
);
1707 possible_field_types
.push_back(ServerFieldTypeSet());
1708 possible_field_types
.back().insert(ADDRESS_HOME_LINE1
);
1709 possible_field_types
.back().insert(ADDRESS_HOME_LINE2
);
1710 possible_field_types
.back().insert(ADDRESS_BILLING_LINE1
);
1711 possible_field_types
.back().insert(ADDRESS_BILLING_LINE2
);
1713 form_structure
.reset(new FormStructure(form
));
1714 ASSERT_EQ(form_structure
->field_count(), possible_field_types
.size());
1715 for (size_t i
= 0; i
< form_structure
->field_count(); ++i
)
1716 form_structure
->field(i
)->set_possible_types(possible_field_types
[i
]);
1717 EXPECT_FALSE(form_structure
->EncodeUploadRequest(available_field_types
, false,
1721 TEST(FormStructureTest
, EncodeFieldAssignments
) {
1722 scoped_ptr
<FormStructure
> form_structure
;
1723 std::vector
<ServerFieldTypeSet
> possible_field_types
;
1725 form_structure
.reset(new FormStructure(form
));
1726 form_structure
->DetermineHeuristicTypes();
1728 FormFieldData field
;
1729 field
.form_control_type
= "text";
1731 field
.label
= ASCIIToUTF16("First Name");
1732 field
.name
= ASCIIToUTF16("firstname");
1733 form
.fields
.push_back(field
);
1734 possible_field_types
.push_back(ServerFieldTypeSet());
1735 possible_field_types
.back().insert(NAME_FIRST
);
1737 field
.label
= ASCIIToUTF16("Last Name");
1738 field
.name
= ASCIIToUTF16("lastname");
1739 form
.fields
.push_back(field
);
1740 possible_field_types
.push_back(ServerFieldTypeSet());
1741 possible_field_types
.back().insert(NAME_LAST
);
1743 field
.label
= ASCIIToUTF16("Email");
1744 field
.name
= ASCIIToUTF16("email");
1745 field
.form_control_type
= "email";
1746 form
.fields
.push_back(field
);
1747 possible_field_types
.push_back(ServerFieldTypeSet());
1748 possible_field_types
.back().insert(EMAIL_ADDRESS
);
1750 field
.label
= ASCIIToUTF16("Phone");
1751 field
.name
= ASCIIToUTF16("phone");
1752 field
.form_control_type
= "number";
1753 form
.fields
.push_back(field
);
1754 possible_field_types
.push_back(ServerFieldTypeSet());
1755 possible_field_types
.back().insert(PHONE_HOME_WHOLE_NUMBER
);
1757 field
.label
= ASCIIToUTF16("Country");
1758 field
.name
= ASCIIToUTF16("country");
1759 field
.form_control_type
= "select-one";
1760 form
.fields
.push_back(field
);
1761 possible_field_types
.push_back(ServerFieldTypeSet());
1762 possible_field_types
.back().insert(ADDRESS_HOME_COUNTRY
);
1764 // Add checkable field.
1765 FormFieldData checkable_field
;
1766 checkable_field
.is_checkable
= true;
1767 checkable_field
.label
= ASCIIToUTF16("Checkable1");
1768 checkable_field
.name
= ASCIIToUTF16("Checkable1");
1769 form
.fields
.push_back(checkable_field
);
1770 possible_field_types
.push_back(ServerFieldTypeSet());
1771 possible_field_types
.back().insert(ADDRESS_HOME_COUNTRY
);
1773 form_structure
.reset(new FormStructure(form
));
1775 ASSERT_EQ(form_structure
->field_count(), possible_field_types
.size());
1776 for (size_t i
= 0; i
< form_structure
->field_count(); ++i
)
1777 form_structure
->field(i
)->set_possible_types(possible_field_types
[i
]);
1779 ServerFieldTypeSet available_field_types
;
1780 available_field_types
.insert(NAME_FIRST
);
1781 available_field_types
.insert(NAME_LAST
);
1782 available_field_types
.insert(ADDRESS_HOME_LINE1
);
1783 available_field_types
.insert(ADDRESS_HOME_LINE2
);
1784 available_field_types
.insert(ADDRESS_HOME_COUNTRY
);
1785 available_field_types
.insert(ADDRESS_BILLING_LINE1
);
1786 available_field_types
.insert(ADDRESS_BILLING_LINE2
);
1787 available_field_types
.insert(EMAIL_ADDRESS
);
1788 available_field_types
.insert(PHONE_HOME_WHOLE_NUMBER
);
1790 std::string encoded_xml
;
1791 EXPECT_TRUE(form_structure
->EncodeFieldAssignments(
1792 available_field_types
, &encoded_xml
));
1794 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1795 "<fieldassignments formsignature=\"8736493185895608956\">"
1796 "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1797 "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1798 "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1799 "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1800 "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1801 "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
1802 "</fieldassignments>",
1805 // Add 2 address fields - this should be still a valid form.
1806 for (size_t i
= 0; i
< 2; ++i
) {
1807 field
.label
= ASCIIToUTF16("Address");
1808 field
.name
= ASCIIToUTF16("address");
1809 field
.form_control_type
= "text";
1810 form
.fields
.push_back(field
);
1811 possible_field_types
.push_back(ServerFieldTypeSet());
1812 possible_field_types
.back().insert(ADDRESS_HOME_LINE1
);
1813 possible_field_types
.back().insert(ADDRESS_HOME_LINE2
);
1814 possible_field_types
.back().insert(ADDRESS_BILLING_LINE1
);
1815 possible_field_types
.back().insert(ADDRESS_BILLING_LINE2
);
1818 form_structure
.reset(new FormStructure(form
));
1819 ASSERT_EQ(form_structure
->field_count(), possible_field_types
.size());
1820 for (size_t i
= 0; i
< form_structure
->field_count(); ++i
)
1821 form_structure
->field(i
)->set_possible_types(possible_field_types
[i
]);
1823 EXPECT_TRUE(form_structure
->EncodeFieldAssignments(
1824 available_field_types
, &encoded_xml
));
1826 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1827 "<fieldassignments formsignature=\"7816485729218079147\">"
1828 "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1829 "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1830 "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1831 "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1832 "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1833 "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
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 "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>"
1839 "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
1840 "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
1841 "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
1842 "</fieldassignments>",
1846 // Check that we compute the "datapresent" string correctly for the given
1847 // |available_types|.
1848 TEST(FormStructureTest
, CheckDataPresence
) {
1851 FormFieldData field
;
1852 field
.form_control_type
= "text";
1854 field
.label
= ASCIIToUTF16("First Name");
1855 field
.name
= ASCIIToUTF16("first");
1856 form
.fields
.push_back(field
);
1858 field
.label
= ASCIIToUTF16("Last Name");
1859 field
.name
= ASCIIToUTF16("last");
1860 form
.fields
.push_back(field
);
1862 field
.label
= ASCIIToUTF16("Email");
1863 field
.name
= ASCIIToUTF16("email");
1864 form
.fields
.push_back(field
);
1866 FormStructure
form_structure(form
);
1868 ServerFieldTypeSet unknown_type
;
1869 unknown_type
.insert(UNKNOWN_TYPE
);
1870 for (size_t i
= 0; i
< form_structure
.field_count(); ++i
)
1871 form_structure
.field(i
)->set_possible_types(unknown_type
);
1873 // No available types.
1874 // datapresent should be "" == trimmmed(0x0000000000000000) ==
1875 // 0b0000000000000000000000000000000000000000000000000000000000000000
1876 ServerFieldTypeSet available_field_types
;
1878 std::string encoded_xml
;
1879 EXPECT_TRUE(form_structure
.EncodeUploadRequest(available_field_types
, false,
1881 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1882 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1883 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1884 " datapresent=\"\">"
1885 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1886 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1887 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1888 "</autofillupload>",
1891 // Only a few types available.
1892 // datapresent should be "1540000240" == trimmmed(0x1540000240000000) ==
1893 // 0b0001010101000000000000000000001001000000000000000000000000000000
1894 // The set bits are:
1898 // 9 == EMAIL_ADDRESS
1899 // 30 == ADDRESS_HOME_LINE1
1900 // 33 == ADDRESS_HOME_CITY
1901 available_field_types
.clear();
1902 available_field_types
.insert(NAME_FIRST
);
1903 available_field_types
.insert(NAME_LAST
);
1904 available_field_types
.insert(NAME_FULL
);
1905 available_field_types
.insert(EMAIL_ADDRESS
);
1906 available_field_types
.insert(ADDRESS_HOME_LINE1
);
1907 available_field_types
.insert(ADDRESS_HOME_CITY
);
1909 EXPECT_TRUE(form_structure
.EncodeUploadRequest(available_field_types
, false,
1911 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1912 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1913 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1914 " datapresent=\"1540000240\">"
1915 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1916 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1917 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1918 "</autofillupload>",
1921 // All supported non-credit card types available.
1922 // datapresent should be "1f7e000378000008" == trimmmed(0x1f7e000378000008) ==
1923 // 0b0001111101111110000000000000001101111000000000000000000000001000
1924 // The set bits are:
1928 // 6 == NAME_MIDDLE_INITIAL
1930 // 9 == EMAIL_ADDRESS
1931 // 10 == PHONE_HOME_NUMBER,
1932 // 11 == PHONE_HOME_CITY_CODE,
1933 // 12 == PHONE_HOME_COUNTRY_CODE,
1934 // 13 == PHONE_HOME_CITY_AND_NUMBER,
1935 // 14 == PHONE_HOME_WHOLE_NUMBER,
1936 // 30 == ADDRESS_HOME_LINE1
1937 // 31 == ADDRESS_HOME_LINE2
1938 // 33 == ADDRESS_HOME_CITY
1939 // 34 == ADDRESS_HOME_STATE
1940 // 35 == ADDRESS_HOME_ZIP
1941 // 36 == ADDRESS_HOME_COUNTRY
1942 // 60 == COMPANY_NAME
1943 available_field_types
.clear();
1944 available_field_types
.insert(NAME_FIRST
);
1945 available_field_types
.insert(NAME_MIDDLE
);
1946 available_field_types
.insert(NAME_LAST
);
1947 available_field_types
.insert(NAME_MIDDLE_INITIAL
);
1948 available_field_types
.insert(NAME_FULL
);
1949 available_field_types
.insert(EMAIL_ADDRESS
);
1950 available_field_types
.insert(PHONE_HOME_NUMBER
);
1951 available_field_types
.insert(PHONE_HOME_CITY_CODE
);
1952 available_field_types
.insert(PHONE_HOME_COUNTRY_CODE
);
1953 available_field_types
.insert(PHONE_HOME_CITY_AND_NUMBER
);
1954 available_field_types
.insert(PHONE_HOME_WHOLE_NUMBER
);
1955 available_field_types
.insert(ADDRESS_HOME_LINE1
);
1956 available_field_types
.insert(ADDRESS_HOME_LINE2
);
1957 available_field_types
.insert(ADDRESS_HOME_CITY
);
1958 available_field_types
.insert(ADDRESS_HOME_STATE
);
1959 available_field_types
.insert(ADDRESS_HOME_ZIP
);
1960 available_field_types
.insert(ADDRESS_HOME_COUNTRY
);
1961 available_field_types
.insert(COMPANY_NAME
);
1963 EXPECT_TRUE(form_structure
.EncodeUploadRequest(available_field_types
, false,
1965 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1966 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1967 " formsignature=\"6402244543831589061\" autofillused=\"false\""
1968 " datapresent=\"1f7e000378000008\">"
1969 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1970 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1971 "<field signature=\"420638584\" autofilltype=\"1\"/>"
1972 "</autofillupload>",
1975 // All supported credit card types available.
1976 // datapresent should be "0000000000001fc0" == trimmmed(0x0000000000001fc0) ==
1977 // 0b0000000000000000000000000000000000000000000000000001111111000000
1978 // The set bits are:
1979 // 51 == CREDIT_CARD_NAME
1980 // 52 == CREDIT_CARD_NUMBER
1981 // 53 == CREDIT_CARD_EXP_MONTH
1982 // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
1983 // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
1984 // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
1985 // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
1986 available_field_types
.clear();
1987 available_field_types
.insert(CREDIT_CARD_NAME
);
1988 available_field_types
.insert(CREDIT_CARD_NUMBER
);
1989 available_field_types
.insert(CREDIT_CARD_EXP_MONTH
);
1990 available_field_types
.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR
);
1991 available_field_types
.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR
);
1992 available_field_types
.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
);
1993 available_field_types
.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
);
1995 EXPECT_TRUE(form_structure
.EncodeUploadRequest(available_field_types
, false,
1997 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1998 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1999 " formsignature=\"6402244543831589061\" autofillused=\"false\""
2000 " datapresent=\"0000000000001fc0\">"
2001 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
2002 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2003 "<field signature=\"420638584\" autofilltype=\"1\"/>"
2004 "</autofillupload>",
2007 // All supported types available.
2008 // datapresent should be "1f7e000378001fc8" == trimmmed(0x1f7e000378001fc8) ==
2009 // 0b0001111101111110000000000000001101111000000000000001111111001000
2010 // The set bits are:
2014 // 6 == NAME_MIDDLE_INITIAL
2016 // 9 == EMAIL_ADDRESS
2017 // 10 == PHONE_HOME_NUMBER,
2018 // 11 == PHONE_HOME_CITY_CODE,
2019 // 12 == PHONE_HOME_COUNTRY_CODE,
2020 // 13 == PHONE_HOME_CITY_AND_NUMBER,
2021 // 14 == PHONE_HOME_WHOLE_NUMBER,
2022 // 30 == ADDRESS_HOME_LINE1
2023 // 31 == ADDRESS_HOME_LINE2
2024 // 33 == ADDRESS_HOME_CITY
2025 // 34 == ADDRESS_HOME_STATE
2026 // 35 == ADDRESS_HOME_ZIP
2027 // 36 == ADDRESS_HOME_COUNTRY
2028 // 51 == CREDIT_CARD_NAME
2029 // 52 == CREDIT_CARD_NUMBER
2030 // 53 == CREDIT_CARD_EXP_MONTH
2031 // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
2032 // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
2033 // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
2034 // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
2035 // 60 == COMPANY_NAME
2036 available_field_types
.clear();
2037 available_field_types
.insert(NAME_FIRST
);
2038 available_field_types
.insert(NAME_MIDDLE
);
2039 available_field_types
.insert(NAME_LAST
);
2040 available_field_types
.insert(NAME_MIDDLE_INITIAL
);
2041 available_field_types
.insert(NAME_FULL
);
2042 available_field_types
.insert(EMAIL_ADDRESS
);
2043 available_field_types
.insert(PHONE_HOME_NUMBER
);
2044 available_field_types
.insert(PHONE_HOME_CITY_CODE
);
2045 available_field_types
.insert(PHONE_HOME_COUNTRY_CODE
);
2046 available_field_types
.insert(PHONE_HOME_CITY_AND_NUMBER
);
2047 available_field_types
.insert(PHONE_HOME_WHOLE_NUMBER
);
2048 available_field_types
.insert(ADDRESS_HOME_LINE1
);
2049 available_field_types
.insert(ADDRESS_HOME_LINE2
);
2050 available_field_types
.insert(ADDRESS_HOME_CITY
);
2051 available_field_types
.insert(ADDRESS_HOME_STATE
);
2052 available_field_types
.insert(ADDRESS_HOME_ZIP
);
2053 available_field_types
.insert(ADDRESS_HOME_COUNTRY
);
2054 available_field_types
.insert(CREDIT_CARD_NAME
);
2055 available_field_types
.insert(CREDIT_CARD_NUMBER
);
2056 available_field_types
.insert(CREDIT_CARD_EXP_MONTH
);
2057 available_field_types
.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR
);
2058 available_field_types
.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR
);
2059 available_field_types
.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
);
2060 available_field_types
.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
);
2061 available_field_types
.insert(COMPANY_NAME
);
2063 EXPECT_TRUE(form_structure
.EncodeUploadRequest(available_field_types
, false,
2065 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2066 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2067 " formsignature=\"6402244543831589061\" autofillused=\"false\""
2068 " datapresent=\"1f7e000378001fc8\">"
2069 "<field signature=\"1089846351\" autofilltype=\"1\"/>"
2070 "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2071 "<field signature=\"420638584\" autofilltype=\"1\"/>"
2072 "</autofillupload>",
2076 TEST(FormStructureTest
, CheckMultipleTypes
) {
2077 // Throughout this test, datapresent should be
2078 // 0x1440000360000008 ==
2079 // 0b0001010001000000000000000000001101100000000000000000000000001000
2080 // The set bits are:
2083 // 9 == EMAIL_ADDRESS
2084 // 30 == ADDRESS_HOME_LINE1
2085 // 31 == ADDRESS_HOME_LINE2
2086 // 33 == ADDRESS_HOME_CITY
2087 // 34 == ADDRESS_HOME_STATE
2088 // 60 == COMPANY_NAME
2089 ServerFieldTypeSet available_field_types
;
2090 available_field_types
.insert(NAME_FIRST
);
2091 available_field_types
.insert(NAME_LAST
);
2092 available_field_types
.insert(EMAIL_ADDRESS
);
2093 available_field_types
.insert(ADDRESS_HOME_LINE1
);
2094 available_field_types
.insert(ADDRESS_HOME_LINE2
);
2095 available_field_types
.insert(ADDRESS_HOME_CITY
);
2096 available_field_types
.insert(ADDRESS_HOME_STATE
);
2097 available_field_types
.insert(COMPANY_NAME
);
2099 // Check that multiple types for the field are processed correctly.
2100 scoped_ptr
<FormStructure
> form_structure
;
2101 std::vector
<ServerFieldTypeSet
> possible_field_types
;
2104 FormFieldData field
;
2105 field
.form_control_type
= "text";
2107 field
.label
= ASCIIToUTF16("email");
2108 field
.name
= ASCIIToUTF16("email");
2109 form
.fields
.push_back(field
);
2110 possible_field_types
.push_back(ServerFieldTypeSet());
2111 possible_field_types
.back().insert(EMAIL_ADDRESS
);
2113 field
.label
= ASCIIToUTF16("First Name");
2114 field
.name
= ASCIIToUTF16("first");
2115 form
.fields
.push_back(field
);
2116 possible_field_types
.push_back(ServerFieldTypeSet());
2117 possible_field_types
.back().insert(NAME_FIRST
);
2119 field
.label
= ASCIIToUTF16("Last Name");
2120 field
.name
= ASCIIToUTF16("last");
2121 form
.fields
.push_back(field
);
2122 possible_field_types
.push_back(ServerFieldTypeSet());
2123 possible_field_types
.back().insert(NAME_LAST
);
2125 field
.label
= ASCIIToUTF16("Address");
2126 field
.name
= ASCIIToUTF16("address");
2127 form
.fields
.push_back(field
);
2128 possible_field_types
.push_back(ServerFieldTypeSet());
2129 possible_field_types
.back().insert(ADDRESS_HOME_LINE1
);
2131 form_structure
.reset(new FormStructure(form
));
2133 for (size_t i
= 0; i
< form_structure
->field_count(); ++i
)
2134 form_structure
->field(i
)->set_possible_types(possible_field_types
[i
]);
2135 std::string encoded_xml
;
2137 // Now we matched both fields singularly.
2138 EXPECT_TRUE(form_structure
->EncodeUploadRequest(available_field_types
, false,
2140 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2141 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2142 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2143 " datapresent=\"1440000360000008\">"
2144 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2145 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2146 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2147 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2148 "</autofillupload>",
2150 // Match third field as both first and last.
2151 possible_field_types
[2].insert(NAME_FIRST
);
2152 form_structure
->field(2)->set_possible_types(possible_field_types
[2]);
2153 EXPECT_TRUE(form_structure
->EncodeUploadRequest(available_field_types
, false,
2155 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2156 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2157 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2158 " datapresent=\"1440000360000008\">"
2159 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2160 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2161 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2162 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2163 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2164 "</autofillupload>",
2166 possible_field_types
[3].insert(ADDRESS_HOME_LINE2
);
2167 form_structure
->field(form_structure
->field_count() - 1)->set_possible_types(
2168 possible_field_types
[form_structure
->field_count() - 1]);
2169 EXPECT_TRUE(form_structure
->EncodeUploadRequest(available_field_types
, false,
2171 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2172 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2173 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2174 " datapresent=\"1440000360000008\">"
2175 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2176 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2177 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2178 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2179 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2180 "<field signature=\"509334676\" autofilltype=\"31\"/>"
2181 "</autofillupload>",
2183 possible_field_types
[3].clear();
2184 possible_field_types
[3].insert(ADDRESS_HOME_LINE1
);
2185 possible_field_types
[3].insert(COMPANY_NAME
);
2186 form_structure
->field(form_structure
->field_count() - 1)->set_possible_types(
2187 possible_field_types
[form_structure
->field_count() - 1]);
2188 EXPECT_TRUE(form_structure
->EncodeUploadRequest(available_field_types
, false,
2190 EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2191 "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2192 " formsignature=\"18062476096658145866\" autofillused=\"false\""
2193 " datapresent=\"1440000360000008\">"
2194 "<field signature=\"420638584\" autofilltype=\"9\"/>"
2195 "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2196 "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2197 "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2198 "<field signature=\"509334676\" autofilltype=\"30\"/>"
2199 "<field signature=\"509334676\" autofilltype=\"60\"/>"
2200 "</autofillupload>",
2204 TEST(FormStructureTest
, CheckFormSignature
) {
2205 // Check that form signature is created correctly.
2206 scoped_ptr
<FormStructure
> form_structure
;
2209 FormFieldData field
;
2210 field
.form_control_type
= "text";
2212 field
.label
= ASCIIToUTF16("email");
2213 field
.name
= ASCIIToUTF16("email");
2214 form
.fields
.push_back(field
);
2216 field
.label
= ASCIIToUTF16("First Name");
2217 field
.name
= ASCIIToUTF16("first");
2218 form
.fields
.push_back(field
);
2220 // Checkable fields shouldn't affect the signature.
2221 field
.label
= ASCIIToUTF16("Select");
2222 field
.name
= ASCIIToUTF16("Select");
2223 field
.form_control_type
= "checkbox";
2224 field
.is_checkable
= true;
2225 form
.fields
.push_back(field
);
2227 form_structure
.reset(new FormStructure(form
));
2229 EXPECT_EQ(FormStructureTest::Hash64Bit(
2230 std::string("://&&email&first")),
2231 form_structure
->FormSignature());
2233 form
.origin
= GURL(std::string("http://www.facebook.com"));
2234 form_structure
.reset(new FormStructure(form
));
2235 EXPECT_EQ(FormStructureTest::Hash64Bit(
2236 std::string("http://www.facebook.com&&email&first")),
2237 form_structure
->FormSignature());
2239 form
.action
= GURL(std::string("https://login.facebook.com/path"));
2240 form_structure
.reset(new FormStructure(form
));
2241 EXPECT_EQ(FormStructureTest::Hash64Bit(
2242 std::string("https://login.facebook.com&&email&first")),
2243 form_structure
->FormSignature());
2245 form
.name
= ASCIIToUTF16("login_form");
2246 form_structure
.reset(new FormStructure(form
));
2247 EXPECT_EQ(FormStructureTest::Hash64Bit(
2248 std::string("https://login.facebook.com&login_form&email&first")),
2249 form_structure
->FormSignature());
2251 field
.is_checkable
= false;
2252 field
.label
= ASCIIToUTF16("Random Field label");
2253 field
.name
= ASCIIToUTF16("random1234");
2254 field
.form_control_type
= "text";
2255 form
.fields
.push_back(field
);
2256 field
.label
= ASCIIToUTF16("Random Field label2");
2257 field
.name
= ASCIIToUTF16("random12345");
2258 form
.fields
.push_back(field
);
2259 field
.label
= ASCIIToUTF16("Random Field label3");
2260 field
.name
= ASCIIToUTF16("1random12345678");
2261 form
.fields
.push_back(field
);
2262 field
.label
= ASCIIToUTF16("Random Field label3");
2263 field
.name
= ASCIIToUTF16("12345random");
2264 form
.fields
.push_back(field
);
2265 form_structure
.reset(new FormStructure(form
));
2266 EXPECT_EQ(FormStructureTest::Hash64Bit(
2267 std::string("https://login.facebook.com&login_form&email&first&"
2268 "random1234&random&1random&random")),
2269 form_structure
->FormSignature());
2272 TEST(FormStructureTest
, ToFormData
) {
2274 form
.name
= ASCIIToUTF16("the-name");
2275 form
.origin
= GURL("http://cool.com");
2276 form
.action
= form
.origin
.Resolve("/login");
2278 FormFieldData field
;
2279 field
.label
= ASCIIToUTF16("username");
2280 field
.name
= ASCIIToUTF16("username");
2281 field
.form_control_type
= "text";
2282 form
.fields
.push_back(field
);
2284 field
.label
= ASCIIToUTF16("password");
2285 field
.name
= ASCIIToUTF16("password");
2286 field
.form_control_type
= "password";
2287 form
.fields
.push_back(field
);
2289 field
.label
= base::string16();
2290 field
.name
= ASCIIToUTF16("Submit");
2291 field
.form_control_type
= "submit";
2292 form
.fields
.push_back(field
);
2294 EXPECT_TRUE(form
.SameFormAs(FormStructure(form
).ToFormData()));
2296 // Currently |FormStructure(form_data)ToFormData().user_submitted| is always
2297 // false. This forces a future author that changes this to update this test.
2298 form
.user_submitted
= true;
2299 EXPECT_FALSE(form
.SameFormAs(FormStructure(form
).ToFormData()));
2302 TEST(FormStructureTest
, SkipFieldTest
) {
2304 form
.name
= ASCIIToUTF16("the-name");
2305 form
.origin
= GURL("http://cool.com");
2306 form
.action
= form
.origin
.Resolve("/login");
2308 FormFieldData field
;
2309 field
.label
= ASCIIToUTF16("username");
2310 field
.name
= ASCIIToUTF16("username");
2311 field
.form_control_type
= "text";
2312 form
.fields
.push_back(field
);
2314 field
.label
= ASCIIToUTF16("select");
2315 field
.name
= ASCIIToUTF16("select");
2316 field
.form_control_type
= "checkbox";
2317 field
.is_checkable
= true;
2318 form
.fields
.push_back(field
);
2320 field
.label
= base::string16();
2321 field
.name
= ASCIIToUTF16("email");
2322 field
.form_control_type
= "text";
2323 field
.is_checkable
= false;
2324 form
.fields
.push_back(field
);
2326 ScopedVector
<FormStructure
> forms
;
2327 forms
.push_back(new FormStructure(form
));
2328 std::vector
<std::string
> encoded_signatures
;
2329 std::string encoded_xml
;
2331 const char kSignature
[] = "18006745212084723782";
2332 const char kResponse
[] =
2333 "<\?xml version=\"1.0\" encoding=\"UTF-8\"?>"
2334 "<autofillquery clientversion=\"6.1.1715.1442/en (GGLL)\">"
2335 "<form signature=\"18006745212084723782\">"
2336 "<field signature=\"239111655\"/>"
2337 "<field signature=\"420638584\"/>"
2340 ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms
.get(),
2341 &encoded_signatures
,
2343 ASSERT_EQ(1U, encoded_signatures
.size());
2344 EXPECT_EQ(kSignature
, encoded_signatures
[0]);
2345 EXPECT_EQ(kResponse
, encoded_xml
);
2348 TEST(FormStructureTest
, PossibleValues
) {
2350 FormFieldData field
;
2351 field
.autocomplete_attribute
= "billing country";
2352 field
.option_contents
.push_back(ASCIIToUTF16("Down Under"));
2353 field
.option_values
.push_back(ASCIIToUTF16("AU"));
2354 field
.option_contents
.push_back(ASCIIToUTF16("Fr"));
2355 field
.option_values
.push_back(ASCIIToUTF16(""));
2356 field
.option_contents
.push_back(ASCIIToUTF16("Germany"));
2357 field
.option_values
.push_back(ASCIIToUTF16("GRMNY"));
2358 form_data
.fields
.push_back(field
);
2359 FormStructure
form_structure(form_data
);
2362 form_structure
.ParseFieldTypesFromAutocompleteAttributes(&unused
, &unused
);
2364 // All values in <option> value= or contents are returned, set to upper case.
2365 std::set
<base::string16
> possible_values
=
2366 form_structure
.PossibleValues(ADDRESS_BILLING_COUNTRY
);
2367 EXPECT_EQ(5U, possible_values
.size());
2368 EXPECT_EQ(1U, possible_values
.count(ASCIIToUTF16("AU")));
2369 EXPECT_EQ(1U, possible_values
.count(ASCIIToUTF16("FR")));
2370 EXPECT_EQ(1U, possible_values
.count(ASCIIToUTF16("DOWN UNDER")));
2371 EXPECT_EQ(1U, possible_values
.count(ASCIIToUTF16("GERMANY")));
2372 EXPECT_EQ(1U, possible_values
.count(ASCIIToUTF16("GRMNY")));
2373 EXPECT_EQ(0U, possible_values
.count(ASCIIToUTF16("Fr")));
2374 EXPECT_EQ(0U, possible_values
.count(ASCIIToUTF16("DE")));
2376 // No field for the given type; empty value set.
2377 EXPECT_EQ(0U, form_structure
.PossibleValues(ADDRESS_HOME_COUNTRY
).size());
2379 // A freeform input (<input>) allows any value (overriding other <select>s).
2380 FormFieldData freeform_field
;
2381 freeform_field
.autocomplete_attribute
= "billing country";
2382 form_data
.fields
.push_back(freeform_field
);
2383 FormStructure
form_structure2(form_data
);
2384 form_structure2
.ParseFieldTypesFromAutocompleteAttributes(&unused
, &unused
);
2385 EXPECT_EQ(0U, form_structure2
.PossibleValues(ADDRESS_BILLING_COUNTRY
).size());
2388 TEST(FormStructureTest
, ParseQueryResponse
) {
2390 FormFieldData field
;
2391 field
.form_control_type
= "text";
2393 field
.label
= ASCIIToUTF16("fullname");
2394 field
.name
= ASCIIToUTF16("fullname");
2395 form
.fields
.push_back(field
);
2397 field
.label
= ASCIIToUTF16("address");
2398 field
.name
= ASCIIToUTF16("address");
2399 form
.fields
.push_back(field
);
2401 // Checkable fields should be ignored in parsing
2402 FormFieldData checkable_field
;
2403 checkable_field
.label
= ASCIIToUTF16("radio_button");
2404 checkable_field
.form_control_type
= "radio";
2405 checkable_field
.is_checkable
= true;
2406 form
.fields
.push_back(checkable_field
);
2408 ScopedVector
<FormStructure
> forms
;
2409 forms
.push_back(new FormStructure(form
));
2411 field
.label
= ASCIIToUTF16("email");
2412 field
.name
= ASCIIToUTF16("email");
2413 form
.fields
.push_back(field
);
2415 field
.label
= ASCIIToUTF16("password");
2416 field
.name
= ASCIIToUTF16("password");
2417 field
.form_control_type
= "password";
2418 form
.fields
.push_back(field
);
2420 forms
.push_back(new FormStructure(form
));
2422 std::string response
=
2423 "<autofillqueryresponse>"
2424 "<field autofilltype=\"7\" />"
2425 "<field autofilltype=\"30\" />"
2426 "<field autofilltype=\"9\" />"
2427 "<field autofilltype=\"0\" />"
2428 "</autofillqueryresponse>";
2430 FormStructure::ParseQueryResponse(response
, forms
.get());
2432 ASSERT_GE(forms
[0]->field_count(), 2U);
2433 ASSERT_GE(forms
[1]->field_count(), 2U);
2434 EXPECT_EQ(7, forms
[0]->field(0)->server_type());
2435 EXPECT_EQ(30, forms
[0]->field(1)->server_type());
2436 EXPECT_EQ(9, forms
[1]->field(0)->server_type());
2437 EXPECT_EQ(0, forms
[1]->field(1)->server_type());
2440 // If user defined types are present, only parse password fields.
2441 TEST(FormStructureTest
, ParseQueryResponseAuthorDefinedTypes
) {
2443 FormFieldData field
;
2445 field
.label
= ASCIIToUTF16("email");
2446 field
.name
= ASCIIToUTF16("email");
2447 field
.form_control_type
= "text";
2448 field
.autocomplete_attribute
= "email";
2449 form
.fields
.push_back(field
);
2451 field
.label
= ASCIIToUTF16("password");
2452 field
.name
= ASCIIToUTF16("password");
2453 field
.form_control_type
= "password";
2454 field
.autocomplete_attribute
= "new-password";
2455 form
.fields
.push_back(field
);
2457 ScopedVector
<FormStructure
> forms
;
2458 forms
.push_back(new FormStructure(form
));
2459 forms
.front()->DetermineHeuristicTypes();
2461 std::string response
=
2462 "<autofillqueryresponse>"
2463 "<field autofilltype=\"9\" />"
2464 "<field autofilltype=\"76\" />"
2465 "</autofillqueryresponse>";
2467 FormStructure::ParseQueryResponse(response
, forms
.get());
2469 ASSERT_GE(forms
[0]->field_count(), 2U);
2470 EXPECT_EQ(NO_SERVER_DATA
, forms
[0]->field(0)->server_type());
2471 EXPECT_EQ(76, forms
[0]->field(1)->server_type());
2474 } // namespace autofill