• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
operator <<(std::ostream & os,const FormData & form)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:
Hash64Bit(const std::string & str)44   static std::string Hash64Bit(const std::string& str) {
45     return FormStructure::Hash64Bit(str);
46   }
47 };
48 
49 namespace {
50 
TEST(FormStructureTest,FieldCount)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 
TEST(FormStructureTest,AutofillCount)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 
TEST(FormStructureTest,SourceURL)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 
TEST(FormStructureTest,IsAutofillable)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 
TEST(FormStructureTest,HeuristicsContactInfo)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 
TEST(FormStructureTest,HeuristicsSample8)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 
TEST(FormStructureTest,HeuristicsSample6)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.
TEST(FormStructureTest,HeuristicsLabelsOnly)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 
TEST(FormStructureTest,HeuristicsCreditCardInfo)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 
TEST(FormStructureTest,HeuristicsCreditCardInfoWithUnknownCardField)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 
TEST(FormStructureTest,ThreeAddressLines)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.
TEST(FormStructureTest,BillingAndShippingAddresses)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.
TEST(FormStructureTest,ThreeAddressLinesExpedia)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.
TEST(FormStructureTest,TwoAddressLinesEbay)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 
TEST(FormStructureTest,HeuristicsStateWithProvince)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.
TEST(FormStructureTest,HeuristicsWithBilling)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 
TEST(FormStructureTest,ThreePartPhoneNumber)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 
TEST(FormStructureTest,HeuristicsInfernoCC)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 
TEST(FormStructureTest,CVCCodeClash)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 
TEST(FormStructureTest,EncodeQueryRequest)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 
TEST(FormStructureTest,EncodeUploadRequest)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 
TEST(FormStructureTest,CheckDataPresence)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 
TEST(FormStructureTest,CheckMultipleTypes)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 
TEST(FormStructureTest,CheckFormSignature)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