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/browser/autofill_manager.h"
14 #include "components/autofill/core/browser/test_autofill_client.h"
15 #include "components/autofill/core/browser/test_autofill_driver.h"
16 #include "components/autofill/core/browser/test_personal_data_manager.h"
17 #include "components/autofill/core/common/password_form.h"
18 #include "components/password_manager/core/browser/mock_password_store.h"
19 #include "components/password_manager/core/browser/password_form_manager.h"
20 #include "components/password_manager/core/browser/password_manager.h"
21 #include "components/password_manager/core/browser/password_manager_driver.h"
22 #include "components/password_manager/core/browser/password_store.h"
23 #include "components/password_manager/core/browser/stub_password_manager_client.h"
24 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
25 #include "components/password_manager/core/browser/test_password_store.h"
26 #include "components/password_manager/core/common/password_manager_pref_names.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 using autofill::PasswordForm;
31 using base::ASCIIToUTF16;
34 using ::testing::Mock;
35 using ::testing::NiceMock;
36 using ::testing::Return;
37 using ::testing::SaveArg;
39 namespace password_manager {
43 void RunAllPendingTasks() {
44 base::RunLoop run_loop;
45 base::MessageLoop::current()->PostTask(
46 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
50 class MockAutofillManager : public autofill::AutofillManager {
52 MockAutofillManager(autofill::AutofillDriver* driver,
53 autofill::AutofillClient* client,
54 autofill::PersonalDataManager* data_manager) :
55 AutofillManager(driver, client, data_manager) {}
57 MOCK_METHOD2(UploadPasswordForm, bool(const autofill::FormData&,
58 const autofill::ServerFieldType&));
61 DISALLOW_COPY_AND_ASSIGN(MockAutofillManager);
64 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
66 MockPasswordManagerDriver():
67 mock_autofill_manager_(&test_autofill_driver_,
68 &test_autofill_client_,
69 &test_personal_data_manager_) {}
71 ~MockPasswordManagerDriver() {}
73 MOCK_METHOD0(IsOffTheRecord, bool());
74 MOCK_METHOD1(AllowPasswordGenerationForForm,
75 void(const autofill::PasswordForm&));
77 virtual autofill::AutofillManager* GetAutofillManager() override {
78 return &mock_autofill_manager_;
81 MockAutofillManager* mock_autofill_manager() {
82 return &mock_autofill_manager_;
86 autofill::TestAutofillDriver test_autofill_driver_;
87 autofill::TestAutofillClient test_autofill_client_;
88 autofill::TestPersonalDataManager test_personal_data_manager_;
90 NiceMock<MockAutofillManager> mock_autofill_manager_;
93 class TestPasswordManagerClient : public StubPasswordManagerClient {
95 explicit TestPasswordManagerClient(PasswordStore* password_store)
96 : password_store_(password_store) {
97 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerSavingEnabled,
101 virtual bool ShouldFilterAutofillResult(
102 const autofill::PasswordForm& form) override {
103 if (form == form_to_filter_)
108 virtual PrefService* GetPrefs() override { return &prefs_; }
109 virtual PasswordStore* GetPasswordStore() override { return password_store_; }
110 virtual PasswordManagerDriver* GetDriver() override { return &driver_; }
112 void SetFormToFilter(const autofill::PasswordForm& form) {
113 form_to_filter_ = form;
116 MockPasswordManagerDriver* mock_driver() { return &driver_; }
119 autofill::PasswordForm form_to_filter_;
121 TestingPrefServiceSimple prefs_;
122 PasswordStore* password_store_;
123 NiceMock<MockPasswordManagerDriver> driver_;
126 class TestPasswordManager : public PasswordManager {
128 explicit TestPasswordManager(PasswordManagerClient* client)
129 : PasswordManager(client) {}
131 void Autofill(const autofill::PasswordForm& form_for_autofill,
132 const autofill::PasswordFormMap& best_matches,
133 const autofill::PasswordForm& preferred_match,
134 bool wait_for_username) const override {
135 best_matches_ = best_matches;
138 const autofill::PasswordFormMap& GetLatestBestMatches() {
139 return best_matches_;
143 // Marked mutable to get around constness of Autofill().
144 mutable autofill::PasswordFormMap best_matches_;
149 class PasswordFormManagerTest : public testing::Test {
151 PasswordFormManagerTest() {}
153 // Types of possible outcomes of simulated matching, see
154 // SimulateMatchingPhase.
155 enum ResultOfSimulatedMatching { RESULT_MATCH_FOUND, RESULT_NO_MATCH };
157 void SetUp() override {
158 observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
159 observed_form_.action = GURL("http://accounts.google.com/a/Login");
160 observed_form_.username_element = ASCIIToUTF16("Email");
161 observed_form_.password_element = ASCIIToUTF16("Passwd");
162 observed_form_.submit_element = ASCIIToUTF16("signIn");
163 observed_form_.signon_realm = "http://accounts.google.com";
165 saved_match_ = observed_form_;
166 saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
167 saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
168 saved_match_.preferred = true;
169 saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
170 saved_match_.password_value = ASCIIToUTF16("test1");
171 saved_match_.other_possible_usernames.push_back(
172 ASCIIToUTF16("test2@gmail.com"));
174 autofill::FormFieldData field;
175 field.label = ASCIIToUTF16("full_name");
176 field.name = ASCIIToUTF16("full_name");
177 field.form_control_type = "text";
178 saved_match_.form_data.fields.push_back(field);
180 field.label = ASCIIToUTF16("Email");
181 field.name = ASCIIToUTF16("Email");
182 field.form_control_type = "text";
183 saved_match_.form_data.fields.push_back(field);
185 field.label = ASCIIToUTF16("password");
186 field.name = ASCIIToUTF16("password");
187 field.form_control_type = "password";
188 saved_match_.form_data.fields.push_back(field);
190 mock_store_ = new NiceMock<MockPasswordStore>();
191 client_.reset(new TestPasswordManagerClient(mock_store_.get()));
194 void TearDown() override {
195 if (mock_store_.get())
196 mock_store_->Shutdown();
199 MockPasswordStore* mock_store() const { return mock_store_.get(); }
201 PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
202 return &p->pending_credentials_;
205 void SimulateMatchingPhase(PasswordFormManager* p,
206 ResultOfSimulatedMatching result) {
207 // Roll up the state to mock out the matching phase.
208 p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
209 if (result == RESULT_NO_MATCH)
212 PasswordForm* match = new PasswordForm(saved_match_);
213 // Heap-allocated form is owned by p.
214 p->best_matches_[match->username_value] = match;
215 p->preferred_match_ = match;
218 void SimulateFetchMatchingLoginsFromPasswordStore(
219 PasswordFormManager* manager) {
220 // Just need to update the internal states.
221 manager->state_ = PasswordFormManager::MATCHING_PHASE;
224 void SimulateResponseFromPasswordStore(
225 PasswordFormManager* manager,
226 const std::vector<PasswordForm*>& result) {
227 // Simply call the callback method when request done. This will transfer
228 // the ownership of the objects in |result| to the |manager|.
229 manager->OnGetPasswordStoreResults(result);
232 void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
233 p->SanitizePossibleUsernames(form);
236 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
237 return p->ShouldIgnoreResult(*form);
240 PasswordForm* observed_form() { return &observed_form_; }
241 PasswordForm* saved_match() { return &saved_match_; }
242 PasswordForm* CreateSavedMatch(bool blacklisted) {
243 // Owned by the caller of this method.
244 PasswordForm* match = new PasswordForm(saved_match_);
245 match->blacklisted_by_user = blacklisted;
249 TestPasswordManagerClient* client() { return client_.get(); }
252 // Necessary for callbacks, and for TestAutofillDriver.
253 base::MessageLoop message_loop;
255 PasswordForm observed_form_;
256 PasswordForm saved_match_;
257 scoped_refptr<NiceMock<MockPasswordStore>> mock_store_;
258 scoped_ptr<TestPasswordManagerClient> client_;
261 TEST_F(PasswordFormManagerTest, TestNewLogin) {
262 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
263 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
265 // User submits credentials for the observed form.
266 PasswordForm credentials = *observed_form();
267 credentials.username_value = saved_match()->username_value;
268 credentials.password_value = saved_match()->password_value;
269 credentials.preferred = true;
270 manager.ProvisionallySave(
271 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
273 // Successful login. The PasswordManager would instruct PasswordFormManager
274 // to save, which should know this is a new login.
275 EXPECT_TRUE(manager.IsNewLogin());
276 // Make sure the credentials that would be submitted on successful login
277 // are going to match the stored entry in the db.
278 EXPECT_EQ(observed_form()->origin.spec(),
279 GetPendingCredentials(&manager)->origin.spec());
280 EXPECT_EQ(observed_form()->signon_realm,
281 GetPendingCredentials(&manager)->signon_realm);
282 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
283 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
284 EXPECT_EQ(saved_match()->password_value,
285 GetPendingCredentials(&manager)->password_value);
286 EXPECT_EQ(saved_match()->username_value,
287 GetPendingCredentials(&manager)->username_value);
288 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
289 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
291 // Now, suppose the user re-visits the site and wants to save an additional
292 // login for the site with a new username. In this case, the matching phase
293 // will yield the previously saved login.
294 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
295 // Set up the new login.
296 base::string16 new_user = ASCIIToUTF16("newuser");
297 base::string16 new_pass = ASCIIToUTF16("newpass");
298 credentials.username_value = new_user;
299 credentials.password_value = new_pass;
300 manager.ProvisionallySave(
301 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
303 // Again, the PasswordFormManager should know this is still a new login.
304 EXPECT_TRUE(manager.IsNewLogin());
305 // And make sure everything squares up again.
306 EXPECT_EQ(observed_form()->origin.spec(),
307 GetPendingCredentials(&manager)->origin.spec());
308 EXPECT_EQ(observed_form()->signon_realm,
309 GetPendingCredentials(&manager)->signon_realm);
310 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
311 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
312 EXPECT_EQ(new_user, GetPendingCredentials(&manager)->username_value);
313 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
314 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
317 // If PSL-matched credentials had been suggested, but the user has overwritten
318 // the password, the provisionally saved credentials should no longer be
319 // considered as PSL-matched, so that the exception for not prompting before
320 // saving PSL-matched credentials should no longer apply.
321 TEST_F(PasswordFormManagerTest,
322 OverriddenPSLMatchedCredentialsNotMarkedAsPSLMatched) {
323 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
325 // The suggestion needs to be PSL-matched.
326 saved_match()->original_signon_realm = "www.example.org";
327 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
329 // User modifies the suggested password and submits the form.
330 PasswordForm credentials(*observed_form());
331 credentials.username_value = saved_match()->username_value;
332 credentials.password_value =
333 saved_match()->password_value + ASCIIToUTF16("modify");
334 manager.ProvisionallySave(
335 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
337 EXPECT_TRUE(manager.IsNewLogin());
338 EXPECT_FALSE(manager.IsPendingCredentialsPublicSuffixMatch());
341 TEST_F(PasswordFormManagerTest, PSLMatchedCredentialsMetadataUpdated) {
342 TestPasswordManagerClient client_with_store(mock_store());
343 EXPECT_CALL(*(client_with_store.mock_driver()), IsOffTheRecord())
344 .WillRepeatedly(Return(false));
346 TestPasswordManager manager(&client_with_store);
347 PasswordFormManager form_manager(&manager,
349 client_with_store.mock_driver(),
353 // The suggestion needs to be PSL-matched.
354 saved_match()->original_signon_realm = "www.example.org";
355 SimulateMatchingPhase(&form_manager, RESULT_MATCH_FOUND);
357 PasswordForm submitted_form(*observed_form());
358 submitted_form.preferred = true;
359 submitted_form.username_value = saved_match()->username_value;
360 submitted_form.password_value = saved_match()->password_value;
361 submitted_form.origin = saved_match()->origin;
362 form_manager.ProvisionallySave(
363 submitted_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
365 PasswordForm expected_saved_form(submitted_form);
366 expected_saved_form.times_used = 1;
367 expected_saved_form.other_possible_usernames.clear();
368 expected_saved_form.form_data = saved_match()->form_data;
369 PasswordForm actual_saved_form;
371 EXPECT_CALL(*(client_with_store.mock_driver()->mock_autofill_manager()),
372 UploadPasswordForm(_, autofill::ACCOUNT_CREATION_PASSWORD))
374 EXPECT_CALL(*mock_store(), AddLogin(_))
375 .WillOnce(SaveArg<0>(&actual_saved_form));
378 // Can't verify time, so ignore it.
379 actual_saved_form.date_created = base::Time();
380 EXPECT_EQ(expected_saved_form, actual_saved_form);
383 TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
384 // Add a new password field to the test form. The PasswordFormManager should
385 // save the password from this field, instead of the current password field.
386 observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
388 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
389 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
391 // User enters current and new credentials to the observed form.
392 PasswordForm credentials(*observed_form());
393 credentials.username_value = saved_match()->username_value;
394 credentials.password_value = saved_match()->password_value;
395 credentials.new_password_value = ASCIIToUTF16("newpassword");
396 credentials.preferred = true;
397 manager.ProvisionallySave(
398 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
400 // Successful login. The PasswordManager would instruct PasswordFormManager
401 // to save, which should know this is a new login.
402 EXPECT_TRUE(manager.IsNewLogin());
403 EXPECT_EQ(credentials.origin, GetPendingCredentials(&manager)->origin);
404 EXPECT_EQ(credentials.signon_realm,
405 GetPendingCredentials(&manager)->signon_realm);
406 EXPECT_EQ(credentials.action, GetPendingCredentials(&manager)->action);
407 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
408 EXPECT_EQ(credentials.username_value,
409 GetPendingCredentials(&manager)->username_value);
411 // By this point, the PasswordFormManager should have promoted the new
412 // password value to be the current password, and should have wiped the
413 // password element names: they are likely going to be different on a login
414 // form, so it is not worth remembering them.
415 EXPECT_EQ(credentials.new_password_value,
416 GetPendingCredentials(&manager)->password_value);
417 EXPECT_TRUE(GetPendingCredentials(&manager)->password_element.empty());
418 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
419 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
422 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
423 // Create a PasswordFormManager with observed_form, as if we just
424 // saw this form and need to find matching logins.
425 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
427 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
429 // User submits credentials for the observed form using a username previously
430 // stored, but a new password. Note that the observed form may have different
431 // origin URL (as it does in this case) than the saved_match, but we want to
432 // make sure the updated password is reflected in saved_match, because that is
433 // what we autofilled.
434 base::string16 new_pass = ASCIIToUTF16("test2");
435 PasswordForm credentials = *observed_form();
436 credentials.username_value = saved_match()->username_value;
437 credentials.password_value = new_pass;
438 credentials.preferred = true;
439 manager.ProvisionallySave(
440 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
442 // Successful login. The PasswordManager would instruct PasswordFormManager
443 // to save, and since this is an update, it should know not to save as a new
445 EXPECT_FALSE(manager.IsNewLogin());
447 // Make sure the credentials that would be submitted on successful login
448 // are going to match the stored entry in the db. (This verifies correct
449 // behaviour for bug 1074420).
450 EXPECT_EQ(GetPendingCredentials(&manager)->origin.spec(),
451 saved_match()->origin.spec());
452 EXPECT_EQ(GetPendingCredentials(&manager)->signon_realm,
453 saved_match()->signon_realm);
454 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
455 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
458 TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
459 // Add a new password field to the test form. The PasswordFormManager should
460 // save the password from this field, instead of the current password field.
461 observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
463 // Given that |observed_form| was most likely a change password form, it
464 // should not serve as a source for updating meta-information stored with the
465 // old credentials, such as element names, as they are likely going to be
466 // different between change password and login forms. To test this in depth,
467 // forcibly wipe |submit_element|, which should normally trigger updating this
468 // field from |observed_form| in the UpdateLogin() step as a special case. We
469 // will verify in the end that this did not happen.
470 saved_match()->submit_element.clear();
472 TestPasswordManagerClient client_with_store(mock_store());
473 PasswordFormManager manager(NULL,
475 client_with_store.GetDriver(),
478 EXPECT_CALL(*client_with_store.mock_driver(), IsOffTheRecord())
479 .WillRepeatedly(Return(false));
480 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
482 // User submits current and new credentials to the observed form.
483 PasswordForm credentials(*observed_form());
484 credentials.username_value = saved_match()->username_value;
485 credentials.password_value = saved_match()->password_value;
486 credentials.new_password_value = ASCIIToUTF16("test2");
487 credentials.preferred = true;
488 manager.ProvisionallySave(
489 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
491 // Successful login. The PasswordManager would instruct PasswordFormManager
492 // to save, and since this is an update, it should know not to save as a new
494 EXPECT_FALSE(manager.IsNewLogin());
496 // By now, the PasswordFormManager should have promoted the new password value
497 // already to be the current password, and should no longer maintain any info
498 // about the new password.
499 EXPECT_EQ(credentials.new_password_value,
500 GetPendingCredentials(&manager)->password_value);
501 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
502 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
504 // Trigger saving to exercise some special case handling in UpdateLogin().
505 PasswordForm new_credentials;
506 EXPECT_CALL(*mock_store(), UpdateLogin(_))
507 .WillOnce(testing::SaveArg<0>(&new_credentials));
509 Mock::VerifyAndClearExpectations(mock_store());
511 // No meta-information should be updated, only the password.
512 EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
513 EXPECT_EQ(saved_match()->username_element, new_credentials.username_element);
514 EXPECT_EQ(saved_match()->password_element, new_credentials.password_element);
515 EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
518 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
519 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
521 // Make sure we don't match a PasswordForm if it was originally saved on
522 // an SSL-valid page and we are now on a page with invalid certificate.
523 saved_match()->ssl_valid = true;
524 EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
526 saved_match()->ssl_valid = false;
527 // Different paths for action / origin are okay.
528 saved_match()->action = GURL("http://www.google.com/b/Login");
529 saved_match()->origin = GURL("http://www.google.com/foo");
530 EXPECT_FALSE(IgnoredResult(&manager, saved_match()));
532 // Results should be ignored if the client requests it.
533 client()->SetFormToFilter(*saved_match());
534 EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
537 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
538 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
540 saved_match()->action = GURL();
541 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
542 // User logs in with the autofilled username / password from saved_match.
543 PasswordForm login = *observed_form();
544 login.username_value = saved_match()->username_value;
545 login.password_value = saved_match()->password_value;
546 manager.ProvisionallySave(
547 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
548 EXPECT_FALSE(manager.IsNewLogin());
549 // We bless our saved PasswordForm entry with the action URL of the
551 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
554 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
555 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
557 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
558 // User logs in with the autofilled username / password from saved_match.
559 PasswordForm login = *observed_form();
560 login.username_value = saved_match()->username_value;
561 login.password_value = saved_match()->password_value;
563 manager.ProvisionallySave(
564 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
565 EXPECT_FALSE(manager.IsNewLogin());
566 // The observed action URL is different from the previously saved one, and
567 // is the same as the one that would be submitted on successful login.
568 EXPECT_NE(observed_form()->action, saved_match()->action);
569 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
572 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
573 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
575 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
576 PasswordForm login(*observed_form());
577 // The submitted action URL is different from the one observed on page load.
578 GURL new_action = GURL("http://www.google.com/new_action");
579 login.action = new_action;
581 manager.ProvisionallySave(
582 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
583 EXPECT_TRUE(manager.IsNewLogin());
584 // Check that the provisionally saved action URL is the same as the submitted
585 // action URL, not the one observed on page load.
586 EXPECT_EQ(new_action, GetPendingCredentials(&manager)->action);
589 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
590 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
591 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare()));
593 TestPasswordManagerClient client_with_store(password_store.get());
594 TestPasswordManager password_manager(&client_with_store);
595 PasswordFormManager manager(&password_manager,
597 client_with_store.GetDriver(),
600 EXPECT_CALL(*client_with_store.mock_driver(),
601 AllowPasswordGenerationForForm(_)).Times(1);
602 EXPECT_CALL(*client_with_store.mock_driver(), IsOffTheRecord())
603 .WillRepeatedly(Return(false));
605 password_store->AddLogin(*saved_match());
606 manager.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
607 RunAllPendingTasks();
609 // The saved match has the right username already.
610 PasswordForm login(*observed_form());
611 login.username_value = saved_match()->username_value;
612 login.password_value = saved_match()->password_value;
613 login.preferred = true;
614 manager.ProvisionallySave(
615 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
617 EXPECT_FALSE(manager.IsNewLogin());
619 RunAllPendingTasks();
621 // Should be only one password stored, and should not have
622 // |other_possible_usernames| set anymore.
623 TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
624 EXPECT_EQ(1U, passwords.size());
625 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
626 EXPECT_EQ(saved_match()->username_value,
627 passwords[saved_match()->signon_realm][0].username_value);
629 passwords[saved_match()->signon_realm][0]
630 .other_possible_usernames.size());
632 // This time use an alternate username
633 PasswordFormManager manager_alt(&password_manager,
635 client_with_store.GetDriver(),
638 EXPECT_CALL(*client_with_store.mock_driver(),
639 AllowPasswordGenerationForForm(_)).Times(1);
640 password_store->Clear();
641 password_store->AddLogin(*saved_match());
642 manager_alt.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
643 RunAllPendingTasks();
645 base::string16 new_username = saved_match()->other_possible_usernames[0];
646 login.username_value = new_username;
647 manager_alt.ProvisionallySave(
648 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
650 EXPECT_FALSE(manager_alt.IsNewLogin());
652 RunAllPendingTasks();
654 // |other_possible_usernames| should also be empty, but username_value should
655 // be changed to match |new_username|
656 passwords = password_store->stored_passwords();
657 EXPECT_EQ(1U, passwords.size());
658 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
659 EXPECT_EQ(new_username,
660 passwords[saved_match()->signon_realm][0].username_value);
662 passwords[saved_match()->signon_realm][0]
663 .other_possible_usernames.size());
664 password_store->Shutdown();
667 TEST_F(PasswordFormManagerTest, TestValidForms) {
668 // User submits credentials for the observed form.
669 PasswordForm credentials = *observed_form();
670 credentials.scheme = PasswordForm::SCHEME_HTML;
671 credentials.username_value = saved_match()->username_value;
672 credentials.password_value = saved_match()->password_value;
674 // An alternate version of the form that also has a new_password_element.
675 PasswordForm new_credentials(*observed_form());
676 new_credentials.new_password_element = ASCIIToUTF16("NewPasswd");
677 new_credentials.new_password_value = ASCIIToUTF16("test1new");
679 // Form with both username_element and password_element.
680 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
681 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
682 EXPECT_TRUE(manager1.HasValidPasswordForm());
684 // Form with username_element, password_element, and new_password_element.
685 PasswordFormManager manager2(NULL, NULL, NULL, new_credentials, false);
686 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
687 EXPECT_TRUE(manager2.HasValidPasswordForm());
689 // Form with username_element and only new_password_element.
690 new_credentials.password_element.clear();
691 PasswordFormManager manager3(NULL, NULL, NULL, new_credentials, false);
692 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
693 EXPECT_TRUE(manager3.HasValidPasswordForm());
695 // Form without a username_element but with a password_element.
696 credentials.username_element.clear();
697 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
698 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
699 EXPECT_TRUE(manager4.HasValidPasswordForm());
701 // Form without a username_element but with a new_password_element.
702 new_credentials.username_element.clear();
703 PasswordFormManager manager5(NULL, NULL, NULL, new_credentials, false);
704 SimulateMatchingPhase(&manager5, RESULT_NO_MATCH);
705 EXPECT_TRUE(manager5.HasValidPasswordForm());
707 // Form without a password_element but with a username_element.
708 credentials.username_element = saved_match()->username_element;
709 credentials.password_element.clear();
710 PasswordFormManager manager6(NULL, NULL, NULL, credentials, false);
711 SimulateMatchingPhase(&manager6, RESULT_NO_MATCH);
712 EXPECT_FALSE(manager6.HasValidPasswordForm());
714 // Form with neither a password_element nor a username_element.
715 credentials.username_element.clear();
716 credentials.password_element.clear();
717 PasswordFormManager manager7(NULL, NULL, NULL, credentials, false);
718 SimulateMatchingPhase(&manager7, RESULT_NO_MATCH);
719 EXPECT_FALSE(manager7.HasValidPasswordForm());
722 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
723 // User submits credentials for the observed form.
724 PasswordForm credentials = *observed_form();
725 credentials.scheme = PasswordForm::SCHEME_BASIC;
726 credentials.username_value = saved_match()->username_value;
727 credentials.password_value = saved_match()->password_value;
729 // Form with both username_element and password_element.
730 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
731 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
732 EXPECT_TRUE(manager1.HasValidPasswordForm());
734 // Form without a username_element but with a password_element.
735 credentials.username_element.clear();
736 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
737 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
738 EXPECT_TRUE(manager2.HasValidPasswordForm());
740 // Form without a password_element but with a username_element.
741 credentials.username_element = saved_match()->username_element;
742 credentials.password_element.clear();
743 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
744 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
745 EXPECT_TRUE(manager3.HasValidPasswordForm());
747 // Form with neither a password_element nor a username_element.
748 credentials.username_element.clear();
749 credentials.password_element.clear();
750 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
751 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
752 EXPECT_TRUE(manager4.HasValidPasswordForm());
755 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
756 TestPasswordManager password_manager(client());
757 PasswordFormManager manager_no_creds(&password_manager,
759 client()->GetDriver(),
763 // First time sign-up attempt. Password store does not contain matching
764 // credentials. AllowPasswordGenerationForForm should be called to send the
765 // "not blacklisted" message.
766 EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
768 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_creds);
769 std::vector<PasswordForm*> result;
770 SimulateResponseFromPasswordStore(&manager_no_creds, result);
771 Mock::VerifyAndClearExpectations(client()->mock_driver());
773 // Signing up on a previously visited site. Credentials are found in the
774 // password store, and are not blacklisted. AllowPasswordGenerationForForm
775 // should be called to send the "not blacklisted" message.
776 PasswordFormManager manager_creds(&password_manager,
778 client()->GetDriver(),
781 EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
783 EXPECT_CALL(*(client()->mock_driver()), IsOffTheRecord())
784 .WillRepeatedly(Return(false));
785 SimulateFetchMatchingLoginsFromPasswordStore(&manager_creds);
786 // We need add heap allocated objects to result.
787 result.push_back(CreateSavedMatch(false));
788 SimulateResponseFromPasswordStore(&manager_creds, result);
789 Mock::VerifyAndClearExpectations(client()->mock_driver());
791 // There are cases, such as when a form is explicitly for creating a new
792 // password, where we may ignore saved credentials. Make sure that we still
793 // allow generation in that case.
794 PasswordForm signup_form(*observed_form());
795 signup_form.new_password_element = base::ASCIIToUTF16("new_password_field");
797 PasswordFormManager manager_dropped_creds(&password_manager,
799 client()->GetDriver(),
802 EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
804 EXPECT_CALL(*(client()->mock_driver()), IsOffTheRecord())
805 .WillRepeatedly(Return(false));
806 SimulateFetchMatchingLoginsFromPasswordStore(&manager_dropped_creds);
808 result.push_back(CreateSavedMatch(false));
809 SimulateResponseFromPasswordStore(&manager_dropped_creds, result);
810 Mock::VerifyAndClearExpectations(client()->mock_driver());
812 // Signing up on a previously visited site. Credentials are found in the
813 // password store, but they are blacklisted. AllowPasswordGenerationForForm
814 // should not be called and no "not blacklisted" message sent.
815 PasswordFormManager manager_blacklisted(&password_manager,
817 client()->GetDriver(),
820 EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
822 SimulateFetchMatchingLoginsFromPasswordStore(&manager_blacklisted);
824 result.push_back(CreateSavedMatch(true));
825 SimulateResponseFromPasswordStore(&manager_blacklisted, result);
826 Mock::VerifyAndClearExpectations(client()->mock_driver());
829 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
830 // Simulate having two matches for this origin, one of which was from a form
831 // with different HTML tags for elements. Because of scoring differences,
832 // only the first form will be sent to Autofill().
833 TestPasswordManager password_manager(client());
834 PasswordFormManager manager_match(&password_manager,
836 client()->GetDriver(),
839 EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
841 EXPECT_CALL(*(client()->mock_driver()), IsOffTheRecord())
842 .WillRepeatedly(Return(false));
844 std::vector<PasswordForm*> results;
845 results.push_back(CreateSavedMatch(false));
846 results.push_back(CreateSavedMatch(false));
847 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
848 results[1]->password_element = ASCIIToUTF16("signup_password");
849 results[1]->username_element = ASCIIToUTF16("signup_username");
850 SimulateFetchMatchingLoginsFromPasswordStore(&manager_match);
851 SimulateResponseFromPasswordStore(&manager_match, results);
852 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
855 // Same thing, except this time the credentials that don't match quite as
856 // well are generated. They should now be sent to Autofill().
857 PasswordFormManager manager_no_match(&password_manager,
859 client()->GetDriver(),
862 EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_))
865 results.push_back(CreateSavedMatch(false));
866 results.push_back(CreateSavedMatch(false));
867 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
868 results[1]->password_element = ASCIIToUTF16("signup_password");
869 results[1]->username_element = ASCIIToUTF16("signup_username");
870 results[1]->type = PasswordForm::TYPE_GENERATED;
871 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_match);
872 SimulateResponseFromPasswordStore(&manager_no_match, results);
873 EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
876 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
877 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
878 PasswordForm credentials(*observed_form());
879 credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
880 credentials.other_possible_usernames.push_back(
881 ASCIIToUTF16("378282246310005"));
882 credentials.other_possible_usernames.push_back(
883 ASCIIToUTF16("other username"));
884 credentials.username_value = ASCIIToUTF16("test@gmail.com");
886 SanitizePossibleUsernames(&manager, &credentials);
888 // Possible credit card number and SSN are stripped.
889 std::vector<base::string16> expected;
890 expected.push_back(ASCIIToUTF16("other username"));
891 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
893 credentials.other_possible_usernames.clear();
894 credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
895 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
896 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
897 credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
898 credentials.other_possible_usernames.push_back(
899 ASCIIToUTF16("test@gmail.com"));
901 SanitizePossibleUsernames(&manager, &credentials);
903 // SSN, duplicate in |other_possible_usernames| and duplicate of
904 // |username_value| all removed.
906 expected.push_back(ASCIIToUTF16("duplicate"));
907 expected.push_back(ASCIIToUTF16("random"));
908 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
911 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
912 // We've found this form on a website:
913 PasswordForm encountered_form;
914 encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
915 encountered_form.signon_realm = "http://accounts.google.com/";
916 encountered_form.action = GURL("http://accounts.google.com/Login");
917 encountered_form.username_element = ASCIIToUTF16("Email");
918 encountered_form.password_element = ASCIIToUTF16("Passwd");
919 encountered_form.submit_element = ASCIIToUTF16("signIn");
921 TestPasswordManagerClient client_with_store(mock_store());
922 EXPECT_CALL(*(client_with_store.mock_driver()), IsOffTheRecord())
923 .WillRepeatedly(Return(false));
924 EXPECT_CALL(*(client_with_store.mock_driver()),
925 AllowPasswordGenerationForForm(_));
927 TestPasswordManager manager(&client_with_store);
928 PasswordFormManager form_manager(&manager,
930 client_with_store.mock_driver(),
934 const PasswordStore::AuthorizationPromptPolicy auth_policy =
935 PasswordStore::DISALLOW_PROMPT;
936 EXPECT_CALL(*mock_store(),
937 GetLogins(encountered_form, auth_policy, &form_manager));
938 form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
940 // Password store only has these incomplete credentials.
941 PasswordForm* incomplete_form = new PasswordForm();
942 incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
943 incomplete_form->signon_realm = "http://accounts.google.com/";
944 incomplete_form->password_value = ASCIIToUTF16("my_password");
945 incomplete_form->username_value = ASCIIToUTF16("my_username");
946 incomplete_form->preferred = true;
947 incomplete_form->ssl_valid = false;
948 incomplete_form->scheme = PasswordForm::SCHEME_HTML;
950 // We expect to see this form eventually sent to the Password store. It
951 // has password/username values from the store and 'username_element',
952 // 'password_element', 'submit_element' and 'action' fields copied from
953 // the encountered form.
954 PasswordForm complete_form(*incomplete_form);
955 complete_form.action = encountered_form.action;
956 complete_form.password_element = encountered_form.password_element;
957 complete_form.username_element = encountered_form.username_element;
958 complete_form.submit_element = encountered_form.submit_element;
960 PasswordForm obsolete_form(*incomplete_form);
961 obsolete_form.action = encountered_form.action;
963 // Feed the incomplete credentials to the manager.
964 std::vector<PasswordForm*> results;
965 results.push_back(incomplete_form); // Takes ownership.
966 form_manager.OnRequestDone(results);
968 form_manager.ProvisionallySave(
969 complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
970 // By now that form has been used once.
971 complete_form.times_used = 1;
972 obsolete_form.times_used = 1;
974 // Check that PasswordStore receives an update request with the complete form.
975 EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form));
976 EXPECT_CALL(*mock_store(), AddLogin(complete_form));
980 TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
981 EXPECT_CALL(*(client()->mock_driver()), IsOffTheRecord())
982 .WillRepeatedly(Return(false));
983 EXPECT_CALL(*(client()->mock_driver()), AllowPasswordGenerationForForm(_));
985 TestPasswordManager password_manager(client());
986 PasswordFormManager manager(&password_manager,
988 client()->mock_driver(),
992 // Simulate having two matches for this form, first comes from different
993 // signon realm, but reports the same origin and action as matched form.
994 // Second candidate has the same signon realm as the form, but has a different
995 // origin and action. Public suffix match is the most important criterion so
996 // the second candidate should be selected.
997 std::vector<PasswordForm*> results;
998 results.push_back(CreateSavedMatch(false));
999 results.push_back(CreateSavedMatch(false));
1000 results[0]->original_signon_realm = "http://accounts2.google.com";
1001 results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
1002 results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
1003 SimulateFetchMatchingLoginsFromPasswordStore(&manager);
1004 SimulateResponseFromPasswordStore(&manager, results);
1005 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
1006 EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
1007 ->second->original_signon_realm);
1010 TEST_F(PasswordFormManagerTest, InvalidActionURLsDoNotMatch) {
1011 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1013 PasswordForm invalid_action_form(*observed_form());
1014 invalid_action_form.action = GURL("http://");
1015 ASSERT_FALSE(invalid_action_form.action.is_valid());
1016 ASSERT_FALSE(invalid_action_form.action.is_empty());
1017 // Non-empty invalid action URLs should not match other actions.
1018 // First when the compared form has an invalid URL:
1020 manager.DoesManage(invalid_action_form) &
1021 PasswordFormManager::RESULT_ACTION_MATCH);
1022 // Then when the observed form has an invalid URL:
1023 PasswordForm valid_action_form(*observed_form());
1024 PasswordFormManager invalid_manager(
1025 NULL, client(), NULL, invalid_action_form, false);
1027 invalid_manager.DoesManage(valid_action_form) &
1028 PasswordFormManager::RESULT_ACTION_MATCH);
1031 TEST_F(PasswordFormManagerTest, EmptyActionURLsDoNotMatchNonEmpty) {
1032 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1034 PasswordForm empty_action_form(*observed_form());
1035 empty_action_form.action = GURL();
1036 ASSERT_FALSE(empty_action_form.action.is_valid());
1037 ASSERT_TRUE(empty_action_form.action.is_empty());
1038 // First when the compared form has an empty URL:
1040 manager.DoesManage(empty_action_form) &
1041 PasswordFormManager::RESULT_ACTION_MATCH);
1042 // Then when the observed form has an empty URL:
1043 PasswordForm valid_action_form(*observed_form());
1044 PasswordFormManager empty_action_manager(
1045 NULL, client(), NULL, empty_action_form, false);
1047 empty_action_manager.DoesManage(valid_action_form) &
1048 PasswordFormManager::RESULT_ACTION_MATCH);
1051 TEST_F(PasswordFormManagerTest, NonHTMLFormsDoNotMatchHTMLForms) {
1052 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1054 ASSERT_EQ(PasswordForm::SCHEME_HTML, observed_form()->scheme);
1055 PasswordForm non_html_form(*observed_form());
1056 non_html_form.scheme = PasswordForm::SCHEME_DIGEST;
1058 manager.DoesManage(non_html_form) &
1059 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1061 // The other way round: observing a non-HTML form, don't match a HTML form.
1062 PasswordForm html_form(*observed_form());
1063 PasswordFormManager non_html_manager(
1064 NULL, client(), NULL, non_html_form, false);
1066 non_html_manager.DoesManage(html_form) &
1067 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1070 TEST_F(PasswordFormManagerTest, OriginCheck_HostsMatchExactly) {
1071 // Host part of origins must match exactly, not just by prefix.
1072 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1074 PasswordForm form_longer_host(*observed_form());
1075 form_longer_host.origin = GURL("http://accounts.google.com.au/a/LoginAuth");
1076 // Check that accounts.google.com does not match accounts.google.com.au.
1078 manager.DoesManage(form_longer_host) &
1079 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1082 TEST_F(PasswordFormManagerTest, OriginCheck_MoreSecureSchemePathsMatchPrefix) {
1083 // If the URL scheme of the observed form is HTTP, and the compared form is
1084 // HTTPS, then the compared form can extend the path.
1085 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1087 PasswordForm form_longer_path(*observed_form());
1088 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1090 manager.DoesManage(form_longer_path) &
1091 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1094 TEST_F(PasswordFormManagerTest,
1095 OriginCheck_NotMoreSecureSchemePathsMatchExactly) {
1096 // If the origin URL scheme of the compared form is not more secure than that
1097 // of the observed form, then the paths must match exactly.
1098 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1100 PasswordForm form_longer_path(*observed_form());
1101 form_longer_path.origin = GURL("http://accounts.google.com/a/LoginAuth/sec");
1102 // Check that /a/LoginAuth does not match /a/LoginAuth/more.
1104 manager.DoesManage(form_longer_path) &
1105 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1107 PasswordForm secure_observed_form(*observed_form());
1108 secure_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth");
1109 PasswordFormManager secure_manager(
1110 NULL, client(), NULL, secure_observed_form, true);
1111 // Also for HTTPS in the observed form, and HTTP in the compared form, an
1112 // exact path match is expected.
1114 secure_manager.DoesManage(form_longer_path) &
1115 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1116 // Not even upgrade to HTTPS in the compared form should help.
1117 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1119 secure_manager.DoesManage(form_longer_path) &
1120 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1123 TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) {
1124 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1125 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare()));
1127 TestPasswordManagerClient client_with_store(password_store.get());
1128 TestPasswordManager password_manager(&client_with_store);
1129 EXPECT_CALL(*client_with_store.mock_driver(),
1130 AllowPasswordGenerationForForm(_)).Times(2);
1131 EXPECT_CALL(*client_with_store.mock_driver(), IsOffTheRecord())
1132 .WillRepeatedly(Return(false));
1134 // Add two credentials with the same username. Both should score the same
1135 // and be seen as candidates to autofill.
1136 PasswordForm first(*saved_match());
1137 first.action = observed_form()->action;
1138 first.password_value = ASCIIToUTF16("first");
1139 password_store->AddLogin(first);
1141 PasswordForm second(first);
1142 second.origin = GURL("http://accounts.google.com/a/AddLogin");
1143 second.password_value = ASCIIToUTF16("second");
1144 second.preferred = false;
1145 password_store->AddLogin(second);
1147 PasswordFormManager storing_manager(&password_manager,
1149 client_with_store.GetDriver(),
1152 storing_manager.FetchMatchingLoginsFromPasswordStore(
1153 PasswordStore::ALLOW_PROMPT);
1154 RunAllPendingTasks();
1156 // We always take the last credential with a particular username, regardless
1157 // of which ones are labeled preferred.
1158 EXPECT_EQ(ASCIIToUTF16("second"),
1159 storing_manager.preferred_match()->password_value);
1161 PasswordForm login(*observed_form());
1162 login.username_value = saved_match()->username_value;
1163 login.password_value = ASCIIToUTF16("third");
1164 login.preferred = true;
1165 storing_manager.ProvisionallySave(
1166 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1168 EXPECT_FALSE(storing_manager.IsNewLogin());
1169 storing_manager.Save();
1170 RunAllPendingTasks();
1172 PasswordFormManager retrieving_manager(&password_manager,
1174 client_with_store.GetDriver(),
1178 retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1179 PasswordStore::ALLOW_PROMPT);
1180 RunAllPendingTasks();
1182 // Make sure that the preferred match is updated appropriately.
1183 EXPECT_EQ(ASCIIToUTF16("third"),
1184 retrieving_manager.preferred_match()->password_value);
1185 password_store->Shutdown();
1188 TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword) {
1189 TestPasswordManagerClient client_with_store(mock_store());
1190 TestPasswordManager password_manager(&client_with_store);
1191 EXPECT_CALL(*client_with_store.mock_driver(), IsOffTheRecord())
1192 .WillRepeatedly(Return(false));
1194 // For newly saved passwords, upload a vote for autofill::PASSWORD.
1195 PasswordFormManager form_manager(&password_manager,
1197 client_with_store.GetDriver(),
1200 SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH);
1202 PasswordForm form_to_save(*saved_match());
1203 form_to_save.preferred = true;
1204 form_to_save.username_value = ASCIIToUTF16("username");
1205 form_to_save.password_value = ASCIIToUTF16("1234");
1207 EXPECT_CALL(*client_with_store.mock_driver()->mock_autofill_manager(),
1208 UploadPasswordForm(_, autofill::PASSWORD)).Times(1);
1209 form_manager.ProvisionallySave(
1211 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1212 form_manager.Save();
1213 Mock::VerifyAndClearExpectations(&form_manager);
1215 // Do not upload a vote if the user is blacklisting the form.
1216 PasswordFormManager blacklist_form_manager(&password_manager,
1218 client_with_store.GetDriver(),
1221 SimulateMatchingPhase(&blacklist_form_manager, RESULT_NO_MATCH);
1223 EXPECT_CALL(*client_with_store.mock_driver()->mock_autofill_manager(),
1224 UploadPasswordForm(_, autofill::PASSWORD)).Times(0);
1225 blacklist_form_manager.PermanentlyBlacklist();
1226 Mock::VerifyAndClearExpectations(&blacklist_form_manager);
1229 TEST_F(PasswordFormManagerTest, UploadFormData_AccountCreationPassword) {
1230 TestPasswordManagerClient client_with_store(mock_store());
1231 TestPasswordManager password_manager(&client_with_store);
1232 EXPECT_CALL(*client_with_store.mock_driver(), IsOffTheRecord())
1233 .WillRepeatedly(Return(false));
1235 PasswordForm form(*observed_form());
1237 autofill::FormFieldData field;
1238 field.label = ASCIIToUTF16("Email");
1239 field.name = ASCIIToUTF16("Email");
1240 field.form_control_type = "text";
1241 form.form_data.fields.push_back(field);
1243 field.label = ASCIIToUTF16("password");
1244 field.name = ASCIIToUTF16("password");
1245 field.form_control_type = "password";
1246 form.form_data.fields.push_back(field);
1248 PasswordFormManager form_manager(&password_manager,
1250 client_with_store.GetDriver(),
1253 std::vector<PasswordForm*> result;
1254 result.push_back(CreateSavedMatch(false));
1256 field.label = ASCIIToUTF16("full_name");
1257 field.name = ASCIIToUTF16("full_name");
1258 field.form_control_type = "text";
1259 result[0]->form_data.fields.push_back(field);
1261 field.label = ASCIIToUTF16("Email");
1262 field.name = ASCIIToUTF16("Email");
1263 field.form_control_type = "text";
1264 result[0]->form_data.fields.push_back(field);
1266 field.label = ASCIIToUTF16("password");
1267 field.name = ASCIIToUTF16("password");
1268 field.form_control_type = "password";
1269 result[0]->form_data.fields.push_back(field);
1271 PasswordForm form_to_save(form);
1272 form_to_save.preferred = true;
1273 form_to_save.username_value = result[0]->username_value;
1274 form_to_save.password_value = result[0]->password_value;
1276 SimulateFetchMatchingLoginsFromPasswordStore(&form_manager);
1277 SimulateResponseFromPasswordStore(&form_manager, result);
1279 EXPECT_CALL(*client_with_store.mock_driver()->mock_autofill_manager(),
1280 UploadPasswordForm(_,
1281 autofill::ACCOUNT_CREATION_PASSWORD)).Times(1);
1282 form_manager.ProvisionallySave(
1284 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1285 form_manager.Save();
1288 TEST_F(PasswordFormManagerTest, CorrectlySavePasswordWithoutUsernameFields) {
1289 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1290 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare()));
1292 TestPasswordManagerClient client_with_store(password_store.get());
1293 TestPasswordManager password_manager(&client_with_store);
1294 EXPECT_CALL(*client_with_store.mock_driver(),
1295 AllowPasswordGenerationForForm(_)).Times(2);
1296 EXPECT_CALL(*client_with_store.mock_driver(), IsOffTheRecord())
1297 .WillRepeatedly(Return(false));
1299 PasswordForm form(*observed_form());
1300 form.username_element.clear();
1301 form.password_value = ASCIIToUTF16("password");
1302 form.preferred = true;
1304 PasswordFormManager storing_manager(&password_manager,
1306 client_with_store.GetDriver(),
1309 storing_manager.FetchMatchingLoginsFromPasswordStore(
1310 PasswordStore::ALLOW_PROMPT);
1311 RunAllPendingTasks();
1313 storing_manager.ProvisionallySave(
1314 form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1316 EXPECT_TRUE(storing_manager.IsNewLogin());
1317 storing_manager.Save();
1318 RunAllPendingTasks();
1320 PasswordFormManager retrieving_manager(&password_manager,
1322 client_with_store.GetDriver(),
1326 retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1327 PasswordStore::ALLOW_PROMPT);
1328 RunAllPendingTasks();
1330 // Make sure that the preferred match is updated appropriately.
1331 EXPECT_EQ(ASCIIToUTF16("password"),
1332 retrieving_manager.preferred_match()->password_value);
1333 password_store->Shutdown();
1336 } // namespace password_manager