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 "base/memory/scoped_ptr.h"
      6 #include "base/message_loop/message_loop.h"
      7 #include "base/prefs/pref_registry_simple.h"
      8 #include "base/prefs/pref_service.h"
      9 #include "base/prefs/testing_pref_service.h"
     10 #include "base/run_loop.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/strings/utf_string_conversions.h"
     13 #include "components/autofill/core/common/password_form.h"
     14 #include "components/password_manager/core/browser/mock_password_store.h"
     15 #include "components/password_manager/core/browser/password_form_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/browser/stub_password_manager_driver.h"
     21 #include "components/password_manager/core/browser/test_password_store.h"
     22 #include "components/password_manager/core/common/password_manager_pref_names.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::Eq;
     30 using ::testing::Mock;
     31 using ::testing::Return;
     32 
     33 namespace autofill {
     34 class AutofillManager;
     35 }
     36 
     37 namespace password_manager {
     38 
     39 namespace {
     40 
     41 void RunAllPendingTasks() {
     42   base::RunLoop run_loop;
     43   base::MessageLoop::current()->PostTask(
     44       FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
     45   run_loop.Run();
     46 }
     47 
     48 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
     49  public:
     50   MOCK_METHOD0(IsOffTheRecord, bool());
     51   MOCK_METHOD1(AllowPasswordGenerationForForm, void(autofill::PasswordForm*));
     52 };
     53 
     54 class TestPasswordManagerClient : public StubPasswordManagerClient {
     55  public:
     56   explicit TestPasswordManagerClient(PasswordStore* password_store)
     57       : password_store_(password_store) {
     58     prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
     59                                            true);
     60   }
     61 
     62   virtual void PromptUserToSavePassword(PasswordFormManager* form_to_save)
     63       OVERRIDE {}
     64   virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
     65   virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_; }
     66   virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
     67   virtual void AuthenticateAutofillAndFillForm(
     68       scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
     69     driver_.FillPasswordForm(*fill_data.get());
     70   }
     71 
     72   MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
     73 
     74  private:
     75   TestingPrefServiceSimple prefs_;
     76   PasswordStore* password_store_;
     77   MockPasswordManagerDriver driver_;
     78 };
     79 
     80 class TestPasswordManager : public PasswordManager {
     81  public:
     82   explicit TestPasswordManager(PasswordManagerClient* client)
     83       : PasswordManager(client) {}
     84 
     85   virtual void Autofill(const autofill::PasswordForm& form_for_autofill,
     86                         const autofill::PasswordFormMap& best_matches,
     87                         const autofill::PasswordForm& preferred_match,
     88                         bool wait_for_username) const OVERRIDE {
     89     best_matches_ = best_matches;
     90   }
     91 
     92   const autofill::PasswordFormMap& GetLatestBestMatches() {
     93     return best_matches_;
     94   }
     95 
     96  private:
     97   // Marked mutable to get around constness of Autofill().
     98   mutable autofill::PasswordFormMap best_matches_;
     99 };
    100 
    101 }  // namespace
    102 
    103 class PasswordFormManagerTest : public testing::Test {
    104  public:
    105   PasswordFormManagerTest() {}
    106 
    107   virtual void SetUp() {
    108     observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
    109     observed_form_.action = GURL("http://accounts.google.com/a/Login");
    110     observed_form_.username_element = ASCIIToUTF16("Email");
    111     observed_form_.password_element = ASCIIToUTF16("Passwd");
    112     observed_form_.submit_element = ASCIIToUTF16("signIn");
    113     observed_form_.signon_realm = "http://accounts.google.com";
    114 
    115     saved_match_ = observed_form_;
    116     saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
    117     saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
    118     saved_match_.preferred = true;
    119     saved_match_.username_value = ASCIIToUTF16("test (at) gmail.com");
    120     saved_match_.password_value = ASCIIToUTF16("test1");
    121     saved_match_.other_possible_usernames.push_back(
    122         ASCIIToUTF16("test2 (at) gmail.com"));
    123   }
    124 
    125   virtual void TearDown() {
    126     if (mock_store_)
    127       mock_store_->Shutdown();
    128   }
    129 
    130   void InitializeMockStore() {
    131     if (!mock_store_) {
    132       mock_store_ = new MockPasswordStore();
    133       ASSERT_TRUE(mock_store_);
    134     }
    135   }
    136 
    137   MockPasswordStore* mock_store() const { return mock_store_.get(); }
    138 
    139   PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
    140     return &p->pending_credentials_;
    141   }
    142 
    143   void SimulateMatchingPhase(PasswordFormManager* p, bool find_match) {
    144     // Roll up the state to mock out the matching phase.
    145     p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
    146     if (!find_match)
    147       return;
    148 
    149     PasswordForm* match = new PasswordForm(saved_match_);
    150     // Heap-allocated form is owned by p.
    151     p->best_matches_[match->username_value] = match;
    152     p->preferred_match_ = match;
    153   }
    154 
    155   void SimulateFetchMatchingLoginsFromPasswordStore(
    156       PasswordFormManager* manager) {
    157     // Just need to update the internal states.
    158     manager->state_ = PasswordFormManager::MATCHING_PHASE;
    159   }
    160 
    161   void SimulateResponseFromPasswordStore(
    162       PasswordFormManager* manager,
    163       const std::vector<PasswordForm*>& result) {
    164     // Simply call the callback method when request done. This will transfer
    165     // the ownership of the objects in |result| to the |manager|.
    166     manager->OnGetPasswordStoreResults(result);
    167   }
    168 
    169   void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
    170     p->SanitizePossibleUsernames(form);
    171   }
    172 
    173   bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
    174     return p->IgnoreResult(*form);
    175   }
    176 
    177   PasswordForm* observed_form() { return &observed_form_; }
    178   PasswordForm* saved_match() { return &saved_match_; }
    179   PasswordForm* CreateSavedMatch(bool blacklisted) {
    180     // Owned by the caller of this method.
    181     PasswordForm* match = new PasswordForm(saved_match_);
    182     match->blacklisted_by_user = blacklisted;
    183     return match;
    184   }
    185 
    186  private:
    187   PasswordForm observed_form_;
    188   PasswordForm saved_match_;
    189   scoped_refptr<MockPasswordStore> mock_store_;
    190 };
    191 
    192 TEST_F(PasswordFormManagerTest, TestNewLogin) {
    193   scoped_ptr<TestPasswordManagerClient> client(
    194       new TestPasswordManagerClient(NULL));
    195   scoped_ptr<StubPasswordManagerDriver> driver;
    196   PasswordFormManager* manager = new PasswordFormManager(
    197       NULL, client.get(), driver.get(), *observed_form(), false);
    198 
    199   SimulateMatchingPhase(manager, false);
    200   // User submits credentials for the observed form.
    201   PasswordForm credentials = *observed_form();
    202   credentials.username_value = saved_match()->username_value;
    203   credentials.password_value = saved_match()->password_value;
    204   credentials.preferred = true;
    205   manager->ProvisionallySave(
    206       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
    207 
    208   // Successful login. The PasswordManager would instruct PasswordFormManager
    209   // to save, which should know this is a new login.
    210   EXPECT_TRUE(manager->IsNewLogin());
    211   // Make sure the credentials that would be submitted on successful login
    212   // are going to match the stored entry in the db.
    213   EXPECT_EQ(observed_form()->origin.spec(),
    214             GetPendingCredentials(manager)->origin.spec());
    215   EXPECT_EQ(observed_form()->signon_realm,
    216             GetPendingCredentials(manager)->signon_realm);
    217   EXPECT_EQ(observed_form()->action, GetPendingCredentials(manager)->action);
    218   EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
    219   EXPECT_EQ(saved_match()->password_value,
    220             GetPendingCredentials(manager)->password_value);
    221   EXPECT_EQ(saved_match()->username_value,
    222             GetPendingCredentials(manager)->username_value);
    223 
    224   // Now, suppose the user re-visits the site and wants to save an additional
    225   // login for the site with a new username. In this case, the matching phase
    226   // will yield the previously saved login.
    227   SimulateMatchingPhase(manager, true);
    228   // Set up the new login.
    229   base::string16 new_user = ASCIIToUTF16("newuser");
    230   base::string16 new_pass = ASCIIToUTF16("newpass");
    231   credentials.username_value = new_user;
    232   credentials.password_value = new_pass;
    233   manager->ProvisionallySave(
    234       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
    235 
    236   // Again, the PasswordFormManager should know this is still a new login.
    237   EXPECT_TRUE(manager->IsNewLogin());
    238   // And make sure everything squares up again.
    239   EXPECT_EQ(observed_form()->origin.spec(),
    240             GetPendingCredentials(manager)->origin.spec());
    241   EXPECT_EQ(observed_form()->signon_realm,
    242             GetPendingCredentials(manager)->signon_realm);
    243   EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
    244   EXPECT_EQ(new_pass, GetPendingCredentials(manager)->password_value);
    245   EXPECT_EQ(new_user, GetPendingCredentials(manager)->username_value);
    246   delete manager;
    247 }
    248 
    249 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
    250   // Create a PasswordFormManager with observed_form, as if we just
    251   // saw this form and need to find matching logins.
    252   scoped_ptr<TestPasswordManagerClient> client(
    253       new TestPasswordManagerClient(NULL));
    254   scoped_ptr<StubPasswordManagerDriver> driver;
    255   PasswordFormManager* manager = new PasswordFormManager(
    256       NULL, client.get(), driver.get(), *observed_form(), false);
    257 
    258   SimulateMatchingPhase(manager, true);
    259 
    260   // User submits credentials for the observed form using a username previously
    261   // stored, but a new password. Note that the observed form may have different
    262   // origin URL (as it does in this case) than the saved_match, but we want to
    263   // make sure the updated password is reflected in saved_match, because that is
    264   // what we autofilled.
    265   base::string16 new_pass = ASCIIToUTF16("newpassword");
    266   PasswordForm credentials = *observed_form();
    267   credentials.username_value = saved_match()->username_value;
    268   credentials.password_value = new_pass;
    269   credentials.preferred = true;
    270   manager->ProvisionallySave(
    271       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
    272 
    273   // Successful login. The PasswordManager would instruct PasswordFormManager
    274   // to save, and since this is an update, it should know not to save as a new
    275   // login.
    276   EXPECT_FALSE(manager->IsNewLogin());
    277 
    278   // Make sure the credentials that would be submitted on successful login
    279   // are going to match the stored entry in the db. (This verifies correct
    280   // behaviour for bug 1074420).
    281   EXPECT_EQ(GetPendingCredentials(manager)->origin.spec(),
    282             saved_match()->origin.spec());
    283   EXPECT_EQ(GetPendingCredentials(manager)->signon_realm,
    284             saved_match()->signon_realm);
    285   EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
    286   EXPECT_EQ(new_pass, GetPendingCredentials(manager)->password_value);
    287   // Done.
    288   delete manager;
    289 }
    290 
    291 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
    292   scoped_ptr<TestPasswordManagerClient> client(
    293       new TestPasswordManagerClient(NULL));
    294   scoped_ptr<StubPasswordManagerDriver> driver;
    295   PasswordFormManager* manager = new PasswordFormManager(
    296       NULL, client.get(), driver.get(), *observed_form(), false);
    297 
    298   // Make sure we don't match a PasswordForm if it was originally saved on
    299   // an SSL-valid page and we are now on a page with invalid certificate.
    300   saved_match()->ssl_valid = true;
    301   EXPECT_TRUE(IgnoredResult(manager, saved_match()));
    302 
    303   saved_match()->ssl_valid = false;
    304   // Different paths for action / origin are okay.
    305   saved_match()->action = GURL("http://www.google.com/b/Login");
    306   saved_match()->origin = GURL("http://www.google.com/foo");
    307   EXPECT_FALSE(IgnoredResult(manager, saved_match()));
    308 
    309   // Done.
    310   delete manager;
    311 }
    312 
    313 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
    314   scoped_ptr<TestPasswordManagerClient> client(
    315       new TestPasswordManagerClient(NULL));
    316   scoped_ptr<StubPasswordManagerDriver> driver;
    317   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    318       NULL, client.get(), driver.get(), *observed_form(), false));
    319 
    320   saved_match()->action = GURL();
    321   SimulateMatchingPhase(manager.get(), true);
    322   // User logs in with the autofilled username / password from saved_match.
    323   PasswordForm login = *observed_form();
    324   login.username_value = saved_match()->username_value;
    325   login.password_value = saved_match()->password_value;
    326   manager->ProvisionallySave(
    327       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
    328   EXPECT_FALSE(manager->IsNewLogin());
    329   // We bless our saved PasswordForm entry with the action URL of the
    330   // observed form.
    331   EXPECT_EQ(observed_form()->action,
    332             GetPendingCredentials(manager.get())->action);
    333 }
    334 
    335 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
    336   scoped_ptr<TestPasswordManagerClient> client(
    337       new TestPasswordManagerClient(NULL));
    338   scoped_ptr<StubPasswordManagerDriver> driver;
    339   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    340       NULL, client.get(), driver.get(), *observed_form(), false));
    341 
    342   SimulateMatchingPhase(manager.get(), true);
    343   // User logs in with the autofilled username / password from saved_match.
    344   PasswordForm login = *observed_form();
    345   login.username_value = saved_match()->username_value;
    346   login.password_value = saved_match()->password_value;
    347 
    348   manager->ProvisionallySave(
    349       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
    350   EXPECT_FALSE(manager->IsNewLogin());
    351   // The observed action URL is different from the previously saved one, and
    352   // is the same as the one that would be submitted on successful login.
    353   EXPECT_NE(observed_form()->action, saved_match()->action);
    354   EXPECT_EQ(observed_form()->action,
    355             GetPendingCredentials(manager.get())->action);
    356 }
    357 
    358 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
    359   scoped_ptr<TestPasswordManagerClient> client(
    360       new TestPasswordManagerClient(NULL));
    361   scoped_ptr<StubPasswordManagerDriver> driver;
    362   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    363       NULL, client.get(), driver.get(), *observed_form(), false));
    364 
    365   SimulateMatchingPhase(manager.get(), false);
    366   PasswordForm login(*observed_form());
    367   // The submitted action URL is different from the one observed on page load.
    368   GURL new_action = GURL("http://www.google.com/new_action");
    369   login.action = new_action;
    370 
    371   manager->ProvisionallySave(
    372       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
    373   EXPECT_TRUE(manager->IsNewLogin());
    374   // Check that the provisionally saved action URL is the same as the submitted
    375   // action URL, not the one observed on page load.
    376   EXPECT_EQ(new_action, GetPendingCredentials(manager.get())->action);
    377 }
    378 
    379 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
    380   // Need a MessageLoop for callbacks.
    381   base::MessageLoop message_loop;
    382   scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
    383   CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare()));
    384 
    385   TestPasswordManagerClient client(password_store.get());
    386   TestPasswordManager password_manager(&client);
    387   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    388       &password_manager, &client, client.GetDriver(), *observed_form(), false));
    389   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
    390       .Times(1);
    391   EXPECT_CALL(*client.GetMockDriver(), IsOffTheRecord())
    392       .WillRepeatedly(Return(false));
    393 
    394   password_store->AddLogin(*saved_match());
    395   manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
    396   RunAllPendingTasks();
    397 
    398   // The saved match has the right username already.
    399   PasswordForm login(*observed_form());
    400   login.username_value = saved_match()->username_value;
    401   login.password_value = saved_match()->password_value;
    402   login.preferred = true;
    403   manager->ProvisionallySave(
    404       login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
    405 
    406   EXPECT_FALSE(manager->IsNewLogin());
    407   manager->Save();
    408   RunAllPendingTasks();
    409 
    410   // Should be only one password stored, and should not have
    411   // |other_possible_usernames| set anymore.
    412   TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
    413   EXPECT_EQ(1U, passwords.size());
    414   ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
    415   EXPECT_EQ(saved_match()->username_value,
    416             passwords[saved_match()->signon_realm][0].username_value);
    417   EXPECT_EQ(0U,
    418             passwords[saved_match()->signon_realm][0]
    419                 .other_possible_usernames.size());
    420 
    421   // This time use an alternate username
    422   manager.reset(new PasswordFormManager(
    423       &password_manager, &client, client.GetDriver(), *observed_form(), false));
    424   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
    425       .Times(1);
    426   password_store->Clear();
    427   password_store->AddLogin(*saved_match());
    428   manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
    429   RunAllPendingTasks();
    430 
    431   base::string16 new_username = saved_match()->other_possible_usernames[0];
    432   login.username_value = new_username;
    433   manager->ProvisionallySave(
    434       login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
    435 
    436   EXPECT_FALSE(manager->IsNewLogin());
    437   manager->Save();
    438   RunAllPendingTasks();
    439 
    440   // |other_possible_usernames| should also be empty, but username_value should
    441   // be changed to match |new_username|
    442   passwords = password_store->stored_passwords();
    443   EXPECT_EQ(1U, passwords.size());
    444   ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
    445   EXPECT_EQ(new_username,
    446             passwords[saved_match()->signon_realm][0].username_value);
    447   EXPECT_EQ(0U,
    448             passwords[saved_match()->signon_realm][0]
    449                 .other_possible_usernames.size());
    450   password_store->Shutdown();
    451 }
    452 
    453 TEST_F(PasswordFormManagerTest, TestValidForms) {
    454   // User submits credentials for the observed form.
    455   PasswordForm credentials = *observed_form();
    456   credentials.scheme = PasswordForm::SCHEME_HTML;
    457   credentials.username_value = saved_match()->username_value;
    458   credentials.password_value = saved_match()->password_value;
    459 
    460   // Form with both username_element and password_element.
    461   PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
    462   SimulateMatchingPhase(&manager1, false);
    463   EXPECT_TRUE(manager1.HasValidPasswordForm());
    464 
    465   // Form without a username_element but with a password_element.
    466   credentials.username_element.clear();
    467   PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
    468   SimulateMatchingPhase(&manager2, false);
    469   EXPECT_FALSE(manager2.HasValidPasswordForm());
    470 
    471   // Form without a password_element but with a username_element.
    472   credentials.username_element = saved_match()->username_element;
    473   credentials.password_element.clear();
    474   PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
    475   SimulateMatchingPhase(&manager3, false);
    476   EXPECT_FALSE(manager3.HasValidPasswordForm());
    477 
    478   // Form with neither a password_element nor a username_element.
    479   credentials.username_element.clear();
    480   credentials.password_element.clear();
    481   PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
    482   SimulateMatchingPhase(&manager4, false);
    483   EXPECT_FALSE(manager4.HasValidPasswordForm());
    484 }
    485 
    486 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
    487   // User submits credentials for the observed form.
    488   PasswordForm credentials = *observed_form();
    489   credentials.scheme = PasswordForm::SCHEME_BASIC;
    490   credentials.username_value = saved_match()->username_value;
    491   credentials.password_value = saved_match()->password_value;
    492 
    493   // Form with both username_element and password_element.
    494   PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
    495   SimulateMatchingPhase(&manager1, false);
    496   EXPECT_TRUE(manager1.HasValidPasswordForm());
    497 
    498   // Form without a username_element but with a password_element.
    499   credentials.username_element.clear();
    500   PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
    501   SimulateMatchingPhase(&manager2, false);
    502   EXPECT_TRUE(manager2.HasValidPasswordForm());
    503 
    504   // Form without a password_element but with a username_element.
    505   credentials.username_element = saved_match()->username_element;
    506   credentials.password_element.clear();
    507   PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
    508   SimulateMatchingPhase(&manager3, false);
    509   EXPECT_TRUE(manager3.HasValidPasswordForm());
    510 
    511   // Form with neither a password_element nor a username_element.
    512   credentials.username_element.clear();
    513   credentials.password_element.clear();
    514   PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
    515   SimulateMatchingPhase(&manager4, false);
    516   EXPECT_TRUE(manager4.HasValidPasswordForm());
    517 }
    518 
    519 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
    520   base::MessageLoop message_loop;
    521 
    522   // A dumb password manager.
    523   TestPasswordManagerClient client(NULL);
    524   TestPasswordManager password_manager(&client);
    525   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    526       &password_manager, &client, client.GetDriver(), *observed_form(), false));
    527 
    528   // First time sign up attempt; No login result is found from password store;
    529   // We should send the not blacklisted message.
    530   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
    531       .Times(1);
    532   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
    533   std::vector<PasswordForm*> result;
    534   SimulateResponseFromPasswordStore(manager.get(), result);
    535   Mock::VerifyAndClearExpectations(client.GetMockDriver());
    536 
    537   // Sign up attempt to previously visited sites; Login result is found from
    538   // password store, and is not blacklisted; We should send the not blacklisted
    539   // message.
    540   manager.reset(new PasswordFormManager(
    541       &password_manager, &client, client.GetDriver(), *observed_form(), false));
    542   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
    543       .Times(1);
    544   EXPECT_CALL(*client.GetMockDriver(), IsOffTheRecord())
    545       .WillRepeatedly(Return(false));
    546   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
    547   // We need add heap allocated objects to result.
    548   result.push_back(CreateSavedMatch(false));
    549   SimulateResponseFromPasswordStore(manager.get(), result);
    550   Mock::VerifyAndClearExpectations(client.GetMockDriver());
    551 
    552   // Sign up attempt to previously visited sites; Login result is found from
    553   // password store, but is blacklisted; We should not send the not blacklisted
    554   // message.
    555   manager.reset(new PasswordFormManager(
    556       &password_manager, &client, client.GetDriver(), *observed_form(), false));
    557   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
    558       .Times(0);
    559   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
    560   result.clear();
    561   result.push_back(CreateSavedMatch(true));
    562   SimulateResponseFromPasswordStore(manager.get(), result);
    563   Mock::VerifyAndClearExpectations(client.GetMockDriver());
    564 }
    565 
    566 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
    567   base::MessageLoop message_loop;
    568 
    569   TestPasswordManagerClient client(NULL);
    570   TestPasswordManager password_manager(&client);
    571   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    572       &password_manager, &client, client.GetDriver(), *observed_form(), false));
    573   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
    574       .Times(1);
    575   EXPECT_CALL(*client.GetMockDriver(), IsOffTheRecord())
    576       .WillRepeatedly(Return(false));
    577 
    578   // Simulate having two matches for this origin, one of which was from a form
    579   // with different HTML tags for elements. Because of scoring differences,
    580   // only the first form will be sent to Autofill().
    581   std::vector<PasswordForm*> results;
    582   results.push_back(CreateSavedMatch(false));
    583   results.push_back(CreateSavedMatch(false));
    584   results[1]->username_value = ASCIIToUTF16("other (at) gmail.com");
    585   results[1]->password_element = ASCIIToUTF16("signup_password");
    586   results[1]->username_element = ASCIIToUTF16("signup_username");
    587   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
    588   SimulateResponseFromPasswordStore(manager.get(), results);
    589   EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
    590   results.clear();
    591 
    592   // Same thing, except this time the credentials that don't match quite as
    593   // well are generated. They should now be sent to Autofill().
    594   manager.reset(new PasswordFormManager(
    595       &password_manager, &client, client.GetDriver(), *observed_form(), false));
    596   EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
    597       .Times(1);
    598 
    599   results.push_back(CreateSavedMatch(false));
    600   results.push_back(CreateSavedMatch(false));
    601   results[1]->username_value = ASCIIToUTF16("other (at) gmail.com");
    602   results[1]->password_element = ASCIIToUTF16("signup_password");
    603   results[1]->username_element = ASCIIToUTF16("signup_username");
    604   results[1]->type = PasswordForm::TYPE_GENERATED;
    605   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
    606   SimulateResponseFromPasswordStore(manager.get(), results);
    607   EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
    608 }
    609 
    610 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
    611   scoped_ptr<TestPasswordManagerClient> client(
    612       new TestPasswordManagerClient(NULL));
    613   scoped_ptr<StubPasswordManagerDriver> driver;
    614   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    615       NULL, client.get(), driver.get(), *observed_form(), false));
    616   PasswordForm credentials(*observed_form());
    617   credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
    618   credentials.other_possible_usernames.push_back(
    619       ASCIIToUTF16("378282246310005"));
    620   credentials.other_possible_usernames.push_back(
    621       ASCIIToUTF16("other username"));
    622   credentials.username_value = ASCIIToUTF16("test (at) gmail.com");
    623 
    624   SanitizePossibleUsernames(manager.get(), &credentials);
    625 
    626   // Possible credit card number and SSN are stripped.
    627   std::vector<base::string16> expected;
    628   expected.push_back(ASCIIToUTF16("other username"));
    629   EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
    630 
    631   credentials.other_possible_usernames.clear();
    632   credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
    633   credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
    634   credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
    635   credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
    636   credentials.other_possible_usernames.push_back(
    637       ASCIIToUTF16("test (at) gmail.com"));
    638 
    639   SanitizePossibleUsernames(manager.get(), &credentials);
    640 
    641   // SSN, duplicate in |other_possible_usernames| and duplicate of
    642   // |username_value| all removed.
    643   expected.clear();
    644   expected.push_back(ASCIIToUTF16("duplicate"));
    645   expected.push_back(ASCIIToUTF16("random"));
    646   EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
    647 }
    648 
    649 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
    650   InitializeMockStore();
    651 
    652   // We've found this form on a website:
    653   PasswordForm encountered_form;
    654   encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
    655   encountered_form.signon_realm = "http://accounts.google.com/";
    656   encountered_form.action = GURL("http://accounts.google.com/Login");
    657   encountered_form.username_element = ASCIIToUTF16("Email");
    658   encountered_form.password_element = ASCIIToUTF16("Passwd");
    659   encountered_form.submit_element = ASCIIToUTF16("signIn");
    660 
    661   TestPasswordManagerClient client(mock_store());
    662   MockPasswordManagerDriver driver;
    663   EXPECT_CALL(driver, IsOffTheRecord()).WillRepeatedly(Return(false));
    664   EXPECT_CALL(driver, AllowPasswordGenerationForForm(_));
    665 
    666   TestPasswordManager manager(&client);
    667   PasswordFormManager form_manager(
    668       &manager, &client, &driver, encountered_form, false);
    669 
    670   const PasswordStore::AuthorizationPromptPolicy auth_policy =
    671       PasswordStore::DISALLOW_PROMPT;
    672   EXPECT_CALL(*mock_store(),
    673               GetLogins(encountered_form, auth_policy, &form_manager));
    674   form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
    675 
    676   // Password store only has these incomplete credentials.
    677   PasswordForm* incomplete_form = new PasswordForm();
    678   incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
    679   incomplete_form->signon_realm = "http://accounts.google.com/";
    680   incomplete_form->password_value = ASCIIToUTF16("my_password");
    681   incomplete_form->username_value = ASCIIToUTF16("my_username");
    682   incomplete_form->preferred = true;
    683   incomplete_form->ssl_valid = false;
    684   incomplete_form->scheme = PasswordForm::SCHEME_HTML;
    685 
    686   // We expect to see this form eventually sent to the Password store. It
    687   // has password/username values from the store and 'username_element',
    688   // 'password_element', 'submit_element' and 'action' fields copied from
    689   // the encountered form.
    690   PasswordForm complete_form(*incomplete_form);
    691   complete_form.action = encountered_form.action;
    692   complete_form.password_element = encountered_form.password_element;
    693   complete_form.username_element = encountered_form.username_element;
    694   complete_form.submit_element = encountered_form.submit_element;
    695 
    696   PasswordForm obsolete_form(*incomplete_form);
    697   obsolete_form.action = encountered_form.action;
    698 
    699   // Feed the incomplete credentials to the manager.
    700   std::vector<PasswordForm*> results;
    701   results.push_back(incomplete_form);  // Takes ownership.
    702   form_manager.OnRequestDone(results);
    703 
    704   form_manager.ProvisionallySave(
    705       complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
    706   // By now that form has been used once.
    707   complete_form.times_used = 1;
    708   obsolete_form.times_used = 1;
    709 
    710   // Check that PasswordStore receives an update request with the complete form.
    711   EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form));
    712   EXPECT_CALL(*mock_store(), AddLogin(complete_form));
    713   form_manager.Save();
    714 }
    715 
    716 TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
    717   base::MessageLoop message_loop;
    718 
    719   TestPasswordManagerClient client(NULL);
    720   MockPasswordManagerDriver driver;
    721   EXPECT_CALL(driver, IsOffTheRecord()).WillRepeatedly(Return(false));
    722   EXPECT_CALL(driver, AllowPasswordGenerationForForm(_));
    723 
    724   TestPasswordManager password_manager(&client);
    725   scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
    726     &password_manager, &client, &driver, *observed_form(), false));
    727 
    728   // Simulate having two matches for this form, first comes from different
    729   // signon realm, but reports the same origin and action as matched form.
    730   // Second candidate has the same signon realm as the form, but has a different
    731   // origin and action. Public suffix match is the most important criterion so
    732   // the second candidate should be selected.
    733   std::vector<PasswordForm*> results;
    734   results.push_back(CreateSavedMatch(false));
    735   results.push_back(CreateSavedMatch(false));
    736   results[0]->original_signon_realm = "http://accounts2.google.com";
    737   results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
    738   results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
    739   SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
    740   SimulateResponseFromPasswordStore(manager.get(), results);
    741   EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
    742   EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
    743       ->second->original_signon_realm);
    744 }
    745 
    746 }  // namespace password_manager
    747