Home | History | Annotate | Download | only in browser
      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 
     59 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); }
     60 
     61 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); }
     62 
     63 class TestPasswordManager : public PasswordManager {
     64  public:
     65   explicit TestPasswordManager(PasswordManagerClient* client)
     66       : PasswordManager(client) {}
     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:
     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 
     99   virtual void TearDown() {
    100     store_->Shutdown();
    101     store_ = NULL;
    102   }
    103 
    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.
    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.
    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 
    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 
    172   TestPasswordManager* manager() { return manager_.get(); }
    173 
    174   void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
    175     manager()->OnPasswordFormSubmitted(form);
    176   }
    177 
    178   PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
    179     return base::Bind(&PasswordManagerTest::FormSubmitted,
    180                       base::Unretained(this));
    181   }
    182 
    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 
    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 
    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 
    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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    598 TEST_F(PasswordManagerTest, SavingNotEnabledOnSSLErrors) {
    599   EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
    600       .WillRepeatedly(Return(true));
    601   EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
    602 }
    603 
    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