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