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.
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"
26 using autofill::PasswordForm;
27 using base::ASCIIToUTF16;
30 using ::testing::Mock;
31 using ::testing::Return;
34 class AutofillManager;
37 namespace password_manager {
41 void RunAllPendingTasks() {
42 base::RunLoop run_loop;
43 base::MessageLoop::current()->PostTask(
44 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
48 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
50 MOCK_METHOD0(IsOffTheRecord, bool());
51 MOCK_METHOD1(AllowPasswordGenerationForForm,
52 void(const autofill::PasswordForm&));
55 class TestPasswordManagerClient : public StubPasswordManagerClient {
57 explicit TestPasswordManagerClient(PasswordStore* password_store)
58 : password_store_(password_store) {
59 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled,
63 virtual bool ShouldFilterAutofillResult(
64 const autofill::PasswordForm& form) OVERRIDE {
65 if (form == form_to_filter_)
70 virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
71 virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_; }
72 virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
73 virtual void AuthenticateAutofillAndFillForm(
74 scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
75 driver_.FillPasswordForm(*fill_data.get());
78 void SetFormToFilter(const autofill::PasswordForm& form) {
79 form_to_filter_ = form;
82 MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
85 autofill::PasswordForm form_to_filter_;
87 TestingPrefServiceSimple prefs_;
88 PasswordStore* password_store_;
89 testing::NiceMock<MockPasswordManagerDriver> driver_;
92 class TestPasswordManager : public PasswordManager {
94 explicit TestPasswordManager(PasswordManagerClient* client)
95 : PasswordManager(client) {}
97 virtual void Autofill(const autofill::PasswordForm& form_for_autofill,
98 const autofill::PasswordFormMap& best_matches,
99 const autofill::PasswordForm& preferred_match,
100 bool wait_for_username) const OVERRIDE {
101 best_matches_ = best_matches;
104 const autofill::PasswordFormMap& GetLatestBestMatches() {
105 return best_matches_;
109 // Marked mutable to get around constness of Autofill().
110 mutable autofill::PasswordFormMap best_matches_;
113 class MockPasswordFormManager : public PasswordFormManager {
115 MockPasswordFormManager(PasswordManager* manager,
116 PasswordManagerClient* client,
117 PasswordManagerDriver* driver,
118 const autofill::PasswordForm& observed_form,
120 : PasswordFormManager(manager, client, driver, observed_form, ssl_valid)
123 MOCK_METHOD2(UploadPasswordForm, void(const autofill::FormData&,
124 const autofill::ServerFieldType&));
129 class PasswordFormManagerTest : public testing::Test {
131 PasswordFormManagerTest() : client_(NULL /*password_store*/) {}
133 // Types of possible outcomes of simulated matching, see
134 // SimulateMatchingPhase.
135 enum ResultOfSimulatedMatching { RESULT_MATCH_FOUND, RESULT_NO_MATCH };
137 virtual void SetUp() {
138 observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
139 observed_form_.action = GURL("http://accounts.google.com/a/Login");
140 observed_form_.username_element = ASCIIToUTF16("Email");
141 observed_form_.password_element = ASCIIToUTF16("Passwd");
142 observed_form_.submit_element = ASCIIToUTF16("signIn");
143 observed_form_.signon_realm = "http://accounts.google.com";
145 saved_match_ = observed_form_;
146 saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
147 saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
148 saved_match_.preferred = true;
149 saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
150 saved_match_.password_value = ASCIIToUTF16("test1");
151 saved_match_.other_possible_usernames.push_back(
152 ASCIIToUTF16("test2@gmail.com"));
155 virtual void TearDown() {
156 if (mock_store_.get())
157 mock_store_->Shutdown();
160 void InitializeMockStore() {
161 if (!mock_store_.get()) {
162 mock_store_ = new testing::NiceMock<MockPasswordStore>();
163 ASSERT_TRUE(mock_store_.get());
167 MockPasswordStore* mock_store() const { return mock_store_.get(); }
169 PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
170 return &p->pending_credentials_;
173 void SimulateMatchingPhase(PasswordFormManager* p,
174 ResultOfSimulatedMatching result) {
175 // Roll up the state to mock out the matching phase.
176 p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
177 if (result == RESULT_NO_MATCH)
180 PasswordForm* match = new PasswordForm(saved_match_);
181 // Heap-allocated form is owned by p.
182 p->best_matches_[match->username_value] = match;
183 p->preferred_match_ = match;
186 void SimulateFetchMatchingLoginsFromPasswordStore(
187 PasswordFormManager* manager) {
188 // Just need to update the internal states.
189 manager->state_ = PasswordFormManager::MATCHING_PHASE;
192 void SimulateResponseFromPasswordStore(
193 PasswordFormManager* manager,
194 const std::vector<PasswordForm*>& result) {
195 // Simply call the callback method when request done. This will transfer
196 // the ownership of the objects in |result| to the |manager|.
197 manager->OnGetPasswordStoreResults(result);
200 void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
201 p->SanitizePossibleUsernames(form);
204 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
205 return p->ShouldIgnoreResult(*form);
208 PasswordForm* observed_form() { return &observed_form_; }
209 PasswordForm* saved_match() { return &saved_match_; }
210 PasswordForm* CreateSavedMatch(bool blacklisted) {
211 // Owned by the caller of this method.
212 PasswordForm* match = new PasswordForm(saved_match_);
213 match->blacklisted_by_user = blacklisted;
217 TestPasswordManagerClient* client() { return &client_; }
220 PasswordForm observed_form_;
221 PasswordForm saved_match_;
222 scoped_refptr<testing::NiceMock<MockPasswordStore> > mock_store_;
223 TestPasswordManagerClient client_;
226 TEST_F(PasswordFormManagerTest, TestNewLogin) {
227 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
228 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
230 // User submits credentials for the observed form.
231 PasswordForm credentials = *observed_form();
232 credentials.username_value = saved_match()->username_value;
233 credentials.password_value = saved_match()->password_value;
234 credentials.preferred = true;
235 manager.ProvisionallySave(
236 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
238 // Successful login. The PasswordManager would instruct PasswordFormManager
239 // to save, which should know this is a new login.
240 EXPECT_TRUE(manager.IsNewLogin());
241 // Make sure the credentials that would be submitted on successful login
242 // are going to match the stored entry in the db.
243 EXPECT_EQ(observed_form()->origin.spec(),
244 GetPendingCredentials(&manager)->origin.spec());
245 EXPECT_EQ(observed_form()->signon_realm,
246 GetPendingCredentials(&manager)->signon_realm);
247 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
248 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
249 EXPECT_EQ(saved_match()->password_value,
250 GetPendingCredentials(&manager)->password_value);
251 EXPECT_EQ(saved_match()->username_value,
252 GetPendingCredentials(&manager)->username_value);
253 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
254 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
256 // Now, suppose the user re-visits the site and wants to save an additional
257 // login for the site with a new username. In this case, the matching phase
258 // will yield the previously saved login.
259 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
260 // Set up the new login.
261 base::string16 new_user = ASCIIToUTF16("newuser");
262 base::string16 new_pass = ASCIIToUTF16("newpass");
263 credentials.username_value = new_user;
264 credentials.password_value = new_pass;
265 manager.ProvisionallySave(
266 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
268 // Again, the PasswordFormManager should know this is still a new login.
269 EXPECT_TRUE(manager.IsNewLogin());
270 // And make sure everything squares up again.
271 EXPECT_EQ(observed_form()->origin.spec(),
272 GetPendingCredentials(&manager)->origin.spec());
273 EXPECT_EQ(observed_form()->signon_realm,
274 GetPendingCredentials(&manager)->signon_realm);
275 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
276 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
277 EXPECT_EQ(new_user, GetPendingCredentials(&manager)->username_value);
278 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
279 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
282 // If PSL-matched credentials had been suggested, but the user has overwritten
283 // the password, the provisionally saved credentials should no longer be
284 // considered as PSL-matched, so that the exception for not prompting before
285 // saving PSL-matched credentials should no longer apply.
286 TEST_F(PasswordFormManagerTest,
287 OverriddenPSLMatchedCredentialsNotMarkedAsPSLMatched) {
288 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
290 // The suggestion needs to be PSL-matched.
291 saved_match()->original_signon_realm = "www.example.org";
292 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
294 // User modifies the suggested password and submits the form.
295 PasswordForm credentials(*observed_form());
296 credentials.username_value = saved_match()->username_value;
297 credentials.password_value =
298 saved_match()->password_value + ASCIIToUTF16("modify");
299 manager.ProvisionallySave(
300 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
302 EXPECT_TRUE(manager.IsNewLogin());
303 EXPECT_FALSE(manager.IsPendingCredentialsPublicSuffixMatch());
306 TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
307 // Add a new password field to the test form. The PasswordFormManager should
308 // save the password from this field, instead of the current password field.
309 observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
311 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
312 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
314 // User enters current and new credentials to the observed form.
315 PasswordForm credentials(*observed_form());
316 credentials.username_value = saved_match()->username_value;
317 credentials.password_value = saved_match()->password_value;
318 credentials.new_password_value = ASCIIToUTF16("newpassword");
319 credentials.preferred = true;
320 manager.ProvisionallySave(
321 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
323 // Successful login. The PasswordManager would instruct PasswordFormManager
324 // to save, which should know this is a new login.
325 EXPECT_TRUE(manager.IsNewLogin());
326 EXPECT_EQ(credentials.origin, GetPendingCredentials(&manager)->origin);
327 EXPECT_EQ(credentials.signon_realm,
328 GetPendingCredentials(&manager)->signon_realm);
329 EXPECT_EQ(credentials.action, GetPendingCredentials(&manager)->action);
330 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
331 EXPECT_EQ(credentials.username_value,
332 GetPendingCredentials(&manager)->username_value);
334 // By this point, the PasswordFormManager should have promoted the new
335 // password value to be the current password, and should have wiped the
336 // password element names: they are likely going to be different on a login
337 // form, so it is not worth remembering them.
338 EXPECT_EQ(credentials.new_password_value,
339 GetPendingCredentials(&manager)->password_value);
340 EXPECT_TRUE(GetPendingCredentials(&manager)->password_element.empty());
341 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
342 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
345 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
346 // Create a PasswordFormManager with observed_form, as if we just
347 // saw this form and need to find matching logins.
348 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
350 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
352 // User submits credentials for the observed form using a username previously
353 // stored, but a new password. Note that the observed form may have different
354 // origin URL (as it does in this case) than the saved_match, but we want to
355 // make sure the updated password is reflected in saved_match, because that is
356 // what we autofilled.
357 base::string16 new_pass = ASCIIToUTF16("test2");
358 PasswordForm credentials = *observed_form();
359 credentials.username_value = saved_match()->username_value;
360 credentials.password_value = new_pass;
361 credentials.preferred = true;
362 manager.ProvisionallySave(
363 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
365 // Successful login. The PasswordManager would instruct PasswordFormManager
366 // to save, and since this is an update, it should know not to save as a new
368 EXPECT_FALSE(manager.IsNewLogin());
370 // Make sure the credentials that would be submitted on successful login
371 // are going to match the stored entry in the db. (This verifies correct
372 // behaviour for bug 1074420).
373 EXPECT_EQ(GetPendingCredentials(&manager)->origin.spec(),
374 saved_match()->origin.spec());
375 EXPECT_EQ(GetPendingCredentials(&manager)->signon_realm,
376 saved_match()->signon_realm);
377 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
378 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
381 TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
382 // Add a new password field to the test form. The PasswordFormManager should
383 // save the password from this field, instead of the current password field.
384 observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
386 // Given that |observed_form| was most likely a change password form, it
387 // should not serve as a source for updating meta-information stored with the
388 // old credentials, such as element names, as they are likely going to be
389 // different between change password and login forms. To test this in depth,
390 // forcibly wipe |submit_element|, which should normally trigger updating this
391 // field from |observed_form| in the UpdateLogin() step as a special case. We
392 // will verify in the end that this did not happen.
393 saved_match()->submit_element.clear();
395 InitializeMockStore();
396 TestPasswordManagerClient client_with_store(mock_store());
397 PasswordFormManager manager(NULL,
399 client_with_store.GetDriver(),
402 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
403 .WillRepeatedly(Return(false));
404 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
406 // User submits current and new credentials to the observed form.
407 PasswordForm credentials(*observed_form());
408 credentials.username_value = saved_match()->username_value;
409 credentials.password_value = saved_match()->password_value;
410 credentials.new_password_value = ASCIIToUTF16("test2");
411 credentials.preferred = true;
412 manager.ProvisionallySave(
413 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
415 // Successful login. The PasswordManager would instruct PasswordFormManager
416 // to save, and since this is an update, it should know not to save as a new
418 EXPECT_FALSE(manager.IsNewLogin());
420 // By now, the PasswordFormManager should have promoted the new password value
421 // already to be the current password, and should no longer maintain any info
422 // about the new password.
423 EXPECT_EQ(credentials.new_password_value,
424 GetPendingCredentials(&manager)->password_value);
425 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
426 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
428 // Trigger saving to exercise some special case handling in UpdateLogin().
429 PasswordForm new_credentials;
430 EXPECT_CALL(*mock_store(), UpdateLogin(_))
431 .WillOnce(testing::SaveArg<0>(&new_credentials));
433 Mock::VerifyAndClearExpectations(mock_store());
435 // No meta-information should be updated, only the password.
436 EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
437 EXPECT_EQ(saved_match()->username_element, new_credentials.username_element);
438 EXPECT_EQ(saved_match()->password_element, new_credentials.password_element);
439 EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
442 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
443 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
445 // Make sure we don't match a PasswordForm if it was originally saved on
446 // an SSL-valid page and we are now on a page with invalid certificate.
447 saved_match()->ssl_valid = true;
448 EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
450 saved_match()->ssl_valid = false;
451 // Different paths for action / origin are okay.
452 saved_match()->action = GURL("http://www.google.com/b/Login");
453 saved_match()->origin = GURL("http://www.google.com/foo");
454 EXPECT_FALSE(IgnoredResult(&manager, saved_match()));
456 // Results should be ignored if the client requests it.
457 client()->SetFormToFilter(*saved_match());
458 EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
461 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
462 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
464 saved_match()->action = GURL();
465 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
466 // User logs in with the autofilled username / password from saved_match.
467 PasswordForm login = *observed_form();
468 login.username_value = saved_match()->username_value;
469 login.password_value = saved_match()->password_value;
470 manager.ProvisionallySave(
471 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
472 EXPECT_FALSE(manager.IsNewLogin());
473 // We bless our saved PasswordForm entry with the action URL of the
475 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
478 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
479 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
481 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
482 // User logs in with the autofilled username / password from saved_match.
483 PasswordForm login = *observed_form();
484 login.username_value = saved_match()->username_value;
485 login.password_value = saved_match()->password_value;
487 manager.ProvisionallySave(
488 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
489 EXPECT_FALSE(manager.IsNewLogin());
490 // The observed action URL is different from the previously saved one, and
491 // is the same as the one that would be submitted on successful login.
492 EXPECT_NE(observed_form()->action, saved_match()->action);
493 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
496 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
497 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
499 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
500 PasswordForm login(*observed_form());
501 // The submitted action URL is different from the one observed on page load.
502 GURL new_action = GURL("http://www.google.com/new_action");
503 login.action = new_action;
505 manager.ProvisionallySave(
506 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
507 EXPECT_TRUE(manager.IsNewLogin());
508 // Check that the provisionally saved action URL is the same as the submitted
509 // action URL, not the one observed on page load.
510 EXPECT_EQ(new_action, GetPendingCredentials(&manager)->action);
513 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
514 // Need a MessageLoop for callbacks.
515 base::MessageLoop message_loop;
516 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
517 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
519 TestPasswordManagerClient client_with_store(password_store.get());
520 TestPasswordManager password_manager(&client_with_store);
521 PasswordFormManager manager(&password_manager,
523 client_with_store.GetDriver(),
526 EXPECT_CALL(*client_with_store.GetMockDriver(),
527 AllowPasswordGenerationForForm(_)).Times(1);
528 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
529 .WillRepeatedly(Return(false));
531 password_store->AddLogin(*saved_match());
532 manager.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
533 RunAllPendingTasks();
535 // The saved match has the right username already.
536 PasswordForm login(*observed_form());
537 login.username_value = saved_match()->username_value;
538 login.password_value = saved_match()->password_value;
539 login.preferred = true;
540 manager.ProvisionallySave(
541 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
543 EXPECT_FALSE(manager.IsNewLogin());
545 RunAllPendingTasks();
547 // Should be only one password stored, and should not have
548 // |other_possible_usernames| set anymore.
549 TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
550 EXPECT_EQ(1U, passwords.size());
551 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
552 EXPECT_EQ(saved_match()->username_value,
553 passwords[saved_match()->signon_realm][0].username_value);
555 passwords[saved_match()->signon_realm][0]
556 .other_possible_usernames.size());
558 // This time use an alternate username
559 PasswordFormManager manager_alt(&password_manager,
561 client_with_store.GetDriver(),
564 EXPECT_CALL(*client_with_store.GetMockDriver(),
565 AllowPasswordGenerationForForm(_)).Times(1);
566 password_store->Clear();
567 password_store->AddLogin(*saved_match());
568 manager_alt.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
569 RunAllPendingTasks();
571 base::string16 new_username = saved_match()->other_possible_usernames[0];
572 login.username_value = new_username;
573 manager_alt.ProvisionallySave(
574 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
576 EXPECT_FALSE(manager_alt.IsNewLogin());
578 RunAllPendingTasks();
580 // |other_possible_usernames| should also be empty, but username_value should
581 // be changed to match |new_username|
582 passwords = password_store->stored_passwords();
583 EXPECT_EQ(1U, passwords.size());
584 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
585 EXPECT_EQ(new_username,
586 passwords[saved_match()->signon_realm][0].username_value);
588 passwords[saved_match()->signon_realm][0]
589 .other_possible_usernames.size());
590 password_store->Shutdown();
593 TEST_F(PasswordFormManagerTest, TestValidForms) {
594 // User submits credentials for the observed form.
595 PasswordForm credentials = *observed_form();
596 credentials.scheme = PasswordForm::SCHEME_HTML;
597 credentials.username_value = saved_match()->username_value;
598 credentials.password_value = saved_match()->password_value;
600 // An alternate version of the form that also has a new_password_element.
601 PasswordForm new_credentials(*observed_form());
602 new_credentials.new_password_element = ASCIIToUTF16("NewPasswd");
603 new_credentials.new_password_value = ASCIIToUTF16("test1new");
605 // Form with both username_element and password_element.
606 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
607 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
608 EXPECT_TRUE(manager1.HasValidPasswordForm());
610 // Form with username_element, password_element, and new_password_element.
611 PasswordFormManager manager2(NULL, NULL, NULL, new_credentials, false);
612 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
613 EXPECT_TRUE(manager2.HasValidPasswordForm());
615 // Form with username_element and only new_password_element.
616 new_credentials.password_element.clear();
617 PasswordFormManager manager3(NULL, NULL, NULL, new_credentials, false);
618 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
619 EXPECT_TRUE(manager3.HasValidPasswordForm());
621 // Form without a username_element but with a password_element.
622 credentials.username_element.clear();
623 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
624 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
625 EXPECT_TRUE(manager4.HasValidPasswordForm());
627 // Form without a username_element but with a new_password_element.
628 new_credentials.username_element.clear();
629 PasswordFormManager manager5(NULL, NULL, NULL, new_credentials, false);
630 SimulateMatchingPhase(&manager5, RESULT_NO_MATCH);
631 EXPECT_TRUE(manager5.HasValidPasswordForm());
633 // Form without a password_element but with a username_element.
634 credentials.username_element = saved_match()->username_element;
635 credentials.password_element.clear();
636 PasswordFormManager manager6(NULL, NULL, NULL, credentials, false);
637 SimulateMatchingPhase(&manager6, RESULT_NO_MATCH);
638 EXPECT_FALSE(manager6.HasValidPasswordForm());
640 // Form with neither a password_element nor a username_element.
641 credentials.username_element.clear();
642 credentials.password_element.clear();
643 PasswordFormManager manager7(NULL, NULL, NULL, credentials, false);
644 SimulateMatchingPhase(&manager7, RESULT_NO_MATCH);
645 EXPECT_FALSE(manager7.HasValidPasswordForm());
648 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
649 // User submits credentials for the observed form.
650 PasswordForm credentials = *observed_form();
651 credentials.scheme = PasswordForm::SCHEME_BASIC;
652 credentials.username_value = saved_match()->username_value;
653 credentials.password_value = saved_match()->password_value;
655 // Form with both username_element and password_element.
656 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
657 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
658 EXPECT_TRUE(manager1.HasValidPasswordForm());
660 // Form without a username_element but with a password_element.
661 credentials.username_element.clear();
662 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
663 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
664 EXPECT_TRUE(manager2.HasValidPasswordForm());
666 // Form without a password_element but with a username_element.
667 credentials.username_element = saved_match()->username_element;
668 credentials.password_element.clear();
669 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
670 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
671 EXPECT_TRUE(manager3.HasValidPasswordForm());
673 // Form with neither a password_element nor a username_element.
674 credentials.username_element.clear();
675 credentials.password_element.clear();
676 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
677 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
678 EXPECT_TRUE(manager4.HasValidPasswordForm());
681 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
682 base::MessageLoop message_loop;
684 TestPasswordManager password_manager(client());
685 PasswordFormManager manager_no_creds(&password_manager,
687 client()->GetDriver(),
691 // First time sign-up attempt. Password store does not contain matching
692 // credentials. AllowPasswordGenerationForForm should be called to send the
693 // "not blacklisted" message.
694 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
696 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_creds);
697 std::vector<PasswordForm*> result;
698 SimulateResponseFromPasswordStore(&manager_no_creds, result);
699 Mock::VerifyAndClearExpectations(client()->GetMockDriver());
701 // Signing up on a previously visited site. Credentials are found in the
702 // password store, and are not blacklisted. AllowPasswordGenerationForForm
703 // should be called to send the "not blacklisted" message.
704 PasswordFormManager manager_creds(&password_manager,
706 client()->GetDriver(),
709 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
711 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
712 .WillRepeatedly(Return(false));
713 SimulateFetchMatchingLoginsFromPasswordStore(&manager_creds);
714 // We need add heap allocated objects to result.
715 result.push_back(CreateSavedMatch(false));
716 SimulateResponseFromPasswordStore(&manager_creds, result);
717 Mock::VerifyAndClearExpectations(client()->GetMockDriver());
719 // There are cases, such as when a form is explicitly for creating a new
720 // password, where we may ignore saved credentials. Make sure that we still
721 // allow generation in that case.
722 PasswordForm signup_form(*observed_form());
723 signup_form.new_password_element = base::ASCIIToUTF16("new_password_field");
725 PasswordFormManager manager_dropped_creds(&password_manager,
727 client()->GetDriver(),
730 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
732 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
733 .WillRepeatedly(Return(false));
734 SimulateFetchMatchingLoginsFromPasswordStore(&manager_dropped_creds);
736 result.push_back(CreateSavedMatch(false));
737 SimulateResponseFromPasswordStore(&manager_dropped_creds, result);
738 Mock::VerifyAndClearExpectations(client()->GetMockDriver());
740 // Signing up on a previously visited site. Credentials are found in the
741 // password store, but they are blacklisted. AllowPasswordGenerationForForm
742 // should not be called and no "not blacklisted" message sent.
743 PasswordFormManager manager_blacklisted(&password_manager,
745 client()->GetDriver(),
748 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
750 SimulateFetchMatchingLoginsFromPasswordStore(&manager_blacklisted);
752 result.push_back(CreateSavedMatch(true));
753 SimulateResponseFromPasswordStore(&manager_blacklisted, result);
754 Mock::VerifyAndClearExpectations(client()->GetMockDriver());
757 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
758 base::MessageLoop message_loop;
760 // Simulate having two matches for this origin, one of which was from a form
761 // with different HTML tags for elements. Because of scoring differences,
762 // only the first form will be sent to Autofill().
763 TestPasswordManager password_manager(client());
764 PasswordFormManager manager_match(&password_manager,
766 client()->GetDriver(),
769 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
771 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
772 .WillRepeatedly(Return(false));
774 std::vector<PasswordForm*> results;
775 results.push_back(CreateSavedMatch(false));
776 results.push_back(CreateSavedMatch(false));
777 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
778 results[1]->password_element = ASCIIToUTF16("signup_password");
779 results[1]->username_element = ASCIIToUTF16("signup_username");
780 SimulateFetchMatchingLoginsFromPasswordStore(&manager_match);
781 SimulateResponseFromPasswordStore(&manager_match, results);
782 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
785 // Same thing, except this time the credentials that don't match quite as
786 // well are generated. They should now be sent to Autofill().
787 PasswordFormManager manager_no_match(&password_manager,
789 client()->GetDriver(),
792 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
795 results.push_back(CreateSavedMatch(false));
796 results.push_back(CreateSavedMatch(false));
797 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
798 results[1]->password_element = ASCIIToUTF16("signup_password");
799 results[1]->username_element = ASCIIToUTF16("signup_username");
800 results[1]->type = PasswordForm::TYPE_GENERATED;
801 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_match);
802 SimulateResponseFromPasswordStore(&manager_no_match, results);
803 EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
806 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
807 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
808 PasswordForm credentials(*observed_form());
809 credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
810 credentials.other_possible_usernames.push_back(
811 ASCIIToUTF16("378282246310005"));
812 credentials.other_possible_usernames.push_back(
813 ASCIIToUTF16("other username"));
814 credentials.username_value = ASCIIToUTF16("test@gmail.com");
816 SanitizePossibleUsernames(&manager, &credentials);
818 // Possible credit card number and SSN are stripped.
819 std::vector<base::string16> expected;
820 expected.push_back(ASCIIToUTF16("other username"));
821 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
823 credentials.other_possible_usernames.clear();
824 credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
825 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
826 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
827 credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
828 credentials.other_possible_usernames.push_back(
829 ASCIIToUTF16("test@gmail.com"));
831 SanitizePossibleUsernames(&manager, &credentials);
833 // SSN, duplicate in |other_possible_usernames| and duplicate of
834 // |username_value| all removed.
836 expected.push_back(ASCIIToUTF16("duplicate"));
837 expected.push_back(ASCIIToUTF16("random"));
838 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
841 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
842 InitializeMockStore();
844 // We've found this form on a website:
845 PasswordForm encountered_form;
846 encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
847 encountered_form.signon_realm = "http://accounts.google.com/";
848 encountered_form.action = GURL("http://accounts.google.com/Login");
849 encountered_form.username_element = ASCIIToUTF16("Email");
850 encountered_form.password_element = ASCIIToUTF16("Passwd");
851 encountered_form.submit_element = ASCIIToUTF16("signIn");
853 TestPasswordManagerClient client_with_store(mock_store());
854 EXPECT_CALL(*(client_with_store.GetMockDriver()), IsOffTheRecord())
855 .WillRepeatedly(Return(false));
856 EXPECT_CALL(*(client_with_store.GetMockDriver()),
857 AllowPasswordGenerationForForm(_));
859 TestPasswordManager manager(&client_with_store);
860 PasswordFormManager form_manager(&manager,
862 client_with_store.GetMockDriver(),
866 const PasswordStore::AuthorizationPromptPolicy auth_policy =
867 PasswordStore::DISALLOW_PROMPT;
868 EXPECT_CALL(*mock_store(),
869 GetLogins(encountered_form, auth_policy, &form_manager));
870 form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
872 // Password store only has these incomplete credentials.
873 PasswordForm* incomplete_form = new PasswordForm();
874 incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
875 incomplete_form->signon_realm = "http://accounts.google.com/";
876 incomplete_form->password_value = ASCIIToUTF16("my_password");
877 incomplete_form->username_value = ASCIIToUTF16("my_username");
878 incomplete_form->preferred = true;
879 incomplete_form->ssl_valid = false;
880 incomplete_form->scheme = PasswordForm::SCHEME_HTML;
882 // We expect to see this form eventually sent to the Password store. It
883 // has password/username values from the store and 'username_element',
884 // 'password_element', 'submit_element' and 'action' fields copied from
885 // the encountered form.
886 PasswordForm complete_form(*incomplete_form);
887 complete_form.action = encountered_form.action;
888 complete_form.password_element = encountered_form.password_element;
889 complete_form.username_element = encountered_form.username_element;
890 complete_form.submit_element = encountered_form.submit_element;
892 PasswordForm obsolete_form(*incomplete_form);
893 obsolete_form.action = encountered_form.action;
895 // Feed the incomplete credentials to the manager.
896 std::vector<PasswordForm*> results;
897 results.push_back(incomplete_form); // Takes ownership.
898 form_manager.OnRequestDone(results);
900 form_manager.ProvisionallySave(
901 complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
902 // By now that form has been used once.
903 complete_form.times_used = 1;
904 obsolete_form.times_used = 1;
906 // Check that PasswordStore receives an update request with the complete form.
907 EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form));
908 EXPECT_CALL(*mock_store(), AddLogin(complete_form));
912 TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
913 base::MessageLoop message_loop;
915 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
916 .WillRepeatedly(Return(false));
917 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_));
919 TestPasswordManager password_manager(client());
920 PasswordFormManager manager(&password_manager,
922 client()->GetMockDriver(),
926 // Simulate having two matches for this form, first comes from different
927 // signon realm, but reports the same origin and action as matched form.
928 // Second candidate has the same signon realm as the form, but has a different
929 // origin and action. Public suffix match is the most important criterion so
930 // the second candidate should be selected.
931 std::vector<PasswordForm*> results;
932 results.push_back(CreateSavedMatch(false));
933 results.push_back(CreateSavedMatch(false));
934 results[0]->original_signon_realm = "http://accounts2.google.com";
935 results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
936 results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
937 SimulateFetchMatchingLoginsFromPasswordStore(&manager);
938 SimulateResponseFromPasswordStore(&manager, results);
939 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
940 EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
941 ->second->original_signon_realm);
944 TEST_F(PasswordFormManagerTest, InvalidActionURLsDoNotMatch) {
945 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
947 PasswordForm invalid_action_form(*observed_form());
948 invalid_action_form.action = GURL("http://");
949 ASSERT_FALSE(invalid_action_form.action.is_valid());
950 ASSERT_FALSE(invalid_action_form.action.is_empty());
951 // Non-empty invalid action URLs should not match other actions.
952 // First when the compared form has an invalid URL:
954 manager.DoesManage(invalid_action_form) &
955 PasswordFormManager::RESULT_ACTION_MATCH);
956 // Then when the observed form has an invalid URL:
957 PasswordForm valid_action_form(*observed_form());
958 PasswordFormManager invalid_manager(
959 NULL, client(), NULL, invalid_action_form, false);
961 invalid_manager.DoesManage(valid_action_form) &
962 PasswordFormManager::RESULT_ACTION_MATCH);
965 TEST_F(PasswordFormManagerTest, EmptyActionURLsDoNotMatchNonEmpty) {
966 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
968 PasswordForm empty_action_form(*observed_form());
969 empty_action_form.action = GURL();
970 ASSERT_FALSE(empty_action_form.action.is_valid());
971 ASSERT_TRUE(empty_action_form.action.is_empty());
972 // First when the compared form has an empty URL:
974 manager.DoesManage(empty_action_form) &
975 PasswordFormManager::RESULT_ACTION_MATCH);
976 // Then when the observed form has an empty URL:
977 PasswordForm valid_action_form(*observed_form());
978 PasswordFormManager empty_action_manager(
979 NULL, client(), NULL, empty_action_form, false);
981 empty_action_manager.DoesManage(valid_action_form) &
982 PasswordFormManager::RESULT_ACTION_MATCH);
985 TEST_F(PasswordFormManagerTest, NonHTMLFormsDoNotMatchHTMLForms) {
986 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
988 ASSERT_EQ(PasswordForm::SCHEME_HTML, observed_form()->scheme);
989 PasswordForm non_html_form(*observed_form());
990 non_html_form.scheme = PasswordForm::SCHEME_DIGEST;
992 manager.DoesManage(non_html_form) &
993 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
995 // The other way round: observing a non-HTML form, don't match a HTML form.
996 PasswordForm html_form(*observed_form());
997 PasswordFormManager non_html_manager(
998 NULL, client(), NULL, non_html_form, false);
1000 non_html_manager.DoesManage(html_form) &
1001 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1004 TEST_F(PasswordFormManagerTest, OriginCheck_HostsMatchExactly) {
1005 // Host part of origins must match exactly, not just by prefix.
1006 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1008 PasswordForm form_longer_host(*observed_form());
1009 form_longer_host.origin = GURL("http://accounts.google.com.au/a/LoginAuth");
1010 // Check that accounts.google.com does not match accounts.google.com.au.
1012 manager.DoesManage(form_longer_host) &
1013 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1016 TEST_F(PasswordFormManagerTest, OriginCheck_MoreSecureSchemePathsMatchPrefix) {
1017 // If the URL scheme of the observed form is HTTP, and the compared form is
1018 // HTTPS, then the compared form can extend the path.
1019 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1021 PasswordForm form_longer_path(*observed_form());
1022 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1024 manager.DoesManage(form_longer_path) &
1025 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1028 TEST_F(PasswordFormManagerTest,
1029 OriginCheck_NotMoreSecureSchemePathsMatchExactly) {
1030 // If the origin URL scheme of the compared form is not more secure than that
1031 // of the observed form, then the paths must match exactly.
1032 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1034 PasswordForm form_longer_path(*observed_form());
1035 form_longer_path.origin = GURL("http://accounts.google.com/a/LoginAuth/sec");
1036 // Check that /a/LoginAuth does not match /a/LoginAuth/more.
1038 manager.DoesManage(form_longer_path) &
1039 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1041 PasswordForm secure_observed_form(*observed_form());
1042 secure_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth");
1043 PasswordFormManager secure_manager(
1044 NULL, client(), NULL, secure_observed_form, true);
1045 // Also for HTTPS in the observed form, and HTTP in the compared form, an
1046 // exact path match is expected.
1048 secure_manager.DoesManage(form_longer_path) &
1049 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1050 // Not even upgrade to HTTPS in the compared form should help.
1051 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1053 secure_manager.DoesManage(form_longer_path) &
1054 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1057 TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) {
1058 // Need a MessageLoop for callbacks.
1059 base::MessageLoop message_loop;
1060 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1061 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
1063 TestPasswordManagerClient client_with_store(password_store.get());
1064 TestPasswordManager password_manager(&client_with_store);
1065 EXPECT_CALL(*client_with_store.GetMockDriver(),
1066 AllowPasswordGenerationForForm(_)).Times(2);
1067 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1068 .WillRepeatedly(Return(false));
1070 // Add two credentials with the same username. Both should score the same
1071 // and be seen as candidates to autofill.
1072 PasswordForm first(*saved_match());
1073 first.action = observed_form()->action;
1074 first.password_value = ASCIIToUTF16("first");
1075 password_store->AddLogin(first);
1077 PasswordForm second(first);
1078 second.origin = GURL("http://accounts.google.com/a/AddLogin");
1079 second.password_value = ASCIIToUTF16("second");
1080 second.preferred = false;
1081 password_store->AddLogin(second);
1083 PasswordFormManager storing_manager(&password_manager,
1085 client_with_store.GetDriver(),
1088 storing_manager.FetchMatchingLoginsFromPasswordStore(
1089 PasswordStore::ALLOW_PROMPT);
1090 RunAllPendingTasks();
1092 // We always take the last credential with a particular username, regardless
1093 // of which ones are labeled preferred.
1094 EXPECT_EQ(ASCIIToUTF16("second"),
1095 storing_manager.preferred_match()->password_value);
1097 PasswordForm login(*observed_form());
1098 login.username_value = saved_match()->username_value;
1099 login.password_value = ASCIIToUTF16("third");
1100 login.preferred = true;
1101 storing_manager.ProvisionallySave(
1102 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1104 EXPECT_FALSE(storing_manager.IsNewLogin());
1105 storing_manager.Save();
1106 RunAllPendingTasks();
1108 PasswordFormManager retrieving_manager(&password_manager,
1110 client_with_store.GetDriver(),
1114 retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1115 PasswordStore::ALLOW_PROMPT);
1116 RunAllPendingTasks();
1118 // Make sure that the preferred match is updated appropriately.
1119 EXPECT_EQ(ASCIIToUTF16("third"),
1120 retrieving_manager.preferred_match()->password_value);
1121 password_store->Shutdown();
1124 TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword) {
1125 InitializeMockStore();
1126 TestPasswordManagerClient client_with_store(mock_store());
1127 TestPasswordManager password_manager(&client_with_store);
1128 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1129 .WillRepeatedly(Return(false));
1131 PasswordForm form(*observed_form());
1133 autofill::FormFieldData field;
1134 field.label = ASCIIToUTF16("full_name");
1135 field.name = ASCIIToUTF16("full_name");
1136 field.form_control_type = "text";
1137 form.form_data.fields.push_back(field);
1139 field.label = ASCIIToUTF16("Email");
1140 field.name = ASCIIToUTF16("Email");
1141 field.form_control_type = "text";
1142 form.form_data.fields.push_back(field);
1144 field.label = ASCIIToUTF16("password");
1145 field.name = ASCIIToUTF16("password");
1146 field.form_control_type = "password";
1147 form.form_data.fields.push_back(field);
1149 // For newly saved passwords, upload a vote for autofill::PASSWORD.
1150 MockPasswordFormManager form_manager(&password_manager,
1152 client_with_store.GetDriver(),
1155 SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH);
1157 PasswordForm form_to_save(form);
1158 form_to_save.preferred = true;
1159 form_to_save.username_value = ASCIIToUTF16("username");
1160 form_to_save.password_value = ASCIIToUTF16("1234");
1162 EXPECT_CALL(form_manager, UploadPasswordForm(_, autofill::PASSWORD)).Times(1);
1163 form_manager.ProvisionallySave(
1165 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1166 form_manager.Save();
1167 Mock::VerifyAndClearExpectations(&form_manager);
1169 // Do not upload a vote if the user is blacklisting the form.
1170 MockPasswordFormManager blacklist_form_manager(&password_manager,
1172 client_with_store.GetDriver(),
1175 SimulateMatchingPhase(&blacklist_form_manager, RESULT_NO_MATCH);
1177 EXPECT_CALL(blacklist_form_manager,
1178 UploadPasswordForm(_, autofill::PASSWORD)).Times(0);
1179 blacklist_form_manager.PermanentlyBlacklist();
1180 Mock::VerifyAndClearExpectations(&blacklist_form_manager);
1183 TEST_F(PasswordFormManagerTest, UploadFormData_AccountCreationPassword) {
1184 InitializeMockStore();
1185 TestPasswordManagerClient client_with_store(mock_store());
1186 TestPasswordManager password_manager(&client_with_store);
1187 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1188 .WillRepeatedly(Return(false));
1190 PasswordForm form(*observed_form());
1192 autofill::FormFieldData field;
1193 field.label = ASCIIToUTF16("Email");
1194 field.name = ASCIIToUTF16("Email");
1195 field.form_control_type = "text";
1196 form.form_data.fields.push_back(field);
1198 field.label = ASCIIToUTF16("password");
1199 field.name = ASCIIToUTF16("password");
1200 field.form_control_type = "password";
1201 form.form_data.fields.push_back(field);
1203 MockPasswordFormManager form_manager(&password_manager,
1205 client_with_store.GetDriver(),
1208 std::vector<PasswordForm*> result;
1209 result.push_back(CreateSavedMatch(false));
1211 field.label = ASCIIToUTF16("full_name");
1212 field.name = ASCIIToUTF16("full_name");
1213 field.form_control_type = "text";
1214 result[0]->form_data.fields.push_back(field);
1216 field.label = ASCIIToUTF16("Email");
1217 field.name = ASCIIToUTF16("Email");
1218 field.form_control_type = "text";
1219 result[0]->form_data.fields.push_back(field);
1221 field.label = ASCIIToUTF16("password");
1222 field.name = ASCIIToUTF16("password");
1223 field.form_control_type = "password";
1224 result[0]->form_data.fields.push_back(field);
1226 PasswordForm form_to_save(form);
1227 form_to_save.preferred = true;
1228 form_to_save.username_value = result[0]->username_value;
1229 form_to_save.password_value = result[0]->password_value;
1231 SimulateFetchMatchingLoginsFromPasswordStore(&form_manager);
1232 SimulateResponseFromPasswordStore(&form_manager, result);
1234 EXPECT_CALL(form_manager,
1235 UploadPasswordForm(_,
1236 autofill::ACCOUNT_CREATION_PASSWORD)).Times(1);
1237 form_manager.ProvisionallySave(
1239 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1240 form_manager.Save();
1243 TEST_F(PasswordFormManagerTest, CorrectlySavePasswordWithoutUsernameFields) {
1244 // Need a MessageLoop for callbacks.
1245 base::MessageLoop message_loop;
1246 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1247 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
1249 TestPasswordManagerClient client_with_store(password_store.get());
1250 TestPasswordManager password_manager(&client_with_store);
1251 EXPECT_CALL(*client_with_store.GetMockDriver(),
1252 AllowPasswordGenerationForForm(_)).Times(2);
1253 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1254 .WillRepeatedly(Return(false));
1256 PasswordForm form(*observed_form());
1257 form.username_element.clear();
1258 form.password_value = ASCIIToUTF16("password");
1259 form.preferred = true;
1261 PasswordFormManager storing_manager(&password_manager,
1263 client_with_store.GetDriver(),
1266 storing_manager.FetchMatchingLoginsFromPasswordStore(
1267 PasswordStore::ALLOW_PROMPT);
1268 RunAllPendingTasks();
1270 storing_manager.ProvisionallySave(
1271 form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1273 EXPECT_TRUE(storing_manager.IsNewLogin());
1274 storing_manager.Save();
1275 RunAllPendingTasks();
1277 PasswordFormManager retrieving_manager(&password_manager,
1279 client_with_store.GetDriver(),
1283 retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1284 PasswordStore::ALLOW_PROMPT);
1285 RunAllPendingTasks();
1287 // Make sure that the preferred match is updated appropriately.
1288 EXPECT_EQ(ASCIIToUTF16("password"),
1289 retrieving_manager.preferred_match()->password_value);
1290 password_store->Shutdown();
1293 } // namespace password_manager