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 void PromptUserToSavePassword(
71 scoped_ptr<PasswordFormManager> form_to_save) OVERRIDE {}
72 virtual PrefService* GetPrefs() OVERRIDE { return &prefs_; }
73 virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_; }
74 virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
75 virtual void AuthenticateAutofillAndFillForm(
76 scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
77 driver_.FillPasswordForm(*fill_data.get());
80 void SetFormToFilter(const autofill::PasswordForm& form) {
81 form_to_filter_ = form;
84 MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
87 autofill::PasswordForm form_to_filter_;
89 TestingPrefServiceSimple prefs_;
90 PasswordStore* password_store_;
91 testing::NiceMock<MockPasswordManagerDriver> driver_;
94 class TestPasswordManager : public PasswordManager {
96 explicit TestPasswordManager(PasswordManagerClient* client)
97 : PasswordManager(client) {}
99 virtual void Autofill(const autofill::PasswordForm& form_for_autofill,
100 const autofill::PasswordFormMap& best_matches,
101 const autofill::PasswordForm& preferred_match,
102 bool wait_for_username) const OVERRIDE {
103 best_matches_ = best_matches;
106 const autofill::PasswordFormMap& GetLatestBestMatches() {
107 return best_matches_;
111 // Marked mutable to get around constness of Autofill().
112 mutable autofill::PasswordFormMap best_matches_;
115 class MockPasswordFormManager : public PasswordFormManager {
117 MockPasswordFormManager(PasswordManager* manager,
118 PasswordManagerClient* client,
119 PasswordManagerDriver* driver,
120 const autofill::PasswordForm& observed_form,
122 : PasswordFormManager(manager, client, driver, observed_form, ssl_valid)
125 MOCK_METHOD2(UploadPasswordForm, void(const autofill::FormData&,
126 const autofill::ServerFieldType&));
131 class PasswordFormManagerTest : public testing::Test {
133 PasswordFormManagerTest() : client_(NULL /*password_store*/) {}
135 // Types of possible outcomes of simulated matching, see
136 // SimulateMatchingPhase.
137 enum ResultOfSimulatedMatching { RESULT_MATCH_FOUND, RESULT_NO_MATCH };
139 virtual void SetUp() {
140 observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
141 observed_form_.action = GURL("http://accounts.google.com/a/Login");
142 observed_form_.username_element = ASCIIToUTF16("Email");
143 observed_form_.password_element = ASCIIToUTF16("Passwd");
144 observed_form_.submit_element = ASCIIToUTF16("signIn");
145 observed_form_.signon_realm = "http://accounts.google.com";
147 saved_match_ = observed_form_;
148 saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
149 saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
150 saved_match_.preferred = true;
151 saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
152 saved_match_.password_value = ASCIIToUTF16("test1");
153 saved_match_.other_possible_usernames.push_back(
154 ASCIIToUTF16("test2@gmail.com"));
157 virtual void TearDown() {
159 mock_store_->Shutdown();
162 void InitializeMockStore() {
163 if (!mock_store_.get()) {
164 mock_store_ = new testing::NiceMock<MockPasswordStore>();
165 ASSERT_TRUE(mock_store_.get());
169 MockPasswordStore* mock_store() const { return mock_store_.get(); }
171 PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
172 return &p->pending_credentials_;
175 void SimulateMatchingPhase(PasswordFormManager* p,
176 ResultOfSimulatedMatching result) {
177 // Roll up the state to mock out the matching phase.
178 p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
179 if (result == RESULT_NO_MATCH)
182 PasswordForm* match = new PasswordForm(saved_match_);
183 // Heap-allocated form is owned by p.
184 p->best_matches_[match->username_value] = match;
185 p->preferred_match_ = match;
188 void SimulateFetchMatchingLoginsFromPasswordStore(
189 PasswordFormManager* manager) {
190 // Just need to update the internal states.
191 manager->state_ = PasswordFormManager::MATCHING_PHASE;
194 void SimulateResponseFromPasswordStore(
195 PasswordFormManager* manager,
196 const std::vector<PasswordForm*>& result) {
197 // Simply call the callback method when request done. This will transfer
198 // the ownership of the objects in |result| to the |manager|.
199 manager->OnGetPasswordStoreResults(result);
202 void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
203 p->SanitizePossibleUsernames(form);
206 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
207 return p->ShouldIgnoreResult(*form);
210 PasswordForm* observed_form() { return &observed_form_; }
211 PasswordForm* saved_match() { return &saved_match_; }
212 PasswordForm* CreateSavedMatch(bool blacklisted) {
213 // Owned by the caller of this method.
214 PasswordForm* match = new PasswordForm(saved_match_);
215 match->blacklisted_by_user = blacklisted;
219 TestPasswordManagerClient* client() { return &client_; }
222 PasswordForm observed_form_;
223 PasswordForm saved_match_;
224 scoped_refptr<testing::NiceMock<MockPasswordStore> > mock_store_;
225 TestPasswordManagerClient client_;
228 TEST_F(PasswordFormManagerTest, TestNewLogin) {
229 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
230 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
232 // User submits credentials for the observed form.
233 PasswordForm credentials = *observed_form();
234 credentials.username_value = saved_match()->username_value;
235 credentials.password_value = saved_match()->password_value;
236 credentials.preferred = true;
237 manager.ProvisionallySave(
238 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
240 // Successful login. The PasswordManager would instruct PasswordFormManager
241 // to save, which should know this is a new login.
242 EXPECT_TRUE(manager.IsNewLogin());
243 // Make sure the credentials that would be submitted on successful login
244 // are going to match the stored entry in the db.
245 EXPECT_EQ(observed_form()->origin.spec(),
246 GetPendingCredentials(&manager)->origin.spec());
247 EXPECT_EQ(observed_form()->signon_realm,
248 GetPendingCredentials(&manager)->signon_realm);
249 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
250 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
251 EXPECT_EQ(saved_match()->password_value,
252 GetPendingCredentials(&manager)->password_value);
253 EXPECT_EQ(saved_match()->username_value,
254 GetPendingCredentials(&manager)->username_value);
255 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
256 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
258 // Now, suppose the user re-visits the site and wants to save an additional
259 // login for the site with a new username. In this case, the matching phase
260 // will yield the previously saved login.
261 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
262 // Set up the new login.
263 base::string16 new_user = ASCIIToUTF16("newuser");
264 base::string16 new_pass = ASCIIToUTF16("newpass");
265 credentials.username_value = new_user;
266 credentials.password_value = new_pass;
267 manager.ProvisionallySave(
268 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
270 // Again, the PasswordFormManager should know this is still a new login.
271 EXPECT_TRUE(manager.IsNewLogin());
272 // And make sure everything squares up again.
273 EXPECT_EQ(observed_form()->origin.spec(),
274 GetPendingCredentials(&manager)->origin.spec());
275 EXPECT_EQ(observed_form()->signon_realm,
276 GetPendingCredentials(&manager)->signon_realm);
277 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
278 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
279 EXPECT_EQ(new_user, GetPendingCredentials(&manager)->username_value);
280 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
281 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
284 // If PSL-matched credentials had been suggested, but the user has overwritten
285 // the password, the provisionally saved credentials should no longer be
286 // considered as PSL-matched, so that the exception for not prompting before
287 // saving PSL-matched credentials should no longer apply.
288 TEST_F(PasswordFormManagerTest,
289 OverriddenPSLMatchedCredentialsNotMarkedAsPSLMatched) {
290 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
292 // The suggestion needs to be PSL-matched.
293 saved_match()->original_signon_realm = "www.example.org";
294 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
296 // User modifies the suggested password and submits the form.
297 PasswordForm credentials(*observed_form());
298 credentials.username_value = saved_match()->username_value;
299 credentials.password_value =
300 saved_match()->password_value + ASCIIToUTF16("modify");
301 manager.ProvisionallySave(
302 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
304 EXPECT_TRUE(manager.IsNewLogin());
305 EXPECT_FALSE(manager.IsPendingCredentialsPublicSuffixMatch());
308 TEST_F(PasswordFormManagerTest, TestNewLoginFromNewPasswordElement) {
309 // Add a new password field to the test form. The PasswordFormManager should
310 // save the password from this field, instead of the current password field.
311 observed_form()->new_password_element = ASCIIToUTF16("NewPasswd");
313 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
314 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
316 // User enters current and new credentials to the observed form.
317 PasswordForm credentials(*observed_form());
318 credentials.username_value = saved_match()->username_value;
319 credentials.password_value = saved_match()->password_value;
320 credentials.new_password_value = ASCIIToUTF16("newpassword");
321 credentials.preferred = true;
322 manager.ProvisionallySave(
323 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
325 // Successful login. The PasswordManager would instruct PasswordFormManager
326 // to save, which should know this is a new login.
327 EXPECT_TRUE(manager.IsNewLogin());
328 EXPECT_EQ(credentials.origin, GetPendingCredentials(&manager)->origin);
329 EXPECT_EQ(credentials.signon_realm,
330 GetPendingCredentials(&manager)->signon_realm);
331 EXPECT_EQ(credentials.action, GetPendingCredentials(&manager)->action);
332 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
333 EXPECT_EQ(credentials.username_value,
334 GetPendingCredentials(&manager)->username_value);
336 // By this point, the PasswordFormManager should have promoted the new
337 // password value to be the current password, and should have wiped the
338 // password element names: they are likely going to be different on a login
339 // form, so it is not worth remembering them.
340 EXPECT_EQ(credentials.new_password_value,
341 GetPendingCredentials(&manager)->password_value);
342 EXPECT_TRUE(GetPendingCredentials(&manager)->password_element.empty());
343 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
344 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
347 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
348 // Create a PasswordFormManager with observed_form, as if we just
349 // saw this form and need to find matching logins.
350 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
352 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
354 // User submits credentials for the observed form using a username previously
355 // stored, but a new password. Note that the observed form may have different
356 // origin URL (as it does in this case) than the saved_match, but we want to
357 // make sure the updated password is reflected in saved_match, because that is
358 // what we autofilled.
359 base::string16 new_pass = ASCIIToUTF16("test2");
360 PasswordForm credentials = *observed_form();
361 credentials.username_value = saved_match()->username_value;
362 credentials.password_value = new_pass;
363 credentials.preferred = true;
364 manager.ProvisionallySave(
365 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
367 // Successful login. The PasswordManager would instruct PasswordFormManager
368 // to save, and since this is an update, it should know not to save as a new
370 EXPECT_FALSE(manager.IsNewLogin());
372 // Make sure the credentials that would be submitted on successful login
373 // are going to match the stored entry in the db. (This verifies correct
374 // behaviour for bug 1074420).
375 EXPECT_EQ(GetPendingCredentials(&manager)->origin.spec(),
376 saved_match()->origin.spec());
377 EXPECT_EQ(GetPendingCredentials(&manager)->signon_realm,
378 saved_match()->signon_realm);
379 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
380 EXPECT_EQ(new_pass, GetPendingCredentials(&manager)->password_value);
383 TEST_F(PasswordFormManagerTest, TestUpdatePasswordFromNewPasswordElement) {
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 // Given that |observed_form| was most likely a change password form, it
389 // should not serve as a source for updating meta-information stored with the
390 // old credentials, such as element names, as they are likely going to be
391 // different between change password and login forms. To test this in depth,
392 // forcibly wipe |submit_element|, which should normally trigger updating this
393 // field from |observed_form| in the UpdateLogin() step as a special case. We
394 // will verify in the end that this did not happen.
395 saved_match()->submit_element.clear();
397 InitializeMockStore();
398 TestPasswordManagerClient client_with_store(mock_store());
399 PasswordFormManager manager(NULL,
401 client_with_store.GetDriver(),
404 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
405 .WillRepeatedly(Return(false));
406 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
408 // User submits current and new credentials to the observed form.
409 PasswordForm credentials(*observed_form());
410 credentials.username_value = saved_match()->username_value;
411 credentials.password_value = saved_match()->password_value;
412 credentials.new_password_value = ASCIIToUTF16("test2");
413 credentials.preferred = true;
414 manager.ProvisionallySave(
415 credentials, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
417 // Successful login. The PasswordManager would instruct PasswordFormManager
418 // to save, and since this is an update, it should know not to save as a new
420 EXPECT_FALSE(manager.IsNewLogin());
422 // By now, the PasswordFormManager should have promoted the new password value
423 // already to be the current password, and should no longer maintain any info
424 // about the new password.
425 EXPECT_EQ(credentials.new_password_value,
426 GetPendingCredentials(&manager)->password_value);
427 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_element.empty());
428 EXPECT_TRUE(GetPendingCredentials(&manager)->new_password_value.empty());
430 // Trigger saving to exercise some special case handling in UpdateLogin().
431 PasswordForm new_credentials;
432 EXPECT_CALL(*mock_store(), UpdateLogin(_))
433 .WillOnce(testing::SaveArg<0>(&new_credentials));
435 Mock::VerifyAndClearExpectations(mock_store());
437 // No meta-information should be updated, only the password.
438 EXPECT_EQ(credentials.new_password_value, new_credentials.password_value);
439 EXPECT_EQ(saved_match()->username_element, new_credentials.username_element);
440 EXPECT_EQ(saved_match()->password_element, new_credentials.password_element);
441 EXPECT_EQ(saved_match()->submit_element, new_credentials.submit_element);
444 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
445 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
447 // Make sure we don't match a PasswordForm if it was originally saved on
448 // an SSL-valid page and we are now on a page with invalid certificate.
449 saved_match()->ssl_valid = true;
450 EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
452 saved_match()->ssl_valid = false;
453 // Different paths for action / origin are okay.
454 saved_match()->action = GURL("http://www.google.com/b/Login");
455 saved_match()->origin = GURL("http://www.google.com/foo");
456 EXPECT_FALSE(IgnoredResult(&manager, saved_match()));
458 // Results should be ignored if the client requests it.
459 client()->SetFormToFilter(*saved_match());
460 EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
463 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
464 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
466 saved_match()->action = GURL();
467 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
468 // User logs in with the autofilled username / password from saved_match.
469 PasswordForm login = *observed_form();
470 login.username_value = saved_match()->username_value;
471 login.password_value = saved_match()->password_value;
472 manager.ProvisionallySave(
473 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
474 EXPECT_FALSE(manager.IsNewLogin());
475 // We bless our saved PasswordForm entry with the action URL of the
477 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
480 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
481 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
483 SimulateMatchingPhase(&manager, RESULT_MATCH_FOUND);
484 // User logs in with the autofilled username / password from saved_match.
485 PasswordForm login = *observed_form();
486 login.username_value = saved_match()->username_value;
487 login.password_value = saved_match()->password_value;
489 manager.ProvisionallySave(
490 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
491 EXPECT_FALSE(manager.IsNewLogin());
492 // The observed action URL is different from the previously saved one, and
493 // is the same as the one that would be submitted on successful login.
494 EXPECT_NE(observed_form()->action, saved_match()->action);
495 EXPECT_EQ(observed_form()->action, GetPendingCredentials(&manager)->action);
498 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
499 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
501 SimulateMatchingPhase(&manager, RESULT_NO_MATCH);
502 PasswordForm login(*observed_form());
503 // The submitted action URL is different from the one observed on page load.
504 GURL new_action = GURL("http://www.google.com/new_action");
505 login.action = new_action;
507 manager.ProvisionallySave(
508 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
509 EXPECT_TRUE(manager.IsNewLogin());
510 // Check that the provisionally saved action URL is the same as the submitted
511 // action URL, not the one observed on page load.
512 EXPECT_EQ(new_action, GetPendingCredentials(&manager)->action);
515 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
516 // Need a MessageLoop for callbacks.
517 base::MessageLoop message_loop;
518 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
519 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
521 TestPasswordManagerClient client_with_store(password_store.get());
522 TestPasswordManager password_manager(&client_with_store);
523 PasswordFormManager manager(&password_manager,
525 client_with_store.GetDriver(),
528 EXPECT_CALL(*client_with_store.GetMockDriver(),
529 AllowPasswordGenerationForForm(_)).Times(1);
530 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
531 .WillRepeatedly(Return(false));
533 password_store->AddLogin(*saved_match());
534 manager.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
535 RunAllPendingTasks();
537 // The saved match has the right username already.
538 PasswordForm login(*observed_form());
539 login.username_value = saved_match()->username_value;
540 login.password_value = saved_match()->password_value;
541 login.preferred = true;
542 manager.ProvisionallySave(
543 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
545 EXPECT_FALSE(manager.IsNewLogin());
547 RunAllPendingTasks();
549 // Should be only one password stored, and should not have
550 // |other_possible_usernames| set anymore.
551 TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
552 EXPECT_EQ(1U, passwords.size());
553 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
554 EXPECT_EQ(saved_match()->username_value,
555 passwords[saved_match()->signon_realm][0].username_value);
557 passwords[saved_match()->signon_realm][0]
558 .other_possible_usernames.size());
560 // This time use an alternate username
561 PasswordFormManager manager_alt(&password_manager,
563 client_with_store.GetDriver(),
566 EXPECT_CALL(*client_with_store.GetMockDriver(),
567 AllowPasswordGenerationForForm(_)).Times(1);
568 password_store->Clear();
569 password_store->AddLogin(*saved_match());
570 manager_alt.FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
571 RunAllPendingTasks();
573 base::string16 new_username = saved_match()->other_possible_usernames[0];
574 login.username_value = new_username;
575 manager_alt.ProvisionallySave(
576 login, PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
578 EXPECT_FALSE(manager_alt.IsNewLogin());
580 RunAllPendingTasks();
582 // |other_possible_usernames| should also be empty, but username_value should
583 // be changed to match |new_username|
584 passwords = password_store->stored_passwords();
585 EXPECT_EQ(1U, passwords.size());
586 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
587 EXPECT_EQ(new_username,
588 passwords[saved_match()->signon_realm][0].username_value);
590 passwords[saved_match()->signon_realm][0]
591 .other_possible_usernames.size());
592 password_store->Shutdown();
595 TEST_F(PasswordFormManagerTest, TestValidForms) {
596 // User submits credentials for the observed form.
597 PasswordForm credentials = *observed_form();
598 credentials.scheme = PasswordForm::SCHEME_HTML;
599 credentials.username_value = saved_match()->username_value;
600 credentials.password_value = saved_match()->password_value;
602 // An alternate version of the form that also has a new_password_element.
603 PasswordForm new_credentials(*observed_form());
604 new_credentials.new_password_element = ASCIIToUTF16("NewPasswd");
605 new_credentials.new_password_value = ASCIIToUTF16("test1new");
607 // Form with both username_element and password_element.
608 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
609 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
610 EXPECT_TRUE(manager1.HasValidPasswordForm());
612 // Form with username_element, password_element, and new_password_element.
613 PasswordFormManager manager2(NULL, NULL, NULL, new_credentials, false);
614 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
615 EXPECT_TRUE(manager2.HasValidPasswordForm());
617 // Form with username_element and only new_password_element.
618 new_credentials.password_element.clear();
619 PasswordFormManager manager3(NULL, NULL, NULL, new_credentials, false);
620 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
621 EXPECT_TRUE(manager3.HasValidPasswordForm());
623 // Form without a username_element but with a password_element.
624 credentials.username_element.clear();
625 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
626 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
627 EXPECT_FALSE(manager4.HasValidPasswordForm());
629 // Form without a username_element but with a new_password_element.
630 new_credentials.username_element.clear();
631 PasswordFormManager manager5(NULL, NULL, NULL, new_credentials, false);
632 SimulateMatchingPhase(&manager5, RESULT_NO_MATCH);
633 EXPECT_FALSE(manager5.HasValidPasswordForm());
635 // Form without a password_element but with a username_element.
636 credentials.username_element = saved_match()->username_element;
637 credentials.password_element.clear();
638 PasswordFormManager manager6(NULL, NULL, NULL, credentials, false);
639 SimulateMatchingPhase(&manager6, RESULT_NO_MATCH);
640 EXPECT_FALSE(manager6.HasValidPasswordForm());
642 // Form with neither a password_element nor a username_element.
643 credentials.username_element.clear();
644 credentials.password_element.clear();
645 PasswordFormManager manager7(NULL, NULL, NULL, credentials, false);
646 SimulateMatchingPhase(&manager7, RESULT_NO_MATCH);
647 EXPECT_FALSE(manager7.HasValidPasswordForm());
650 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
651 // User submits credentials for the observed form.
652 PasswordForm credentials = *observed_form();
653 credentials.scheme = PasswordForm::SCHEME_BASIC;
654 credentials.username_value = saved_match()->username_value;
655 credentials.password_value = saved_match()->password_value;
657 // Form with both username_element and password_element.
658 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
659 SimulateMatchingPhase(&manager1, RESULT_NO_MATCH);
660 EXPECT_TRUE(manager1.HasValidPasswordForm());
662 // Form without a username_element but with a password_element.
663 credentials.username_element.clear();
664 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
665 SimulateMatchingPhase(&manager2, RESULT_NO_MATCH);
666 EXPECT_TRUE(manager2.HasValidPasswordForm());
668 // Form without a password_element but with a username_element.
669 credentials.username_element = saved_match()->username_element;
670 credentials.password_element.clear();
671 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
672 SimulateMatchingPhase(&manager3, RESULT_NO_MATCH);
673 EXPECT_TRUE(manager3.HasValidPasswordForm());
675 // Form with neither a password_element nor a username_element.
676 credentials.username_element.clear();
677 credentials.password_element.clear();
678 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
679 SimulateMatchingPhase(&manager4, RESULT_NO_MATCH);
680 EXPECT_TRUE(manager4.HasValidPasswordForm());
683 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
684 base::MessageLoop message_loop;
686 TestPasswordManager password_manager(client());
687 PasswordFormManager manager_no_creds(&password_manager,
689 client()->GetDriver(),
693 // First time sign-up attempt. Password store does not contain matching
694 // credentials. AllowPasswordGenerationForForm should be called to send the
695 // "not blacklisted" message.
696 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
698 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_creds);
699 std::vector<PasswordForm*> result;
700 SimulateResponseFromPasswordStore(&manager_no_creds, result);
701 Mock::VerifyAndClearExpectations(client()->GetMockDriver());
703 // Signing up on a previously visited site. Credentials are found in the
704 // password store, and are not blacklisted. AllowPasswordGenerationForForm
705 // should be called to send the "not blacklisted" message.
706 PasswordFormManager manager_creds(&password_manager,
708 client()->GetDriver(),
711 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
713 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
714 .WillRepeatedly(Return(false));
715 SimulateFetchMatchingLoginsFromPasswordStore(&manager_creds);
716 // We need add heap allocated objects to result.
717 result.push_back(CreateSavedMatch(false));
718 SimulateResponseFromPasswordStore(&manager_creds, result);
719 Mock::VerifyAndClearExpectations(client()->GetMockDriver());
721 // Signing up on a previously visited site. Credentials are found in the
722 // password store, but they are blacklisted. AllowPasswordGenerationForForm
723 // should not be called and no "not blacklisted" message sent.
724 PasswordFormManager manager_blacklisted(&password_manager,
726 client()->GetDriver(),
729 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
731 SimulateFetchMatchingLoginsFromPasswordStore(&manager_blacklisted);
733 result.push_back(CreateSavedMatch(true));
734 SimulateResponseFromPasswordStore(&manager_blacklisted, result);
735 Mock::VerifyAndClearExpectations(client()->GetMockDriver());
738 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
739 base::MessageLoop message_loop;
741 // Simulate having two matches for this origin, one of which was from a form
742 // with different HTML tags for elements. Because of scoring differences,
743 // only the first form will be sent to Autofill().
744 TestPasswordManager password_manager(client());
745 PasswordFormManager manager_match(&password_manager,
747 client()->GetDriver(),
750 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
752 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
753 .WillRepeatedly(Return(false));
755 std::vector<PasswordForm*> results;
756 results.push_back(CreateSavedMatch(false));
757 results.push_back(CreateSavedMatch(false));
758 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
759 results[1]->password_element = ASCIIToUTF16("signup_password");
760 results[1]->username_element = ASCIIToUTF16("signup_username");
761 SimulateFetchMatchingLoginsFromPasswordStore(&manager_match);
762 SimulateResponseFromPasswordStore(&manager_match, results);
763 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
766 // Same thing, except this time the credentials that don't match quite as
767 // well are generated. They should now be sent to Autofill().
768 PasswordFormManager manager_no_match(&password_manager,
770 client()->GetDriver(),
773 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_))
776 results.push_back(CreateSavedMatch(false));
777 results.push_back(CreateSavedMatch(false));
778 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
779 results[1]->password_element = ASCIIToUTF16("signup_password");
780 results[1]->username_element = ASCIIToUTF16("signup_username");
781 results[1]->type = PasswordForm::TYPE_GENERATED;
782 SimulateFetchMatchingLoginsFromPasswordStore(&manager_no_match);
783 SimulateResponseFromPasswordStore(&manager_no_match, results);
784 EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
787 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
788 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
789 PasswordForm credentials(*observed_form());
790 credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
791 credentials.other_possible_usernames.push_back(
792 ASCIIToUTF16("378282246310005"));
793 credentials.other_possible_usernames.push_back(
794 ASCIIToUTF16("other username"));
795 credentials.username_value = ASCIIToUTF16("test@gmail.com");
797 SanitizePossibleUsernames(&manager, &credentials);
799 // Possible credit card number and SSN are stripped.
800 std::vector<base::string16> expected;
801 expected.push_back(ASCIIToUTF16("other username"));
802 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
804 credentials.other_possible_usernames.clear();
805 credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
806 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
807 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
808 credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
809 credentials.other_possible_usernames.push_back(
810 ASCIIToUTF16("test@gmail.com"));
812 SanitizePossibleUsernames(&manager, &credentials);
814 // SSN, duplicate in |other_possible_usernames| and duplicate of
815 // |username_value| all removed.
817 expected.push_back(ASCIIToUTF16("duplicate"));
818 expected.push_back(ASCIIToUTF16("random"));
819 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
822 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
823 InitializeMockStore();
825 // We've found this form on a website:
826 PasswordForm encountered_form;
827 encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
828 encountered_form.signon_realm = "http://accounts.google.com/";
829 encountered_form.action = GURL("http://accounts.google.com/Login");
830 encountered_form.username_element = ASCIIToUTF16("Email");
831 encountered_form.password_element = ASCIIToUTF16("Passwd");
832 encountered_form.submit_element = ASCIIToUTF16("signIn");
834 TestPasswordManagerClient client_with_store(mock_store());
835 EXPECT_CALL(*(client_with_store.GetMockDriver()), IsOffTheRecord())
836 .WillRepeatedly(Return(false));
837 EXPECT_CALL(*(client_with_store.GetMockDriver()),
838 AllowPasswordGenerationForForm(_));
840 TestPasswordManager manager(&client_with_store);
841 PasswordFormManager form_manager(&manager,
843 client_with_store.GetMockDriver(),
847 const PasswordStore::AuthorizationPromptPolicy auth_policy =
848 PasswordStore::DISALLOW_PROMPT;
849 EXPECT_CALL(*mock_store(),
850 GetLogins(encountered_form, auth_policy, &form_manager));
851 form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
853 // Password store only has these incomplete credentials.
854 PasswordForm* incomplete_form = new PasswordForm();
855 incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
856 incomplete_form->signon_realm = "http://accounts.google.com/";
857 incomplete_form->password_value = ASCIIToUTF16("my_password");
858 incomplete_form->username_value = ASCIIToUTF16("my_username");
859 incomplete_form->preferred = true;
860 incomplete_form->ssl_valid = false;
861 incomplete_form->scheme = PasswordForm::SCHEME_HTML;
863 // We expect to see this form eventually sent to the Password store. It
864 // has password/username values from the store and 'username_element',
865 // 'password_element', 'submit_element' and 'action' fields copied from
866 // the encountered form.
867 PasswordForm complete_form(*incomplete_form);
868 complete_form.action = encountered_form.action;
869 complete_form.password_element = encountered_form.password_element;
870 complete_form.username_element = encountered_form.username_element;
871 complete_form.submit_element = encountered_form.submit_element;
873 PasswordForm obsolete_form(*incomplete_form);
874 obsolete_form.action = encountered_form.action;
876 // Feed the incomplete credentials to the manager.
877 std::vector<PasswordForm*> results;
878 results.push_back(incomplete_form); // Takes ownership.
879 form_manager.OnRequestDone(results);
881 form_manager.ProvisionallySave(
882 complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
883 // By now that form has been used once.
884 complete_form.times_used = 1;
885 obsolete_form.times_used = 1;
887 // Check that PasswordStore receives an update request with the complete form.
888 EXPECT_CALL(*mock_store(), RemoveLogin(obsolete_form));
889 EXPECT_CALL(*mock_store(), AddLogin(complete_form));
893 TEST_F(PasswordFormManagerTest, TestScoringPublicSuffixMatch) {
894 base::MessageLoop message_loop;
896 EXPECT_CALL(*(client()->GetMockDriver()), IsOffTheRecord())
897 .WillRepeatedly(Return(false));
898 EXPECT_CALL(*(client()->GetMockDriver()), AllowPasswordGenerationForForm(_));
900 TestPasswordManager password_manager(client());
901 PasswordFormManager manager(&password_manager,
903 client()->GetMockDriver(),
907 // Simulate having two matches for this form, first comes from different
908 // signon realm, but reports the same origin and action as matched form.
909 // Second candidate has the same signon realm as the form, but has a different
910 // origin and action. Public suffix match is the most important criterion so
911 // the second candidate should be selected.
912 std::vector<PasswordForm*> results;
913 results.push_back(CreateSavedMatch(false));
914 results.push_back(CreateSavedMatch(false));
915 results[0]->original_signon_realm = "http://accounts2.google.com";
916 results[1]->origin = GURL("http://accounts.google.com/a/ServiceLoginAuth2");
917 results[1]->action = GURL("http://accounts.google.com/a/ServiceLogin2");
918 SimulateFetchMatchingLoginsFromPasswordStore(&manager);
919 SimulateResponseFromPasswordStore(&manager, results);
920 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
921 EXPECT_EQ("", password_manager.GetLatestBestMatches().begin()
922 ->second->original_signon_realm);
925 TEST_F(PasswordFormManagerTest, InvalidActionURLsDoNotMatch) {
926 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
928 PasswordForm invalid_action_form(*observed_form());
929 invalid_action_form.action = GURL("http://");
930 ASSERT_FALSE(invalid_action_form.action.is_valid());
931 ASSERT_FALSE(invalid_action_form.action.is_empty());
932 // Non-empty invalid action URLs should not match other actions.
933 // First when the compared form has an invalid URL:
935 manager.DoesManage(invalid_action_form) &
936 PasswordFormManager::RESULT_ACTION_MATCH);
937 // Then when the observed form has an invalid URL:
938 PasswordForm valid_action_form(*observed_form());
939 PasswordFormManager invalid_manager(
940 NULL, client(), NULL, invalid_action_form, false);
942 invalid_manager.DoesManage(valid_action_form) &
943 PasswordFormManager::RESULT_ACTION_MATCH);
946 TEST_F(PasswordFormManagerTest, EmptyActionURLsDoNotMatchNonEmpty) {
947 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
949 PasswordForm empty_action_form(*observed_form());
950 empty_action_form.action = GURL();
951 ASSERT_FALSE(empty_action_form.action.is_valid());
952 ASSERT_TRUE(empty_action_form.action.is_empty());
953 // First when the compared form has an empty URL:
955 manager.DoesManage(empty_action_form) &
956 PasswordFormManager::RESULT_ACTION_MATCH);
957 // Then when the observed form has an empty URL:
958 PasswordForm valid_action_form(*observed_form());
959 PasswordFormManager empty_action_manager(
960 NULL, client(), NULL, empty_action_form, false);
962 empty_action_manager.DoesManage(valid_action_form) &
963 PasswordFormManager::RESULT_ACTION_MATCH);
966 TEST_F(PasswordFormManagerTest, NonHTMLFormsDoNotMatchHTMLForms) {
967 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
969 ASSERT_EQ(PasswordForm::SCHEME_HTML, observed_form()->scheme);
970 PasswordForm non_html_form(*observed_form());
971 non_html_form.scheme = PasswordForm::SCHEME_DIGEST;
973 manager.DoesManage(non_html_form) &
974 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
976 // The other way round: observing a non-HTML form, don't match a HTML form.
977 PasswordForm html_form(*observed_form());
978 PasswordFormManager non_html_manager(
979 NULL, client(), NULL, non_html_form, false);
981 non_html_manager.DoesManage(html_form) &
982 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
985 TEST_F(PasswordFormManagerTest, OriginCheck_HostsMatchExactly) {
986 // Host part of origins must match exactly, not just by prefix.
987 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
989 PasswordForm form_longer_host(*observed_form());
990 form_longer_host.origin = GURL("http://accounts.google.com.au/a/LoginAuth");
991 // Check that accounts.google.com does not match accounts.google.com.au.
993 manager.DoesManage(form_longer_host) &
994 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
997 TEST_F(PasswordFormManagerTest, OriginCheck_MoreSecureSchemePathsMatchPrefix) {
998 // If the URL scheme of the observed form is HTTP, and the compared form is
999 // HTTPS, then the compared form can extend the path.
1000 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1002 PasswordForm form_longer_path(*observed_form());
1003 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1005 manager.DoesManage(form_longer_path) &
1006 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1009 TEST_F(PasswordFormManagerTest,
1010 OriginCheck_NotMoreSecureSchemePathsMatchExactly) {
1011 // If the origin URL scheme of the compared form is not more secure than that
1012 // of the observed form, then the paths must match exactly.
1013 PasswordFormManager manager(NULL, client(), NULL, *observed_form(), false);
1015 PasswordForm form_longer_path(*observed_form());
1016 form_longer_path.origin = GURL("http://accounts.google.com/a/LoginAuth/sec");
1017 // Check that /a/LoginAuth does not match /a/LoginAuth/more.
1019 manager.DoesManage(form_longer_path) &
1020 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1022 PasswordForm secure_observed_form(*observed_form());
1023 secure_observed_form.origin = GURL("https://accounts.google.com/a/LoginAuth");
1024 PasswordFormManager secure_manager(
1025 NULL, client(), NULL, secure_observed_form, true);
1026 // Also for HTTPS in the observed form, and HTTP in the compared form, an
1027 // exact path match is expected.
1029 secure_manager.DoesManage(form_longer_path) &
1030 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1031 // Not even upgrade to HTTPS in the compared form should help.
1032 form_longer_path.origin = GURL("https://accounts.google.com/a/LoginAuth/sec");
1034 secure_manager.DoesManage(form_longer_path) &
1035 PasswordFormManager::RESULT_MANDATORY_ATTRIBUTES_MATCH);
1038 TEST_F(PasswordFormManagerTest, CorrectlyUpdatePasswordsWithSameUsername) {
1039 // Need a MessageLoop for callbacks.
1040 base::MessageLoop message_loop;
1041 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
1042 CHECK(password_store->Init(syncer::SyncableService::StartSyncFlare(), ""));
1044 TestPasswordManagerClient client_with_store(password_store.get());
1045 TestPasswordManager password_manager(&client_with_store);
1046 EXPECT_CALL(*client_with_store.GetMockDriver(),
1047 AllowPasswordGenerationForForm(_)).Times(2);
1048 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1049 .WillRepeatedly(Return(false));
1051 // Add two credentials with the same username. Both should score the same
1052 // and be seen as candidates to autofill.
1053 PasswordForm first(*saved_match());
1054 first.action = observed_form()->action;
1055 first.password_value = ASCIIToUTF16("first");
1056 password_store->AddLogin(first);
1058 PasswordForm second(first);
1059 second.origin = GURL("http://accounts.google.com/a/AddLogin");
1060 second.password_value = ASCIIToUTF16("second");
1061 second.preferred = false;
1062 password_store->AddLogin(second);
1064 PasswordFormManager storing_manager(&password_manager,
1066 client_with_store.GetDriver(),
1069 storing_manager.FetchMatchingLoginsFromPasswordStore(
1070 PasswordStore::ALLOW_PROMPT);
1071 RunAllPendingTasks();
1073 // We always take the last credential with a particular username, regardless
1074 // of which ones are labeled preferred.
1075 EXPECT_EQ(ASCIIToUTF16("second"),
1076 storing_manager.preferred_match()->password_value);
1078 PasswordForm login(*observed_form());
1079 login.username_value = saved_match()->username_value;
1080 login.password_value = ASCIIToUTF16("third");
1081 login.preferred = true;
1082 storing_manager.ProvisionallySave(
1083 login, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1085 EXPECT_FALSE(storing_manager.IsNewLogin());
1086 storing_manager.Save();
1087 RunAllPendingTasks();
1089 PasswordFormManager retrieving_manager(&password_manager,
1091 client_with_store.GetDriver(),
1095 retrieving_manager.FetchMatchingLoginsFromPasswordStore(
1096 PasswordStore::ALLOW_PROMPT);
1097 RunAllPendingTasks();
1099 // Make sure that the preferred match is updated appropriately.
1100 EXPECT_EQ(ASCIIToUTF16("third"),
1101 retrieving_manager.preferred_match()->password_value);
1102 password_store->Shutdown();
1105 TEST_F(PasswordFormManagerTest, UploadFormData_NewPassword) {
1106 InitializeMockStore();
1107 TestPasswordManagerClient client_with_store(mock_store());
1108 TestPasswordManager password_manager(&client_with_store);
1109 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1110 .WillRepeatedly(Return(false));
1112 PasswordForm form(*observed_form());
1114 autofill::FormFieldData field;
1115 field.label = ASCIIToUTF16("full_name");
1116 field.name = ASCIIToUTF16("full_name");
1117 field.form_control_type = "text";
1118 form.form_data.fields.push_back(field);
1120 field.label = ASCIIToUTF16("Email");
1121 field.name = ASCIIToUTF16("Email");
1122 field.form_control_type = "text";
1123 form.form_data.fields.push_back(field);
1125 field.label = ASCIIToUTF16("password");
1126 field.name = ASCIIToUTF16("password");
1127 field.form_control_type = "password";
1128 form.form_data.fields.push_back(field);
1130 // For newly saved passwords, upload a vote for autofill::PASSWORD.
1131 MockPasswordFormManager form_manager(&password_manager,
1133 client_with_store.GetDriver(),
1136 SimulateMatchingPhase(&form_manager, RESULT_NO_MATCH);
1138 PasswordForm form_to_save(form);
1139 form_to_save.preferred = true;
1140 form_to_save.username_value = ASCIIToUTF16("username");
1141 form_to_save.password_value = ASCIIToUTF16("1234");
1143 EXPECT_CALL(form_manager, UploadPasswordForm(_, autofill::PASSWORD)).Times(1);
1144 form_manager.ProvisionallySave(
1146 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1147 form_manager.Save();
1148 Mock::VerifyAndClearExpectations(&form_manager);
1150 // Do not upload a vote if the user is blacklisting the form.
1151 MockPasswordFormManager blacklist_form_manager(&password_manager,
1153 client_with_store.GetDriver(),
1156 SimulateMatchingPhase(&blacklist_form_manager, RESULT_NO_MATCH);
1158 EXPECT_CALL(blacklist_form_manager,
1159 UploadPasswordForm(_, autofill::PASSWORD)).Times(0);
1160 blacklist_form_manager.PermanentlyBlacklist();
1161 Mock::VerifyAndClearExpectations(&blacklist_form_manager);
1164 TEST_F(PasswordFormManagerTest, UploadFormData_AccountCreationPassword) {
1165 InitializeMockStore();
1166 TestPasswordManagerClient client_with_store(mock_store());
1167 TestPasswordManager password_manager(&client_with_store);
1168 EXPECT_CALL(*client_with_store.GetMockDriver(), IsOffTheRecord())
1169 .WillRepeatedly(Return(false));
1171 PasswordForm form(*observed_form());
1173 autofill::FormFieldData field;
1174 field.label = ASCIIToUTF16("Email");
1175 field.name = ASCIIToUTF16("Email");
1176 field.form_control_type = "text";
1177 form.form_data.fields.push_back(field);
1179 field.label = ASCIIToUTF16("password");
1180 field.name = ASCIIToUTF16("password");
1181 field.form_control_type = "password";
1182 form.form_data.fields.push_back(field);
1184 MockPasswordFormManager form_manager(&password_manager,
1186 client_with_store.GetDriver(),
1189 std::vector<PasswordForm*> result;
1190 result.push_back(CreateSavedMatch(false));
1192 field.label = ASCIIToUTF16("full_name");
1193 field.name = ASCIIToUTF16("full_name");
1194 field.form_control_type = "text";
1195 result[0]->form_data.fields.push_back(field);
1197 field.label = ASCIIToUTF16("Email");
1198 field.name = ASCIIToUTF16("Email");
1199 field.form_control_type = "text";
1200 result[0]->form_data.fields.push_back(field);
1202 field.label = ASCIIToUTF16("password");
1203 field.name = ASCIIToUTF16("password");
1204 field.form_control_type = "password";
1205 result[0]->form_data.fields.push_back(field);
1207 PasswordForm form_to_save(form);
1208 form_to_save.preferred = true;
1209 form_to_save.username_value = result[0]->username_value;
1210 form_to_save.password_value = result[0]->password_value;
1212 SimulateFetchMatchingLoginsFromPasswordStore(&form_manager);
1213 SimulateResponseFromPasswordStore(&form_manager, result);
1215 EXPECT_CALL(form_manager,
1216 UploadPasswordForm(_,
1217 autofill::ACCOUNT_CREATION_PASSWORD)).Times(1);
1218 form_manager.ProvisionallySave(
1220 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
1221 form_manager.Save();
1224 } // namespace password_manager