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