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