OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |