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