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" |
11 #include "content/public/test/render_view_test.h" | 11 #include "content/public/test/render_view_test.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | |
12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
13 #include "third_party/WebKit/public/platform/WebVector.h" | 14 #include "third_party/WebKit/public/platform/WebVector.h" |
14 #include "third_party/WebKit/public/web/WebDocument.h" | 15 #include "third_party/WebKit/public/web/WebDocument.h" |
15 #include "third_party/WebKit/public/web/WebFormElement.h" | 16 #include "third_party/WebKit/public/web/WebFormElement.h" |
16 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 17 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
17 | 18 |
18 using blink::WebFormElement; | 19 using blink::WebFormElement; |
19 using blink::WebFrame; | 20 using blink::WebFrame; |
20 using blink::WebVector; | 21 using blink::WebVector; |
21 | 22 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 | 106 |
106 *password_form = CreatePasswordForm(forms[0]); | 107 *password_form = CreatePasswordForm(forms[0]); |
107 } | 108 } |
108 | 109 |
109 private: | 110 private: |
110 DISALLOW_COPY_AND_ASSIGN(PasswordFormConversionUtilsTest); | 111 DISALLOW_COPY_AND_ASSIGN(PasswordFormConversionUtilsTest); |
111 }; | 112 }; |
112 | 113 |
113 } // namespace | 114 } // namespace |
114 | 115 |
115 TEST_F(PasswordFormConversionUtilsTest, ValidWebFormElementToPasswordForm) { | 116 TEST_F(PasswordFormConversionUtilsTest, BasicFormAttributes) { |
116 PasswordFormBuilder builder(kTestFormActionURL); | 117 PasswordFormBuilder builder(kTestFormActionURL); |
117 builder.AddUsernameField("username", "johnsmith", NULL); | 118 builder.AddUsernameField("username", "johnsmith", NULL); |
118 builder.AddSubmitButton(); | 119 builder.AddSubmitButton(); |
119 builder.AddPasswordField("password", "secret", NULL); | 120 builder.AddPasswordField("password", "secret", NULL); |
120 std::string html = builder.ProduceHTML(); | 121 std::string html = builder.ProduceHTML(); |
121 | 122 |
122 scoped_ptr<PasswordForm> password_form; | 123 scoped_ptr<PasswordForm> password_form; |
123 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | 124 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); |
124 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get()); | 125 ASSERT_TRUE(password_form); |
125 | 126 |
126 EXPECT_EQ("data:", password_form->signon_realm); | 127 EXPECT_EQ("data:", password_form->signon_realm); |
127 EXPECT_EQ(GURL(kTestFormActionURL), password_form->action); | 128 EXPECT_EQ(GURL(kTestFormActionURL), password_form->action); |
128 EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); | 129 EXPECT_EQ(base::UTF8ToUTF16("username"), password_form->username_element); |
129 EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); | 130 EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); |
130 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); | 131 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); |
131 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); | 132 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); |
132 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form->scheme); | 133 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form->scheme); |
133 EXPECT_FALSE(password_form->ssl_valid); | 134 EXPECT_FALSE(password_form->ssl_valid); |
134 EXPECT_FALSE(password_form->preferred); | 135 EXPECT_FALSE(password_form->preferred); |
135 EXPECT_FALSE(password_form->blacklisted_by_user); | 136 EXPECT_FALSE(password_form->blacklisted_by_user); |
136 EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type); | 137 EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type); |
137 } | 138 EXPECT_FALSE(password_form->use_additional_authentication); |
138 | |
139 TEST_F(PasswordFormConversionUtilsTest, InvalidWebFormElementToPasswordForm) { | |
140 PasswordFormBuilder builder("invalid_target"); | |
141 builder.AddUsernameField("username", "johnsmith", NULL); | |
142 builder.AddSubmitButton(); | |
143 builder.AddPasswordField("password", "secret", NULL); | |
144 std::string html = builder.ProduceHTML(); | |
145 | |
146 scoped_ptr<PasswordForm> password_form; | |
147 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
148 ASSERT_EQ(static_cast<PasswordForm*>(NULL), password_form.get()); | |
149 } | 139 } |
150 | 140 |
151 TEST_F(PasswordFormConversionUtilsTest, | 141 TEST_F(PasswordFormConversionUtilsTest, |
152 WebFormWithMultipleUseNameAndPassWordFieldsToPasswordForm) { | 142 IdentifyingUsernameFields) { |
vabr (Chromium)
2014/07/07 12:12:19
If I understand it correctly, this test was replac
engedy
2014/07/09 16:58:35
This test was exploded into three parts: the usern
| |
153 PasswordFormBuilder builder(kTestFormActionURL); | |
154 builder.AddUsernameField("username1", "John", NULL); | |
155 builder.AddPasswordField("password1", "oldsecret", NULL); | |
156 builder.AddUsernameField("username2", "William", NULL); | |
157 builder.AddPasswordField("password2", "secret", NULL); | |
158 builder.AddUsernameField("username3", "Smith", NULL); | |
159 builder.AddPasswordField("password3", "secret", NULL); | |
160 builder.AddSubmitButton(); | |
161 std::string html = builder.ProduceHTML(); | |
162 | |
163 scoped_ptr<PasswordForm> password_form; | |
164 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
165 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get()); | |
166 | |
167 EXPECT_EQ("data:", password_form->signon_realm); | |
168 EXPECT_EQ(GURL(kTestFormActionURL), password_form->action); | |
169 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); | |
170 EXPECT_EQ(base::UTF8ToUTF16("John"), password_form->username_value); | |
171 EXPECT_EQ(base::UTF8ToUTF16("password1"), | |
172 password_form->password_element); | |
173 EXPECT_EQ(base::UTF8ToUTF16("oldsecret"), password_form->password_value); | |
174 EXPECT_EQ(base::UTF8ToUTF16("password2"), | |
175 password_form->new_password_element); | |
176 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->new_password_value); | |
177 ASSERT_EQ(2u, password_form->other_possible_usernames.size()); | |
178 EXPECT_EQ(base::UTF8ToUTF16("William"), | |
179 password_form->other_possible_usernames[0]); | |
180 EXPECT_EQ(base::UTF8ToUTF16("Smith"), | |
181 password_form->other_possible_usernames[1]); | |
182 EXPECT_EQ(PasswordForm::SCHEME_HTML, password_form->scheme); | |
183 EXPECT_FALSE(password_form->ssl_valid); | |
184 EXPECT_FALSE(password_form->preferred); | |
185 EXPECT_FALSE(password_form->blacklisted_by_user); | |
186 EXPECT_EQ(PasswordForm::TYPE_MANUAL, password_form->type); | |
187 } | |
188 | |
189 TEST_F(PasswordFormConversionUtilsTest, | |
190 WebFormwithThreeDifferentPasswordsToPasswordForm) { | |
191 PasswordFormBuilder builder(kTestFormActionURL); | |
192 builder.AddUsernameField("username1", "John", NULL); | |
193 builder.AddPasswordField("password1", "alpha", NULL); | |
194 builder.AddPasswordField("password2", "beta", NULL); | |
195 builder.AddPasswordField("password3", "gamma", NULL); | |
196 builder.AddSubmitButton(); | |
197 std::string html = builder.ProduceHTML(); | |
198 | |
199 scoped_ptr<PasswordForm> password_form; | |
200 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
201 ASSERT_EQ(static_cast<PasswordForm*>(NULL), password_form.get()); | |
202 } | |
203 | |
204 TEST_F(PasswordFormConversionUtilsTest, | |
205 UsernameFieldsWithAutocompleteAttributes) { | |
206 // Each test case consists of a set of parameters to be plugged into the | 143 // Each test case consists of a set of parameters to be plugged into the |
207 // PasswordFormBuilder below, plus the corresponding expectations. | 144 // PasswordFormBuilder below, plus the corresponding expectations. |
208 struct TestCase { | 145 struct TestCase { |
209 const char* autocomplete[3]; | 146 const char* autocomplete[3]; |
210 const char* expected_username_element; | 147 const char* expected_username_element; |
211 const char* expected_username_value; | 148 const char* expected_username_value; |
212 const char* expected_other_possible_usernames; | 149 const char* expected_other_possible_usernames; |
213 } cases[] = { | 150 } cases[] = { |
151 // When no elements are marked with autocomplete='username', the text-type | |
152 // input field before the first password element should get selected as | |
153 // the username, and the rest should be marked as alternatives. | |
154 {{NULL, NULL, NULL}, "username2", "William", "John+Smith"}, | |
214 // When a sole element is marked with autocomplete='username', it should | 155 // When a sole element is marked with autocomplete='username', it should |
215 // be treated as the username for sure, with no other_possible_usernames. | 156 // be treated as the username for sure, with no other_possible_usernames. |
216 {{"username", NULL, NULL}, "username1", "John", ""}, | 157 {{"username", NULL, NULL}, "username1", "John", ""}, |
217 {{NULL, "username", NULL}, "username2", "William", ""}, | 158 {{NULL, "username", NULL}, "username2", "William", ""}, |
218 {{NULL, NULL, "username"}, "username3", "Smith", ""}, | 159 {{NULL, NULL, "username"}, "username3", "Smith", ""}, |
219 // When >=2 elements have the attribute, the first should be selected as | 160 // When >=2 elements have the attribute, the first should be selected as |
220 // the username, and the rest should go to other_possible_usernames. | 161 // the username, and the rest should go to other_possible_usernames. |
221 {{"username", "username", NULL}, "username1", "John", "William"}, | 162 {{"username", "username", NULL}, "username1", "John", "William"}, |
222 {{NULL, "username", "username"}, "username2", "William", "Smith"}, | 163 {{NULL, "username", "username"}, "username2", "William", "Smith"}, |
223 {{"username", NULL, "username"}, "username1", "John", "Smith"}, | 164 {{"username", NULL, "username"}, "username1", "John", "Smith"}, |
(...skipping 14 matching lines...) Expand all Loading... | |
238 PasswordFormBuilder builder(kTestFormActionURL); | 179 PasswordFormBuilder builder(kTestFormActionURL); |
239 builder.AddUsernameField("username1", "John", cases[i].autocomplete[0]); | 180 builder.AddUsernameField("username1", "John", cases[i].autocomplete[0]); |
240 builder.AddUsernameField("username2", "William", cases[i].autocomplete[1]); | 181 builder.AddUsernameField("username2", "William", cases[i].autocomplete[1]); |
241 builder.AddPasswordField("password", "secret", NULL); | 182 builder.AddPasswordField("password", "secret", NULL); |
242 builder.AddUsernameField("username3", "Smith", cases[i].autocomplete[2]); | 183 builder.AddUsernameField("username3", "Smith", cases[i].autocomplete[2]); |
243 builder.AddSubmitButton(); | 184 builder.AddSubmitButton(); |
244 std::string html = builder.ProduceHTML(); | 185 std::string html = builder.ProduceHTML(); |
245 | 186 |
246 scoped_ptr<PasswordForm> password_form; | 187 scoped_ptr<PasswordForm> password_form; |
247 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | 188 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); |
248 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get()); | 189 ASSERT_TRUE(password_form); |
249 | 190 |
250 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element), | 191 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_element), |
251 password_form->username_element); | 192 password_form->username_element); |
252 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), | 193 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), |
253 password_form->username_value); | 194 password_form->username_value); |
195 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_other_possible_usernames), | |
196 JoinString(password_form->other_possible_usernames, '+')); | |
197 | |
198 // Do a basic sanity check that we are still having a password field. | |
254 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); | 199 EXPECT_EQ(base::UTF8ToUTF16("password"), password_form->password_element); |
255 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); | 200 EXPECT_EQ(base::UTF8ToUTF16("secret"), password_form->password_value); |
256 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_other_possible_usernames), | 201 } |
257 JoinString(password_form->other_possible_usernames, '+')); | 202 } |
203 | |
204 TEST_F(PasswordFormConversionUtilsTest, IdentifyingTwoPasswordFields) { | |
205 // Each test case consists of a set of parameters to be plugged into the | |
206 // PasswordFormBuilder below, plus the corresponding expectations. | |
207 struct TestCase { | |
208 const char* password_values[2]; | |
209 const char* expected_password_element; | |
210 const char* expected_password_value; | |
211 const char* expected_new_password_element; | |
212 const char* expected_new_password_value; | |
213 } cases[] = { | |
214 // Twp non-empty fields with the same value should be treated as a new | |
215 // password field plus a confirmation field for the new password. | |
216 {{"alpha", "alpha"}, "", "", "password1", "alpha"}, | |
217 // The same goes if the fields are yet empty: we speculate that we will | |
218 // identify them as new password fields once they are filled out, and we | |
219 // want to keep our abstract interpretation of the form less flaky. | |
220 {{"", ""}, "", "", "password1", ""}, | |
221 // Two different values should be treated as a password change form, one | |
222 // that also asks for the current password, but only once for the new. | |
223 {{"alpha", ""}, "password1", "alpha", "password2", ""}, | |
224 {{"", "beta"}, "password1", "", "password2", "beta"}, | |
225 {{"alpha", "beta"}, "password1", "alpha", "password2", "beta"}}; | |
226 | |
227 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { | |
228 SCOPED_TRACE(testing::Message() << "Iteration " << i); | |
229 | |
230 PasswordFormBuilder builder(kTestFormActionURL); | |
231 builder.AddPasswordField("password1", cases[i].password_values[0], NULL); | |
232 builder.AddUsernameField("username1", "William", NULL); | |
233 builder.AddPasswordField("password2", cases[i].password_values[1], NULL); | |
234 builder.AddUsernameField("username2", "Smith", NULL); | |
235 builder.AddSubmitButton(); | |
236 std::string html = builder.ProduceHTML(); | |
237 | |
238 scoped_ptr<PasswordForm> password_form; | |
239 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
240 ASSERT_TRUE(password_form); | |
241 | |
242 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), | |
243 password_form->password_element); | |
244 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), | |
245 password_form->password_value); | |
246 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), | |
247 password_form->new_password_element); | |
248 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), | |
249 password_form->new_password_value); | |
250 | |
251 // Do a basic sanity check that we are still selecting the right username. | |
252 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); | |
253 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); | |
254 EXPECT_THAT(password_form->other_possible_usernames, | |
255 testing::ElementsAre(base::UTF8ToUTF16("Smith"))); | |
256 } | |
257 } | |
258 | |
259 TEST_F(PasswordFormConversionUtilsTest, IdentifyingThreePasswordFields) { | |
260 // Each test case consists of a set of parameters to be plugged into the | |
261 // PasswordFormBuilder below, plus the corresponding expectations. | |
262 struct TestCase { | |
263 const char* password_values[3]; | |
264 const char* expected_password_element; | |
265 const char* expected_password_value; | |
266 const char* expected_new_password_element; | |
267 const char* expected_new_password_value; | |
268 } cases[] = { | |
269 // Two fields with the same value, and one different: we should treat this | |
270 // as a password change form with confirmation for the new password. Note | |
271 // that we only recognize (current + new + new) and (new + new + current) | |
272 // without autocomplete attributes. | |
273 {{"alpha", "", ""}, "password1", "alpha", "password2", ""}, | |
274 {{"", "beta", "beta"}, "password1", "", "password2", "beta"}, | |
275 {{"alpha", "beta", "beta"}, "password1", "alpha", "password2", "beta"}, | |
276 {{"beta", "beta", "alpha"}, "password3", "alpha", "password1", "beta"}, | |
277 // If the fields are yet empty, we speculate that we will identify them as | |
278 // (current + new + new) once they are filled out, so we should classify | |
279 // them the same for now to keep our abstract interpretation less flaky. | |
280 {{"", "", ""}, "password1", "", "password2", ""}}; | |
281 // Note: In all other cases, we give up and consider the form invalid. | |
282 // This is tested in InvalidFormDueToConfusingPasswordFields. | |
283 | |
284 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { | |
285 SCOPED_TRACE(testing::Message() << "Iteration " << i); | |
286 | |
287 PasswordFormBuilder builder(kTestFormActionURL); | |
288 builder.AddPasswordField("password1", cases[i].password_values[0], NULL); | |
289 builder.AddUsernameField("username1", "William", NULL); | |
290 builder.AddPasswordField("password2", cases[i].password_values[1], NULL); | |
291 builder.AddUsernameField("username2", "Smith", NULL); | |
292 builder.AddPasswordField("password3", cases[i].password_values[2], NULL); | |
293 builder.AddSubmitButton(); | |
294 std::string html = builder.ProduceHTML(); | |
295 | |
296 scoped_ptr<PasswordForm> password_form; | |
297 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
298 ASSERT_TRUE(password_form); | |
299 | |
300 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), | |
301 password_form->password_element); | |
302 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), | |
303 password_form->password_value); | |
304 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), | |
305 password_form->new_password_element); | |
306 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), | |
307 password_form->new_password_value); | |
308 | |
309 // Do a basic sanity check that we are still selecting the right username. | |
310 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); | |
311 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); | |
312 EXPECT_THAT(password_form->other_possible_usernames, | |
313 testing::ElementsAre(base::UTF8ToUTF16("Smith"))); | |
258 } | 314 } |
259 } | 315 } |
260 | 316 |
261 TEST_F(PasswordFormConversionUtilsTest, | 317 TEST_F(PasswordFormConversionUtilsTest, |
262 PasswordFieldsWithAutocompleteAttributes) { | 318 IdentifyingPasswordFieldsWithAutocompleteAttributes) { |
263 // Each test case consists of a set of parameters to be plugged into the | 319 // Each test case consists of a set of parameters to be plugged into the |
264 // PasswordFormBuilder below, plus the corresponding expectations. | 320 // PasswordFormBuilder below, plus the corresponding expectations. |
265 struct TestCase { | 321 struct TestCase { |
266 const char* autocomplete[3]; | 322 const char* autocomplete[3]; |
267 const char* expected_password_element; | 323 const char* expected_password_element; |
268 const char* expected_password_value; | 324 const char* expected_password_value; |
269 const char* expected_new_password_element; | 325 const char* expected_new_password_element; |
270 const char* expected_new_password_value; | 326 const char* expected_new_password_value; |
271 } cases[] = { | 327 } cases[] = { |
272 // When there are elements marked with autocomplete='current-password', | 328 // When there are elements marked with autocomplete='current-password', |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
354 builder.AddPasswordField("password1", "alpha", cases[i].autocomplete[0]); | 410 builder.AddPasswordField("password1", "alpha", cases[i].autocomplete[0]); |
355 builder.AddUsernameField("username1", "William", NULL); | 411 builder.AddUsernameField("username1", "William", NULL); |
356 builder.AddPasswordField("password2", "beta", cases[i].autocomplete[1]); | 412 builder.AddPasswordField("password2", "beta", cases[i].autocomplete[1]); |
357 builder.AddUsernameField("username2", "Smith", NULL); | 413 builder.AddUsernameField("username2", "Smith", NULL); |
358 builder.AddPasswordField("password3", "gamma", cases[i].autocomplete[2]); | 414 builder.AddPasswordField("password3", "gamma", cases[i].autocomplete[2]); |
359 builder.AddSubmitButton(); | 415 builder.AddSubmitButton(); |
360 std::string html = builder.ProduceHTML(); | 416 std::string html = builder.ProduceHTML(); |
361 | 417 |
362 scoped_ptr<PasswordForm> password_form; | 418 scoped_ptr<PasswordForm> password_form; |
363 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | 419 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); |
364 ASSERT_NE(static_cast<PasswordForm*>(NULL), password_form.get()); | 420 ASSERT_TRUE(password_form); |
365 | 421 |
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. | |
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), | 422 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), |
373 password_form->password_element); | 423 password_form->password_element); |
374 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), | 424 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), |
375 password_form->password_value); | 425 password_form->password_value); |
376 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), | 426 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), |
377 password_form->new_password_element); | 427 password_form->new_password_element); |
378 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), | 428 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), |
379 password_form->new_password_value); | 429 password_form->new_password_value); |
380 ASSERT_EQ(1u, password_form->other_possible_usernames.size()); | 430 |
381 EXPECT_EQ(base::UTF8ToUTF16("Smith"), | 431 // Any constellation of password autocomplete attributes should have no |
382 password_form->other_possible_usernames[0]); | 432 // effect on that the text-type input field before the first password field |
433 // should be selected as the username. | |
434 // TODO(engedy): Double-check whether this is the intended behavior. | |
435 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); | |
436 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); | |
437 EXPECT_THAT(password_form->other_possible_usernames, | |
438 testing::ElementsAre(base::UTF8ToUTF16("Smith"))); | |
383 } | 439 } |
384 } | 440 } |
385 | 441 |
442 TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToBadActionURL) { | |
443 PasswordFormBuilder builder("invalid_target"); | |
444 builder.AddUsernameField("username", "JohnSmith", NULL); | |
445 builder.AddSubmitButton(); | |
446 builder.AddPasswordField("password", "secret", NULL); | |
447 std::string html = builder.ProduceHTML(); | |
448 | |
449 scoped_ptr<PasswordForm> password_form; | |
450 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
451 EXPECT_FALSE(password_form); | |
452 } | |
453 | |
454 TEST_F(PasswordFormConversionUtilsTest, InvalidFormDueToNoPasswordFields) { | |
455 PasswordFormBuilder builder(kTestFormActionURL); | |
456 builder.AddUsernameField("username1", "John", NULL); | |
457 builder.AddUsernameField("username2", "Smith", NULL); | |
458 builder.AddSubmitButton(); | |
459 std::string html = builder.ProduceHTML(); | |
460 | |
461 scoped_ptr<PasswordForm> password_form; | |
462 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
463 EXPECT_FALSE(password_form); | |
464 } | |
465 | |
466 TEST_F(PasswordFormConversionUtilsTest, | |
467 InvalidFormDueToConfusingPasswordFields) { | |
468 // Each test case consists of a set of parameters to be plugged into the | |
469 // PasswordFormBuilder below. | |
470 const char* cases[][3] = { | |
471 // No autocomplete attributes to guide us, and we see: | |
472 // * three password values that are all different, | |
473 // * three password values that are all the same; | |
474 // * three password values with the first and last matching. | |
475 // In any case, we are lost, and we should just give up on this form. | |
476 {"alpha", "beta", "gamma"}, | |
477 {"alpha", "alpha", "alpha"}, | |
478 {"alpha", "beta", "alpha"}}; | |
479 | |
480 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { | |
481 SCOPED_TRACE(testing::Message() << "Iteration " << i); | |
482 | |
483 PasswordFormBuilder builder(kTestFormActionURL); | |
484 builder.AddUsernameField("username1", "John", NULL); | |
485 builder.AddPasswordField("password1", cases[i][0], NULL); | |
486 builder.AddPasswordField("password2", cases[i][1], NULL); | |
487 builder.AddPasswordField("password3", cases[i][2], NULL); | |
488 builder.AddSubmitButton(); | |
489 std::string html = builder.ProduceHTML(); | |
490 | |
491 scoped_ptr<PasswordForm> password_form; | |
492 ASSERT_NO_FATAL_FAILURE(LoadHTMLAndConvertForm(html, &password_form)); | |
493 EXPECT_FALSE(password_form); | |
494 } | |
495 } | |
496 | |
386 } // namespace autofill | 497 } // namespace autofill |
OLD | NEW |