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 <vector>
6
7 #include "base/message_loop/message_loop.h"
8 #include "base/prefs/pref_registry_simple.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "components/password_manager/core/browser/mock_password_store.h"
14 #include "components/password_manager/core/browser/password_autofill_manager.h"
15 #include "components/password_manager/core/browser/password_manager.h"
16 #include "components/password_manager/core/browser/password_manager_driver.h"
17 #include "components/password_manager/core/browser/password_store.h"
18 #include "components/password_manager/core/browser/stub_password_manager_client.h"
19 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
20 #include "components/password_manager/core/common/password_manager_pref_names.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 class PasswordGenerationManager;
25
26 using autofill::PasswordForm;
27 using base::ASCIIToUTF16;
28 using testing::_;
29 using testing::AnyNumber;
30 using testing::DoAll;
31 using testing::Exactly;
32 using testing::Return;
33 using testing::WithArg;
34
35 namespace autofill {
36 class AutofillManager;
37 }
38
39 namespace password_manager {
40
41 namespace {
42
43 class MockPasswordManagerClient : public StubPasswordManagerClient {
44 public:
45 MOCK_METHOD1(PromptUserToSavePassword, void(PasswordFormManager*));
46 MOCK_METHOD0(GetPasswordStore, PasswordStore*());
47 MOCK_METHOD0(GetPrefs, PrefService*());
48 MOCK_METHOD0(GetDriver, PasswordManagerDriver*());
49 };
50
51 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
52 public:
53 MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&));
54 MOCK_METHOD0(GetPasswordManager, PasswordManager*());
55 MOCK_METHOD0(GetPasswordAutofillManager, PasswordAutofillManager*());
56 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
57 };
58
ACTION_P(InvokeConsumer,forms)59 ACTION_P(InvokeConsumer, forms) { arg0->OnGetPasswordStoreResults(forms); }
60
ACTION_P(SaveToScopedPtr,scoped)61 ACTION_P(SaveToScopedPtr, scoped) { scoped->reset(arg0); }
62
63 class TestPasswordManager : public PasswordManager {
64 public:
TestPasswordManager(PasswordManagerClient * client)65 explicit TestPasswordManager(PasswordManagerClient* client)
66 : PasswordManager(client) {}
~TestPasswordManager()67 virtual ~TestPasswordManager() {}
68
69 private:
70 DISALLOW_COPY_AND_ASSIGN(TestPasswordManager);
71 };
72
73 } // namespace
74
75 class PasswordManagerTest : public testing::Test {
76 protected:
SetUp()77 virtual void SetUp() {
78 prefs_.registry()->RegisterBooleanPref(prefs::kPasswordManagerEnabled,
79 true);
80
81 store_ = new MockPasswordStore;
82 EXPECT_CALL(*store_, ReportMetrics()).Times(AnyNumber());
83 CHECK(store_->Init(syncer::SyncableService::StartSyncFlare()));
84
85 EXPECT_CALL(client_, GetPasswordStore()).WillRepeatedly(Return(store_));
86 EXPECT_CALL(client_, GetPrefs()).WillRepeatedly(Return(&prefs_));
87 EXPECT_CALL(client_, GetDriver()).WillRepeatedly(Return(&driver_));
88
89 manager_.reset(new TestPasswordManager(&client_));
90 password_autofill_manager_.reset(
91 new PasswordAutofillManager(&client_, NULL));
92
93 EXPECT_CALL(driver_, GetPasswordManager())
94 .WillRepeatedly(Return(manager_.get()));
95 EXPECT_CALL(driver_, GetPasswordAutofillManager())
96 .WillRepeatedly(Return(password_autofill_manager_.get()));
97 }
98
TearDown()99 virtual void TearDown() {
100 store_->Shutdown();
101 store_ = NULL;
102 }
103
MakeSimpleForm()104 PasswordForm MakeSimpleForm() {
105 PasswordForm form;
106 form.origin = GURL("http://www.google.com/a/LoginAuth");
107 form.action = GURL("http://www.google.com/a/Login");
108 form.username_element = ASCIIToUTF16("Email");
109 form.password_element = ASCIIToUTF16("Passwd");
110 form.username_value = ASCIIToUTF16("google");
111 form.password_value = ASCIIToUTF16("password");
112 // Default to true so we only need to add tests in autocomplete=off cases.
113 form.password_autocomplete_set = true;
114 form.submit_element = ASCIIToUTF16("signIn");
115 form.signon_realm = "http://www.google.com";
116 return form;
117 }
118
119 // Reproduction of the form present on twitter's login page.
MakeTwitterLoginForm()120 PasswordForm MakeTwitterLoginForm() {
121 PasswordForm form;
122 form.origin = GURL("https://twitter.com/");
123 form.action = GURL("https://twitter.com/sessions");
124 form.username_element = ASCIIToUTF16("Email");
125 form.password_element = ASCIIToUTF16("Passwd");
126 form.username_value = ASCIIToUTF16("twitter");
127 form.password_value = ASCIIToUTF16("password");
128 form.password_autocomplete_set = true;
129 form.submit_element = ASCIIToUTF16("signIn");
130 form.signon_realm = "https://twitter.com";
131 return form;
132 }
133
134 // Reproduction of the form present on twitter's failed login page.
MakeTwitterFailedLoginForm()135 PasswordForm MakeTwitterFailedLoginForm() {
136 PasswordForm form;
137 form.origin = GURL("https://twitter.com/login/error?redirect_after_login");
138 form.action = GURL("https://twitter.com/sessions");
139 form.username_element = ASCIIToUTF16("EmailField");
140 form.password_element = ASCIIToUTF16("PasswdField");
141 form.username_value = ASCIIToUTF16("twitter");
142 form.password_value = ASCIIToUTF16("password");
143 form.password_autocomplete_set = true;
144 form.submit_element = ASCIIToUTF16("signIn");
145 form.signon_realm = "https://twitter.com";
146 return form;
147 }
148
FormsAreEqual(const autofill::PasswordForm & lhs,const autofill::PasswordForm & rhs)149 bool FormsAreEqual(const autofill::PasswordForm& lhs,
150 const autofill::PasswordForm& rhs) {
151 if (lhs.origin != rhs.origin)
152 return false;
153 if (lhs.action != rhs.action)
154 return false;
155 if (lhs.username_element != rhs.username_element)
156 return false;
157 if (lhs.password_element != rhs.password_element)
158 return false;
159 if (lhs.username_value != rhs.username_value)
160 return false;
161 if (lhs.password_value != rhs.password_value)
162 return false;
163 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
164 return false;
165 if (lhs.submit_element != rhs.submit_element)
166 return false;
167 if (lhs.signon_realm != rhs.signon_realm)
168 return false;
169 return true;
170 }
171
manager()172 TestPasswordManager* manager() { return manager_.get(); }
173
OnPasswordFormSubmitted(const autofill::PasswordForm & form)174 void OnPasswordFormSubmitted(const autofill::PasswordForm& form) {
175 manager()->OnPasswordFormSubmitted(form);
176 }
177
SubmissionCallback()178 PasswordManager::PasswordSubmittedCallback SubmissionCallback() {
179 return base::Bind(&PasswordManagerTest::FormSubmitted,
180 base::Unretained(this));
181 }
182
FormSubmitted(const autofill::PasswordForm & form)183 void FormSubmitted(const autofill::PasswordForm& form) {
184 submitted_form_ = form;
185 }
186
187 TestingPrefServiceSimple prefs_;
188 scoped_refptr<MockPasswordStore> store_;
189 MockPasswordManagerClient client_;
190 MockPasswordManagerDriver driver_;
191 scoped_ptr<PasswordAutofillManager> password_autofill_manager_;
192 scoped_ptr<TestPasswordManager> manager_;
193 PasswordForm submitted_form_;
194 };
195
196 MATCHER_P(FormMatches, form, "") {
197 return form.signon_realm == arg.signon_realm && form.origin == arg.origin &&
198 form.action == arg.action &&
199 form.username_element == arg.username_element &&
200 form.password_element == arg.password_element &&
201 form.password_autocomplete_set == arg.password_autocomplete_set &&
202 form.submit_element == arg.submit_element;
203 }
204
TEST_F(PasswordManagerTest,FormSubmitEmptyStore)205 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
206 // Test that observing a newly submitted form shows the save password bar.
207 std::vector<PasswordForm*> result; // Empty password store.
208 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
209 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
210 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
211 std::vector<PasswordForm> observed;
212 PasswordForm form(MakeSimpleForm());
213 observed.push_back(form);
214 manager()->OnPasswordFormsParsed(observed); // The initial load.
215 manager()->OnPasswordFormsRendered(observed); // The initial layout.
216
217 // And the form submit contract is to call ProvisionallySavePassword.
218 manager()->ProvisionallySavePassword(form);
219
220 scoped_ptr<PasswordFormManager> form_to_save;
221 EXPECT_CALL(client_, PromptUserToSavePassword(_))
222 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
223
224 // Now the password manager waits for the navigation to complete.
225 observed.clear();
226 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
227 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
228
229 ASSERT_TRUE(form_to_save.get());
230 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
231
232 // Simulate saving the form, as if the info bar was accepted.
233 form_to_save->Save();
234 }
235
TEST_F(PasswordManagerTest,GeneratedPasswordFormSubmitEmptyStore)236 TEST_F(PasswordManagerTest, GeneratedPasswordFormSubmitEmptyStore) {
237 // This test is the same FormSubmitEmptyStore, except that it simulates the
238 // user generating the password through the browser.
239 std::vector<PasswordForm*> result; // Empty password store.
240 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
241 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
242 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
243 std::vector<PasswordForm> observed;
244 PasswordForm form(MakeSimpleForm());
245 observed.push_back(form);
246 manager()->OnPasswordFormsParsed(observed); // The initial load.
247 manager()->OnPasswordFormsRendered(observed); // The initial layout.
248
249 // Simulate the user generating the password and submitting the form.
250 manager()->SetFormHasGeneratedPassword(form);
251 manager()->ProvisionallySavePassword(form);
252
253 // The user should not be presented with an infobar as they have already given
254 // consent by using the generated password. The form should be saved once
255 // navigation occurs.
256 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
257 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
258
259 // Now the password manager waits for the navigation to complete.
260 observed.clear();
261 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
262 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
263 }
264
TEST_F(PasswordManagerTest,FormSubmitNoGoodMatch)265 TEST_F(PasswordManagerTest, FormSubmitNoGoodMatch) {
266 // Same as above, except with an existing form for the same signon realm,
267 // but different origin. Detailed cases like this are covered by
268 // PasswordFormManagerTest.
269 std::vector<PasswordForm*> result;
270 PasswordForm* existing_different = new PasswordForm(MakeSimpleForm());
271 existing_different->username_value = ASCIIToUTF16("google2");
272 result.push_back(existing_different);
273 EXPECT_CALL(driver_, FillPasswordForm(_));
274 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
275 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
276
277 std::vector<PasswordForm> observed;
278 PasswordForm form(MakeSimpleForm());
279 observed.push_back(form);
280 manager()->OnPasswordFormsParsed(observed); // The initial load.
281 manager()->OnPasswordFormsRendered(observed); // The initial layout.
282 manager()->ProvisionallySavePassword(form);
283
284 // We still expect an add, since we didn't have a good match.
285 scoped_ptr<PasswordFormManager> form_to_save;
286 EXPECT_CALL(client_, PromptUserToSavePassword(_))
287 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
288
289 // Now the password manager waits for the navigation to complete.
290 observed.clear();
291 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
292 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
293
294 ASSERT_TRUE(form_to_save.get());
295 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
296
297 // Simulate saving the form.
298 form_to_save->Save();
299 }
300
TEST_F(PasswordManagerTest,FormSeenThenLeftPage)301 TEST_F(PasswordManagerTest, FormSeenThenLeftPage) {
302 std::vector<PasswordForm*> result; // Empty password store.
303 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
304 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
305 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
306 std::vector<PasswordForm> observed;
307 PasswordForm form(MakeSimpleForm());
308 observed.push_back(form);
309 manager()->OnPasswordFormsParsed(observed); // The initial load.
310 manager()->OnPasswordFormsRendered(observed); // The initial layout.
311
312 // No message from the renderer that a password was submitted. No
313 // expected calls.
314 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(0);
315 observed.clear();
316 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
317 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
318 }
319
TEST_F(PasswordManagerTest,FormSubmitAfterNavigateInPage)320 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateInPage) {
321 // Test that navigating in the page does not prevent us from showing the save
322 // password infobar.
323 std::vector<PasswordForm*> result; // Empty password store.
324 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
325 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
326 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
327 std::vector<PasswordForm> observed;
328 PasswordForm form(MakeSimpleForm());
329 observed.push_back(form);
330 manager()->OnPasswordFormsParsed(observed); // The initial load.
331 manager()->OnPasswordFormsRendered(observed); // The initial layout.
332
333 // Simulate navigating in the page.
334 manager()->DidNavigateMainFrame(true);
335
336 // Simulate submitting the password.
337 OnPasswordFormSubmitted(form);
338
339 // Now the password manager waits for the navigation to complete.
340 scoped_ptr<PasswordFormManager> form_to_save;
341 EXPECT_CALL(client_, PromptUserToSavePassword(_))
342 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
343
344 observed.clear();
345 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
346 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
347
348 ASSERT_FALSE(NULL == form_to_save.get());
349 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
350
351 // Simulate saving the form, as if the info bar was accepted.
352 form_to_save->Save();
353 }
354
355 // This test verifies a fix for http://crbug.com/236673
TEST_F(PasswordManagerTest,FormSubmitWithFormOnPreviousPage)356 TEST_F(PasswordManagerTest, FormSubmitWithFormOnPreviousPage) {
357 std::vector<PasswordForm*> result; // Empty password store.
358 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
359 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
360 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
361 PasswordForm first_form(MakeSimpleForm());
362 first_form.origin = GURL("http://www.nytimes.com/");
363 first_form.action = GURL("https://myaccount.nytimes.com/auth/login");
364 first_form.signon_realm = "http://www.nytimes.com/";
365 PasswordForm second_form(MakeSimpleForm());
366 second_form.origin = GURL("https://myaccount.nytimes.com/auth/login");
367 second_form.action = GURL("https://myaccount.nytimes.com/auth/login");
368 second_form.signon_realm = "https://myaccount.nytimes.com/";
369
370 // Pretend that the form is hidden on the first page.
371 std::vector<PasswordForm> observed;
372 observed.push_back(first_form);
373 manager()->OnPasswordFormsParsed(observed);
374 observed.clear();
375 manager()->OnPasswordFormsRendered(observed);
376
377 // Now navigate to a second page.
378 manager()->DidNavigateMainFrame(false);
379
380 // This page contains a form with the same markup, but on a different
381 // URL.
382 observed.push_back(second_form);
383 manager()->OnPasswordFormsParsed(observed);
384 manager()->OnPasswordFormsRendered(observed);
385
386 // Now submit this form
387 OnPasswordFormSubmitted(second_form);
388
389 // Navigation after form submit.
390 scoped_ptr<PasswordFormManager> form_to_save;
391 EXPECT_CALL(client_, PromptUserToSavePassword(_))
392 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
393 observed.clear();
394 manager()->OnPasswordFormsParsed(observed);
395 manager()->OnPasswordFormsRendered(observed);
396
397 // Make sure that the saved form matches the second form, not the first.
398 ASSERT_TRUE(form_to_save.get());
399 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(second_form)));
400
401 // Simulate saving the form, as if the info bar was accepted.
402 form_to_save->Save();
403 }
404
TEST_F(PasswordManagerTest,FormSubmitFailedLogin)405 TEST_F(PasswordManagerTest, FormSubmitFailedLogin) {
406 std::vector<PasswordForm*> result; // Empty password store.
407 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
408 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
409 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
410 std::vector<PasswordForm> observed;
411 PasswordForm form(MakeSimpleForm());
412 observed.push_back(form);
413 manager()->OnPasswordFormsParsed(observed); // The initial load.
414 manager()->OnPasswordFormsRendered(observed); // The initial layout.
415
416 manager()->ProvisionallySavePassword(form);
417
418 // The form reappears, and is visible in the layout:
419 // No expected calls to the PasswordStore...
420 manager()->OnPasswordFormsParsed(observed);
421 manager()->OnPasswordFormsRendered(observed);
422 }
423
TEST_F(PasswordManagerTest,FormSubmitInvisibleLogin)424 TEST_F(PasswordManagerTest, FormSubmitInvisibleLogin) {
425 // Tests fix of issue 28911: if the login form reappears on the subsequent
426 // page, but is invisible, it shouldn't count as a failed login.
427 std::vector<PasswordForm*> result; // Empty password store.
428 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
429 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
430 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
431 std::vector<PasswordForm> observed;
432 PasswordForm form(MakeSimpleForm());
433 observed.push_back(form);
434 manager()->OnPasswordFormsParsed(observed); // The initial load.
435 manager()->OnPasswordFormsRendered(observed); // The initial layout.
436
437 manager()->ProvisionallySavePassword(form);
438
439 // Expect info bar to appear:
440 scoped_ptr<PasswordFormManager> form_to_save;
441 EXPECT_CALL(client_, PromptUserToSavePassword(_))
442 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save)));
443
444 // The form reappears, but is not visible in the layout:
445 manager()->OnPasswordFormsParsed(observed);
446 observed.clear();
447 manager()->OnPasswordFormsRendered(observed);
448
449 ASSERT_TRUE(form_to_save.get());
450 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
451
452 // Simulate saving the form.
453 form_to_save->Save();
454 }
455
TEST_F(PasswordManagerTest,InitiallyInvisibleForm)456 TEST_F(PasswordManagerTest, InitiallyInvisibleForm) {
457 // Make sure an invisible login form still gets autofilled.
458 std::vector<PasswordForm*> result;
459 PasswordForm* existing = new PasswordForm(MakeSimpleForm());
460 result.push_back(existing);
461 EXPECT_CALL(driver_, FillPasswordForm(_));
462 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
463 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
464 std::vector<PasswordForm> observed;
465 PasswordForm form(MakeSimpleForm());
466 observed.push_back(form);
467 manager()->OnPasswordFormsParsed(observed); // The initial load.
468 observed.clear();
469 manager()->OnPasswordFormsRendered(observed); // The initial layout.
470
471 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
472 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
473 }
474
TEST_F(PasswordManagerTest,SavingDependsOnManagerEnabledPreference)475 TEST_F(PasswordManagerTest, SavingDependsOnManagerEnabledPreference) {
476 // Test that saving passwords depends on the password manager enabled
477 // preference.
478 prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
479 base::Value::CreateBooleanValue(true));
480 EXPECT_TRUE(manager()->IsSavingEnabledForCurrentPage());
481 prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
482 base::Value::CreateBooleanValue(false));
483 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
484 }
485
TEST_F(PasswordManagerTest,FillPasswordsOnDisabledManager)486 TEST_F(PasswordManagerTest, FillPasswordsOnDisabledManager) {
487 // Test fix for issue 158296: Passwords must be filled even if the password
488 // manager is disabled.
489 std::vector<PasswordForm*> result;
490 PasswordForm* existing = new PasswordForm(MakeSimpleForm());
491 result.push_back(existing);
492 prefs_.SetUserPref(prefs::kPasswordManagerEnabled,
493 base::Value::CreateBooleanValue(false));
494 EXPECT_CALL(driver_, FillPasswordForm(_));
495 EXPECT_CALL(*store_.get(),
496 GetLogins(_, testing::Eq(PasswordStore::DISALLOW_PROMPT), _))
497 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
498 std::vector<PasswordForm> observed;
499 PasswordForm form(MakeSimpleForm());
500 observed.push_back(form);
501 manager()->OnPasswordFormsParsed(observed);
502 }
503
TEST_F(PasswordManagerTest,FormSavedWithAutocompleteOff)504 TEST_F(PasswordManagerTest, FormSavedWithAutocompleteOff) {
505 // Test password form with non-generated password will be saved even if
506 // autocomplete=off.
507 std::vector<PasswordForm*> result; // Empty password store.
508 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
509 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
510 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
511 std::vector<PasswordForm> observed;
512 PasswordForm form(MakeSimpleForm());
513 form.password_autocomplete_set = false;
514 observed.push_back(form);
515 manager()->OnPasswordFormsParsed(observed); // The initial load.
516 manager()->OnPasswordFormsRendered(observed); // The initial layout.
517
518 // And the form submit contract is to call ProvisionallySavePassword.
519 manager()->ProvisionallySavePassword(form);
520
521 // Password form should be saved.
522 scoped_ptr<PasswordFormManager> form_to_save;
523 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(1)).WillOnce(
524 WithArg<0>(SaveToScopedPtr(&form_to_save)));
525 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))).Times(Exactly(0));
526
527 // Now the password manager waits for the navigation to complete.
528 observed.clear();
529 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
530 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
531
532 ASSERT_TRUE(form_to_save.get());
533 }
534
TEST_F(PasswordManagerTest,GeneratedPasswordFormSavedAutocompleteOff)535 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
536 // Test password form with generated password will still be saved if
537 // autocomplete=off.
538 std::vector<PasswordForm*> result; // Empty password store.
539 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(Exactly(0));
540 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
541 .WillOnce(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
542 std::vector<PasswordForm> observed;
543 PasswordForm form(MakeSimpleForm());
544 form.password_autocomplete_set = false;
545 observed.push_back(form);
546 manager()->OnPasswordFormsParsed(observed); // The initial load.
547 manager()->OnPasswordFormsRendered(observed); // The initial layout.
548
549 // Simulate the user generating the password and submitting the form.
550 manager()->SetFormHasGeneratedPassword(form);
551 manager()->ProvisionallySavePassword(form);
552
553 // The user should not be presented with an infobar as they have already given
554 // consent by using the generated password. The form should be saved once
555 // navigation occurs.
556 EXPECT_CALL(client_, PromptUserToSavePassword(_)).Times(Exactly(0));
557 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
558
559 // Now the password manager waits for the navigation to complete.
560 observed.clear();
561 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
562 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
563 }
564
TEST_F(PasswordManagerTest,SubmissionCallbackTest)565 TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
566 manager()->AddSubmissionCallback(SubmissionCallback());
567 PasswordForm form = MakeSimpleForm();
568 OnPasswordFormSubmitted(form);
569 EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
570 }
571
TEST_F(PasswordManagerTest,PasswordFormReappearance)572 TEST_F(PasswordManagerTest, PasswordFormReappearance) {
573 // Test the heuristic to know if a password form reappears.
574 // We assume that if we send our credentials and there
575 // is at least one visible password form in the next page that
576 // means that our previous login attempt failed.
577 std::vector<PasswordForm*> result; // Empty password store.
578 EXPECT_CALL(driver_, FillPasswordForm(_)).Times(0);
579 EXPECT_CALL(*store_.get(), GetLogins(_, _, _))
580 .WillRepeatedly(DoAll(WithArg<2>(InvokeConsumer(result)), Return()));
581 std::vector<PasswordForm> observed;
582 PasswordForm login_form(MakeTwitterLoginForm());
583 observed.push_back(login_form);
584 manager()->OnPasswordFormsParsed(observed); // The initial load.
585 manager()->OnPasswordFormsRendered(observed); // The initial layout.
586
587 manager()->ProvisionallySavePassword(login_form);
588
589 PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
590 observed.clear();
591 observed.push_back(failed_login_form);
592 // A PasswordForm appears, and is visible in the layout:
593 // No expected calls to the PasswordStore...
594 manager()->OnPasswordFormsParsed(observed);
595 manager()->OnPasswordFormsRendered(observed);
596 }
597
TEST_F(PasswordManagerTest,SavingNotEnabledOnSSLErrors)598 TEST_F(PasswordManagerTest, SavingNotEnabledOnSSLErrors) {
599 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
600 .WillRepeatedly(Return(true));
601 EXPECT_FALSE(manager()->IsSavingEnabledForCurrentPage());
602 }
603
TEST_F(PasswordManagerTest,AutofillingNotEnabledOnSSLErrors)604 TEST_F(PasswordManagerTest, AutofillingNotEnabledOnSSLErrors) {
605 // Test that in the presence of SSL errors, the password manager does not
606 // attempt to autofill forms found on a website.
607 EXPECT_CALL(driver_, DidLastPageLoadEncounterSSLErrors())
608 .WillRepeatedly(Return(true));
609
610 // Let us pretend some forms were found on a website.
611 std::vector<PasswordForm> forms;
612 forms.push_back(MakeSimpleForm());
613
614 // Feed those forms to |manager()| and check that it does not try to find
615 // matching saved credentials for the forms.
616 EXPECT_CALL(*store_.get(), GetLogins(_, _, _)).Times(Exactly(0));
617 manager()->OnPasswordFormsParsed(forms);
618 }
619
620 } // namespace password_manager
621