| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/strings/string16.h" | 9 #include "base/strings/string16.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 | 376 |
| 377 TEST_F(MAYBE_PasswordFormConversionUtilsTest, IdentifyingTwoPasswordFields) { | 377 TEST_F(MAYBE_PasswordFormConversionUtilsTest, IdentifyingTwoPasswordFields) { |
| 378 // Each test case consists of a set of parameters to be plugged into the | 378 // Each test case consists of a set of parameters to be plugged into the |
| 379 // PasswordFormBuilder below, plus the corresponding expectations. | 379 // PasswordFormBuilder below, plus the corresponding expectations. |
| 380 struct TestCase { | 380 struct TestCase { |
| 381 const char* password_values[2]; | 381 const char* password_values[2]; |
| 382 const char* expected_password_element; | 382 const char* expected_password_element; |
| 383 const char* expected_password_value; | 383 const char* expected_password_value; |
| 384 const char* expected_new_password_element; | 384 const char* expected_new_password_element; |
| 385 const char* expected_new_password_value; | 385 const char* expected_new_password_value; |
| 386 const char* expected_confirmation_element; |
| 386 } cases[] = { | 387 } cases[] = { |
| 387 // Two non-empty fields with the same value should be treated as a new | 388 // Two non-empty fields with the same value should be treated as a new |
| 388 // password field plus a confirmation field for the new password. | 389 // password field plus a confirmation field for the new password. |
| 389 {{"alpha", "alpha"}, "", "", "password1", "alpha"}, | 390 {{"alpha", "alpha"}, "", "", "password1", "alpha", "password2"}, |
| 390 // The same goes if the fields are yet empty: we speculate that we will | 391 // The same goes if the fields are yet empty: we speculate that we will |
| 391 // identify them as new password fields once they are filled out, and we | 392 // identify them as new password fields once they are filled out, and we |
| 392 // want to keep our abstract interpretation of the form less flaky. | 393 // want to keep our abstract interpretation of the form less flaky. |
| 393 {{"", ""}, "password1", "", "password2", ""}, | 394 {{"", ""}, "password1", "", "password2", "", ""}, |
| 394 // Two different values should be treated as a password change form, one | 395 // Two different values should be treated as a password change form, one |
| 395 // that also asks for the current password, but only once for the new. | 396 // that also asks for the current password, but only once for the new. |
| 396 {{"alpha", ""}, "password1", "alpha", "password2", ""}, | 397 {{"alpha", ""}, "password1", "alpha", "password2", "", ""}, |
| 397 {{"", "beta"}, "password1", "", "password2", "beta"}, | 398 {{"", "beta"}, "password1", "", "password2", "beta", ""}, |
| 398 {{"alpha", "beta"}, "password1", "alpha", "password2", "beta"}}; | 399 {{"alpha", "beta"}, "password1", "alpha", "password2", "beta", ""}}; |
| 399 | 400 |
| 400 for (size_t i = 0; i < arraysize(cases); ++i) { | 401 for (size_t i = 0; i < arraysize(cases); ++i) { |
| 401 SCOPED_TRACE(testing::Message() << "Iteration " << i); | 402 SCOPED_TRACE(testing::Message() << "Iteration " << i); |
| 402 | 403 |
| 403 PasswordFormBuilder builder(kTestFormActionURL); | 404 PasswordFormBuilder builder(kTestFormActionURL); |
| 404 builder.AddTextField("username1", "William", nullptr); | 405 builder.AddTextField("username1", "William", nullptr); |
| 405 builder.AddPasswordField("password1", cases[i].password_values[0], nullptr); | 406 builder.AddPasswordField("password1", cases[i].password_values[0], nullptr); |
| 406 builder.AddTextField("username2", "Smith", nullptr); | 407 builder.AddTextField("username2", "Smith", nullptr); |
| 407 builder.AddPasswordField("password2", cases[i].password_values[1], nullptr); | 408 builder.AddPasswordField("password2", cases[i].password_values[1], nullptr); |
| 408 builder.AddSubmitButton("submit"); | 409 builder.AddSubmitButton("submit"); |
| 409 std::string html = builder.ProduceHTML(); | 410 std::string html = builder.ProduceHTML(); |
| 410 | 411 |
| 411 std::unique_ptr<PasswordForm> password_form = | 412 std::unique_ptr<PasswordForm> password_form = |
| 412 LoadHTMLAndConvertForm(html, nullptr, false); | 413 LoadHTMLAndConvertForm(html, nullptr, false); |
| 413 ASSERT_TRUE(password_form); | 414 ASSERT_TRUE(password_form); |
| 414 | 415 |
| 415 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), | 416 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), |
| 416 password_form->password_element); | 417 password_form->password_element); |
| 417 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), | 418 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), |
| 418 password_form->password_value); | 419 password_form->password_value); |
| 419 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), | 420 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), |
| 420 password_form->new_password_element); | 421 password_form->new_password_element); |
| 421 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), | 422 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), |
| 422 password_form->new_password_value); | 423 password_form->new_password_value); |
| 424 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_confirmation_element), |
| 425 password_form->confirmation_password_element); |
| 423 | 426 |
| 424 // Do a basic sanity check that we are still selecting the right username. | 427 // Do a basic sanity check that we are still selecting the right username. |
| 425 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); | 428 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); |
| 426 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); | 429 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); |
| 427 EXPECT_THAT(password_form->other_possible_usernames, | 430 EXPECT_THAT(password_form->other_possible_usernames, |
| 428 testing::ElementsAre(base::UTF8ToUTF16("Smith"))); | 431 testing::ElementsAre(base::UTF8ToUTF16("Smith"))); |
| 429 } | 432 } |
| 430 } | 433 } |
| 431 | 434 |
| 432 TEST_F(MAYBE_PasswordFormConversionUtilsTest, IdentifyingThreePasswordFields) { | 435 TEST_F(MAYBE_PasswordFormConversionUtilsTest, IdentifyingThreePasswordFields) { |
| 433 // Each test case consists of a set of parameters to be plugged into the | 436 // Each test case consists of a set of parameters to be plugged into the |
| 434 // PasswordFormBuilder below, plus the corresponding expectations. | 437 // PasswordFormBuilder below, plus the corresponding expectations. |
| 435 struct TestCase { | 438 struct TestCase { |
| 436 const char* password_values[3]; | 439 const char* password_values[3]; |
| 437 const char* expected_password_element; | 440 const char* expected_password_element; |
| 438 const char* expected_password_value; | 441 const char* expected_password_value; |
| 439 const char* expected_new_password_element; | 442 const char* expected_new_password_element; |
| 440 const char* expected_new_password_value; | 443 const char* expected_new_password_value; |
| 444 const char* expected_confirmation_element; |
| 441 } cases[] = { | 445 } cases[] = { |
| 442 // Two fields with the same value, and one different: we should treat this | 446 // Two fields with the same value, and one different: we should treat this |
| 443 // as a password change form with confirmation for the new password. Note | 447 // as a password change form with confirmation for the new password. Note |
| 444 // that we only recognize (current + new + new) and (new + new + current) | 448 // that we only recognize (current + new + new) and (new + new + current) |
| 445 // without autocomplete attributes. | 449 // without autocomplete attributes. |
| 446 {{"alpha", "", ""}, "password1", "alpha", "password2", ""}, | 450 {{"alpha", "", ""}, "password1", "alpha", "password2", "", "password3"}, |
| 447 {{"", "beta", "beta"}, "password1", "", "password2", "beta"}, | 451 {{"", "beta", "beta"}, "password1", "", "password2", "beta", "password3"}, |
| 448 {{"alpha", "beta", "beta"}, "password1", "alpha", "password2", "beta"}, | 452 {{"alpha", "beta", "beta"}, |
| 453 "password1", |
| 454 "alpha", |
| 455 "password2", |
| 456 "beta", |
| 457 "password3"}, |
| 449 // If confirmed password comes first, assume that the third password | 458 // If confirmed password comes first, assume that the third password |
| 450 // field is related to security question, SSN, or credit card and ignore | 459 // field is related to security question, SSN, or credit card and ignore |
| 451 // it. | 460 // it. |
| 452 {{"beta", "beta", "alpha"}, "", "", "password1", "beta"}, | 461 {{"beta", "beta", "alpha"}, "", "", "password1", "beta", "password2"}, |
| 453 // If the fields are yet empty, we speculate that we will identify them as | 462 // If the fields are yet empty, we speculate that we will identify them as |
| 454 // (current + new + new) once they are filled out, so we should classify | 463 // (current + new + new) once they are filled out, so we should classify |
| 455 // them the same for now to keep our abstract interpretation less flaky. | 464 // them the same for now to keep our abstract interpretation less flaky. |
| 456 {{"", "", ""}, "password1", "", "password2", ""}}; | 465 {{"", "", ""}, "password1", "", "password2", "", "password3"}}; |
| 457 // Note: In all other cases, we give up and consider the form invalid. | 466 // Note: In all other cases, we give up and consider the form invalid. |
| 458 // This is tested in InvalidFormDueToConfusingPasswordFields. | 467 // This is tested in InvalidFormDueToConfusingPasswordFields. |
| 459 | 468 |
| 460 for (size_t i = 0; i < arraysize(cases); ++i) { | 469 for (size_t i = 0; i < arraysize(cases); ++i) { |
| 461 SCOPED_TRACE(testing::Message() << "Iteration " << i); | 470 SCOPED_TRACE(testing::Message() << "Iteration " << i); |
| 462 | 471 |
| 463 PasswordFormBuilder builder(kTestFormActionURL); | 472 PasswordFormBuilder builder(kTestFormActionURL); |
| 464 builder.AddTextField("username1", "William", nullptr); | 473 builder.AddTextField("username1", "William", nullptr); |
| 465 builder.AddPasswordField("password1", cases[i].password_values[0], nullptr); | 474 builder.AddPasswordField("password1", cases[i].password_values[0], nullptr); |
| 466 builder.AddPasswordField("password2", cases[i].password_values[1], nullptr); | 475 builder.AddPasswordField("password2", cases[i].password_values[1], nullptr); |
| 467 builder.AddTextField("username2", "Smith", nullptr); | 476 builder.AddTextField("username2", "Smith", nullptr); |
| 468 builder.AddPasswordField("password3", cases[i].password_values[2], nullptr); | 477 builder.AddPasswordField("password3", cases[i].password_values[2], nullptr); |
| 469 builder.AddSubmitButton("submit"); | 478 builder.AddSubmitButton("submit"); |
| 470 std::string html = builder.ProduceHTML(); | 479 std::string html = builder.ProduceHTML(); |
| 471 | 480 |
| 472 std::unique_ptr<PasswordForm> password_form = | 481 std::unique_ptr<PasswordForm> password_form = |
| 473 LoadHTMLAndConvertForm(html, nullptr, false); | 482 LoadHTMLAndConvertForm(html, nullptr, false); |
| 474 ASSERT_TRUE(password_form); | 483 ASSERT_TRUE(password_form); |
| 475 | 484 |
| 476 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), | 485 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_element), |
| 477 password_form->password_element); | 486 password_form->password_element); |
| 478 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), | 487 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_password_value), |
| 479 password_form->password_value); | 488 password_form->password_value); |
| 480 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), | 489 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_element), |
| 481 password_form->new_password_element); | 490 password_form->new_password_element); |
| 482 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), | 491 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_new_password_value), |
| 483 password_form->new_password_value); | 492 password_form->new_password_value); |
| 493 EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_confirmation_element), |
| 494 password_form->confirmation_password_element); |
| 484 | 495 |
| 485 // Do a basic sanity check that we are still selecting the right username. | 496 // Do a basic sanity check that we are still selecting the right username. |
| 486 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); | 497 EXPECT_EQ(base::UTF8ToUTF16("username1"), password_form->username_element); |
| 487 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); | 498 EXPECT_EQ(base::UTF8ToUTF16("William"), password_form->username_value); |
| 488 EXPECT_THAT(password_form->other_possible_usernames, | 499 EXPECT_THAT(password_form->other_possible_usernames, |
| 489 testing::ElementsAre(base::UTF8ToUTF16("Smith"))); | 500 testing::ElementsAre(base::UTF8ToUTF16("Smith"))); |
| 490 } | 501 } |
| 491 } | 502 } |
| 492 | 503 |
| 493 TEST_F(MAYBE_PasswordFormConversionUtilsTest, | 504 TEST_F(MAYBE_PasswordFormConversionUtilsTest, |
| (...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 builder.AddPasswordField("password", "secret", nullptr); | 1464 builder.AddPasswordField("password", "secret", nullptr); |
| 1454 std::string html = builder.ProduceHTML(); | 1465 std::string html = builder.ProduceHTML(); |
| 1455 | 1466 |
| 1456 std::unique_ptr<PasswordForm> password_form = | 1467 std::unique_ptr<PasswordForm> password_form = |
| 1457 LoadHTMLAndConvertForm(html, nullptr, true); | 1468 LoadHTMLAndConvertForm(html, nullptr, true); |
| 1458 ASSERT_TRUE(password_form); | 1469 ASSERT_TRUE(password_form); |
| 1459 EXPECT_FALSE(password_form->does_look_like_signup_form); | 1470 EXPECT_FALSE(password_form->does_look_like_signup_form); |
| 1460 } | 1471 } |
| 1461 | 1472 |
| 1462 } // namespace autofill | 1473 } // namespace autofill |
| OLD | NEW |