Home | History | Annotate | Download | only in autofill
      1 // Copyright (c) 2011 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 "base/memory/scoped_ptr.h"
      6 #include "base/string_util.h"
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/autofill/form_structure.h"
      9 #include "googleurl/src/gurl.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
     12 #include "webkit/glue/form_data.h"
     13 #include "webkit/glue/form_field.h"
     14 
     15 using webkit_glue::FormData;
     16 using WebKit::WebInputElement;
     17 
     18 namespace webkit_glue {
     19 
     20 std::ostream& operator<<(std::ostream& os, const FormData& form) {
     21   os << UTF16ToUTF8(form.name)
     22      << " "
     23      << UTF16ToUTF8(form.method)
     24      << " "
     25      << form.origin.spec()
     26      << " "
     27      << form.action.spec()
     28      << " ";
     29 
     30   for (std::vector<webkit_glue::FormField>::const_iterator iter =
     31            form.fields.begin();
     32        iter != form.fields.end(); ++iter) {
     33     os << *iter
     34        << " ";
     35   }
     36 
     37   return os;
     38 }
     39 
     40 }  // namespace webkit_glue
     41 
     42 class FormStructureTest {
     43  public:
     44   static std::string Hash64Bit(const std::string& str) {
     45     return FormStructure::Hash64Bit(str);
     46   }
     47 };
     48 
     49 namespace {
     50 
     51 TEST(FormStructureTest, FieldCount) {
     52   FormData form;
     53   form.method = ASCIIToUTF16("post");
     54   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("username"),
     55                                                ASCIIToUTF16("username"),
     56                                                string16(),
     57                                                ASCIIToUTF16("text"),
     58                                                0,
     59                                                false));
     60   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("password"),
     61                                                ASCIIToUTF16("password"),
     62                                                string16(),
     63                                                ASCIIToUTF16("password"),
     64                                                0,
     65                                                false));
     66   form.fields.push_back(webkit_glue::FormField(string16(),
     67                                                ASCIIToUTF16("Submit"),
     68                                                string16(),
     69                                                ASCIIToUTF16("submit"),
     70                                                0,
     71                                                false));
     72   FormStructure form_structure(form);
     73 
     74   // All fields are counted.
     75   EXPECT_EQ(3U, form_structure.field_count());
     76 }
     77 
     78 TEST(FormStructureTest, AutofillCount) {
     79   FormData form;
     80   form.method = ASCIIToUTF16("post");
     81   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("username"),
     82                                                ASCIIToUTF16("username"),
     83                                                string16(),
     84                                                ASCIIToUTF16("text"),
     85                                                0,
     86                                                false));
     87   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("password"),
     88                                                ASCIIToUTF16("password"),
     89                                                string16(),
     90                                                ASCIIToUTF16("password"),
     91                                                0,
     92                                                false));
     93   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("state"),
     94                                                ASCIIToUTF16("state"),
     95                                                string16(),
     96                                                ASCIIToUTF16("select-one"),
     97                                                0,
     98                                                false));
     99   form.fields.push_back(webkit_glue::FormField(string16(),
    100                                                ASCIIToUTF16("Submit"),
    101                                                string16(),
    102                                                ASCIIToUTF16("submit"),
    103                                                0,
    104                                                false));
    105   FormStructure form_structure(form);
    106   form_structure.DetermineHeuristicTypes();
    107 
    108   // Only text and select fields that are heuristically matched are counted.
    109   EXPECT_EQ(1U, form_structure.autofill_count());
    110 }
    111 
    112 TEST(FormStructureTest, SourceURL) {
    113   FormData form;
    114   form.origin = GURL("http://www.foo.com/");
    115   form.method = ASCIIToUTF16("post");
    116   FormStructure form_structure(form);
    117 
    118   EXPECT_EQ(form.origin, form_structure.source_url());
    119 }
    120 
    121 TEST(FormStructureTest, IsAutofillable) {
    122   scoped_ptr<FormStructure> form_structure;
    123   FormData form;
    124 
    125   // We need at least three text fields to be auto-fillable.
    126   form.method = ASCIIToUTF16("post");
    127   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("username"),
    128                                                ASCIIToUTF16("username"),
    129                                                string16(),
    130                                                ASCIIToUTF16("text"),
    131                                                0,
    132                                                false));
    133   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("password"),
    134                                                ASCIIToUTF16("password"),
    135                                                string16(),
    136                                                ASCIIToUTF16("password"),
    137                                                0,
    138                                                false));
    139   form.fields.push_back(webkit_glue::FormField(string16(),
    140                                                ASCIIToUTF16("Submit"),
    141                                                string16(),
    142                                                ASCIIToUTF16("submit"),
    143                                                0,
    144                                                false));
    145   form_structure.reset(new FormStructure(form));
    146   form_structure->DetermineHeuristicTypes();
    147   EXPECT_FALSE(form_structure->IsAutofillable(true));
    148 
    149   // We now have three text fields, but only two auto-fillable fields.
    150   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
    151                                                ASCIIToUTF16("firstname"),
    152                                                string16(),
    153                                                ASCIIToUTF16("text"),
    154                                                0,
    155                                                false));
    156   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Last Name"),
    157                                                ASCIIToUTF16("lastname"),
    158                                                string16(),
    159                                                ASCIIToUTF16("text"),
    160                                                0,
    161                                                false));
    162   form_structure.reset(new FormStructure(form));
    163   form_structure->DetermineHeuristicTypes();
    164   EXPECT_FALSE(form_structure->IsAutofillable(true));
    165 
    166   // We now have three auto-fillable fields.
    167   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Email"),
    168                                                ASCIIToUTF16("email"),
    169                                                string16(),
    170                                                ASCIIToUTF16("text"),
    171                                                0,
    172                                                false));
    173   form_structure.reset(new FormStructure(form));
    174   form_structure->DetermineHeuristicTypes();
    175   EXPECT_TRUE(form_structure->IsAutofillable(true));
    176 
    177   // The method must be 'post', though we can intentionally ignore this
    178   // criterion for the sake of providing a helpful warning message to the user.
    179   form.method = ASCIIToUTF16("get");
    180   form_structure.reset(new FormStructure(form));
    181   form_structure->DetermineHeuristicTypes();
    182   EXPECT_FALSE(form_structure->IsAutofillable(true));
    183   EXPECT_TRUE(form_structure->IsAutofillable(false));
    184 
    185   // The target cannot include http(s)://*/search...
    186   form.method = ASCIIToUTF16("post");
    187   form.action = GURL("http://google.com/search?q=hello");
    188   form_structure.reset(new FormStructure(form));
    189   form_structure->DetermineHeuristicTypes();
    190   EXPECT_FALSE(form_structure->IsAutofillable(true));
    191 
    192   // But search can be in the URL.
    193   form.action = GURL("http://search.com/?q=hello");
    194   form_structure.reset(new FormStructure(form));
    195   form_structure->DetermineHeuristicTypes();
    196   EXPECT_TRUE(form_structure->IsAutofillable(true));
    197 }
    198 
    199 TEST(FormStructureTest, HeuristicsContactInfo) {
    200   scoped_ptr<FormStructure> form_structure;
    201   FormData form;
    202 
    203   form.method = ASCIIToUTF16("post");
    204   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
    205                                                ASCIIToUTF16("firstname"),
    206                                                string16(),
    207                                                ASCIIToUTF16("text"),
    208                                                0,
    209                                                false));
    210   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Last Name"),
    211                                                ASCIIToUTF16("lastname"),
    212                                                string16(),
    213                                                ASCIIToUTF16("text"),
    214                                                0,
    215                                                false));
    216   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("EMail"),
    217                                                ASCIIToUTF16("email"),
    218                                                string16(),
    219                                                ASCIIToUTF16("text"),
    220                                                0,
    221                                                false));
    222   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Phone"),
    223                                                ASCIIToUTF16("phone"),
    224                                                string16(),
    225                                                ASCIIToUTF16("text"),
    226                                                0,
    227                                                false));
    228   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Fax"),
    229                                                ASCIIToUTF16("fax"),
    230                                                string16(),
    231                                                ASCIIToUTF16("text"),
    232                                                0,
    233                                                false));
    234   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
    235                                                ASCIIToUTF16("address"),
    236                                                string16(),
    237                                                ASCIIToUTF16("text"),
    238                                                0,
    239                                                false));
    240   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("City"),
    241                                                ASCIIToUTF16("city"),
    242                                                string16(),
    243                                                ASCIIToUTF16("text"),
    244                                                0,
    245                                                false));
    246   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Zip code"),
    247                                                ASCIIToUTF16("zipcode"),
    248                                                string16(),
    249                                                ASCIIToUTF16("text"),
    250                                                0,
    251                                                false));
    252   form.fields.push_back(webkit_glue::FormField(string16(),
    253                                                ASCIIToUTF16("Submit"),
    254                                                string16(),
    255                                                ASCIIToUTF16("submit"),
    256                                                0,
    257                                                false));
    258   form_structure.reset(new FormStructure(form));
    259   form_structure->DetermineHeuristicTypes();
    260   EXPECT_TRUE(form_structure->IsAutofillable(true));
    261 
    262   // Expect the correct number of fields.
    263   ASSERT_EQ(9U, form_structure->field_count());
    264   ASSERT_EQ(8U, form_structure->autofill_count());
    265 
    266   // First name.
    267   EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
    268   // Last name.
    269   EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
    270   // Email.
    271   EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
    272   // Phone.
    273   EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
    274       form_structure->field(3)->heuristic_type());
    275   // Fax.
    276   EXPECT_EQ(PHONE_FAX_WHOLE_NUMBER, form_structure->field(4)->heuristic_type());
    277   // Address.
    278   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(5)->heuristic_type());
    279   // City.
    280   EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(6)->heuristic_type());
    281   // Zip.
    282   EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(7)->heuristic_type());
    283   // Submit.
    284   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(8)->heuristic_type());
    285 }
    286 
    287 TEST(FormStructureTest, HeuristicsSample8) {
    288   scoped_ptr<FormStructure> form_structure;
    289   FormData form;
    290 
    291   form.method = ASCIIToUTF16("post");
    292   form.fields.push_back(
    293       webkit_glue::FormField(ASCIIToUTF16("Your First Name:"),
    294                              ASCIIToUTF16("bill.first"),
    295                              string16(),
    296                              ASCIIToUTF16("text"),
    297                              0,
    298                              false));
    299   form.fields.push_back(
    300       webkit_glue::FormField(ASCIIToUTF16("Your Last Name:"),
    301                              ASCIIToUTF16("bill.last"),
    302                              string16(),
    303                              ASCIIToUTF16("text"),
    304                              0,
    305                              false));
    306   form.fields.push_back(
    307       webkit_glue::FormField(ASCIIToUTF16("Street Address Line 1:"),
    308                              ASCIIToUTF16("bill.street1"),
    309                              string16(),
    310                              ASCIIToUTF16("text"),
    311                              0,
    312                              false));
    313   form.fields.push_back(
    314       webkit_glue::FormField(ASCIIToUTF16("Street Address Line 2:"),
    315                              ASCIIToUTF16("bill.street2"),
    316                              string16(),
    317                              ASCIIToUTF16("text"),
    318                              0,
    319                              false));
    320   form.fields.push_back(
    321       webkit_glue::FormField(ASCIIToUTF16("City:"),
    322                              ASCIIToUTF16("bill.city"),
    323                              string16(),
    324                              ASCIIToUTF16("text"),
    325                              0,
    326                              false));
    327   form.fields.push_back(
    328       webkit_glue::FormField(ASCIIToUTF16("State (U.S.):"),
    329                              ASCIIToUTF16("bill.state"),
    330                              string16(),
    331                              ASCIIToUTF16("text"),
    332                              0,
    333                              false));
    334   form.fields.push_back(
    335       webkit_glue::FormField(ASCIIToUTF16("Zip/Postal Code:"),
    336                              ASCIIToUTF16("BillTo.PostalCode"),
    337                              string16(),
    338                              ASCIIToUTF16("text"),
    339                              0,
    340                              false));
    341   form.fields.push_back(
    342       webkit_glue::FormField(ASCIIToUTF16("Country:"),
    343                              ASCIIToUTF16("bill.country"),
    344                              string16(),
    345                              ASCIIToUTF16("text"),
    346                              0,
    347                              false));
    348   form.fields.push_back(
    349       webkit_glue::FormField(ASCIIToUTF16("Phone Number:"),
    350                              ASCIIToUTF16("BillTo.Phone"),
    351                              string16(),
    352                              ASCIIToUTF16("text"),
    353                              0,
    354                              false));
    355   form.fields.push_back(
    356       webkit_glue::FormField(string16(),
    357                              ASCIIToUTF16("Submit"),
    358                              string16(),
    359                              ASCIIToUTF16("submit"),
    360                              0,
    361                              false));
    362   form_structure.reset(new FormStructure(form));
    363   form_structure->DetermineHeuristicTypes();
    364   EXPECT_TRUE(form_structure->IsAutofillable(true));
    365   ASSERT_EQ(10U, form_structure->field_count());
    366   ASSERT_EQ(9U, form_structure->autofill_count());
    367 
    368   // First name.
    369   EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
    370   // Last name.
    371   EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
    372   // Address.
    373   EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(2)->heuristic_type());
    374   // Address.
    375   EXPECT_EQ(ADDRESS_BILLING_LINE2, form_structure->field(3)->heuristic_type());
    376   // City.
    377   EXPECT_EQ(ADDRESS_BILLING_CITY, form_structure->field(4)->heuristic_type());
    378   // State.
    379   EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure->field(5)->heuristic_type());
    380   // Zip.
    381   EXPECT_EQ(ADDRESS_BILLING_ZIP, form_structure->field(6)->heuristic_type());
    382   // Country.
    383   EXPECT_EQ(ADDRESS_BILLING_COUNTRY,
    384       form_structure->field(7)->heuristic_type());
    385   // Phone.
    386   EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
    387       form_structure->field(8)->heuristic_type());
    388   // Submit.
    389   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type());
    390 }
    391 
    392 TEST(FormStructureTest, HeuristicsSample6) {
    393   scoped_ptr<FormStructure> form_structure;
    394   FormData form;
    395 
    396   form.method = ASCIIToUTF16("post");
    397   form.fields.push_back(
    398       webkit_glue::FormField(ASCIIToUTF16("E-mail address"),
    399                              ASCIIToUTF16("email"),
    400                              string16(),
    401                              ASCIIToUTF16("text"),
    402                              0,
    403                              false));
    404   form.fields.push_back(
    405       webkit_glue::FormField(ASCIIToUTF16("Full name"),
    406                              ASCIIToUTF16("name"),
    407                              string16(),
    408                              ASCIIToUTF16("text"),
    409                              0,
    410                              false));
    411   form.fields.push_back(
    412       webkit_glue::FormField(ASCIIToUTF16("Company"),
    413                              ASCIIToUTF16("company"),
    414                              string16(),
    415                              ASCIIToUTF16("text"),
    416                              0,
    417                              false));
    418   form.fields.push_back(
    419       webkit_glue::FormField(ASCIIToUTF16("Address"),
    420                              ASCIIToUTF16("address"),
    421                              string16(),
    422                              ASCIIToUTF16("text"),
    423                              0,
    424                              false));
    425   form.fields.push_back(
    426       webkit_glue::FormField(ASCIIToUTF16("City"),
    427                              ASCIIToUTF16("city"),
    428                              string16(),
    429                              ASCIIToUTF16("text"),
    430                              0,
    431                              false));
    432   // TODO(jhawkins): Add state select control.
    433   form.fields.push_back(
    434       webkit_glue::FormField(ASCIIToUTF16("Zip Code"),
    435                              ASCIIToUTF16("Home.PostalCode"),
    436                              string16(),
    437                              ASCIIToUTF16("text"),
    438                              0,
    439                              false));
    440   // TODO(jhawkins): Phone number.
    441   form.fields.push_back(
    442       webkit_glue::FormField(string16(),
    443                              ASCIIToUTF16("Submit"),
    444                              ASCIIToUTF16("continue"),
    445                              ASCIIToUTF16("submit"),
    446                              0,
    447                              false));
    448   form_structure.reset(new FormStructure(form));
    449   form_structure->DetermineHeuristicTypes();
    450   EXPECT_TRUE(form_structure->IsAutofillable(true));
    451   ASSERT_EQ(7U, form_structure->field_count());
    452   ASSERT_EQ(6U, form_structure->autofill_count());
    453 
    454   // Email.
    455   EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(0)->heuristic_type());
    456   // Full name.
    457   EXPECT_EQ(NAME_FULL, form_structure->field(1)->heuristic_type());
    458   // Company
    459   EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
    460   // Address.
    461   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(3)->heuristic_type());
    462   // City.
    463   EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
    464   // Zip.
    465   EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(5)->heuristic_type());
    466   // Submit.
    467   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
    468 }
    469 
    470 // Tests a sequence of FormFields where only labels are supplied to heuristics
    471 // for matching.  This works because FormField labels are matched in the case
    472 // that input element ids (or |name| fields) are missing.
    473 TEST(FormStructureTest, HeuristicsLabelsOnly) {
    474   scoped_ptr<FormStructure> form_structure;
    475   FormData form;
    476 
    477   form.method = ASCIIToUTF16("post");
    478   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
    479                                                string16(),
    480                                                string16(),
    481                                                ASCIIToUTF16("text"),
    482                                                0,
    483                                                false));
    484   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Last Name"),
    485                                                string16(),
    486                                                string16(),
    487                                                ASCIIToUTF16("text"),
    488                                                0,
    489                                                false));
    490   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("EMail"),
    491                                                string16(),
    492                                                string16(),
    493                                                ASCIIToUTF16("text"),
    494                                                0,
    495                                                false));
    496   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Phone"),
    497                                                string16(),
    498                                                string16(),
    499                                                ASCIIToUTF16("text"),
    500                                                0,
    501                                                false));
    502   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Fax"),
    503                                                string16(),
    504                                                string16(),
    505                                                ASCIIToUTF16("text"),
    506                                                0,
    507                                                false));
    508   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
    509                                                string16(),
    510                                                string16(),
    511                                                ASCIIToUTF16("text"),
    512                                                0,
    513                                                false));
    514   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
    515                                                string16(),
    516                                                string16(),
    517                                                ASCIIToUTF16("text"),
    518                                                0,
    519                                                false));
    520   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Zip code"),
    521                                                string16(),
    522                                                string16(),
    523                                                ASCIIToUTF16("text"),
    524                                                0,
    525                                                false));
    526   form.fields.push_back(webkit_glue::FormField(string16(),
    527                                                ASCIIToUTF16("Submit"),
    528                                                string16(),
    529                                                ASCIIToUTF16("submit"),
    530                                                0,
    531                                                false));
    532   form_structure.reset(new FormStructure(form));
    533   form_structure->DetermineHeuristicTypes();
    534   EXPECT_TRUE(form_structure->IsAutofillable(true));
    535   ASSERT_EQ(9U, form_structure->field_count());
    536   ASSERT_EQ(8U, form_structure->autofill_count());
    537 
    538   // First name.
    539   EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
    540   // Last name.
    541   EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
    542   // Email.
    543   EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
    544   // Phone.
    545   EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
    546       form_structure->field(3)->heuristic_type());
    547   // Fax.
    548   EXPECT_EQ(PHONE_FAX_WHOLE_NUMBER, form_structure->field(4)->heuristic_type());
    549   // Address.
    550   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(5)->heuristic_type());
    551   // Address Line 2.
    552   EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(6)->heuristic_type());
    553   // Zip.
    554   EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(7)->heuristic_type());
    555   // Submit.
    556   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(8)->heuristic_type());
    557 }
    558 
    559 TEST(FormStructureTest, HeuristicsCreditCardInfo) {
    560   scoped_ptr<FormStructure> form_structure;
    561   FormData form;
    562 
    563   form.method = ASCIIToUTF16("post");
    564   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Name on Card"),
    565                                                ASCIIToUTF16("name on card"),
    566                                                string16(),
    567                                                ASCIIToUTF16("text"),
    568                                                0,
    569                                                false));
    570   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Card Number"),
    571                                                ASCIIToUTF16("card_number"),
    572                                                string16(),
    573                                                ASCIIToUTF16("text"),
    574                                                0,
    575                                                false));
    576   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Exp Month"),
    577                                                ASCIIToUTF16("ccmonth"),
    578                                                string16(),
    579                                                ASCIIToUTF16("text"),
    580                                                0,
    581                                                false));
    582   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Exp Year"),
    583                                                ASCIIToUTF16("ccyear"),
    584                                                string16(),
    585                                                ASCIIToUTF16("text"),
    586                                                0,
    587                                                false));
    588   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Verification"),
    589                                                ASCIIToUTF16("verification"),
    590                                                string16(),
    591                                                ASCIIToUTF16("text"),
    592                                                0,
    593                                                false));
    594   form.fields.push_back(webkit_glue::FormField(string16(),
    595                                                ASCIIToUTF16("Submit"),
    596                                                string16(),
    597                                                ASCIIToUTF16("submit"),
    598                                                0,
    599                                                false));
    600   form_structure.reset(new FormStructure(form));
    601   form_structure->DetermineHeuristicTypes();
    602   EXPECT_TRUE(form_structure->IsAutofillable(true));
    603   ASSERT_EQ(6U, form_structure->field_count());
    604   ASSERT_EQ(4U, form_structure->autofill_count());
    605 
    606   // Credit card name.
    607   EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
    608   // Credit card number.
    609   EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type());
    610   // Credit card expiration month.
    611   EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(2)->heuristic_type());
    612   // Credit card expiration year.
    613   EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
    614             form_structure->field(3)->heuristic_type());
    615   // We don't determine CVV.
    616   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(4)->heuristic_type());
    617   // Submit.
    618   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
    619 }
    620 
    621 TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
    622   scoped_ptr<FormStructure> form_structure;
    623   FormData form;
    624 
    625   form.method = ASCIIToUTF16("post");
    626   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Name on Card"),
    627                                                ASCIIToUTF16("name on card"),
    628                                                string16(),
    629                                                ASCIIToUTF16("text"),
    630                                                0,
    631                                                false));
    632   // This is not a field we know how to process.  But we should skip over it
    633   // and process the other fields in the card block.
    634   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Card Type"),
    635                                                ASCIIToUTF16("card_type"),
    636                                                string16(),
    637                                                ASCIIToUTF16("text"),
    638                                                0,
    639                                                false));
    640   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Card Number"),
    641                                                ASCIIToUTF16("card_number"),
    642                                                string16(),
    643                                                ASCIIToUTF16("text"),
    644                                                0,
    645                                                false));
    646   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Exp Month"),
    647                                                ASCIIToUTF16("ccmonth"),
    648                                                string16(),
    649                                                ASCIIToUTF16("text"),
    650                                                0,
    651                                                false));
    652   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Exp Year"),
    653                                                ASCIIToUTF16("ccyear"),
    654                                                string16(),
    655                                                ASCIIToUTF16("text"),
    656                                                0,
    657                                                false));
    658   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Verification"),
    659                                                ASCIIToUTF16("verification"),
    660                                                string16(),
    661                                                ASCIIToUTF16("text"),
    662                                                0,
    663                                                false));
    664   form.fields.push_back(webkit_glue::FormField(string16(),
    665                                                ASCIIToUTF16("Submit"),
    666                                                string16(),
    667                                                ASCIIToUTF16("submit"),
    668                                                0,
    669                                                false));
    670   form_structure.reset(new FormStructure(form));
    671   form_structure->DetermineHeuristicTypes();
    672   EXPECT_TRUE(form_structure->IsAutofillable(true));
    673   ASSERT_EQ(7U, form_structure->field_count());
    674   ASSERT_EQ(4U, form_structure->autofill_count());
    675 
    676   // Credit card name.
    677   EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
    678   // Credit card type.  This is an unknown type but related to the credit card.
    679   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
    680   // Credit card number.
    681   EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type());
    682   // Credit card expiration month.
    683   EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
    684   // Credit card expiration year.
    685   EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
    686             form_structure->field(4)->heuristic_type());
    687   // We don't determine CVV.
    688   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
    689   // Submit.
    690   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
    691 }
    692 
    693 TEST(FormStructureTest, ThreeAddressLines) {
    694   scoped_ptr<FormStructure> form_structure;
    695   FormData form;
    696 
    697   form.method = ASCIIToUTF16("post");
    698   form.fields.push_back(
    699       webkit_glue::FormField(ASCIIToUTF16("Address Line1"),
    700                              ASCIIToUTF16("Address"),
    701                              string16(),
    702                              ASCIIToUTF16("text"),
    703                              0,
    704                              false));
    705   form.fields.push_back(
    706       webkit_glue::FormField(ASCIIToUTF16("Address Line2"),
    707                              ASCIIToUTF16("Address"),
    708                              string16(),
    709                              ASCIIToUTF16("text"),
    710                              0,
    711                              false));
    712   form.fields.push_back(
    713       webkit_glue::FormField(ASCIIToUTF16("Address Line3"),
    714                              ASCIIToUTF16("Address"),
    715                              string16(),
    716                              ASCIIToUTF16("text"),
    717                              0,
    718                              false));
    719   form.fields.push_back(
    720       webkit_glue::FormField(ASCIIToUTF16("City"),
    721                              ASCIIToUTF16("city"),
    722                              string16(),
    723                              ASCIIToUTF16("text"),
    724                              0,
    725                              false));
    726   form_structure.reset(new FormStructure(form));
    727   form_structure->DetermineHeuristicTypes();
    728   EXPECT_TRUE(form_structure->IsAutofillable(true));
    729   ASSERT_EQ(4U, form_structure->field_count());
    730   ASSERT_EQ(3U, form_structure->autofill_count());
    731 
    732   // Address Line 1.
    733   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
    734   // Address Line 2.
    735   EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
    736   // Address Line 3.
    737   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
    738   // City.
    739   EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
    740 }
    741 
    742 // This test verifies that "addressLine1" and "addressLine2" matches heuristics.
    743 // This occured in https://www.gorillaclothing.com/.  http://crbug.com/52126.
    744 TEST(FormStructureTest, BillingAndShippingAddresses) {
    745   scoped_ptr<FormStructure> form_structure;
    746   FormData form;
    747 
    748   form.method = ASCIIToUTF16("post");
    749   form.fields.push_back(
    750       webkit_glue::FormField(ASCIIToUTF16("Address Line1"),
    751                              ASCIIToUTF16("shipping.address.addressLine1"),
    752                              string16(),
    753                              ASCIIToUTF16("text"),
    754                              0,
    755                              false));
    756   form.fields.push_back(
    757       webkit_glue::FormField(ASCIIToUTF16("Address Line2"),
    758                              ASCIIToUTF16("shipping.address.addressLine2"),
    759                              string16(),
    760                              ASCIIToUTF16("text"),
    761                              0,
    762                              false));
    763   form.fields.push_back(
    764       webkit_glue::FormField(ASCIIToUTF16("Address Line1"),
    765                              ASCIIToUTF16("billing.address.addressLine1"),
    766                              string16(),
    767                              ASCIIToUTF16("text"),
    768                              0,
    769                              false));
    770   form.fields.push_back(
    771       webkit_glue::FormField(ASCIIToUTF16("Address Line2"),
    772                              ASCIIToUTF16("billing.address.addressLine2"),
    773                              string16(),
    774                              ASCIIToUTF16("text"),
    775                              0,
    776                              false));
    777   form_structure.reset(new FormStructure(form));
    778   form_structure->DetermineHeuristicTypes();
    779   EXPECT_TRUE(form_structure->IsAutofillable(true));
    780   ASSERT_EQ(4U, form_structure->field_count());
    781   ASSERT_EQ(4U, form_structure->autofill_count());
    782 
    783   // Address Line 1.
    784   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
    785   // Address Line 2.
    786   EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
    787   // Address Line 1.
    788   EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(2)->heuristic_type());
    789   // Address Line 2.
    790   EXPECT_EQ(ADDRESS_BILLING_LINE2, form_structure->field(3)->heuristic_type());
    791 }
    792 
    793 
    794 // This example comes from expedia.com where they use a "Suite" label to
    795 // indicate a suite or apartment number.  We interpret this as address line 2.
    796 // And the following "Street address second line" we interpret as address line
    797 // 3 and discard.
    798 // See http://crbug.com/48197 for details.
    799 TEST(FormStructureTest, ThreeAddressLinesExpedia) {
    800   scoped_ptr<FormStructure> form_structure;
    801   FormData form;
    802 
    803   form.method = ASCIIToUTF16("post");
    804   form.fields.push_back(
    805       webkit_glue::FormField(ASCIIToUTF16("Street:"),
    806                              ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1"),
    807                              string16(),
    808                              ASCIIToUTF16("text"),
    809                              0,
    810                              false));
    811   form.fields.push_back(
    812       webkit_glue::FormField(ASCIIToUTF16("Suite or Apt:"),
    813                              ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap"),
    814                              string16(),
    815                              ASCIIToUTF16("text"),
    816                              0,
    817                              false));
    818   form.fields.push_back(
    819       webkit_glue::FormField(ASCIIToUTF16("Street address second line"),
    820                              ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads2"),
    821                              string16(),
    822                              ASCIIToUTF16("text"),
    823                              0,
    824                              false));
    825   form.fields.push_back(
    826       webkit_glue::FormField(ASCIIToUTF16("City:"),
    827                              ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adct"),
    828                              string16(),
    829                              ASCIIToUTF16("text"),
    830                              0,
    831                              false));
    832   form_structure.reset(new FormStructure(form));
    833   form_structure->DetermineHeuristicTypes();
    834   EXPECT_TRUE(form_structure->IsAutofillable(true));
    835   ASSERT_EQ(4U, form_structure->field_count());
    836   ASSERT_EQ(3U, form_structure->autofill_count());
    837 
    838   // Address Line 1.
    839   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
    840   // Suite / Apt.
    841   EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
    842   // Address Line 3.
    843   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
    844   // City.
    845   EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(3)->heuristic_type());
    846 }
    847 
    848 // This example comes from ebay.com where the word "suite" appears in the label
    849 // and the name "address2" clearly indicates that this is the address line 2.
    850 // See http://crbug.com/48197 for details.
    851 TEST(FormStructureTest, TwoAddressLinesEbay) {
    852   scoped_ptr<FormStructure> form_structure;
    853   FormData form;
    854 
    855   form.method = ASCIIToUTF16("post");
    856   form.fields.push_back(
    857       webkit_glue::FormField(ASCIIToUTF16("Address Line1"),
    858                              ASCIIToUTF16("address1"),
    859                              string16(),
    860                              ASCIIToUTF16("text"),
    861                              0,
    862                              false));
    863   form.fields.push_back(
    864       webkit_glue::FormField(ASCIIToUTF16("Floor number, suite number, etc"),
    865                              ASCIIToUTF16("address2"),
    866                              string16(),
    867                              ASCIIToUTF16("text"),
    868                              0,
    869                              false));
    870   form.fields.push_back(
    871       webkit_glue::FormField(ASCIIToUTF16("City"),
    872                              ASCIIToUTF16("city"),
    873                              string16(),
    874                              ASCIIToUTF16("text"),
    875                              0,
    876                              false));
    877   form_structure.reset(new FormStructure(form));
    878   form_structure->DetermineHeuristicTypes();
    879   EXPECT_TRUE(form_structure->IsAutofillable(true));
    880   ASSERT_EQ(3U, form_structure->field_count());
    881   ASSERT_EQ(3U, form_structure->autofill_count());
    882 
    883   // Address Line 1.
    884   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
    885   // Address Line 2.
    886   EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
    887   // City.
    888   EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(2)->heuristic_type());
    889 }
    890 
    891 TEST(FormStructureTest, HeuristicsStateWithProvince) {
    892   scoped_ptr<FormStructure> form_structure;
    893   FormData form;
    894 
    895   form.method = ASCIIToUTF16("post");
    896   form.fields.push_back(
    897       webkit_glue::FormField(ASCIIToUTF16("Address Line1"),
    898                              ASCIIToUTF16("Address"),
    899                              string16(),
    900                              ASCIIToUTF16("text"),
    901                              0,
    902                              false));
    903   form.fields.push_back(
    904       webkit_glue::FormField(ASCIIToUTF16("Address Line2"),
    905                              ASCIIToUTF16("Address"),
    906                              string16(),
    907                              ASCIIToUTF16("text"),
    908                              0,
    909                              false));
    910   form.fields.push_back(
    911       webkit_glue::FormField(ASCIIToUTF16("State/Province/Region"),
    912                              ASCIIToUTF16("State"),
    913                              string16(),
    914                              ASCIIToUTF16("text"),
    915                              0,
    916                              false));
    917   form_structure.reset(new FormStructure(form));
    918   form_structure->DetermineHeuristicTypes();
    919   EXPECT_TRUE(form_structure->IsAutofillable(true));
    920   ASSERT_EQ(3U, form_structure->field_count());
    921   ASSERT_EQ(3U, form_structure->autofill_count());
    922 
    923   // Address Line 1.
    924   EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(0)->heuristic_type());
    925   // Address Line 2.
    926   EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(1)->heuristic_type());
    927   // State.
    928   EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(2)->heuristic_type());
    929 }
    930 
    931 // This example comes from lego.com's checkout page.
    932 TEST(FormStructureTest, HeuristicsWithBilling) {
    933   scoped_ptr<FormStructure> form_structure;
    934   FormData form;
    935 
    936   form.method = ASCIIToUTF16("post");
    937   form.fields.push_back(
    938       webkit_glue::FormField(ASCIIToUTF16("First Name*:"),
    939                              ASCIIToUTF16("editBillingAddress$firstNameBox"),
    940                              string16(),
    941                              ASCIIToUTF16("text"),
    942                              0,
    943                              false));
    944   form.fields.push_back(
    945       webkit_glue::FormField(ASCIIToUTF16("Last Name*:"),
    946                              ASCIIToUTF16("editBillingAddress$lastNameBox"),
    947                              string16(),
    948                              ASCIIToUTF16("text"),
    949                              0,
    950                              false));
    951   form.fields.push_back(
    952       webkit_glue::FormField(ASCIIToUTF16("Company Name:"),
    953                              ASCIIToUTF16("editBillingAddress$companyBox"),
    954                              string16(),
    955                              ASCIIToUTF16("text"),
    956                              0,
    957                              false));
    958   form.fields.push_back(
    959       webkit_glue::FormField(ASCIIToUTF16("Address*:"),
    960                              ASCIIToUTF16("editBillingAddress$addressLine1Box"),
    961                              string16(),
    962                              ASCIIToUTF16("text"),
    963                              0,
    964                              false));
    965   form.fields.push_back(
    966       webkit_glue::FormField(ASCIIToUTF16("Apt/Suite :"),
    967                              ASCIIToUTF16("editBillingAddress$addressLine2Box"),
    968                              string16(),
    969                              ASCIIToUTF16("text"),
    970                              0,
    971                              false));
    972   form.fields.push_back(
    973       webkit_glue::FormField(ASCIIToUTF16("City*:"),
    974                              ASCIIToUTF16("editBillingAddress$cityBox"),
    975                              string16(),
    976                              ASCIIToUTF16("text"),
    977                              0,
    978                              false));
    979   form.fields.push_back(
    980       webkit_glue::FormField(ASCIIToUTF16("State/Province*:"),
    981                              ASCIIToUTF16("editBillingAddress$stateDropDown"),
    982                              string16(),
    983                              ASCIIToUTF16("text"),
    984                              0,
    985                              false));
    986   form.fields.push_back(
    987       webkit_glue::FormField(ASCIIToUTF16("Country*:"),
    988                              ASCIIToUTF16("editBillingAddress$countryDropDown"),
    989                              string16(),
    990                              ASCIIToUTF16("text"),
    991                              0,
    992                              false));
    993   form.fields.push_back(
    994       webkit_glue::FormField(ASCIIToUTF16("Postal Code*:"),
    995                              ASCIIToUTF16("editBillingAddress$zipCodeBox"),
    996                              string16(),
    997                              ASCIIToUTF16("text"),
    998                              0,
    999                              false));
   1000   form.fields.push_back(
   1001       webkit_glue::FormField(ASCIIToUTF16("Phone*:"),
   1002                              ASCIIToUTF16("editBillingAddress$phoneBox"),
   1003                              string16(),
   1004                              ASCIIToUTF16("text"),
   1005                              0,
   1006                              false));
   1007   form.fields.push_back(
   1008       webkit_glue::FormField(ASCIIToUTF16("Email Address*:"),
   1009                              ASCIIToUTF16("email$emailBox"),
   1010                              string16(),
   1011                              ASCIIToUTF16("text"),
   1012                              0,
   1013                              false));
   1014   form_structure.reset(new FormStructure(form));
   1015   form_structure->DetermineHeuristicTypes();
   1016   EXPECT_TRUE(form_structure->IsAutofillable(true));
   1017   ASSERT_EQ(11U, form_structure->field_count());
   1018   ASSERT_EQ(11U, form_structure->autofill_count());
   1019 
   1020   EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
   1021   EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
   1022   EXPECT_EQ(COMPANY_NAME, form_structure->field(2)->heuristic_type());
   1023   EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(3)->heuristic_type());
   1024   EXPECT_EQ(ADDRESS_BILLING_LINE2, form_structure->field(4)->heuristic_type());
   1025   EXPECT_EQ(ADDRESS_BILLING_CITY, form_structure->field(5)->heuristic_type());
   1026   EXPECT_EQ(ADDRESS_BILLING_STATE, form_structure->field(6)->heuristic_type());
   1027   EXPECT_EQ(ADDRESS_BILLING_COUNTRY,
   1028             form_structure->field(7)->heuristic_type());
   1029   EXPECT_EQ(ADDRESS_BILLING_ZIP, form_structure->field(8)->heuristic_type());
   1030   EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
   1031             form_structure->field(9)->heuristic_type());
   1032   EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(10)->heuristic_type());
   1033 }
   1034 
   1035 TEST(FormStructureTest, ThreePartPhoneNumber) {
   1036   scoped_ptr<FormStructure> form_structure;
   1037   FormData form;
   1038 
   1039   form.method = ASCIIToUTF16("post");
   1040   form.fields.push_back(
   1041       webkit_glue::FormField(ASCIIToUTF16("Phone:"),
   1042                              ASCIIToUTF16("dayphone1"),
   1043                              string16(),
   1044                              ASCIIToUTF16("text"),
   1045                              0,
   1046                              false));
   1047   form.fields.push_back(
   1048       webkit_glue::FormField(ASCIIToUTF16("-"),
   1049                              ASCIIToUTF16("dayphone2"),
   1050                              string16(),
   1051                              ASCIIToUTF16("text"),
   1052                              3,  // Size of prefix is 3.
   1053                              false));
   1054   form.fields.push_back(
   1055       webkit_glue::FormField(ASCIIToUTF16("-"),
   1056                              ASCIIToUTF16("dayphone3"),
   1057                              string16(),
   1058                              ASCIIToUTF16("text"),
   1059                              4,  // Size of suffix is 4. If unlimited size is
   1060                                  // passed, phone will be parsed as
   1061                                  // <country code> - <area code> - <phone>.
   1062                              false));
   1063   form.fields.push_back(
   1064       webkit_glue::FormField(ASCIIToUTF16("ext.:"),
   1065                              ASCIIToUTF16("dayphone4"),
   1066                              string16(),
   1067                              ASCIIToUTF16("text"),
   1068                              0,
   1069                              false));
   1070   form_structure.reset(new FormStructure(form));
   1071   form_structure->DetermineHeuristicTypes();
   1072   EXPECT_TRUE(form_structure->IsAutofillable(true));
   1073   ASSERT_EQ(4U, form_structure->field_count());
   1074   ASSERT_EQ(3U, form_structure->autofill_count());
   1075 
   1076   // Area code.
   1077   EXPECT_EQ(PHONE_HOME_CITY_CODE, form_structure->field(0)->heuristic_type());
   1078   // Phone number suffix.
   1079   EXPECT_EQ(PHONE_HOME_NUMBER,
   1080             form_structure->field(1)->heuristic_type());
   1081   // Phone number suffix.
   1082   EXPECT_EQ(PHONE_HOME_NUMBER,
   1083             form_structure->field(2)->heuristic_type());
   1084   // Unknown.
   1085   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
   1086 }
   1087 
   1088 TEST(FormStructureTest, HeuristicsInfernoCC) {
   1089   scoped_ptr<FormStructure> form_structure;
   1090   FormData form;
   1091   form.method = ASCIIToUTF16("post");
   1092   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Name on Card"),
   1093                                                ASCIIToUTF16("name_on_card"),
   1094                                                string16(),
   1095                                                ASCIIToUTF16("text"),
   1096                                                0,
   1097                                                false));
   1098   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
   1099                                                ASCIIToUTF16("billing_address"),
   1100                                                string16(),
   1101                                                ASCIIToUTF16("text"),
   1102                                                0,
   1103                                                false));
   1104   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Card Number"),
   1105                                                ASCIIToUTF16("card_number"),
   1106                                                string16(),
   1107                                                ASCIIToUTF16("text"),
   1108                                                0,
   1109                                                false));
   1110   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Expiration Date"),
   1111                                                ASCIIToUTF16("expiration_month"),
   1112                                                string16(),
   1113                                                ASCIIToUTF16("text"),
   1114                                                0,
   1115                                                false));
   1116   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Expiration Year"),
   1117                                                ASCIIToUTF16("expiration_year"),
   1118                                                string16(),
   1119                                                ASCIIToUTF16("text"),
   1120                                                0,
   1121                                                false));
   1122   form_structure.reset(new FormStructure(form));
   1123   form_structure->DetermineHeuristicTypes();
   1124   EXPECT_TRUE(form_structure->IsAutofillable(true));
   1125 
   1126   // Expect the correct number of fields.
   1127   ASSERT_EQ(5U, form_structure->field_count());
   1128   ASSERT_EQ(5U, form_structure->autofill_count());
   1129 
   1130   // Name on Card.
   1131   EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
   1132   // Address.
   1133   EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(1)->heuristic_type());
   1134   // Card Number.
   1135   EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type());
   1136   // Expiration Date.
   1137   EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
   1138   // Expiration Year.
   1139   EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
   1140             form_structure->field(4)->heuristic_type());
   1141 }
   1142 
   1143 TEST(FormStructureTest, CVCCodeClash) {
   1144   scoped_ptr<FormStructure> form_structure;
   1145   FormData form;
   1146   form.method = ASCIIToUTF16("post");
   1147   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Card number"),
   1148                                                ASCIIToUTF16("ccnumber"),
   1149                                                string16(),
   1150                                                ASCIIToUTF16("text"),
   1151                                                0,
   1152                                                false));
   1153   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First name"),
   1154                                                ASCIIToUTF16("first_name"),
   1155                                                string16(),
   1156                                                ASCIIToUTF16("text"),
   1157                                                0,
   1158                                                false));
   1159   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Last name"),
   1160                                                ASCIIToUTF16("last_name"),
   1161                                                string16(),
   1162                                                ASCIIToUTF16("text"),
   1163                                                0,
   1164                                                false));
   1165   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Expiration date"),
   1166                                                ASCIIToUTF16("ccexpiresmonth"),
   1167                                                string16(),
   1168                                                ASCIIToUTF16("text"),
   1169                                                0,
   1170                                                false));
   1171   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16(""),
   1172                                                ASCIIToUTF16("ccexpiresyear"),
   1173                                                string16(),
   1174                                                ASCIIToUTF16("text"),
   1175                                                0,
   1176                                                false));
   1177   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("cvc number"),
   1178                                                ASCIIToUTF16("csc"),
   1179                                                string16(),
   1180                                                ASCIIToUTF16("text"),
   1181                                                0,
   1182                                                false));
   1183   form_structure.reset(new FormStructure(form));
   1184   form_structure->DetermineHeuristicTypes();
   1185   EXPECT_TRUE(form_structure->IsAutofillable(true));
   1186 
   1187   // Expect the correct number of fields.
   1188   ASSERT_EQ(6U, form_structure->field_count());
   1189   ASSERT_EQ(4U, form_structure->autofill_count());
   1190 
   1191   // Card Number.
   1192   EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(0)->heuristic_type());
   1193   // First name, taken as name on card.
   1194   EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(1)->heuristic_type());
   1195   // Last name is not merged.
   1196   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
   1197   // Expiration Date.
   1198   EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type());
   1199   // Expiration Year.
   1200   EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
   1201             form_structure->field(4)->heuristic_type());
   1202   // CVC code should not match.
   1203   EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
   1204 }
   1205 
   1206 TEST(FormStructureTest, EncodeQueryRequest) {
   1207   FormData form;
   1208   form.method = ASCIIToUTF16("post");
   1209   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Name on Card"),
   1210                                                ASCIIToUTF16("name_on_card"),
   1211                                                string16(),
   1212                                                ASCIIToUTF16("text"),
   1213                                                0,
   1214                                                false));
   1215   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
   1216                                                ASCIIToUTF16("billing_address"),
   1217                                                string16(),
   1218                                                ASCIIToUTF16("text"),
   1219                                                0,
   1220                                                false));
   1221   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Card Number"),
   1222                                                ASCIIToUTF16("card_number"),
   1223                                                string16(),
   1224                                                ASCIIToUTF16("text"),
   1225                                                0,
   1226                                                false));
   1227   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Expiration Date"),
   1228                                                ASCIIToUTF16("expiration_month"),
   1229                                                string16(),
   1230                                                ASCIIToUTF16("text"),
   1231                                                0,
   1232                                                false));
   1233   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Expiration Year"),
   1234                                                ASCIIToUTF16("expiration_year"),
   1235                                                string16(),
   1236                                                ASCIIToUTF16("text"),
   1237                                                0,
   1238                                                false));
   1239   ScopedVector<FormStructure> forms;
   1240   forms.push_back(new FormStructure(form));
   1241   std::vector<std::string> encoded_signatures;
   1242   std::string encoded_xml;
   1243   const char * const kSignature1 = "11337937696949187602";
   1244   const char * const kResponse1 =
   1245       "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery "
   1246       "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
   1247       "signature=\"11337937696949187602\"><field signature=\"412125936\"/>"
   1248       "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
   1249       "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>"
   1250       "</autofillquery>";
   1251   ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms, &encoded_signatures,
   1252                                                 &encoded_xml));
   1253   ASSERT_EQ(1U, encoded_signatures.size());
   1254   EXPECT_EQ(kSignature1, encoded_signatures[0]);
   1255   EXPECT_EQ(kResponse1, encoded_xml);
   1256 
   1257   // Add the same form, only one will be encoded, so EncodeQueryRequest() should
   1258   // return the same data.
   1259   forms.push_back(new FormStructure(form));
   1260   ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms, &encoded_signatures,
   1261                                                 &encoded_xml));
   1262   ASSERT_EQ(1U, encoded_signatures.size());
   1263   EXPECT_EQ(kSignature1, encoded_signatures[0]);
   1264   EXPECT_EQ(kResponse1, encoded_xml);
   1265   // Add 5 address fields - this should be still a valid form.
   1266   for (size_t i = 0; i < 5; ++i) {
   1267     form.fields.push_back(
   1268         webkit_glue::FormField(ASCIIToUTF16("Address"),
   1269                                ASCIIToUTF16("address"),
   1270                                string16(),
   1271                                ASCIIToUTF16("text"),
   1272                                0,
   1273                                false));
   1274   }
   1275 
   1276   forms.push_back(new FormStructure(form));
   1277   ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms, &encoded_signatures,
   1278                                                 &encoded_xml));
   1279   ASSERT_EQ(2U, encoded_signatures.size());
   1280   EXPECT_EQ(kSignature1, encoded_signatures[0]);
   1281   const char * const kSignature2 = "8308881815906226214";
   1282   EXPECT_EQ(kSignature2, encoded_signatures[1]);
   1283   const char * const kResponse2 =
   1284       "<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillquery "
   1285       "clientversion=\"6.1.1715.1442/en (GGLL)\" accepts=\"e\"><form "
   1286       "signature=\"11337937696949187602\"><field signature=\"412125936\"/>"
   1287       "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
   1288       "<field signature=\"747221617\"/><field signature=\"4108155786\"/></form>"
   1289       "<form signature=\"8308881815906226214\"><field signature=\"412125936\"/>"
   1290       "<field signature=\"1917667676\"/><field signature=\"2226358947\"/>"
   1291       "<field signature=\"747221617\"/><field signature=\"4108155786\"/><field "
   1292       "signature=\"509334676\"/><field signature=\"509334676\"/><field "
   1293       "signature=\"509334676\"/><field signature=\"509334676\"/><field "
   1294       "signature=\"509334676\"/></form></autofillquery>";
   1295   EXPECT_EQ(kResponse2, encoded_xml);
   1296 
   1297   // Add 50 address fields - the form is not valid anymore, but previous ones
   1298   // are. The result should be the same as in previous test.
   1299   for (size_t i = 0; i < 50; ++i) {
   1300     form.fields.push_back(
   1301         webkit_glue::FormField(ASCIIToUTF16("Address"),
   1302                                ASCIIToUTF16("address"),
   1303                                string16(),
   1304                                ASCIIToUTF16("text"),
   1305                                0,
   1306                                false));
   1307   }
   1308 
   1309   forms.push_back(new FormStructure(form));
   1310   ASSERT_TRUE(FormStructure::EncodeQueryRequest(forms, &encoded_signatures,
   1311                                                 &encoded_xml));
   1312   ASSERT_EQ(2U, encoded_signatures.size());
   1313   EXPECT_EQ(kSignature1, encoded_signatures[0]);
   1314   EXPECT_EQ(kSignature2, encoded_signatures[1]);
   1315   EXPECT_EQ(kResponse2, encoded_xml);
   1316 
   1317   // Check that we fail if there are only bad form(s).
   1318   ScopedVector<FormStructure> bad_forms;
   1319   bad_forms.push_back(new FormStructure(form));
   1320   EXPECT_FALSE(FormStructure::EncodeQueryRequest(bad_forms, &encoded_signatures,
   1321                                                  &encoded_xml));
   1322   EXPECT_EQ(0U, encoded_signatures.size());
   1323   EXPECT_EQ("", encoded_xml);
   1324 }
   1325 
   1326 TEST(FormStructureTest, EncodeUploadRequest) {
   1327   scoped_ptr<FormStructure> form_structure;
   1328   std::vector<FieldTypeSet> possible_field_types;
   1329   FormData form;
   1330   form.method = ASCIIToUTF16("post");
   1331   form_structure.reset(new FormStructure(form));
   1332   form_structure->DetermineHeuristicTypes();
   1333   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
   1334                         ASCIIToUTF16("firstname"),
   1335                         string16(),
   1336                         ASCIIToUTF16("text"),
   1337                         0,
   1338                         false));
   1339   possible_field_types.push_back(FieldTypeSet());
   1340   possible_field_types.back().insert(NAME_FIRST);
   1341   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Last Name"),
   1342                         ASCIIToUTF16("lastname"),
   1343                         string16(),
   1344                         ASCIIToUTF16("text"),
   1345                         0,
   1346                         false));
   1347   possible_field_types.push_back(FieldTypeSet());
   1348   possible_field_types.back().insert(NAME_LAST);
   1349   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("EMail"),
   1350                         ASCIIToUTF16("email"),
   1351                         string16(),
   1352                         ASCIIToUTF16("email"),
   1353                         0,
   1354                         false));
   1355   possible_field_types.push_back(FieldTypeSet());
   1356   possible_field_types.back().insert(EMAIL_ADDRESS);
   1357   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Phone"),
   1358                         ASCIIToUTF16("phone"),
   1359                         string16(),
   1360                         ASCIIToUTF16("number"),
   1361                         0,
   1362                         false));
   1363   possible_field_types.push_back(FieldTypeSet());
   1364   possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
   1365   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Country"),
   1366                         ASCIIToUTF16("country"),
   1367                         string16(),
   1368                         ASCIIToUTF16("select-one"),
   1369                         0,
   1370                         false));
   1371   possible_field_types.push_back(FieldTypeSet());
   1372   possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
   1373   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Fax"),
   1374                         ASCIIToUTF16("fax"),
   1375                         string16(),
   1376                         ASCIIToUTF16("tel"),
   1377                         0,
   1378                         false));
   1379   possible_field_types.push_back(FieldTypeSet());
   1380   possible_field_types.back().insert(PHONE_FAX_WHOLE_NUMBER);
   1381   form_structure.reset(new FormStructure(form));
   1382 
   1383   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
   1384   for (size_t i = 0; i < form_structure->field_count(); ++i)
   1385     form_structure->set_possible_types(i, possible_field_types[i]);
   1386 
   1387   std::string encoded_xml;
   1388   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1389   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
   1390             "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
   1391             "formsignature=\"7641728017676399335\" autofillused=\"false\" "
   1392             "datapresent=\"1442008008\">"
   1393             "<field signature=\"3763331450\" autofilltype=\"3\"/>"
   1394             "<field signature=\"3494530716\" autofilltype=\"5\"/>"
   1395             "<field signature=\"1029417091\" autofilltype=\"9\"/>"
   1396             "<field signature=\"466116101\" autofilltype=\"14\"/>"
   1397             "<field signature=\"2799270304\" autofilltype=\"36\"/>"
   1398             "<field signature=\"1876771436\" autofilltype=\"24\"/>"
   1399             "</autofillupload>",
   1400             encoded_xml);
   1401   EXPECT_TRUE(form_structure->EncodeUploadRequest(true, &encoded_xml));
   1402   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
   1403             "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
   1404             "formsignature=\"7641728017676399335\" autofillused=\"true\" "
   1405             "datapresent=\"1442008008\">"
   1406             "<field signature=\"3763331450\" autofilltype=\"3\"/>"
   1407             "<field signature=\"3494530716\" autofilltype=\"5\"/>"
   1408             "<field signature=\"1029417091\" autofilltype=\"9\"/>"
   1409             "<field signature=\"466116101\" autofilltype=\"14\"/>"
   1410             "<field signature=\"2799270304\" autofilltype=\"36\"/>"
   1411             "<field signature=\"1876771436\" autofilltype=\"24\"/>"
   1412             "</autofillupload>",
   1413             encoded_xml);
   1414 
   1415   // Add 2 address fields - this should be still a valid form.
   1416   for (size_t i = 0; i < 2; ++i) {
   1417     form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
   1418                                                  ASCIIToUTF16("address"),
   1419                                                  string16(),
   1420                                                  ASCIIToUTF16("text"),
   1421                                                  0,
   1422                                                  false));
   1423     possible_field_types.push_back(FieldTypeSet());
   1424     possible_field_types.back().insert(ADDRESS_HOME_LINE1);
   1425     possible_field_types.back().insert(ADDRESS_HOME_LINE2);
   1426     possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
   1427     possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
   1428   }
   1429   form_structure.reset(new FormStructure(form));
   1430   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
   1431   for (size_t i = 0; i < form_structure->field_count(); ++i)
   1432     form_structure->set_possible_types(i, possible_field_types[i]);
   1433   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1434   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?>"
   1435             "<autofillupload clientversion=\"6.1.1715.1442/en (GGLL)\" "
   1436             "formsignature=\"12226592129574322128\" autofillused=\"false\" "
   1437             "datapresent=\"144200830e\">"
   1438             "<field signature=\"3763331450\" autofilltype=\"3\"/>"
   1439             "<field signature=\"3494530716\" autofilltype=\"5\"/>"
   1440             "<field signature=\"1029417091\" autofilltype=\"9\"/>"
   1441             "<field signature=\"466116101\" autofilltype=\"14\"/>"
   1442             "<field signature=\"2799270304\" autofilltype=\"36\"/>"
   1443             "<field signature=\"1876771436\" autofilltype=\"24\"/>"
   1444             "<field signature=\"509334676\" autofilltype=\"30\"/>"
   1445             "<field signature=\"509334676\" autofilltype=\"31\"/>"
   1446             "<field signature=\"509334676\" autofilltype=\"37\"/>"
   1447             "<field signature=\"509334676\" autofilltype=\"38\"/>"
   1448             "<field signature=\"509334676\" autofilltype=\"30\"/>"
   1449             "<field signature=\"509334676\" autofilltype=\"31\"/>"
   1450             "<field signature=\"509334676\" autofilltype=\"37\"/>"
   1451             "<field signature=\"509334676\" autofilltype=\"38\"/>"
   1452             "</autofillupload>",
   1453             encoded_xml);
   1454 
   1455   // Add 50 address fields - now the form is invalid, as it has too many fields.
   1456   for (size_t i = 0; i < 50; ++i) {
   1457     form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
   1458                                                  ASCIIToUTF16("address"),
   1459                                                  string16(),
   1460                                                  ASCIIToUTF16("text"),
   1461                                                  0,
   1462                                                  false));
   1463     possible_field_types.push_back(FieldTypeSet());
   1464     possible_field_types.back().insert(ADDRESS_HOME_LINE1);
   1465     possible_field_types.back().insert(ADDRESS_HOME_LINE2);
   1466     possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
   1467     possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
   1468   }
   1469   form_structure.reset(new FormStructure(form));
   1470   ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
   1471   for (size_t i = 0; i < form_structure->field_count(); ++i)
   1472     form_structure->set_possible_types(i, possible_field_types[i]);
   1473   EXPECT_FALSE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1474   EXPECT_EQ("", encoded_xml);
   1475 }
   1476 
   1477 TEST(FormStructureTest, CheckDataPresence) {
   1478   // Checks bits set in the datapresence field: for each type in the form
   1479   // relevant bit in datapresence has to be set.
   1480   scoped_ptr<FormStructure> form_structure;
   1481   std::vector<FieldTypeSet> possible_field_types;
   1482   FormData form;
   1483   form.method = ASCIIToUTF16("post");
   1484   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
   1485                         ASCIIToUTF16("first"),
   1486                         string16(),
   1487                         ASCIIToUTF16("text"),
   1488                         0,
   1489                         false));
   1490   possible_field_types.push_back(FieldTypeSet());
   1491   possible_field_types.back().insert(NAME_FIRST);
   1492   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Last Name"),
   1493                         ASCIIToUTF16("last"),
   1494                         string16(),
   1495                         ASCIIToUTF16("text"),
   1496                         0,
   1497                         false));
   1498   possible_field_types.push_back(FieldTypeSet());
   1499   possible_field_types.back().insert(NAME_LAST);
   1500   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("email"),
   1501                         ASCIIToUTF16("email"),
   1502                         string16(),
   1503                         ASCIIToUTF16("text"),
   1504                         0,
   1505                         false));
   1506   possible_field_types.push_back(FieldTypeSet());
   1507   possible_field_types.back().insert(EMAIL_ADDRESS);
   1508   form_structure.reset(new FormStructure(form));
   1509   for (size_t i = 0; i < form_structure->field_count(); ++i)
   1510     form_structure->set_possible_types(i, possible_field_types[i]);
   1511   std::string encoded_xml;
   1512   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1513   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillupload "
   1514             "clientversion=\"6.1.1715.1442/en (GGLL)\" formsignature=\""
   1515             "6402244543831589061\" autofillused=\"false\" "
   1516             "datapresent=\"1440\"><field signature=\"1089846351\" ",
   1517             encoded_xml.substr(0, 200));
   1518 
   1519   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
   1520                         ASCIIToUTF16("address"),
   1521                         string16(),
   1522                         ASCIIToUTF16("text"),
   1523                         0,
   1524                         false));
   1525   possible_field_types.push_back(FieldTypeSet());
   1526   possible_field_types.back().insert(ADDRESS_HOME_LINE1);
   1527   form_structure.reset(new FormStructure(form));
   1528   for (size_t i = 0; i < form_structure->field_count(); ++i)
   1529     form_structure->set_possible_types(i, possible_field_types[i]);
   1530   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1531   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillupload "
   1532             "clientversion=\"6.1.1715.1442/en (GGLL)\" formsignature=\""
   1533             "11817937699000629499\" autofillused=\"false\" "
   1534             "datapresent=\"14400002\"><field signature=\"1089846",
   1535             encoded_xml.substr(0, 200));
   1536 
   1537   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("F4"),
   1538                         ASCIIToUTF16("f4"),
   1539                         string16(),
   1540                         ASCIIToUTF16("text"),
   1541                         0,
   1542                         false));
   1543   possible_field_types.push_back(FieldTypeSet());
   1544   possible_field_types.back().insert(CREDIT_CARD_TYPE);
   1545   form_structure.reset(new FormStructure(form));
   1546   for (size_t i = 0; i < form_structure->field_count(); ++i)
   1547     form_structure->set_possible_types(i, possible_field_types[i]);
   1548   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1549   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillupload "
   1550             "clientversion=\"6.1.1715.1442/en (GGLL)\" formsignature=\""
   1551             "15126663683491865216\" autofillused=\"false\" "
   1552             "datapresent=\"1440000200000020\"><field signature=",
   1553             encoded_xml.substr(0, 200));
   1554 }
   1555 
   1556 TEST(FormStructureTest, CheckMultipleTypes) {
   1557   // Check that multiple types for the field are processed correctly, both in
   1558   // datapresence and in actual field data.
   1559   scoped_ptr<FormStructure> form_structure;
   1560   std::vector<FieldTypeSet> possible_field_types;
   1561   FormData form;
   1562   form.method = ASCIIToUTF16("post");
   1563   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("email"),
   1564                         ASCIIToUTF16("email"),
   1565                         string16(),
   1566                         ASCIIToUTF16("text"),
   1567                         0,
   1568                         false));
   1569   possible_field_types.push_back(FieldTypeSet());
   1570   possible_field_types.back().insert(EMAIL_ADDRESS);
   1571   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
   1572                         ASCIIToUTF16("first"),
   1573                         string16(),
   1574                         ASCIIToUTF16("text"),
   1575                         0,
   1576                         false));
   1577   possible_field_types.push_back(FieldTypeSet());
   1578   possible_field_types.back().insert(NAME_FIRST);
   1579   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Last Name"),
   1580                         ASCIIToUTF16("last"),
   1581                         string16(),
   1582                         ASCIIToUTF16("text"),
   1583                         0,
   1584                         false));
   1585   possible_field_types.push_back(FieldTypeSet());
   1586   possible_field_types.back().insert(NAME_LAST);
   1587   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"),
   1588                         ASCIIToUTF16("address"),
   1589                         string16(),
   1590                         ASCIIToUTF16("text"),
   1591                         0,
   1592                         false));
   1593   possible_field_types.push_back(FieldTypeSet());
   1594   possible_field_types.back().insert(ADDRESS_HOME_LINE1);
   1595   form_structure.reset(new FormStructure(form));
   1596   for (size_t i = 0; i < form_structure->field_count(); ++i)
   1597     form_structure->set_possible_types(i, possible_field_types[i]);
   1598   std::string encoded_xml;
   1599   // Now we matched both fields singularly.
   1600   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1601   // datapresent==14400002==00010100010000000000000000000010b set bits are:
   1602   // #3 == NAME_FIRST
   1603   // #5 == NAME_LAST
   1604   // #9 == EMAIL_ADDRESS
   1605   // #30 == ADDRESS_HOME_LINE1
   1606   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillupload "
   1607             "clientversion=\"6.1.1715.1442/en (GGLL)\" formsignature=\""
   1608             "18062476096658145866\" autofillused=\"false\" datapresent="
   1609             "\"14400002\"><field signature=\"420638584\" autofilltype="
   1610             "\"9\"/><field signature=\"1089846351\" autofilltype=\"3\"/><field "
   1611             "signature=\"2404144663\" autofilltype=\"5\"/><field signature="
   1612             "\"509334676\" autofilltype=\"30\"/></autofillupload>",
   1613             encoded_xml);
   1614   // Match third field as both first and last.
   1615   possible_field_types[2].insert(NAME_FIRST);
   1616   form_structure->set_possible_types(2, possible_field_types[2]);
   1617   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1618   // datapresent==14400002==00010100010000000000000000000010b set bits are:
   1619   // #3 == NAME_FIRST
   1620   // #5 == NAME_LAST
   1621   // #9 == EMAIL_ADDRESS
   1622   // #30 == ADDRESS_HOME_LINE1
   1623   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillupload "
   1624             "clientversion=\"6.1.1715.1442/en (GGLL)\" formsignature=\""
   1625             "18062476096658145866\" autofillused=\"false\" datapresent="
   1626             "\"14400002\"><field signature=\"420638584\" autofilltype="
   1627             "\"9\"/><field signature=\"1089846351\" autofilltype=\"3\"/><field "
   1628             "signature=\"2404144663\" autofilltype=\"3\"/><field "
   1629             "signature=\"2404144663\" autofilltype=\"5\"/><field signature="
   1630             "\"509334676\" autofilltype=\"30\"/></autofillupload>",
   1631             encoded_xml);
   1632   possible_field_types[3].insert(ADDRESS_BILLING_LINE1);
   1633   form_structure->set_possible_types(
   1634       form_structure->field_count() - 1,
   1635       possible_field_types[form_structure->field_count() - 1]);
   1636   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1637   // datapresent==1440000204==0001010001000000000000000000001000000100b set bits
   1638   // are:
   1639   // #3 == NAME_FIRST
   1640   // #5 == NAME_LAST
   1641   // #9 == EMAIL_ADDRESS
   1642   // #30 == ADDRESS_HOME_LINE1
   1643   // #37 == ADDRESS_BILLING_LINE1
   1644   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillupload "
   1645             "clientversion=\"6.1.1715.1442/en (GGLL)\" formsignature=\""
   1646             "18062476096658145866\" autofillused=\"false\" datapresent="
   1647             "\"1440000204\"><field signature=\"420638584\" autofilltype="
   1648             "\"9\"/><field signature=\"1089846351\" autofilltype=\"3\"/><field "
   1649             "signature=\"2404144663\" autofilltype=\"3\"/><field "
   1650             "signature=\"2404144663\" autofilltype=\"5\"/><field signature="
   1651             "\"509334676\" autofilltype=\"30\"/><field signature=\"509334676\" "
   1652             "autofilltype=\"37\"/></autofillupload>",
   1653             encoded_xml);
   1654   possible_field_types[3].clear();
   1655   possible_field_types[3].insert(ADDRESS_HOME_LINE1);
   1656   possible_field_types[3].insert(ADDRESS_BILLING_LINE2);
   1657   form_structure->set_possible_types(
   1658       form_structure->field_count() - 1,
   1659       possible_field_types[form_structure->field_count() - 1]);
   1660   EXPECT_TRUE(form_structure->EncodeUploadRequest(false, &encoded_xml));
   1661   // datapresent==1440000202==0001010001000000000000000000001000000010b set bits
   1662   // are:
   1663   // #3 == NAME_FIRST
   1664   // #5 == NAME_LAST
   1665   // #9 == EMAIL_ADDRESS
   1666   // #30 == ADDRESS_HOME_LINE1
   1667   // #38 == ADDRESS_BILLING_LINE2
   1668   EXPECT_EQ("<\?xml version=\"1.0\" encoding=\"UTF-8\"\?><autofillupload "
   1669             "clientversion=\"6.1.1715.1442/en (GGLL)\" formsignature=\""
   1670             "18062476096658145866\" autofillused=\"false\" datapresent="
   1671             "\"1440000202\"><field signature=\"420638584\" autofilltype="
   1672             "\"9\"/><field signature=\"1089846351\" autofilltype=\"3\"/><field "
   1673             "signature=\"2404144663\" autofilltype=\"3\"/><field "
   1674             "signature=\"2404144663\" autofilltype=\"5\"/><field signature="
   1675             "\"509334676\" autofilltype=\"30\"/><field signature=\"509334676\" "
   1676             "autofilltype=\"38\"/></autofillupload>",
   1677             encoded_xml);
   1678 }
   1679 
   1680 TEST(FormStructureTest, CheckFormSignature) {
   1681   // Check that form signature is created correctly.
   1682   scoped_ptr<FormStructure> form_structure;
   1683   FormData form;
   1684   form.method = ASCIIToUTF16("post");
   1685   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("email"),
   1686                         ASCIIToUTF16("email"),
   1687                         string16(),
   1688                         ASCIIToUTF16("text"),
   1689                         0,
   1690                         false));
   1691   form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"),
   1692                         ASCIIToUTF16("first"),
   1693                         string16(),
   1694                         ASCIIToUTF16("text"),
   1695                         0,
   1696                         false));
   1697   form_structure.reset(new FormStructure(form));
   1698 
   1699   EXPECT_EQ(FormStructureTest::Hash64Bit(
   1700       std::string("://&&email&first")),
   1701       form_structure->FormSignature());
   1702 
   1703   form.origin = GURL(std::string("http://www.facebook.com"));
   1704   form_structure.reset(new FormStructure(form));
   1705   EXPECT_EQ(FormStructureTest::Hash64Bit(
   1706       std::string("http://www.facebook.com&&email&first")),
   1707       form_structure->FormSignature());
   1708 
   1709   form.action = GURL(std::string("https://login.facebook.com/path"));
   1710   form_structure.reset(new FormStructure(form));
   1711   EXPECT_EQ(FormStructureTest::Hash64Bit(
   1712       std::string("https://login.facebook.com&&email&first")),
   1713       form_structure->FormSignature());
   1714 
   1715   form.name = ASCIIToUTF16("login_form");
   1716   form_structure.reset(new FormStructure(form));
   1717   EXPECT_EQ(FormStructureTest::Hash64Bit(
   1718       std::string("https://login.facebook.com&login_form&email&first")),
   1719       form_structure->FormSignature());
   1720 }
   1721 
   1722 }  // namespace
   1723