• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_store.h"
14 #include "components/password_manager/core/browser/password_autofill_manager.h"
15 #include "components/password_manager/core/browser/password_manager.h"
16 #include "components/password_manager/core/browser/password_manager_driver.h"
17 #include "components/password_manager/core/browser/password_store.h"
18 #include "components/password_manager/core/browser/stub_password_manager_client.h"
19 #include "components/password_manager/core/browser/stub_password_manager_driver.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 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
52  public:
53   MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&));
54   MOCK_METHOD0(GetPasswordManager, PasswordManager*());
55   MOCK_METHOD0(GetPasswordAutofillManager, PasswordAutofillManager*());
56   MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
57 };
58 
ACTION_P(InvokeConsumer,forms)59 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); }
60 
ACTION_P(SaveToScopedPtr,scoped)61 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); }
62 
63 class TestPasswordManager : public PasswordManager {
64  public:
TestPasswordManager(PasswordManagerClient * client)65   explicit TestPasswordManager(PasswordManagerClient* client)
66       : PasswordManager(client) {}
~TestPasswordManager()67   virtual ~TestPasswordManager() {}
68 
69  private:
70   DISALLOW_COPY_AND_ASSIGN(TestPasswordManager);
71 };
72 
73 }  // namespace
74 
75 class PasswordManagerTest : public testing::Test {
76  protected:
SetUp()77   virtual void SetUp() {
78     prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
79                                            true);
80 
81     store_ = new MockPasswordStore;
82     EXPECT_CALL(*store_, ReportMetrics()).Times(AnyNumber());
83     CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
84 
85     EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_));
86     EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_));
87     EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
88 
89     manager_.reset(new TestPasswordManager(&client_));
90     password_autofill_manager_.reset(
91         new PasswordAutofillManager(&client_, NULL));
92 
93     EXPECT_CALL(driver_, GetPasswordManager())
94         .WillRepeatedly(Return(manager_.get()));
95     EXPECT_CALL(driver_, GetPasswordAutofillManager())
96         .WillRepeatedly(Return(password_autofill_manager_.get()));
97   }
98 
TearDown()99   virtual void TearDown() {
100     store_->Shutdown();
101     store_ = NULL;
102   }
103 
MakeSimpleForm()104   PasswordForm MakeSimpleForm() {
105     PasswordForm form;
106     form.origin = GURL("http://www.google.com/a/LoginAuth");
107     form.action = GURL("http://www.google.com/a/Login");
108     form.username_element = ASCIIToUTF16("Email");
109     form.password_element = ASCIIToUTF16("Passwd");
110     form.username_value = ASCIIToUTF16("google");
111     form.password_value = ASCIIToUTF16("password");
112     // Default to true so we only need to add tests in autocomplete=off cases.
113     form.password_autocomplete_set = true;
114     form.submit_element = ASCIIToUTF16("signIn");
115     form.signon_realm = "http://www.google.com";
116     return form;
117   }
118 
119   // Reproduction of the form present on twitter's login page.
MakeTwitterLoginForm()120   PasswordForm MakeTwitterLoginForm() {
121     PasswordForm form;
122     form.origin = GURL("https://twitter.com/");
123     form.action = GURL("https://twitter.com/sessions");
124     form.username_element = ASCIIToUTF16("Email");
125     form.password_element = ASCIIToUTF16("Passwd");
126     form.username_value = ASCIIToUTF16("twitter");
127     form.password_value = ASCIIToUTF16("password");
128     form.password_autocomplete_set = true;
129     form.submit_element = ASCIIToUTF16("signIn");
130     form.signon_realm = "https://twitter.com";
131     return form;
132   }
133 
134   // Reproduction of the form present on twitter's failed login page.
MakeTwitterFailedLoginForm()135   PasswordForm MakeTwitterFailedLoginForm() {
136     PasswordForm form;
137     form.origin = GURL("https://twitter.com/login/error?redirect_after_login");
138     form.action = GURL("https://twitter.com/sessions");
139     form.username_element = ASCIIToUTF16("EmailField");
140     form.password_element = ASCIIToUTF16("PasswdField");
141     form.username_value = ASCIIToUTF16("twitter");
142     form.password_value = ASCIIToUTF16("password");
143     form.password_autocomplete_set = true;
144     form.submit_element = ASCIIToUTF16("signIn");
145     form.signon_realm = "https://twitter.com";
146     return form;
147   }
148 
FormsAreEqual(const autofill::PasswordForm & lhs,const autofill::PasswordForm & rhs)149   bool FormsAreEqual(const autofill::PasswordForm& lhs,
150                      const autofill::PasswordForm& rhs) {
151     if (lhs.origin != rhs.origin)
152       return false;
153     if (lhs.action != rhs.action)
154       return false;
155     if (lhs.username_element != rhs.username_element)
156       return false;
157     if (lhs.password_element != rhs.password_element)
158       return false;
159     if (lhs.username_value != rhs.username_value)
160       return false;
161     if (lhs.password_value != rhs.password_value)
162       return false;
163     if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
164       return false;
165     if (lhs.submit_element != rhs.submit_element)
166       return false;
167     if (lhs.signon_realm != rhs.signon_realm)
168       return false;
169     return true;
170   }
171 
manager()172   TestPasswordManager* manager() { return manager_.get(); }
173 
OnPasswordFormSubmitted(const autofill::PasswordForm & form)174   void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
175     manager()->OnPasswordFormSubmitted(form);
176   }
177 
SubmissionCallback()178   PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
179     return base::Bind(&PasswordManagerTest::FormSubmitted,
180                       base::Unretained(this));
181   }
182 
FormSubmitted(const autofill::PasswordForm & form)183   void FormSubmitted(const autofill::PasswordForm& form) {
184     submitted_form_ = form;
185   }
186 
187   TestingPrefServiceSimple prefs_;
188   scoped_refptr<MockPasswordStore> store_;
189   MockPasswordManagerClient client_;
190   MockPasswordManagerDriver driver_;
191   scoped_ptr<PasswordAutofillManager> password_autofill_manager_;
192   scoped_ptr<TestPasswordManager> manager_;
193   PasswordForm submitted_form_;
194 };
195 
196 MATCHER_P(FormMatches, form, "") {
197   return form.signon_realm == arg.signon_realm && form.origin == arg.origin &&
198          form.action == arg.action &&
199          form.username_element == arg.username_element &&
200          form.password_element == arg.password_element &&
201          form.password_autocomplete_set == arg.password_autocomplete_set &&
202          form.submit_element == arg.submit_element;
203 }
204 
TEST_F(PasswordManagerTest,FormSubmitEmptyStore)205 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
206   // Test that observing a newly submitted form shows the save password bar.
207   std::vector<PasswordForm*> result;  // Empty password store.
208   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
209   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
210       .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
211   std::vector<PasswordForm> observed;
212   PasswordForm form(MakeSimpleForm());
213   observed.push_back(form);
214   manager()->OnPasswordFormsParsed(observed);    // The initial load.
215   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
216 
217   // And the form submit contract is to call ProvisionallySavePassword.
218   manager()->ProvisionallySavePassword(form);
219 
220   scoped_ptr<PasswordFormManager> form_to_save;
221   EXPECT_CALL(client_, PromptUserToSavePassword(_))
222       .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
223 
224   // Now the password manager waits for the navigation to complete.
225   observed.clear();
226   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
227   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
228 
229   ASSERT_TRUE(form_to_save.get());
230   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
231 
232   // Simulate saving the form, as if the info bar was accepted.
233   form_to_save->Save();
234 }
235 
TEST_F(PasswordManagerTest,GeneratedPasswordFormSubmitEmptyStore)236 TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
237   // This test is the same FormSubmitEmptyStore, except that it simulates the
238   // user generating the password through the browser.
239   std::vector<PasswordForm*> result;  // Empty password store.
240   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
241   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
242       .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
243   std::vector<PasswordForm> observed;
244   PasswordForm form(MakeSimpleForm());
245   observed.push_back(form);
246   manager()->OnPasswordFormsParsed(observed);    // The initial load.
247   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
248 
249   // Simulate the user generating the password and submitting the form.
250   manager()->SetFormHasGeneratedPassword(form);
251   manager()->ProvisionallySavePassword(form);
252 
253   // The user should not be presented with an infobar as they have already given
254   // consent by using the generated password. The form should be saved once
255   // navigation occurs.
256   EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
257   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
258 
259   // Now the password manager waits for the navigation to complete.
260   observed.clear();
261   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
262   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
263 }
264 
TEST_F(PasswordManagerTest,FormSubmitNoGoodMatch)265 TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
266   // Same as above, except with an existing form for the same signon realm,
267   // but different origin.  Detailed cases like this are covered by
268   // PasswordFormManagerTest.
269   std::vector<PasswordForm*> result;
270   PasswordForm* existing_different = new PasswordForm(MakeSimpleForm());
271   existing_different->username_value = ASCIIToUTF16("google2");
272   result.push_back(existing_different);
273   EXPECT_CALL(driver_, FillPasswordForm(_));
274   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
275       .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
276 
277   std::vector<PasswordForm> observed;
278   PasswordForm form(MakeSimpleForm());
279   observed.push_back(form);
280   manager()->OnPasswordFormsParsed(observed);    // The initial load.
281   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
282   manager()->ProvisionallySavePassword(form);
283 
284   // We still expect an add, since we didn't have a good match.
285   scoped_ptr<PasswordFormManager> form_to_save;
286   EXPECT_CALL(client_, PromptUserToSavePassword(_))
287       .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
288 
289   // Now the password manager waits for the navigation to complete.
290   observed.clear();
291   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
292   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
293 
294   ASSERT_TRUE(form_to_save.get());
295   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
296 
297   // Simulate saving the form.
298   form_to_save->Save();
299 }
300 
TEST_F(PasswordManagerTest,FormSeenThenLeftPage)301 TEST_F(PasswordManagerTest, FormSeenThenLeftPage) {
302   std::vector<PasswordForm*> result;  // Empty password store.
303   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
304   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
305       .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
306   std::vector<PasswordForm> observed;
307   PasswordForm form(MakeSimpleForm());
308   observed.push_back(form);
309   manager()->OnPasswordFormsParsed(observed);    // The initial load.
310   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
311 
312   // No message from the renderer that a password was submitted. No
313   // expected calls.
314   EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(0);
315   observed.clear();
316   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
317   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
318 }
319 
TEST_F(PasswordManagerTest,FormSubmitAfterNavigateInPage)320 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) {
321   // Test that navigating in the page does not prevent us from showing the save
322   // password infobar.
323   std::vector<PasswordForm*> result;  // Empty password store.
324   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
325   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
326       .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
327   std::vector<PasswordForm> observed;
328   PasswordForm form(MakeSimpleForm());
329   observed.push_back(form);
330   manager()->OnPasswordFormsParsed(observed);    // The initial load.
331   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
332 
333   // Simulate navigating in the page.
334   manager()->DidNavigateMainFrame(true);
335 
336   // Simulate submitting the password.
337   OnPasswordFormSubmitted(form);
338 
339   // Now the password manager waits for the navigation to complete.
340   scoped_ptr<PasswordFormManager> form_to_save;
341   EXPECT_CALL(client_, PromptUserToSavePassword(_))
342       .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
343 
344   observed.clear();
345   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
346   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
347 
348   ASSERT_FALSE(NULL == form_to_save.get());
349   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
350 
351   // Simulate saving the form, as if the info bar was accepted.
352   form_to_save->Save();
353 }
354 
355 // This test verifies a fix for http://crbug.com/236673
TEST_F(PasswordManagerTest,FormSubmitWithFormOnPreviousPage)356 TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) {
357   std::vector<PasswordForm*> result;  // Empty password store.
358   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
359   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
360       .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
361   PasswordForm first_form(MakeSimpleForm());
362   first_form.origin = GURL("http://www.nytimes.com/");
363   first_form.action = GURL("https://myaccount.nytimes.com/auth/login");
364   first_form.signon_realm = "http://www.nytimes.com/";
365   PasswordForm second_form(MakeSimpleForm());
366   second_form.origin = GURL("https://myaccount.nytimes.com/auth/login");
367   second_form.action = GURL("https://myaccount.nytimes.com/auth/login");
368   second_form.signon_realm = "https://myaccount.nytimes.com/";
369 
370   // Pretend that the form is hidden on the first page.
371   std::vector<PasswordForm> observed;
372   observed.push_back(first_form);
373   manager()->OnPasswordFormsParsed(observed);
374   observed.clear();
375   manager()->OnPasswordFormsRendered(observed);
376 
377   // Now navigate to a second page.
378   manager()->DidNavigateMainFrame(false);
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(client_, PromptUserToSavePassword(_))
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 
TEST_F(PasswordManagerTest,FormSubmitFailedLogin)405 TEST_F(PasswordManagerTest, FormSubmitFailedLogin) {
406   std::vector<PasswordForm*> result;  // Empty password store.
407   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
408   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
409       .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
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 
TEST_F(PasswordManagerTest,FormSubmitInvisibleLogin)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(driver_, FillPasswordForm(_)).Times(Exactly(0));
429   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
430       .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
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(client_, PromptUserToSavePassword(_))
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 
TEST_F(PasswordManagerTest,InitiallyInvisibleForm)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(driver_, FillPasswordForm(_));
462   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
463       .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
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 
TEST_F(PasswordManagerTest,SavingDependsOnManagerEnabledPreference)475 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
476   // Test that saving passwords depends on the password manager enabled
477   // preference.
478   prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
479                      base::Value::CreateBooleanValue(true));
480   EXPECT_TRUE(manager()->IsSavingEnabledForCurrentPage());
481   prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
482                      base::Value::CreateBooleanValue(false));
483   EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
484 }
485 
TEST_F(PasswordManagerTest,FillPasswordsOnDisabledManager)486 TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) {
487   // Test fix for issue 158296: Passwords must be filled even if the password
488   // manager is disabled.
489   std::vector<PasswordForm*> result;
490   PasswordForm* existing = new PasswordForm(MakeSimpleForm());
491   result.push_back(existing);
492   prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
493                      base::Value::CreateBooleanValue(false));
494   EXPECT_CALL(driver_, FillPasswordForm(_));
495   EXPECT_CALL(*store_.get(),
496               GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _))
497       .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
498   std::vector<PasswordForm> observed;
499   PasswordForm form(MakeSimpleForm());
500   observed.push_back(form);
501   manager()->OnPasswordFormsParsed(observed);
502 }
503 
TEST_F(PasswordManagerTest,FormSavedWithAutocompleteOff)504 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) {
505   // Test password form with non-generated password will be saved even if
506   // autocomplete=off.
507   std::vector<PasswordForm*> result;  // Empty password store.
508   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
509   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
510       .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
511   std::vector<PasswordForm> observed;
512   PasswordForm form(MakeSimpleForm());
513   form.password_autocomplete_set = false;
514   observed.push_back(form);
515   manager()->OnPasswordFormsParsed(observed);    // The initial load.
516   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
517 
518   // And the form submit contract is to call ProvisionallySavePassword.
519   manager()->ProvisionallySavePassword(form);
520 
521   // Password form should be saved.
522   scoped_ptr<PasswordFormManager> form_to_save;
523   EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(1)).WillOnce(
524       WithArg<0>(SaveToScopedPtr(&form_to_save)));
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   ASSERT_TRUE(form_to_save.get());
533 }
534 
TEST_F(PasswordManagerTest,GeneratedPasswordFormSavedAutocompleteOff)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(driver_, 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(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
557   EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
558 
559   // Now the password manager waits for the navigation to complete.
560   observed.clear();
561   manager()->OnPasswordFormsParsed(observed);    // The post-navigation load.
562   manager()->OnPasswordFormsRendered(observed);  // The post-navigation layout.
563 }
564 
TEST_F(PasswordManagerTest,SubmissionCallbackTest)565 TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
566   manager()->AddSubmissionCallback(SubmissionCallback());
567   PasswordForm form = MakeSimpleForm();
568   OnPasswordFormSubmitted(form);
569   EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
570 }
571 
TEST_F(PasswordManagerTest,PasswordFormReappearance)572 TEST_F(PasswordManagerTest, PasswordFormReappearance) {
573   // Test the heuristic to know if a password form reappears.
574   // We assume that if we send our credentials and there
575   // is at least one visible password form in the next page that
576   // means that our previous login attempt failed.
577   std::vector<PasswordForm*> result;  // Empty password store.
578   EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
579   EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
580       .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
581   std::vector<PasswordForm> observed;
582   PasswordForm login_form(MakeTwitterLoginForm());
583   observed.push_back(login_form);
584   manager()->OnPasswordFormsParsed(observed);    // The initial load.
585   manager()->OnPasswordFormsRendered(observed);  // The initial layout.
586 
587   manager()->ProvisionallySavePassword(login_form);
588 
589   PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
590   observed.clear();
591   observed.push_back(failed_login_form);
592   // A PasswordForm appears, and is visible in the layout:
593   // No expected calls to the PasswordStore...
594   manager()->OnPasswordFormsParsed(observed);
595   manager()->OnPasswordFormsRendered(observed);
596 }
597 
TEST_F(PasswordManagerTest,SavingNotEnabledOnSSLErrors)598 TEST_F(PasswordManagerTest, SavingNotEnabledOnSSLErrors) {
599   EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
600       .WillRepeatedly(Return(true));
601   EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
602 }
603 
TEST_F(PasswordManagerTest,AutofillingNotEnabledOnSSLErrors)604 TEST_F(PasswordManagerTest, AutofillingNotEnabledOnSSLErrors) {
605   // Test that in the presence of SSL errors, the password manager does not
606   // attempt to autofill forms found on a website.
607   EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
608       .WillRepeatedly(Return(true));
609 
610   // Let us pretend some forms were found on a website.
611   std::vector<PasswordForm> forms;
612   forms.push_back(MakeSimpleForm());
613 
614   // Feed those forms to |manager()| and check that it does not try to find
615   // matching saved credentials for the forms.
616   EXPECT_CALL(*store_.get(), GetLogins(_, _, _)).Times(Exactly(0));
617   manager()->OnPasswordFormsParsed(forms);
618 }
619 
620 }  // namespace password_manager
621