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