1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <vector> 6 7 #include "base/message_loop/message_loop.h" 8 #include "base/prefs/pref_registry_simple.h" 9 #include "base/prefs/pref_service.h" 10 #include "base/prefs/testing_pref_service.h" 11 #include "base/strings/string_util.h" 12 #include "base/strings/utf_string_conversions.h" 13 #include "components/password_manager/core/browser/mock_password_store.h" 14 #include "components/password_manager/core/browser/password_autofill_manager.h" 15 #include "components/password_manager/core/browser/password_manager.h" 16 #include "components/password_manager/core/browser/password_manager_driver.h" 17 #include "components/password_manager/core/browser/password_store.h" 18 #include "components/password_manager/core/browser/stub_password_manager_client.h" 19 #include "components/password_manager/core/browser/stub_password_manager_driver.h" 20 #include "components/password_manager/core/common/password_manager_pref_names.h" 21 #include "testing/gmock/include/gmock/gmock.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 class PasswordGenerationManager; 25 26 using autofill::PasswordForm; 27 using base::ASCIIToUTF16; 28 using testing::_; 29 using testing::AnyNumber; 30 using testing::DoAll; 31 using testing::Exactly; 32 using testing::Return; 33 using testing::WithArg; 34 35 namespace autofill { 36 class AutofillManager; 37 } 38 39 namespace password_manager { 40 41 namespace { 42 43 class MockPasswordManagerClient : public StubPasswordManagerClient { 44 public: 45 MOCK_METHOD1(PromptUserToSavePassword, void(PasswordFormManager*)); 46 MOCK_METHOD0(GetPasswordStore, PasswordStore*()); 47 MOCK_METHOD0(GetPrefs, PrefService*()); 48 MOCK_METHOD0(GetDriver, PasswordManagerDriver*()); 49 }; 50 51 class MockPasswordManagerDriver : public StubPasswordManagerDriver { 52 public: 53 MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&)); 54 MOCK_METHOD0(GetPasswordManager, PasswordManager*()); 55 MOCK_METHOD0(GetPasswordAutofillManager, PasswordAutofillManager*()); 56 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool()); 57 }; 58 59 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); } 60 61 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); } 62 63 class TestPasswordManager : public PasswordManager { 64 public: 65 explicit TestPasswordManager(PasswordManagerClient* client) 66 : PasswordManager(client) {} 67 virtual ~TestPasswordManager() {} 68 69 private: 70 DISALLOW_COPY_AND_ASSIGN(TestPasswordManager); 71 }; 72 73 } // namespace 74 75 class PasswordManagerTest : public testing::Test { 76 protected: 77 virtual void SetUp() { 78 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled, 79 true); 80 81 store_ = new MockPasswordStore; 82 EXPECT_CALL(*store_, ReportMetrics()).Times(AnyNumber()); 83 CHECK(store_->Init(syncer::SyncableService::StartSyncFlare())); 84 85 EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_)); 86 EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_)); 87 EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_)); 88 89 manager_.reset(new TestPasswordManager(&client_)); 90 password_autofill_manager_.reset( 91 new PasswordAutofillManager(&client_, NULL)); 92 93 EXPECT_CALL(driver_, GetPasswordManager()) 94 .WillRepeatedly(Return(manager_.get())); 95 EXPECT_CALL(driver_, GetPasswordAutofillManager()) 96 .WillRepeatedly(Return(password_autofill_manager_.get())); 97 } 98 99 virtual void TearDown() { 100 store_->Shutdown(); 101 store_ = NULL; 102 } 103 104 PasswordForm MakeSimpleForm() { 105 PasswordForm form; 106 form.origin = GURL("http://www.google.com/a/LoginAuth"); 107 form.action = GURL("http://www.google.com/a/Login"); 108 form.username_element = ASCIIToUTF16("Email"); 109 form.password_element = ASCIIToUTF16("Passwd"); 110 form.username_value = ASCIIToUTF16("google"); 111 form.password_value = ASCIIToUTF16("password"); 112 // Default to true so we only need to add tests in autocomplete=off cases. 113 form.password_autocomplete_set = true; 114 form.submit_element = ASCIIToUTF16("signIn"); 115 form.signon_realm = "http://www.google.com"; 116 return form; 117 } 118 119 // Reproduction of the form present on twitter's login page. 120 PasswordForm MakeTwitterLoginForm() { 121 PasswordForm form; 122 form.origin = GURL("https://twitter.com/"); 123 form.action = GURL("https://twitter.com/sessions"); 124 form.username_element = ASCIIToUTF16("Email"); 125 form.password_element = ASCIIToUTF16("Passwd"); 126 form.username_value = ASCIIToUTF16("twitter"); 127 form.password_value = ASCIIToUTF16("password"); 128 form.password_autocomplete_set = true; 129 form.submit_element = ASCIIToUTF16("signIn"); 130 form.signon_realm = "https://twitter.com"; 131 return form; 132 } 133 134 // Reproduction of the form present on twitter's failed login page. 135 PasswordForm MakeTwitterFailedLoginForm() { 136 PasswordForm form; 137 form.origin = GURL("https://twitter.com/login/error?redirect_after_login"); 138 form.action = GURL("https://twitter.com/sessions"); 139 form.username_element = ASCIIToUTF16("EmailField"); 140 form.password_element = ASCIIToUTF16("PasswdField"); 141 form.username_value = ASCIIToUTF16("twitter"); 142 form.password_value = ASCIIToUTF16("password"); 143 form.password_autocomplete_set = true; 144 form.submit_element = ASCIIToUTF16("signIn"); 145 form.signon_realm = "https://twitter.com"; 146 return form; 147 } 148 149 bool FormsAreEqual(const autofill::PasswordForm& lhs, 150 const autofill::PasswordForm& rhs) { 151 if (lhs.origin != rhs.origin) 152 return false; 153 if (lhs.action != rhs.action) 154 return false; 155 if (lhs.username_element != rhs.username_element) 156 return false; 157 if (lhs.password_element != rhs.password_element) 158 return false; 159 if (lhs.username_value != rhs.username_value) 160 return false; 161 if (lhs.password_value != rhs.password_value) 162 return false; 163 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set) 164 return false; 165 if (lhs.submit_element != rhs.submit_element) 166 return false; 167 if (lhs.signon_realm != rhs.signon_realm) 168 return false; 169 return true; 170 } 171 172 TestPasswordManager* manager() { return manager_.get(); } 173 174 void OnPasswordFormSubmitted(const autofill::PasswordForm& form) { 175 manager()->OnPasswordFormSubmitted(form); 176 } 177 178 PasswordManager::PasswordSubmittedCallback SubmissionCallback() { 179 return base::Bind(&PasswordManagerTest::FormSubmitted, 180 base::Unretained(this)); 181 } 182 183 void FormSubmitted(const autofill::PasswordForm& form) { 184 submitted_form_ = form; 185 } 186 187 TestingPrefServiceSimple prefs_; 188 scoped_refptr<MockPasswordStore> store_; 189 MockPasswordManagerClient client_; 190 MockPasswordManagerDriver driver_; 191 scoped_ptr<PasswordAutofillManager> password_autofill_manager_; 192 scoped_ptr<TestPasswordManager> manager_; 193 PasswordForm submitted_form_; 194 }; 195 196 MATCHER_P(FormMatches, form, "") { 197 return form.signon_realm == arg.signon_realm && form.origin == arg.origin && 198 form.action == arg.action && 199 form.username_element == arg.username_element && 200 form.password_element == arg.password_element && 201 form.password_autocomplete_set == arg.password_autocomplete_set && 202 form.submit_element == arg.submit_element; 203 } 204 205 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) { 206 // Test that observing a newly submitted form shows the save password bar. 207 std::vector<PasswordForm*> result; // Empty password store. 208 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 209 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 210 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 211 std::vector<PasswordForm> observed; 212 PasswordForm form(MakeSimpleForm()); 213 observed.push_back(form); 214 manager()->OnPasswordFormsParsed(observed); // The initial load. 215 manager()->OnPasswordFormsRendered(observed); // The initial layout. 216 217 // And the form submit contract is to call ProvisionallySavePassword. 218 manager()->ProvisionallySavePassword(form); 219 220 scoped_ptr<PasswordFormManager> form_to_save; 221 EXPECT_CALL(client_, PromptUserToSavePassword(_)) 222 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 223 224 // Now the password manager waits for the navigation to complete. 225 observed.clear(); 226 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 227 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 228 229 ASSERT_TRUE(form_to_save.get()); 230 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 231 232 // Simulate saving the form, as if the info bar was accepted. 233 form_to_save->Save(); 234 } 235 236 TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) { 237 // This test is the same FormSubmitEmptyStore, except that it simulates the 238 // user generating the password through the browser. 239 std::vector<PasswordForm*> result; // Empty password store. 240 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 241 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 242 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 243 std::vector<PasswordForm> observed; 244 PasswordForm form(MakeSimpleForm()); 245 observed.push_back(form); 246 manager()->OnPasswordFormsParsed(observed); // The initial load. 247 manager()->OnPasswordFormsRendered(observed); // The initial layout. 248 249 // Simulate the user generating the password and submitting the form. 250 manager()->SetFormHasGeneratedPassword(form); 251 manager()->ProvisionallySavePassword(form); 252 253 // The user should not be presented with an infobar as they have already given 254 // consent by using the generated password. The form should be saved once 255 // navigation occurs. 256 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0)); 257 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 258 259 // Now the password manager waits for the navigation to complete. 260 observed.clear(); 261 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 262 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 263 } 264 265 TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) { 266 // Same as above, except with an existing form for the same signon realm, 267 // but different origin. Detailed cases like this are covered by 268 // PasswordFormManagerTest. 269 std::vector<PasswordForm*> result; 270 PasswordForm* existing_different = new PasswordForm(MakeSimpleForm()); 271 existing_different->username_value = ASCIIToUTF16("google2"); 272 result.push_back(existing_different); 273 EXPECT_CALL(driver_, FillPasswordForm(_)); 274 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 275 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 276 277 std::vector<PasswordForm> observed; 278 PasswordForm form(MakeSimpleForm()); 279 observed.push_back(form); 280 manager()->OnPasswordFormsParsed(observed); // The initial load. 281 manager()->OnPasswordFormsRendered(observed); // The initial layout. 282 manager()->ProvisionallySavePassword(form); 283 284 // We still expect an add, since we didn't have a good match. 285 scoped_ptr<PasswordFormManager> form_to_save; 286 EXPECT_CALL(client_, PromptUserToSavePassword(_)) 287 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 288 289 // Now the password manager waits for the navigation to complete. 290 observed.clear(); 291 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 292 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 293 294 ASSERT_TRUE(form_to_save.get()); 295 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 296 297 // Simulate saving the form. 298 form_to_save->Save(); 299 } 300 301 TEST_F(PasswordManagerTest, FormSeenThenLeftPage) { 302 std::vector<PasswordForm*> result; // Empty password store. 303 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 304 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 305 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 306 std::vector<PasswordForm> observed; 307 PasswordForm form(MakeSimpleForm()); 308 observed.push_back(form); 309 manager()->OnPasswordFormsParsed(observed); // The initial load. 310 manager()->OnPasswordFormsRendered(observed); // The initial layout. 311 312 // No message from the renderer that a password was submitted. No 313 // expected calls. 314 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(0); 315 observed.clear(); 316 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 317 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 318 } 319 320 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) { 321 // Test that navigating in the page does not prevent us from showing the save 322 // password infobar. 323 std::vector<PasswordForm*> result; // Empty password store. 324 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 325 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 326 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 327 std::vector<PasswordForm> observed; 328 PasswordForm form(MakeSimpleForm()); 329 observed.push_back(form); 330 manager()->OnPasswordFormsParsed(observed); // The initial load. 331 manager()->OnPasswordFormsRendered(observed); // The initial layout. 332 333 // Simulate navigating in the page. 334 manager()->DidNavigateMainFrame(true); 335 336 // Simulate submitting the password. 337 OnPasswordFormSubmitted(form); 338 339 // Now the password manager waits for the navigation to complete. 340 scoped_ptr<PasswordFormManager> form_to_save; 341 EXPECT_CALL(client_, PromptUserToSavePassword(_)) 342 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 343 344 observed.clear(); 345 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 346 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 347 348 ASSERT_FALSE(NULL == form_to_save.get()); 349 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 350 351 // Simulate saving the form, as if the info bar was accepted. 352 form_to_save->Save(); 353 } 354 355 // This test verifies a fix for http://crbug.com/236673 356 TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) { 357 std::vector<PasswordForm*> result; // Empty password store. 358 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 359 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 360 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 361 PasswordForm first_form(MakeSimpleForm()); 362 first_form.origin = GURL("http://www.nytimes.com/"); 363 first_form.action = GURL("https://myaccount.nytimes.com/auth/login"); 364 first_form.signon_realm = "http://www.nytimes.com/"; 365 PasswordForm second_form(MakeSimpleForm()); 366 second_form.origin = GURL("https://myaccount.nytimes.com/auth/login"); 367 second_form.action = GURL("https://myaccount.nytimes.com/auth/login"); 368 second_form.signon_realm = "https://myaccount.nytimes.com/"; 369 370 // Pretend that the form is hidden on the first page. 371 std::vector<PasswordForm> observed; 372 observed.push_back(first_form); 373 manager()->OnPasswordFormsParsed(observed); 374 observed.clear(); 375 manager()->OnPasswordFormsRendered(observed); 376 377 // Now navigate to a second page. 378 manager()->DidNavigateMainFrame(false); 379 380 // This page contains a form with the same markup, but on a different 381 // URL. 382 observed.push_back(second_form); 383 manager()->OnPasswordFormsParsed(observed); 384 manager()->OnPasswordFormsRendered(observed); 385 386 // Now submit this form 387 OnPasswordFormSubmitted(second_form); 388 389 // Navigation after form submit. 390 scoped_ptr<PasswordFormManager> form_to_save; 391 EXPECT_CALL(client_, PromptUserToSavePassword(_)) 392 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 393 observed.clear(); 394 manager()->OnPasswordFormsParsed(observed); 395 manager()->OnPasswordFormsRendered(observed); 396 397 // Make sure that the saved form matches the second form, not the first. 398 ASSERT_TRUE(form_to_save.get()); 399 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(second_form))); 400 401 // Simulate saving the form, as if the info bar was accepted. 402 form_to_save->Save(); 403 } 404 405 TEST_F(PasswordManagerTest, FormSubmitFailedLogin) { 406 std::vector<PasswordForm*> result; // Empty password store. 407 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 408 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 409 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 410 std::vector<PasswordForm> observed; 411 PasswordForm form(MakeSimpleForm()); 412 observed.push_back(form); 413 manager()->OnPasswordFormsParsed(observed); // The initial load. 414 manager()->OnPasswordFormsRendered(observed); // The initial layout. 415 416 manager()->ProvisionallySavePassword(form); 417 418 // The form reappears, and is visible in the layout: 419 // No expected calls to the PasswordStore... 420 manager()->OnPasswordFormsParsed(observed); 421 manager()->OnPasswordFormsRendered(observed); 422 } 423 424 TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) { 425 // Tests fix of issue 28911: if the login form reappears on the subsequent 426 // page, but is invisible, it shouldn't count as a failed login. 427 std::vector<PasswordForm*> result; // Empty password store. 428 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 429 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 430 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 431 std::vector<PasswordForm> observed; 432 PasswordForm form(MakeSimpleForm()); 433 observed.push_back(form); 434 manager()->OnPasswordFormsParsed(observed); // The initial load. 435 manager()->OnPasswordFormsRendered(observed); // The initial layout. 436 437 manager()->ProvisionallySavePassword(form); 438 439 // Expect info bar to appear: 440 scoped_ptr<PasswordFormManager> form_to_save; 441 EXPECT_CALL(client_, PromptUserToSavePassword(_)) 442 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); 443 444 // The form reappears, but is not visible in the layout: 445 manager()->OnPasswordFormsParsed(observed); 446 observed.clear(); 447 manager()->OnPasswordFormsRendered(observed); 448 449 ASSERT_TRUE(form_to_save.get()); 450 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 451 452 // Simulate saving the form. 453 form_to_save->Save(); 454 } 455 456 TEST_F(PasswordManagerTest, InitiallyInvisibleForm) { 457 // Make sure an invisible login form still gets autofilled. 458 std::vector<PasswordForm*> result; 459 PasswordForm* existing = new PasswordForm(MakeSimpleForm()); 460 result.push_back(existing); 461 EXPECT_CALL(driver_, FillPasswordForm(_)); 462 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 463 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 464 std::vector<PasswordForm> observed; 465 PasswordForm form(MakeSimpleForm()); 466 observed.push_back(form); 467 manager()->OnPasswordFormsParsed(observed); // The initial load. 468 observed.clear(); 469 manager()->OnPasswordFormsRendered(observed); // The initial layout. 470 471 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 472 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 473 } 474 475 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) { 476 // Test that saving passwords depends on the password manager enabled 477 // preference. 478 prefs_.SetUserPref(prefs::kPasswordManagerEnabled, 479 base::Value::CreateBooleanValue(true)); 480 EXPECT_TRUE(manager()->IsSavingEnabledForCurrentPage()); 481 prefs_.SetUserPref(prefs::kPasswordManagerEnabled, 482 base::Value::CreateBooleanValue(false)); 483 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage()); 484 } 485 486 TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) { 487 // Test fix for issue 158296: Passwords must be filled even if the password 488 // manager is disabled. 489 std::vector<PasswordForm*> result; 490 PasswordForm* existing = new PasswordForm(MakeSimpleForm()); 491 result.push_back(existing); 492 prefs_.SetUserPref(prefs::kPasswordManagerEnabled, 493 base::Value::CreateBooleanValue(false)); 494 EXPECT_CALL(driver_, FillPasswordForm(_)); 495 EXPECT_CALL(*store_.get(), 496 GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _)) 497 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 498 std::vector<PasswordForm> observed; 499 PasswordForm form(MakeSimpleForm()); 500 observed.push_back(form); 501 manager()->OnPasswordFormsParsed(observed); 502 } 503 504 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) { 505 // Test password form with non-generated password will be saved even if 506 // autocomplete=off. 507 std::vector<PasswordForm*> result; // Empty password store. 508 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 509 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 510 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 511 std::vector<PasswordForm> observed; 512 PasswordForm form(MakeSimpleForm()); 513 form.password_autocomplete_set = false; 514 observed.push_back(form); 515 manager()->OnPasswordFormsParsed(observed); // The initial load. 516 manager()->OnPasswordFormsRendered(observed); // The initial layout. 517 518 // And the form submit contract is to call ProvisionallySavePassword. 519 manager()->ProvisionallySavePassword(form); 520 521 // Password form should be saved. 522 scoped_ptr<PasswordFormManager> form_to_save; 523 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(1)).WillOnce( 524 WithArg<0>(SaveToScopedPtr(&form_to_save))); 525 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0)); 526 527 // Now the password manager waits for the navigation to complete. 528 observed.clear(); 529 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 530 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 531 532 ASSERT_TRUE(form_to_save.get()); 533 } 534 535 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) { 536 // Test password form with generated password will still be saved if 537 // autocomplete=off. 538 std::vector<PasswordForm*> result; // Empty password store. 539 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0)); 540 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 541 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 542 std::vector<PasswordForm> observed; 543 PasswordForm form(MakeSimpleForm()); 544 form.password_autocomplete_set = false; 545 observed.push_back(form); 546 manager()->OnPasswordFormsParsed(observed); // The initial load. 547 manager()->OnPasswordFormsRendered(observed); // The initial layout. 548 549 // Simulate the user generating the password and submitting the form. 550 manager()->SetFormHasGeneratedPassword(form); 551 manager()->ProvisionallySavePassword(form); 552 553 // The user should not be presented with an infobar as they have already given 554 // consent by using the generated password. The form should be saved once 555 // navigation occurs. 556 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0)); 557 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); 558 559 // Now the password manager waits for the navigation to complete. 560 observed.clear(); 561 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. 562 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. 563 } 564 565 TEST_F(PasswordManagerTest, SubmissionCallbackTest) { 566 manager()->AddSubmissionCallback(SubmissionCallback()); 567 PasswordForm form = MakeSimpleForm(); 568 OnPasswordFormSubmitted(form); 569 EXPECT_TRUE(FormsAreEqual(form, submitted_form_)); 570 } 571 572 TEST_F(PasswordManagerTest, PasswordFormReappearance) { 573 // Test the heuristic to know if a password form reappears. 574 // We assume that if we send our credentials and there 575 // is at least one visible password form in the next page that 576 // means that our previous login attempt failed. 577 std::vector<PasswordForm*> result; // Empty password store. 578 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0); 579 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)) 580 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return())); 581 std::vector<PasswordForm> observed; 582 PasswordForm login_form(MakeTwitterLoginForm()); 583 observed.push_back(login_form); 584 manager()->OnPasswordFormsParsed(observed); // The initial load. 585 manager()->OnPasswordFormsRendered(observed); // The initial layout. 586 587 manager()->ProvisionallySavePassword(login_form); 588 589 PasswordForm failed_login_form(MakeTwitterFailedLoginForm()); 590 observed.clear(); 591 observed.push_back(failed_login_form); 592 // A PasswordForm appears, and is visible in the layout: 593 // No expected calls to the PasswordStore... 594 manager()->OnPasswordFormsParsed(observed); 595 manager()->OnPasswordFormsRendered(observed); 596 } 597 598 TEST_F(PasswordManagerTest, SavingNotEnabledOnSSLErrors) { 599 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors()) 600 .WillRepeatedly(Return(true)); 601 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage()); 602 } 603 604 TEST_F(PasswordManagerTest, AutofillingNotEnabledOnSSLErrors) { 605 // Test that in the presence of SSL errors, the password manager does not 606 // attempt to autofill forms found on a website. 607 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors()) 608 .WillRepeatedly(Return(true)); 609 610 // Let us pretend some forms were found on a website. 611 std::vector<PasswordForm> forms; 612 forms.push_back(MakeSimpleForm()); 613 614 // Feed those forms to |manager()| and check that it does not try to find 615 // matching saved credentials for the forms. 616 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)).Times(Exactly(0)); 617 manager()->OnPasswordFormsParsed(forms); 618 } 619 620 } // namespace password_manager 621