NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / password_manager / password_form_manager_unittest.cc
blob37bfb2b7287acb99e2cf375522a5a48e79a76fcd
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 "testing/gtest/include/gtest/gtest.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/password_manager/password_form_manager.h"
12 #include "chrome/browser/password_manager/password_manager.h"
13 #include "chrome/browser/password_manager/password_manager_client.h"
14 #include "chrome/browser/password_manager/password_manager_driver.h"
15 #include "chrome/browser/password_manager/password_store_factory.h"
16 #include "chrome/browser/password_manager/test_password_store_service.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/autofill/core/common/password_form.h"
20 #include "components/password_manager/core/browser/password_store.h"
21 #include "components/password_manager/core/browser/test_password_store.h"
22 #include "content/public/test/test_utils.h"
23 #include "testing/gmock/include/gmock/gmock.h"
25 using autofill::PasswordForm;
26 using base::ASCIIToUTF16;
27 using ::testing::_;
28 using ::testing::Eq;
29 using ::testing::Mock;
31 namespace autofill {
32 class AutofillManager;
35 namespace {
37 class MockPasswordManagerDriver : public PasswordManagerDriver {
38 public:
39 MockPasswordManagerDriver() {}
40 virtual ~MockPasswordManagerDriver() {}
42 MOCK_METHOD1(FillPasswordForm,
43 void(const autofill::PasswordFormFillData& form_data));
44 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
45 MOCK_METHOD0(IsOffTheRecord, bool());
46 MOCK_METHOD0(GetPasswordGenerationManager, PasswordGenerationManager*());
47 MOCK_METHOD0(GetPasswordManager, PasswordManager*());
48 MOCK_METHOD0(GetAutofillManager, autofill::AutofillManager*());
49 MOCK_METHOD1(AllowPasswordGenerationForForm,
50 void(autofill::PasswordForm* form));
53 class TestPasswordManagerClient : public PasswordManagerClient {
54 public:
55 explicit TestPasswordManagerClient(Profile* profile,
56 PasswordStore* password_store)
57 : profile_(profile),
58 password_store_(password_store) {}
60 virtual void PromptUserToSavePassword(PasswordFormManager* form_to_save)
61 OVERRIDE {}
62 virtual PrefService* GetPrefs() OVERRIDE { return profile_->GetPrefs(); }
63 virtual PasswordStore* GetPasswordStore() OVERRIDE { return password_store_;}
64 virtual PasswordManagerDriver* GetDriver() OVERRIDE { return &driver_; }
65 virtual void AuthenticateAutofillAndFillForm(
66 scoped_ptr<autofill::PasswordFormFillData> fill_data) OVERRIDE {
67 driver_.FillPasswordForm(*fill_data.get());
70 MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
72 private:
73 Profile* profile_;
74 PasswordStore* password_store_;
75 MockPasswordManagerDriver driver_;
78 class TestPasswordManager : public PasswordManager {
79 public:
80 explicit TestPasswordManager(PasswordManagerClient* client)
81 : PasswordManager(client) {}
83 virtual void Autofill(
84 const autofill::PasswordForm& form_for_autofill,
85 const autofill::PasswordFormMap& best_matches,
86 const autofill::PasswordForm& preferred_match,
87 bool wait_for_username) const OVERRIDE {
88 best_matches_ = best_matches;
91 const autofill::PasswordFormMap& GetLatestBestMatches() {
92 return best_matches_;
95 private:
96 // Marked mutable to get around constness of Autofill().
97 mutable autofill::PasswordFormMap best_matches_;
100 } // namespace
102 class PasswordFormManagerTest : public testing::Test {
103 public:
104 PasswordFormManagerTest() {
107 virtual void SetUp() {
108 observed_form_.origin = GURL("http://accounts.google.com/a/LoginAuth");
109 observed_form_.action = GURL("http://accounts.google.com/a/Login");
110 observed_form_.username_element = ASCIIToUTF16("Email");
111 observed_form_.password_element = ASCIIToUTF16("Passwd");
112 observed_form_.submit_element = ASCIIToUTF16("signIn");
113 observed_form_.signon_realm = "http://accounts.google.com";
115 saved_match_ = observed_form_;
116 saved_match_.origin = GURL("http://accounts.google.com/a/ServiceLoginAuth");
117 saved_match_.action = GURL("http://accounts.google.com/a/ServiceLogin");
118 saved_match_.preferred = true;
119 saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
120 saved_match_.password_value = ASCIIToUTF16("test1");
121 saved_match_.other_possible_usernames.push_back(
122 ASCIIToUTF16("test2@gmail.com"));
123 profile_ = new TestingProfile();
126 virtual void TearDown() {
127 delete profile_;
130 PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
131 return &p->pending_credentials_;
134 void SimulateMatchingPhase(PasswordFormManager* p, bool find_match) {
135 // Roll up the state to mock out the matching phase.
136 p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
137 if (!find_match)
138 return;
140 PasswordForm* match = new PasswordForm(saved_match_);
141 // Heap-allocated form is owned by p.
142 p->best_matches_[match->username_value] = match;
143 p->preferred_match_ = match;
146 void SimulateFetchMatchingLoginsFromPasswordStore(
147 PasswordFormManager* manager) {
148 // Just need to update the internal states.
149 manager->state_ = PasswordFormManager::MATCHING_PHASE;
152 void SimulateResponseFromPasswordStore(
153 PasswordFormManager* manager,
154 const std::vector<PasswordForm*>& result) {
155 // Simply call the callback method when request done. This will transfer
156 // the ownership of the objects in |result| to the |manager|.
157 manager->OnGetPasswordStoreResults(result);
160 void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
161 p->SanitizePossibleUsernames(form);
164 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
165 return p->IgnoreResult(*form);
168 Profile* profile() { return profile_; }
170 PasswordForm* observed_form() { return &observed_form_; }
171 PasswordForm* saved_match() { return &saved_match_; }
172 PasswordForm* CreateSavedMatch(bool blacklisted) {
173 // Owned by the caller of this method.
174 PasswordForm* match = new PasswordForm(saved_match_);
175 match->blacklisted_by_user = blacklisted;
176 return match;
179 private:
180 PasswordForm observed_form_;
181 PasswordForm saved_match_;
182 Profile* profile_;
185 TEST_F(PasswordFormManagerTest, TestNewLogin) {
186 scoped_ptr<TestPasswordManagerClient> client(
187 new TestPasswordManagerClient(profile(), NULL));
188 scoped_ptr<MockPasswordManagerDriver> driver;
189 PasswordFormManager* manager = new PasswordFormManager(
190 NULL, client.get(), driver.get(), *observed_form(), false);
192 SimulateMatchingPhase(manager, false);
193 // User submits credentials for the observed form.
194 PasswordForm credentials = *observed_form();
195 credentials.username_value = saved_match()->username_value;
196 credentials.password_value = saved_match()->password_value;
197 credentials.preferred = true;
198 manager->ProvisionallySave(
199 credentials,
200 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
202 // Successful login. The PasswordManager would instruct PasswordFormManager
203 // to save, which should know this is a new login.
204 EXPECT_TRUE(manager->IsNewLogin());
205 // Make sure the credentials that would be submitted on successful login
206 // are going to match the stored entry in the db.
207 EXPECT_EQ(observed_form()->origin.spec(),
208 GetPendingCredentials(manager)->origin.spec());
209 EXPECT_EQ(observed_form()->signon_realm,
210 GetPendingCredentials(manager)->signon_realm);
211 EXPECT_EQ(observed_form()->action,
212 GetPendingCredentials(manager)->action);
213 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
214 EXPECT_EQ(saved_match()->password_value,
215 GetPendingCredentials(manager)->password_value);
216 EXPECT_EQ(saved_match()->username_value,
217 GetPendingCredentials(manager)->username_value);
219 // Now, suppose the user re-visits the site and wants to save an additional
220 // login for the site with a new username. In this case, the matching phase
221 // will yield the previously saved login.
222 SimulateMatchingPhase(manager, true);
223 // Set up the new login.
224 base::string16 new_user = ASCIIToUTF16("newuser");
225 base::string16 new_pass = ASCIIToUTF16("newpass");
226 credentials.username_value = new_user;
227 credentials.password_value = new_pass;
228 manager->ProvisionallySave(
229 credentials,
230 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
232 // Again, the PasswordFormManager should know this is still a new login.
233 EXPECT_TRUE(manager->IsNewLogin());
234 // And make sure everything squares up again.
235 EXPECT_EQ(observed_form()->origin.spec(),
236 GetPendingCredentials(manager)->origin.spec());
237 EXPECT_EQ(observed_form()->signon_realm,
238 GetPendingCredentials(manager)->signon_realm);
239 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
240 EXPECT_EQ(new_pass,
241 GetPendingCredentials(manager)->password_value);
242 EXPECT_EQ(new_user,
243 GetPendingCredentials(manager)->username_value);
244 delete manager;
247 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
248 // Create a PasswordFormManager with observed_form, as if we just
249 // saw this form and need to find matching logins.
250 scoped_ptr<TestPasswordManagerClient> client(
251 new TestPasswordManagerClient(profile(), NULL));
252 scoped_ptr<MockPasswordManagerDriver> driver;
253 PasswordFormManager* manager = new PasswordFormManager(
254 NULL, client.get(), driver.get(), *observed_form(), false);
256 SimulateMatchingPhase(manager, true);
258 // User submits credentials for the observed form using a username previously
259 // stored, but a new password. Note that the observed form may have different
260 // origin URL (as it does in this case) than the saved_match, but we want to
261 // make sure the updated password is reflected in saved_match, because that is
262 // what we autofilled.
263 base::string16 new_pass = ASCIIToUTF16("newpassword");
264 PasswordForm credentials = *observed_form();
265 credentials.username_value = saved_match()->username_value;
266 credentials.password_value = new_pass;
267 credentials.preferred = true;
268 manager->ProvisionallySave(
269 credentials,
270 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
272 // Successful login. The PasswordManager would instruct PasswordFormManager
273 // to save, and since this is an update, it should know not to save as a new
274 // login.
275 EXPECT_FALSE(manager->IsNewLogin());
277 // Make sure the credentials that would be submitted on successful login
278 // are going to match the stored entry in the db. (This verifies correct
279 // behaviour for bug 1074420).
280 EXPECT_EQ(GetPendingCredentials(manager)->origin.spec(),
281 saved_match()->origin.spec());
282 EXPECT_EQ(GetPendingCredentials(manager)->signon_realm,
283 saved_match()->signon_realm);
284 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
285 EXPECT_EQ(new_pass,
286 GetPendingCredentials(manager)->password_value);
287 // Done.
288 delete manager;
291 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
292 scoped_ptr<TestPasswordManagerClient> client(
293 new TestPasswordManagerClient(profile(), NULL));
294 scoped_ptr<MockPasswordManagerDriver> driver;
295 PasswordFormManager* manager = new PasswordFormManager(
296 NULL, client.get(), driver.get(), *observed_form(), false);
298 // Make sure we don't match a PasswordForm if it was originally saved on
299 // an SSL-valid page and we are now on a page with invalid certificate.
300 saved_match()->ssl_valid = true;
301 EXPECT_TRUE(IgnoredResult(manager, saved_match()));
303 saved_match()->ssl_valid = false;
304 // Different paths for action / origin are okay.
305 saved_match()->action = GURL("http://www.google.com/b/Login");
306 saved_match()->origin = GURL("http://www.google.com/foo");
307 EXPECT_FALSE(IgnoredResult(manager, saved_match()));
309 // Done.
310 delete manager;
313 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
314 scoped_ptr<TestPasswordManagerClient> client(
315 new TestPasswordManagerClient(profile(), NULL));
316 scoped_ptr<MockPasswordManagerDriver> driver;
317 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
318 NULL, client.get(), driver.get(), *observed_form(), false));
320 saved_match()->action = GURL();
321 SimulateMatchingPhase(manager.get(), true);
322 // User logs in with the autofilled username / password from saved_match.
323 PasswordForm login = *observed_form();
324 login.username_value = saved_match()->username_value;
325 login.password_value = saved_match()->password_value;
326 manager->ProvisionallySave(
327 login,
328 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
329 EXPECT_FALSE(manager->IsNewLogin());
330 // We bless our saved PasswordForm entry with the action URL of the
331 // observed form.
332 EXPECT_EQ(observed_form()->action,
333 GetPendingCredentials(manager.get())->action);
336 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
337 scoped_ptr<TestPasswordManagerClient> client(
338 new TestPasswordManagerClient(profile(), NULL));
339 scoped_ptr<MockPasswordManagerDriver> driver;
340 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
341 NULL, client.get(), driver.get(), *observed_form(), false));
343 SimulateMatchingPhase(manager.get(), true);
344 // User logs in with the autofilled username / password from saved_match.
345 PasswordForm login = *observed_form();
346 login.username_value = saved_match()->username_value;
347 login.password_value = saved_match()->password_value;
349 manager->ProvisionallySave(
350 login,
351 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
352 EXPECT_FALSE(manager->IsNewLogin());
353 // The observed action URL is different from the previously saved one, and
354 // is the same as the one that would be submitted on successful login.
355 EXPECT_NE(observed_form()->action, saved_match()->action);
356 EXPECT_EQ(observed_form()->action,
357 GetPendingCredentials(manager.get())->action);
360 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
361 scoped_ptr<TestPasswordManagerClient> client(
362 new TestPasswordManagerClient(profile(), NULL));
363 scoped_ptr<MockPasswordManagerDriver> driver;
364 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
365 NULL, client.get(), driver.get(), *observed_form(), false));
367 SimulateMatchingPhase(manager.get(), false);
368 PasswordForm login(*observed_form());
369 // The submitted action URL is different from the one observed on page load.
370 GURL new_action = GURL("http://www.google.com/new_action");
371 login.action = new_action;
373 manager->ProvisionallySave(
374 login,
375 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
376 EXPECT_TRUE(manager->IsNewLogin());
377 // Check that the provisionally saved action URL is the same as the submitted
378 // action URL, not the one observed on page load.
379 EXPECT_EQ(new_action,
380 GetPendingCredentials(manager.get())->action);
383 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
384 // Need a MessageLoop for callbacks.
385 base::MessageLoop message_loop;
386 PasswordStoreFactory::GetInstance()->SetTestingFactory(
387 profile(), TestPasswordStoreService::Build);
388 scoped_refptr<PasswordStore> store_temp(
389 PasswordStoreFactory::GetForProfile(profile(), Profile::IMPLICIT_ACCESS));
390 scoped_refptr<TestPasswordStore> password_store =
391 static_cast<TestPasswordStore*>(store_temp.get());
393 TestPasswordManagerClient client(profile(), password_store.get());
394 TestPasswordManager password_manager(&client);
395 scoped_ptr<PasswordFormManager> manager(
396 new PasswordFormManager(&password_manager,
397 &client,
398 client.GetDriver(),
399 *observed_form(),
400 false));
402 password_store->AddLogin(*saved_match());
403 manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
404 content::RunAllPendingInMessageLoop();
406 // The saved match has the right username already.
407 PasswordForm login(*observed_form());
408 login.username_value = saved_match()->username_value;
409 login.password_value = saved_match()->password_value;
410 login.preferred = true;
411 manager->ProvisionallySave(
412 login,
413 PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
415 EXPECT_FALSE(manager->IsNewLogin());
416 manager->Save();
417 content::RunAllPendingInMessageLoop();
419 // Should be only one password stored, and should not have
420 // |other_possible_usernames| set anymore.
421 TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
422 EXPECT_EQ(1U, passwords.size());
423 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
424 EXPECT_EQ(saved_match()->username_value,
425 passwords[saved_match()->signon_realm][0].username_value);
426 EXPECT_EQ(
428 passwords[saved_match()->signon_realm][0].
429 other_possible_usernames.size());
431 // This time use an alternate username
432 manager.reset(new PasswordFormManager(&password_manager,
433 &client,
434 client.GetDriver(),
435 *observed_form(),
436 false));
437 password_store->Clear();
438 password_store->AddLogin(*saved_match());
439 manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
440 content::RunAllPendingInMessageLoop();
442 base::string16 new_username = saved_match()->other_possible_usernames[0];
443 login.username_value = new_username;
444 manager->ProvisionallySave(
445 login,
446 PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
448 EXPECT_FALSE(manager->IsNewLogin());
449 manager->Save();
450 content::RunAllPendingInMessageLoop();
452 // |other_possible_usernames| should also be empty, but username_value should
453 // be changed to match |new_username|
454 passwords = password_store->stored_passwords();
455 EXPECT_EQ(1U, passwords.size());
456 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
457 EXPECT_EQ(new_username,
458 passwords[saved_match()->signon_realm][0].username_value);
459 EXPECT_EQ(
461 passwords[saved_match()->signon_realm][0].
462 other_possible_usernames.size());
465 TEST_F(PasswordFormManagerTest, TestValidForms) {
466 // User submits credentials for the observed form.
467 PasswordForm credentials = *observed_form();
468 credentials.scheme = PasswordForm::SCHEME_HTML;
469 credentials.username_value = saved_match()->username_value;
470 credentials.password_value = saved_match()->password_value;
472 // Form with both username_element and password_element.
473 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
474 SimulateMatchingPhase(&manager1, false);
475 EXPECT_TRUE(manager1.HasValidPasswordForm());
477 // Form without a username_element but with a password_element.
478 credentials.username_element.clear();
479 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
480 SimulateMatchingPhase(&manager2, false);
481 EXPECT_FALSE(manager2.HasValidPasswordForm());
483 // Form without a password_element but with a username_element.
484 credentials.username_element = saved_match()->username_element;
485 credentials.password_element.clear();
486 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
487 SimulateMatchingPhase(&manager3, false);
488 EXPECT_FALSE(manager3.HasValidPasswordForm());
490 // Form with neither a password_element nor a username_element.
491 credentials.username_element.clear();
492 credentials.password_element.clear();
493 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
494 SimulateMatchingPhase(&manager4, false);
495 EXPECT_FALSE(manager4.HasValidPasswordForm());
498 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
499 // User submits credentials for the observed form.
500 PasswordForm credentials = *observed_form();
501 credentials.scheme = PasswordForm::SCHEME_BASIC;
502 credentials.username_value = saved_match()->username_value;
503 credentials.password_value = saved_match()->password_value;
505 // Form with both username_element and password_element.
506 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
507 SimulateMatchingPhase(&manager1, false);
508 EXPECT_TRUE(manager1.HasValidPasswordForm());
510 // Form without a username_element but with a password_element.
511 credentials.username_element.clear();
512 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
513 SimulateMatchingPhase(&manager2, false);
514 EXPECT_TRUE(manager2.HasValidPasswordForm());
516 // Form without a password_element but with a username_element.
517 credentials.username_element = saved_match()->username_element;
518 credentials.password_element.clear();
519 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
520 SimulateMatchingPhase(&manager3, false);
521 EXPECT_TRUE(manager3.HasValidPasswordForm());
523 // Form with neither a password_element nor a username_element.
524 credentials.username_element.clear();
525 credentials.password_element.clear();
526 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
527 SimulateMatchingPhase(&manager4, false);
528 EXPECT_TRUE(manager4.HasValidPasswordForm());
531 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
532 base::MessageLoop message_loop;
534 // A dumb password manager.
535 TestPasswordManagerClient client(profile(), NULL);
536 TestPasswordManager password_manager(&client);
537 scoped_ptr<PasswordFormManager> manager(
538 new PasswordFormManager(&password_manager,
539 &client,
540 client.GetDriver(),
541 *observed_form(),
542 false));
544 // First time sign up attempt; No login result is found from password store;
545 // We should send the not blacklisted message.
546 EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
547 .Times(1);
548 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
549 std::vector<PasswordForm*> result;
550 SimulateResponseFromPasswordStore(manager.get(), result);
551 Mock::VerifyAndClearExpectations(client.GetMockDriver());
553 // Sign up attempt to previously visited sites; Login result is found from
554 // password store, and is not blacklisted; We should send the not blacklisted
555 // message.
556 manager.reset(new PasswordFormManager(&password_manager,
557 &client,
558 client.GetDriver(),
559 *observed_form(),
560 false));
561 EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
562 .Times(1);
563 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
564 // We need add heap allocated objects to result.
565 result.push_back(CreateSavedMatch(false));
566 SimulateResponseFromPasswordStore(manager.get(), result);
567 Mock::VerifyAndClearExpectations(client.GetMockDriver());
569 // Sign up attempt to previously visited sites; Login result is found from
570 // password store, but is blacklisted; We should not send the not blacklisted
571 // message.
572 manager.reset(new PasswordFormManager(&password_manager,
573 &client,
574 client.GetDriver(),
575 *observed_form(),
576 false));
577 EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
578 .Times(0);
579 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
580 result.clear();
581 result.push_back(CreateSavedMatch(true));
582 SimulateResponseFromPasswordStore(manager.get(), result);
583 Mock::VerifyAndClearExpectations(client.GetMockDriver());
586 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
587 base::MessageLoop message_loop;
589 TestPasswordManagerClient client(profile(), NULL);
590 TestPasswordManager password_manager(&client);
591 scoped_ptr<PasswordFormManager> manager(
592 new PasswordFormManager(&password_manager,
593 &client,
594 client.GetDriver(),
595 *observed_form(),
596 false));
598 // Simulate having two matches for this origin, one of which was from a form
599 // with different HTML tags for elements. Because of scoring differences,
600 // only the first form will be sent to Autofill().
601 std::vector<PasswordForm*> results;
602 results.push_back(CreateSavedMatch(false));
603 results.push_back(CreateSavedMatch(false));
604 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
605 results[1]->password_element = ASCIIToUTF16("signup_password");
606 results[1]->username_element = ASCIIToUTF16("signup_username");
607 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
608 SimulateResponseFromPasswordStore(manager.get(), results);
609 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
610 results.clear();
612 // Same thing, except this time the credentials that don't match quite as
613 // well are generated. They should now be sent to Autofill().
614 manager.reset(new PasswordFormManager(&password_manager,
615 &client,
616 client.GetDriver(),
617 *observed_form(),
618 false));
619 results.push_back(CreateSavedMatch(false));
620 results.push_back(CreateSavedMatch(false));
621 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
622 results[1]->password_element = ASCIIToUTF16("signup_password");
623 results[1]->username_element = ASCIIToUTF16("signup_username");
624 results[1]->type = PasswordForm::TYPE_GENERATED;
625 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
626 SimulateResponseFromPasswordStore(manager.get(), results);
627 EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
630 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
631 scoped_ptr<TestPasswordManagerClient> client(
632 new TestPasswordManagerClient(profile(), NULL));
633 scoped_ptr<MockPasswordManagerDriver> driver;
634 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
635 NULL, client.get(), driver.get(), *observed_form(), false));
636 PasswordForm credentials(*observed_form());
637 credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
638 credentials.other_possible_usernames.push_back(
639 ASCIIToUTF16("378282246310005"));
640 credentials.other_possible_usernames.push_back(
641 ASCIIToUTF16("other username"));
642 credentials.username_value = ASCIIToUTF16("test@gmail.com");
644 SanitizePossibleUsernames(manager.get(), &credentials);
646 // Possible credit card number and SSN are stripped.
647 std::vector<base::string16> expected;
648 expected.push_back(ASCIIToUTF16("other username"));
649 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
651 credentials.other_possible_usernames.clear();
652 credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
653 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
654 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
655 credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
656 credentials.other_possible_usernames.push_back(
657 ASCIIToUTF16("test@gmail.com"));
659 SanitizePossibleUsernames(manager.get(), &credentials);
661 // SSN, duplicate in |other_possible_usernames| and duplicate of
662 // |username_value| all removed.
663 expected.clear();
664 expected.push_back(ASCIIToUTF16("duplicate"));
665 expected.push_back(ASCIIToUTF16("random"));
666 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));