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.
5 #include "components/password_manager/core/browser/password_manager.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/prefs/testing_pref_service.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "components/password_manager/core/browser/mock_password_store.h"
17 #include "components/password_manager/core/browser/password_autofill_manager.h"
18 #include "components/password_manager/core/browser/password_manager_driver.h"
19 #include "components/password_manager/core/browser/password_store.h"
20 #include "components/password_manager/core/browser/stub_password_manager_client.h"
21 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
22 #include "components/password_manager/core/common/password_manager_pref_names.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 class PasswordGenerationManager;
28 using autofill::PasswordForm;
29 using base::ASCIIToUTF16;
31 using testing::AnyNumber;
33 using testing::Exactly;
34 using testing::Return;
35 using testing::WithArg;
38 class AutofillManager;
41 namespace password_manager {
45 class MockPasswordManagerClient : public StubPasswordManagerClient {
47 MOCK_CONST_METHOD0(IsPasswordManagerEnabledForCurrentPage, bool());
48 MOCK_CONST_METHOD2(IsSyncAccountCredential,
49 bool(const std::string&, const std::string&));
50 MOCK_METHOD1(PromptUserToSavePasswordPtr, void(PasswordFormManager*));
51 MOCK_METHOD1(AutomaticPasswordSavePtr, void(PasswordFormManager*));
52 MOCK_METHOD0(GetPasswordStore, PasswordStore*());
53 MOCK_METHOD0(GetPrefs, PrefService*());
54 MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
56 // Workaround for scoped_ptr<> lacking a copy constructor.
57 virtual bool PromptUserToSavePassword(
58 scoped_ptr<PasswordFormManager> manager) override {
59 PromptUserToSavePasswordPtr(manager.release());
62 virtual void AutomaticPasswordSave(
63 scoped_ptr<PasswordFormManager> manager) override {
64 AutomaticPasswordSavePtr(manager.release());
68 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
70 MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&));
71 MOCK_METHOD0(GetPasswordManager, PasswordManager*());
72 MOCK_METHOD0(GetPasswordAutofillManager, PasswordAutofillManager*());
73 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
76 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); }
78 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); }
80 class TestPasswordManager : public PasswordManager {
82 explicit TestPasswordManager(PasswordManagerClient* client)
83 : PasswordManager(client) {}
84 ~TestPasswordManager() override {}
87 DISALLOW_COPY_AND_ASSIGN(TestPasswordManager);
92 class PasswordManagerTest : public testing::Test {
94 void SetUp() override {
95 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled,
98 store_ = new MockPasswordStore;
99 EXPECT_CALL(*store_.get(), ReportMetrics(_, _)).Times(AnyNumber());
100 CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
102 EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage())
103 .WillRepeatedly(Return(true));
104 EXPECT_CALL(client_, IsSyncAccountCredential(_, _))
105 .WillRepeatedly(Return(false));
106 EXPECT_CALL(client_, GetPasswordStore())
107 .WillRepeatedly(Return(store_.get()));
108 EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_));
109 EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
111 manager_.reset(new TestPasswordManager(&client_));
112 password_autofill_manager_.reset(
113 new PasswordAutofillManager(&client_, NULL));
115 EXPECT_CALL(driver_, GetPasswordManager())
116 .WillRepeatedly(Return(manager_.get()));
117 EXPECT_CALL(driver_, GetPasswordAutofillManager())
118 .WillRepeatedly(Return(password_autofill_manager_.get()));
119 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
120 .WillRepeatedly(Return(false));
123 void TearDown() override {
128 PasswordForm MakeSimpleForm() {
130 form.origin = GURL("http://www.google.com/a/LoginAuth");
131 form.action = GURL("http://www.google.com/a/Login");
132 form.username_element = ASCIIToUTF16("Email");
133 form.password_element = ASCIIToUTF16("Passwd");
134 form.username_value = ASCIIToUTF16("google");
135 form.password_value = ASCIIToUTF16("password");
136 // Default to true so we only need to add tests in autocomplete=off cases.
137 form.password_autocomplete_set = true;
138 form.submit_element = ASCIIToUTF16("signIn");
139 form.signon_realm = "http://www.google.com";
143 // Create a sign-up form that only has a new password field.
144 PasswordForm MakeFormWithOnlyNewPasswordField() {
145 PasswordForm form = MakeSimpleForm();
146 form.new_password_element.swap(form.password_element);
147 form.new_password_value.swap(form.password_value);
151 // Reproduction of the form present on twitter's login page.
152 PasswordForm MakeTwitterLoginForm() {
154 form.origin = GURL("https://twitter.com/");
155 form.action = GURL("https://twitter.com/sessions");
156 form.username_element = ASCIIToUTF16("Email");
157 form.password_element = ASCIIToUTF16("Passwd");
158 form.username_value = ASCIIToUTF16("twitter");
159 form.password_value = ASCIIToUTF16("password");
160 form.password_autocomplete_set = true;
161 form.submit_element = ASCIIToUTF16("signIn");
162 form.signon_realm = "https://twitter.com";
166 // Reproduction of the form present on twitter's failed login page.
167 PasswordForm MakeTwitterFailedLoginForm() {
169 form.origin = GURL("https://twitter.com/login/error?redirect_after_login");
170 form.action = GURL("https://twitter.com/sessions");
171 form.username_element = ASCIIToUTF16("EmailField");
172 form.password_element = ASCIIToUTF16("PasswdField");
173 form.username_value = ASCIIToUTF16("twitter");
174 form.password_value = ASCIIToUTF16("password");
175 form.password_autocomplete_set = true;
176 form.submit_element = ASCIIToUTF16("signIn");
177 form.signon_realm = "https://twitter.com";
181 PasswordForm MakeSimpleFormWithOnlyPasswordField() {
182 PasswordForm form(MakeSimpleForm());
183 form.username_element.clear();
184 form.username_value.clear();
188 bool FormsAreEqual(const autofill::PasswordForm& lhs,
189 const autofill::PasswordForm& rhs) {
190 if (lhs.origin != rhs.origin)
192 if (lhs.action != rhs.action)
194 if (lhs.username_element != rhs.username_element)
196 if (lhs.password_element != rhs.password_element)
198 if (lhs.new_password_element != rhs.new_password_element)
200 if (lhs.username_value != rhs.username_value)
202 if (lhs.password_value != rhs.password_value)
204 if (lhs.new_password_value != rhs.new_password_value)
206 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
208 if (lhs.submit_element != rhs.submit_element)
210 if (lhs.signon_realm != rhs.signon_realm)
215 TestPasswordManager* manager() { return manager_.get(); }
217 void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
218 manager()->OnPasswordFormSubmitted(form);
221 PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
222 return base::Bind(&PasswordManagerTest::FormSubmitted,
223 base::Unretained(this));
226 void FormSubmitted(const autofill::PasswordForm& form) {
227 submitted_form_ = form;
230 TestingPrefServiceSimple prefs_;
231 scoped_refptr<MockPasswordStore> store_;
232 MockPasswordManagerClient client_;
233 MockPasswordManagerDriver driver_;
234 scoped_ptr<PasswordAutofillManager> password_autofill_manager_;
235 scoped_ptr<TestPasswordManager> manager_;
236 PasswordForm submitted_form_;
239 MATCHER_P(FormMatches, form, "") {
240 return form.signon_realm == arg.signon_realm && form.origin == arg.origin &&
241 form.action == arg.action &&
242 form.username_element == arg.username_element &&
243 form.password_element == arg.password_element &&
244 form.new_password_element == arg.new_password_element &&
245 form.password_autocomplete_set == arg.password_autocomplete_set &&
246 form.submit_element == arg.submit_element;
249 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
250 // Test that observing a newly submitted form shows the save password bar.
251 std::vector<PasswordForm*> result; // Empty password store.
252 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
253 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
254 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
255 std::vector<PasswordForm> observed;
256 PasswordForm form(MakeSimpleForm());
257 observed.push_back(form);
258 manager()->OnPasswordFormsParsed(observed); // The initial load.
259 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
261 // And the form submit contract is to call ProvisionallySavePassword.
262 manager()->ProvisionallySavePassword(form);
264 scoped_ptr<PasswordFormManager> form_to_save;
265 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_))
266 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
268 // Now the password manager waits for the navigation to complete.
270 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
271 manager()->OnPasswordFormsRendered(observed,
272 true); // The post-navigation layout.
274 ASSERT_TRUE(form_to_save.get());
275 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
277 // Simulate saving the form, as if the info bar was accepted.
278 form_to_save->Save();
281 TEST_F(PasswordManagerTest, FormSubmitWithOnlyNewPasswordField) {
282 // This test is the same as FormSubmitEmptyStore, except that it simulates the
283 // user entering credentials into a sign-up form that only has a new password
285 std::vector<PasswordForm*> result; // Empty password store.
286 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
287 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
288 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
289 std::vector<PasswordForm> observed;
290 PasswordForm form(MakeFormWithOnlyNewPasswordField());
291 observed.push_back(form);
292 manager()->OnPasswordFormsParsed(observed);
293 manager()->OnPasswordFormsRendered(observed, true);
295 // And the form submit contract is to call ProvisionallySavePassword.
296 manager()->ProvisionallySavePassword(form);
298 scoped_ptr<PasswordFormManager> form_to_save;
299 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_))
300 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
302 // Now the password manager waits for the navigation to complete.
304 manager()->OnPasswordFormsParsed(observed);
305 manager()->OnPasswordFormsRendered(observed, true);
307 ASSERT_TRUE(form_to_save.get());
309 // Simulate saving the form, as if the info bar was accepted.
310 PasswordForm saved_form;
311 EXPECT_CALL(*store_.get(), AddLogin(_))
312 .WillOnce(testing::SaveArg<0>(&saved_form));
313 form_to_save->Save();
315 // The value of the new password field should have been promoted to, and saved
316 // to the password store as the current password, and no password element name
317 // should have been saved.
318 PasswordForm expected_form(form);
319 expected_form.password_value.swap(expected_form.new_password_value);
320 expected_form.new_password_element.clear();
321 EXPECT_THAT(saved_form, FormMatches(expected_form));
322 EXPECT_EQ(expected_form.password_value, saved_form.password_value);
323 EXPECT_EQ(expected_form.new_password_value, saved_form.new_password_value);
326 TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
327 // This test is the same as FormSubmitEmptyStore, except that it simulates the
328 // user generating the password through the browser.
329 std::vector<PasswordForm*> result; // Empty password store.
330 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
331 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
332 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
333 std::vector<PasswordForm> observed;
334 PasswordForm form(MakeSimpleForm());
335 observed.push_back(form);
336 manager()->OnPasswordFormsParsed(observed); // The initial load.
337 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
339 // Simulate the user generating the password and submitting the form.
340 manager()->SetFormHasGeneratedPassword(form);
341 manager()->ProvisionallySavePassword(form);
343 // The user should not be presented with an infobar as they have already given
344 // consent by using the generated password. The form should be saved once
345 // navigation occurs. The client will be informed that automatic saving has
347 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0));
348 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
349 scoped_ptr<PasswordFormManager> saved_form_manager;
350 EXPECT_CALL(client_, AutomaticPasswordSavePtr(_)).Times(Exactly(1))
351 .WillOnce(WithArg<0>(SaveToScopedPtr(&saved_form_manager)));
353 // Now the password manager waits for the navigation to complete.
355 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
356 manager()->OnPasswordFormsRendered(observed,
357 true); // The post-navigation layout.
360 TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
361 // Same as above, except with an existing form for the same signon realm,
362 // but different origin. Detailed cases like this are covered by
363 // PasswordFormManagerTest.
364 std::vector<PasswordForm*> result;
365 PasswordForm* existing_different = new PasswordForm(MakeSimpleForm());
366 existing_different->username_value = ASCIIToUTF16("google2");
367 result.push_back(existing_different);
368 EXPECT_CALL(driver_, FillPasswordForm(_));
369 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
370 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
372 std::vector<PasswordForm> observed;
373 PasswordForm form(MakeSimpleForm());
374 observed.push_back(form);
375 manager()->OnPasswordFormsParsed(observed); // The initial load.
376 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
377 manager()->ProvisionallySavePassword(form);
379 // We still expect an add, since we didn't have a good match.
380 scoped_ptr<PasswordFormManager> form_to_save;
381 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_))
382 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
384 // Now the password manager waits for the navigation to complete.
386 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
387 manager()->OnPasswordFormsRendered(observed,
388 true); // The post-navigation layout.
390 ASSERT_TRUE(form_to_save.get());
391 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
393 // Simulate saving the form.
394 form_to_save->Save();
397 TEST_F(PasswordManagerTest, FormSeenThenLeftPage) {
398 std::vector<PasswordForm*> result; // Empty password store.
399 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
400 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
401 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
402 std::vector<PasswordForm> observed;
403 PasswordForm form(MakeSimpleForm());
404 observed.push_back(form);
405 manager()->OnPasswordFormsParsed(observed); // The initial load.
406 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
408 // No message from the renderer that a password was submitted. No
410 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(0);
412 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
413 manager()->OnPasswordFormsRendered(observed,
414 true); // The post-navigation layout.
417 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) {
418 // Test that navigating in the page does not prevent us from showing the save
420 std::vector<PasswordForm*> result; // Empty password store.
421 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
422 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
423 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
424 std::vector<PasswordForm> observed;
425 PasswordForm form(MakeSimpleForm());
426 observed.push_back(form);
427 manager()->OnPasswordFormsParsed(observed); // The initial load.
428 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
430 // Simulate navigating in the page.
431 manager()->DidNavigateMainFrame(true);
433 // Simulate submitting the password.
434 OnPasswordFormSubmitted(form);
436 // Now the password manager waits for the navigation to complete.
437 scoped_ptr<PasswordFormManager> form_to_save;
438 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_))
439 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
442 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
443 manager()->OnPasswordFormsRendered(observed,
444 true); // The post-navigation layout.
446 ASSERT_FALSE(NULL == form_to_save.get());
447 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
449 // Simulate saving the form, as if the info bar was accepted.
450 form_to_save->Save();
453 // This test verifies a fix for http://crbug.com/236673
454 TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) {
455 std::vector<PasswordForm*> result; // Empty password store.
456 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
457 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
458 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
459 PasswordForm first_form(MakeSimpleForm());
460 first_form.origin = GURL("http://www.nytimes.com/");
461 first_form.action = GURL("https://myaccount.nytimes.com/auth/login");
462 first_form.signon_realm = "http://www.nytimes.com/";
463 PasswordForm second_form(MakeSimpleForm());
464 second_form.origin = GURL("https://myaccount.nytimes.com/auth/login");
465 second_form.action = GURL("https://myaccount.nytimes.com/auth/login");
466 second_form.signon_realm = "https://myaccount.nytimes.com/";
468 // Pretend that the form is hidden on the first page.
469 std::vector<PasswordForm> observed;
470 observed.push_back(first_form);
471 manager()->OnPasswordFormsParsed(observed);
473 manager()->OnPasswordFormsRendered(observed, true);
475 // Now navigate to a second page.
476 manager()->DidNavigateMainFrame(false);
478 // This page contains a form with the same markup, but on a different
480 observed.push_back(second_form);
481 manager()->OnPasswordFormsParsed(observed);
482 manager()->OnPasswordFormsRendered(observed, true);
484 // Now submit this form
485 OnPasswordFormSubmitted(second_form);
487 // Navigation after form submit.
488 scoped_ptr<PasswordFormManager> form_to_save;
489 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_))
490 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
492 manager()->OnPasswordFormsParsed(observed);
493 manager()->OnPasswordFormsRendered(observed, true);
495 // Make sure that the saved form matches the second form, not the first.
496 ASSERT_TRUE(form_to_save.get());
497 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(second_form)));
499 // Simulate saving the form, as if the info bar was accepted.
500 form_to_save->Save();
503 TEST_F(PasswordManagerTest, FormSubmitFailedLogin) {
504 std::vector<PasswordForm*> result; // Empty password store.
505 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
506 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
507 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
508 std::vector<PasswordForm> observed;
509 PasswordForm form(MakeSimpleForm());
510 observed.push_back(form);
511 manager()->OnPasswordFormsParsed(observed); // The initial load.
512 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
514 manager()->ProvisionallySavePassword(form);
516 // The form reappears, and is visible in the layout:
517 // No expected calls to the PasswordStore...
518 manager()->OnPasswordFormsParsed(observed);
519 manager()->OnPasswordFormsRendered(observed, true);
522 TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) {
523 // Tests fix of issue 28911: if the login form reappears on the subsequent
524 // page, but is invisible, it shouldn't count as a failed login.
525 std::vector<PasswordForm*> result; // Empty password store.
526 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
527 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
528 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
529 std::vector<PasswordForm> observed;
530 PasswordForm form(MakeSimpleForm());
531 observed.push_back(form);
532 manager()->OnPasswordFormsParsed(observed); // The initial load.
533 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
535 manager()->ProvisionallySavePassword(form);
537 // Expect info bar to appear:
538 scoped_ptr<PasswordFormManager> form_to_save;
539 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_))
540 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
542 // The form reappears, but is not visible in the layout:
543 manager()->OnPasswordFormsParsed(observed);
545 manager()->OnPasswordFormsRendered(observed, true);
547 ASSERT_TRUE(form_to_save.get());
548 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
550 // Simulate saving the form.
551 form_to_save->Save();
554 TEST_F(PasswordManagerTest, InitiallyInvisibleForm) {
555 // Make sure an invisible login form still gets autofilled.
556 std::vector<PasswordForm*> result;
557 PasswordForm* existing = new PasswordForm(MakeSimpleForm());
558 result.push_back(existing);
559 EXPECT_CALL(driver_, FillPasswordForm(_));
560 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
561 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
562 std::vector<PasswordForm> observed;
563 PasswordForm form(MakeSimpleForm());
564 observed.push_back(form);
565 manager()->OnPasswordFormsParsed(observed); // The initial load.
567 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
569 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
570 manager()->OnPasswordFormsRendered(observed,
571 true); // The post-navigation layout.
574 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
575 // Test that saving passwords depends on the password manager enabled
577 prefs_.SetUserPref(prefs::kPasswordManagerSavingEnabled,
578 new base::FundamentalValue(true));
579 EXPECT_TRUE(manager()->IsSavingEnabledForCurrentPage());
580 prefs_.SetUserPref(prefs::kPasswordManagerSavingEnabled,
581 new base::FundamentalValue(false));
582 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
585 TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) {
586 // Test fix for issue 158296: Passwords must be filled even if the password
587 // manager is disabled.
588 std::vector<PasswordForm*> result;
589 PasswordForm* existing = new PasswordForm(MakeSimpleForm());
590 result.push_back(existing);
591 prefs_.SetUserPref(prefs::kPasswordManagerSavingEnabled,
592 new base::FundamentalValue(false));
593 EXPECT_CALL(driver_, FillPasswordForm(_));
594 EXPECT_CALL(*store_.get(),
595 GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _))
596 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
597 std::vector<PasswordForm> observed;
598 PasswordForm form(MakeSimpleForm());
599 observed.push_back(form);
600 manager()->OnPasswordFormsParsed(observed);
603 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) {
604 // Test password form with non-generated password will be saved even if
606 std::vector<PasswordForm*> result; // Empty password store.
607 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
608 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
609 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
610 std::vector<PasswordForm> observed;
611 PasswordForm form(MakeSimpleForm());
612 form.password_autocomplete_set = false;
613 observed.push_back(form);
614 manager()->OnPasswordFormsParsed(observed); // The initial load.
615 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
617 // And the form submit contract is to call ProvisionallySavePassword.
618 manager()->ProvisionallySavePassword(form);
620 // Password form should be saved.
621 scoped_ptr<PasswordFormManager> form_to_save;
622 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(1))
623 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
624 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0));
626 // Now the password manager waits for the navigation to complete.
628 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
629 manager()->OnPasswordFormsRendered(observed,
630 true); // The post-navigation layout.
632 ASSERT_TRUE(form_to_save.get());
635 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
636 // Test password form with generated password will still be saved if
638 std::vector<PasswordForm*> result; // Empty password store.
639 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
640 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
641 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
642 std::vector<PasswordForm> observed;
643 PasswordForm form(MakeSimpleForm());
644 form.password_autocomplete_set = false;
645 observed.push_back(form);
646 manager()->OnPasswordFormsParsed(observed); // The initial load.
647 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
649 // Simulate the user generating the password and submitting the form.
650 manager()->SetFormHasGeneratedPassword(form);
651 manager()->ProvisionallySavePassword(form);
653 // The user should not be presented with an infobar as they have already given
654 // consent by using the generated password. The form should be saved once
655 // navigation occurs. The client will be informed that automatic saving has
657 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0));
658 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
659 scoped_ptr<PasswordFormManager> saved_form_manager;
660 EXPECT_CALL(client_, AutomaticPasswordSavePtr(_)).Times(Exactly(1))
661 .WillOnce(WithArg<0>(SaveToScopedPtr(&saved_form_manager)));
663 // Now the password manager waits for the navigation to complete.
665 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
666 manager()->OnPasswordFormsRendered(observed,
667 true); // The post-navigation layout.
670 TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
671 manager()->AddSubmissionCallback(SubmissionCallback());
672 PasswordForm form = MakeSimpleForm();
673 OnPasswordFormSubmitted(form);
674 EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
677 TEST_F(PasswordManagerTest, PasswordFormReappearance) {
678 // Test the heuristic to know if a password form reappears.
679 // We assume that if we send our credentials and there
680 // is at least one visible password form in the next page that
681 // means that our previous login attempt failed.
682 std::vector<PasswordForm*> result; // Empty password store.
683 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
684 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
685 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
686 std::vector<PasswordForm> observed;
687 PasswordForm login_form(MakeTwitterLoginForm());
688 observed.push_back(login_form);
689 manager()->OnPasswordFormsParsed(observed); // The initial load.
690 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
692 manager()->ProvisionallySavePassword(login_form);
694 PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
696 observed.push_back(failed_login_form);
697 // A PasswordForm appears, and is visible in the layout:
698 // No expected calls to the PasswordStore...
699 manager()->OnPasswordFormsParsed(observed);
700 manager()->OnPasswordFormsRendered(observed, true);
703 TEST_F(PasswordManagerTest, SavingNotEnabledOnSSLErrors) {
704 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
705 .WillRepeatedly(Return(true));
706 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
709 TEST_F(PasswordManagerTest, AutofillingNotEnabledOnSSLErrors) {
710 // Test that in the presence of SSL errors, the password manager does not
711 // attempt to autofill forms found on a website.
712 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
713 .WillRepeatedly(Return(true));
715 // Let us pretend some forms were found on a website.
716 std::vector<PasswordForm> forms;
717 forms.push_back(MakeSimpleForm());
719 // Feed those forms to |manager()| and check that it does not try to find
720 // matching saved credentials for the forms.
721 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)).Times(Exactly(0));
722 manager()->OnPasswordFormsParsed(forms);
725 TEST_F(PasswordManagerTest, SavingDisabledIfManagerDisabled) {
726 EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage())
727 .WillRepeatedly(Return(false));
728 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
731 TEST_F(PasswordManagerTest, AutofillingDisabledIfManagerDisabled) {
732 EXPECT_CALL(client_, IsPasswordManagerEnabledForCurrentPage())
733 .WillRepeatedly(Return(false));
735 // Let us pretend some forms were found on a website.
736 std::vector<PasswordForm> forms;
737 forms.push_back(MakeSimpleForm());
739 // Feed those forms to |manager()| and check that it does not try to find
740 // matching saved credentials for the forms.
741 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)).Times(Exactly(0));
742 manager()->OnPasswordFormsParsed(forms);
745 TEST_F(PasswordManagerTest, SyncCredentialsNotSaved) {
746 EXPECT_CALL(client_, IsSyncAccountCredential(_, _))
747 .WillRepeatedly(Return(true));
749 // Simulate loading a simple form with no existing stored password.
750 std::vector<PasswordForm*> result; // Empty password store.
751 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
752 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
753 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
754 std::vector<PasswordForm> observed;
755 PasswordForm form(MakeSimpleForm());
756 form.password_autocomplete_set = false;
757 observed.push_back(form);
758 manager()->OnPasswordFormsParsed(observed); // The initial load.
759 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
761 // User should not be prompted and password should not be saved.
762 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0));
763 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0));
765 // Submit form and finish navigation.
766 manager()->ProvisionallySavePassword(form);
768 manager()->OnPasswordFormsParsed(observed);
769 manager()->OnPasswordFormsRendered(observed, true);
772 // On failed login attempts, the retry-form can have action scheme changed from
773 // HTTP to HTTPS (see http://crbug.com/400769). Check that such retry-form is
774 // considered equal to the original login form, and the attempt recognised as a
776 TEST_F(PasswordManagerTest,
777 SeeingFormActionWithOnlyHttpHttpsChangeIsLoginFailure) {
778 std::vector<PasswordForm*> result; // Empty password store.
779 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
780 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
781 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
783 PasswordForm first_form(MakeSimpleForm());
784 first_form.origin = GURL("http://www.xda-developers.com/");
785 first_form.action = GURL("http://forum.xda-developers.com/login.php");
787 // |second_form|'s action differs only with it's scheme i.e. *https://*.
788 PasswordForm second_form(first_form);
789 second_form.action = GURL("https://forum.xda-developers.com/login.php");
791 std::vector<PasswordForm> observed;
792 observed.push_back(first_form);
793 manager()->OnPasswordFormsParsed(observed);
794 manager()->OnPasswordFormsRendered(observed, true);
797 // Now submit the |first_form|.
798 OnPasswordFormSubmitted(first_form);
800 // Simulate loading a page, which contains |second_form| instead of
802 observed.push_back(second_form);
804 // Verify that no prompt to save the password is shown.
805 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(Exactly(0));
806 manager()->OnPasswordFormsParsed(observed);
807 manager()->OnPasswordFormsRendered(observed, true);
811 // Create a form with a new_password_element. Submit the form with the empty
812 // new password value. It shouldn't overwrite the existing password.
813 TEST_F(PasswordManagerTest, DoNotUpdateWithEmptyPassword) {
814 std::vector<PasswordForm*> result; // Empty password store.
815 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
816 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
817 std::vector<PasswordForm> observed;
818 PasswordForm form(MakeSimpleForm());
819 form.new_password_element = ASCIIToUTF16("new_password_element");
820 form.new_password_value.clear();
821 observed.push_back(form);
822 manager()->OnPasswordFormsParsed(observed); // The initial load.
823 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
825 // And the form submit contract is to call ProvisionallySavePassword.
826 OnPasswordFormSubmitted(form);
828 scoped_ptr<PasswordFormManager> form_to_save;
829 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_)).Times(0);
831 // Now the password manager waits for the login to complete successfully.
833 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
834 manager()->OnPasswordFormsRendered(observed,
835 true); // The post-navigation layout.
838 TEST_F(PasswordManagerTest, FormSubmitWithOnlyPassowrdField) {
839 // Test to verify that on submitting the HTML password form without having
840 // username input filed shows password save promt and saves the password to
842 std::vector<PasswordForm*> result; // Empty password store.
843 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
844 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
845 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
846 std::vector<PasswordForm> observed;
848 // Loads passsword form without username input field.
849 PasswordForm form(MakeSimpleFormWithOnlyPasswordField());
850 observed.push_back(form);
851 manager()->OnPasswordFormsParsed(observed); // The initial load.
852 manager()->OnPasswordFormsRendered(observed, true); // The initial layout.
854 // And the form submit contract is to call ProvisionallySavePassword.
855 manager()->ProvisionallySavePassword(form);
857 scoped_ptr<PasswordFormManager> form_to_save;
858 EXPECT_CALL(client_, PromptUserToSavePasswordPtr(_))
859 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
861 // Now the password manager waits for the navigation to complete.
863 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
864 manager()->OnPasswordFormsRendered(observed,
865 true); // The post-navigation layout.
867 ASSERT_TRUE(form_to_save.get());
868 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
870 // Simulate saving the form, as if the info bar was accepted.
871 form_to_save->Save();
874 } // namespace password_manager