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.
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_manager_driver.h"
14 #include "components/password_manager/core/browser/mock_password_store.h"
15 #include "components/password_manager/core/browser/password_autofill_manager.h"
16 #include "components/password_manager/core/browser/password_manager.h"
17 #include "components/password_manager/core/browser/password_manager_driver.h"
18 #include "components/password_manager/core/browser/password_store.h"
19 #include "components/password_manager/core/browser/stub_password_manager_client.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"
24 class PasswordGenerationManager;
26 using autofill::PasswordForm;
27 using base::ASCIIToUTF16;
29 using testing::AnyNumber;
31 using testing::Exactly;
32 using testing::Return;
33 using testing::WithArg;
36 class AutofillManager;
39 namespace password_manager {
43 class MockPasswordManagerClient : public StubPasswordManagerClient {
45 MOCK_METHOD1(PromptUserToSavePassword, void(PasswordFormManager*));
46 MOCK_METHOD0(GetPasswordStore, PasswordStore*());
47 MOCK_METHOD0(GetPrefs, PrefService*());
48 MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
51 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); }
53 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); }
55 class TestPasswordManager : public PasswordManager {
57 explicit TestPasswordManager(PasswordManagerClient* client)
58 : PasswordManager(client) {}
59 virtual ~TestPasswordManager() {}
62 DISALLOW_COPY_AND_ASSIGN(TestPasswordManager);
67 class PasswordManagerTest : public testing::Test {
69 virtual void SetUp() {
70 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
73 store_ = new MockPasswordStore;
74 CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
76 EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_));
77 EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_));
78 EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
80 manager_.reset(new TestPasswordManager(&client_));
81 password_autofill_manager_.reset(
82 new PasswordAutofillManager(&client_, NULL));
84 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
85 .WillRepeatedly(Return(false));
86 EXPECT_CALL(driver_, IsOffTheRecord()).WillRepeatedly(Return(false));
87 EXPECT_CALL(driver_, GetPasswordGenerationManager())
88 .WillRepeatedly(Return(static_cast<PasswordGenerationManager*>(NULL)));
89 EXPECT_CALL(driver_, GetPasswordManager())
90 .WillRepeatedly(Return(manager_.get()));
91 EXPECT_CALL(driver_, AllowPasswordGenerationForForm(_)).Times(AnyNumber());
92 EXPECT_CALL(driver_, GetPasswordAutofillManager())
93 .WillRepeatedly(Return(password_autofill_manager_.get()));
95 EXPECT_CALL(*store_, ReportMetricsImpl()).Times(AnyNumber());
98 virtual void TearDown() {
103 PasswordForm MakeSimpleForm() {
105 form.origin = GURL("http://www.google.com/a/LoginAuth");
106 form.action = GURL("http://www.google.com/a/Login");
107 form.username_element = ASCIIToUTF16("Email");
108 form.password_element = ASCIIToUTF16("Passwd");
109 form.username_value = ASCIIToUTF16("google");
110 form.password_value = ASCIIToUTF16("password");
111 // Default to true so we only need to add tests in autocomplete=off cases.
112 form.password_autocomplete_set = true;
113 form.submit_element = ASCIIToUTF16("signIn");
114 form.signon_realm = "http://www.google.com";
118 // Reproduction of the form present on twitter's login page.
119 PasswordForm MakeTwitterLoginForm() {
121 form.origin = GURL("https://twitter.com/");
122 form.action = GURL("https://twitter.com/sessions");
123 form.username_element = ASCIIToUTF16("Email");
124 form.password_element = ASCIIToUTF16("Passwd");
125 form.username_value = ASCIIToUTF16("twitter");
126 form.password_value = ASCIIToUTF16("password");
127 form.password_autocomplete_set = true;
128 form.submit_element = ASCIIToUTF16("signIn");
129 form.signon_realm = "https://twitter.com";
133 // Reproduction of the form present on twitter's failed login page.
134 PasswordForm MakeTwitterFailedLoginForm() {
136 form.origin = GURL("https://twitter.com/login/error?redirect_after_login");
137 form.action = GURL("https://twitter.com/sessions");
138 form.username_element = ASCIIToUTF16("EmailField");
139 form.password_element = ASCIIToUTF16("PasswdField");
140 form.username_value = ASCIIToUTF16("twitter");
141 form.password_value = ASCIIToUTF16("password");
142 form.password_autocomplete_set = true;
143 form.submit_element = ASCIIToUTF16("signIn");
144 form.signon_realm = "https://twitter.com";
148 bool FormsAreEqual(const autofill::PasswordForm& lhs,
149 const autofill::PasswordForm& rhs) {
150 if (lhs.origin != rhs.origin)
152 if (lhs.action != rhs.action)
154 if (lhs.username_element != rhs.username_element)
156 if (lhs.password_element != rhs.password_element)
158 if (lhs.username_value != rhs.username_value)
160 if (lhs.password_value != rhs.password_value)
162 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
164 if (lhs.submit_element != rhs.submit_element)
166 if (lhs.signon_realm != rhs.signon_realm)
171 TestPasswordManager* manager() { return manager_.get(); }
173 void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
174 manager()->OnPasswordFormSubmitted(form);
177 PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
178 return base::Bind(&PasswordManagerTest::FormSubmitted,
179 base::Unretained(this));
182 void FormSubmitted(const autofill::PasswordForm& form) {
183 submitted_form_ = form;
186 TestingPrefServiceSimple prefs_;
187 scoped_refptr<MockPasswordStore> store_;
188 MockPasswordManagerClient client_;
189 MockPasswordManagerDriver driver_;
190 scoped_ptr<PasswordAutofillManager> password_autofill_manager_;
191 scoped_ptr<TestPasswordManager> manager_;
192 PasswordForm submitted_form_;
195 MATCHER_P(FormMatches, form, "") {
196 return form.signon_realm == arg.signon_realm && form.origin == arg.origin &&
197 form.action == arg.action &&
198 form.username_element == arg.username_element &&
199 form.password_element == arg.password_element &&
200 form.password_autocomplete_set == arg.password_autocomplete_set &&
201 form.submit_element == arg.submit_element;
204 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
205 // Test that observing a newly submitted form shows the save password bar.
206 std::vector<PasswordForm*> result; // Empty password store.
207 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
208 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
209 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
210 std::vector<PasswordForm> observed;
211 PasswordForm form(MakeSimpleForm());
212 observed.push_back(form);
213 manager()->OnPasswordFormsParsed(observed); // The initial load.
214 manager()->OnPasswordFormsRendered(observed); // The initial layout.
216 // And the form submit contract is to call ProvisionallySavePassword.
217 manager()->ProvisionallySavePassword(form);
219 scoped_ptr<PasswordFormManager> form_to_save;
220 EXPECT_CALL(client_, PromptUserToSavePassword(_))
221 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
223 // Now the password manager waits for the navigation to complete.
225 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
226 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
228 ASSERT_TRUE(form_to_save.get());
229 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
231 // Simulate saving the form, as if the info bar was accepted.
232 form_to_save->Save();
235 TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
236 // This test is the same FormSubmitEmptyStore, except that it simulates the
237 // user generating the password through the browser.
238 std::vector<PasswordForm*> result; // Empty password store.
239 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
240 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
241 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
242 std::vector<PasswordForm> observed;
243 PasswordForm form(MakeSimpleForm());
244 observed.push_back(form);
245 manager()->OnPasswordFormsParsed(observed); // The initial load.
246 manager()->OnPasswordFormsRendered(observed); // The initial layout.
248 // Simulate the user generating the password and submitting the form.
249 manager()->SetFormHasGeneratedPassword(form);
250 manager()->ProvisionallySavePassword(form);
252 // The user should not be presented with an infobar as they have already given
253 // consent by using the generated password. The form should be saved once
254 // navigation occurs.
255 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
256 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
258 // Now the password manager waits for the navigation to complete.
260 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
261 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
264 TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
265 // Same as above, except with an existing form for the same signon realm,
266 // but different origin. Detailed cases like this are covered by
267 // PasswordFormManagerTest.
268 std::vector<PasswordForm*> result;
269 PasswordForm* existing_different = new PasswordForm(MakeSimpleForm());
270 existing_different->username_value = ASCIIToUTF16("google2");
271 result.push_back(existing_different);
272 EXPECT_CALL(driver_, FillPasswordForm(_));
273 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
274 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
276 std::vector<PasswordForm> observed;
277 PasswordForm form(MakeSimpleForm());
278 observed.push_back(form);
279 manager()->OnPasswordFormsParsed(observed); // The initial load.
280 manager()->OnPasswordFormsRendered(observed); // The initial layout.
281 manager()->ProvisionallySavePassword(form);
283 // We still expect an add, since we didn't have a good match.
284 scoped_ptr<PasswordFormManager> form_to_save;
285 EXPECT_CALL(client_, PromptUserToSavePassword(_))
286 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
288 // Now the password manager waits for the navigation to complete.
290 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
291 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
293 ASSERT_TRUE(form_to_save.get());
294 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
296 // Simulate saving the form.
297 form_to_save->Save();
300 TEST_F(PasswordManagerTest, FormSeenThenLeftPage) {
301 std::vector<PasswordForm*> result; // Empty password store.
302 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
303 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
304 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
305 std::vector<PasswordForm> observed;
306 PasswordForm form(MakeSimpleForm());
307 observed.push_back(form);
308 manager()->OnPasswordFormsParsed(observed); // The initial load.
309 manager()->OnPasswordFormsRendered(observed); // The initial layout.
311 // No message from the renderer that a password was submitted. No
313 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(0);
315 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
316 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
319 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) {
320 // Test that navigating in the page does not prevent us from showing the save
322 std::vector<PasswordForm*> result; // Empty password store.
323 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
324 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
325 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
326 std::vector<PasswordForm> observed;
327 PasswordForm form(MakeSimpleForm());
328 observed.push_back(form);
329 manager()->OnPasswordFormsParsed(observed); // The initial load.
330 manager()->OnPasswordFormsRendered(observed); // The initial layout.
332 // Simulate navigating in the page.
333 manager()->DidNavigateMainFrame(true);
335 // Simulate submitting the password.
336 OnPasswordFormSubmitted(form);
338 // Now the password manager waits for the navigation to complete.
339 scoped_ptr<PasswordFormManager> form_to_save;
340 EXPECT_CALL(client_, PromptUserToSavePassword(_))
341 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
344 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
345 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
347 ASSERT_FALSE(NULL == form_to_save.get());
348 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
350 // Simulate saving the form, as if the info bar was accepted.
351 form_to_save->Save();
354 // This test verifies a fix for http://crbug.com/236673
355 TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) {
356 std::vector<PasswordForm*> result; // Empty password store.
357 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
358 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
359 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
360 PasswordForm first_form(MakeSimpleForm());
361 first_form.origin = GURL("http://www.nytimes.com/");
362 first_form.action = GURL("https://myaccount.nytimes.com/auth/login");
363 first_form.signon_realm = "http://www.nytimes.com/";
364 PasswordForm second_form(MakeSimpleForm());
365 second_form.origin = GURL("https://myaccount.nytimes.com/auth/login");
366 second_form.action = GURL("https://myaccount.nytimes.com/auth/login");
367 second_form.signon_realm = "https://myaccount.nytimes.com/";
369 // Pretend that the form is hidden on the first page.
370 std::vector<PasswordForm> observed;
371 observed.push_back(first_form);
372 manager()->OnPasswordFormsParsed(observed);
374 manager()->OnPasswordFormsRendered(observed);
376 // Now navigate to a second page.
377 manager()->DidNavigateMainFrame(false);
379 // This page contains a form with the same markup, but on a different
381 observed.push_back(second_form);
382 manager()->OnPasswordFormsParsed(observed);
383 manager()->OnPasswordFormsRendered(observed);
385 // Now submit this form
386 OnPasswordFormSubmitted(second_form);
388 // Navigation after form submit.
389 scoped_ptr<PasswordFormManager> form_to_save;
390 EXPECT_CALL(client_, PromptUserToSavePassword(_))
391 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
393 manager()->OnPasswordFormsParsed(observed);
394 manager()->OnPasswordFormsRendered(observed);
396 // Make sure that the saved form matches the second form, not the first.
397 ASSERT_TRUE(form_to_save.get());
398 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(second_form)));
400 // Simulate saving the form, as if the info bar was accepted.
401 form_to_save->Save();
404 TEST_F(PasswordManagerTest, FormSubmitFailedLogin) {
405 std::vector<PasswordForm*> result; // Empty password store.
406 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
407 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
408 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
409 std::vector<PasswordForm> observed;
410 PasswordForm form(MakeSimpleForm());
411 observed.push_back(form);
412 manager()->OnPasswordFormsParsed(observed); // The initial load.
413 manager()->OnPasswordFormsRendered(observed); // The initial layout.
415 manager()->ProvisionallySavePassword(form);
417 // The form reappears, and is visible in the layout:
418 // No expected calls to the PasswordStore...
419 manager()->OnPasswordFormsParsed(observed);
420 manager()->OnPasswordFormsRendered(observed);
423 TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) {
424 // Tests fix of issue 28911: if the login form reappears on the subsequent
425 // page, but is invisible, it shouldn't count as a failed login.
426 std::vector<PasswordForm*> result; // Empty password store.
427 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
428 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
429 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
430 std::vector<PasswordForm> observed;
431 PasswordForm form(MakeSimpleForm());
432 observed.push_back(form);
433 manager()->OnPasswordFormsParsed(observed); // The initial load.
434 manager()->OnPasswordFormsRendered(observed); // The initial layout.
436 manager()->ProvisionallySavePassword(form);
438 // Expect info bar to appear:
439 scoped_ptr<PasswordFormManager> form_to_save;
440 EXPECT_CALL(client_, PromptUserToSavePassword(_))
441 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
443 // The form reappears, but is not visible in the layout:
444 manager()->OnPasswordFormsParsed(observed);
446 manager()->OnPasswordFormsRendered(observed);
448 ASSERT_TRUE(form_to_save.get());
449 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
451 // Simulate saving the form.
452 form_to_save->Save();
455 TEST_F(PasswordManagerTest, InitiallyInvisibleForm) {
456 // Make sure an invisible login form still gets autofilled.
457 std::vector<PasswordForm*> result;
458 PasswordForm* existing = new PasswordForm(MakeSimpleForm());
459 result.push_back(existing);
460 EXPECT_CALL(driver_, FillPasswordForm(_));
461 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
462 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
463 std::vector<PasswordForm> observed;
464 PasswordForm form(MakeSimpleForm());
465 observed.push_back(form);
466 manager()->OnPasswordFormsParsed(observed); // The initial load.
468 manager()->OnPasswordFormsRendered(observed); // The initial layout.
470 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
471 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
474 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
475 // Test that saving passwords depends on the password manager enabled
477 prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
478 base::Value::CreateBooleanValue(true));
479 EXPECT_TRUE(manager()->IsSavingEnabled());
480 prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
481 base::Value::CreateBooleanValue(false));
482 EXPECT_FALSE(manager()->IsSavingEnabled());
485 TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) {
486 // Test fix for issue 158296: Passwords must be filled even if the password
487 // manager is disabled.
488 std::vector<PasswordForm*> result;
489 PasswordForm* existing = new PasswordForm(MakeSimpleForm());
490 result.push_back(existing);
491 prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
492 base::Value::CreateBooleanValue(false));
493 EXPECT_CALL(driver_, FillPasswordForm(_));
494 EXPECT_CALL(*store_.get(),
495 GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _))
496 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
497 std::vector<PasswordForm> observed;
498 PasswordForm form(MakeSimpleForm());
499 observed.push_back(form);
500 manager()->OnPasswordFormsParsed(observed);
503 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) {
504 // Test password form with non-generated password will be saved even if
506 std::vector<PasswordForm*> result; // Empty password store.
507 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
508 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
509 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
510 std::vector<PasswordForm> observed;
511 PasswordForm form(MakeSimpleForm());
512 form.password_autocomplete_set = false;
513 observed.push_back(form);
514 manager()->OnPasswordFormsParsed(observed); // The initial load.
515 manager()->OnPasswordFormsRendered(observed); // The initial layout.
517 // And the form submit contract is to call ProvisionallySavePassword.
518 manager()->ProvisionallySavePassword(form);
520 // Password form should be saved.
521 scoped_ptr<PasswordFormManager> form_to_save;
522 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(1)).WillOnce(
523 WithArg<0>(SaveToScopedPtr(&form_to_save)));
524 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0));
526 // Now the password manager waits for the navigation to complete.
528 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
529 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
531 ASSERT_TRUE(form_to_save.get());
534 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
535 // Test password form with generated password will still be saved if
537 std::vector<PasswordForm*> result; // Empty password store.
538 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
539 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
540 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
541 std::vector<PasswordForm> observed;
542 PasswordForm form(MakeSimpleForm());
543 form.password_autocomplete_set = false;
544 observed.push_back(form);
545 manager()->OnPasswordFormsParsed(observed); // The initial load.
546 manager()->OnPasswordFormsRendered(observed); // The initial layout.
548 // Simulate the user generating the password and submitting the form.
549 manager()->SetFormHasGeneratedPassword(form);
550 manager()->ProvisionallySavePassword(form);
552 // The user should not be presented with an infobar as they have already given
553 // consent by using the generated password. The form should be saved once
554 // navigation occurs.
555 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
556 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
558 // Now the password manager waits for the navigation to complete.
560 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
561 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
564 TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
565 manager()->AddSubmissionCallback(SubmissionCallback());
566 PasswordForm form = MakeSimpleForm();
567 OnPasswordFormSubmitted(form);
568 EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
571 TEST_F(PasswordManagerTest, PasswordFormReappearance) {
572 // Test the heuristic to know if a password form reappears.
573 // We assume that if we send our credentials and there
574 // is at least one visible password form in the next page that
575 // means that our previous login attempt failed.
576 std::vector<PasswordForm*> result; // Empty password store.
577 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
578 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
579 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
580 std::vector<PasswordForm> observed;
581 PasswordForm login_form(MakeTwitterLoginForm());
582 observed.push_back(login_form);
583 manager()->OnPasswordFormsParsed(observed); // The initial load.
584 manager()->OnPasswordFormsRendered(observed); // The initial layout.
586 manager()->ProvisionallySavePassword(login_form);
588 PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
590 observed.push_back(failed_login_form);
591 // A PasswordForm appears, and is visible in the layout:
592 // No expected calls to the PasswordStore...
593 manager()->OnPasswordFormsParsed(observed);
594 manager()->OnPasswordFormsRendered(observed);
597 } // namespace password_manager