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

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

Issue 103503002: Ignore autocomplete='off' for usernames and passwords. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Nits from gcasto Created 7 years 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <vector> 5 #include <vector>
6 6
7 #include "base/message_loop/message_loop.h" 7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/password_manager/mock_password_store.h" 10 #include "chrome/browser/password_manager/mock_password_store.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 95
96 PasswordForm MakeSimpleForm() { 96 PasswordForm MakeSimpleForm() {
97 PasswordForm form; 97 PasswordForm form;
98 form.origin = GURL("http://www.google.com/a/LoginAuth"); 98 form.origin = GURL("http://www.google.com/a/LoginAuth");
99 form.action = GURL("http://www.google.com/a/Login"); 99 form.action = GURL("http://www.google.com/a/Login");
100 form.username_element = ASCIIToUTF16("Email"); 100 form.username_element = ASCIIToUTF16("Email");
101 form.password_element = ASCIIToUTF16("Passwd"); 101 form.password_element = ASCIIToUTF16("Passwd");
102 form.username_value = ASCIIToUTF16("google"); 102 form.username_value = ASCIIToUTF16("google");
103 form.password_value = ASCIIToUTF16("password"); 103 form.password_value = ASCIIToUTF16("password");
104 // Default to true so we only need to add tests in autocomplete=off cases.
105 form.password_autocomplete_set = true;
106 form.submit_element = ASCIIToUTF16("signIn"); 104 form.submit_element = ASCIIToUTF16("signIn");
107 form.signon_realm = "http://www.google.com"; 105 form.signon_realm = "http://www.google.com";
108 return form; 106 return form;
109 } 107 }
110 108
111 // Reproduction of the form present on twitter's login page. 109 // Reproduction of the form present on twitter's login page.
112 PasswordForm MakeTwitterLoginForm() { 110 PasswordForm MakeTwitterLoginForm() {
113 PasswordForm form; 111 PasswordForm form;
114 form.origin = GURL("https://twitter.com/"); 112 form.origin = GURL("https://twitter.com/");
115 form.action = GURL("https://twitter.com/sessions"); 113 form.action = GURL("https://twitter.com/sessions");
116 form.username_element = ASCIIToUTF16("Email"); 114 form.username_element = ASCIIToUTF16("Email");
117 form.password_element = ASCIIToUTF16("Passwd"); 115 form.password_element = ASCIIToUTF16("Passwd");
118 form.username_value = ASCIIToUTF16("twitter"); 116 form.username_value = ASCIIToUTF16("twitter");
119 form.password_value = ASCIIToUTF16("password"); 117 form.password_value = ASCIIToUTF16("password");
120 form.password_autocomplete_set = true;
121 form.submit_element = ASCIIToUTF16("signIn"); 118 form.submit_element = ASCIIToUTF16("signIn");
122 form.signon_realm = "https://twitter.com"; 119 form.signon_realm = "https://twitter.com";
123 return form; 120 return form;
124 } 121 }
125 122
126 // Reproduction of the form present on twitter's failed login page. 123 // Reproduction of the form present on twitter's failed login page.
127 PasswordForm MakeTwitterFailedLoginForm() { 124 PasswordForm MakeTwitterFailedLoginForm() {
128 PasswordForm form; 125 PasswordForm form;
129 form.origin = 126 form.origin =
130 GURL("https://twitter.com/login/error?redirect_after_login"); 127 GURL("https://twitter.com/login/error?redirect_after_login");
131 form.action = GURL("https://twitter.com/sessions"); 128 form.action = GURL("https://twitter.com/sessions");
132 form.username_element = ASCIIToUTF16("EmailField"); 129 form.username_element = ASCIIToUTF16("EmailField");
133 form.password_element = ASCIIToUTF16("PasswdField"); 130 form.password_element = ASCIIToUTF16("PasswdField");
134 form.username_value = ASCIIToUTF16("twitter"); 131 form.username_value = ASCIIToUTF16("twitter");
135 form.password_value = ASCIIToUTF16("password"); 132 form.password_value = ASCIIToUTF16("password");
136 form.password_autocomplete_set = true;
137 form.submit_element = ASCIIToUTF16("signIn"); 133 form.submit_element = ASCIIToUTF16("signIn");
138 form.signon_realm = "https://twitter.com"; 134 form.signon_realm = "https://twitter.com";
139 return form; 135 return form;
140 } 136 }
141 137
142 bool FormsAreEqual(const autofill::PasswordForm& lhs, 138 bool FormsAreEqual(const autofill::PasswordForm& lhs,
143 const autofill::PasswordForm& rhs) { 139 const autofill::PasswordForm& rhs) {
144 if (lhs.origin != rhs.origin) 140 if (lhs.origin != rhs.origin)
145 return false; 141 return false;
146 if (lhs.action != rhs.action) 142 if (lhs.action != rhs.action)
147 return false; 143 return false;
148 if (lhs.username_element != rhs.username_element) 144 if (lhs.username_element != rhs.username_element)
149 return false; 145 return false;
150 if (lhs.password_element != rhs.password_element) 146 if (lhs.password_element != rhs.password_element)
151 return false; 147 return false;
152 if (lhs.username_value != rhs.username_value) 148 if (lhs.username_value != rhs.username_value)
153 return false; 149 return false;
154 if (lhs.password_value != rhs.password_value) 150 if (lhs.password_value != rhs.password_value)
155 return false; 151 return false;
156 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set)
157 return false;
158 if (lhs.submit_element != rhs.submit_element) 152 if (lhs.submit_element != rhs.submit_element)
159 return false; 153 return false;
160 if (lhs.signon_realm != rhs.signon_realm) 154 if (lhs.signon_realm != rhs.signon_realm)
161 return false; 155 return false;
162 return true; 156 return true;
163 } 157 }
164 158
165 TestPasswordManager* manager() { 159 TestPasswordManager* manager() {
166 return manager_; 160 return manager_;
167 } 161 }
(...skipping 16 matching lines...) Expand all
184 MockPasswordManagerDelegate delegate_; // Owned by manager_. 178 MockPasswordManagerDelegate delegate_; // Owned by manager_.
185 PasswordForm submitted_form_; 179 PasswordForm submitted_form_;
186 }; 180 };
187 181
188 MATCHER_P(FormMatches, form, "") { 182 MATCHER_P(FormMatches, form, "") {
189 return form.signon_realm == arg.signon_realm && 183 return form.signon_realm == arg.signon_realm &&
190 form.origin == arg.origin && 184 form.origin == arg.origin &&
191 form.action == arg.action && 185 form.action == arg.action &&
192 form.username_element == arg.username_element && 186 form.username_element == arg.username_element &&
193 form.password_element == arg.password_element && 187 form.password_element == arg.password_element &&
194 form.password_autocomplete_set ==
195 arg.password_autocomplete_set &&
196 form.submit_element == arg.submit_element; 188 form.submit_element == arg.submit_element;
197 } 189 }
198 190
199 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) { 191 TEST_F(PasswordManagerTest, FormSubmitEmptyStore) {
200 // Test that observing a newly submitted form shows the save password bar. 192 // Test that observing a newly submitted form shows the save password bar.
201 std::vector<PasswordForm*> result; // Empty password store. 193 std::vector<PasswordForm*> result; // Empty password store.
202 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); 194 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
203 EXPECT_CALL(*store_.get(), GetLogins(_, _)) 195 EXPECT_CALL(*store_.get(), GetLogins(_, _))
204 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); 196 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
205 std::vector<PasswordForm> observed; 197 std::vector<PasswordForm> observed;
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 Value::CreateBooleanValue(false)); 487 Value::CreateBooleanValue(false));
496 EXPECT_CALL(delegate_, FillPasswordForm(_)); 488 EXPECT_CALL(delegate_, FillPasswordForm(_));
497 EXPECT_CALL(*store_.get(), GetLogins(_, _)) 489 EXPECT_CALL(*store_.get(), GetLogins(_, _))
498 .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); 490 .WillRepeatedly(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
499 std::vector<PasswordForm> observed; 491 std::vector<PasswordForm> observed;
500 PasswordForm form(MakeSimpleForm()); 492 PasswordForm form(MakeSimpleForm());
501 observed.push_back(form); 493 observed.push_back(form);
502 manager()->OnPasswordFormsParsed(observed); 494 manager()->OnPasswordFormsParsed(observed);
503 } 495 }
504 496
505 TEST_F(PasswordManagerTest, FormNotSavedAutocompleteOff) {
506 // Test password form with non-generated password will not be saved if
507 // autocomplete=off.
508 std::vector<PasswordForm*> result; // Empty password store.
509 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
510 EXPECT_CALL(*store_.get(), GetLogins(_, _))
511 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
512 std::vector<PasswordForm> observed;
513 PasswordForm form(MakeSimpleForm());
514 form.password_autocomplete_set = false;
515 observed.push_back(form);
516 manager()->OnPasswordFormsParsed(observed); // The initial load.
517 manager()->OnPasswordFormsRendered(observed); // The initial layout.
518
519 // And the form submit contract is to call ProvisionallySavePassword.
520 manager()->ProvisionallySavePassword(form);
521
522 // Password form should not be saved.
523 EXPECT_CALL(delegate_,
524 AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0));
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
533 TEST_F(PasswordManagerTest, GeneratedPasswordFormSavedAutocompleteOff) {
534 // Test password form with generated password will still be saved if
535 // autocomplete=off.
536 std::vector<PasswordForm*> result; // Empty password store.
537 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0));
538 EXPECT_CALL(*store_.get(), GetLogins(_, _))
539 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1)));
540 std::vector<PasswordForm> observed;
541 PasswordForm form(MakeSimpleForm());
542 form.password_autocomplete_set = false;
543 observed.push_back(form);
544 manager()->OnPasswordFormsParsed(observed); // The initial load.
545 manager()->OnPasswordFormsRendered(observed); // The initial layout.
546
547 // Simulate the user generating the password and submitting the form.
548 manager()->SetFormHasGeneratedPassword(form);
549 manager()->ProvisionallySavePassword(form);
550
551 // The user should not be presented with an infobar as they have already given
552 // consent by using the generated password. The form should be saved once
553 // navigation occurs.
554 EXPECT_CALL(delegate_,
555 AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0));
556 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form)));
557
558 // Now the password manager waits for the navigation to complete.
559 observed.clear();
560 manager()->OnPasswordFormsParsed(observed); // The post-navigation load.
561 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout.
562 }
563
564 TEST_F(PasswordManagerTest, SubmissionCallbackTest) { 497 TEST_F(PasswordManagerTest, SubmissionCallbackTest) {
565 manager()->AddSubmissionCallback(SubmissionCallback()); 498 manager()->AddSubmissionCallback(SubmissionCallback());
566 PasswordForm form = MakeSimpleForm(); 499 PasswordForm form = MakeSimpleForm();
567 OnPasswordFormSubmitted(form); 500 OnPasswordFormSubmitted(form);
568 EXPECT_TRUE(FormsAreEqual(form, submitted_form_)); 501 EXPECT_TRUE(FormsAreEqual(form, submitted_form_));
569 } 502 }
570 503
571 TEST_F(PasswordManagerTest, PasswordFormReappearance) { 504 TEST_F(PasswordManagerTest, PasswordFormReappearance) {
572 // Test the heuristic to know if a password form reappears. 505 // Test the heuristic to know if a password form reappears.
573 // We assume that if we send our credentials and there 506 // We assume that if we send our credentials and there
(...skipping 12 matching lines...) Expand all
586 manager()->ProvisionallySavePassword(login_form); 519 manager()->ProvisionallySavePassword(login_form);
587 520
588 PasswordForm failed_login_form(MakeTwitterFailedLoginForm()); 521 PasswordForm failed_login_form(MakeTwitterFailedLoginForm());
589 observed.clear(); 522 observed.clear();
590 observed.push_back(failed_login_form); 523 observed.push_back(failed_login_form);
591 // A PasswordForm appears, and is visible in the layout: 524 // A PasswordForm appears, and is visible in the layout:
592 // No expected calls to the PasswordStore... 525 // No expected calls to the PasswordStore...
593 manager()->OnPasswordFormsParsed(observed); 526 manager()->OnPasswordFormsParsed(observed);
594 manager()->OnPasswordFormsRendered(observed); 527 manager()->OnPasswordFormsRendered(observed);
595 } 528 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_manager.cc ('k') | chrome/renderer/autofill/password_autofill_agent_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698