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
;
29 using ::testing::Mock
;
32 class AutofillManager
;
37 class MockPasswordManagerDriver
: public PasswordManagerDriver
{
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
{
55 explicit TestPasswordManagerClient(Profile
* profile
,
56 PasswordStore
* password_store
)
58 password_store_(password_store
) {}
60 virtual void PromptUserToSavePassword(PasswordFormManager
* form_to_save
)
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_
; }
74 PasswordStore
* password_store_
;
75 MockPasswordManagerDriver driver_
;
78 class TestPasswordManager
: public PasswordManager
{
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() {
96 // Marked mutable to get around constness of Autofill().
97 mutable autofill::PasswordFormMap best_matches_
;
102 class PasswordFormManagerTest
: public testing::Test
{
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() {
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
;
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
;
180 PasswordForm observed_form_
;
181 PasswordForm saved_match_
;
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(
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(
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
);
241 GetPendingCredentials(manager
)->password_value
);
243 GetPendingCredentials(manager
)->username_value
);
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(
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
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
);
286 GetPendingCredentials(manager
)->password_value
);
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()));
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(
328 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
329 EXPECT_FALSE(manager
->IsNewLogin());
330 // We bless our saved PasswordForm entry with the action URL of the
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(
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(
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
,
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(
413 PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES
);
415 EXPECT_FALSE(manager
->IsNewLogin());
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
);
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
,
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(
446 PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES
);
448 EXPECT_FALSE(manager
->IsNewLogin());
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
);
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
,
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(_
))
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
556 manager
.reset(new PasswordFormManager(&password_manager
,
561 EXPECT_CALL(*client
.GetMockDriver(), AllowPasswordGenerationForForm(_
))
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
572 manager
.reset(new PasswordFormManager(&password_manager
,
577 EXPECT_CALL(*client
.GetMockDriver(), AllowPasswordGenerationForForm(_
))
579 SimulateFetchMatchingLoginsFromPasswordStore(manager
.get());
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
,
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());
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
,
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.
664 expected
.push_back(ASCIIToUTF16("duplicate"));
665 expected
.push_back(ASCIIToUTF16("random"));
666 EXPECT_THAT(credentials
.other_possible_usernames
, Eq(expected
));