Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(267)

Side by Side Diff: chrome/browser/autofill/form_structure_unittest.cc

Issue 11198048: [Autofill] Update the autocomplete types implementation to match the current HTML spec. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update AutofillFieldTest expectations Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/memory/scoped_ptr.h" 5 #include "base/memory/scoped_ptr.h"
6 #include "base/string_util.h" 6 #include "base/string_util.h"
7 #include "base/utf_string_conversions.h" 7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/autofill/form_structure.h" 8 #include "chrome/browser/autofill/form_structure.h"
9 #include "chrome/common/form_data.h" 9 #include "chrome/common/form_data.h"
10 #include "chrome/common/form_field_data.h" 10 #include "chrome/common/form_field_data.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 } 45 }
46 }; 46 };
47 47
48 TEST(FormStructureTest, FieldCount) { 48 TEST(FormStructureTest, FieldCount) {
49 FormData form; 49 FormData form;
50 form.method = ASCIIToUTF16("post"); 50 form.method = ASCIIToUTF16("post");
51 51
52 FormFieldData field; 52 FormFieldData field;
53 field.label = ASCIIToUTF16("username"); 53 field.label = ASCIIToUTF16("username");
54 field.name = ASCIIToUTF16("username"); 54 field.name = ASCIIToUTF16("username");
55 field.form_control_type = ASCIIToUTF16("text"); 55 field.form_control_type = "text";
56 form.fields.push_back(field); 56 form.fields.push_back(field);
57 57
58 field.label = ASCIIToUTF16("password"); 58 field.label = ASCIIToUTF16("password");
59 field.name = ASCIIToUTF16("password"); 59 field.name = ASCIIToUTF16("password");
60 field.form_control_type = ASCIIToUTF16("password"); 60 field.form_control_type = "password";
61 form.fields.push_back(field); 61 form.fields.push_back(field);
62 62
63 field.label = string16(); 63 field.label = string16();
64 field.name = ASCIIToUTF16("Submit"); 64 field.name = ASCIIToUTF16("Submit");
65 field.form_control_type = ASCIIToUTF16("submit"); 65 field.form_control_type = "submit";
66 form.fields.push_back(field); 66 form.fields.push_back(field);
67 67
68 FormStructure form_structure(form); 68 FormStructure form_structure(form);
69 69
70 // All fields are counted. 70 // All fields are counted.
71 EXPECT_EQ(3U, form_structure.field_count()); 71 EXPECT_EQ(3U, form_structure.field_count());
72 } 72 }
73 73
74 TEST(FormStructureTest, AutofillCount) { 74 TEST(FormStructureTest, AutofillCount) {
75 FormData form; 75 FormData form;
76 form.method = ASCIIToUTF16("post"); 76 form.method = ASCIIToUTF16("post");
77 77
78 FormFieldData field; 78 FormFieldData field;
79 field.label = ASCIIToUTF16("username"); 79 field.label = ASCIIToUTF16("username");
80 field.name = ASCIIToUTF16("username"); 80 field.name = ASCIIToUTF16("username");
81 field.form_control_type = ASCIIToUTF16("text"); 81 field.form_control_type = "text";
82 form.fields.push_back(field); 82 form.fields.push_back(field);
83 83
84 field.label = ASCIIToUTF16("password"); 84 field.label = ASCIIToUTF16("password");
85 field.name = ASCIIToUTF16("password"); 85 field.name = ASCIIToUTF16("password");
86 field.form_control_type = ASCIIToUTF16("password"); 86 field.form_control_type = "password";
87 form.fields.push_back(field); 87 form.fields.push_back(field);
88 88
89 field.label = ASCIIToUTF16("state"); 89 field.label = ASCIIToUTF16("state");
90 field.name = ASCIIToUTF16("state"); 90 field.name = ASCIIToUTF16("state");
91 field.form_control_type = ASCIIToUTF16("select-one"); 91 field.form_control_type = "select-one";
92 form.fields.push_back(field); 92 form.fields.push_back(field);
93 93
94 field.label = string16(); 94 field.label = string16();
95 field.name = ASCIIToUTF16("Submit"); 95 field.name = ASCIIToUTF16("Submit");
96 field.form_control_type = ASCIIToUTF16("submit"); 96 field.form_control_type = "submit";
97 form.fields.push_back(field); 97 form.fields.push_back(field);
98 98
99 FormStructure form_structure(form); 99 FormStructure form_structure(form);
100 form_structure.DetermineHeuristicTypes(); 100 form_structure.DetermineHeuristicTypes();
101 101
102 // Only text and select fields that are heuristically matched are counted. 102 // Only text and select fields that are heuristically matched are counted.
103 EXPECT_EQ(1U, form_structure.autofill_count()); 103 EXPECT_EQ(1U, form_structure.autofill_count());
104 } 104 }
105 105
106 TEST(FormStructureTest, SourceURL) { 106 TEST(FormStructureTest, SourceURL) {
107 FormData form; 107 FormData form;
108 form.origin = GURL("http://www.foo.com/"); 108 form.origin = GURL("http://www.foo.com/");
109 form.method = ASCIIToUTF16("post"); 109 form.method = ASCIIToUTF16("post");
110 FormStructure form_structure(form); 110 FormStructure form_structure(form);
111 111
112 EXPECT_EQ(form.origin, form_structure.source_url()); 112 EXPECT_EQ(form.origin, form_structure.source_url());
113 } 113 }
114 114
115 TEST(FormStructureTest, IsAutofillable) { 115 TEST(FormStructureTest, IsAutofillable) {
116 scoped_ptr<FormStructure> form_structure; 116 scoped_ptr<FormStructure> form_structure;
117 FormData form; 117 FormData form;
118 118
119 // We need at least three text fields to be auto-fillable. 119 // We need at least three text fields to be auto-fillable.
120 form.method = ASCIIToUTF16("post"); 120 form.method = ASCIIToUTF16("post");
121 121
122 FormFieldData field; 122 FormFieldData field;
123 field.label = ASCIIToUTF16("username"); 123 field.label = ASCIIToUTF16("username");
124 field.name = ASCIIToUTF16("username"); 124 field.name = ASCIIToUTF16("username");
125 field.form_control_type = ASCIIToUTF16("text"); 125 field.form_control_type = "text";
126 form.fields.push_back(field); 126 form.fields.push_back(field);
127 127
128 field.label = ASCIIToUTF16("password"); 128 field.label = ASCIIToUTF16("password");
129 field.name = ASCIIToUTF16("password"); 129 field.name = ASCIIToUTF16("password");
130 field.form_control_type = ASCIIToUTF16("password"); 130 field.form_control_type = "password";
131 form.fields.push_back(field); 131 form.fields.push_back(field);
132 132
133 field.label = string16(); 133 field.label = string16();
134 field.name = ASCIIToUTF16("Submit"); 134 field.name = ASCIIToUTF16("Submit");
135 field.form_control_type = ASCIIToUTF16("submit"); 135 field.form_control_type = "submit";
136 form.fields.push_back(field); 136 form.fields.push_back(field);
137 137
138 form_structure.reset(new FormStructure(form)); 138 form_structure.reset(new FormStructure(form));
139 form_structure->DetermineHeuristicTypes(); 139 form_structure->DetermineHeuristicTypes();
140 EXPECT_FALSE(form_structure->IsAutofillable(true)); 140 EXPECT_FALSE(form_structure->IsAutofillable(true));
141 141
142 // We now have three text fields, but only two auto-fillable fields. 142 // We now have three text fields, but only two auto-fillable fields.
143 field.label = ASCIIToUTF16("First Name"); 143 field.label = ASCIIToUTF16("First Name");
144 field.name = ASCIIToUTF16("firstname"); 144 field.name = ASCIIToUTF16("firstname");
145 field.form_control_type = ASCIIToUTF16("text"); 145 field.form_control_type = "text";
146 form.fields.push_back(field); 146 form.fields.push_back(field);
147 147
148 field.label = ASCIIToUTF16("Last Name"); 148 field.label = ASCIIToUTF16("Last Name");
149 field.name = ASCIIToUTF16("lastname"); 149 field.name = ASCIIToUTF16("lastname");
150 field.form_control_type = ASCIIToUTF16("text"); 150 field.form_control_type = "text";
151 form.fields.push_back(field); 151 form.fields.push_back(field);
152 152
153 form_structure.reset(new FormStructure(form)); 153 form_structure.reset(new FormStructure(form));
154 form_structure->DetermineHeuristicTypes(); 154 form_structure->DetermineHeuristicTypes();
155 EXPECT_FALSE(form_structure->IsAutofillable(true)); 155 EXPECT_FALSE(form_structure->IsAutofillable(true));
156 156
157 // We now have three auto-fillable fields. 157 // We now have three auto-fillable fields.
158 field.label = ASCIIToUTF16("Email"); 158 field.label = ASCIIToUTF16("Email");
159 field.name = ASCIIToUTF16("email"); 159 field.name = ASCIIToUTF16("email");
160 field.form_control_type = ASCIIToUTF16("email"); 160 field.form_control_type = "email";
161 form.fields.push_back(field); 161 form.fields.push_back(field);
162 162
163 form_structure.reset(new FormStructure(form)); 163 form_structure.reset(new FormStructure(form));
164 form_structure->DetermineHeuristicTypes(); 164 form_structure->DetermineHeuristicTypes();
165 EXPECT_TRUE(form_structure->IsAutofillable(true)); 165 EXPECT_TRUE(form_structure->IsAutofillable(true));
166 166
167 // The method must be 'post', though we can intentionally ignore this 167 // The method must be 'post', though we can intentionally ignore this
168 // criterion for the sake of providing a helpful warning message to the user. 168 // criterion for the sake of providing a helpful warning message to the user.
169 form.method = ASCIIToUTF16("get"); 169 form.method = ASCIIToUTF16("get");
170 form_structure.reset(new FormStructure(form)); 170 form_structure.reset(new FormStructure(form));
(...skipping 18 matching lines...) Expand all
189 TEST(FormStructureTest, ShouldBeParsed) { 189 TEST(FormStructureTest, ShouldBeParsed) {
190 scoped_ptr<FormStructure> form_structure; 190 scoped_ptr<FormStructure> form_structure;
191 FormData form; 191 FormData form;
192 192
193 // We need at least three text fields to be parseable. 193 // We need at least three text fields to be parseable.
194 form.method = ASCIIToUTF16("post"); 194 form.method = ASCIIToUTF16("post");
195 195
196 FormFieldData field; 196 FormFieldData field;
197 field.label = ASCIIToUTF16("username"); 197 field.label = ASCIIToUTF16("username");
198 field.name = ASCIIToUTF16("username"); 198 field.name = ASCIIToUTF16("username");
199 field.form_control_type = ASCIIToUTF16("text"); 199 field.form_control_type = "text";
200 form.fields.push_back(field); 200 form.fields.push_back(field);
201 201
202 form_structure.reset(new FormStructure(form)); 202 form_structure.reset(new FormStructure(form));
203 EXPECT_FALSE(form_structure->ShouldBeParsed(true)); 203 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
204 204
205 // We now have three text fields, though only two are auto-fillable. 205 // We now have three text fields, though only two are auto-fillable.
206 field.label = ASCIIToUTF16("First Name"); 206 field.label = ASCIIToUTF16("First Name");
207 field.name = ASCIIToUTF16("firstname"); 207 field.name = ASCIIToUTF16("firstname");
208 field.form_control_type = ASCIIToUTF16("text"); 208 field.form_control_type = "text";
209 form.fields.push_back(field); 209 form.fields.push_back(field);
210 210
211 field.label = ASCIIToUTF16("Last Name"); 211 field.label = ASCIIToUTF16("Last Name");
212 field.name = ASCIIToUTF16("lastname"); 212 field.name = ASCIIToUTF16("lastname");
213 field.form_control_type = ASCIIToUTF16("text"); 213 field.form_control_type = "text";
214 form.fields.push_back(field); 214 form.fields.push_back(field);
215 215
216 form_structure.reset(new FormStructure(form)); 216 form_structure.reset(new FormStructure(form));
217 EXPECT_TRUE(form_structure->ShouldBeParsed(true)); 217 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
218 218
219 // The method must be 'post', though we can intentionally ignore this 219 // The method must be 'post', though we can intentionally ignore this
220 // criterion for the sake of providing a helpful warning message to the user. 220 // criterion for the sake of providing a helpful warning message to the user.
221 form.method = ASCIIToUTF16("get"); 221 form.method = ASCIIToUTF16("get");
222 form_structure.reset(new FormStructure(form)); 222 form_structure.reset(new FormStructure(form));
223 EXPECT_FALSE(form_structure->IsAutofillable(true)); 223 EXPECT_FALSE(form_structure->IsAutofillable(true));
224 EXPECT_TRUE(form_structure->ShouldBeParsed(false)); 224 EXPECT_TRUE(form_structure->ShouldBeParsed(false));
225 225
226 // The target cannot include http(s)://*/search... 226 // The target cannot include http(s)://*/search...
227 form.method = ASCIIToUTF16("post"); 227 form.method = ASCIIToUTF16("post");
228 form.action = GURL("http://google.com/search?q=hello"); 228 form.action = GURL("http://google.com/search?q=hello");
229 form_structure.reset(new FormStructure(form)); 229 form_structure.reset(new FormStructure(form));
230 EXPECT_FALSE(form_structure->ShouldBeParsed(true)); 230 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
231 231
232 // But search can be in the URL. 232 // But search can be in the URL.
233 form.action = GURL("http://search.com/?q=hello"); 233 form.action = GURL("http://search.com/?q=hello");
234 form_structure.reset(new FormStructure(form)); 234 form_structure.reset(new FormStructure(form));
235 EXPECT_TRUE(form_structure->ShouldBeParsed(true)); 235 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
236 236
237 // The form need only have three fields, but at least one must be a text 237 // The form need only have three fields, but at least one must be a text
238 // field. 238 // field.
239 form.fields.clear(); 239 form.fields.clear();
240 240
241 field.label = ASCIIToUTF16("Email"); 241 field.label = ASCIIToUTF16("Email");
242 field.name = ASCIIToUTF16("email"); 242 field.name = ASCIIToUTF16("email");
243 field.form_control_type = ASCIIToUTF16("email"); 243 field.form_control_type = "email";
244 form.fields.push_back(field); 244 form.fields.push_back(field);
245 245
246 field.label = ASCIIToUTF16("State"); 246 field.label = ASCIIToUTF16("State");
247 field.name = ASCIIToUTF16("state"); 247 field.name = ASCIIToUTF16("state");
248 field.form_control_type = ASCIIToUTF16("select-one"); 248 field.form_control_type = "select-one";
249 form.fields.push_back(field); 249 form.fields.push_back(field);
250 250
251 field.label = ASCIIToUTF16("Country"); 251 field.label = ASCIIToUTF16("Country");
252 field.name = ASCIIToUTF16("country"); 252 field.name = ASCIIToUTF16("country");
253 field.form_control_type = ASCIIToUTF16("select-one"); 253 field.form_control_type = "select-one";
254 form.fields.push_back(field); 254 form.fields.push_back(field);
255 255
256 form_structure.reset(new FormStructure(form)); 256 form_structure.reset(new FormStructure(form));
257 EXPECT_TRUE(form_structure->ShouldBeParsed(true)); 257 EXPECT_TRUE(form_structure->ShouldBeParsed(true));
258 258
259 form.fields[0].form_control_type = ASCIIToUTF16("select-one"); 259 form.fields[0].form_control_type = "select-one";
260 form_structure.reset(new FormStructure(form)); 260 form_structure.reset(new FormStructure(form));
261 EXPECT_FALSE(form_structure->ShouldBeParsed(true)); 261 EXPECT_FALSE(form_structure->ShouldBeParsed(true));
262 } 262 }
263 263
264 TEST(FormStructureTest, HeuristicsContactInfo) { 264 TEST(FormStructureTest, HeuristicsContactInfo) {
265 scoped_ptr<FormStructure> form_structure; 265 scoped_ptr<FormStructure> form_structure;
266 FormData form; 266 FormData form;
267 form.method = ASCIIToUTF16("post"); 267 form.method = ASCIIToUTF16("post");
268 268
269 FormFieldData field; 269 FormFieldData field;
270 field.form_control_type = ASCIIToUTF16("text"); 270 field.form_control_type = "text";
271 271
272 field.label = ASCIIToUTF16("First Name"); 272 field.label = ASCIIToUTF16("First Name");
273 field.name = ASCIIToUTF16("firstname"); 273 field.name = ASCIIToUTF16("firstname");
274 form.fields.push_back(field); 274 form.fields.push_back(field);
275 275
276 field.label = ASCIIToUTF16("Last Name"); 276 field.label = ASCIIToUTF16("Last Name");
277 field.name = ASCIIToUTF16("lastname"); 277 field.name = ASCIIToUTF16("lastname");
278 form.fields.push_back(field); 278 form.fields.push_back(field);
279 279
280 field.label = ASCIIToUTF16("Email"); 280 field.label = ASCIIToUTF16("Email");
(...skipping 11 matching lines...) Expand all
292 field.label = ASCIIToUTF16("City"); 292 field.label = ASCIIToUTF16("City");
293 field.name = ASCIIToUTF16("city"); 293 field.name = ASCIIToUTF16("city");
294 form.fields.push_back(field); 294 form.fields.push_back(field);
295 295
296 field.label = ASCIIToUTF16("Zip code"); 296 field.label = ASCIIToUTF16("Zip code");
297 field.name = ASCIIToUTF16("zipcode"); 297 field.name = ASCIIToUTF16("zipcode");
298 form.fields.push_back(field); 298 form.fields.push_back(field);
299 299
300 field.label = string16(); 300 field.label = string16();
301 field.name = ASCIIToUTF16("Submit"); 301 field.name = ASCIIToUTF16("Submit");
302 field.form_control_type = ASCIIToUTF16("submit"); 302 field.form_control_type = "submit";
303 form.fields.push_back(field); 303 form.fields.push_back(field);
304 304
305 form_structure.reset(new FormStructure(form)); 305 form_structure.reset(new FormStructure(form));
306 form_structure->DetermineHeuristicTypes(); 306 form_structure->DetermineHeuristicTypes();
307 EXPECT_TRUE(form_structure->IsAutofillable(true)); 307 EXPECT_TRUE(form_structure->IsAutofillable(true));
308 308
309 // Expect the correct number of fields. 309 // Expect the correct number of fields.
310 ASSERT_EQ(8U, form_structure->field_count()); 310 ASSERT_EQ(8U, form_structure->field_count());
311 ASSERT_EQ(7U, form_structure->autofill_count()); 311 ASSERT_EQ(7U, form_structure->autofill_count());
312 312
313 // First name. 313 // First name.
314 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); 314 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
315 // Last name. 315 // Last name.
316 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); 316 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
317 // Email. 317 // Email.
318 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type()); 318 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
319 // Phone. 319 // Phone.
320 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, 320 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER,
321 form_structure->field(3)->heuristic_type()); 321 form_structure->field(3)->heuristic_type());
322 // Address. 322 // Address.
323 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type()); 323 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(4)->heuristic_type());
324 // City. 324 // City.
325 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type()); 325 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(5)->heuristic_type());
326 // Zip. 326 // Zip.
327 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type()); 327 EXPECT_EQ(ADDRESS_HOME_ZIP, form_structure->field(6)->heuristic_type());
328 // Submit. 328 // Submit.
329 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type()); 329 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
330 } 330 }
331 331
332 // Verify that we can correctly process the |autocompletetype| attribute. 332 // Verify that we can correctly process the |autocomplete| attribute.
333 TEST(FormStructureTest, HeuristicsAutocompletetype) { 333 TEST(FormStructureTest, HeuristicsAutocompleteAttribute) {
334 scoped_ptr<FormStructure> form_structure; 334 scoped_ptr<FormStructure> form_structure;
335 FormData form; 335 FormData form;
336 form.method = ASCIIToUTF16("post"); 336 form.method = ASCIIToUTF16("post");
337 337
338 FormFieldData field; 338 FormFieldData field;
339 field.form_control_type = ASCIIToUTF16("text"); 339 field.form_control_type = "text";
340 340
341 field.label = string16(); 341 field.label = string16();
342 field.name = ASCIIToUTF16("field1"); 342 field.name = ASCIIToUTF16("field1");
343 field.autocomplete_type = ASCIIToUTF16("given-name"); 343 field.autocomplete_attribute = "given-name";
344 form.fields.push_back(field); 344 form.fields.push_back(field);
345 345
346 field.label = string16(); 346 field.label = string16();
347 field.name = ASCIIToUTF16("field2"); 347 field.name = ASCIIToUTF16("field2");
348 field.autocomplete_type = ASCIIToUTF16("surname"); 348 field.autocomplete_attribute = "family-name";
349 form.fields.push_back(field); 349 form.fields.push_back(field);
350 350
351 field.label = string16(); 351 field.label = string16();
352 field.name = ASCIIToUTF16("field3"); 352 field.name = ASCIIToUTF16("field3");
353 field.autocomplete_type = ASCIIToUTF16("email"); 353 field.autocomplete_attribute = "email";
354 form.fields.push_back(field); 354 form.fields.push_back(field);
355 355
356 form_structure.reset(new FormStructure(form)); 356 form_structure.reset(new FormStructure(form));
357 form_structure->DetermineHeuristicTypes(); 357 form_structure->DetermineHeuristicTypes();
358 EXPECT_TRUE(form_structure->IsAutofillable(true)); 358 EXPECT_TRUE(form_structure->IsAutofillable(true));
359 359
360 // Expect the correct number of fields. 360 // Expect the correct number of fields.
361 ASSERT_EQ(3U, form_structure->field_count()); 361 ASSERT_EQ(3U, form_structure->field_count());
362 ASSERT_EQ(3U, form_structure->autofill_count()); 362 ASSERT_EQ(3U, form_structure->autofill_count());
363 363
364 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); 364 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
365 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); 365 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
366 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type()); 366 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
367 } 367 }
368 368
369 // Verify that we can correctly process the |autocompletetype| attribute for 369 // Verify that we can correctly process the 'autocomplete' attribute for phone
370 // phone number types (especially phone prefixes and suffixes). 370 // number types (especially phone prefixes and suffixes).
371 TEST(FormStructureTest, HeuristicsAutocompletetypePhones) { 371 TEST(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
372 scoped_ptr<FormStructure> form_structure; 372 scoped_ptr<FormStructure> form_structure;
373 FormData form; 373 FormData form;
374 form.method = ASCIIToUTF16("post"); 374 form.method = ASCIIToUTF16("post");
375 375
376 FormFieldData field; 376 FormFieldData field;
377 field.form_control_type = ASCIIToUTF16("text"); 377 field.form_control_type = "text";
378 378
379 field.label = string16(); 379 field.label = string16();
380 field.name = ASCIIToUTF16("field1"); 380 field.name = ASCIIToUTF16("field1");
381 field.autocomplete_type = ASCIIToUTF16("phone-local"); 381 field.autocomplete_attribute = "tel-local";
382 form.fields.push_back(field); 382 form.fields.push_back(field);
383 383
384 field.label = string16(); 384 field.label = string16();
385 field.name = ASCIIToUTF16("field2"); 385 field.name = ASCIIToUTF16("field2");
386 field.autocomplete_type = ASCIIToUTF16("phone-local-prefix"); 386 field.autocomplete_attribute = "tel-local-prefix";
387 form.fields.push_back(field); 387 form.fields.push_back(field);
388 388
389 field.label = string16(); 389 field.label = string16();
390 field.name = ASCIIToUTF16("field3"); 390 field.name = ASCIIToUTF16("field3");
391 field.autocomplete_type = ASCIIToUTF16("phone-local-suffix"); 391 field.autocomplete_attribute = "tel-local-suffix";
392 form.fields.push_back(field); 392 form.fields.push_back(field);
393 393
394 form_structure.reset(new FormStructure(form)); 394 form_structure.reset(new FormStructure(form));
395 form_structure->DetermineHeuristicTypes(); 395 form_structure->DetermineHeuristicTypes();
396 EXPECT_TRUE(form_structure->IsAutofillable(true)); 396 EXPECT_TRUE(form_structure->IsAutofillable(true));
397 397
398 // Expect the correct number of fields. 398 // Expect the correct number of fields.
399 ASSERT_EQ(3U, form_structure->field_count()); 399 ASSERT_EQ(3U, form_structure->field_count());
400 EXPECT_EQ(3U, form_structure->autofill_count()); 400 EXPECT_EQ(3U, form_structure->autofill_count());
401 401
402 EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(0)->heuristic_type()); 402 EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(0)->heuristic_type());
403 EXPECT_EQ(AutofillField::IGNORED, form_structure->field(0)->phone_part()); 403 EXPECT_EQ(AutofillField::IGNORED, form_structure->field(0)->phone_part());
404 EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(1)->heuristic_type()); 404 EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(1)->heuristic_type());
405 EXPECT_EQ(AutofillField::PHONE_PREFIX, 405 EXPECT_EQ(AutofillField::PHONE_PREFIX,
406 form_structure->field(1)->phone_part()); 406 form_structure->field(1)->phone_part());
407 EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(2)->heuristic_type()); 407 EXPECT_EQ(PHONE_HOME_NUMBER, form_structure->field(2)->heuristic_type());
408 EXPECT_EQ(AutofillField::PHONE_SUFFIX, 408 EXPECT_EQ(AutofillField::PHONE_SUFFIX,
409 form_structure->field(2)->phone_part()); 409 form_structure->field(2)->phone_part());
410 } 410 }
411 411
412 // If at least one field includes the |autocompletetype| attribute, we should 412 // If at least one field includes type hints in the 'autocomplete' attribute, we
413 // not try to apply any other heuristics. 413 // should not try to apply any other heuristics.
414 TEST(FormStructureTest, AutocompletetypeOverridesOtherHeuristics) { 414 TEST(FormStructureTest, AutocompleteAttributeOverridesOtherHeuristics) {
415 scoped_ptr<FormStructure> form_structure; 415 scoped_ptr<FormStructure> form_structure;
416 FormData form; 416 FormData form;
417 form.method = ASCIIToUTF16("post"); 417 form.method = ASCIIToUTF16("post");
418 418
419 // Start with a regular contact form. 419 // Start with a regular contact form.
420 FormFieldData field; 420 FormFieldData field;
421 field.form_control_type = ASCIIToUTF16("text"); 421 field.form_control_type = "text";
422 422
423 field.label = ASCIIToUTF16("First Name"); 423 field.label = ASCIIToUTF16("First Name");
424 field.name = ASCIIToUTF16("firstname"); 424 field.name = ASCIIToUTF16("firstname");
425 form.fields.push_back(field); 425 form.fields.push_back(field);
426 426
427 field.label = ASCIIToUTF16("Last Name"); 427 field.label = ASCIIToUTF16("Last Name");
428 field.name = ASCIIToUTF16("lastname"); 428 field.name = ASCIIToUTF16("lastname");
429 form.fields.push_back(field); 429 form.fields.push_back(field);
430 430
431 field.label = ASCIIToUTF16("Email"); 431 field.label = ASCIIToUTF16("Email");
432 field.name = ASCIIToUTF16("email"); 432 field.name = ASCIIToUTF16("email");
433 form.fields.push_back(field); 433 form.fields.push_back(field);
434 434
435 form_structure.reset(new FormStructure(form)); 435 form_structure.reset(new FormStructure(form));
436 form_structure->DetermineHeuristicTypes(); 436 form_structure->DetermineHeuristicTypes();
437 EXPECT_TRUE(form_structure->IsAutofillable(true)); 437 EXPECT_TRUE(form_structure->IsAutofillable(true));
438 EXPECT_TRUE(form_structure->ShouldBeCrowdsourced()); 438 EXPECT_TRUE(form_structure->ShouldBeCrowdsourced());
439 439
440 ASSERT_EQ(3U, form_structure->field_count()); 440 ASSERT_EQ(3U, form_structure->field_count());
441 ASSERT_EQ(3U, form_structure->autofill_count()); 441 ASSERT_EQ(3U, form_structure->autofill_count());
442 442
443 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); 443 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
444 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); 444 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type());
445 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type()); 445 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(2)->heuristic_type());
446 446
447 // Now update the first form field to include an 'autocompletetype' attribute. 447 // Now update the first form field to include an 'autocomplete' attribute.
448 form.fields.front().autocomplete_type = ASCIIToUTF16("x-other"); 448 form.fields.front().autocomplete_attribute = "x-other";
449 form_structure.reset(new FormStructure(form)); 449 form_structure.reset(new FormStructure(form));
450 form_structure->DetermineHeuristicTypes(); 450 form_structure->DetermineHeuristicTypes();
451 EXPECT_FALSE(form_structure->IsAutofillable(true)); 451 EXPECT_FALSE(form_structure->IsAutofillable(true));
452 EXPECT_FALSE(form_structure->ShouldBeCrowdsourced()); 452 EXPECT_FALSE(form_structure->ShouldBeCrowdsourced());
453 453
454 ASSERT_EQ(3U, form_structure->field_count()); 454 ASSERT_EQ(3U, form_structure->field_count());
455 ASSERT_EQ(0U, form_structure->autofill_count()); 455 ASSERT_EQ(0U, form_structure->autofill_count());
456 456
457 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type()); 457 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(0)->heuristic_type());
458 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type()); 458 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(1)->heuristic_type());
459 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type()); 459 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(2)->heuristic_type());
460 } 460 }
461 461
462 // Verify that we can correctly process sections listed in the |autocomplete| 462 // Verify that we can correctly process sections listed in the |autocomplete|
463 // attribute. 463 // attribute.
464 TEST(FormStructureTest, HeuristicsAutocompletetypeWithSections) { 464 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSections) {
465 scoped_ptr<FormStructure> form_structure;
466 FormData form; 465 FormData form;
467 form.method = ASCIIToUTF16("post"); 466 form.method = ASCIIToUTF16("post");
468 467
469 FormFieldData field; 468 FormFieldData field;
470 field.form_control_type = ASCIIToUTF16("text"); 469 field.form_control_type = "text";
471 470
472 // We expect "shipping" and "billing" to be the most common sections. 471 // Some fields will have no section specified. These fall into the default
473 field.label = string16(); 472 // section.
474 field.name = ASCIIToUTF16("field1"); 473 field.autocomplete_attribute = "email";
475 field.autocomplete_type = ASCIIToUTF16("section-shipping given-name");
476 form.fields.push_back(field);
477
478 // Some field will have no section specified. These fall into the default
479 // section, with an empty name.
480 field.label = string16();
481 field.name = ASCIIToUTF16("field2");
482 field.autocomplete_type = ASCIIToUTF16("surname");
483 form.fields.push_back(field); 474 form.fields.push_back(field);
484 475
485 // We allow arbitrary section names. 476 // We allow arbitrary section names.
486 field.label = string16(); 477 field.autocomplete_attribute = "section-foo email";
487 field.name = ASCIIToUTF16("field3");
488 field.autocomplete_type = ASCIIToUTF16("section-foo address-line1");
489 form.fields.push_back(field); 478 form.fields.push_back(field);
490 479
491 // Specifying "section-" is equivalent to not specifying a section. 480 // "shipping" and "billing" are special section tokens that don't require the
492 field.label = string16(); 481 // "section-" prefix.
493 field.name = ASCIIToUTF16("field4"); 482 field.autocomplete_attribute = "shipping email";
494 field.autocomplete_type = ASCIIToUTF16("section- address-line2"); 483 form.fields.push_back(field);
484 field.autocomplete_attribute = "billing email";
485 form.fields.push_back(field);
486
487 // "shipping" and "billing" can be combined with other section names.
488 field.autocomplete_attribute = "section-foo shipping email";
489 form.fields.push_back(field);
490 field.autocomplete_attribute = "section-foo billing email";
495 form.fields.push_back(field); 491 form.fields.push_back(field);
496 492
497 // We don't do anything clever to try to coalesce sections; it's up to site 493 // We don't do anything clever to try to coalesce sections; it's up to site
498 // authors to avoid typos. 494 // authors to avoid typos.
499 field.label = string16(); 495 field.autocomplete_attribute = "section--foo email";
500 field.name = ASCIIToUTF16("field5"); 496 form.fields.push_back(field);
501 field.autocomplete_type = ASCIIToUTF16("section--shipping locality"); 497
498 // "shipping email" and "section--shipping" email should be parsed as
499 // different sections. This is only an interesting test due to how we
500 // implement implicit section names from attributes like "shipping email"; see
501 // the implementation for more details.
502 field.autocomplete_attribute = "section--shipping email";
502 form.fields.push_back(field); 503 form.fields.push_back(field);
503 504
504 // Credit card fields are implicitly in a separate section from other fields. 505 // Credit card fields are implicitly in a separate section from other fields.
505 field.label = string16(); 506 field.autocomplete_attribute = "section-foo cc-number";
506 field.name = ASCIIToUTF16("field6");
507 field.autocomplete_type = ASCIIToUTF16("section-shipping cc-number");
508 form.fields.push_back(field); 507 form.fields.push_back(field);
509 508
510 form_structure.reset(new FormStructure(form)); 509 FormStructure form_structure(form);
511 form_structure->DetermineHeuristicTypes(); 510 form_structure.DetermineHeuristicTypes();
512 EXPECT_TRUE(form_structure->IsAutofillable(true)); 511 EXPECT_TRUE(form_structure.IsAutofillable(true));
513 512
514 // Expect the correct number of fields. 513 // Expect the correct number of fields.
515 ASSERT_EQ(6U, form_structure->field_count()); 514 ASSERT_EQ(9U, form_structure.field_count());
516 ASSERT_EQ(6U, form_structure->autofill_count()); 515 EXPECT_EQ(9U, form_structure.autofill_count());
517 516
518 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); 517 // All of the fields in this form should be parsed as belonging to different
519 EXPECT_EQ(ASCIIToUTF16("shipping-default"), 518 // sections.
520 form_structure->field(0)->section()); 519 std::set<std::string> section_names;
521 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); 520 for (size_t i = 0; i < 9; ++i) {
522 EXPECT_EQ(ASCIIToUTF16("-default"), form_structure->field(1)->section()); 521 section_names.insert(form_structure.field(i)->section());
523 EXPECT_EQ(ADDRESS_HOME_LINE1, form_structure->field(2)->heuristic_type()); 522 }
524 EXPECT_EQ(ASCIIToUTF16("foo-default"), form_structure->field(2)->section()); 523 EXPECT_EQ(9U, section_names.size());
525 EXPECT_EQ(ADDRESS_HOME_LINE2, form_structure->field(3)->heuristic_type());
526 EXPECT_EQ(ASCIIToUTF16("-default"), form_structure->field(3)->section());
527 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(4)->heuristic_type());
528 EXPECT_EQ(ASCIIToUTF16("-shipping-default"),
529 form_structure->field(4)->section());
530 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(5)->heuristic_type());
531 EXPECT_EQ(ASCIIToUTF16("shipping-cc"), form_structure->field(5)->section());
532 } 524 }
533 525
534 // Verify that we can correctly process fallback types listed in the 526 // Verify that we can correctly process a degenerate section listed in the
535 // |autocompletetype| attribute. 527 // |autocomplete| attribute.
536 TEST(FormStructureTest, HeuristicsAutocompletetypeWithFallbacks) { 528 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsDegenerate) {
537 scoped_ptr<FormStructure> form_structure;
538 FormData form; 529 FormData form;
539 form.method = ASCIIToUTF16("post"); 530 form.method = ASCIIToUTF16("post");
540 531
541 FormFieldData field; 532 FormFieldData field;
542 field.form_control_type = ASCIIToUTF16("text"); 533 field.form_control_type = "text";
543 534
544 // Skip over any sections and "x"-prefixed types. 535 // Some fields will have no section specified. These fall into the default
545 field.label = string16(); 536 // section.
546 field.name = ASCIIToUTF16("field1"); 537 field.autocomplete_attribute = "email";
547 field.autocomplete_type =
548 ASCIIToUTF16("section-full-name x-given-name-initial given-name");
549 form.fields.push_back(field); 538 form.fields.push_back(field);
550 539
551 // Stop processing once we see a known type. 540 // Specifying "section-" is equivalent to not specifying a section.
552 field.label = string16(); 541 field.autocomplete_attribute = "section- email";
553 field.name = ASCIIToUTF16("field2");
554 field.autocomplete_type = ASCIIToUTF16("section-full-name surname full-name");
555 form.fields.push_back(field); 542 form.fields.push_back(field);
556 543
557 // Skip over unknown types even if they are not prefixed with "x-". 544 // Invalid tokens should prevent us from setting a section name.
558 field.label = string16(); 545 field.autocomplete_attribute = "garbage section-foo email";
559 field.name = ASCIIToUTF16("field3"); 546 form.fields.push_back(field);
560 field.autocomplete_type = 547 field.autocomplete_attribute = "garbage section-bar email";
561 ASCIIToUTF16("section-shipping mobile-phone-full phone-full"); 548 form.fields.push_back(field);
549 field.autocomplete_attribute = "garbage shipping email";
550 form.fields.push_back(field);
551 field.autocomplete_attribute = "garbage billing email";
562 form.fields.push_back(field); 552 form.fields.push_back(field);
563 553
564 form_structure.reset(new FormStructure(form)); 554 FormStructure form_structure(form);
565 form_structure->DetermineHeuristicTypes(); 555 form_structure.DetermineHeuristicTypes();
566 EXPECT_TRUE(form_structure->IsAutofillable(true));
567 556
568 // Expect the correct number of fields. 557 // Expect the correct number of fields.
569 ASSERT_EQ(3U, form_structure->field_count()); 558 ASSERT_EQ(6U, form_structure.field_count());
570 ASSERT_EQ(3U, form_structure->autofill_count()); 559 EXPECT_EQ(2U, form_structure.autofill_count());
571 560
572 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); 561 // All of the fields in this form should be parsed as belonging to the same
573 EXPECT_EQ(ASCIIToUTF16("full-name-default"), 562 // section.
574 form_structure->field(0)->section()); 563 std::set<std::string> section_names;
575 EXPECT_EQ(NAME_LAST, form_structure->field(1)->heuristic_type()); 564 for (size_t i = 0; i < 6; ++i) {
576 EXPECT_EQ(ASCIIToUTF16("full-name-default"), 565 section_names.insert(form_structure.field(i)->section());
577 form_structure->field(1)->section()); 566 }
578 EXPECT_EQ(PHONE_HOME_WHOLE_NUMBER, 567 EXPECT_EQ(1U, section_names.size());
579 form_structure->field(2)->heuristic_type()); 568 }
580 EXPECT_EQ(ASCIIToUTF16("shipping-default"), 569
581 form_structure->field(2)->section()); 570 // Verify that we can correctly process repeated sections listed in the
571 // |autocomplete| attribute.
572 TEST(FormStructureTest, HeuristicsAutocompleteAttributeWithSectionsRepeated) {
573 FormData form;
574 form.method = ASCIIToUTF16("post");
575
576 FormFieldData field;
577 field.form_control_type = "text";
578
579 field.autocomplete_attribute = "section-foo email";
580 form.fields.push_back(field);
581 field.autocomplete_attribute = "section-foo street-address";
582 form.fields.push_back(field);
583
584 FormStructure form_structure(form);
585 form_structure.DetermineHeuristicTypes();
586
587 // Expect the correct number of fields.
588 ASSERT_EQ(2U, form_structure.field_count());
589 EXPECT_EQ(2U, form_structure.autofill_count());
590
591 // All of the fields in this form should be parsed as belonging to the same
592 // section.
593 std::set<std::string> section_names;
594 for (size_t i = 0; i < 2; ++i) {
595 section_names.insert(form_structure.field(i)->section());
596 }
597 EXPECT_EQ(1U, section_names.size());
598 }
599
600 // Verify that we do not override the author-specified sections from a form with
601 // local heuristics.
602 TEST(FormStructureTest, HeuristicsDontOverrideAutocompleteAttributeSections) {
603 FormData form;
604 form.method = ASCIIToUTF16("post");
605
606 FormFieldData field;
607 field.form_control_type = "text";
608
609 field.name = ASCIIToUTF16("one");
610 field.autocomplete_attribute = "street-address";
611 form.fields.push_back(field);
612 field.name = string16();
613 field.autocomplete_attribute = "section-foo email";
614 form.fields.push_back(field);
615 field.name = string16();
616 field.autocomplete_attribute = "name";
617 form.fields.push_back(field);
618 field.name = ASCIIToUTF16("two");
619 field.autocomplete_attribute = "street-address";
620 form.fields.push_back(field);
621
622 FormStructure form_structure(form);
623 form_structure.DetermineHeuristicTypes();
624
625 // Expect the correct number of fields.
626 ASSERT_EQ(4U, form_structure.field_count());
627 EXPECT_EQ(4U, form_structure.autofill_count());
628
629 // Normally, the two separate address fields would cause us to detect two
630 // separate sections; but because there is an author-specified section in this
631 // form, we do not apply these usual heuristics.
632 EXPECT_EQ(ASCIIToUTF16("one"), form_structure.field(0)->name);
633 EXPECT_EQ(ASCIIToUTF16("two"), form_structure.field(3)->name);
634 EXPECT_EQ(form_structure.field(0)->section(),
635 form_structure.field(3)->section());
582 } 636 }
583 637
584 TEST(FormStructureTest, HeuristicsSample8) { 638 TEST(FormStructureTest, HeuristicsSample8) {
585 scoped_ptr<FormStructure> form_structure; 639 scoped_ptr<FormStructure> form_structure;
586 FormData form; 640 FormData form;
587 form.method = ASCIIToUTF16("post"); 641 form.method = ASCIIToUTF16("post");
588 642
589 FormFieldData field; 643 FormFieldData field;
590 field.form_control_type = ASCIIToUTF16("text"); 644 field.form_control_type = "text";
591 645
592 field.label = ASCIIToUTF16("Your First Name:"); 646 field.label = ASCIIToUTF16("Your First Name:");
593 field.name = ASCIIToUTF16("bill.first"); 647 field.name = ASCIIToUTF16("bill.first");
594 form.fields.push_back(field); 648 form.fields.push_back(field);
595 649
596 field.label = ASCIIToUTF16("Your Last Name:"); 650 field.label = ASCIIToUTF16("Your Last Name:");
597 field.name = ASCIIToUTF16("bill.last"); 651 field.name = ASCIIToUTF16("bill.last");
598 form.fields.push_back(field); 652 form.fields.push_back(field);
599 653
600 field.label = ASCIIToUTF16("Street Address Line 1:"); 654 field.label = ASCIIToUTF16("Street Address Line 1:");
(...skipping 19 matching lines...) Expand all
620 field.label = ASCIIToUTF16("Country:"); 674 field.label = ASCIIToUTF16("Country:");
621 field.name = ASCIIToUTF16("bill.country"); 675 field.name = ASCIIToUTF16("bill.country");
622 form.fields.push_back(field); 676 form.fields.push_back(field);
623 677
624 field.label = ASCIIToUTF16("Phone Number:"); 678 field.label = ASCIIToUTF16("Phone Number:");
625 field.name = ASCIIToUTF16("BillTo.Phone"); 679 field.name = ASCIIToUTF16("BillTo.Phone");
626 form.fields.push_back(field); 680 form.fields.push_back(field);
627 681
628 field.label = string16(); 682 field.label = string16();
629 field.name = ASCIIToUTF16("Submit"); 683 field.name = ASCIIToUTF16("Submit");
630 field.form_control_type = ASCIIToUTF16("submit"); 684 field.form_control_type = "submit";
631 form.fields.push_back(field); 685 form.fields.push_back(field);
632 686
633 form_structure.reset(new FormStructure(form)); 687 form_structure.reset(new FormStructure(form));
634 form_structure->DetermineHeuristicTypes(); 688 form_structure->DetermineHeuristicTypes();
635 EXPECT_TRUE(form_structure->IsAutofillable(true)); 689 EXPECT_TRUE(form_structure->IsAutofillable(true));
636 ASSERT_EQ(10U, form_structure->field_count()); 690 ASSERT_EQ(10U, form_structure->field_count());
637 ASSERT_EQ(9U, form_structure->autofill_count()); 691 ASSERT_EQ(9U, form_structure->autofill_count());
638 692
639 // First name. 693 // First name.
640 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); 694 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
(...skipping 18 matching lines...) Expand all
659 // Submit. 713 // Submit.
660 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type()); 714 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type());
661 } 715 }
662 716
663 TEST(FormStructureTest, HeuristicsSample6) { 717 TEST(FormStructureTest, HeuristicsSample6) {
664 scoped_ptr<FormStructure> form_structure; 718 scoped_ptr<FormStructure> form_structure;
665 FormData form; 719 FormData form;
666 form.method = ASCIIToUTF16("post"); 720 form.method = ASCIIToUTF16("post");
667 721
668 FormFieldData field; 722 FormFieldData field;
669 field.form_control_type = ASCIIToUTF16("text"); 723 field.form_control_type = "text";
670 724
671 field.label = ASCIIToUTF16("E-mail address"); 725 field.label = ASCIIToUTF16("E-mail address");
672 field.name = ASCIIToUTF16("email"); 726 field.name = ASCIIToUTF16("email");
673 form.fields.push_back(field); 727 form.fields.push_back(field);
674 728
675 field.label = ASCIIToUTF16("Full name"); 729 field.label = ASCIIToUTF16("Full name");
676 field.name = ASCIIToUTF16("name"); 730 field.name = ASCIIToUTF16("name");
677 form.fields.push_back(field); 731 form.fields.push_back(field);
678 732
679 field.label = ASCIIToUTF16("Company"); 733 field.label = ASCIIToUTF16("Company");
680 field.name = ASCIIToUTF16("company"); 734 field.name = ASCIIToUTF16("company");
681 form.fields.push_back(field); 735 form.fields.push_back(field);
682 736
683 field.label = ASCIIToUTF16("Address"); 737 field.label = ASCIIToUTF16("Address");
684 field.name = ASCIIToUTF16("address"); 738 field.name = ASCIIToUTF16("address");
685 form.fields.push_back(field); 739 form.fields.push_back(field);
686 740
687 field.label = ASCIIToUTF16("City"); 741 field.label = ASCIIToUTF16("City");
688 field.name = ASCIIToUTF16("city"); 742 field.name = ASCIIToUTF16("city");
689 form.fields.push_back(field); 743 form.fields.push_back(field);
690 744
691 field.label = ASCIIToUTF16("Zip Code"); 745 field.label = ASCIIToUTF16("Zip Code");
692 field.name = ASCIIToUTF16("Home.PostalCode"); 746 field.name = ASCIIToUTF16("Home.PostalCode");
693 form.fields.push_back(field); 747 form.fields.push_back(field);
694 748
695 field.label = string16(); 749 field.label = string16();
696 field.name = ASCIIToUTF16("Submit"); 750 field.name = ASCIIToUTF16("Submit");
697 field.value = ASCIIToUTF16("continue"); 751 field.value = ASCIIToUTF16("continue");
698 field.form_control_type = ASCIIToUTF16("submit"); 752 field.form_control_type = "submit";
699 form.fields.push_back(field); 753 form.fields.push_back(field);
700 754
701 form_structure.reset(new FormStructure(form)); 755 form_structure.reset(new FormStructure(form));
702 form_structure->DetermineHeuristicTypes(); 756 form_structure->DetermineHeuristicTypes();
703 EXPECT_TRUE(form_structure->IsAutofillable(true)); 757 EXPECT_TRUE(form_structure->IsAutofillable(true));
704 ASSERT_EQ(7U, form_structure->field_count()); 758 ASSERT_EQ(7U, form_structure->field_count());
705 ASSERT_EQ(6U, form_structure->autofill_count()); 759 ASSERT_EQ(6U, form_structure->autofill_count());
706 760
707 // Email. 761 // Email.
708 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(0)->heuristic_type()); 762 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(0)->heuristic_type());
(...skipping 13 matching lines...) Expand all
722 776
723 // Tests a sequence of FormFields where only labels are supplied to heuristics 777 // Tests a sequence of FormFields where only labels are supplied to heuristics
724 // for matching. This works because FormFieldData labels are matched in the 778 // for matching. This works because FormFieldData labels are matched in the
725 // case that input element ids (or |name| fields) are missing. 779 // case that input element ids (or |name| fields) are missing.
726 TEST(FormStructureTest, HeuristicsLabelsOnly) { 780 TEST(FormStructureTest, HeuristicsLabelsOnly) {
727 scoped_ptr<FormStructure> form_structure; 781 scoped_ptr<FormStructure> form_structure;
728 FormData form; 782 FormData form;
729 form.method = ASCIIToUTF16("post"); 783 form.method = ASCIIToUTF16("post");
730 784
731 FormFieldData field; 785 FormFieldData field;
732 field.form_control_type = ASCIIToUTF16("text"); 786 field.form_control_type = "text";
733 787
734 field.label = ASCIIToUTF16("First Name"); 788 field.label = ASCIIToUTF16("First Name");
735 field.name = string16(); 789 field.name = string16();
736 form.fields.push_back(field); 790 form.fields.push_back(field);
737 791
738 field.label = ASCIIToUTF16("Last Name"); 792 field.label = ASCIIToUTF16("Last Name");
739 field.name = string16(); 793 field.name = string16();
740 form.fields.push_back(field); 794 form.fields.push_back(field);
741 795
742 field.label = ASCIIToUTF16("Email"); 796 field.label = ASCIIToUTF16("Email");
(...skipping 11 matching lines...) Expand all
754 field.label = ASCIIToUTF16("Address"); 808 field.label = ASCIIToUTF16("Address");
755 field.name = string16(); 809 field.name = string16();
756 form.fields.push_back(field); 810 form.fields.push_back(field);
757 811
758 field.label = ASCIIToUTF16("Zip code"); 812 field.label = ASCIIToUTF16("Zip code");
759 field.name = string16(); 813 field.name = string16();
760 form.fields.push_back(field); 814 form.fields.push_back(field);
761 815
762 field.label = string16(); 816 field.label = string16();
763 field.name = ASCIIToUTF16("Submit"); 817 field.name = ASCIIToUTF16("Submit");
764 field.form_control_type = ASCIIToUTF16("submit"); 818 field.form_control_type = "submit";
765 form.fields.push_back(field); 819 form.fields.push_back(field);
766 820
767 form_structure.reset(new FormStructure(form)); 821 form_structure.reset(new FormStructure(form));
768 form_structure->DetermineHeuristicTypes(); 822 form_structure->DetermineHeuristicTypes();
769 EXPECT_TRUE(form_structure->IsAutofillable(true)); 823 EXPECT_TRUE(form_structure->IsAutofillable(true));
770 ASSERT_EQ(8U, form_structure->field_count()); 824 ASSERT_EQ(8U, form_structure->field_count());
771 ASSERT_EQ(7U, form_structure->autofill_count()); 825 ASSERT_EQ(7U, form_structure->autofill_count());
772 826
773 // First name. 827 // First name.
774 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type()); 828 EXPECT_EQ(NAME_FIRST, form_structure->field(0)->heuristic_type());
(...skipping 13 matching lines...) Expand all
788 // Submit. 842 // Submit.
789 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type()); 843 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(7)->heuristic_type());
790 } 844 }
791 845
792 TEST(FormStructureTest, HeuristicsCreditCardInfo) { 846 TEST(FormStructureTest, HeuristicsCreditCardInfo) {
793 scoped_ptr<FormStructure> form_structure; 847 scoped_ptr<FormStructure> form_structure;
794 FormData form; 848 FormData form;
795 form.method = ASCIIToUTF16("post"); 849 form.method = ASCIIToUTF16("post");
796 850
797 FormFieldData field; 851 FormFieldData field;
798 field.form_control_type = ASCIIToUTF16("text"); 852 field.form_control_type = "text";
799 853
800 field.label = ASCIIToUTF16("Name on Card"); 854 field.label = ASCIIToUTF16("Name on Card");
801 field.name = ASCIIToUTF16("name_on_card"); 855 field.name = ASCIIToUTF16("name_on_card");
802 form.fields.push_back(field); 856 form.fields.push_back(field);
803 857
804 field.label = ASCIIToUTF16("Card Number"); 858 field.label = ASCIIToUTF16("Card Number");
805 field.name = ASCIIToUTF16("card_number"); 859 field.name = ASCIIToUTF16("card_number");
806 form.fields.push_back(field); 860 form.fields.push_back(field);
807 861
808 field.label = ASCIIToUTF16("Exp Month"); 862 field.label = ASCIIToUTF16("Exp Month");
809 field.name = ASCIIToUTF16("ccmonth"); 863 field.name = ASCIIToUTF16("ccmonth");
810 form.fields.push_back(field); 864 form.fields.push_back(field);
811 865
812 field.label = ASCIIToUTF16("Exp Year"); 866 field.label = ASCIIToUTF16("Exp Year");
813 field.name = ASCIIToUTF16("ccyear"); 867 field.name = ASCIIToUTF16("ccyear");
814 form.fields.push_back(field); 868 form.fields.push_back(field);
815 869
816 field.label = ASCIIToUTF16("Verification"); 870 field.label = ASCIIToUTF16("Verification");
817 field.name = ASCIIToUTF16("verification"); 871 field.name = ASCIIToUTF16("verification");
818 form.fields.push_back(field); 872 form.fields.push_back(field);
819 873
820 field.label = string16(); 874 field.label = string16();
821 field.name = ASCIIToUTF16("Submit"); 875 field.name = ASCIIToUTF16("Submit");
822 field.form_control_type = ASCIIToUTF16("submit"); 876 field.form_control_type = "submit";
823 form.fields.push_back(field); 877 form.fields.push_back(field);
824 878
825 form_structure.reset(new FormStructure(form)); 879 form_structure.reset(new FormStructure(form));
826 form_structure->DetermineHeuristicTypes(); 880 form_structure->DetermineHeuristicTypes();
827 EXPECT_TRUE(form_structure->IsAutofillable(true)); 881 EXPECT_TRUE(form_structure->IsAutofillable(true));
828 ASSERT_EQ(6U, form_structure->field_count()); 882 ASSERT_EQ(6U, form_structure->field_count());
829 ASSERT_EQ(4U, form_structure->autofill_count()); 883 ASSERT_EQ(4U, form_structure->autofill_count());
830 884
831 // Credit card name. 885 // Credit card name.
832 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); 886 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
833 // Credit card number. 887 // Credit card number.
834 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type()); 888 EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(1)->heuristic_type());
835 // Credit card expiration month. 889 // Credit card expiration month.
836 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(2)->heuristic_type()); 890 EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(2)->heuristic_type());
837 // Credit card expiration year. 891 // Credit card expiration year.
838 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, 892 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
839 form_structure->field(3)->heuristic_type()); 893 form_structure->field(3)->heuristic_type());
840 // We don't determine CVV. 894 // We don't determine CVV.
841 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(4)->heuristic_type()); 895 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(4)->heuristic_type());
842 // Submit. 896 // Submit.
843 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type()); 897 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
844 } 898 }
845 899
846 TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { 900 TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) {
847 scoped_ptr<FormStructure> form_structure; 901 scoped_ptr<FormStructure> form_structure;
848 FormData form; 902 FormData form;
849 form.method = ASCIIToUTF16("post"); 903 form.method = ASCIIToUTF16("post");
850 904
851 FormFieldData field; 905 FormFieldData field;
852 field.form_control_type = ASCIIToUTF16("text"); 906 field.form_control_type = "text";
853 907
854 field.label = ASCIIToUTF16("Name on Card"); 908 field.label = ASCIIToUTF16("Name on Card");
855 field.name = ASCIIToUTF16("name_on_card"); 909 field.name = ASCIIToUTF16("name_on_card");
856 form.fields.push_back(field); 910 form.fields.push_back(field);
857 911
858 // This is not a field we know how to process. But we should skip over it 912 // This is not a field we know how to process. But we should skip over it
859 // and process the other fields in the card block. 913 // and process the other fields in the card block.
860 field.label = ASCIIToUTF16("Card Type"); 914 field.label = ASCIIToUTF16("Card Type");
861 field.name = ASCIIToUTF16("card_type"); 915 field.name = ASCIIToUTF16("card_type");
862 form.fields.push_back(field); 916 form.fields.push_back(field);
863 917
864 field.label = ASCIIToUTF16("Card Number"); 918 field.label = ASCIIToUTF16("Card Number");
865 field.name = ASCIIToUTF16("card_number"); 919 field.name = ASCIIToUTF16("card_number");
866 form.fields.push_back(field); 920 form.fields.push_back(field);
867 921
868 field.label = ASCIIToUTF16("Exp Month"); 922 field.label = ASCIIToUTF16("Exp Month");
869 field.name = ASCIIToUTF16("ccmonth"); 923 field.name = ASCIIToUTF16("ccmonth");
870 form.fields.push_back(field); 924 form.fields.push_back(field);
871 925
872 field.label = ASCIIToUTF16("Exp Year"); 926 field.label = ASCIIToUTF16("Exp Year");
873 field.name = ASCIIToUTF16("ccyear"); 927 field.name = ASCIIToUTF16("ccyear");
874 form.fields.push_back(field); 928 form.fields.push_back(field);
875 929
876 field.label = ASCIIToUTF16("Verification"); 930 field.label = ASCIIToUTF16("Verification");
877 field.name = ASCIIToUTF16("verification"); 931 field.name = ASCIIToUTF16("verification");
878 form.fields.push_back(field); 932 form.fields.push_back(field);
879 933
880 field.label = string16(); 934 field.label = string16();
881 field.name = ASCIIToUTF16("Submit"); 935 field.name = ASCIIToUTF16("Submit");
882 field.form_control_type = ASCIIToUTF16("submit"); 936 field.form_control_type = "submit";
883 form.fields.push_back(field); 937 form.fields.push_back(field);
884 938
885 form_structure.reset(new FormStructure(form)); 939 form_structure.reset(new FormStructure(form));
886 form_structure->DetermineHeuristicTypes(); 940 form_structure->DetermineHeuristicTypes();
887 EXPECT_TRUE(form_structure->IsAutofillable(true)); 941 EXPECT_TRUE(form_structure->IsAutofillable(true));
888 ASSERT_EQ(7U, form_structure->field_count()); 942 ASSERT_EQ(7U, form_structure->field_count());
889 ASSERT_EQ(4U, form_structure->autofill_count()); 943 ASSERT_EQ(4U, form_structure->autofill_count());
890 944
891 // Credit card name. 945 // Credit card name.
892 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); 946 EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type());
(...skipping 11 matching lines...) Expand all
904 // Submit. 958 // Submit.
905 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type()); 959 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(6)->heuristic_type());
906 } 960 }
907 961
908 TEST(FormStructureTest, ThreeAddressLines) { 962 TEST(FormStructureTest, ThreeAddressLines) {
909 scoped_ptr<FormStructure> form_structure; 963 scoped_ptr<FormStructure> form_structure;
910 FormData form; 964 FormData form;
911 form.method = ASCIIToUTF16("post"); 965 form.method = ASCIIToUTF16("post");
912 966
913 FormFieldData field; 967 FormFieldData field;
914 field.form_control_type = ASCIIToUTF16("text"); 968 field.form_control_type = "text";
915 969
916 field.label = ASCIIToUTF16("Address Line1"); 970 field.label = ASCIIToUTF16("Address Line1");
917 field.name = ASCIIToUTF16("Address"); 971 field.name = ASCIIToUTF16("Address");
918 form.fields.push_back(field); 972 form.fields.push_back(field);
919 973
920 field.label = ASCIIToUTF16("Address Line2"); 974 field.label = ASCIIToUTF16("Address Line2");
921 field.name = ASCIIToUTF16("Address"); 975 field.name = ASCIIToUTF16("Address");
922 form.fields.push_back(field); 976 form.fields.push_back(field);
923 977
924 field.label = ASCIIToUTF16("Address Line3"); 978 field.label = ASCIIToUTF16("Address Line3");
(...skipping 21 matching lines...) Expand all
946 } 1000 }
947 1001
948 // This test verifies that "addressLine1" and "addressLine2" matches heuristics. 1002 // This test verifies that "addressLine1" and "addressLine2" matches heuristics.
949 // This occured in https://www.gorillaclothing.com/. http://crbug.com/52126. 1003 // This occured in https://www.gorillaclothing.com/. http://crbug.com/52126.
950 TEST(FormStructureTest, BillingAndShippingAddresses) { 1004 TEST(FormStructureTest, BillingAndShippingAddresses) {
951 scoped_ptr<FormStructure> form_structure; 1005 scoped_ptr<FormStructure> form_structure;
952 FormData form; 1006 FormData form;
953 form.method = ASCIIToUTF16("post"); 1007 form.method = ASCIIToUTF16("post");
954 1008
955 FormFieldData field; 1009 FormFieldData field;
956 field.form_control_type = ASCIIToUTF16("text"); 1010 field.form_control_type = "text";
957 1011
958 field.label = ASCIIToUTF16("Address Line1"); 1012 field.label = ASCIIToUTF16("Address Line1");
959 field.name = ASCIIToUTF16("shipping.address.addressLine1"); 1013 field.name = ASCIIToUTF16("shipping.address.addressLine1");
960 form.fields.push_back(field); 1014 form.fields.push_back(field);
961 1015
962 field.label = ASCIIToUTF16("Address Line2"); 1016 field.label = ASCIIToUTF16("Address Line2");
963 field.name = ASCIIToUTF16("shipping.address.addressLine2"); 1017 field.name = ASCIIToUTF16("shipping.address.addressLine2");
964 form.fields.push_back(field); 1018 form.fields.push_back(field);
965 1019
966 field.label = ASCIIToUTF16("Address Line1"); 1020 field.label = ASCIIToUTF16("Address Line1");
(...skipping 25 matching lines...) Expand all
992 // indicate a suite or apartment number. We interpret this as address line 2. 1046 // indicate a suite or apartment number. We interpret this as address line 2.
993 // And the following "Street address second line" we interpret as address line 1047 // And the following "Street address second line" we interpret as address line
994 // 3 and discard. 1048 // 3 and discard.
995 // See http://crbug.com/48197 for details. 1049 // See http://crbug.com/48197 for details.
996 TEST(FormStructureTest, ThreeAddressLinesExpedia) { 1050 TEST(FormStructureTest, ThreeAddressLinesExpedia) {
997 scoped_ptr<FormStructure> form_structure; 1051 scoped_ptr<FormStructure> form_structure;
998 FormData form; 1052 FormData form;
999 form.method = ASCIIToUTF16("post"); 1053 form.method = ASCIIToUTF16("post");
1000 1054
1001 FormFieldData field; 1055 FormFieldData field;
1002 field.form_control_type = ASCIIToUTF16("text"); 1056 field.form_control_type = "text";
1003 1057
1004 field.label = ASCIIToUTF16("Street:"); 1058 field.label = ASCIIToUTF16("Street:");
1005 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1"); 1059 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_ads1");
1006 form.fields.push_back(field); 1060 form.fields.push_back(field);
1007 1061
1008 field.label = ASCIIToUTF16("Suite or Apt:"); 1062 field.label = ASCIIToUTF16("Suite or Apt:");
1009 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap"); 1063 field.name = ASCIIToUTF16("FOPIH_RgWebCC_0_IHAddress_adap");
1010 form.fields.push_back(field); 1064 form.fields.push_back(field);
1011 1065
1012 field.label = ASCIIToUTF16("Street address second line"); 1066 field.label = ASCIIToUTF16("Street address second line");
(...skipping 22 matching lines...) Expand all
1035 1089
1036 // This example comes from ebay.com where the word "suite" appears in the label 1090 // This example comes from ebay.com where the word "suite" appears in the label
1037 // and the name "address2" clearly indicates that this is the address line 2. 1091 // and the name "address2" clearly indicates that this is the address line 2.
1038 // See http://crbug.com/48197 for details. 1092 // See http://crbug.com/48197 for details.
1039 TEST(FormStructureTest, TwoAddressLinesEbay) { 1093 TEST(FormStructureTest, TwoAddressLinesEbay) {
1040 scoped_ptr<FormStructure> form_structure; 1094 scoped_ptr<FormStructure> form_structure;
1041 FormData form; 1095 FormData form;
1042 form.method = ASCIIToUTF16("post"); 1096 form.method = ASCIIToUTF16("post");
1043 1097
1044 FormFieldData field; 1098 FormFieldData field;
1045 field.form_control_type = ASCIIToUTF16("text"); 1099 field.form_control_type = "text";
1046 1100
1047 field.label = ASCIIToUTF16("Address Line1"); 1101 field.label = ASCIIToUTF16("Address Line1");
1048 field.name = ASCIIToUTF16("address1"); 1102 field.name = ASCIIToUTF16("address1");
1049 form.fields.push_back(field); 1103 form.fields.push_back(field);
1050 1104
1051 field.label = ASCIIToUTF16("Floor number, suite number, etc"); 1105 field.label = ASCIIToUTF16("Floor number, suite number, etc");
1052 field.name = ASCIIToUTF16("address2"); 1106 field.name = ASCIIToUTF16("address2");
1053 form.fields.push_back(field); 1107 form.fields.push_back(field);
1054 1108
1055 field.label = ASCIIToUTF16("City:"); 1109 field.label = ASCIIToUTF16("City:");
(...skipping 13 matching lines...) Expand all
1069 // City. 1123 // City.
1070 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(2)->heuristic_type()); 1124 EXPECT_EQ(ADDRESS_HOME_CITY, form_structure->field(2)->heuristic_type());
1071 } 1125 }
1072 1126
1073 TEST(FormStructureTest, HeuristicsStateWithProvince) { 1127 TEST(FormStructureTest, HeuristicsStateWithProvince) {
1074 scoped_ptr<FormStructure> form_structure; 1128 scoped_ptr<FormStructure> form_structure;
1075 FormData form; 1129 FormData form;
1076 form.method = ASCIIToUTF16("post"); 1130 form.method = ASCIIToUTF16("post");
1077 1131
1078 FormFieldData field; 1132 FormFieldData field;
1079 field.form_control_type = ASCIIToUTF16("text"); 1133 field.form_control_type = "text";
1080 1134
1081 field.label = ASCIIToUTF16("Address Line1"); 1135 field.label = ASCIIToUTF16("Address Line1");
1082 field.name = ASCIIToUTF16("Address"); 1136 field.name = ASCIIToUTF16("Address");
1083 form.fields.push_back(field); 1137 form.fields.push_back(field);
1084 1138
1085 field.label = ASCIIToUTF16("Address Line2"); 1139 field.label = ASCIIToUTF16("Address Line2");
1086 field.name = ASCIIToUTF16("Address"); 1140 field.name = ASCIIToUTF16("Address");
1087 form.fields.push_back(field); 1141 form.fields.push_back(field);
1088 1142
1089 field.label = ASCIIToUTF16("State/Province/Region"); 1143 field.label = ASCIIToUTF16("State/Province/Region");
(...skipping 14 matching lines...) Expand all
1104 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(2)->heuristic_type()); 1158 EXPECT_EQ(ADDRESS_HOME_STATE, form_structure->field(2)->heuristic_type());
1105 } 1159 }
1106 1160
1107 // This example comes from lego.com's checkout page. 1161 // This example comes from lego.com's checkout page.
1108 TEST(FormStructureTest, HeuristicsWithBilling) { 1162 TEST(FormStructureTest, HeuristicsWithBilling) {
1109 scoped_ptr<FormStructure> form_structure; 1163 scoped_ptr<FormStructure> form_structure;
1110 FormData form; 1164 FormData form;
1111 form.method = ASCIIToUTF16("post"); 1165 form.method = ASCIIToUTF16("post");
1112 1166
1113 FormFieldData field; 1167 FormFieldData field;
1114 field.form_control_type = ASCIIToUTF16("text"); 1168 field.form_control_type = "text";
1115 1169
1116 field.label = ASCIIToUTF16("First Name*:"); 1170 field.label = ASCIIToUTF16("First Name*:");
1117 field.name = ASCIIToUTF16("editBillingAddress$firstNameBox"); 1171 field.name = ASCIIToUTF16("editBillingAddress$firstNameBox");
1118 form.fields.push_back(field); 1172 form.fields.push_back(field);
1119 1173
1120 field.label = ASCIIToUTF16("Last Name*:"); 1174 field.label = ASCIIToUTF16("Last Name*:");
1121 field.name = ASCIIToUTF16("editBillingAddress$lastNameBox"); 1175 field.name = ASCIIToUTF16("editBillingAddress$lastNameBox");
1122 form.fields.push_back(field); 1176 form.fields.push_back(field);
1123 1177
1124 field.label = ASCIIToUTF16("Company Name:"); 1178 field.label = ASCIIToUTF16("Company Name:");
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 form_structure->field(9)->heuristic_type()); 1231 form_structure->field(9)->heuristic_type());
1178 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(10)->heuristic_type()); 1232 EXPECT_EQ(EMAIL_ADDRESS, form_structure->field(10)->heuristic_type());
1179 } 1233 }
1180 1234
1181 TEST(FormStructureTest, ThreePartPhoneNumber) { 1235 TEST(FormStructureTest, ThreePartPhoneNumber) {
1182 scoped_ptr<FormStructure> form_structure; 1236 scoped_ptr<FormStructure> form_structure;
1183 FormData form; 1237 FormData form;
1184 form.method = ASCIIToUTF16("post"); 1238 form.method = ASCIIToUTF16("post");
1185 1239
1186 FormFieldData field; 1240 FormFieldData field;
1187 field.form_control_type = ASCIIToUTF16("text"); 1241 field.form_control_type = "text";
1188 1242
1189 field.label = ASCIIToUTF16("Phone:"); 1243 field.label = ASCIIToUTF16("Phone:");
1190 field.name = ASCIIToUTF16("dayphone1"); 1244 field.name = ASCIIToUTF16("dayphone1");
1191 field.max_length = 0; 1245 field.max_length = 0;
1192 form.fields.push_back(field); 1246 form.fields.push_back(field);
1193 1247
1194 field.label = ASCIIToUTF16("-"); 1248 field.label = ASCIIToUTF16("-");
1195 field.name = ASCIIToUTF16("dayphone2"); 1249 field.name = ASCIIToUTF16("dayphone2");
1196 field.max_length = 3; // Size of prefix is 3. 1250 field.max_length = 3; // Size of prefix is 3.
1197 form.fields.push_back(field); 1251 form.fields.push_back(field);
(...skipping 27 matching lines...) Expand all
1225 // Unknown. 1279 // Unknown.
1226 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type()); 1280 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(3)->heuristic_type());
1227 } 1281 }
1228 1282
1229 TEST(FormStructureTest, HeuristicsInfernoCC) { 1283 TEST(FormStructureTest, HeuristicsInfernoCC) {
1230 scoped_ptr<FormStructure> form_structure; 1284 scoped_ptr<FormStructure> form_structure;
1231 FormData form; 1285 FormData form;
1232 form.method = ASCIIToUTF16("post"); 1286 form.method = ASCIIToUTF16("post");
1233 1287
1234 FormFieldData field; 1288 FormFieldData field;
1235 field.form_control_type = ASCIIToUTF16("text"); 1289 field.form_control_type = "text";
1236 1290
1237 field.label = ASCIIToUTF16("Name on Card"); 1291 field.label = ASCIIToUTF16("Name on Card");
1238 field.name = ASCIIToUTF16("name_on_card"); 1292 field.name = ASCIIToUTF16("name_on_card");
1239 form.fields.push_back(field); 1293 form.fields.push_back(field);
1240 1294
1241 field.label = ASCIIToUTF16("Address"); 1295 field.label = ASCIIToUTF16("Address");
1242 field.name = ASCIIToUTF16("billing_address"); 1296 field.name = ASCIIToUTF16("billing_address");
1243 form.fields.push_back(field); 1297 form.fields.push_back(field);
1244 1298
1245 field.label = ASCIIToUTF16("Card Number"); 1299 field.label = ASCIIToUTF16("Card Number");
(...skipping 28 matching lines...) Expand all
1274 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, 1328 EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR,
1275 form_structure->field(4)->heuristic_type()); 1329 form_structure->field(4)->heuristic_type());
1276 } 1330 }
1277 1331
1278 TEST(FormStructureTest, CVCCodeClash) { 1332 TEST(FormStructureTest, CVCCodeClash) {
1279 scoped_ptr<FormStructure> form_structure; 1333 scoped_ptr<FormStructure> form_structure;
1280 FormData form; 1334 FormData form;
1281 form.method = ASCIIToUTF16("post"); 1335 form.method = ASCIIToUTF16("post");
1282 1336
1283 FormFieldData field; 1337 FormFieldData field;
1284 field.form_control_type = ASCIIToUTF16("text"); 1338 field.form_control_type = "text";
1285 1339
1286 field.label = ASCIIToUTF16("Card number"); 1340 field.label = ASCIIToUTF16("Card number");
1287 field.name = ASCIIToUTF16("ccnumber"); 1341 field.name = ASCIIToUTF16("ccnumber");
1288 form.fields.push_back(field); 1342 form.fields.push_back(field);
1289 1343
1290 field.label = ASCIIToUTF16("First name"); 1344 field.label = ASCIIToUTF16("First name");
1291 field.name = ASCIIToUTF16("first_name"); 1345 field.name = ASCIIToUTF16("first_name");
1292 form.fields.push_back(field); 1346 form.fields.push_back(field);
1293 1347
1294 field.label = ASCIIToUTF16("Last name"); 1348 field.label = ASCIIToUTF16("Last name");
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 form_structure->field(4)->heuristic_type()); 1382 form_structure->field(4)->heuristic_type());
1329 // CVC code should not match. 1383 // CVC code should not match.
1330 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type()); 1384 EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(5)->heuristic_type());
1331 } 1385 }
1332 1386
1333 TEST(FormStructureTest, EncodeQueryRequest) { 1387 TEST(FormStructureTest, EncodeQueryRequest) {
1334 FormData form; 1388 FormData form;
1335 form.method = ASCIIToUTF16("post"); 1389 form.method = ASCIIToUTF16("post");
1336 1390
1337 FormFieldData field; 1391 FormFieldData field;
1338 field.form_control_type = ASCIIToUTF16("text"); 1392 field.form_control_type = "text";
1339 1393
1340 field.label = ASCIIToUTF16("Name on Card"); 1394 field.label = ASCIIToUTF16("Name on Card");
1341 field.name = ASCIIToUTF16("name_on_card"); 1395 field.name = ASCIIToUTF16("name_on_card");
1342 form.fields.push_back(field); 1396 form.fields.push_back(field);
1343 1397
1344 field.label = ASCIIToUTF16("Address"); 1398 field.label = ASCIIToUTF16("Address");
1345 field.name = ASCIIToUTF16("billing_address"); 1399 field.name = ASCIIToUTF16("billing_address");
1346 form.fields.push_back(field); 1400 form.fields.push_back(field);
1347 1401
1348 field.label = ASCIIToUTF16("Card Number"); 1402 field.label = ASCIIToUTF16("Card Number");
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 1497
1444 TEST(FormStructureTest, EncodeUploadRequest) { 1498 TEST(FormStructureTest, EncodeUploadRequest) {
1445 scoped_ptr<FormStructure> form_structure; 1499 scoped_ptr<FormStructure> form_structure;
1446 std::vector<FieldTypeSet> possible_field_types; 1500 std::vector<FieldTypeSet> possible_field_types;
1447 FormData form; 1501 FormData form;
1448 form.method = ASCIIToUTF16("post"); 1502 form.method = ASCIIToUTF16("post");
1449 form_structure.reset(new FormStructure(form)); 1503 form_structure.reset(new FormStructure(form));
1450 form_structure->DetermineHeuristicTypes(); 1504 form_structure->DetermineHeuristicTypes();
1451 1505
1452 FormFieldData field; 1506 FormFieldData field;
1453 field.form_control_type = ASCIIToUTF16("text"); 1507 field.form_control_type = "text";
1454 1508
1455 field.label = ASCIIToUTF16("First Name"); 1509 field.label = ASCIIToUTF16("First Name");
1456 field.name = ASCIIToUTF16("firstname"); 1510 field.name = ASCIIToUTF16("firstname");
1457 form.fields.push_back(field); 1511 form.fields.push_back(field);
1458 possible_field_types.push_back(FieldTypeSet()); 1512 possible_field_types.push_back(FieldTypeSet());
1459 possible_field_types.back().insert(NAME_FIRST); 1513 possible_field_types.back().insert(NAME_FIRST);
1460 1514
1461 field.label = ASCIIToUTF16("Last Name"); 1515 field.label = ASCIIToUTF16("Last Name");
1462 field.name = ASCIIToUTF16("lastname"); 1516 field.name = ASCIIToUTF16("lastname");
1463 form.fields.push_back(field); 1517 form.fields.push_back(field);
1464 possible_field_types.push_back(FieldTypeSet()); 1518 possible_field_types.push_back(FieldTypeSet());
1465 possible_field_types.back().insert(NAME_LAST); 1519 possible_field_types.back().insert(NAME_LAST);
1466 1520
1467 field.label = ASCIIToUTF16("Email"); 1521 field.label = ASCIIToUTF16("Email");
1468 field.name = ASCIIToUTF16("email"); 1522 field.name = ASCIIToUTF16("email");
1469 field.form_control_type = ASCIIToUTF16("email"); 1523 field.form_control_type = "email";
1470 form.fields.push_back(field); 1524 form.fields.push_back(field);
1471 possible_field_types.push_back(FieldTypeSet()); 1525 possible_field_types.push_back(FieldTypeSet());
1472 possible_field_types.back().insert(EMAIL_ADDRESS); 1526 possible_field_types.back().insert(EMAIL_ADDRESS);
1473 1527
1474 field.label = ASCIIToUTF16("Phone"); 1528 field.label = ASCIIToUTF16("Phone");
1475 field.name = ASCIIToUTF16("phone"); 1529 field.name = ASCIIToUTF16("phone");
1476 field.form_control_type = ASCIIToUTF16("number"); 1530 field.form_control_type = "number";
1477 form.fields.push_back(field); 1531 form.fields.push_back(field);
1478 possible_field_types.push_back(FieldTypeSet()); 1532 possible_field_types.push_back(FieldTypeSet());
1479 possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER); 1533 possible_field_types.back().insert(PHONE_HOME_WHOLE_NUMBER);
1480 1534
1481 field.label = ASCIIToUTF16("Country"); 1535 field.label = ASCIIToUTF16("Country");
1482 field.name = ASCIIToUTF16("country"); 1536 field.name = ASCIIToUTF16("country");
1483 field.form_control_type = ASCIIToUTF16("select-one"); 1537 field.form_control_type = "select-one";
1484 form.fields.push_back(field); 1538 form.fields.push_back(field);
1485 possible_field_types.push_back(FieldTypeSet()); 1539 possible_field_types.push_back(FieldTypeSet());
1486 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY); 1540 possible_field_types.back().insert(ADDRESS_HOME_COUNTRY);
1487 form_structure.reset(new FormStructure(form)); 1541 form_structure.reset(new FormStructure(form));
1488 1542
1489 ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); 1543 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1490 for (size_t i = 0; i < form_structure->field_count(); ++i) 1544 for (size_t i = 0; i < form_structure->field_count(); ++i)
1491 form_structure->field(i)->set_possible_types(possible_field_types[i]); 1545 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1492 1546
1493 FieldTypeSet available_field_types; 1547 FieldTypeSet available_field_types;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1526 "<field signature=\"1029417091\" autofilltype=\"9\"/>" 1580 "<field signature=\"1029417091\" autofilltype=\"9\"/>"
1527 "<field signature=\"466116101\" autofilltype=\"14\"/>" 1581 "<field signature=\"466116101\" autofilltype=\"14\"/>"
1528 "<field signature=\"2799270304\" autofilltype=\"36\"/>" 1582 "<field signature=\"2799270304\" autofilltype=\"36\"/>"
1529 "</autofillupload>", 1583 "</autofillupload>",
1530 encoded_xml); 1584 encoded_xml);
1531 1585
1532 // Add 2 address fields - this should be still a valid form. 1586 // Add 2 address fields - this should be still a valid form.
1533 for (size_t i = 0; i < 2; ++i) { 1587 for (size_t i = 0; i < 2; ++i) {
1534 field.label = ASCIIToUTF16("Address"); 1588 field.label = ASCIIToUTF16("Address");
1535 field.name = ASCIIToUTF16("address"); 1589 field.name = ASCIIToUTF16("address");
1536 field.form_control_type = ASCIIToUTF16("text"); 1590 field.form_control_type = "text";
1537 form.fields.push_back(field); 1591 form.fields.push_back(field);
1538 possible_field_types.push_back(FieldTypeSet()); 1592 possible_field_types.push_back(FieldTypeSet());
1539 possible_field_types.back().insert(ADDRESS_HOME_LINE1); 1593 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1540 possible_field_types.back().insert(ADDRESS_HOME_LINE2); 1594 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1541 possible_field_types.back().insert(ADDRESS_BILLING_LINE1); 1595 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1542 possible_field_types.back().insert(ADDRESS_BILLING_LINE2); 1596 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1543 } 1597 }
1544 1598
1545 form_structure.reset(new FormStructure(form)); 1599 form_structure.reset(new FormStructure(form));
1546 ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); 1600 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
(...skipping 19 matching lines...) Expand all
1566 "<field signature=\"509334676\" autofilltype=\"31\"/>" 1620 "<field signature=\"509334676\" autofilltype=\"31\"/>"
1567 "<field signature=\"509334676\" autofilltype=\"37\"/>" 1621 "<field signature=\"509334676\" autofilltype=\"37\"/>"
1568 "<field signature=\"509334676\" autofilltype=\"38\"/>" 1622 "<field signature=\"509334676\" autofilltype=\"38\"/>"
1569 "</autofillupload>", 1623 "</autofillupload>",
1570 encoded_xml); 1624 encoded_xml);
1571 1625
1572 // Add 50 address fields - now the form is invalid, as it has too many fields. 1626 // Add 50 address fields - now the form is invalid, as it has too many fields.
1573 for (size_t i = 0; i < 50; ++i) { 1627 for (size_t i = 0; i < 50; ++i) {
1574 field.label = ASCIIToUTF16("Address"); 1628 field.label = ASCIIToUTF16("Address");
1575 field.name = ASCIIToUTF16("address"); 1629 field.name = ASCIIToUTF16("address");
1576 field.form_control_type = ASCIIToUTF16("text"); 1630 field.form_control_type = "text";
1577 form.fields.push_back(field); 1631 form.fields.push_back(field);
1578 possible_field_types.push_back(FieldTypeSet()); 1632 possible_field_types.push_back(FieldTypeSet());
1579 possible_field_types.back().insert(ADDRESS_HOME_LINE1); 1633 possible_field_types.back().insert(ADDRESS_HOME_LINE1);
1580 possible_field_types.back().insert(ADDRESS_HOME_LINE2); 1634 possible_field_types.back().insert(ADDRESS_HOME_LINE2);
1581 possible_field_types.back().insert(ADDRESS_BILLING_LINE1); 1635 possible_field_types.back().insert(ADDRESS_BILLING_LINE1);
1582 possible_field_types.back().insert(ADDRESS_BILLING_LINE2); 1636 possible_field_types.back().insert(ADDRESS_BILLING_LINE2);
1583 } 1637 }
1584 form_structure.reset(new FormStructure(form)); 1638 form_structure.reset(new FormStructure(form));
1585 ASSERT_EQ(form_structure->field_count(), possible_field_types.size()); 1639 ASSERT_EQ(form_structure->field_count(), possible_field_types.size());
1586 for (size_t i = 0; i < form_structure->field_count(); ++i) 1640 for (size_t i = 0; i < form_structure->field_count(); ++i)
1587 form_structure->field(i)->set_possible_types(possible_field_types[i]); 1641 form_structure->field(i)->set_possible_types(possible_field_types[i]);
1588 EXPECT_FALSE(form_structure->EncodeUploadRequest(available_field_types, false, 1642 EXPECT_FALSE(form_structure->EncodeUploadRequest(available_field_types, false,
1589 &encoded_xml)); 1643 &encoded_xml));
1590 } 1644 }
1591 1645
1592 // Check that we compute the "datapresent" string correctly for the given 1646 // Check that we compute the "datapresent" string correctly for the given
1593 // |available_types|. 1647 // |available_types|.
1594 TEST(FormStructureTest, CheckDataPresence) { 1648 TEST(FormStructureTest, CheckDataPresence) {
1595 FormData form; 1649 FormData form;
1596 form.method = ASCIIToUTF16("post"); 1650 form.method = ASCIIToUTF16("post");
1597 1651
1598 FormFieldData field; 1652 FormFieldData field;
1599 field.form_control_type = ASCIIToUTF16("text"); 1653 field.form_control_type = "text";
1600 1654
1601 field.label = ASCIIToUTF16("First Name"); 1655 field.label = ASCIIToUTF16("First Name");
1602 field.name = ASCIIToUTF16("first"); 1656 field.name = ASCIIToUTF16("first");
1603 form.fields.push_back(field); 1657 form.fields.push_back(field);
1604 1658
1605 field.label = ASCIIToUTF16("Last Name"); 1659 field.label = ASCIIToUTF16("Last Name");
1606 field.name = ASCIIToUTF16("last"); 1660 field.name = ASCIIToUTF16("last");
1607 form.fields.push_back(field); 1661 form.fields.push_back(field);
1608 1662
1609 field.label = ASCIIToUTF16("Email"); 1663 field.label = ASCIIToUTF16("Email");
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 available_field_types.insert(ADDRESS_HOME_STATE); 1897 available_field_types.insert(ADDRESS_HOME_STATE);
1844 available_field_types.insert(COMPANY_NAME); 1898 available_field_types.insert(COMPANY_NAME);
1845 1899
1846 // Check that multiple types for the field are processed correctly. 1900 // Check that multiple types for the field are processed correctly.
1847 scoped_ptr<FormStructure> form_structure; 1901 scoped_ptr<FormStructure> form_structure;
1848 std::vector<FieldTypeSet> possible_field_types; 1902 std::vector<FieldTypeSet> possible_field_types;
1849 FormData form; 1903 FormData form;
1850 form.method = ASCIIToUTF16("post"); 1904 form.method = ASCIIToUTF16("post");
1851 1905
1852 FormFieldData field; 1906 FormFieldData field;
1853 field.form_control_type = ASCIIToUTF16("text"); 1907 field.form_control_type = "text";
1854 1908
1855 field.label = ASCIIToUTF16("email"); 1909 field.label = ASCIIToUTF16("email");
1856 field.name = ASCIIToUTF16("email"); 1910 field.name = ASCIIToUTF16("email");
1857 form.fields.push_back(field); 1911 form.fields.push_back(field);
1858 possible_field_types.push_back(FieldTypeSet()); 1912 possible_field_types.push_back(FieldTypeSet());
1859 possible_field_types.back().insert(EMAIL_ADDRESS); 1913 possible_field_types.back().insert(EMAIL_ADDRESS);
1860 1914
1861 field.label = ASCIIToUTF16("First Name"); 1915 field.label = ASCIIToUTF16("First Name");
1862 field.name = ASCIIToUTF16("first"); 1916 field.name = ASCIIToUTF16("first");
1863 form.fields.push_back(field); 1917 form.fields.push_back(field);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 encoded_xml); 2003 encoded_xml);
1950 } 2004 }
1951 2005
1952 TEST(FormStructureTest, CheckFormSignature) { 2006 TEST(FormStructureTest, CheckFormSignature) {
1953 // Check that form signature is created correctly. 2007 // Check that form signature is created correctly.
1954 scoped_ptr<FormStructure> form_structure; 2008 scoped_ptr<FormStructure> form_structure;
1955 FormData form; 2009 FormData form;
1956 form.method = ASCIIToUTF16("post"); 2010 form.method = ASCIIToUTF16("post");
1957 2011
1958 FormFieldData field; 2012 FormFieldData field;
1959 field.form_control_type = ASCIIToUTF16("text"); 2013 field.form_control_type = "text";
1960 2014
1961 field.label = ASCIIToUTF16("email"); 2015 field.label = ASCIIToUTF16("email");
1962 field.name = ASCIIToUTF16("email"); 2016 field.name = ASCIIToUTF16("email");
1963 form.fields.push_back(field); 2017 form.fields.push_back(field);
1964 2018
1965 field.label = ASCIIToUTF16("First Name"); 2019 field.label = ASCIIToUTF16("First Name");
1966 field.name = ASCIIToUTF16("first"); 2020 field.name = ASCIIToUTF16("first");
1967 form.fields.push_back(field); 2021 form.fields.push_back(field);
1968 2022
1969 form_structure.reset(new FormStructure(form)); 2023 form_structure.reset(new FormStructure(form));
(...skipping 13 matching lines...) Expand all
1983 EXPECT_EQ(FormStructureTest::Hash64Bit( 2037 EXPECT_EQ(FormStructureTest::Hash64Bit(
1984 std::string("https://login.facebook.com&&email&first")), 2038 std::string("https://login.facebook.com&&email&first")),
1985 form_structure->FormSignature()); 2039 form_structure->FormSignature());
1986 2040
1987 form.name = ASCIIToUTF16("login_form"); 2041 form.name = ASCIIToUTF16("login_form");
1988 form_structure.reset(new FormStructure(form)); 2042 form_structure.reset(new FormStructure(form));
1989 EXPECT_EQ(FormStructureTest::Hash64Bit( 2043 EXPECT_EQ(FormStructureTest::Hash64Bit(
1990 std::string("https://login.facebook.com&login_form&email&first")), 2044 std::string("https://login.facebook.com&login_form&email&first")),
1991 form_structure->FormSignature()); 2045 form_structure->FormSignature());
1992 } 2046 }
OLDNEW
« no previous file with comments | « chrome/browser/autofill/form_structure.cc ('k') | chrome/browser/autofill/name_field_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698