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