- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / password_manager / password_manager_unittest.cc
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/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/password_manager/mock_password_store.h"
11 #include "chrome/browser/password_manager/password_manager.h"
12 #include "chrome/browser/password_manager/password_manager_delegate.h"
13 #include "chrome/browser/password_manager/password_store.h"
14 #include "chrome/browser/password_manager/password_store_factory.h"
15 #include "chrome/common/pref_names.h"
16 #include "chrome/common/url_constants.h"
17 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
18 #include "chrome/test/base/testing_pref_service_syncable.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "content/public/browser/navigation_details.h"
21 #include "content/public/common/frame_navigate_params.h"
22 #include "content/public/test/test_browser_thread.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25
26 using autofill::PasswordForm;
27 using testing::_;
28 using testing::DoAll;
29 using testing::Exactly;
30 using testing::Return;
31 using testing::WithArg;
32
33 namespace {
34
35 class MockPasswordManagerDelegate : public PasswordManagerDelegate {
36  public:
37   MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&));
38   MOCK_METHOD1(AddSavePasswordInfoBarIfPermitted, void(PasswordFormManager*));
39   MOCK_METHOD0(GetProfile, Profile*());
40   MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
41 };
42
43 ACTION_P(InvokeConsumer, forms) {
44   arg0->OnGetPasswordStoreResults(forms);
45 }
46
47 ACTION_P(SaveToScopedPtr, scoped) {
48   scoped->reset(arg0);
49 }
50
51 class TestPasswordManager : public PasswordManager {
52  public:
53   TestPasswordManager(content::WebContents* contents,
54                       PasswordManagerDelegate* delegate)
55       : PasswordManager(contents, delegate) {}
56   virtual ~TestPasswordManager() {}
57
58   virtual void OnPasswordFormSubmitted(const PasswordForm& form) OVERRIDE {
59     PasswordManager::OnPasswordFormSubmitted(form);
60   }
61
62   static TestPasswordManager* CreateForWebContentsAndDelegate(
63       content::WebContents* contents,
64       PasswordManagerDelegate* delegate) {
65     TestPasswordManager* tpm = new TestPasswordManager(contents, delegate);
66     contents->SetUserData(UserDataKey(), tpm);
67     return tpm;
68   }
69
70  private:
71   DISALLOW_COPY_AND_ASSIGN(TestPasswordManager);
72 };
73
74 }  // namespace
75
76 class PasswordManagerTest : public ChromeRenderViewHostTestHarness {
77  protected:
78   virtual void SetUp() {
79     ChromeRenderViewHostTestHarness::SetUp();
80     store_ = static_cast<MockPasswordStore*>(
81         PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse(
82             profile(), MockPasswordStore::Build).get());
83
84     EXPECT_CALL(delegate_, GetProfile()).WillRepeatedly(Return(profile()));
85     manager_ = TestPasswordManager::CreateForWebContentsAndDelegate(
86         web_contents(), &delegate_);
87     EXPECT_CALL(delegate_, DidLastPageLoadEncounterSSLErrors())
88         .WillRepeatedly(Return(false));
89   }
90
91   virtual void TearDown() {
92     store_ = NULL;
93     ChromeRenderViewHostTestHarness::TearDown();
94   }
95
96   PasswordForm MakeSimpleForm() {
97     PasswordForm form;
98     form.origin = GURL("http://www.google.com/a/LoginAuth");
99     form.action = GURL("http://www.google.com/a/Login");
100     form.username_element = ASCIIToUTF16("Email");
101     form.password_element = ASCIIToUTF16("Passwd");
102     form.username_value = ASCIIToUTF16("google");
103     form.password_value = ASCIIToUTF16("password");
104     // Default to true so we only need to add tests in autocomplete=off cases.
105     form.password_autocomplete_set = true;
106     form.submit_element = ASCIIToUTF16("signIn");
107     form.signon_realm = "http://www.google.com";
108     return form;
109   }
110
111   // Reproduction of the form present on twitter's login page.
112   PasswordForm MakeTwitterLoginForm() {
113     PasswordForm form;
114     form.origin = GURL("https://twitter.com/");
115     form.action = GURL("https://twitter.com/sessions");
116     form.username_element = ASCIIToUTF16("Email");
117     form.password_element = ASCIIToUTF16("Passwd");
118     form.username_value = ASCIIToUTF16("twitter");
119     form.password_value = ASCIIToUTF16("password");
120     form.password_autocomplete_set = true;
121     form.submit_element = ASCIIToUTF16("signIn");
122     form.signon_realm = "https://twitter.com";
123     return form;
124   }
125
126   // Reproduction of the form present on twitter's failed login page.
127   PasswordForm MakeTwitterFailedLoginForm() {
128     PasswordForm form;
129     form.origin =
130         GURL("https://twitter.com/login/error?redirect_after_login");
131     form.action = GURL("https://twitter.com/sessions");
132     form.username_element = ASCIIToUTF16("EmailField");
133     form.password_element = ASCIIToUTF16("PasswdField");
134     form.username_value = ASCIIToUTF16("twitter");
135     form.password_value = ASCIIToUTF16("password");
136     form.password_autocomplete_set = true;
137     form.submit_element = ASCIIToUTF16("signIn");
138     form.signon_realm = "https://twitter.com";
139     return form;
140   }
141
142   bool FormsAreEqual(const autofill::PasswordForm& lhs,
143                      const autofill::PasswordForm& rhs) {
144     if (lhs.origin != rhs.origin)
145       return false;
146     if (lhs.action != rhs.action)
147       return false;
148     if (lhs.username_element != rhs.username_element)
149       return false;
150     if (lhs.password_element != rhs.password_element)
151       return false;
152     if (lhs.username_value != rhs.username_value)
153       return false;
154     if (lhs.password_value != rhs.password_value)
155       return false;
156     if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
157       return false;
158     if (lhs.submit_element != rhs.submit_element)
159       return false;
160     if (lhs.signon_realm != rhs.signon_realm)
161       return false;
162     return true;
163   }
164
165   TestPasswordManager* manager() {
166     return manager_;
167   }
168
169   void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
170     manager()->OnPasswordFormSubmitted(form);
171   }
172
173   PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
174     return base::Bind(&PasswordManagerTest::FormSubmitted,
175                       base::Unretained(this));
176   }
177
178   void FormSubmitted(const autofill::PasswordForm& form) {
179     submitted_form_ = form;
180   }
181
182   scoped_refptr<MockPasswordStore> store_;
183   TestPasswordManager* manager_;
184   MockPasswordManagerDelegate delegate_;  // Owned by manager_.
185   PasswordForm submitted_form_;
186 };
187
188 MATCHER_P(FormMatches, form, "") {
189   return form.signon_realm == arg.signon_realm &&
190          form.origin == arg.origin &&
191          form.action == arg.action &&
192          form.username_element == arg.username_element &&
193          form.password_element == arg.password_element &&
194          form.password_autocomplete_set ==
195              arg.password_autocomplete_set &&
196          form.submit_element == arg.submit_element;
197 }
198
199 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
200   // Test that observing a newly submitted form shows the save password bar.
201   std::vector<PasswordForm*> result;  // Empty password store.
202   EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
203   EXPECT_CALL(*store_.get(), GetLogins(_, _))
204       .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
205   std::vector<PasswordForm> observed;
206   PasswordForm form(MakeSimpleForm());
207   observed.push_back(form);
208   manager()->OnPasswordFormsParsed(observed);  // The initial load.
209   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
210
211   // And the form submit contract is to call ProvisionallySavePassword.
212   manager()->ProvisionallySavePassword(form);
213
214   scoped_ptr<PasswordFormManager> form_to_save;
215   EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_))
216       .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
217
218   // Now the password manager waits for the navigation to complete.
219   observed.clear();
220   manager()->OnPasswordFormsParsed(observed);  // The post-navigation load.
221   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
222
223   ASSERT_TRUE(form_to_save.get());
224   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
225
226   // Simulate saving the form, as if the info bar was accepted.
227   form_to_save->Save();
228 }
229
230 TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
231   // This test is the same FormSubmitEmptyStore, except that it simulates the
232   // user generating the password through the browser.
233   std::vector<PasswordForm*> result;  // Empty password store.
234   EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
235   EXPECT_CALL(*store_.get(), GetLogins(_, _))
236       .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
237   std::vector<PasswordForm> observed;
238   PasswordForm form(MakeSimpleForm());
239   observed.push_back(form);
240   manager()->OnPasswordFormsParsed(observed);  // The initial load.
241   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
242
243   // Simulate the user generating the password and submitting the form.
244   manager()->SetFormHasGeneratedPassword(form);
245   manager()->ProvisionallySavePassword(form);
246
247   // The user should not be presented with an infobar as they have already given
248   // consent by using the generated password. The form should be saved once
249   // navigation occurs.
250   EXPECT_CALL(delegate_,
251               AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0));
252   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
253
254   // Now the password manager waits for the navigation to complete.
255   observed.clear();
256   manager()->OnPasswordFormsParsed(observed);  // The post-navigation load.
257   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
258 }
259
260 TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
261   // Same as above, except with an existing form for the same signon realm,
262   // but different origin.  Detailed cases like this are covered by
263   // PasswordFormManagerTest.
264   std::vector<PasswordForm*> result;
265   PasswordForm* existing_different = new PasswordForm(MakeSimpleForm());
266   existing_different->username_value = ASCIIToUTF16("google2");
267   result.push_back(existing_different);
268   EXPECT_CALL(delegate_, FillPasswordForm(_));
269   EXPECT_CALL(*store_.get(), GetLogins(_, _))
270       .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
271
272   std::vector<PasswordForm> observed;
273   PasswordForm form(MakeSimpleForm());
274   observed.push_back(form);
275   manager()->OnPasswordFormsParsed(observed);  // The initial load.
276   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
277   manager()->ProvisionallySavePassword(form);
278
279   // We still expect an add, since we didn't have a good match.
280   scoped_ptr<PasswordFormManager> form_to_save;
281   EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_))
282       .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
283
284   // Now the password manager waits for the navigation to complete.
285   observed.clear();
286   manager()->OnPasswordFormsParsed(observed);  // The post-navigation load.
287   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
288
289   ASSERT_TRUE(form_to_save.get());
290   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
291
292   // Simulate saving the form.
293   form_to_save->Save();
294 }
295
296 TEST_F(PasswordManagerTest, FormSeenThenLeftPage) {
297   std::vector<PasswordForm*> result;  // Empty password store.
298   EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
299   EXPECT_CALL(*store_.get(), GetLogins(_, _))
300       .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
301   std::vector<PasswordForm> observed;
302   PasswordForm form(MakeSimpleForm());
303   observed.push_back(form);
304   manager()->OnPasswordFormsParsed(observed);  // The initial load.
305   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
306
307   // No message from the renderer that a password was submitted. No
308   // expected calls.
309   EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_)).Times(0);
310   observed.clear();
311   manager()->OnPasswordFormsParsed(observed);  // The post-navigation load.
312   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
313 }
314
315 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateSubframe) {
316   // Test that navigating a subframe does not prevent us from showing the save
317   // password infobar.
318   std::vector<PasswordForm*> result;  // Empty password store.
319   EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
320   EXPECT_CALL(*store_.get(), GetLogins(_, _))
321       .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
322   std::vector<PasswordForm> observed;
323   PasswordForm form(MakeSimpleForm());
324   observed.push_back(form);
325   manager()->OnPasswordFormsParsed(observed);  // The initial load.
326   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
327
328   // Simulate navigating a sub-frame.
329   content::LoadCommittedDetails details;
330   content::FrameNavigateParams params;
331   manager()->DidNavigateAnyFrame(details, params);
332
333   // Simulate submitting the password.
334   OnPasswordFormSubmitted(form);
335
336   // Now the password manager waits for the navigation to complete.
337   scoped_ptr<PasswordFormManager> form_to_save;
338   EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_))
339       .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
340
341   observed.clear();
342   manager()->OnPasswordFormsParsed(observed);  // The post-navigation load.
343   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
344
345   ASSERT_FALSE(NULL == form_to_save.get());
346   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
347
348   // Simulate saving the form, as if the info bar was accepted.
349   form_to_save->Save();
350 }
351
352 // This test verifies a fix for http://crbug.com/236673
353 TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) {
354   std::vector<PasswordForm*> result;  // Empty password store.
355   EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
356   EXPECT_CALL(*store_.get(), GetLogins(_, _))
357       .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
358   PasswordForm first_form(MakeSimpleForm());
359   first_form.origin = GURL("http://www.nytimes.com/");
360   first_form.action = GURL("https://myaccount.nytimes.com/auth/login");
361   first_form.signon_realm = "http://www.nytimes.com/";
362   PasswordForm second_form(MakeSimpleForm());
363   second_form.origin = GURL("https://myaccount.nytimes.com/auth/login");
364   second_form.action = GURL("https://myaccount.nytimes.com/auth/login");
365   second_form.signon_realm = "https://myaccount.nytimes.com/";
366
367   // Pretend that the form is hidden on the first page.
368   std::vector<PasswordForm> observed;
369   observed.push_back(first_form);
370   manager()->OnPasswordFormsParsed(observed);
371   observed.clear();
372   manager()->OnPasswordFormsRendered(observed);
373
374   // Now navigate to a second page.
375   content::LoadCommittedDetails details;
376   details.is_main_frame = true;
377   content::FrameNavigateParams params;
378   manager()->DidNavigateMainFrame(details, params);
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(delegate_, AddSavePasswordInfoBarIfPermitted(_))
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(delegate_, FillPasswordForm(_)).Times(Exactly(0));
408   EXPECT_CALL(*store_.get(), GetLogins(_, _))
409       .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
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(delegate_, FillPasswordForm(_)).Times(Exactly(0));
429   EXPECT_CALL(*store_.get(), GetLogins(_, _))
430       .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
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(delegate_, AddSavePasswordInfoBarIfPermitted(_))
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(delegate_, FillPasswordForm(_));
462   EXPECT_CALL(*store_.get(), GetLogins(_, _))
463       .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
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   TestingPrefServiceSyncable* prefService = profile()->GetTestingPrefService();
479   prefService->SetUserPref(prefs::kPasswordManagerEnabled,
480                            Value::CreateBooleanValue(true));
481   EXPECT_TRUE(manager()->IsSavingEnabled());
482   prefService->SetUserPref(prefs::kPasswordManagerEnabled,
483                            Value::CreateBooleanValue(false));
484   EXPECT_FALSE(manager()->IsSavingEnabled());
485 }
486
487 TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) {
488   // Test fix for issue 158296: Passwords must be filled even if the password
489   // manager is disabled.
490   std::vector<PasswordForm*> result;
491   PasswordForm* existing = new PasswordForm(MakeSimpleForm());
492   result.push_back(existing);
493   TestingPrefServiceSyncable* prefService = profile()->GetTestingPrefService();
494   prefService->SetUserPref(prefs::kPasswordManagerEnabled,
495                            Value::CreateBooleanValue(false));
496   EXPECT_CALL(delegate_, FillPasswordForm(_));
497   EXPECT_CALL(*store_.get(), GetLogins(_, _))
498       .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
499   std::vector<PasswordForm> observed;
500   PasswordForm form(MakeSimpleForm());
501   observed.push_back(form);
502   manager()->OnPasswordFormsParsed(observed);
503 }
504
505 TEST_F(PasswordManagerTest, FormNotSavedAutocompleteOff) {
506   // Test password form with non-generated password will not be saved if
507   // autocomplete=off.
508   std::vector<PasswordForm*> result;  // Empty password store.
509   EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
510   EXPECT_CALL(*store_.get(), GetLogins(_, _))
511       .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
512   std::vector<PasswordForm> observed;
513   PasswordForm form(MakeSimpleForm());
514   form.password_autocomplete_set = false;
515   observed.push_back(form);
516   manager()->OnPasswordFormsParsed(observed);  // The initial load.
517   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
518
519   // And the form submit contract is to call ProvisionallySavePassword.
520   manager()->ProvisionallySavePassword(form);
521
522   // Password form should not be saved.
523   EXPECT_CALL(delegate_,
524               AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0));
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
533 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
534   // Test password form with generated password will still be saved if
535   // autocomplete=off.
536   std::vector<PasswordForm*> result;  // Empty password store.
537   EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
538   EXPECT_CALL(*store_.get(), GetLogins(_, _))
539       .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
540   std::vector<PasswordForm> observed;
541   PasswordForm form(MakeSimpleForm());
542   form.password_autocomplete_set = false;
543   observed.push_back(form);
544   manager()->OnPasswordFormsParsed(observed);  // The initial load.
545   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
546
547   // Simulate the user generating the password and submitting the form.
548   manager()->SetFormHasGeneratedPassword(form);
549   manager()->ProvisionallySavePassword(form);
550
551   // The user should not be presented with an infobar as they have already given
552   // consent by using the generated password. The form should be saved once
553   // navigation occurs.
554   EXPECT_CALL(delegate_,
555               AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0));
556   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
557
558   // Now the password manager waits for the navigation to complete.
559   observed.clear();
560   manager()->OnPasswordFormsParsed(observed);  // The post-navigation load.
561   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
562 }
563
564 TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
565   manager()->AddSubmissionCallback(SubmissionCallback());
566   PasswordForm form = MakeSimpleForm();
567   OnPasswordFormSubmitted(form);
568   EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
569 }
570
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(delegate_, FillPasswordForm(_)).Times(0);
578   EXPECT_CALL(*store_.get(), GetLogins(_, _))
579       .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
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.
585
586   manager()->ProvisionallySavePassword(login_form);
587
588   PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
589   observed.clear();
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);
595 }