Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: chrome/browser/password_manager/password_form_manager_unittest.cc

Issue 190453002: Componentize PasswordManager and PasswordFormManager unittests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "testing/gtest/include/gtest/gtest.h"
6
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/profiles/profile_manager.h"
12 #include "chrome/test/base/testing_profile.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_client.h"
18 #include "components/password_manager/core/browser/password_manager_driver.h"
19 #include "components/password_manager/core/browser/password_store.h"
20 #include "components/password_manager/core/browser/test_password_store.h"
21 #include "content/public/test/test_utils.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23
24 using autofill::PasswordForm;
25 using base::ASCIIToUTF16;
26 using ::testing::_;
27 using ::testing::Eq;
28 using ::testing::Mock;
29 using ::testing::Return;
30
31 namespace autofill {
32 class AutofillManager;
33 }
34
35 namespace {
36
37 class MockPasswordManagerDriver : public PasswordManagerDriver {
38 public:
39 MockPasswordManagerDriver() {}
40 virtual ~MockPasswordManagerDriver() {}
41
42 MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&));
43 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
44 MOCK_METHOD0(IsOffTheRecord, bool());
45 MOCK_METHOD0(GetPasswordGenerationManager, PasswordGenerationManager*());
46 MOCK_METHOD0(GetPasswordManager, PasswordManager*());
47 MOCK_METHOD0(GetAutofillManager, autofill::AutofillManager*());
48 MOCK_METHOD1(AllowPasswordGenerationForForm, void(autofill::PasswordForm*));
49 MOCK_METHOD1(AccountCreationFormsFound,
50 void(const std::vector<autofill::FormData>&));
51 };
52
53 class TestPasswordManagerClient : public PasswordManagerClient {
54 public:
55 explicit TestPasswordManagerClient(Profile* profile,
56 PasswordStore* password_store)
57 : profile_(profile),
58 password_store_(password_store) {}
59
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());
68 }
69
70 MockPasswordManagerDriver* GetMockDriver() { return &driver_; }
71
72 private:
73 Profile* profile_;
74 PasswordStore* password_store_;
75 MockPasswordManagerDriver driver_;
76 };
77
78 class TestPasswordManager : public PasswordManager {
79 public:
80 explicit TestPasswordManager(PasswordManagerClient* client)
81 : PasswordManager(client) {}
82
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;
89 }
90
91 const autofill::PasswordFormMap& GetLatestBestMatches() {
92 return best_matches_;
93 }
94
95 private:
96 // Marked mutable to get around constness of Autofill().
97 mutable autofill::PasswordFormMap best_matches_;
98 };
99
100 } // namespace
101
102 class PasswordFormManagerTest : public testing::Test {
103 public:
104 PasswordFormManagerTest() {
105 }
106
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";
114
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();
124 }
125
126 virtual void TearDown() {
127 delete profile_;
128 if (mock_store_)
129 mock_store_->Shutdown();
130 }
131
132 void InitializeMockStore() {
133 if (!mock_store_) {
134 mock_store_ = new MockPasswordStore();
135 ASSERT_TRUE(mock_store_);
136 }
137 }
138
139 MockPasswordStore* mock_store() const {
140 return mock_store_.get();
141 }
142
143 PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
144 return &p->pending_credentials_;
145 }
146
147 void SimulateMatchingPhase(PasswordFormManager* p, bool find_match) {
148 // Roll up the state to mock out the matching phase.
149 p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
150 if (!find_match)
151 return;
152
153 PasswordForm* match = new PasswordForm(saved_match_);
154 // Heap-allocated form is owned by p.
155 p->best_matches_[match->username_value] = match;
156 p->preferred_match_ = match;
157 }
158
159 void SimulateFetchMatchingLoginsFromPasswordStore(
160 PasswordFormManager* manager) {
161 // Just need to update the internal states.
162 manager->state_ = PasswordFormManager::MATCHING_PHASE;
163 }
164
165 void SimulateResponseFromPasswordStore(
166 PasswordFormManager* manager,
167 const std::vector<PasswordForm*>& result) {
168 // Simply call the callback method when request done. This will transfer
169 // the ownership of the objects in |result| to the |manager|.
170 manager->OnGetPasswordStoreResults(result);
171 }
172
173 void SanitizePossibleUsernames(PasswordFormManager* p, PasswordForm* form) {
174 p->SanitizePossibleUsernames(form);
175 }
176
177 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
178 return p->IgnoreResult(*form);
179 }
180
181 Profile* profile() { return profile_; }
182
183 PasswordForm* observed_form() { return &observed_form_; }
184 PasswordForm* saved_match() { return &saved_match_; }
185 PasswordForm* CreateSavedMatch(bool blacklisted) {
186 // Owned by the caller of this method.
187 PasswordForm* match = new PasswordForm(saved_match_);
188 match->blacklisted_by_user = blacklisted;
189 return match;
190 }
191
192 private:
193 PasswordForm observed_form_;
194 PasswordForm saved_match_;
195 Profile* profile_;
196 scoped_refptr<MockPasswordStore> mock_store_;
197 };
198
199 TEST_F(PasswordFormManagerTest, TestNewLogin) {
200 scoped_ptr<TestPasswordManagerClient> client(
201 new TestPasswordManagerClient(profile(), NULL));
202 scoped_ptr<MockPasswordManagerDriver> driver;
203 PasswordFormManager* manager = new PasswordFormManager(
204 NULL, client.get(), driver.get(), *observed_form(), false);
205
206 SimulateMatchingPhase(manager, false);
207 // User submits credentials for the observed form.
208 PasswordForm credentials = *observed_form();
209 credentials.username_value = saved_match()->username_value;
210 credentials.password_value = saved_match()->password_value;
211 credentials.preferred = true;
212 manager->ProvisionallySave(
213 credentials,
214 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
215
216 // Successful login. The PasswordManager would instruct PasswordFormManager
217 // to save, which should know this is a new login.
218 EXPECT_TRUE(manager->IsNewLogin());
219 // Make sure the credentials that would be submitted on successful login
220 // are going to match the stored entry in the db.
221 EXPECT_EQ(observed_form()->origin.spec(),
222 GetPendingCredentials(manager)->origin.spec());
223 EXPECT_EQ(observed_form()->signon_realm,
224 GetPendingCredentials(manager)->signon_realm);
225 EXPECT_EQ(observed_form()->action,
226 GetPendingCredentials(manager)->action);
227 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
228 EXPECT_EQ(saved_match()->password_value,
229 GetPendingCredentials(manager)->password_value);
230 EXPECT_EQ(saved_match()->username_value,
231 GetPendingCredentials(manager)->username_value);
232
233 // Now, suppose the user re-visits the site and wants to save an additional
234 // login for the site with a new username. In this case, the matching phase
235 // will yield the previously saved login.
236 SimulateMatchingPhase(manager, true);
237 // Set up the new login.
238 base::string16 new_user = ASCIIToUTF16("newuser");
239 base::string16 new_pass = ASCIIToUTF16("newpass");
240 credentials.username_value = new_user;
241 credentials.password_value = new_pass;
242 manager->ProvisionallySave(
243 credentials,
244 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
245
246 // Again, the PasswordFormManager should know this is still a new login.
247 EXPECT_TRUE(manager->IsNewLogin());
248 // And make sure everything squares up again.
249 EXPECT_EQ(observed_form()->origin.spec(),
250 GetPendingCredentials(manager)->origin.spec());
251 EXPECT_EQ(observed_form()->signon_realm,
252 GetPendingCredentials(manager)->signon_realm);
253 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
254 EXPECT_EQ(new_pass,
255 GetPendingCredentials(manager)->password_value);
256 EXPECT_EQ(new_user,
257 GetPendingCredentials(manager)->username_value);
258 delete manager;
259 }
260
261 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
262 // Create a PasswordFormManager with observed_form, as if we just
263 // saw this form and need to find matching logins.
264 scoped_ptr<TestPasswordManagerClient> client(
265 new TestPasswordManagerClient(profile(), NULL));
266 scoped_ptr<MockPasswordManagerDriver> driver;
267 PasswordFormManager* manager = new PasswordFormManager(
268 NULL, client.get(), driver.get(), *observed_form(), false);
269
270 SimulateMatchingPhase(manager, true);
271
272 // User submits credentials for the observed form using a username previously
273 // stored, but a new password. Note that the observed form may have different
274 // origin URL (as it does in this case) than the saved_match, but we want to
275 // make sure the updated password is reflected in saved_match, because that is
276 // what we autofilled.
277 base::string16 new_pass = ASCIIToUTF16("newpassword");
278 PasswordForm credentials = *observed_form();
279 credentials.username_value = saved_match()->username_value;
280 credentials.password_value = new_pass;
281 credentials.preferred = true;
282 manager->ProvisionallySave(
283 credentials,
284 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
285
286 // Successful login. The PasswordManager would instruct PasswordFormManager
287 // to save, and since this is an update, it should know not to save as a new
288 // login.
289 EXPECT_FALSE(manager->IsNewLogin());
290
291 // Make sure the credentials that would be submitted on successful login
292 // are going to match the stored entry in the db. (This verifies correct
293 // behaviour for bug 1074420).
294 EXPECT_EQ(GetPendingCredentials(manager)->origin.spec(),
295 saved_match()->origin.spec());
296 EXPECT_EQ(GetPendingCredentials(manager)->signon_realm,
297 saved_match()->signon_realm);
298 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
299 EXPECT_EQ(new_pass,
300 GetPendingCredentials(manager)->password_value);
301 // Done.
302 delete manager;
303 }
304
305 TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
306 scoped_ptr<TestPasswordManagerClient> client(
307 new TestPasswordManagerClient(profile(), NULL));
308 scoped_ptr<MockPasswordManagerDriver> driver;
309 PasswordFormManager* manager = new PasswordFormManager(
310 NULL, client.get(), driver.get(), *observed_form(), false);
311
312 // Make sure we don't match a PasswordForm if it was originally saved on
313 // an SSL-valid page and we are now on a page with invalid certificate.
314 saved_match()->ssl_valid = true;
315 EXPECT_TRUE(IgnoredResult(manager, saved_match()));
316
317 saved_match()->ssl_valid = false;
318 // Different paths for action / origin are okay.
319 saved_match()->action = GURL("http://www.google.com/b/Login");
320 saved_match()->origin = GURL("http://www.google.com/foo");
321 EXPECT_FALSE(IgnoredResult(manager, saved_match()));
322
323 // Done.
324 delete manager;
325 }
326
327 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
328 scoped_ptr<TestPasswordManagerClient> client(
329 new TestPasswordManagerClient(profile(), NULL));
330 scoped_ptr<MockPasswordManagerDriver> driver;
331 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
332 NULL, client.get(), driver.get(), *observed_form(), false));
333
334 saved_match()->action = GURL();
335 SimulateMatchingPhase(manager.get(), true);
336 // User logs in with the autofilled username / password from saved_match.
337 PasswordForm login = *observed_form();
338 login.username_value = saved_match()->username_value;
339 login.password_value = saved_match()->password_value;
340 manager->ProvisionallySave(
341 login,
342 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
343 EXPECT_FALSE(manager->IsNewLogin());
344 // We bless our saved PasswordForm entry with the action URL of the
345 // observed form.
346 EXPECT_EQ(observed_form()->action,
347 GetPendingCredentials(manager.get())->action);
348 }
349
350 TEST_F(PasswordFormManagerTest, TestUpdateAction) {
351 scoped_ptr<TestPasswordManagerClient> client(
352 new TestPasswordManagerClient(profile(), NULL));
353 scoped_ptr<MockPasswordManagerDriver> driver;
354 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
355 NULL, client.get(), driver.get(), *observed_form(), false));
356
357 SimulateMatchingPhase(manager.get(), true);
358 // User logs in with the autofilled username / password from saved_match.
359 PasswordForm login = *observed_form();
360 login.username_value = saved_match()->username_value;
361 login.password_value = saved_match()->password_value;
362
363 manager->ProvisionallySave(
364 login,
365 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
366 EXPECT_FALSE(manager->IsNewLogin());
367 // The observed action URL is different from the previously saved one, and
368 // is the same as the one that would be submitted on successful login.
369 EXPECT_NE(observed_form()->action, saved_match()->action);
370 EXPECT_EQ(observed_form()->action,
371 GetPendingCredentials(manager.get())->action);
372 }
373
374 TEST_F(PasswordFormManagerTest, TestDynamicAction) {
375 scoped_ptr<TestPasswordManagerClient> client(
376 new TestPasswordManagerClient(profile(), NULL));
377 scoped_ptr<MockPasswordManagerDriver> driver;
378 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
379 NULL, client.get(), driver.get(), *observed_form(), false));
380
381 SimulateMatchingPhase(manager.get(), false);
382 PasswordForm login(*observed_form());
383 // The submitted action URL is different from the one observed on page load.
384 GURL new_action = GURL("http://www.google.com/new_action");
385 login.action = new_action;
386
387 manager->ProvisionallySave(
388 login,
389 PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
390 EXPECT_TRUE(manager->IsNewLogin());
391 // Check that the provisionally saved action URL is the same as the submitted
392 // action URL, not the one observed on page load.
393 EXPECT_EQ(new_action,
394 GetPendingCredentials(manager.get())->action);
395 }
396
397 TEST_F(PasswordFormManagerTest, TestAlternateUsername) {
398 // Need a MessageLoop for callbacks.
399 base::MessageLoop message_loop;
400 scoped_refptr<TestPasswordStore> password_store = new TestPasswordStore;
401 CHECK(password_store->Init());
402
403 TestPasswordManagerClient client(profile(), password_store.get());
404 TestPasswordManager password_manager(&client);
405 scoped_ptr<PasswordFormManager> manager(
406 new PasswordFormManager(&password_manager,
407 &client,
408 client.GetDriver(),
409 *observed_form(),
410 false));
411
412 password_store->AddLogin(*saved_match());
413 manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
414 content::RunAllPendingInMessageLoop();
415
416 // The saved match has the right username already.
417 PasswordForm login(*observed_form());
418 login.username_value = saved_match()->username_value;
419 login.password_value = saved_match()->password_value;
420 login.preferred = true;
421 manager->ProvisionallySave(
422 login,
423 PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
424
425 EXPECT_FALSE(manager->IsNewLogin());
426 manager->Save();
427 content::RunAllPendingInMessageLoop();
428
429 // Should be only one password stored, and should not have
430 // |other_possible_usernames| set anymore.
431 TestPasswordStore::PasswordMap passwords = password_store->stored_passwords();
432 EXPECT_EQ(1U, passwords.size());
433 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
434 EXPECT_EQ(saved_match()->username_value,
435 passwords[saved_match()->signon_realm][0].username_value);
436 EXPECT_EQ(
437 0U,
438 passwords[saved_match()->signon_realm][0].
439 other_possible_usernames.size());
440
441 // This time use an alternate username
442 manager.reset(new PasswordFormManager(&password_manager,
443 &client,
444 client.GetDriver(),
445 *observed_form(),
446 false));
447 password_store->Clear();
448 password_store->AddLogin(*saved_match());
449 manager->FetchMatchingLoginsFromPasswordStore(PasswordStore::ALLOW_PROMPT);
450 content::RunAllPendingInMessageLoop();
451
452 base::string16 new_username = saved_match()->other_possible_usernames[0];
453 login.username_value = new_username;
454 manager->ProvisionallySave(
455 login,
456 PasswordFormManager::ALLOW_OTHER_POSSIBLE_USERNAMES);
457
458 EXPECT_FALSE(manager->IsNewLogin());
459 manager->Save();
460 content::RunAllPendingInMessageLoop();
461
462 // |other_possible_usernames| should also be empty, but username_value should
463 // be changed to match |new_username|
464 passwords = password_store->stored_passwords();
465 EXPECT_EQ(1U, passwords.size());
466 ASSERT_EQ(1U, passwords[saved_match()->signon_realm].size());
467 EXPECT_EQ(new_username,
468 passwords[saved_match()->signon_realm][0].username_value);
469 EXPECT_EQ(
470 0U,
471 passwords[saved_match()->signon_realm][0].
472 other_possible_usernames.size());
473 password_store->Shutdown();
474 }
475
476 TEST_F(PasswordFormManagerTest, TestValidForms) {
477 // User submits credentials for the observed form.
478 PasswordForm credentials = *observed_form();
479 credentials.scheme = PasswordForm::SCHEME_HTML;
480 credentials.username_value = saved_match()->username_value;
481 credentials.password_value = saved_match()->password_value;
482
483 // Form with both username_element and password_element.
484 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
485 SimulateMatchingPhase(&manager1, false);
486 EXPECT_TRUE(manager1.HasValidPasswordForm());
487
488 // Form without a username_element but with a password_element.
489 credentials.username_element.clear();
490 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
491 SimulateMatchingPhase(&manager2, false);
492 EXPECT_FALSE(manager2.HasValidPasswordForm());
493
494 // Form without a password_element but with a username_element.
495 credentials.username_element = saved_match()->username_element;
496 credentials.password_element.clear();
497 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
498 SimulateMatchingPhase(&manager3, false);
499 EXPECT_FALSE(manager3.HasValidPasswordForm());
500
501 // Form with neither a password_element nor a username_element.
502 credentials.username_element.clear();
503 credentials.password_element.clear();
504 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
505 SimulateMatchingPhase(&manager4, false);
506 EXPECT_FALSE(manager4.HasValidPasswordForm());
507 }
508
509 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
510 // User submits credentials for the observed form.
511 PasswordForm credentials = *observed_form();
512 credentials.scheme = PasswordForm::SCHEME_BASIC;
513 credentials.username_value = saved_match()->username_value;
514 credentials.password_value = saved_match()->password_value;
515
516 // Form with both username_element and password_element.
517 PasswordFormManager manager1(NULL, NULL, NULL, credentials, false);
518 SimulateMatchingPhase(&manager1, false);
519 EXPECT_TRUE(manager1.HasValidPasswordForm());
520
521 // Form without a username_element but with a password_element.
522 credentials.username_element.clear();
523 PasswordFormManager manager2(NULL, NULL, NULL, credentials, false);
524 SimulateMatchingPhase(&manager2, false);
525 EXPECT_TRUE(manager2.HasValidPasswordForm());
526
527 // Form without a password_element but with a username_element.
528 credentials.username_element = saved_match()->username_element;
529 credentials.password_element.clear();
530 PasswordFormManager manager3(NULL, NULL, NULL, credentials, false);
531 SimulateMatchingPhase(&manager3, false);
532 EXPECT_TRUE(manager3.HasValidPasswordForm());
533
534 // Form with neither a password_element nor a username_element.
535 credentials.username_element.clear();
536 credentials.password_element.clear();
537 PasswordFormManager manager4(NULL, NULL, NULL, credentials, false);
538 SimulateMatchingPhase(&manager4, false);
539 EXPECT_TRUE(manager4.HasValidPasswordForm());
540 }
541
542 TEST_F(PasswordFormManagerTest, TestSendNotBlacklistedMessage) {
543 base::MessageLoop message_loop;
544
545 // A dumb password manager.
546 TestPasswordManagerClient client(profile(), NULL);
547 TestPasswordManager password_manager(&client);
548 scoped_ptr<PasswordFormManager> manager(
549 new PasswordFormManager(&password_manager,
550 &client,
551 client.GetDriver(),
552 *observed_form(),
553 false));
554
555 // First time sign up attempt; No login result is found from password store;
556 // We should send the not blacklisted message.
557 EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
558 .Times(1);
559 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
560 std::vector<PasswordForm*> result;
561 SimulateResponseFromPasswordStore(manager.get(), result);
562 Mock::VerifyAndClearExpectations(client.GetMockDriver());
563
564 // Sign up attempt to previously visited sites; Login result is found from
565 // password store, and is not blacklisted; We should send the not blacklisted
566 // message.
567 manager.reset(new PasswordFormManager(&password_manager,
568 &client,
569 client.GetDriver(),
570 *observed_form(),
571 false));
572 EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
573 .Times(1);
574 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
575 // We need add heap allocated objects to result.
576 result.push_back(CreateSavedMatch(false));
577 SimulateResponseFromPasswordStore(manager.get(), result);
578 Mock::VerifyAndClearExpectations(client.GetMockDriver());
579
580 // Sign up attempt to previously visited sites; Login result is found from
581 // password store, but is blacklisted; We should not send the not blacklisted
582 // message.
583 manager.reset(new PasswordFormManager(&password_manager,
584 &client,
585 client.GetDriver(),
586 *observed_form(),
587 false));
588 EXPECT_CALL(*client.GetMockDriver(), AllowPasswordGenerationForForm(_))
589 .Times(0);
590 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
591 result.clear();
592 result.push_back(CreateSavedMatch(true));
593 SimulateResponseFromPasswordStore(manager.get(), result);
594 Mock::VerifyAndClearExpectations(client.GetMockDriver());
595 }
596
597 TEST_F(PasswordFormManagerTest, TestForceInclusionOfGeneratedPasswords) {
598 base::MessageLoop message_loop;
599
600 TestPasswordManagerClient client(profile(), NULL);
601 TestPasswordManager password_manager(&client);
602 scoped_ptr<PasswordFormManager> manager(
603 new PasswordFormManager(&password_manager,
604 &client,
605 client.GetDriver(),
606 *observed_form(),
607 false));
608
609 // Simulate having two matches for this origin, one of which was from a form
610 // with different HTML tags for elements. Because of scoring differences,
611 // only the first form will be sent to Autofill().
612 std::vector<PasswordForm*> results;
613 results.push_back(CreateSavedMatch(false));
614 results.push_back(CreateSavedMatch(false));
615 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
616 results[1]->password_element = ASCIIToUTF16("signup_password");
617 results[1]->username_element = ASCIIToUTF16("signup_username");
618 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
619 SimulateResponseFromPasswordStore(manager.get(), results);
620 EXPECT_EQ(1u, password_manager.GetLatestBestMatches().size());
621 results.clear();
622
623 // Same thing, except this time the credentials that don't match quite as
624 // well are generated. They should now be sent to Autofill().
625 manager.reset(new PasswordFormManager(&password_manager,
626 &client,
627 client.GetDriver(),
628 *observed_form(),
629 false));
630 results.push_back(CreateSavedMatch(false));
631 results.push_back(CreateSavedMatch(false));
632 results[1]->username_value = ASCIIToUTF16("other@gmail.com");
633 results[1]->password_element = ASCIIToUTF16("signup_password");
634 results[1]->username_element = ASCIIToUTF16("signup_username");
635 results[1]->type = PasswordForm::TYPE_GENERATED;
636 SimulateFetchMatchingLoginsFromPasswordStore(manager.get());
637 SimulateResponseFromPasswordStore(manager.get(), results);
638 EXPECT_EQ(2u, password_manager.GetLatestBestMatches().size());
639 }
640
641 TEST_F(PasswordFormManagerTest, TestSanitizePossibleUsernames) {
642 scoped_ptr<TestPasswordManagerClient> client(
643 new TestPasswordManagerClient(profile(), NULL));
644 scoped_ptr<MockPasswordManagerDriver> driver;
645 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
646 NULL, client.get(), driver.get(), *observed_form(), false));
647 PasswordForm credentials(*observed_form());
648 credentials.other_possible_usernames.push_back(ASCIIToUTF16("543-43-1234"));
649 credentials.other_possible_usernames.push_back(
650 ASCIIToUTF16("378282246310005"));
651 credentials.other_possible_usernames.push_back(
652 ASCIIToUTF16("other username"));
653 credentials.username_value = ASCIIToUTF16("test@gmail.com");
654
655 SanitizePossibleUsernames(manager.get(), &credentials);
656
657 // Possible credit card number and SSN are stripped.
658 std::vector<base::string16> expected;
659 expected.push_back(ASCIIToUTF16("other username"));
660 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
661
662 credentials.other_possible_usernames.clear();
663 credentials.other_possible_usernames.push_back(ASCIIToUTF16("511-32-9830"));
664 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
665 credentials.other_possible_usernames.push_back(ASCIIToUTF16("duplicate"));
666 credentials.other_possible_usernames.push_back(ASCIIToUTF16("random"));
667 credentials.other_possible_usernames.push_back(
668 ASCIIToUTF16("test@gmail.com"));
669
670 SanitizePossibleUsernames(manager.get(), &credentials);
671
672 // SSN, duplicate in |other_possible_usernames| and duplicate of
673 // |username_value| all removed.
674 expected.clear();
675 expected.push_back(ASCIIToUTF16("duplicate"));
676 expected.push_back(ASCIIToUTF16("random"));
677 EXPECT_THAT(credentials.other_possible_usernames, Eq(expected));
678 }
679
680 TEST_F(PasswordFormManagerTest, TestUpdateIncompleteCredentials) {
681 InitializeMockStore();
682
683 // We've found this form on a website:
684 PasswordForm encountered_form;
685 encountered_form.origin = GURL("http://accounts.google.com/LoginAuth");
686 encountered_form.signon_realm = "http://accounts.google.com/";
687 encountered_form.action = GURL("http://accounts.google.com/Login");
688 encountered_form.username_element = ASCIIToUTF16("Email");
689 encountered_form.password_element = ASCIIToUTF16("Passwd");
690 encountered_form.submit_element = ASCIIToUTF16("signIn");
691
692 TestPasswordManagerClient client(profile(), mock_store());
693 MockPasswordManagerDriver driver;
694 EXPECT_CALL(driver, IsOffTheRecord()).WillRepeatedly(Return(false));
695 EXPECT_CALL(driver, AllowPasswordGenerationForForm(_));
696
697 TestPasswordManager manager(&client);
698 PasswordFormManager form_manager(&manager,
699 &client,
700 &driver,
701 encountered_form,
702 false);
703
704 const PasswordStore::AuthorizationPromptPolicy auth_policy =
705 PasswordStore::DISALLOW_PROMPT;
706 EXPECT_CALL(*mock_store(), GetLogins(encountered_form,
707 auth_policy,
708 &form_manager));
709 form_manager.FetchMatchingLoginsFromPasswordStore(auth_policy);
710
711 // Password store only has these incomplete credentials.
712 PasswordForm* incomplete_form = new PasswordForm();
713 incomplete_form->origin = GURL("http://accounts.google.com/LoginAuth");
714 incomplete_form->signon_realm = "http://accounts.google.com/";
715 incomplete_form->password_value = ASCIIToUTF16("my_password");
716 incomplete_form->username_value = ASCIIToUTF16("my_username");
717 incomplete_form->preferred = true;
718 incomplete_form->ssl_valid = false;
719 incomplete_form->scheme = PasswordForm::SCHEME_HTML;
720
721 // We expect to see this form eventually sent to the Password store. It
722 // has password/username values from the store and 'username_element',
723 // 'password_element', 'submit_element' and 'action' fields copied from
724 // the encountered form.
725 PasswordForm complete_form(*incomplete_form);
726 complete_form.action = encountered_form.action;
727 complete_form.password_element = encountered_form.password_element;
728 complete_form.username_element = encountered_form.username_element;
729 complete_form.submit_element = encountered_form.submit_element;
730
731 // Feed the incomplete credentials to the manager.
732 std::vector<PasswordForm*> results;
733 results.push_back(incomplete_form); // Takes ownership.
734 form_manager.OnRequestDone(results);
735
736 form_manager.ProvisionallySave(
737 complete_form, PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES);
738 // By now that form has been used once.
739 complete_form.times_used = 1;
740
741 // Check that PasswordStore receives an update request with the complete form.
742 EXPECT_CALL(*mock_store(), UpdateLogin(complete_form));
743 form_manager.Save();
744 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698