form_structure_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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.
4
5#include "components/autofill/core/browser/form_structure.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/strings/string_util.h"
9#include "base/strings/utf_string_conversions.h"
10#include "components/autofill/core/browser/autofill_metrics.h"
11#include "components/autofill/core/common/form_data.h"
12#include "components/autofill/core/common/form_field_data.h"
13#include "testing/gtest/include/gtest/gtest.h"
14#include "third_party/WebKit/public/web/WebInputElement.h"
15#include "url/gurl.h"
16
17using blink::WebInputElement;
18
19namespace autofill {
20namespace {
21
22// Unlike the base AutofillMetrics, exposes copy and assignment constructors,
23// which are handy for briefer test code.  The AutofillMetrics class is
24// stateless, so this is safe.
25class TestAutofillMetrics : public AutofillMetrics {
26 public:
27  TestAutofillMetrics() {}
28  virtual ~TestAutofillMetrics() {}
29};
30
31}  // anonymous namespace
32
33
34namespace content {
35
36std::ostream& operator<<(std::ostream& os, const FormData& form) {
37  os << UTF16ToUTF8(form.name)
38     << " "
39     << UTF16ToUTF8(form.method)
40     << " "
41     << form.origin.spec()
42     << " "
43     << form.action.spec()
44     << " ";
45
46  for (std::vector<FormFieldData>::const_iterator iter =
47           form.fields.begin();
48       iter != form.fields.end(); ++iter) {
49    os << *iter
50       << " ";
51  }
52
53  return os;
54}
55
56}  // namespace content
57
58class FormStructureTest {
59 public:
60  static std::string Hash64Bit(const std::string& str) {
61    return FormStructure::Hash64Bit(str);
62  }
63};
64
65TEST(FormStructureTest, FieldCount) {
66  scoped_ptr<FormStructure> form_structure;
67  FormData form;
68  form.method = ASCIIToUTF16("post");
69
70  FormFieldData field;
71  field.label = ASCIIToUTF16("username");
72  field.name = ASCIIToUTF16("username");
73  field.form_control_type = "text";
74  form.fields.push_back(field);
75
76  field.label = ASCIIToUTF16("password");
77  field.name = ASCIIToUTF16("password");
78  field.form_control_type = "password";
79  form.fields.push_back(field);
80
81  field.label = base::string16();
82  field.name = ASCIIToUTF16("Submit");
83  field.form_control_type = "submit";
84  form.fields.push_back(field);
85
86  field.label = ASCIIToUTF16("address1");
87  field.name = ASCIIToUTF16("address1");
88  field.form_control_type = "text";
89  field.should_autocomplete = false;
90  form.fields.push_back(field);
91
92  // The render process sends all fields to browser including fields with
93  // autocomplete=off
94  form_structure.reset(new FormStructure(form));
95  EXPECT_EQ(4U, form_structure->field_count());
96}
97
98TEST(FormStructureTest, AutofillCount) {
99  scoped_ptr<FormStructure> form_structure;
100  FormData form;
101  form.method = ASCIIToUTF16("post");
102
103  FormFieldData field;
104  field.label = ASCIIToUTF16("username");
105  field.name = ASCIIToUTF16("username");
106  field.form_control_type = "text";
107  form.fields.push_back(field);
108
109  field.label = ASCIIToUTF16("password");
110  field.name = ASCIIToUTF16("password");
111  field.form_control_type = "password";
112  form.fields.push_back(field);
113
114  field.label = ASCIIToUTF16("state");
115  field.name = ASCIIToUTF16("state");
116  field.form_control_type = "select-one";
117  form.fields.push_back(field);
118
119  field.label = base::string16();
120  field.name = ASCIIToUTF16("Submit");
121  field.form_control_type = "submit";
122  form.fields.push_back(field);
123
124  // Only text and select fields that are heuristically matched are counted.
125  form_structure.reset(new FormStructure(form));
126  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
127  EXPECT_EQ(1U, form_structure->autofill_count());
128
129  // Add a field with should_autocomplete=false.
130  field.label = ASCIIToUTF16("address1");
131  field.name = ASCIIToUTF16("address1");
132  field.form_control_type = "text";
133  field.should_autocomplete = false;
134  form.fields.push_back(field);
135
136  form_structure.reset(new FormStructure(form));
137  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
138  // DetermineHeuristicTypes also assign field type for fields with
139  // autocomplete=off thus autofill_count includes them. This is a bug,
140  // and they should not be counted. See http://crbug.com/176432 for details.
141  // TODO(benquan): change it to EXPECT_EQ(1U, ... when the bug is fixed.
142  EXPECT_EQ(2U, form_structure->autofill_count());
143}
144
145TEST(FormStructureTest, SourceURL) {
146  FormData form;
147  form.origin = GURL("http://www.foo.com/");
148  form.method = ASCIIToUTF16("post");
149  FormStructure form_structure(form);
150
151  EXPECT_EQ(form.origin, form_structure.source_url());
152}
153
154TEST(FormStructureTest, IsAutofillable) {
155  scoped_ptr<FormStructure> form_structure;
156  FormData form;
157
158  // We need at least three text fields to be auto-fillable.
159  form.method = ASCIIToUTF16("post");
160
161  FormFieldData field;
162
163  field.label = ASCIIToUTF16("username");
164  field.name = ASCIIToUTF16("username");
165  field.form_control_type = "text";
166  form.fields.push_back(field);
167
168  field.label = ASCIIToUTF16("password");
169  field.name = ASCIIToUTF16("password");
170  field.form_control_type = "password";
171  form.fields.push_back(field);
172
173  field.label = base::string16();
174  field.name = ASCIIToUTF16("Submit");
175  field.form_control_type = "submit";
176  form.fields.push_back(field);
177
178  form_structure.reset(new FormStructure(form));
179  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
180  EXPECT_FALSE(form_structure->IsAutofillable(true));
181
182  // We now have three text fields, but only two auto-fillable fields.
183  field.label = ASCIIToUTF16("First Name");
184  field.name = ASCIIToUTF16("firstname");
185  field.form_control_type = "text";
186  form.fields.push_back(field);
187
188  field.label = ASCIIToUTF16("Last Name");
189  field.name = ASCIIToUTF16("lastname");
190  field.form_control_type = "text";
191  form.fields.push_back(field);
192
193  form_structure.reset(new FormStructure(form));
194  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
195  EXPECT_FALSE(form_structure->IsAutofillable(true));
196
197  // We now have three auto-fillable fields.
198  field.label = ASCIIToUTF16("Email");
199  field.name = ASCIIToUTF16("email");
200  field.form_control_type = "email";
201  form.fields.push_back(field);
202
203  form_structure.reset(new FormStructure(form));
204  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
205  EXPECT_TRUE(form_structure->IsAutofillable(true));
206
207  // The method must be 'post', though we can intentionally ignore this
208  // criterion for the sake of providing a helpful warning message to the user.
209  form.method = ASCIIToUTF16("get");
210  form_structure.reset(new FormStructure(form));
211  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
212  EXPECT_FALSE(form_structure->IsAutofillable(true));
213  EXPECT_TRUE(form_structure->IsAutofillable(false));
214
215  // The target cannot include http(s)://*/search...
216  form.method = ASCIIToUTF16("post");
217  form.action = GURL("http://google.com/search?q=hello");
218  form_structure.reset(new FormStructure(form));
219  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
220  EXPECT_FALSE(form_structure->IsAutofillable(true));
221
222  // But search can be in the URL.
223  form.action = GURL("http://search.com/?q=hello");
224  form_structure.reset(new FormStructure(form));
225  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
226  EXPECT_TRUE(form_structure->IsAutofillable(true));
227}
228
229TEST(FormStructureTest, ShouldBeParsed) {
230  scoped_ptr<FormStructure> form_structure;
231  FormData form;
232
233  // We need at least three text fields to be parseable.
234  form.method = ASCIIToUTF16("post");
235
236  FormFieldData field;
237  field.label = ASCIIToUTF16("username");
238  field.name = ASCIIToUTF16("username");
239  field.form_control_type = "text";
240  form.fields.push_back(field);
241
242  FormFieldData checkable_field;
243  checkable_field.is_checkable = true;
244  checkable_field.name = ASCIIToUTF16("radiobtn");
245  checkable_field.form_control_type = "radio";
246  form.fields.push_back(checkable_field);
247
248  checkable_field.name = ASCIIToUTF16("checkbox");
249  checkable_field.form_control_type = "checkbox";
250  form.fields.push_back(checkable_field);
251
252  // We have only one text field, should not be parsed.
253  form_structure.reset(new FormStructure(form));
254  EXPECT_FALSE(form_structure->ShouldBeParsed(true));
255
256  // We now have three text fields, though only two are auto-fillable.
257  field.label = ASCIIToUTF16("First Name");
258  field.name = ASCIIToUTF16("firstname");
259  field.form_control_type = "text";
260  form.fields.push_back(field);
261
262  field.label = ASCIIToUTF16("Last Name");
263  field.name = ASCIIToUTF16("lastname");
264  field.form_control_type = "text";
265  form.fields.push_back(field);
266
267  form_structure.reset(new FormStructure(form));
268  EXPECT_TRUE(form_structure->ShouldBeParsed(true));
269
270  // The method must be 'post', though we can intentionally ignore this
271  // criterion for the sake of providing a helpful warning message to the user.
272  form.method = ASCIIToUTF16("get");
273  form_structure.reset(new FormStructure(form));
274  EXPECT_FALSE(form_structure->IsAutofillable(true));
275  EXPECT_TRUE(form_structure->ShouldBeParsed(false));
276
277  // The target cannot include http(s)://*/search...
278  form.method = ASCIIToUTF16("post");
279  form.action = GURL("http://google.com/search?q=hello");
280  form_structure.reset(new FormStructure(form));
281  EXPECT_FALSE(form_structure->ShouldBeParsed(true));
282
283  // But search can be in the URL.
284  form.action = GURL("http://search.com/?q=hello");
285  form_structure.reset(new FormStructure(form));
286  EXPECT_TRUE(form_structure->ShouldBeParsed(true));
287
288  // The form need only have three fields, but at least one must be a text
289  // field.
290  form.fields.clear();
291
292  field.label = ASCIIToUTF16("Email");
293  field.name = ASCIIToUTF16("email");
294  field.form_control_type = "email";
295  form.fields.push_back(field);
296
297  field.label = ASCIIToUTF16("State");
298  field.name = ASCIIToUTF16("state");
299  field.form_control_type = "select-one";
300  form.fields.push_back(field);
301
302  field.label = ASCIIToUTF16("Country");
303  field.name = ASCIIToUTF16("country");
304  field.form_control_type = "select-one";
305  form.fields.push_back(field);
306
307  form_structure.reset(new FormStructure(form));
308  EXPECT_TRUE(form_structure->ShouldBeParsed(true));
309
310  form.fields[0].form_control_type = "select-one";
311  // Now, no text fields.
312  form_structure.reset(new FormStructure(form));
313  EXPECT_FALSE(form_structure->ShouldBeParsed(true));
314}
315
316TEST(FormStructureTest, HeuristicsContactInfo) {
317  scoped_ptr<FormStructure> form_structure;
318  FormData form;
319  form.method = ASCIIToUTF16("post");
320
321  FormFieldData field;
322  field.form_control_type = "text";
323
324  field.label = ASCIIToUTF16("First Name");
325  field.name = ASCIIToUTF16("firstname");
326  form.fields.push_back(field);
327
328  field.label = ASCIIToUTF16("Last Name");
329  field.name = ASCIIToUTF16("lastname");
330  form.fields.push_back(field);
331
332  field.label = ASCIIToUTF16("Email");
333  field.name = ASCIIToUTF16("email");
334  form.fields.push_back(field);
335
336  field.label = ASCIIToUTF16("Phone");
337  field.name = ASCIIToUTF16("phone");
338  form.fields.push_back(field);
339
340  field.label = ASCIIToUTF16("Address");
341  field.name = ASCIIToUTF16("address");
342  form.fields.push_back(field);
343
344  field.label = ASCIIToUTF16("City");
345  field.name = ASCIIToUTF16("city");
346  form.fields.push_back(field);
347
348  field.label = ASCIIToUTF16("Zip code");
349  field.name = ASCIIToUTF16("zipcode");
350  form.fields.push_back(field);
351
352  field.label = base::string16();
353  field.name = ASCIIToUTF16("Submit");
354  field.form_control_type = "submit";
355  form.fields.push_back(field);
356
357  form_structure.reset(new FormStructure(form));
358  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
359  EXPECT_TRUE(form_structure->IsAutofillable(true));
360
361  // Expect the correct number of fields.
362  ASSERT_EQ(8U, form_structure->field_count());
363  ASSERT_EQ(7U, form_structure->autofill_count());
364
365  // First name.
366  EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
367  // Last name.
368  EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
369  // Email.
370  EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
371  // Phone.
372  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
373      form_structure->field(3)->heuristic_type());
374  // Address.
375  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type());
376  // City.
377  EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type());
378  // Zip.
379  EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
380  // Submit.
381  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
382}
383
384// Verify that we can correctly process the |autocomplete| attribute.
385TEST(FormStructureTest, HeuristicsAutocompleteAttribute) {
386  scoped_ptr<FormStructure> form_structure;
387  FormData form;
388  form.method = ASCIIToUTF16("post");
389
390  FormFieldData field;
391  field.form_control_type = "text";
392
393  field.label = base::string16();
394  field.name = ASCIIToUTF16("field1");
395  field.autocomplete_attribute = "given-name";
396  form.fields.push_back(field);
397
398  field.label = base::string16();
399  field.name = ASCIIToUTF16("field2");
400  field.autocomplete_attribute = "family-name";
401  form.fields.push_back(field);
402
403  field.label = base::string16();
404  field.name = ASCIIToUTF16("field3");
405  field.autocomplete_attribute = "email";
406  form.fields.push_back(field);
407
408  form_structure.reset(new FormStructure(form));
409  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
410  EXPECT_TRUE(form_structure->IsAutofillable(true));
411
412  // Expect the correct number of fields.
413  ASSERT_EQ(3U, form_structure->field_count());
414  ASSERT_EQ(3U, form_structure->autofill_count());
415
416  EXPECT_EQ(HTML_TYPE_GIVEN_NAME, form_structure->field(0)->html_type());
417  EXPECT_EQ(HTML_TYPE_FAMILY_NAME, form_structure->field(1)->html_type());
418  EXPECT_EQ(HTML_TYPE_EMAIL, form_structure->field(2)->html_type());
419  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type());
420  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
421  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
422}
423
424// Verify that we can correctly process the 'autocomplete' attribute for phone
425// number types (especially phone prefixes and suffixes).
426TEST(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
427  scoped_ptr<FormStructure> form_structure;
428  FormData form;
429  form.method = ASCIIToUTF16("post");
430
431  FormFieldData field;
432  field.form_control_type = "text";
433
434  field.label = base::string16();
435  field.name = ASCIIToUTF16("field1");
436  field.autocomplete_attribute = "tel-local";
437  form.fields.push_back(field);
438
439  field.label = base::string16();
440  field.name = ASCIIToUTF16("field2");
441  field.autocomplete_attribute = "tel-local-prefix";
442  form.fields.push_back(field);
443
444  field.label = base::string16();
445  field.name = ASCIIToUTF16("field3");
446  field.autocomplete_attribute = "tel-local-suffix";
447  form.fields.push_back(field);
448
449  form_structure.reset(new FormStructure(form));
450  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
451  EXPECT_TRUE(form_structure->IsAutofillable(true));
452
453  // Expect the correct number of fields.
454  ASSERT_EQ(3U, form_structure->field_count());
455  EXPECT_EQ(3U, form_structure->autofill_count());
456
457  EXPECT_EQ(HTML_TYPE_TEL_LOCAL, form_structure->field(0)->html_type());
458  EXPECT_EQ(AutofillField::IGNORED, form_structure->field(0)->phone_part());
459  EXPECT_EQ(HTML_TYPE_TEL_LOCAL_PREFIX, form_structure->field(1)->html_type());
460  EXPECT_EQ(AutofillField::PHONE_PREFIX,
461            form_structure->field(1)->phone_part());
462  EXPECT_EQ(HTML_TYPE_TEL_LOCAL_SUFFIX, form_structure->field(2)->html_type());
463  EXPECT_EQ(AutofillField::PHONE_SUFFIX,
464            form_structure->field(2)->phone_part());
465}
466
467// If at least one field includes type hints in the 'autocomplete' attribute, we
468// should not try to apply any other heuristics.
469TEST(FormStructureTest, AutocompleteAttributeOverridesOtherHeuristics) {
470  scoped_ptr<FormStructure> form_structure;
471  FormData form;
472  form.method = ASCIIToUTF16("post");
473
474  // Start with a regular contact form.
475  FormFieldData field;
476  field.form_control_type = "text";
477
478  field.label = ASCIIToUTF16("First Name");
479  field.name = ASCIIToUTF16("firstname");
480  form.fields.push_back(field);
481
482  field.label = ASCIIToUTF16("Last Name");
483  field.name = ASCIIToUTF16("lastname");
484  form.fields.push_back(field);
485
486  field.label = ASCIIToUTF16("Email");
487  field.name = ASCIIToUTF16("email");
488  form.fields.push_back(field);
489
490  form_structure.reset(new FormStructure(form));
491  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
492  EXPECT_TRUE(form_structure->IsAutofillable(true));
493  EXPECT_TRUE(form_structure->ShouldBeCrowdsourced());
494
495  ASSERT_EQ(3U, form_structure->field_count());
496  ASSERT_EQ(3U, form_structure->autofill_count());
497
498  EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
499  EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
500  EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
501
502  // Now update the first form field to include an 'autocomplete' attribute.
503  form.fields.front().autocomplete_attribute = "x-other";
504  form_structure.reset(new FormStructure(form));
505  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
506  EXPECT_FALSE(form_structure->IsAutofillable(true));
507  EXPECT_FALSE(form_structure->ShouldBeCrowdsourced());
508
509  ASSERT_EQ(3U, form_structure->field_count());
510  ASSERT_EQ(0U, form_structure->autofill_count());
511
512  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type());
513  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
514  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
515}
516
517// Verify that we can correctly process sections listed in the |autocomplete|
518// attribute.
519TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) {
520  FormData form;
521  form.method = ASCIIToUTF16("post");
522
523  FormFieldData field;
524  field.form_control_type = "text";
525
526  // Some fields will have no section specified.  These fall into the default
527  // section.
528  field.autocomplete_attribute = "email";
529  form.fields.push_back(field);
530
531  // We allow arbitrary section names.
532  field.autocomplete_attribute = "section-foo email";
533  form.fields.push_back(field);
534
535  // "shipping" and "billing" are special section tokens that don't require the
536  // "section-" prefix.
537  field.autocomplete_attribute = "shipping email";
538  form.fields.push_back(field);
539  field.autocomplete_attribute = "billing email";
540  form.fields.push_back(field);
541
542  // "shipping" and "billing" can be combined with other section names.
543  field.autocomplete_attribute = "section-foo shipping email";
544  form.fields.push_back(field);
545  field.autocomplete_attribute = "section-foo billing email";
546  form.fields.push_back(field);
547
548  // We don't do anything clever to try to coalesce sections; it's up to site
549  // authors to avoid typos.
550  field.autocomplete_attribute = "section--foo email";
551  form.fields.push_back(field);
552
553  // "shipping email" and "section--shipping" email should be parsed as
554  // different sections.  This is only an interesting test due to how we
555  // implement implicit section names from attributes like "shipping email"; see
556  // the implementation for more details.
557  field.autocomplete_attribute = "section--shipping email";
558  form.fields.push_back(field);
559
560  // Credit card fields are implicitly in a separate section from other fields.
561  field.autocomplete_attribute = "section-foo cc-number";
562  form.fields.push_back(field);
563
564  FormStructure form_structure(form);
565  form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
566  EXPECT_TRUE(form_structure.IsAutofillable(true));
567
568  // Expect the correct number of fields.
569  ASSERT_EQ(9U, form_structure.field_count());
570  EXPECT_EQ(9U, form_structure.autofill_count());
571
572  // All of the fields in this form should be parsed as belonging to different
573  // sections.
574  std::set<std::string> section_names;
575  for (size_t i = 0; i < 9; ++i) {
576    section_names.insert(form_structure.field(i)->section());
577  }
578  EXPECT_EQ(9U, section_names.size());
579}
580
581// Verify that we can correctly process a degenerate section listed in the
582// |autocomplete| attribute.
583TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsDegenerate) {
584  FormData form;
585  form.method = ASCIIToUTF16("post");
586
587  FormFieldData field;
588  field.form_control_type = "text";
589
590  // Some fields will have no section specified.  These fall into the default
591  // section.
592  field.autocomplete_attribute = "email";
593  form.fields.push_back(field);
594
595  // Specifying "section-" is equivalent to not specifying a section.
596  field.autocomplete_attribute = "section- email";
597  form.fields.push_back(field);
598
599  // Invalid tokens should prevent us from setting a section name.
600  field.autocomplete_attribute = "garbage section-foo email";
601  form.fields.push_back(field);
602  field.autocomplete_attribute = "garbage section-bar email";
603  form.fields.push_back(field);
604  field.autocomplete_attribute = "garbage shipping email";
605  form.fields.push_back(field);
606  field.autocomplete_attribute = "garbage billing email";
607  form.fields.push_back(field);
608
609  FormStructure form_structure(form);
610  form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
611
612  // Expect the correct number of fields.
613  ASSERT_EQ(6U, form_structure.field_count());
614  EXPECT_EQ(2U, form_structure.autofill_count());
615
616  // All of the fields in this form should be parsed as belonging to the same
617  // section.
618  std::set<std::string> section_names;
619  for (size_t i = 0; i < 6; ++i) {
620    section_names.insert(form_structure.field(i)->section());
621  }
622  EXPECT_EQ(1U, section_names.size());
623}
624
625// Verify that we can correctly process repeated sections listed in the
626// |autocomplete| attribute.
627TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsRepeated) {
628  FormData form;
629  form.method = ASCIIToUTF16("post");
630
631  FormFieldData field;
632  field.form_control_type = "text";
633
634  field.autocomplete_attribute = "section-foo email";
635  form.fields.push_back(field);
636  field.autocomplete_attribute = "section-foo address-line1";
637  form.fields.push_back(field);
638
639  FormStructure form_structure(form);
640  form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
641
642  // Expect the correct number of fields.
643  ASSERT_EQ(2U, form_structure.field_count());
644  EXPECT_EQ(2U, form_structure.autofill_count());
645
646  // All of the fields in this form should be parsed as belonging to the same
647  // section.
648  std::set<std::string> section_names;
649  for (size_t i = 0; i < 2; ++i) {
650    section_names.insert(form_structure.field(i)->section());
651  }
652  EXPECT_EQ(1U, section_names.size());
653}
654
655// Verify that we do not override the author-specified sections from a form with
656// local heuristics.
657TEST(FormStructureTest, HeuristicsDontOverrideAutocompleteAttributeSections) {
658  FormData form;
659  form.method = ASCIIToUTF16("post");
660
661  FormFieldData field;
662  field.form_control_type = "text";
663
664  field.name = ASCIIToUTF16("one");
665  field.autocomplete_attribute = "address-line1";
666  form.fields.push_back(field);
667  field.name = base::string16();
668  field.autocomplete_attribute = "section-foo email";
669  form.fields.push_back(field);
670  field.name = base::string16();
671  field.autocomplete_attribute = "name";
672  form.fields.push_back(field);
673  field.name = ASCIIToUTF16("two");
674  field.autocomplete_attribute = "address-line1";
675  form.fields.push_back(field);
676
677  FormStructure form_structure(form);
678  form_structure.DetermineHeuristicTypes(TestAutofillMetrics());
679
680  // Expect the correct number of fields.
681  ASSERT_EQ(4U, form_structure.field_count());
682  EXPECT_EQ(4U, form_structure.autofill_count());
683
684  // Normally, the two separate address fields would cause us to detect two
685  // separate sections; but because there is an author-specified section in this
686  // form, we do not apply these usual heuristics.
687  EXPECT_EQ(ASCIIToUTF16("one"), form_structure.field(0)->name);
688  EXPECT_EQ(ASCIIToUTF16("two"), form_structure.field(3)->name);
689  EXPECT_EQ(form_structure.field(0)->section(),
690            form_structure.field(3)->section());
691}
692
693TEST(FormStructureTest, HeuristicsSample8) {
694  scoped_ptr<FormStructure> form_structure;
695  FormData form;
696  form.method = ASCIIToUTF16("post");
697
698  FormFieldData field;
699  field.form_control_type = "text";
700
701  field.label = ASCIIToUTF16("Your First Name:");
702  field.name = ASCIIToUTF16("bill.first");
703  form.fields.push_back(field);
704
705  field.label = ASCIIToUTF16("Your Last Name:");
706  field.name = ASCIIToUTF16("bill.last");
707  form.fields.push_back(field);
708
709  field.label = ASCIIToUTF16("Street Address Line 1:");
710  field.name = ASCIIToUTF16("bill.street1");
711  form.fields.push_back(field);
712
713  field.label = ASCIIToUTF16("Street Address Line 2:");
714  field.name = ASCIIToUTF16("bill.street2");
715  form.fields.push_back(field);
716
717  field.label = ASCIIToUTF16("City");
718  field.name = ASCIIToUTF16("bill.city");
719  form.fields.push_back(field);
720
721  field.label = ASCIIToUTF16("State (U.S.):");
722  field.name = ASCIIToUTF16("bill.state");
723  form.fields.push_back(field);
724
725  field.label = ASCIIToUTF16("Zip/Postal Code:");
726  field.name = ASCIIToUTF16("BillTo.PostalCode");
727  form.fields.push_back(field);
728
729  field.label = ASCIIToUTF16("Country:");
730  field.name = ASCIIToUTF16("bill.country");
731  form.fields.push_back(field);
732
733  field.label = ASCIIToUTF16("Phone Number:");
734  field.name = ASCIIToUTF16("BillTo.Phone");
735  form.fields.push_back(field);
736
737  field.label = base::string16();
738  field.name = ASCIIToUTF16("Submit");
739  field.form_control_type = "submit";
740  form.fields.push_back(field);
741
742  form_structure.reset(new FormStructure(form));
743  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
744  EXPECT_TRUE(form_structure->IsAutofillable(true));
745  ASSERT_EQ(10U, form_structure->field_count());
746  ASSERT_EQ(9U, form_structure->autofill_count());
747
748  // First name.
749  EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
750  // Last name.
751  EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
752  // Address.
753  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(2)->heuristic_type());
754  // Address.
755  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(3)->heuristic_type());
756  // City.
757  EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
758  // State.
759  EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(5)->heuristic_type());
760  // Zip.
761  EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
762  // Country.
763  EXPECT_EQ(ADDRESS_HOME_COUNTRY, form_structure->field(7)->heuristic_type());
764  // Phone.
765  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
766      form_structure->field(8)->heuristic_type());
767  // Submit.
768  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type());
769}
770
771TEST(FormStructureTest, HeuristicsSample6) {
772  scoped_ptr<FormStructure> form_structure;
773  FormData form;
774  form.method = ASCIIToUTF16("post");
775
776  FormFieldData field;
777  field.form_control_type = "text";
778
779  field.label = ASCIIToUTF16("E-mail address");
780  field.name = ASCIIToUTF16("email");
781  form.fields.push_back(field);
782
783  field.label = ASCIIToUTF16("Full name");
784  field.name = ASCIIToUTF16("name");
785  form.fields.push_back(field);
786
787  field.label = ASCIIToUTF16("Company");
788  field.name = ASCIIToUTF16("company");
789  form.fields.push_back(field);
790
791  field.label = ASCIIToUTF16("Address");
792  field.name = ASCIIToUTF16("address");
793  form.fields.push_back(field);
794
795  field.label = ASCIIToUTF16("City");
796  field.name = ASCIIToUTF16("city");
797  form.fields.push_back(field);
798
799  field.label = ASCIIToUTF16("Zip Code");
800  field.name = ASCIIToUTF16("Home.PostalCode");
801  form.fields.push_back(field);
802
803  field.label = base::string16();
804  field.name = ASCIIToUTF16("Submit");
805  field.value = ASCIIToUTF16("continue");
806  field.form_control_type = "submit";
807  form.fields.push_back(field);
808
809  form_structure.reset(new FormStructure(form));
810  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
811  EXPECT_TRUE(form_structure->IsAutofillable(true));
812  ASSERT_EQ(7U, form_structure->field_count());
813  ASSERT_EQ(6U, form_structure->autofill_count());
814
815  // Email.
816  EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(0)->heuristic_type());
817  // Full name.
818  EXPECT_EQ(NAME_FULL, form_structure->field(1)->heuristic_type());
819  // Company
820  EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
821  // Address.
822  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type());
823  // City.
824  EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
825  // Zip.
826  EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(5)->heuristic_type());
827  // Submit.
828  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
829}
830
831// Tests a sequence of FormFields where only labels are supplied to heuristics
832// for matching.  This works because FormFieldData labels are matched in the
833// case that input element ids (or |name| fields) are missing.
834TEST(FormStructureTest, HeuristicsLabelsOnly) {
835  scoped_ptr<FormStructure> form_structure;
836  FormData form;
837  form.method = ASCIIToUTF16("post");
838
839  FormFieldData field;
840  field.form_control_type = "text";
841
842  field.label = ASCIIToUTF16("First Name");
843  field.name = base::string16();
844  form.fields.push_back(field);
845
846  field.label = ASCIIToUTF16("Last Name");
847  field.name = base::string16();
848  form.fields.push_back(field);
849
850  field.label = ASCIIToUTF16("Email");
851  field.name = base::string16();
852  form.fields.push_back(field);
853
854  field.label = ASCIIToUTF16("Phone");
855  field.name = base::string16();
856  form.fields.push_back(field);
857
858  field.label = ASCIIToUTF16("Address");
859  field.name = base::string16();
860  form.fields.push_back(field);
861
862  field.label = ASCIIToUTF16("Address");
863  field.name = base::string16();
864  form.fields.push_back(field);
865
866  field.label = ASCIIToUTF16("Zip code");
867  field.name = base::string16();
868  form.fields.push_back(field);
869
870  field.label = base::string16();
871  field.name = ASCIIToUTF16("Submit");
872  field.form_control_type = "submit";
873  form.fields.push_back(field);
874
875  form_structure.reset(new FormStructure(form));
876  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
877  EXPECT_TRUE(form_structure->IsAutofillable(true));
878  ASSERT_EQ(8U, form_structure->field_count());
879  ASSERT_EQ(7U, form_structure->autofill_count());
880
881  // First name.
882  EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
883  // Last name.
884  EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
885  // Email.
886  EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
887  // Phone.
888  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
889      form_structure->field(3)->heuristic_type());
890  // Address.
891  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type());
892  // Address Line 2.
893  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(5)->heuristic_type());
894  // Zip.
895  EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
896  // Submit.
897  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
898}
899
900TEST(FormStructureTest, HeuristicsCreditCardInfo) {
901  scoped_ptr<FormStructure> form_structure;
902  FormData form;
903  form.method = ASCIIToUTF16("post");
904
905  FormFieldData field;
906  field.form_control_type = "text";
907
908  field.label = ASCIIToUTF16("Name on Card");
909  field.name = ASCIIToUTF16("name_on_card");
910  form.fields.push_back(field);
911
912  field.label = ASCIIToUTF16("Card Number");
913  field.name = ASCIIToUTF16("card_number");
914  form.fields.push_back(field);
915
916  field.label = ASCIIToUTF16("Exp Month");
917  field.name = ASCIIToUTF16("ccmonth");
918  form.fields.push_back(field);
919
920  field.label = ASCIIToUTF16("Exp Year");
921  field.name = ASCIIToUTF16("ccyear");
922  form.fields.push_back(field);
923
924  field.label = ASCIIToUTF16("Verification");
925  field.name = ASCIIToUTF16("verification");
926  form.fields.push_back(field);
927
928  field.label = base::string16();
929  field.name = ASCIIToUTF16("Submit");
930  field.form_control_type = "submit";
931  form.fields.push_back(field);
932
933  form_structure.reset(new FormStructure(form));
934  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
935  EXPECT_TRUE(form_structure->IsAutofillable(true));
936  ASSERT_EQ(6U, form_structure->field_count());
937  ASSERT_EQ(5U, form_structure->autofill_count());
938
939  // Credit card name.
940  EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
941  // Credit card number.
942  EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type());
943  // Credit card expiration month.
944  EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(2)->heuristic_type());
945  // Credit card expiration year.
946  EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
947            form_structure->field(3)->heuristic_type());
948  // CVV.
949  EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
950            form_structure->field(4)->heuristic_type());
951  // Submit.
952  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
953}
954
955TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
956  scoped_ptr<FormStructure> form_structure;
957  FormData form;
958  form.method = ASCIIToUTF16("post");
959
960  FormFieldData field;
961  field.form_control_type = "text";
962
963  field.label = ASCIIToUTF16("Name on Card");
964  field.name = ASCIIToUTF16("name_on_card");
965  form.fields.push_back(field);
966
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);
972
973  field.label = ASCIIToUTF16("Card Number");
974  field.name = ASCIIToUTF16("card_number");
975  form.fields.push_back(field);
976
977  field.label = ASCIIToUTF16("Exp Month");
978  field.name = ASCIIToUTF16("ccmonth");
979  form.fields.push_back(field);
980
981  field.label = ASCIIToUTF16("Exp Year");
982  field.name = ASCIIToUTF16("ccyear");
983  form.fields.push_back(field);
984
985  field.label = ASCIIToUTF16("Verification");
986  field.name = ASCIIToUTF16("verification");
987  form.fields.push_back(field);
988
989  field.label = base::string16();
990  field.name = ASCIIToUTF16("Submit");
991  field.form_control_type = "submit";
992  form.fields.push_back(field);
993
994  form_structure.reset(new FormStructure(form));
995  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
996  EXPECT_TRUE(form_structure->IsAutofillable(true));
997  ASSERT_EQ(7U, form_structure->field_count());
998  ASSERT_EQ(5U, form_structure->autofill_count());
999
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());
1011  // CVV.
1012  EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
1013            form_structure->field(5)->heuristic_type());
1014  // Submit.
1015  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
1016}
1017
1018TEST(FormStructureTest, ThreeAddressLines) {
1019  scoped_ptr<FormStructure> form_structure;
1020  FormData form;
1021  form.method = ASCIIToUTF16("post");
1022
1023  FormFieldData field;
1024  field.form_control_type = "text";
1025
1026  field.label = ASCIIToUTF16("Address Line1");
1027  field.name = ASCIIToUTF16("Address");
1028  form.fields.push_back(field);
1029
1030  field.label = ASCIIToUTF16("Address Line2");
1031  field.name = ASCIIToUTF16("Address");
1032  form.fields.push_back(field);
1033
1034  field.label = ASCIIToUTF16("Address Line3");
1035  field.name = ASCIIToUTF16("Address");
1036  form.fields.push_back(field);
1037
1038  field.label = ASCIIToUTF16("City");
1039  field.name = ASCIIToUTF16("city");
1040  form.fields.push_back(field);
1041
1042  form_structure.reset(new FormStructure(form));
1043  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1044  EXPECT_TRUE(form_structure->IsAutofillable(true));
1045  ASSERT_EQ(4U, form_structure->field_count());
1046  ASSERT_EQ(3U, form_structure->autofill_count());
1047
1048  // Address Line 1.
1049  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1050  // Address Line 2.
1051  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1052  // Address Line 3.
1053  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1054  // City.
1055  EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
1056}
1057
1058// Numbered address lines after line two are ignored.
1059TEST(FormStructureTest, SurplusAddressLinesIgnored) {
1060  scoped_ptr<FormStructure> form_structure;
1061  FormData form;
1062  form.method = ASCIIToUTF16("post");
1063
1064  FormFieldData field;
1065  field.form_control_type = "text";
1066
1067  field.label = ASCIIToUTF16("Address Line1");
1068  field.name = ASCIIToUTF16("shipping.address.addressLine1");
1069  form.fields.push_back(field);
1070
1071  field.label = ASCIIToUTF16("Address Line2");
1072  field.name = ASCIIToUTF16("shipping.address.addressLine2");
1073  form.fields.push_back(field);
1074
1075  field.label = ASCIIToUTF16("Address Line3");
1076  field.name = ASCIIToUTF16("billing.address.addressLine3");
1077  form.fields.push_back(field);
1078
1079  field.label = ASCIIToUTF16("Address Line4");
1080  field.name = ASCIIToUTF16("billing.address.addressLine4");
1081  form.fields.push_back(field);
1082
1083  form_structure.reset(new FormStructure(form));
1084  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1085  ASSERT_EQ(4U, form_structure->field_count());
1086  ASSERT_EQ(2U, form_structure->autofill_count());
1087
1088  // Address Line 1.
1089  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1090  // Address Line 2.
1091  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1092  // Address Line 3 (ignored).
1093  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1094  // Address Line 4 (ignored).
1095  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
1096}
1097
1098// This example comes from expedia.com where they use a "Suite" label to
1099// indicate a suite or apartment number.  We interpret this as address line 2.
1100// And the following "Street address second line" we interpret as address line
1101// 3 and discard.
1102// See http://crbug.com/48197 for details.
1103TEST(FormStructureTest, ThreeAddressLinesExpedia) {
1104  scoped_ptr<FormStructure> form_structure;
1105  FormData form;
1106  form.method = ASCIIToUTF16("post");
1107
1108  FormFieldData field;
1109  field.form_control_type = "text";
1110
1111  field.label = ASCIIToUTF16("Street:");
1112  field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1");
1113  form.fields.push_back(field);
1114
1115  field.label = ASCIIToUTF16("Suite or Apt:");
1116  field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap");
1117  form.fields.push_back(field);
1118
1119  field.label = ASCIIToUTF16("Street address second line");
1120  field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads2");
1121  form.fields.push_back(field);
1122
1123  field.label = ASCIIToUTF16("City:");
1124  field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adct");
1125  form.fields.push_back(field);
1126
1127  form_structure.reset(new FormStructure(form));
1128  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1129  EXPECT_TRUE(form_structure->IsAutofillable(true));
1130  ASSERT_EQ(4U, form_structure->field_count());
1131  EXPECT_EQ(3U, form_structure->autofill_count());
1132
1133  // Address Line 1.
1134  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1135  // Suite / Apt.
1136  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1137  // Address Line 3.
1138  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1139  // City.
1140  EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
1141}
1142
1143// This example comes from ebay.com where the word "suite" appears in the label
1144// and the name "address2" clearly indicates that this is the address line 2.
1145// See http://crbug.com/48197 for details.
1146TEST(FormStructureTest, TwoAddressLinesEbay) {
1147  scoped_ptr<FormStructure> form_structure;
1148  FormData form;
1149  form.method = ASCIIToUTF16("post");
1150
1151  FormFieldData field;
1152  field.form_control_type = "text";
1153
1154  field.label = ASCIIToUTF16("Address Line1");
1155  field.name = ASCIIToUTF16("address1");
1156  form.fields.push_back(field);
1157
1158  field.label = ASCIIToUTF16("Floor number, suite number, etc");
1159  field.name = ASCIIToUTF16("address2");
1160  form.fields.push_back(field);
1161
1162  field.label = ASCIIToUTF16("City:");
1163  field.name = ASCIIToUTF16("city");
1164  form.fields.push_back(field);
1165
1166  form_structure.reset(new FormStructure(form));
1167  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1168  EXPECT_TRUE(form_structure->IsAutofillable(true));
1169  ASSERT_EQ(3U, form_structure->field_count());
1170  ASSERT_EQ(3U, form_structure->autofill_count());
1171
1172  // Address Line 1.
1173  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1174  // Address Line 2.
1175  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1176  // City.
1177  EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(2)->heuristic_type());
1178}
1179
1180TEST(FormStructureTest, HeuristicsStateWithProvince) {
1181  scoped_ptr<FormStructure> form_structure;
1182  FormData form;
1183  form.method = ASCIIToUTF16("post");
1184
1185  FormFieldData field;
1186  field.form_control_type = "text";
1187
1188  field.label = ASCIIToUTF16("Address Line1");
1189  field.name = ASCIIToUTF16("Address");
1190  form.fields.push_back(field);
1191
1192  field.label = ASCIIToUTF16("Address Line2");
1193  field.name = ASCIIToUTF16("Address");
1194  form.fields.push_back(field);
1195
1196  field.label = ASCIIToUTF16("State/Province/Region");
1197  field.name = ASCIIToUTF16("State");
1198  form.fields.push_back(field);
1199
1200  form_structure.reset(new FormStructure(form));
1201  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1202  EXPECT_TRUE(form_structure->IsAutofillable(true));
1203  ASSERT_EQ(3U, form_structure->field_count());
1204  ASSERT_EQ(3U, form_structure->autofill_count());
1205
1206  // Address Line 1.
1207  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
1208  // Address Line 2.
1209  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
1210  // State.
1211  EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(2)->heuristic_type());
1212}
1213
1214// This example comes from lego.com's checkout page.
1215TEST(FormStructureTest, HeuristicsWithBilling) {
1216  scoped_ptr<FormStructure> form_structure;
1217  FormData form;
1218  form.method = ASCIIToUTF16("post");
1219
1220  FormFieldData field;
1221  field.form_control_type = "text";
1222
1223  field.label = ASCIIToUTF16("First Name*:");
1224  field.name = ASCIIToUTF16("editBillingAddress$firstNameBox");
1225  form.fields.push_back(field);
1226
1227  field.label = ASCIIToUTF16("Last Name*:");
1228  field.name = ASCIIToUTF16("editBillingAddress$lastNameBox");
1229  form.fields.push_back(field);
1230
1231  field.label = ASCIIToUTF16("Company Name:");
1232  field.name = ASCIIToUTF16("editBillingAddress$companyBox");
1233  form.fields.push_back(field);
1234
1235  field.label = ASCIIToUTF16("Address*:");
1236  field.name = ASCIIToUTF16("editBillingAddress$addressLine1Box");
1237  form.fields.push_back(field);
1238
1239  field.label = ASCIIToUTF16("Apt/Suite :");
1240  field.name = ASCIIToUTF16("editBillingAddress$addressLine2Box");
1241  form.fields.push_back(field);
1242
1243  field.label = ASCIIToUTF16("City*:");
1244  field.name = ASCIIToUTF16("editBillingAddress$cityBox");
1245  form.fields.push_back(field);
1246
1247  field.label = ASCIIToUTF16("State/Province*:");
1248  field.name = ASCIIToUTF16("editBillingAddress$stateDropDown");
1249  form.fields.push_back(field);
1250
1251  field.label = ASCIIToUTF16("Country*:");
1252  field.name = ASCIIToUTF16("editBillingAddress$countryDropDown");
1253  form.fields.push_back(field);
1254
1255  field.label = ASCIIToUTF16("Postal Code*:");
1256  field.name = ASCIIToUTF16("editBillingAddress$zipCodeBox");
1257  form.fields.push_back(field);
1258
1259  field.label = ASCIIToUTF16("Phone*:");
1260  field.name = ASCIIToUTF16("editBillingAddress$phoneBox");
1261  form.fields.push_back(field);
1262
1263  field.label = ASCIIToUTF16("Email Address*:");
1264  field.name = ASCIIToUTF16("email$emailBox");
1265  form.fields.push_back(field);
1266
1267  form_structure.reset(new FormStructure(form));
1268  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1269  EXPECT_TRUE(form_structure->IsAutofillable(true));
1270  ASSERT_EQ(11U, form_structure->field_count());
1271  ASSERT_EQ(11U, form_structure->autofill_count());
1272
1273  EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
1274  EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
1275  EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
1276  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type());
1277  EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(4)->heuristic_type());
1278  EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type());
1279  EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(6)->heuristic_type());
1280  EXPECT_EQ(ADDRESS_HOME_COUNTRY, form_structure->field(7)->heuristic_type());
1281  EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(8)->heuristic_type());
1282  EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
1283            form_structure->field(9)->heuristic_type());
1284  EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(10)->heuristic_type());
1285}
1286
1287TEST(FormStructureTest, ThreePartPhoneNumber) {
1288  scoped_ptr<FormStructure> form_structure;
1289  FormData form;
1290  form.method = ASCIIToUTF16("post");
1291
1292  FormFieldData field;
1293  field.form_control_type = "text";
1294
1295  field.label = ASCIIToUTF16("Phone:");
1296  field.name = ASCIIToUTF16("dayphone1");
1297  field.max_length = 0;
1298  form.fields.push_back(field);
1299
1300  field.label = ASCIIToUTF16("-");
1301  field.name = ASCIIToUTF16("dayphone2");
1302  field.max_length = 3;  // Size of prefix is 3.
1303  form.fields.push_back(field);
1304
1305  field.label = ASCIIToUTF16("-");
1306  field.name = ASCIIToUTF16("dayphone3");
1307  field.max_length = 4;  // Size of suffix is 4.  If unlimited size is
1308                         // passed, phone will be parsed as
1309                         // <country code> - <area code> - <phone>.
1310  form.fields.push_back(field);
1311
1312  field.label = ASCIIToUTF16("ext.:");
1313  field.name = ASCIIToUTF16("dayphone4");
1314  field.max_length = 0;
1315  form.fields.push_back(field);
1316
1317  form_structure.reset(new FormStructure(form));
1318  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1319  EXPECT_TRUE(form_structure->IsAutofillable(true));
1320  ASSERT_EQ(4U, form_structure->field_count());
1321  ASSERT_EQ(3U, form_structure->autofill_count());
1322
1323  // Area code.
1324  EXPECT_EQ(PHONE_HOME_CITY_CODE, form_structure->field(0)->heuristic_type());
1325  // Phone number suffix.
1326  EXPECT_EQ(PHONE_HOME_NUMBER,
1327            form_structure->field(1)->heuristic_type());
1328  // Phone number suffix.
1329  EXPECT_EQ(PHONE_HOME_NUMBER,
1330            form_structure->field(2)->heuristic_type());
1331  // Unknown.
1332  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
1333}
1334
1335TEST(FormStructureTest, HeuristicsInfernoCC) {
1336  scoped_ptr<FormStructure> form_structure;
1337  FormData form;
1338  form.method = ASCIIToUTF16("post");
1339
1340  FormFieldData field;
1341  field.form_control_type = "text";
1342
1343  field.label = ASCIIToUTF16("Name on Card");
1344  field.name = ASCIIToUTF16("name_on_card");
1345  form.fields.push_back(field);
1346
1347  field.label = ASCIIToUTF16("Address");
1348  field.name = ASCIIToUTF16("billing_address");
1349  form.fields.push_back(field);
1350
1351  field.label = ASCIIToUTF16("Card Number");
1352  field.name = ASCIIToUTF16("card_number");
1353  form.fields.push_back(field);
1354
1355  field.label = ASCIIToUTF16("Expiration Date");
1356  field.name = ASCIIToUTF16("expiration_month");
1357  form.fields.push_back(field);
1358
1359  field.label = ASCIIToUTF16("Expiration Year");
1360  field.name = ASCIIToUTF16("expiration_year");
1361  form.fields.push_back(field);
1362
1363  form_structure.reset(new FormStructure(form));
1364  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1365  EXPECT_TRUE(form_structure->IsAutofillable(true));
1366
1367  // Expect the correct number of fields.
1368  ASSERT_EQ(5U, form_structure->field_count());
1369  EXPECT_EQ(5U, form_structure->autofill_count());
1370
1371  // Name on Card.
1372  EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
1373  // Address.
1374  EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(1)->heuristic_type());
1375  // Card Number.
1376  EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type());
1377  // Expiration Date.
1378  EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1379  // Expiration Year.
1380  EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1381            form_structure->field(4)->heuristic_type());
1382}
1383
1384TEST(FormStructureTest, CVCCodeClash) {
1385  scoped_ptr<FormStructure> form_structure;
1386  FormData form;
1387  form.method = ASCIIToUTF16("post");
1388
1389  FormFieldData field;
1390  field.form_control_type = "text";
1391
1392  field.label = ASCIIToUTF16("Card number");
1393  field.name = ASCIIToUTF16("ccnumber");
1394  form.fields.push_back(field);
1395
1396  field.label = ASCIIToUTF16("First name");
1397  field.name = ASCIIToUTF16("first_name");
1398  form.fields.push_back(field);
1399
1400  field.label = ASCIIToUTF16("Last name");
1401  field.name = ASCIIToUTF16("last_name");
1402  form.fields.push_back(field);
1403
1404  field.label = ASCIIToUTF16("Expiration date");
1405  field.name = ASCIIToUTF16("ccexpiresmonth");
1406  form.fields.push_back(field);
1407
1408  field.label = base::string16();
1409  field.name = ASCIIToUTF16("ccexpiresyear");
1410  form.fields.push_back(field);
1411
1412  field.label = ASCIIToUTF16("cvc number");
1413  field.name = ASCIIToUTF16("csc");
1414  form.fields.push_back(field);
1415
1416  form_structure.reset(new FormStructure(form));
1417  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1418  EXPECT_TRUE(form_structure->IsAutofillable(true));
1419
1420  // Expect the correct number of fields.
1421  ASSERT_EQ(6U, form_structure->field_count());
1422  ASSERT_EQ(5U, form_structure->autofill_count());
1423
1424  // Card Number.
1425  EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(0)->heuristic_type());
1426  // First name, taken as name on card.
1427  EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(1)->heuristic_type());
1428  // Last name is not merged.
1429  EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
1430  // Expiration Date.
1431  EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
1432  // Expiration Year.
1433  EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1434            form_structure->field(4)->heuristic_type());
1435  // CVC code.
1436  EXPECT_EQ(CREDIT_CARD_VERIFICATION_CODE,
1437            form_structure->field(5)->heuristic_type());
1438}
1439
1440TEST(FormStructureTest, EncodeQueryRequest) {
1441  FormData form;
1442  form.method = ASCIIToUTF16("post");
1443
1444  FormFieldData field;
1445  field.form_control_type = "text";
1446
1447  field.label = ASCIIToUTF16("Name on Card");
1448  field.name = ASCIIToUTF16("name_on_card");
1449  form.fields.push_back(field);
1450
1451  field.label = ASCIIToUTF16("Address");
1452  field.name = ASCIIToUTF16("billing_address");
1453  form.fields.push_back(field);
1454
1455  field.label = ASCIIToUTF16("Card Number");
1456  field.name = ASCIIToUTF16("card_number");
1457  form.fields.push_back(field);
1458
1459  field.label = ASCIIToUTF16("Expiration Date");
1460  field.name = ASCIIToUTF16("expiration_month");
1461  form.fields.push_back(field);
1462
1463  field.label = ASCIIToUTF16("Expiration Year");
1464  field.name = ASCIIToUTF16("expiration_year");
1465  form.fields.push_back(field);
1466
1467  // Add checkable field.
1468  FormFieldData checkable_field;
1469  checkable_field.is_checkable = true;
1470  checkable_field.label = ASCIIToUTF16("Checkable1");
1471  checkable_field.name = ASCIIToUTF16("Checkable1");
1472  form.fields.push_back(checkable_field);
1473
1474  ScopedVector<FormStructure> forms;
1475  forms.push_back(new FormStructure(form));
1476  std::vector<std::string> encoded_signatures;
1477  std::string encoded_xml;
1478  const char * const kSignature1 = "11337937696949187602";
1479  const char * const kResponse1 =
1480      "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery "
1481      "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
1482      "signature=\"11337937696949187602\"><field signature=\"412125936\"/>"
1483      "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
1484      "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>"
1485      "</autofillquery>";
1486  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1487                                                &encoded_signatures,
1488                                                &encoded_xml));
1489  ASSERT_EQ(1U, encoded_signatures.size());
1490  EXPECT_EQ(kSignature1, encoded_signatures[0]);
1491  EXPECT_EQ(kResponse1, encoded_xml);
1492
1493  // Add the same form, only one will be encoded, so EncodeQueryRequest() should
1494  // return the same data.
1495  forms.push_back(new FormStructure(form));
1496  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1497                                                &encoded_signatures,
1498                                                &encoded_xml));
1499  ASSERT_EQ(1U, encoded_signatures.size());
1500  EXPECT_EQ(kSignature1, encoded_signatures[0]);
1501  EXPECT_EQ(kResponse1, encoded_xml);
1502  // Add 5 address fields - this should be still a valid form.
1503  for (size_t i = 0; i < 5; ++i) {
1504    field.label = ASCIIToUTF16("Address");
1505    field.name = ASCIIToUTF16("address");
1506    form.fields.push_back(field);
1507  }
1508
1509  forms.push_back(new FormStructure(form));
1510  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1511                                                &encoded_signatures,
1512                                                &encoded_xml));
1513  ASSERT_EQ(2U, encoded_signatures.size());
1514  EXPECT_EQ(kSignature1, encoded_signatures[0]);
1515  const char * const kSignature2 = "8308881815906226214";
1516  EXPECT_EQ(kSignature2, encoded_signatures[1]);
1517  const char * const kResponse2 =
1518      "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery "
1519      "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
1520      "signature=\"11337937696949187602\"><field signature=\"412125936\"/>"
1521      "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
1522      "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>"
1523      "<form signature=\"8308881815906226214\"><field signature=\"412125936\"/>"
1524      "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
1525      "<field signature=\"747221617\"/><field signature=\"4108155786\"/><field "
1526      "signature=\"509334676\"/><field signature=\"509334676\"/><field "
1527      "signature=\"509334676\"/><field signature=\"509334676\"/><field "
1528      "signature=\"509334676\"/></form></autofillquery>";
1529  EXPECT_EQ(kResponse2, encoded_xml);
1530
1531  FormData malformed_form(form);
1532  // Add 50 address fields - the form is not valid anymore, but previous ones
1533  // are. The result should be the same as in previous test.
1534  for (size_t i = 0; i < 50; ++i) {
1535    field.label = ASCIIToUTF16("Address");
1536    field.name = ASCIIToUTF16("address");
1537    malformed_form.fields.push_back(field);
1538  }
1539
1540  forms.push_back(new FormStructure(malformed_form));
1541  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
1542                                                &encoded_signatures,
1543                                                &encoded_xml));
1544  ASSERT_EQ(2U, encoded_signatures.size());
1545  EXPECT_EQ(kSignature1, encoded_signatures[0]);
1546  EXPECT_EQ(kSignature2, encoded_signatures[1]);
1547  EXPECT_EQ(kResponse2, encoded_xml);
1548
1549  // Check that we fail if there are only bad form(s).
1550  ScopedVector<FormStructure> bad_forms;
1551  bad_forms.push_back(new FormStructure(malformed_form));
1552  EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms.get(),
1553                                                 &encoded_signatures,
1554                                                 &encoded_xml));
1555  EXPECT_EQ(0U, encoded_signatures.size());
1556  EXPECT_EQ("", encoded_xml);
1557}
1558
1559TEST(FormStructureTest, EncodeUploadRequest) {
1560  scoped_ptr<FormStructure> form_structure;
1561  std::vector<ServerFieldTypeSet> possible_field_types;
1562  FormData form;
1563  form.method = ASCIIToUTF16("post");
1564  form_structure.reset(new FormStructure(form));
1565  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1566
1567  FormFieldData field;
1568  field.form_control_type = "text";
1569
1570  field.label = ASCIIToUTF16("First Name");
1571  field.name = ASCIIToUTF16("firstname");
1572  form.fields.push_back(field);
1573  possible_field_types.push_back(ServerFieldTypeSet());
1574  possible_field_types.back().insert(NAME_FIRST);
1575
1576  field.label = ASCIIToUTF16("Last Name");
1577  field.name = ASCIIToUTF16("lastname");
1578  form.fields.push_back(field);
1579  possible_field_types.push_back(ServerFieldTypeSet());
1580  possible_field_types.back().insert(NAME_LAST);
1581
1582  field.label = ASCIIToUTF16("Email");
1583  field.name = ASCIIToUTF16("email");
1584  field.form_control_type = "email";
1585  form.fields.push_back(field);
1586  possible_field_types.push_back(ServerFieldTypeSet());
1587  possible_field_types.back().insert(EMAIL_ADDRESS);
1588
1589  field.label = ASCIIToUTF16("Phone");
1590  field.name = ASCIIToUTF16("phone");
1591  field.form_control_type = "number";
1592  form.fields.push_back(field);
1593  possible_field_types.push_back(ServerFieldTypeSet());
1594  possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
1595
1596  field.label = ASCIIToUTF16("Country");
1597  field.name = ASCIIToUTF16("country");
1598  field.form_control_type = "select-one";
1599  form.fields.push_back(field);
1600  possible_field_types.push_back(ServerFieldTypeSet());
1601  possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1602
1603  // Add checkable field.
1604  FormFieldData checkable_field;
1605  checkable_field.is_checkable = true;
1606  checkable_field.label = ASCIIToUTF16("Checkable1");
1607  checkable_field.name = ASCIIToUTF16("Checkable1");
1608  form.fields.push_back(checkable_field);
1609  possible_field_types.push_back(ServerFieldTypeSet());
1610  possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1611
1612  form_structure.reset(new FormStructure(form));
1613
1614  ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1615  for (size_t i = 0; i < form_structure->field_count(); ++i)
1616    form_structure->field(i)->set_possible_types(possible_field_types[i]);
1617
1618  ServerFieldTypeSet available_field_types;
1619  available_field_types.insert(NAME_FIRST);
1620  available_field_types.insert(NAME_LAST);
1621  available_field_types.insert(ADDRESS_HOME_LINE1);
1622  available_field_types.insert(ADDRESS_HOME_LINE2);
1623  available_field_types.insert(ADDRESS_HOME_COUNTRY);
1624  available_field_types.insert(ADDRESS_BILLING_LINE1);
1625  available_field_types.insert(ADDRESS_BILLING_LINE2);
1626  available_field_types.insert(EMAIL_ADDRESS);
1627  available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1628
1629  std::string encoded_xml;
1630  EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
1631                                                  &encoded_xml));
1632  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1633            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1634            "formsignature=\"8736493185895608956\" autofillused=\"false\" "
1635            "datapresent=\"144200030e\">"
1636            "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1637            "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1638            "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1639            "<field signature=\"466116101\" autofilltype=\"14\"/>"
1640            "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1641            "</autofillupload>",
1642            encoded_xml);
1643  EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, true,
1644                                                  &encoded_xml));
1645  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1646            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1647            "formsignature=\"8736493185895608956\" autofillused=\"true\" "
1648            "datapresent=\"144200030e\">"
1649            "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1650            "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1651            "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1652            "<field signature=\"466116101\" autofilltype=\"14\"/>"
1653            "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1654            "</autofillupload>",
1655            encoded_xml);
1656
1657  // Add 2 address fields - this should be still a valid form.
1658  for (size_t i = 0; i < 2; ++i) {
1659    field.label = ASCIIToUTF16("Address");
1660    field.name = ASCIIToUTF16("address");
1661    field.form_control_type = "text";
1662    form.fields.push_back(field);
1663    possible_field_types.push_back(ServerFieldTypeSet());
1664    possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1665    possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1666    possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1667    possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1668  }
1669
1670  form_structure.reset(new FormStructure(form));
1671  ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1672  for (size_t i = 0; i < form_structure->field_count(); ++i)
1673    form_structure->field(i)->set_possible_types(possible_field_types[i]);
1674
1675  EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
1676                                                  &encoded_xml));
1677  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1678            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
1679            "formsignature=\"7816485729218079147\" autofillused=\"false\" "
1680            "datapresent=\"144200030e\">"
1681            "<field signature=\"3763331450\" autofilltype=\"3\"/>"
1682            "<field signature=\"3494530716\" autofilltype=\"5\"/>"
1683            "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1684            "<field signature=\"466116101\" autofilltype=\"14\"/>"
1685            "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1686            "<field signature=\"509334676\" autofilltype=\"30\"/>"
1687            "<field signature=\"509334676\" autofilltype=\"31\"/>"
1688            "<field signature=\"509334676\" autofilltype=\"37\"/>"
1689            "<field signature=\"509334676\" autofilltype=\"38\"/>"
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            "</autofillupload>",
1695            encoded_xml);
1696
1697  // Add 50 address fields - now the form is invalid, as it has too many fields.
1698  for (size_t i = 0; i < 50; ++i) {
1699    field.label = ASCIIToUTF16("Address");
1700    field.name = ASCIIToUTF16("address");
1701    field.form_control_type = "text";
1702    form.fields.push_back(field);
1703    possible_field_types.push_back(ServerFieldTypeSet());
1704    possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1705    possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1706    possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1707    possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1708  }
1709  form_structure.reset(new FormStructure(form));
1710  ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1711  for (size_t i = 0; i < form_structure->field_count(); ++i)
1712    form_structure->field(i)->set_possible_types(possible_field_types[i]);
1713  EXPECT_FALSE(form_structure->EncodeUploadRequest(available_field_types, false,
1714                                                   &encoded_xml));
1715}
1716
1717TEST(FormStructureTest, EncodeFieldAssignments) {
1718  scoped_ptr<FormStructure> form_structure;
1719  std::vector<ServerFieldTypeSet> possible_field_types;
1720  FormData form;
1721  form.method = ASCIIToUTF16("post");
1722  form_structure.reset(new FormStructure(form));
1723  form_structure->DetermineHeuristicTypes(TestAutofillMetrics());
1724
1725  FormFieldData field;
1726  field.form_control_type = "text";
1727
1728  field.label = ASCIIToUTF16("First Name");
1729  field.name = ASCIIToUTF16("firstname");
1730  form.fields.push_back(field);
1731  possible_field_types.push_back(ServerFieldTypeSet());
1732  possible_field_types.back().insert(NAME_FIRST);
1733
1734  field.label = ASCIIToUTF16("Last Name");
1735  field.name = ASCIIToUTF16("lastname");
1736  form.fields.push_back(field);
1737  possible_field_types.push_back(ServerFieldTypeSet());
1738  possible_field_types.back().insert(NAME_LAST);
1739
1740  field.label = ASCIIToUTF16("Email");
1741  field.name = ASCIIToUTF16("email");
1742  field.form_control_type = "email";
1743  form.fields.push_back(field);
1744  possible_field_types.push_back(ServerFieldTypeSet());
1745  possible_field_types.back().insert(EMAIL_ADDRESS);
1746
1747  field.label = ASCIIToUTF16("Phone");
1748  field.name = ASCIIToUTF16("phone");
1749  field.form_control_type = "number";
1750  form.fields.push_back(field);
1751  possible_field_types.push_back(ServerFieldTypeSet());
1752  possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
1753
1754  field.label = ASCIIToUTF16("Country");
1755  field.name = ASCIIToUTF16("country");
1756  field.form_control_type = "select-one";
1757  form.fields.push_back(field);
1758  possible_field_types.push_back(ServerFieldTypeSet());
1759  possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1760
1761  // Add checkable field.
1762  FormFieldData checkable_field;
1763  checkable_field.is_checkable = true;
1764  checkable_field.label = ASCIIToUTF16("Checkable1");
1765  checkable_field.name = ASCIIToUTF16("Checkable1");
1766  form.fields.push_back(checkable_field);
1767  possible_field_types.push_back(ServerFieldTypeSet());
1768  possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1769
1770  form_structure.reset(new FormStructure(form));
1771
1772  ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1773  for (size_t i = 0; i < form_structure->field_count(); ++i)
1774    form_structure->field(i)->set_possible_types(possible_field_types[i]);
1775
1776  ServerFieldTypeSet available_field_types;
1777  available_field_types.insert(NAME_FIRST);
1778  available_field_types.insert(NAME_LAST);
1779  available_field_types.insert(ADDRESS_HOME_LINE1);
1780  available_field_types.insert(ADDRESS_HOME_LINE2);
1781  available_field_types.insert(ADDRESS_HOME_COUNTRY);
1782  available_field_types.insert(ADDRESS_BILLING_LINE1);
1783  available_field_types.insert(ADDRESS_BILLING_LINE2);
1784  available_field_types.insert(EMAIL_ADDRESS);
1785  available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1786
1787  std::string encoded_xml;
1788  EXPECT_TRUE(form_structure->EncodeFieldAssignments(
1789      available_field_types, &encoded_xml));
1790  EXPECT_EQ(
1791      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1792      "<fieldassignments formsignature=\"8736493185895608956\">"
1793      "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1794      "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1795      "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1796      "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1797      "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1798      "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
1799      "</fieldassignments>",
1800      encoded_xml);
1801
1802  // Add 2 address fields - this should be still a valid form.
1803  for (size_t i = 0; i < 2; ++i) {
1804    field.label = ASCIIToUTF16("Address");
1805    field.name = ASCIIToUTF16("address");
1806    field.form_control_type = "text";
1807    form.fields.push_back(field);
1808    possible_field_types.push_back(ServerFieldTypeSet());
1809    possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1810    possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1811    possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1812    possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1813  }
1814
1815  form_structure.reset(new FormStructure(form));
1816  ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1817  for (size_t i = 0; i < form_structure->field_count(); ++i)
1818    form_structure->field(i)->set_possible_types(possible_field_types[i]);
1819
1820  EXPECT_TRUE(form_structure->EncodeFieldAssignments(
1821      available_field_types, &encoded_xml));
1822  EXPECT_EQ(
1823      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
1824      "<fieldassignments formsignature=\"7816485729218079147\">"
1825      "<fields fieldid=\"3763331450\" fieldtype=\"3\" name=\"firstname\"/>"
1826      "<fields fieldid=\"3494530716\" fieldtype=\"5\" name=\"lastname\"/>"
1827      "<fields fieldid=\"1029417091\" fieldtype=\"9\" name=\"email\"/>"
1828      "<fields fieldid=\"466116101\" fieldtype=\"14\" name=\"phone\"/>"
1829      "<fields fieldid=\"2799270304\" fieldtype=\"36\" name=\"country\"/>"
1830      "<fields fieldid=\"3410250678\" fieldtype=\"36\" name=\"Checkable1\"/>"
1831      "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>"
1832      "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
1833      "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
1834      "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
1835      "<fields fieldid=\"509334676\" fieldtype=\"30\" name=\"address\"/>"
1836      "<fields fieldid=\"509334676\" fieldtype=\"31\" name=\"address\"/>"
1837      "<fields fieldid=\"509334676\" fieldtype=\"37\" name=\"address\"/>"
1838      "<fields fieldid=\"509334676\" fieldtype=\"38\" name=\"address\"/>"
1839      "</fieldassignments>",
1840      encoded_xml);
1841}
1842
1843// Check that we compute the "datapresent" string correctly for the given
1844// |available_types|.
1845TEST(FormStructureTest, CheckDataPresence) {
1846  FormData form;
1847  form.method = ASCIIToUTF16("post");
1848
1849  FormFieldData field;
1850  field.form_control_type = "text";
1851
1852  field.label = ASCIIToUTF16("First Name");
1853  field.name = ASCIIToUTF16("first");
1854  form.fields.push_back(field);
1855
1856  field.label = ASCIIToUTF16("Last Name");
1857  field.name = ASCIIToUTF16("last");
1858  form.fields.push_back(field);
1859
1860  field.label = ASCIIToUTF16("Email");
1861  field.name = ASCIIToUTF16("email");
1862  form.fields.push_back(field);
1863
1864  FormStructure form_structure(form);
1865
1866  ServerFieldTypeSet unknown_type;
1867  unknown_type.insert(UNKNOWN_TYPE);
1868  for (size_t i = 0; i < form_structure.field_count(); ++i)
1869    form_structure.field(i)->set_possible_types(unknown_type);
1870
1871  // No available types.
1872  // datapresent should be "" == trimmmed(0x0000000000000000) ==
1873  //     0b0000000000000000000000000000000000000000000000000000000000000000
1874  ServerFieldTypeSet available_field_types;
1875
1876  std::string encoded_xml;
1877  EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1878                                                 &encoded_xml));
1879  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1880            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1881            " formsignature=\"6402244543831589061\" autofillused=\"false\""
1882            " datapresent=\"\">"
1883            "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1884            "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1885            "<field signature=\"420638584\" autofilltype=\"1\"/>"
1886            "</autofillupload>",
1887            encoded_xml);
1888
1889  // Only a few types available.
1890  // datapresent should be "1540000240" == trimmmed(0x1540000240000000) ==
1891  //     0b0001010101000000000000000000001001000000000000000000000000000000
1892  // The set bits are:
1893  //  3 == NAME_FIRST
1894  //  5 == NAME_LAST
1895  //  7 == NAME_FULL
1896  //  9 == EMAIL_ADDRESS
1897  // 30 == ADDRESS_HOME_LINE1
1898  // 33 == ADDRESS_HOME_CITY
1899  available_field_types.clear();
1900  available_field_types.insert(NAME_FIRST);
1901  available_field_types.insert(NAME_LAST);
1902  available_field_types.insert(NAME_FULL);
1903  available_field_types.insert(EMAIL_ADDRESS);
1904  available_field_types.insert(ADDRESS_HOME_LINE1);
1905  available_field_types.insert(ADDRESS_HOME_CITY);
1906
1907  EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1908                                                 &encoded_xml));
1909  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1910            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1911            " formsignature=\"6402244543831589061\" autofillused=\"false\""
1912            " datapresent=\"1540000240\">"
1913            "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1914            "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1915            "<field signature=\"420638584\" autofilltype=\"1\"/>"
1916            "</autofillupload>",
1917            encoded_xml);
1918
1919  // All supported non-credit card types available.
1920  // datapresent should be "1f7e000378000008" == trimmmed(0x1f7e000378000008) ==
1921  //     0b0001111101111110000000000000001101111000000000000000000000001000
1922  // The set bits are:
1923  //  3 == NAME_FIRST
1924  //  4 == NAME_MIDDLE
1925  //  5 == NAME_LAST
1926  //  6 == NAME_MIDDLE_INITIAL
1927  //  7 == NAME_FULL
1928  //  9 == EMAIL_ADDRESS
1929  // 10 == PHONE_HOME_NUMBER,
1930  // 11 == PHONE_HOME_CITY_CODE,
1931  // 12 == PHONE_HOME_COUNTRY_CODE,
1932  // 13 == PHONE_HOME_CITY_AND_NUMBER,
1933  // 14 == PHONE_HOME_WHOLE_NUMBER,
1934  // 30 == ADDRESS_HOME_LINE1
1935  // 31 == ADDRESS_HOME_LINE2
1936  // 33 == ADDRESS_HOME_CITY
1937  // 34 == ADDRESS_HOME_STATE
1938  // 35 == ADDRESS_HOME_ZIP
1939  // 36 == ADDRESS_HOME_COUNTRY
1940  // 60 == COMPANY_NAME
1941  available_field_types.clear();
1942  available_field_types.insert(NAME_FIRST);
1943  available_field_types.insert(NAME_MIDDLE);
1944  available_field_types.insert(NAME_LAST);
1945  available_field_types.insert(NAME_MIDDLE_INITIAL);
1946  available_field_types.insert(NAME_FULL);
1947  available_field_types.insert(EMAIL_ADDRESS);
1948  available_field_types.insert(PHONE_HOME_NUMBER);
1949  available_field_types.insert(PHONE_HOME_CITY_CODE);
1950  available_field_types.insert(PHONE_HOME_COUNTRY_CODE);
1951  available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER);
1952  available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
1953  available_field_types.insert(ADDRESS_HOME_LINE1);
1954  available_field_types.insert(ADDRESS_HOME_LINE2);
1955  available_field_types.insert(ADDRESS_HOME_CITY);
1956  available_field_types.insert(ADDRESS_HOME_STATE);
1957  available_field_types.insert(ADDRESS_HOME_ZIP);
1958  available_field_types.insert(ADDRESS_HOME_COUNTRY);
1959  available_field_types.insert(COMPANY_NAME);
1960
1961  EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1962                                                 &encoded_xml));
1963  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1964            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1965            " formsignature=\"6402244543831589061\" autofillused=\"false\""
1966            " datapresent=\"1f7e000378000008\">"
1967            "<field signature=\"1089846351\" autofilltype=\"1\"/>"
1968            "<field signature=\"2404144663\" autofilltype=\"1\"/>"
1969            "<field signature=\"420638584\" autofilltype=\"1\"/>"
1970            "</autofillupload>",
1971            encoded_xml);
1972
1973  // All supported credit card types available.
1974  // datapresent should be "0000000000001fc0" == trimmmed(0x0000000000001fc0) ==
1975  //     0b0000000000000000000000000000000000000000000000000001111111000000
1976  // The set bits are:
1977  // 51 == CREDIT_CARD_NAME
1978  // 52 == CREDIT_CARD_NUMBER
1979  // 53 == CREDIT_CARD_EXP_MONTH
1980  // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
1981  // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
1982  // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
1983  // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
1984  available_field_types.clear();
1985  available_field_types.insert(CREDIT_CARD_NAME);
1986  available_field_types.insert(CREDIT_CARD_NUMBER);
1987  available_field_types.insert(CREDIT_CARD_EXP_MONTH);
1988  available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
1989  available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
1990  available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
1991  available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
1992
1993  EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
1994                                                 &encoded_xml));
1995  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
1996            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
1997            " formsignature=\"6402244543831589061\" autofillused=\"false\""
1998            " datapresent=\"0000000000001fc0\">"
1999            "<field signature=\"1089846351\" autofilltype=\"1\"/>"
2000            "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2001            "<field signature=\"420638584\" autofilltype=\"1\"/>"
2002            "</autofillupload>",
2003            encoded_xml);
2004
2005  // All supported types available.
2006  // datapresent should be "1f7e000378001fc8" == trimmmed(0x1f7e000378001fc8) ==
2007  //     0b0001111101111110000000000000001101111000000000000001111111001000
2008  // The set bits are:
2009  //  3 == NAME_FIRST
2010  //  4 == NAME_MIDDLE
2011  //  5 == NAME_LAST
2012  //  6 == NAME_MIDDLE_INITIAL
2013  //  7 == NAME_FULL
2014  //  9 == EMAIL_ADDRESS
2015  // 10 == PHONE_HOME_NUMBER,
2016  // 11 == PHONE_HOME_CITY_CODE,
2017  // 12 == PHONE_HOME_COUNTRY_CODE,
2018  // 13 == PHONE_HOME_CITY_AND_NUMBER,
2019  // 14 == PHONE_HOME_WHOLE_NUMBER,
2020  // 30 == ADDRESS_HOME_LINE1
2021  // 31 == ADDRESS_HOME_LINE2
2022  // 33 == ADDRESS_HOME_CITY
2023  // 34 == ADDRESS_HOME_STATE
2024  // 35 == ADDRESS_HOME_ZIP
2025  // 36 == ADDRESS_HOME_COUNTRY
2026  // 51 == CREDIT_CARD_NAME
2027  // 52 == CREDIT_CARD_NUMBER
2028  // 53 == CREDIT_CARD_EXP_MONTH
2029  // 54 == CREDIT_CARD_EXP_2_DIGIT_YEAR
2030  // 55 == CREDIT_CARD_EXP_4_DIGIT_YEAR
2031  // 56 == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR
2032  // 57 == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR
2033  // 60 == COMPANY_NAME
2034  available_field_types.clear();
2035  available_field_types.insert(NAME_FIRST);
2036  available_field_types.insert(NAME_MIDDLE);
2037  available_field_types.insert(NAME_LAST);
2038  available_field_types.insert(NAME_MIDDLE_INITIAL);
2039  available_field_types.insert(NAME_FULL);
2040  available_field_types.insert(EMAIL_ADDRESS);
2041  available_field_types.insert(PHONE_HOME_NUMBER);
2042  available_field_types.insert(PHONE_HOME_CITY_CODE);
2043  available_field_types.insert(PHONE_HOME_COUNTRY_CODE);
2044  available_field_types.insert(PHONE_HOME_CITY_AND_NUMBER);
2045  available_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
2046  available_field_types.insert(ADDRESS_HOME_LINE1);
2047  available_field_types.insert(ADDRESS_HOME_LINE2);
2048  available_field_types.insert(ADDRESS_HOME_CITY);
2049  available_field_types.insert(ADDRESS_HOME_STATE);
2050  available_field_types.insert(ADDRESS_HOME_ZIP);
2051  available_field_types.insert(ADDRESS_HOME_COUNTRY);
2052  available_field_types.insert(CREDIT_CARD_NAME);
2053  available_field_types.insert(CREDIT_CARD_NUMBER);
2054  available_field_types.insert(CREDIT_CARD_EXP_MONTH);
2055  available_field_types.insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
2056  available_field_types.insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
2057  available_field_types.insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
2058  available_field_types.insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
2059  available_field_types.insert(COMPANY_NAME);
2060
2061  EXPECT_TRUE(form_structure.EncodeUploadRequest(available_field_types, false,
2062                                                 &encoded_xml));
2063  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2064            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2065            " formsignature=\"6402244543831589061\" autofillused=\"false\""
2066            " datapresent=\"1f7e000378001fc8\">"
2067            "<field signature=\"1089846351\" autofilltype=\"1\"/>"
2068            "<field signature=\"2404144663\" autofilltype=\"1\"/>"
2069            "<field signature=\"420638584\" autofilltype=\"1\"/>"
2070            "</autofillupload>",
2071            encoded_xml);
2072}
2073
2074TEST(FormStructureTest, CheckMultipleTypes) {
2075  // Throughout this test, datapresent should be
2076  // 0x1440000360000008 ==
2077  //     0b0001010001000000000000000000001101100000000000000000000000001000
2078  // The set bits are:
2079  //  3 == NAME_FIRST
2080  //  5 == NAME_LAST
2081  //  9 == EMAIL_ADDRESS
2082  // 30 == ADDRESS_HOME_LINE1
2083  // 31 == ADDRESS_HOME_LINE2
2084  // 33 == ADDRESS_HOME_CITY
2085  // 34 == ADDRESS_HOME_STATE
2086  // 60 == COMPANY_NAME
2087  ServerFieldTypeSet available_field_types;
2088  available_field_types.insert(NAME_FIRST);
2089  available_field_types.insert(NAME_LAST);
2090  available_field_types.insert(EMAIL_ADDRESS);
2091  available_field_types.insert(ADDRESS_HOME_LINE1);
2092  available_field_types.insert(ADDRESS_HOME_LINE2);
2093  available_field_types.insert(ADDRESS_HOME_CITY);
2094  available_field_types.insert(ADDRESS_HOME_STATE);
2095  available_field_types.insert(COMPANY_NAME);
2096
2097  // Check that multiple types for the field are processed correctly.
2098  scoped_ptr<FormStructure> form_structure;
2099  std::vector<ServerFieldTypeSet> possible_field_types;
2100  FormData form;
2101  form.method = ASCIIToUTF16("post");
2102
2103  FormFieldData field;
2104  field.form_control_type = "text";
2105
2106  field.label = ASCIIToUTF16("email");
2107  field.name = ASCIIToUTF16("email");
2108  form.fields.push_back(field);
2109  possible_field_types.push_back(ServerFieldTypeSet());
2110  possible_field_types.back().insert(EMAIL_ADDRESS);
2111
2112  field.label = ASCIIToUTF16("First Name");
2113  field.name = ASCIIToUTF16("first");
2114  form.fields.push_back(field);
2115  possible_field_types.push_back(ServerFieldTypeSet());
2116  possible_field_types.back().insert(NAME_FIRST);
2117
2118  field.label = ASCIIToUTF16("Last Name");
2119  field.name = ASCIIToUTF16("last");
2120  form.fields.push_back(field);
2121  possible_field_types.push_back(ServerFieldTypeSet());
2122  possible_field_types.back().insert(NAME_LAST);
2123
2124  field.label = ASCIIToUTF16("Address");
2125  field.name = ASCIIToUTF16("address");
2126  form.fields.push_back(field);
2127  possible_field_types.push_back(ServerFieldTypeSet());
2128  possible_field_types.back().insert(ADDRESS_HOME_LINE1);
2129
2130  form_structure.reset(new FormStructure(form));
2131
2132  for (size_t i = 0; i < form_structure->field_count(); ++i)
2133    form_structure->field(i)->set_possible_types(possible_field_types[i]);
2134  std::string encoded_xml;
2135
2136  // Now we matched both fields singularly.
2137  EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2138                                                  &encoded_xml));
2139  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2140            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2141            " formsignature=\"18062476096658145866\" autofillused=\"false\""
2142            " datapresent=\"1440000360000008\">"
2143            "<field signature=\"420638584\" autofilltype=\"9\"/>"
2144            "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2145            "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2146            "<field signature=\"509334676\" autofilltype=\"30\"/>"
2147            "</autofillupload>",
2148            encoded_xml);
2149  // Match third field as both first and last.
2150  possible_field_types[2].insert(NAME_FIRST);
2151  form_structure->field(2)->set_possible_types(possible_field_types[2]);
2152  EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2153                                                  &encoded_xml));
2154  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2155            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2156            " formsignature=\"18062476096658145866\" autofillused=\"false\""
2157            " datapresent=\"1440000360000008\">"
2158            "<field signature=\"420638584\" autofilltype=\"9\"/>"
2159            "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2160            "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2161            "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2162            "<field signature=\"509334676\" autofilltype=\"30\"/>"
2163            "</autofillupload>",
2164            encoded_xml);
2165  possible_field_types[3].insert(ADDRESS_HOME_LINE2);
2166  form_structure->field(form_structure->field_count() - 1)->set_possible_types(
2167      possible_field_types[form_structure->field_count() - 1]);
2168  EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2169                                                  &encoded_xml));
2170  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2171            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2172            " formsignature=\"18062476096658145866\" autofillused=\"false\""
2173            " datapresent=\"1440000360000008\">"
2174            "<field signature=\"420638584\" autofilltype=\"9\"/>"
2175            "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2176            "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2177            "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2178            "<field signature=\"509334676\" autofilltype=\"30\"/>"
2179            "<field signature=\"509334676\" autofilltype=\"31\"/>"
2180            "</autofillupload>",
2181            encoded_xml);
2182  possible_field_types[3].clear();
2183  possible_field_types[3].insert(ADDRESS_HOME_LINE1);
2184  possible_field_types[3].insert(COMPANY_NAME);
2185  form_structure->field(form_structure->field_count() - 1)->set_possible_types(
2186      possible_field_types[form_structure->field_count() - 1]);
2187  EXPECT_TRUE(form_structure->EncodeUploadRequest(available_field_types, false,
2188                                                  &encoded_xml));
2189  EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
2190            "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\""
2191            " formsignature=\"18062476096658145866\" autofillused=\"false\""
2192            " datapresent=\"1440000360000008\">"
2193            "<field signature=\"420638584\" autofilltype=\"9\"/>"
2194            "<field signature=\"1089846351\" autofilltype=\"3\"/>"
2195            "<field signature=\"2404144663\" autofilltype=\"3\"/>"
2196            "<field signature=\"2404144663\" autofilltype=\"5\"/>"
2197            "<field signature=\"509334676\" autofilltype=\"30\"/>"
2198            "<field signature=\"509334676\" autofilltype=\"60\"/>"
2199            "</autofillupload>",
2200            encoded_xml);
2201}
2202
2203TEST(FormStructureTest, CheckFormSignature) {
2204  // Check that form signature is created correctly.
2205  scoped_ptr<FormStructure> form_structure;
2206  FormData form;
2207  form.method = ASCIIToUTF16("post");
2208
2209  FormFieldData field;
2210  field.form_control_type = "text";
2211
2212  field.label = ASCIIToUTF16("email");
2213  field.name = ASCIIToUTF16("email");
2214  form.fields.push_back(field);
2215
2216  field.label = ASCIIToUTF16("First Name");
2217  field.name = ASCIIToUTF16("first");
2218  form.fields.push_back(field);
2219
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);
2226
2227  form_structure.reset(new FormStructure(form));
2228
2229  EXPECT_EQ(FormStructureTest::Hash64Bit(
2230      std::string("://&&email&first")),
2231      form_structure->FormSignature());
2232
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());
2238
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());
2244
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());
2250
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());
2270
2271}
2272
2273TEST(FormStructureTest, ToFormData) {
2274  FormData form;
2275  form.name = ASCIIToUTF16("the-name");
2276  form.method = ASCIIToUTF16("POST");
2277  form.origin = GURL("http://cool.com");
2278  form.action = form.origin.Resolve("/login");
2279
2280  FormFieldData field;
2281  field.label = ASCIIToUTF16("username");
2282  field.name = ASCIIToUTF16("username");
2283  field.form_control_type = "text";
2284  form.fields.push_back(field);
2285
2286  field.label = ASCIIToUTF16("password");
2287  field.name = ASCIIToUTF16("password");
2288  field.form_control_type = "password";
2289  form.fields.push_back(field);
2290
2291  field.label = base::string16();
2292  field.name = ASCIIToUTF16("Submit");
2293  field.form_control_type = "submit";
2294  form.fields.push_back(field);
2295
2296  EXPECT_EQ(form, FormStructure(form).ToFormData());
2297
2298  // Currently |FormStructure(form_data)ToFormData().user_submitted| is always
2299  // false. This forces a future author that changes this to update this test.
2300  form.user_submitted = true;
2301  EXPECT_NE(form, FormStructure(form).ToFormData());
2302}
2303
2304TEST(FormStructureTest, SkipFieldTest) {
2305  FormData form;
2306  form.name = ASCIIToUTF16("the-name");
2307  form.method = ASCIIToUTF16("POST");
2308  form.origin = GURL("http://cool.com");
2309  form.action = form.origin.Resolve("/login");
2310
2311  FormFieldData field;
2312  field.label = ASCIIToUTF16("username");
2313  field.name = ASCIIToUTF16("username");
2314  field.form_control_type = "text";
2315  form.fields.push_back(field);
2316
2317  field.label = ASCIIToUTF16("select");
2318  field.name = ASCIIToUTF16("select");
2319  field.form_control_type = "checkbox";
2320  field.is_checkable = true;
2321  form.fields.push_back(field);
2322
2323  field.label = base::string16();
2324  field.name = ASCIIToUTF16("email");
2325  field.form_control_type = "text";
2326  field.is_checkable = false;
2327  form.fields.push_back(field);
2328
2329  ScopedVector<FormStructure> forms;
2330  forms.push_back(new FormStructure(form));
2331  std::vector<std::string> encoded_signatures;
2332  std::string encoded_xml;
2333
2334  const char * const kSignature = "18006745212084723782";
2335  const char * const kResponse =
2336      "<\?xml version=\"1.0\" encoding=\"UTF-8\"?><autofillquery "
2337      "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
2338      "signature=\"18006745212084723782\"><field signature=\"239111655\"/>"
2339      "<field signature=\"420638584\"/></form></autofillquery>";
2340  ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms.get(),
2341                                                &encoded_signatures,
2342                                                &encoded_xml));
2343  ASSERT_EQ(1U, encoded_signatures.size());
2344  EXPECT_EQ(kSignature, encoded_signatures[0]);
2345  EXPECT_EQ(kResponse, encoded_xml);
2346}
2347
2348}  // namespace autofill
2349