77b7d4c718c8a300065c4824c966dba0203f1328
[platform/framework/web/crosswalk.git] / src / components / password_manager / core / browser / password_form_manager_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "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,
52                void(const autofill::PasswordForm&));
53 };
54
55 class TestPasswordManagerClient : public StubPasswordManagerClient {
56  public:
57   explicit TestPasswordManagerClient(PasswordStore* password_store)
58       : password_store_(password_store) {
59     prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled,
60                                            true);
61   }
62
63   virtual bool ShouldFilterAutofillResult(
64       const autofill::PasswordForm& form) OVERRIDE {
65     if (form == form_to_filter_)
66       return true;
67     return false;
68   }
69
70   virtual void PromptUserToSavePassword(
71       scoped_ptr<PasswordFormManager> form_to_save) OVERRIDE {}
72   virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
73   virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_; }
74   virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
75   virtual void AuthenticateAutofillAndFillForm(
76       scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
77     driver_.FillPasswordForm(*fill_data.get());
78   }
79
80   void SetFormToFilter(const autofill::PasswordForm& form) {
81     form_to_filter_ = form;
82   }
83
84   MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
85
86  private:
87   autofill::PasswordForm form_to_filter_;
88
89   TestingPrefServiceSimple prefs_;
90   PasswordStore* password_store_;
91   MockPasswordManagerDriver driver_;
92 };
93
94 class TestPasswordManager : public PasswordManager {
95  public:
96   explicit TestPasswordManager(PasswordManagerClient* client)
97       : PasswordManager(client) {}
98
99   virtual void Autofill(const autofill::PasswordForm& form_for_autofill,
100                         const autofill::PasswordFormMap& best_matches,
101                         const autofill::PasswordForm& preferred_match,
102                         bool wait_for_username) const OVERRIDE {
103     best_matches_ = best_matches;
104   }
105
106   const autofill::PasswordFormMap& GetLatestBestMatches() {
107     return best_matches_;
108   }
109
110  private:
111   // Marked mutable to get around constness of Autofill().
112   mutable autofill::PasswordFormMap best_matches_;
113 };
114
115 }  // namespace
116
117 class PasswordFormManagerTest : public testing::Test {
118  public:
119   PasswordFormManagerTest() : client_(NULL /*password_store*/) {}
120
121   // Types of possible outcomes of simulated matching, see
122   // SimulateMatchingPhase.
123   enum ResultOfSimulatedMatching { RESULT_MATCH_FOUND, RESULT_NO_MATCH };
124
125   virtual void SetUp() {
126     observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
127     observed_form_.action = GURL("http://accounts.google.com/a/Login");
128     observed_form_.username_element = ASCIIToUTF16("Email");
129     observed_form_.password_element = ASCIIToUTF16("Passwd");
130     observed_form_.submit_element = ASCIIToUTF16("signIn");
131     observed_form_.signon_realm = "http://accounts.google.com";
132
133     saved_match_ = observed_form_;
134     saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
135     saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
136     saved_match_.preferred = true;
137     saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
138     saved_match_.password_value = ASCIIToUTF16("test1");
139     saved_match_.other_possible_usernames.push_back(
140         ASCIIToUTF16("test2@gmail.com"));
141   }
142
143   virtual void TearDown() {
144     if (mock_store_)
145       mock_store_->Shutdown();
146   }
147
148   void InitializeMockStore() {
149     if (!mock_store_) {
150       mock_store_ = new MockPasswordStore();
151       ASSERT_TRUE(mock_store_);
152     }
153   }
154
155   MockPasswordStore* mock_store() const { return mock_store_.get(); }
156
157   PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
158     return &p->pending_credentials_;
159   }
160
161   void SimulateMatchingPhase(PasswordFormManager* p,
162                              ResultOfSimulatedMatching result) {
163     // Roll up the state to mock out the matching phase.
164     p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
165     if (result == RESULT_NO_MATCH)
166       return;
167
168     PasswordForm* match = new PasswordForm(saved_match_);
169     // Heap-allocated form is owned by p.
170     p->best_matches_[match->username_value] = match;
171     p->preferred_match_ = match;
172   }
173
174   void SimulateFetchMatchingLoginsFromPasswordStore(
175       PasswordFormManager* manager) {
176     // Just need to update the internal states.
177     manager->state_ = PasswordFormManager::MATCHING_PHASE;
178   }
179
180   void SimulateResponseFromPasswordStore(
181       PasswordFormManager* manager,
182       const std::vector<PasswordForm*>& result) {
183     // Simply call the callback method when request done. This will transfer
184     // the ownership of the objects in |result| to the |manager|.
185     manager->OnGetPasswordStoreResults(result);
186   }
187
188   void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
189     p->SanitizePossibleUsernames(form);
190   }
191
192   bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
193     return p->ShouldIgnoreResult(*form);
194   }
195
196   PasswordForm* observed_form() { return &observed_form_; }
197   PasswordForm* saved_match() { return &saved_match_; }
198   PasswordForm* CreateSavedMatch(bool blacklisted) {
199     // Owned by the caller of this method.
200     PasswordForm* match = new PasswordForm(saved_match_);
201     match->blacklisted_by_user = blacklisted;
202     return match;
203   }
204
205   TestPasswordManagerClient* client() { return &client_; }
206
207  private:
208   PasswordForm observed_form_;
209   PasswordForm saved_match_;
210   scoped_refptr<MockPasswordStore> mock_store_;
211   TestPasswordManagerClient client_;
212 };
213
214 TEST_F(PasswordFormManagerTest, TestNewLogin) {
215   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
216   SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
217
218   // User submits credentials for the observed form.
219   PasswordForm credentials = *observed_form();
220   credentials.username_value = saved_match()->username_value;
221   credentials.password_value = saved_match()->password_value;
222   credentials.preferred = true;
223   manager.ProvisionallySave(
224       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
225
226   // Successful login. The PasswordManager would instruct PasswordFormManager
227   // to save, which should know this is a new login.
228   EXPECT_TRUE(manager.IsNewLogin());
229   // Make sure the credentials that would be submitted on successful login
230   // are going to match the stored entry in the db.
231   EXPECT_EQ(observed_form()->origin.spec(),
232             GetPendingCredentials(&manager)->origin.spec());
233   EXPECT_EQ(observed_form()->signon_realm,
234             GetPendingCredentials(&manager)->signon_realm);
235   EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
236   EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
237   EXPECT_EQ(saved_match()->password_value,
238             GetPendingCredentials(&manager)->password_value);
239   EXPECT_EQ(saved_match()->username_value,
240             GetPendingCredentials(&manager)->username_value);
241   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
242   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
243
244   // Now, suppose the user re-visits the site and wants to save an additional
245   // login for the site with a new username. In this case, the matching phase
246   // will yield the previously saved login.
247   SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
248   // Set up the new login.
249   base::string16 new_user = ASCIIToUTF16("newuser");
250   base::string16 new_pass = ASCIIToUTF16("newpass");
251   credentials.username_value = new_user;
252   credentials.password_value = new_pass;
253   manager.ProvisionallySave(
254       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
255
256   // Again, the PasswordFormManager should know this is still a new login.
257   EXPECT_TRUE(manager.IsNewLogin());
258   // And make sure everything squares up again.
259   EXPECT_EQ(observed_form()->origin.spec(),
260             GetPendingCredentials(&manager)->origin.spec());
261   EXPECT_EQ(observed_form()->signon_realm,
262             GetPendingCredentials(&manager)->signon_realm);
263   EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
264   EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
265   EXPECT_EQ(new_user, GetPendingCredentials(&manager)->username_value);
266   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
267   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
268 }
269
270 // If PSL-matched credentials had been suggested, but the user has overwritten
271 // the password, the provisionally saved credentials should no longer be
272 // considered as PSL-matched, so that the exception for not prompting before
273 // saving PSL-matched credentials should no longer apply.
274 TEST_F(PasswordFormManagerTest,
275        OverriddenPSLMatchedCredentialsNotMarkedAsPSLMatched) {
276   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
277
278   // The suggestion needs to be PSL-matched.
279   saved_match()->original_signon_realm = "www.example.org";
280   SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
281
282   // User modifies the suggested password and submits the form.
283   PasswordForm credentials(*observed_form());
284   credentials.username_value = saved_match()->username_value;
285   credentials.password_value =
286       saved_match()->password_value + ASCIIToUTF16("modify");
287   manager.ProvisionallySave(
288       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
289
290   EXPECT_TRUE(manager.IsNewLogin());
291   EXPECT_FALSE(manager.IsPendingCredentialsPublicSuffixMatch());
292 }
293
294 TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
295   // Add a new password field to the test form. The PasswordFormManager should
296   // save the password from this field, instead of the current password field.
297   observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
298
299   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
300   SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
301
302   // User enters current and new credentials to the observed form.
303   PasswordForm credentials(*observed_form());
304   credentials.username_value = saved_match()->username_value;
305   credentials.password_value = saved_match()->password_value;
306   credentials.new_password_value = ASCIIToUTF16("newpassword");
307   credentials.preferred = true;
308   manager.ProvisionallySave(
309       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
310
311   // Successful login. The PasswordManager would instruct PasswordFormManager
312   // to save, which should know this is a new login.
313   EXPECT_TRUE(manager.IsNewLogin());
314   EXPECT_EQ(credentials.origin, GetPendingCredentials(&manager)->origin);
315   EXPECT_EQ(credentials.signon_realm,
316             GetPendingCredentials(&manager)->signon_realm);
317   EXPECT_EQ(credentials.action, GetPendingCredentials(&manager)->action);
318   EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
319   EXPECT_EQ(credentials.username_value,
320             GetPendingCredentials(&manager)->username_value);
321
322   // By this point, the PasswordFormManager should have promoted the new
323   // password value to be the current password, and should have wiped the
324   // password element names: they are likely going to be different on a login
325   // form, so it is not worth remembering them.
326   EXPECT_EQ(credentials.new_password_value,
327             GetPendingCredentials(&manager)->password_value);
328   EXPECT_TRUE(GetPendingCredentials(&manager)->password_element.empty());
329   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
330   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
331 }
332
333 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
334   // Create a PasswordFormManager with observed_form, as if we just
335   // saw this form and need to find matching logins.
336   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
337
338   SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
339
340   // User submits credentials for the observed form using a username previously
341   // stored, but a new password. Note that the observed form may have different
342   // origin URL (as it does in this case) than the saved_match, but we want to
343   // make sure the updated password is reflected in saved_match, because that is
344   // what we autofilled.
345   base::string16 new_pass = ASCIIToUTF16("test2");
346   PasswordForm credentials = *observed_form();
347   credentials.username_value = saved_match()->username_value;
348   credentials.password_value = new_pass;
349   credentials.preferred = true;
350   manager.ProvisionallySave(
351       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
352
353   // Successful login. The PasswordManager would instruct PasswordFormManager
354   // to save, and since this is an update, it should know not to save as a new
355   // login.
356   EXPECT_FALSE(manager.IsNewLogin());
357
358   // Make sure the credentials that would be submitted on successful login
359   // are going to match the stored entry in the db. (This verifies correct
360   // behaviour for bug 1074420).
361   EXPECT_EQ(GetPendingCredentials(&manager)->origin.spec(),
362             saved_match()->origin.spec());
363   EXPECT_EQ(GetPendingCredentials(&manager)->signon_realm,
364             saved_match()->signon_realm);
365   EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
366   EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
367 }
368
369 TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
370   // Add a new password field to the test form. The PasswordFormManager should
371   // save the password from this field, instead of the current password field.
372   observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
373
374   // Given that |observed_form| was most likely a change password form, it
375   // should not serve as a source for updating meta-information stored with the
376   // old credentials, such as element names, as they are likely going to be
377   // different between change password and login forms. To test this in depth,
378   // forcibly wipe |submit_element|, which should normally trigger updating this
379   // field from |observed_form| in the UpdateLogin() step as a special case. We
380   // will verify in the end that this did not happen.
381   saved_match()->submit_element.clear();
382
383   InitializeMockStore();
384   TestPasswordManagerClient client_with_store(mock_store());
385   PasswordFormManager manager(NULL,
386                               &client_with_store,
387                               client_with_store.GetDriver(),
388                               *observed_form(),
389                               false);
390   EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
391       .WillRepeatedly(Return(false));
392   SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
393
394   // User submits current and new credentials to the observed form.
395   PasswordForm credentials(*observed_form());
396   credentials.username_value = saved_match()->username_value;
397   credentials.password_value = saved_match()->password_value;
398   credentials.new_password_value = ASCIIToUTF16("test2");
399   credentials.preferred = true;
400   manager.ProvisionallySave(
401       credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
402
403   // Successful login. The PasswordManager would instruct PasswordFormManager
404   // to save, and since this is an update, it should know not to save as a new
405   // login.
406   EXPECT_FALSE(manager.IsNewLogin());
407
408   // By now, the PasswordFormManager should have promoted the new password value
409   // already to be the current password, and should no longer maintain any info
410   // about the new password.
411   EXPECT_EQ(credentials.new_password_value,
412             GetPendingCredentials(&manager)->password_value);
413   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
414   EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
415
416   // Trigger saving to exercise some special case handling in UpdateLogin().
417   PasswordForm new_credentials;
418   EXPECT_CALL(*mock_store(), UpdateLogin(_))
419       .WillOnce(testing::SaveArg<0>(&new_credentials));
420   manager.Save();
421   Mock::VerifyAndClearExpectations(mock_store());
422
423   // No meta-information should be updated, only the password.
424   EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
425   EXPECT_EQ(saved_match()->username_element, new_credentials.username_element);
426   EXPECT_EQ(saved_match()->password_element, new_credentials.password_element);
427   EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
428 }
429
430 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
431   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
432
433   // Make sure we don't match a PasswordForm if it was originally saved on
434   // an SSL-valid page and we are now on a page with invalid certificate.
435   saved_match()->ssl_valid = true;
436   EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
437
438   saved_match()->ssl_valid = false;
439   // Different paths for action / origin are okay.
440   saved_match()->action = GURL("http://www.google.com/b/Login");
441   saved_match()->origin = GURL("http://www.google.com/foo");
442   EXPECT_FALSE(IgnoredResult(&manager, saved_match()));
443
444   // Results should be ignored if the client requests it.
445   client()->SetFormToFilter(*saved_match());
446   EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
447 }
448
449 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
450   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
451
452   saved_match()->action = GURL();
453   SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
454   // User logs in with the autofilled username / password from saved_match.
455   PasswordForm login = *observed_form();
456   login.username_value = saved_match()->username_value;
457   login.password_value = saved_match()->password_value;
458   manager.ProvisionallySave(
459       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
460   EXPECT_FALSE(manager.IsNewLogin());
461   // We bless our saved PasswordForm entry with the action URL of the
462   // observed form.
463   EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
464 }
465
466 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
467   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
468
469   SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
470   // User logs in with the autofilled username / password from saved_match.
471   PasswordForm login = *observed_form();
472   login.username_value = saved_match()->username_value;
473   login.password_value = saved_match()->password_value;
474
475   manager.ProvisionallySave(
476       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
477   EXPECT_FALSE(manager.IsNewLogin());
478   // The observed action URL is different from the previously saved one, and
479   // is the same as the one that would be submitted on successful login.
480   EXPECT_NE(observed_form()->action, saved_match()->action);
481   EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
482 }
483
484 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
485   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
486
487   SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
488   PasswordForm login(*observed_form());
489   // The submitted action URL is different from the one observed on page load.
490   GURL new_action = GURL("http://www.google.com/new_action");
491   login.action = new_action;
492
493   manager.ProvisionallySave(
494       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
495   EXPECT_TRUE(manager.IsNewLogin());
496   // Check that the provisionally saved action URL is the same as the submitted
497   // action URL, not the one observed on page load.
498   EXPECT_EQ(new_action, GetPendingCredentials(&manager)->action);
499 }
500
501 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
502   // Need a MessageLoop for callbacks.
503   base::MessageLoop message_loop;
504   scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
505   CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
506
507   TestPasswordManagerClient client_with_store(password_store.get());
508   TestPasswordManager password_manager(&client_with_store);
509   PasswordFormManager manager(&password_manager,
510                               &client_with_store,
511                               client_with_store.GetDriver(),
512                               *observed_form(),
513                               false);
514   EXPECT_CALL(*client_with_store.GetMockDriver(),
515               AllowPasswordGenerationForForm(_)).Times(1);
516   EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
517       .WillRepeatedly(Return(false));
518
519   password_store->AddLogin(*saved_match());
520   manager.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
521   RunAllPendingTasks();
522
523   // The saved match has the right username already.
524   PasswordForm login(*observed_form());
525   login.username_value = saved_match()->username_value;
526   login.password_value = saved_match()->password_value;
527   login.preferred = true;
528   manager.ProvisionallySave(
529       login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
530
531   EXPECT_FALSE(manager.IsNewLogin());
532   manager.Save();
533   RunAllPendingTasks();
534
535   // Should be only one password stored, and should not have
536   // |other_possible_usernames| set anymore.
537   TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
538   EXPECT_EQ(1U, passwords.size());
539   ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
540   EXPECT_EQ(saved_match()->username_value,
541             passwords[saved_match()->signon_realm][0].username_value);
542   EXPECT_EQ(0U,
543             passwords[saved_match()->signon_realm][0]
544                 .other_possible_usernames.size());
545
546   // This time use an alternate username
547   PasswordFormManager manager_alt(&password_manager,
548                                   &client_with_store,
549                                   client_with_store.GetDriver(),
550                                   *observed_form(),
551                                   false);
552   EXPECT_CALL(*client_with_store.GetMockDriver(),
553               AllowPasswordGenerationForForm(_)).Times(1);
554   password_store->Clear();
555   password_store->AddLogin(*saved_match());
556   manager_alt.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
557   RunAllPendingTasks();
558
559   base::string16 new_username = saved_match()->other_possible_usernames[0];
560   login.username_value = new_username;
561   manager_alt.ProvisionallySave(
562       login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
563
564   EXPECT_FALSE(manager_alt.IsNewLogin());
565   manager_alt.Save();
566   RunAllPendingTasks();
567
568   // |other_possible_usernames| should also be empty, but username_value should
569   // be changed to match |new_username|
570   passwords = password_store->stored_passwords();
571   EXPECT_EQ(1U, passwords.size());
572   ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
573   EXPECT_EQ(new_username,
574             passwords[saved_match()->signon_realm][0].username_value);
575   EXPECT_EQ(0U,
576             passwords[saved_match()->signon_realm][0]
577                 .other_possible_usernames.size());
578   password_store->Shutdown();
579 }
580
581 TEST_F(PasswordFormManagerTest, TestValidForms) {
582   // User submits credentials for the observed form.
583   PasswordForm credentials = *observed_form();
584   credentials.scheme = PasswordForm::SCHEME_HTML;
585   credentials.username_value = saved_match()->username_value;
586   credentials.password_value = saved_match()->password_value;
587
588   // An alternate version of the form that also has a new_password_element.
589   PasswordForm new_credentials(*observed_form());
590   new_credentials.new_password_element = ASCIIToUTF16("NewPasswd");
591   new_credentials.new_password_value = ASCIIToUTF16("test1new");
592
593   // Form with both username_element and password_element.
594   PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
595   SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
596   EXPECT_TRUE(manager1.HasValidPasswordForm());
597
598   // Form with username_element, password_element, and new_password_element.
599   PasswordFormManager manager2(NULL, NULL, NULL, new_credentials, false);
600   SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
601   EXPECT_TRUE(manager2.HasValidPasswordForm());
602
603   // Form with username_element and only new_password_element.
604   new_credentials.password_element.clear();
605   PasswordFormManager manager3(NULL, NULL, NULL, new_credentials, false);
606   SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
607   EXPECT_TRUE(manager3.HasValidPasswordForm());
608
609   // Form without a username_element but with a password_element.
610   credentials.username_element.clear();
611   PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
612   SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
613   EXPECT_FALSE(manager4.HasValidPasswordForm());
614
615   // Form without a username_element but with a new_password_element.
616   new_credentials.username_element.clear();
617   PasswordFormManager manager5(NULL, NULL, NULL, new_credentials, false);
618   SimulateMatchingPhase(&manager5, RESULT_NO_MATCH);
619   EXPECT_FALSE(manager5.HasValidPasswordForm());
620
621   // Form without a password_element but with a username_element.
622   credentials.username_element = saved_match()->username_element;
623   credentials.password_element.clear();
624   PasswordFormManager manager6(NULL, NULL, NULL, credentials, false);
625   SimulateMatchingPhase(&manager6, RESULT_NO_MATCH);
626   EXPECT_FALSE(manager6.HasValidPasswordForm());
627
628   // Form with neither a password_element nor a username_element.
629   credentials.username_element.clear();
630   credentials.password_element.clear();
631   PasswordFormManager manager7(NULL, NULL, NULL, credentials, false);
632   SimulateMatchingPhase(&manager7, RESULT_NO_MATCH);
633   EXPECT_FALSE(manager7.HasValidPasswordForm());
634 }
635
636 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
637   // User submits credentials for the observed form.
638   PasswordForm credentials = *observed_form();
639   credentials.scheme = PasswordForm::SCHEME_BASIC;
640   credentials.username_value = saved_match()->username_value;
641   credentials.password_value = saved_match()->password_value;
642
643   // Form with both username_element and password_element.
644   PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
645   SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
646   EXPECT_TRUE(manager1.HasValidPasswordForm());
647
648   // Form without a username_element but with a password_element.
649   credentials.username_element.clear();
650   PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
651   SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
652   EXPECT_TRUE(manager2.HasValidPasswordForm());
653
654   // Form without a password_element but with a username_element.
655   credentials.username_element = saved_match()->username_element;
656   credentials.password_element.clear();
657   PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
658   SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
659   EXPECT_TRUE(manager3.HasValidPasswordForm());
660
661   // Form with neither a password_element nor a username_element.
662   credentials.username_element.clear();
663   credentials.password_element.clear();
664   PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
665   SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
666   EXPECT_TRUE(manager4.HasValidPasswordForm());
667 }
668
669 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
670   base::MessageLoop message_loop;
671
672   TestPasswordManager password_manager(client());
673   PasswordFormManager manager_no_creds(&password_manager,
674                                        client(),
675                                        client()->GetDriver(),
676                                        *observed_form(),
677                                        false);
678
679   // First time sign-up attempt. Password store does not contain matching
680   // credentials. AllowPasswordGenerationForForm should be called to send the
681   // "not blacklisted" message.
682   EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
683       .Times(1);
684   SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_creds);
685   std::vector<PasswordForm*> result;
686   SimulateResponseFromPasswordStore(&manager_no_creds, result);
687   Mock::VerifyAndClearExpectations(client()->GetMockDriver());
688
689   // Signing up on a previously visited site. Credentials are found in the
690   // password store, and are not blacklisted. AllowPasswordGenerationForForm
691   // should be called to send the "not blacklisted" message.
692   PasswordFormManager manager_creds(&password_manager,
693                                     client(),
694                                     client()->GetDriver(),
695                                     *observed_form(),
696                                     false);
697   EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
698       .Times(1);
699   EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
700       .WillRepeatedly(Return(false));
701   SimulateFetchMatchingLoginsFromPasswordStore(&manager_creds);
702   // We need add heap allocated objects to result.
703   result.push_back(CreateSavedMatch(false));
704   SimulateResponseFromPasswordStore(&manager_creds, result);
705   Mock::VerifyAndClearExpectations(client()->GetMockDriver());
706
707   // Signing up on a previously visited site. Credentials are found in the
708   // password store, but they are blacklisted. AllowPasswordGenerationForForm
709   // should not be called and no "not blacklisted" message sent.
710   PasswordFormManager manager_blacklisted(&password_manager,
711                                           client(),
712                                           client()->GetDriver(),
713                                           *observed_form(),
714                                           false);
715   EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
716       .Times(0);
717   SimulateFetchMatchingLoginsFromPasswordStore(&manager_blacklisted);
718   result.clear();
719   result.push_back(CreateSavedMatch(true));
720   SimulateResponseFromPasswordStore(&manager_blacklisted, result);
721   Mock::VerifyAndClearExpectations(client()->GetMockDriver());
722 }
723
724 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
725   base::MessageLoop message_loop;
726
727   // Simulate having two matches for this origin, one of which was from a form
728   // with different HTML tags for elements. Because of scoring differences,
729   // only the first form will be sent to Autofill().
730   TestPasswordManager password_manager(client());
731   PasswordFormManager manager_match(&password_manager,
732                                     client(),
733                                     client()->GetDriver(),
734                                     *observed_form(),
735                                     false);
736   EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
737       .Times(1);
738   EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
739       .WillRepeatedly(Return(false));
740
741   std::vector<PasswordForm*> results;
742   results.push_back(CreateSavedMatch(false));
743   results.push_back(CreateSavedMatch(false));
744   results[1]->username_value = ASCIIToUTF16("other@gmail.com");
745   results[1]->password_element = ASCIIToUTF16("signup_password");
746   results[1]->username_element = ASCIIToUTF16("signup_username");
747   SimulateFetchMatchingLoginsFromPasswordStore(&manager_match);
748   SimulateResponseFromPasswordStore(&manager_match, results);
749   EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
750   results.clear();
751
752   // Same thing, except this time the credentials that don't match quite as
753   // well are generated. They should now be sent to Autofill().
754   PasswordFormManager manager_no_match(&password_manager,
755                                        client(),
756                                        client()->GetDriver(),
757                                        *observed_form(),
758                                        false);
759   EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
760       .Times(1);
761
762   results.push_back(CreateSavedMatch(false));
763   results.push_back(CreateSavedMatch(false));
764   results[1]->username_value = ASCIIToUTF16("other@gmail.com");
765   results[1]->password_element = ASCIIToUTF16("signup_password");
766   results[1]->username_element = ASCIIToUTF16("signup_username");
767   results[1]->type = PasswordForm::TYPE_GENERATED;
768   SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_match);
769   SimulateResponseFromPasswordStore(&manager_no_match, results);
770   EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
771 }
772
773 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
774   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
775   PasswordForm credentials(*observed_form());
776   credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
777   credentials.other_possible_usernames.push_back(
778       ASCIIToUTF16("378282246310005"));
779   credentials.other_possible_usernames.push_back(
780       ASCIIToUTF16("other username"));
781   credentials.username_value = ASCIIToUTF16("test@gmail.com");
782
783   SanitizePossibleUsernames(&manager, &credentials);
784
785   // Possible credit card number and SSN are stripped.
786   std::vector<base::string16> expected;
787   expected.push_back(ASCIIToUTF16("other username"));
788   EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
789
790   credentials.other_possible_usernames.clear();
791   credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
792   credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
793   credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
794   credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
795   credentials.other_possible_usernames.push_back(
796       ASCIIToUTF16("test@gmail.com"));
797
798   SanitizePossibleUsernames(&manager, &credentials);
799
800   // SSN, duplicate in |other_possible_usernames| and duplicate of
801   // |username_value| all removed.
802   expected.clear();
803   expected.push_back(ASCIIToUTF16("duplicate"));
804   expected.push_back(ASCIIToUTF16("random"));
805   EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
806 }
807
808 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
809   InitializeMockStore();
810
811   // We've found this form on a website:
812   PasswordForm encountered_form;
813   encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
814   encountered_form.signon_realm = "http://accounts.google.com/";
815   encountered_form.action = GURL("http://accounts.google.com/Login");
816   encountered_form.username_element = ASCIIToUTF16("Email");
817   encountered_form.password_element = ASCIIToUTF16("Passwd");
818   encountered_form.submit_element = ASCIIToUTF16("signIn");
819
820   TestPasswordManagerClient client_with_store(mock_store());
821   EXPECT_CALL(*(client_with_store.GetMockDriver()), IsOffTheRecord())
822       .WillRepeatedly(Return(false));
823   EXPECT_CALL(*(client_with_store.GetMockDriver()),
824               AllowPasswordGenerationForForm(_));
825
826   TestPasswordManager manager(&client_with_store);
827   PasswordFormManager form_manager(&manager,
828                                    &client_with_store,
829                                    client_with_store.GetMockDriver(),
830                                    encountered_form,
831                                    false);
832
833   const PasswordStore::AuthorizationPromptPolicy auth_policy =
834       PasswordStore::DISALLOW_PROMPT;
835   EXPECT_CALL(*mock_store(),
836               GetLogins(encountered_form, auth_policy, &form_manager));
837   form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
838
839   // Password store only has these incomplete credentials.
840   PasswordForm* incomplete_form = new PasswordForm();
841   incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
842   incomplete_form->signon_realm = "http://accounts.google.com/";
843   incomplete_form->password_value = ASCIIToUTF16("my_password");
844   incomplete_form->username_value = ASCIIToUTF16("my_username");
845   incomplete_form->preferred = true;
846   incomplete_form->ssl_valid = false;
847   incomplete_form->scheme = PasswordForm::SCHEME_HTML;
848
849   // We expect to see this form eventually sent to the Password store. It
850   // has password/username values from the store and 'username_element',
851   // 'password_element', 'submit_element' and 'action' fields copied from
852   // the encountered form.
853   PasswordForm complete_form(*incomplete_form);
854   complete_form.action = encountered_form.action;
855   complete_form.password_element = encountered_form.password_element;
856   complete_form.username_element = encountered_form.username_element;
857   complete_form.submit_element = encountered_form.submit_element;
858
859   PasswordForm obsolete_form(*incomplete_form);
860   obsolete_form.action = encountered_form.action;
861
862   // Feed the incomplete credentials to the manager.
863   std::vector<PasswordForm*> results;
864   results.push_back(incomplete_form);  // Takes ownership.
865   form_manager.OnRequestDone(results);
866
867   form_manager.ProvisionallySave(
868       complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
869   // By now that form has been used once.
870   complete_form.times_used = 1;
871   obsolete_form.times_used = 1;
872
873   // Check that PasswordStore receives an update request with the complete form.
874   EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form));
875   EXPECT_CALL(*mock_store(), AddLogin(complete_form));
876   form_manager.Save();
877 }
878
879 TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
880   base::MessageLoop message_loop;
881
882   EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
883       .WillRepeatedly(Return(false));
884   EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_));
885
886   TestPasswordManager password_manager(client());
887   PasswordFormManager manager(&password_manager,
888                               client(),
889                               client()->GetMockDriver(),
890                               *observed_form(),
891                               false);
892
893   // Simulate having two matches for this form, first comes from different
894   // signon realm, but reports the same origin and action as matched form.
895   // Second candidate has the same signon realm as the form, but has a different
896   // origin and action. Public suffix match is the most important criterion so
897   // the second candidate should be selected.
898   std::vector<PasswordForm*> results;
899   results.push_back(CreateSavedMatch(false));
900   results.push_back(CreateSavedMatch(false));
901   results[0]->original_signon_realm = "http://accounts2.google.com";
902   results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
903   results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
904   SimulateFetchMatchingLoginsFromPasswordStore(&manager);
905   SimulateResponseFromPasswordStore(&manager, results);
906   EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
907   EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
908       ->second->original_signon_realm);
909 }
910
911 TEST_F(PasswordFormManagerTest, InvalidActionURLsDoNotMatch) {
912   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
913
914   PasswordForm invalid_action_form(*observed_form());
915   invalid_action_form.action = GURL("http://");
916   ASSERT_FALSE(invalid_action_form.action.is_valid());
917   ASSERT_FALSE(invalid_action_form.action.is_empty());
918   // Non-empty invalid action URLs should not match other actions.
919   // First when the compared form has an invalid URL:
920   EXPECT_EQ(0,
921             manager.DoesManage(invalid_action_form) &
922                 PasswordFormManager::RESULT_ACTION_MATCH);
923   // Then when the observed form has an invalid URL:
924   PasswordForm valid_action_form(*observed_form());
925   PasswordFormManager invalid_manager(
926       NULL, client(), NULL, invalid_action_form, false);
927   EXPECT_EQ(0,
928             invalid_manager.DoesManage(valid_action_form) &
929                 PasswordFormManager::RESULT_ACTION_MATCH);
930 }
931
932 TEST_F(PasswordFormManagerTest, EmptyActionURLsDoNotMatchNonEmpty) {
933   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
934
935   PasswordForm empty_action_form(*observed_form());
936   empty_action_form.action = GURL();
937   ASSERT_FALSE(empty_action_form.action.is_valid());
938   ASSERT_TRUE(empty_action_form.action.is_empty());
939   // First when the compared form has an empty URL:
940   EXPECT_EQ(0,
941             manager.DoesManage(empty_action_form) &
942                 PasswordFormManager::RESULT_ACTION_MATCH);
943   // Then when the observed form has an empty URL:
944   PasswordForm valid_action_form(*observed_form());
945   PasswordFormManager empty_action_manager(
946       NULL, client(), NULL, empty_action_form, false);
947   EXPECT_EQ(0,
948             empty_action_manager.DoesManage(valid_action_form) &
949                 PasswordFormManager::RESULT_ACTION_MATCH);
950 }
951
952 TEST_F(PasswordFormManagerTest, NonHTMLFormsDoNotMatchHTMLForms) {
953   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
954
955   ASSERT_EQ(PasswordForm::SCHEME_HTML, observed_form()->scheme);
956   PasswordForm non_html_form(*observed_form());
957   non_html_form.scheme = PasswordForm::SCHEME_DIGEST;
958   EXPECT_EQ(0,
959             manager.DoesManage(non_html_form) &
960                 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
961
962   // The other way round: observing a non-HTML form, don't match a HTML form.
963   PasswordForm html_form(*observed_form());
964   PasswordFormManager non_html_manager(
965       NULL, client(), NULL, non_html_form, false);
966   EXPECT_EQ(0,
967             non_html_manager.DoesManage(html_form) &
968                 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
969 }
970
971 TEST_F(PasswordFormManagerTest, OriginCheck_HostsMatchExactly) {
972   // Host part of origins must match exactly, not just by prefix.
973   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
974
975   PasswordForm form_longer_host(*observed_form());
976   form_longer_host.origin = GURL("http://accounts.google.com.au/a/LoginAuth");
977   // Check that accounts.google.com does not match accounts.google.com.au.
978   EXPECT_EQ(0,
979             manager.DoesManage(form_longer_host) &
980                 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
981 }
982
983 TEST_F(PasswordFormManagerTest, OriginCheck_MoreSecureSchemePathsMatchPrefix) {
984   // If the URL scheme of the observed form is HTTP, and the compared form is
985   // HTTPS, then the compared form can extend the path.
986   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
987
988   PasswordForm form_longer_path(*observed_form());
989   form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
990   EXPECT_NE(0,
991             manager.DoesManage(form_longer_path) &
992                 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
993 }
994
995 TEST_F(PasswordFormManagerTest,
996        OriginCheck_NotMoreSecureSchemePathsMatchExactly) {
997   // If the origin URL scheme of the compared form is not more secure than that
998   // of the observed form, then the paths must match exactly.
999   PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1000
1001   PasswordForm form_longer_path(*observed_form());
1002   form_longer_path.origin = GURL("http://accounts.google.com/a/LoginAuth/sec");
1003   // Check that /a/LoginAuth does not match /a/LoginAuth/more.
1004   EXPECT_EQ(0,
1005             manager.DoesManage(form_longer_path) &
1006                 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1007
1008   PasswordForm secure_observed_form(*observed_form());
1009   secure_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth");
1010   PasswordFormManager secure_manager(
1011       NULL, client(), NULL, secure_observed_form, true);
1012   // Also for HTTPS in the observed form, and HTTP in the compared form, an
1013   // exact path match is expected.
1014   EXPECT_EQ(0,
1015             secure_manager.DoesManage(form_longer_path) &
1016                 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1017   // Not even upgrade to HTTPS in the compared form should help.
1018   form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1019   EXPECT_EQ(0,
1020             secure_manager.DoesManage(form_longer_path) &
1021                 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1022 }
1023
1024 TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) {
1025   // Need a MessageLoop for callbacks.
1026   base::MessageLoop message_loop;
1027   scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1028   CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
1029
1030   TestPasswordManagerClient client_with_store(password_store.get());
1031   TestPasswordManager password_manager(&client_with_store);
1032   EXPECT_CALL(*client_with_store.GetMockDriver(),
1033               AllowPasswordGenerationForForm(_)).Times(2);
1034   EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1035       .WillRepeatedly(Return(false));
1036
1037   // Add two credentials with the same username. Both should score the same
1038   // and be seen as candidates to autofill.
1039   PasswordForm first(*saved_match());
1040   first.action = observed_form()->action;
1041   first.password_value = ASCIIToUTF16("first");
1042   password_store->AddLogin(first);
1043
1044   PasswordForm second(first);
1045   second.origin = GURL("http://accounts.google.com/a/AddLogin");
1046   second.password_value = ASCIIToUTF16("second");
1047   second.preferred = false;
1048   password_store->AddLogin(second);
1049
1050   PasswordFormManager storing_manager(&password_manager,
1051                                       &client_with_store,
1052                                       client_with_store.GetDriver(),
1053                                       *observed_form(),
1054                                       false);
1055   storing_manager.FetchMatchingLoginsFromPasswordStore(
1056       PasswordStore::ALLOW_PROMPT);
1057   RunAllPendingTasks();
1058
1059   // We always take the last credential with a particular username, regardless
1060   // of which ones are labeled preferred.
1061   EXPECT_EQ(ASCIIToUTF16("second"),
1062             storing_manager.preferred_match()->password_value);
1063
1064   PasswordForm login(*observed_form());
1065   login.username_value = saved_match()->username_value;
1066   login.password_value = ASCIIToUTF16("third");
1067   login.preferred = true;
1068   storing_manager.ProvisionallySave(
1069       login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1070
1071   EXPECT_FALSE(storing_manager.IsNewLogin());
1072   storing_manager.Save();
1073   RunAllPendingTasks();
1074
1075   PasswordFormManager retrieving_manager(&password_manager,
1076                                          &client_with_store,
1077                                          client_with_store.GetDriver(),
1078                                          *observed_form(),
1079                                          false);
1080
1081   retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1082       PasswordStore::ALLOW_PROMPT);
1083   RunAllPendingTasks();
1084
1085   // Make sure that the preferred match is updated appropriately.
1086   EXPECT_EQ(ASCIIToUTF16("third"),
1087             retrieving_manager.preferred_match()->password_value);
1088   password_store->Shutdown();
1089 }
1090
1091 }  // namespace password_manager