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

Side by Side Diff: components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc

Issue 369323003: Implement autocomplete='current-password' and 'new-password'. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed nits. Created 6 years, 5 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
« no previous file with comments | « components/autofill/content/renderer/password_form_conversion_utils.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 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/strings/string16.h" 5 #include "base/strings/string16.h"
6 #include "base/strings/string_util.h" 6 #include "base/strings/string_util.h"
7 #include "base/strings/stringprintf.h" 7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "components/autofill/content/renderer/password_form_conversion_utils.h" 9 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
10 #include "components/autofill/core/common/password_form.h" 10 #include "components/autofill/core/common/password_form.h"
(...skipping 21 matching lines...) Expand all
32 // specified |action| URL. 32 // specified |action| URL.
33 explicit PasswordFormBuilder(const char* action) { 33 explicit PasswordFormBuilder(const char* action) {
34 base::StringAppendF( 34 base::StringAppendF(
35 &html_, "<FORM name=\"Test\" action=\"%s\" method=\"post\">", action); 35 &html_, "<FORM name=\"Test\" action=\"%s\" method=\"post\">", action);
36 } 36 }
37 37
38 // Appends a new text-type field at the end of the form, having the specified 38 // Appends a new text-type field at the end of the form, having the specified
39 // |name_and_id|, |value|, and |autocomplete| attributes. The |autocomplete| 39 // |name_and_id|, |value|, and |autocomplete| attributes. The |autocomplete|
40 // argument can take two special values, namely: 40 // argument can take two special values, namely:
41 // 1.) NULL, causing no autocomplete attribute to be added, 41 // 1.) NULL, causing no autocomplete attribute to be added,
42 // 2.) "", causing an empty attribute (i.e. autocomplete='') to be added. 42 // 2.) "", causing an empty attribute (i.e. autocomplete="") to be added.
43 void AddUsernameField(const char* name_and_id, 43 void AddUsernameField(const char* name_and_id,
44 const char* value, 44 const char* value,
45 const char* autocomplete) { 45 const char* autocomplete) {
46 std::string autocomplete_attribute(autocomplete != NULL ? 46 std::string autocomplete_attribute(autocomplete ?
47 base::StringPrintf("autocomplete=\"%s\"", autocomplete) : ""); 47 base::StringPrintf("autocomplete=\"%s\"", autocomplete) : "");
48 base::StringAppendF( 48 base::StringAppendF(
49 &html_, 49 &html_,
50 "<INPUT type=\"text\" name=\"%s\" id=\"%s\" value=\"%s\" %s/>", 50 "<INPUT type=\"text\" name=\"%s\" id=\"%s\" value=\"%s\" %s/>",
51 name_and_id, name_and_id, value, autocomplete_attribute.c_str()); 51 name_and_id, name_and_id, value, autocomplete_attribute.c_str());
52 } 52 }
53 53
54 // Appends a new password-type field at the end of the form, having the 54 // Appends a new password-type field at the end of the form, having the
55 // specified |name_and_id| and |value| attributes. 55 // specified |name_and_id|, |value|, and |autocomplete| attributes. Special
56 void AddPasswordField(const char* name_and_id, const char* value) { 56 // values for |autocomplete| are the same as in AddUsernameField.
57 void AddPasswordField(const char* name_and_id,
58 const char* value,
59 const char* autocomplete) {
60 std::string autocomplete_attribute(autocomplete ?
61 base::StringPrintf("autocomplete=\"%s\"", autocomplete): "");
57 base::StringAppendF( 62 base::StringAppendF(
58 &html_, 63 &html_,
59 "<INPUT type=\"password\" name=\"%s\" id=\"%s\" value=\"%s\"/>", 64 "<INPUT type=\"password\" name=\"%s\" id=\"%s\" value=\"%s\" %s/>",
60 name_and_id, name_and_id, value); 65 name_and_id, name_and_id, value, autocomplete_attribute.c_str());
61 } 66 }
62 67
63 // Appends a new submit-type field at the end of the form. 68 // Appends a new submit-type field at the end of the form.
64 void AddSubmitButton() { 69 void AddSubmitButton() {
65 html_ += "<INPUT type=\"submit\" name=\"submit\" value=\"Submit\"/>"; 70 html_ += "<INPUT type=\"submit\" name=\"submit\" value=\"Submit\"/>";
66 } 71 }
67 72
68 // Returns the HTML code for the form containing the fields that have been 73 // Returns the HTML code for the form containing the fields that have been
69 // added so far. 74 // added so far.
70 std::string ProduceHTML() const { 75 std::string ProduceHTML() const {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 private: 109 private:
105 DISALLOW_COPY_AND_ASSIGN(PasswordFormConversionUtilsTest); 110 DISALLOW_COPY_AND_ASSIGN(PasswordFormConversionUtilsTest);
106 }; 111 };
107 112
108 } // namespace 113 } // namespace
109 114
110 TEST_F(PasswordFormConversionUtilsTest, ValidWebFormElementToPasswordForm) { 115 TEST_F(PasswordFormConversionUtilsTest, ValidWebFormElementToPasswordForm) {
111 PasswordFormBuilder builder(kTestFormActionURL); 116 PasswordFormBuilder builder(kTestFormActionURL);
112 builder.AddUsernameField("username", "johnsmith", NULL); 117 builder.AddUsernameField("username", "johnsmith", NULL);
113 builder.AddSubmitButton(); 118 builder.AddSubmitButton();
114 builder.AddPasswordField("password", "secret"); 119 builder.AddPasswordField("password", "secret", NULL);
115 std::string html = builder.ProduceHTML(); 120 std::string html = builder.ProduceHTML();
116 121
117 scoped_ptr<PasswordForm> password_form; 122 scoped_ptr<PasswordForm> password_form;
118 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); 123 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form));
119 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get()); 124 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get());
120 125
121 EXPECT_EQ("data:", password_form->signon_realm); 126 EXPECT_EQ("data:", password_form->signon_realm);
122 EXPECT_EQ(GURL(kTestFormActionURL), password_form->action); 127 EXPECT_EQ(GURL(kTestFormActionURL), password_form->action);
123 EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); 128 EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element);
124 EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); 129 EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value);
125 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); 130 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
126 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); 131 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
127 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form->scheme); 132 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form->scheme);
128 EXPECT_FALSE(password_form->ssl_valid); 133 EXPECT_FALSE(password_form->ssl_valid);
129 EXPECT_FALSE(password_form->preferred); 134 EXPECT_FALSE(password_form->preferred);
130 EXPECT_FALSE(password_form->blacklisted_by_user); 135 EXPECT_FALSE(password_form->blacklisted_by_user);
131 EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type); 136 EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type);
132 } 137 }
133 138
134 TEST_F(PasswordFormConversionUtilsTest, InvalidWebFormElementToPasswordForm) { 139 TEST_F(PasswordFormConversionUtilsTest, InvalidWebFormElementToPasswordForm) {
135 PasswordFormBuilder builder("invalid_target"); 140 PasswordFormBuilder builder("invalid_target");
136 builder.AddUsernameField("username", "johnsmith", NULL); 141 builder.AddUsernameField("username", "johnsmith", NULL);
137 builder.AddSubmitButton(); 142 builder.AddSubmitButton();
138 builder.AddPasswordField("password", "secret"); 143 builder.AddPasswordField("password", "secret", NULL);
139 std::string html = builder.ProduceHTML(); 144 std::string html = builder.ProduceHTML();
140 145
141 scoped_ptr<PasswordForm> password_form; 146 scoped_ptr<PasswordForm> password_form;
142 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); 147 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form));
143 ASSERT_EQ(static_cast<PasswordForm*>(NULL), password_form.get()); 148 ASSERT_EQ(static_cast<PasswordForm*>(NULL), password_form.get());
144 } 149 }
145 150
146 TEST_F(PasswordFormConversionUtilsTest, 151 TEST_F(PasswordFormConversionUtilsTest,
147 WebFormWithMultipleUseNameAndPassWordFieldsToPasswordForm) { 152 WebFormWithMultipleUseNameAndPassWordFieldsToPasswordForm) {
148 PasswordFormBuilder builder(kTestFormActionURL); 153 PasswordFormBuilder builder(kTestFormActionURL);
149 builder.AddUsernameField("username1", "John", NULL); 154 builder.AddUsernameField("username1", "John", NULL);
150 builder.AddPasswordField("password1", "oldsecret"); 155 builder.AddPasswordField("password1", "oldsecret", NULL);
151 builder.AddUsernameField("username2", "William", NULL); 156 builder.AddUsernameField("username2", "William", NULL);
152 builder.AddPasswordField("password2", "secret"); 157 builder.AddPasswordField("password2", "secret", NULL);
153 builder.AddUsernameField("username3", "Smith", NULL); 158 builder.AddUsernameField("username3", "Smith", NULL);
154 builder.AddPasswordField("password3", "secret"); 159 builder.AddPasswordField("password3", "secret", NULL);
155 builder.AddSubmitButton(); 160 builder.AddSubmitButton();
156 std::string html = builder.ProduceHTML(); 161 std::string html = builder.ProduceHTML();
157 162
158 scoped_ptr<PasswordForm> password_form; 163 scoped_ptr<PasswordForm> password_form;
159 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); 164 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form));
160 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get()); 165 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get());
161 166
162 EXPECT_EQ("data:", password_form->signon_realm); 167 EXPECT_EQ("data:", password_form->signon_realm);
163 EXPECT_EQ(GURL(kTestFormActionURL), password_form->action); 168 EXPECT_EQ(GURL(kTestFormActionURL), password_form->action);
164 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); 169 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element);
(...skipping 13 matching lines...) Expand all
178 EXPECT_FALSE(password_form->ssl_valid); 183 EXPECT_FALSE(password_form->ssl_valid);
179 EXPECT_FALSE(password_form->preferred); 184 EXPECT_FALSE(password_form->preferred);
180 EXPECT_FALSE(password_form->blacklisted_by_user); 185 EXPECT_FALSE(password_form->blacklisted_by_user);
181 EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type); 186 EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type);
182 } 187 }
183 188
184 TEST_F(PasswordFormConversionUtilsTest, 189 TEST_F(PasswordFormConversionUtilsTest,
185 WebFormwithThreeDifferentPasswordsToPasswordForm) { 190 WebFormwithThreeDifferentPasswordsToPasswordForm) {
186 PasswordFormBuilder builder(kTestFormActionURL); 191 PasswordFormBuilder builder(kTestFormActionURL);
187 builder.AddUsernameField("username1", "John", NULL); 192 builder.AddUsernameField("username1", "John", NULL);
188 builder.AddPasswordField("password1", "alpha"); 193 builder.AddPasswordField("password1", "alpha", NULL);
189 builder.AddPasswordField("password2", "beta"); 194 builder.AddPasswordField("password2", "beta", NULL);
190 builder.AddPasswordField("password3", "gamma"); 195 builder.AddPasswordField("password3", "gamma", NULL);
191 builder.AddSubmitButton(); 196 builder.AddSubmitButton();
192 std::string html = builder.ProduceHTML(); 197 std::string html = builder.ProduceHTML();
193 198
194 scoped_ptr<PasswordForm> password_form; 199 scoped_ptr<PasswordForm> password_form;
195 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); 200 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form));
196 ASSERT_EQ(static_cast<PasswordForm*>(NULL), password_form.get()); 201 ASSERT_EQ(static_cast<PasswordForm*>(NULL), password_form.get());
197 } 202 }
198 203
199 TEST_F(PasswordFormConversionUtilsTest, 204 TEST_F(PasswordFormConversionUtilsTest,
200 UsernameFieldsWithAutocompleteAttributes) { 205 UsernameFieldsWithAutocompleteAttributes) {
(...skipping 10 matching lines...) Expand all
211 {{"username", NULL, NULL}, "username1", "John", ""}, 216 {{"username", NULL, NULL}, "username1", "John", ""},
212 {{NULL, "username", NULL}, "username2", "William", ""}, 217 {{NULL, "username", NULL}, "username2", "William", ""},
213 {{NULL, NULL, "username"}, "username3", "Smith", ""}, 218 {{NULL, NULL, "username"}, "username3", "Smith", ""},
214 // When >=2 elements have the attribute, the first should be selected as 219 // When >=2 elements have the attribute, the first should be selected as
215 // the username, and the rest should go to other_possible_usernames. 220 // the username, and the rest should go to other_possible_usernames.
216 {{"username", "username", NULL}, "username1", "John", "William"}, 221 {{"username", "username", NULL}, "username1", "John", "William"},
217 {{NULL, "username", "username"}, "username2", "William", "Smith"}, 222 {{NULL, "username", "username"}, "username2", "William", "Smith"},
218 {{"username", NULL, "username"}, "username1", "John", "Smith"}, 223 {{"username", NULL, "username"}, "username1", "John", "Smith"},
219 {{"username", "username", "username"}, "username1", "John", 224 {{"username", "username", "username"}, "username1", "John",
220 "William+Smith"}, 225 "William+Smith"},
221 // When there is an empty autocomplete attribute (i.e. autocomplete=''), 226 // When there is an empty autocomplete attribute (i.e. autocomplete=""),
222 // it should have the same effect as having no attribute whatsoever. 227 // it should have the same effect as having no attribute whatsoever.
223 {{"", "", ""}, "username2", "William", "John+Smith"}, 228 {{"", "", ""}, "username2", "William", "John+Smith"},
224 {{"", "", "username"}, "username3", "Smith", ""}, 229 {{"", "", "username"}, "username3", "Smith", ""},
225 {{"username", "", "username"}, "username1", "John", "Smith"}, 230 {{"username", "", "username"}, "username1", "John", "Smith"},
226 // Whether attribute values are upper or mixed case, it should not matter. 231 // It should not matter if attribute values are upper or mixed case.
227 {{"USERNAME", NULL, "uSeRNaMe"}, "username1", "John", "Smith"}, 232 {{"USERNAME", NULL, "uSeRNaMe"}, "username1", "John", "Smith"},
228 {{"uSeRNaMe", NULL, "USERNAME"}, "username1", "John", "Smith"}}; 233 {{"uSeRNaMe", NULL, "USERNAME"}, "username1", "John", "Smith"}};
229 234
230 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 235 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
231 SCOPED_TRACE(testing::Message() << "Iteration " << i); 236 SCOPED_TRACE(testing::Message() << "Iteration " << i);
232 237
233 PasswordFormBuilder builder(kTestFormActionURL); 238 PasswordFormBuilder builder(kTestFormActionURL);
234 builder.AddUsernameField("username1", "John", cases[i].autocomplete[0]); 239 builder.AddUsernameField("username1", "John", cases[i].autocomplete[0]);
235 builder.AddUsernameField("username2", "William", cases[i].autocomplete[1]); 240 builder.AddUsernameField("username2", "William", cases[i].autocomplete[1]);
236 builder.AddPasswordField("password", "secret"); 241 builder.AddPasswordField("password", "secret", NULL);
237 builder.AddUsernameField("username3", "Smith", cases[i].autocomplete[2]); 242 builder.AddUsernameField("username3", "Smith", cases[i].autocomplete[2]);
238 builder.AddSubmitButton(); 243 builder.AddSubmitButton();
239 std::string html = builder.ProduceHTML(); 244 std::string html = builder.ProduceHTML();
240 245
241 scoped_ptr<PasswordForm> password_form; 246 scoped_ptr<PasswordForm> password_form;
242 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); 247 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form));
243 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get()); 248 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get());
244 249
245 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element), 250 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element),
246 password_form->username_element); 251 password_form->username_element);
247 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), 252 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value),
248 password_form->username_value); 253 password_form->username_value);
249 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); 254 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element);
250 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); 255 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value);
251 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_other_possible_usernames), 256 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_other_possible_usernames),
252 JoinString(password_form->other_possible_usernames, '+')); 257 JoinString(password_form->other_possible_usernames, '+'));
253 } 258 }
254 } 259 }
255 260
261 TEST_F(PasswordFormConversionUtilsTest,
262 PasswordFieldsWithAutocompleteAttributes) {
263 // Each test case consists of a set of parameters to be plugged into the
264 // PasswordFormBuilder below, plus the corresponding expectations.
265 struct TestCase {
266 const char* autocomplete[3];
267 const char* expected_password_element;
268 const char* expected_password_value;
269 const char* expected_new_password_element;
270 const char* expected_new_password_value;
271 } cases[] = {
272 // When there are elements marked with autocomplete='current-password',
273 // but no elements with 'new-password', we should treat the first of the
274 // former kind as the current password, and ignore all other password
275 // fields, assuming they are not intentionally not marked. They might be
276 // for other purposes, such as PINs, OTPs, and the like. Actual values in
277 // the password fields should be ignored in all cases below.
278 {{"current-password", NULL, NULL}, "password1", "alpha", "", ""},
Garrett Casto 2014/07/07 22:32:36 Nit: Given how much information there is here, I t
engedy 2014/07/09 14:24:10 Done.
279 {{NULL, "current-password", NULL}, "password2", "beta", "", ""},
280 {{NULL, NULL, "current-password"}, "password3", "gamma", "", ""},
281 {{NULL, "current-password", "current-password"},
282 "password2", "beta", "", ""},
283 {{"current-password", NULL, "current-password"},
284 "password1", "alpha", "", ""},
285 {{"current-password", "current-password", NULL},
286 "password1", "alpha", "", ""},
287 {{"current-password", "current-password", "current-password"},
288 "password1", "alpha", "", ""},
289 // The same goes vice versa for autocomplete='new-password'.
290 {{"new-password", NULL, NULL}, "", "", "password1", "alpha"},
291 {{NULL, "new-password", NULL}, "", "", "password2", "beta"},
292 {{NULL, NULL, "new-password"}, "", "", "password3", "gamma"},
293 {{NULL, "new-password", "new-password"}, "", "", "password2", "beta"},
294 {{"new-password", NULL, "new-password"}, "", "", "password1", "alpha"},
295 {{"new-password", "new-password", NULL}, "", "", "password1", "alpha"},
296 {{"new-password", "new-password", "new-password"},
297 "", "", "password1", "alpha"},
298 // When there is one element marked with autocomplete='current-password',
299 // and one with 'new-password', just comply, regardless of their order.
300 // Ignore the unmarked password field(s) for the same reason as above.
301 {{"current-password", "new-password", NULL},
302 "password1", "alpha", "password2", "beta"},
303 {{"current-password", NULL, "new-password"},
304 "password1", "alpha", "password3", "gamma"},
305 {{NULL, "current-password", "new-password"},
306 "password2", "beta", "password3", "gamma"},
307 {{"new-password", "current-password", NULL},
308 "password2", "beta", "password1", "alpha"},
309 {{"new-password", NULL, "current-password"},
310 "password3", "gamma", "password1", "alpha"},
311 {{NULL, "new-password", "current-password"},
312 "password3", "gamma", "password2", "beta"},
313 // In case of duplicated elements of either kind, go with the first one of
314 // its kind.
315 {{"current-password", "current-password", "new-password"},
316 "password1", "alpha", "password3", "gamma"},
317 {{"current-password", "new-password", "current-password"},
318 "password1", "alpha", "password2", "beta"},
319 {{"new-password", "current-password", "current-password"},
320 "password2", "beta", "password1", "alpha"},
321 {{"current-password", "new-password", "new-password"},
322 "password1", "alpha", "password2", "beta"},
323 {{"new-password", "current-password", "new-password"},
324 "password2", "beta", "password1", "alpha"},
325 {{"new-password", "new-password", "current-password"},
326 "password3", "gamma", "password1", "alpha"},
327 // When there is an empty autocomplete attribute (i.e. autocomplete=""),
328 // it should have the same effect as having no attribute whatsoever.
329 {{"current-password", "", ""},
330 "password1", "alpha", "", ""},
331 {{"", "", "new-password"},
332 "", "", "password3", "gamma"},
333 {{"", "new-password", ""},
334 "", "", "password2", "beta"},
335 {{"", "current-password", "current-password"},
336 "password2", "beta", "", ""},
337 {{"new-password", "", "new-password"}, "", "", "password1", "alpha"},
338 {{"new-password", "", "current-password"},
339 "password3", "gamma", "password1", "alpha"},
340 // It should not matter if attribute values are upper or mixed case.
341 {{NULL, "current-password", NULL},
342 "password2", "beta", "", ""},
343 {{NULL, "CURRENT-PASSWORD", NULL},
344 "password2", "beta", "", ""},
345 {{NULL, "new-password", NULL},
346 "", "", "password2", "beta"},
347 {{NULL, "nEw-PaSsWoRd", NULL},
348 "", "", "password2", "beta"}};
349
350 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
351 SCOPED_TRACE(testing::Message() << "Iteration " << i);
352
353 PasswordFormBuilder builder(kTestFormActionURL);
354 builder.AddPasswordField("password1", "alpha", cases[i].autocomplete[0]);
355 builder.AddUsernameField("username1", "William", NULL);
356 builder.AddPasswordField("password2", "beta", cases[i].autocomplete[1]);
357 builder.AddUsernameField("username2", "Smith", NULL);
358 builder.AddPasswordField("password3", "gamma", cases[i].autocomplete[2]);
359 builder.AddSubmitButton();
360 std::string html = builder.ProduceHTML();
361
362 scoped_ptr<PasswordForm> password_form;
363 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form));
364 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get());
365
366 // Any constellation of password autocomplete attributes should have no
367 // effect on that the first text-type input field before a password field
368 // should be selected as the username.
369 // TODO(engedy): Double-check whether this is the intended behavior.
Garrett Casto 2014/07/07 22:32:36 I guess there are a few options we could use. Befo
engedy 2014/07/09 14:24:10 I have kept the current implementation, then.
370 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element);
371 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value);
372 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element),
373 password_form->password_element);
374 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value),
375 password_form->password_value);
376 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element),
377 password_form->new_password_element);
378 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value),
379 password_form->new_password_value);
380 ASSERT_EQ(1u, password_form->other_possible_usernames.size());
381 EXPECT_EQ(base::UTF8ToUTF16("Smith"),
382 password_form->other_possible_usernames[0]);
383 }
384 }
385
256 } // namespace autofill 386 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/content/renderer/password_form_conversion_utils.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698