Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / password_manager / core / browser / 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/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"
23
24 class PasswordGenerationManager;
25
26 using autofill::PasswordForm;
27 using base::ASCIIToUTF16;
28 using testing::_;
29 using testing::AnyNumber;
30 using testing::DoAll;
31 using testing::Exactly;
32 using testing::Return;
33 using testing::WithArg;
34
35 namespace autofill {
36 class AutofillManager;
37 }
38
39 namespace password_manager {
40
41 namespace {
42
43 class MockPasswordManagerClient : public StubPasswordManagerClient {
44  public:
45   MOCK_METHOD1(PromptUserToSavePassword, void(PasswordFormManager*));
46   MOCK_METHOD0(GetPasswordStore, PasswordStore*());
47   MOCK_METHOD0(GetPrefs, PrefService*());
48   MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
49 };
50
51 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); }
52
53 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); }
54
55 class TestPasswordManager : public PasswordManager {
56  public:
57   explicit TestPasswordManager(PasswordManagerClient* client)
58       : PasswordManager(client) {}
59   virtual ~TestPasswordManager() {}
60
61  private:
62   DISALLOW_COPY_AND_ASSIGN(TestPasswordManager);
63 };
64
65 }  // namespace
66
67 class PasswordManagerTest : public testing::Test {
68  protected:
69   virtual void SetUp() {
70     prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
71                                            true);
72
73     store_ = new MockPasswordStore;
74     CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
75
76     EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_));
77     EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_));
78     EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
79
80     manager_.reset(new TestPasswordManager(&client_));
81     password_autofill_manager_.reset(
82         new PasswordAutofillManager(&client_, NULL));
83
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()));
94
95     EXPECT_CALL(*store_, ReportMetricsImpl()).Times(AnyNumber());
96   }
97
98   virtual void TearDown() {
99     store_->Shutdown();
100     store_ = NULL;
101   }
102
103   PasswordForm MakeSimpleForm() {
104     PasswordForm form;
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";
115     return form;
116   }
117
118   // Reproduction of the form present on twitter's login page.
119   PasswordForm MakeTwitterLoginForm() {
120     PasswordForm form;
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";
130     return form;
131   }
132
133   // Reproduction of the form present on twitter's failed login page.
134   PasswordForm MakeTwitterFailedLoginForm() {
135     PasswordForm form;
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";
145     return form;
146   }
147
148   bool FormsAreEqual(const autofill::PasswordForm& lhs,
149                      const autofill::PasswordForm& rhs) {
150     if (lhs.origin != rhs.origin)
151       return false;
152     if (lhs.action != rhs.action)
153       return false;
154     if (lhs.username_element != rhs.username_element)
155       return false;
156     if (lhs.password_element != rhs.password_element)
157       return false;
158     if (lhs.username_value != rhs.username_value)
159       return false;
160     if (lhs.password_value != rhs.password_value)
161       return false;
162     if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
163       return false;
164     if (lhs.submit_element != rhs.submit_element)
165       return false;
166     if (lhs.signon_realm != rhs.signon_realm)
167       return false;
168     return true;
169   }
170
171   TestPasswordManager* manager() { return manager_.get(); }
172
173   void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
174     manager()->OnPasswordFormSubmitted(form);
175   }
176
177   PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
178     return base::Bind(&PasswordManagerTest::FormSubmitted,
179                       base::Unretained(this));
180   }
181
182   void FormSubmitted(const autofill::PasswordForm& form) {
183     submitted_form_ = form;
184   }
185
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_;
193 };
194
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;
202 }
203
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.
215
216   // And the form submit contract is to call ProvisionallySavePassword.
217   manager()->ProvisionallySavePassword(form);
218
219   scoped_ptr<PasswordFormManager> form_to_save;
220   EXPECT_CALL(client_, PromptUserToSavePassword(_))
221       .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
222
223   // Now the password manager waits for the navigation to complete.
224   observed.clear();
225   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
226   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
227
228   ASSERT_TRUE(form_to_save.get());
229   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
230
231   // Simulate saving the form, as if the info bar was accepted.
232   form_to_save->Save();
233 }
234
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.
247
248   // Simulate the user generating the password and submitting the form.
249   manager()->SetFormHasGeneratedPassword(form);
250   manager()->ProvisionallySavePassword(form);
251
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)));
257
258   // Now the password manager waits for the navigation to complete.
259   observed.clear();
260   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
261   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
262 }
263
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()));
275
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);
282
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)));
287
288   // Now the password manager waits for the navigation to complete.
289   observed.clear();
290   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
291   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
292
293   ASSERT_TRUE(form_to_save.get());
294   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
295
296   // Simulate saving the form.
297   form_to_save->Save();
298 }
299
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.
310
311   // No message from the renderer that a password was submitted. No
312   // expected calls.
313   EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(0);
314   observed.clear();
315   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
316   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
317 }
318
319 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) {
320   // Test that navigating in the page does not prevent us from showing the save
321   // password infobar.
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.
331
332   // Simulate navigating in the page.
333   manager()->DidNavigateMainFrame(true);
334
335   // Simulate submitting the password.
336   OnPasswordFormSubmitted(form);
337
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)));
342
343   observed.clear();
344   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
345   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
346
347   ASSERT_FALSE(NULL == form_to_save.get());
348   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
349
350   // Simulate saving the form, as if the info bar was accepted.
351   form_to_save->Save();
352 }
353
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/";
368
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);
373   observed.clear();
374   manager()->OnPasswordFormsRendered(observed);
375
376   // Now navigate to a second page.
377   manager()->DidNavigateMainFrame(false);
378
379   // This page contains a form with the same markup, but on a different
380   // URL.
381   observed.push_back(second_form);
382   manager()->OnPasswordFormsParsed(observed);
383   manager()->OnPasswordFormsRendered(observed);
384
385   // Now submit this form
386   OnPasswordFormSubmitted(second_form);
387
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)));
392   observed.clear();
393   manager()->OnPasswordFormsParsed(observed);
394   manager()->OnPasswordFormsRendered(observed);
395
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)));
399
400   // Simulate saving the form, as if the info bar was accepted.
401   form_to_save->Save();
402 }
403
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.
414
415   manager()->ProvisionallySavePassword(form);
416
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);
421 }
422
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.
435
436   manager()->ProvisionallySavePassword(form);
437
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)));
442
443   // The form reappears, but is not visible in the layout:
444   manager()->OnPasswordFormsParsed(observed);
445   observed.clear();
446   manager()->OnPasswordFormsRendered(observed);
447
448   ASSERT_TRUE(form_to_save.get());
449   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
450
451   // Simulate saving the form.
452   form_to_save->Save();
453 }
454
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.
467   observed.clear();
468   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
469
470   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
471   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
472 }
473
474 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
475   // Test that saving passwords depends on the password manager enabled
476   // preference.
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());
483 }
484
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);
501 }
502
503 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) {
504   // Test password form with non-generated password will be saved even if
505   // autocomplete=off.
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.
516
517   // And the form submit contract is to call ProvisionallySavePassword.
518   manager()->ProvisionallySavePassword(form);
519
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));
525
526   // Now the password manager waits for the navigation to complete.
527   observed.clear();
528   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
529   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
530
531   ASSERT_TRUE(form_to_save.get());
532 }
533
534 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
535   // Test password form with generated password will still be saved if
536   // autocomplete=off.
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.
547
548   // Simulate the user generating the password and submitting the form.
549   manager()->SetFormHasGeneratedPassword(form);
550   manager()->ProvisionallySavePassword(form);
551
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)));
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(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.
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 }
596
597 }  // namespace password_manager