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

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

Issue 9625026: Save password without an associated username. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Refine the unit_test codes Created 8 years, 8 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "testing/gtest/include/gtest/gtest.h" 5 #include "testing/gtest/include/gtest/gtest.h"
6 6
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 #include "base/utf_string_conversions.h" 8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/password_manager/password_form_manager.h" 9 #include "chrome/browser/password_manager/password_form_manager.h"
10 #include "chrome/browser/password_manager/password_manager.h" 10 #include "chrome/browser/password_manager/password_manager.h"
(...skipping 17 matching lines...) Expand all
28 28
29 saved_match_ = observed_form_; 29 saved_match_ = observed_form_;
30 saved_match_.origin = GURL("http://www.google.com/a/ServiceLoginAuth"); 30 saved_match_.origin = GURL("http://www.google.com/a/ServiceLoginAuth");
31 saved_match_.action = GURL("http://www.google.com/a/ServiceLogin"); 31 saved_match_.action = GURL("http://www.google.com/a/ServiceLogin");
32 saved_match_.preferred = true; 32 saved_match_.preferred = true;
33 saved_match_.username_value = ASCIIToUTF16("test@gmail.com"); 33 saved_match_.username_value = ASCIIToUTF16("test@gmail.com");
34 saved_match_.password_value = ASCIIToUTF16("test1"); 34 saved_match_.password_value = ASCIIToUTF16("test1");
35 profile_ = new TestingProfile(); 35 profile_ = new TestingProfile();
36 } 36 }
37 37
38 // Remove the username and regenerate the profile.
39 // This function changes the observed_form_ and saved_match_.
40 // This function should be called at the beginning of tests
41 // for which there is no username.
Ilya Sherman 2012/04/26 23:42:42 nit: "no username" -> "no username field".
42 void SetUpForNoUsernameTests() {
43 observed_form_.origin = GURL("http://www.google.com/b/LoginAuth");
44 observed_form_.action = GURL("http://www.google.com/b/Login");
45 observed_form_.username_element = ASCIIToUTF16("");
46 observed_form_.password_element = ASCIIToUTF16("Passwd");
47 observed_form_.submit_element = ASCIIToUTF16("signIn");
48 observed_form_.signon_realm = "http://www.google.com";
49
50 saved_match_ = observed_form_;
51 saved_match_.origin = GURL("http://www.google.com/b/ServiceLoginAuth");
52 saved_match_.action = GURL("http://www.google.com/b/ServiceLogin");
53 saved_match_.preferred = true;
54 saved_match_.username_value = ASCIIToUTF16("");
55 saved_match_.password_value = ASCIIToUTF16("test2");
56 }
57
38 virtual void TearDown() { 58 virtual void TearDown() {
39 delete profile_; 59 delete profile_;
40 } 60 }
41 61
42 PasswordForm* GetPendingCredentials(PasswordFormManager* p) { 62 PasswordForm* GetPendingCredentials(PasswordFormManager* p) {
43 return &p->pending_credentials_; 63 return &p->pending_credentials_;
44 } 64 }
45 65
46 void SimulateMatchingPhase(PasswordFormManager* p, bool find_match) { 66 void SimulateMatchingPhase(PasswordFormManager* p, bool find_match) {
47 // Roll up the state to mock out the matching phase. 67 // Roll up the state to mock out the matching phase.
48 p->state_ = PasswordFormManager::POST_MATCHING_PHASE; 68 p->state_ = PasswordFormManager::POST_MATCHING_PHASE;
49 if (!find_match) 69 if (!find_match)
50 return; 70 return;
51 71
52 PasswordForm* match = new PasswordForm(saved_match_); 72 PasswordForm* match = new PasswordForm(saved_match_);
53 // Heap-allocated form is owned by p. 73 // Heap-allocated form is owned by p.
54 p->best_matches_[match->username_value] = match; 74 p->best_matches_[match->username_value] = match;
55 p->preferred_match_ = match; 75 p->preferred_match_ = match;
56 } 76 }
57 77
58 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) { 78 bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
59 return p->IgnoreResult(*form); 79 return p->IgnoreResult(*form);
60 } 80 }
61 81
82 void VerifyNewLogin(PasswordFormManager* manager) {
83 // Successful login. The PasswordManager would instruct PasswordFormManager
84 // to save, which should know this is a new login.
85 EXPECT_TRUE(manager->IsNewLogin());
86 // Make sure the credentials that would be submitted on successful login
87 // are going to match the stored entry in the db.
88 EXPECT_EQ(observed_form()->origin.spec(),
89 GetPendingCredentials(manager)->origin.spec());
90 EXPECT_EQ(observed_form()->signon_realm,
91 GetPendingCredentials(manager)->signon_realm);
92 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
93 EXPECT_EQ(saved_match()->password_value,
94 GetPendingCredentials(manager)->password_value);
95 EXPECT_EQ(saved_match()->username_value,
96 GetPendingCredentials(manager)->username_value);
97 }
98
99 void TestEmptyAction() {
100 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager(
101 profile(), NULL, *observed_form(), false));
102
103 saved_match()->action = GURL();
104 SimulateMatchingPhase(manager.get(), true);
105 // User logs in with the autofilled username / password from saved_match.
106 PasswordForm login = *observed_form();
107 login.username_value = saved_match()->username_value;
108 login.password_value = saved_match()->password_value;
109 manager->ProvisionallySave(login);
110 EXPECT_FALSE(manager->IsNewLogin());
111 // We bless our saved PasswordForm entry with the action URL of the
112 // observed form.
113 EXPECT_EQ(observed_form()->action,
114 GetPendingCredentials(manager.get())->action);
115 }
116
117 void TestValidForms() {
118 // User submits credentials for the observed form.
119 PasswordForm credentials = *observed_form();
120 credentials.scheme = PasswordForm::SCHEME_HTML;
121 credentials.username_value = saved_match()->username_value;
122 credentials.password_value = saved_match()->password_value;
123
124 // Form with both username_element and password_element.
125 PasswordFormManager manager1(profile(), NULL, credentials, false);
126 SimulateMatchingPhase(&manager1, false);
127 EXPECT_TRUE(manager1.HasValidPasswordForm());
128
129 // Form without a username_element but with a password_element.
130 // It should be true, because we should save and autofill a password
131 // if there isn't any username.
132 credentials.username_element.clear();
133 PasswordFormManager manager2(profile(), NULL, credentials, false);
134 SimulateMatchingPhase(&manager2, false);
135 EXPECT_TRUE(manager2.HasValidPasswordForm());
136
137 // Form without a password_element but with a username_element.
138 credentials.username_element = saved_match()->username_element;
139 credentials.password_element.clear();
140 PasswordFormManager manager3(profile(), NULL, credentials, false);
141 SimulateMatchingPhase(&manager3, false);
142 EXPECT_FALSE(manager3.HasValidPasswordForm());
143
144 // Form with neither a password_element nor a username_element.
145 credentials.username_element.clear();
146 credentials.password_element.clear();
147 PasswordFormManager manager4(profile(), NULL, credentials, false);
148 SimulateMatchingPhase(&manager4, false);
149 EXPECT_FALSE(manager4.HasValidPasswordForm());
150 }
151
152 void TestValidFormsBasic() {
153 // User submits credentials for the observed form.
154 PasswordForm credentials = *observed_form();
155 credentials.scheme = PasswordForm::SCHEME_BASIC;
156 credentials.username_value = saved_match()->username_value;
157 credentials.password_value = saved_match()->password_value;
158
159 // Form with both username_element and password_element.
160 PasswordFormManager manager1(profile(), NULL, credentials, false);
161 SimulateMatchingPhase(&manager1, false);
162 EXPECT_TRUE(manager1.HasValidPasswordForm());
163
164 // Form without a username_element but with a password_element.
165 credentials.username_element.clear();
166 PasswordFormManager manager2(profile(), NULL, credentials, false);
167 SimulateMatchingPhase(&manager2, false);
168 EXPECT_TRUE(manager2.HasValidPasswordForm());
169
170 // Form without a password_element but with a username_element.
171 credentials.username_element = saved_match()->username_element;
172 credentials.password_element.clear();
173 PasswordFormManager manager3(profile(), NULL, credentials, false);
174 SimulateMatchingPhase(&manager3, false);
175 EXPECT_TRUE(manager3.HasValidPasswordForm());
176
177 // Form with neither a password_element nor a username_element.
178 credentials.username_element.clear();
179 credentials.password_element.clear();
180 PasswordFormManager manager4(profile(), NULL, credentials, false);
181 SimulateMatchingPhase(&manager4, false);
182 EXPECT_TRUE(manager4.HasValidPasswordForm());
183 }
184
62 Profile* profile() { return profile_; } 185 Profile* profile() { return profile_; }
63 186
64 PasswordForm* observed_form() { return &observed_form_; } 187 PasswordForm* observed_form() { return &observed_form_; }
65 PasswordForm* saved_match() { return &saved_match_; } 188 PasswordForm* saved_match() { return &saved_match_; }
66 189
67 private: 190 private:
68 PasswordForm observed_form_; 191 PasswordForm observed_form_;
69 PasswordForm saved_match_; 192 PasswordForm saved_match_;
70 Profile* profile_; 193 Profile* profile_;
71 }; 194 };
72 195
73 TEST_F(PasswordFormManagerTest, TestNewLogin) { 196 TEST_F(PasswordFormManagerTest, TestNewLogin) {
74 PasswordFormManager* manager = new PasswordFormManager( 197 PasswordFormManager manager(profile(), NULL, *observed_form(), false);
75 profile(), NULL, *observed_form(), false); 198 SimulateMatchingPhase(&manager, false);
76 SimulateMatchingPhase(manager, false);
77 // User submits credentials for the observed form. 199 // User submits credentials for the observed form.
78 PasswordForm credentials = *observed_form(); 200 PasswordForm credentials = *observed_form();
79 credentials.username_value = saved_match()->username_value; 201 credentials.username_value = saved_match()->username_value;
80 credentials.password_value = saved_match()->password_value; 202 credentials.password_value = saved_match()->password_value;
81 credentials.preferred = true; 203 credentials.preferred = true;
82 manager->ProvisionallySave(credentials); 204 manager.ProvisionallySave(credentials);
83 205 VerifyNewLogin(&manager);
84 // Successful login. The PasswordManager would instruct PasswordFormManager
85 // to save, which should know this is a new login.
86 EXPECT_TRUE(manager->IsNewLogin());
87 // Make sure the credentials that would be submitted on successful login
88 // are going to match the stored entry in the db.
89 EXPECT_EQ(observed_form()->origin.spec(),
90 GetPendingCredentials(manager)->origin.spec());
91 EXPECT_EQ(observed_form()->signon_realm,
92 GetPendingCredentials(manager)->signon_realm);
93 EXPECT_TRUE(GetPendingCredentials(manager)->preferred);
94 EXPECT_EQ(saved_match()->password_value,
95 GetPendingCredentials(manager)->password_value);
96 EXPECT_EQ(saved_match()->username_value,
97 GetPendingCredentials(manager)->username_value);
98 206
99 // Now, suppose the user re-visits the site and wants to save an additional 207 // Now, suppose the user re-visits the site and wants to save an additional
100 // login for the site with a new username. In this case, the matching phase 208 // login for the site with a new username. In this case, the matching phase
101 // will yield the previously saved login. 209 // will yield the previously saved login.
102 SimulateMatchingPhase(manager, true); 210 SimulateMatchingPhase(&manager, true);
103 // Set up the new login. 211 // Set up the new login.
104 string16 new_user = ASCIIToUTF16("newuser"); 212 string16 new_user = ASCIIToUTF16("newuser");
105 string16 new_pass = ASCIIToUTF16("newpass"); 213 string16 new_pass = ASCIIToUTF16("newpass");
106 credentials.username_value = new_user; 214 credentials.username_value = new_user;
107 credentials.password_value = new_pass; 215 credentials.password_value = new_pass;
108 manager->ProvisionallySave(credentials); 216 manager.ProvisionallySave(credentials);
109 217
110 // Again, the PasswordFormManager should know this is still a new login. 218 // Again, the PasswordFormManager should know this is still a new login.
111 EXPECT_TRUE(manager->IsNewLogin()); 219 EXPECT_TRUE(manager.IsNewLogin());
112 // And make sure everything squares up again. 220 // And make sure everything squares up again.
113 EXPECT_EQ(observed_form()->origin.spec(), 221 EXPECT_EQ(observed_form()->origin.spec(),
114 GetPendingCredentials(manager)->origin.spec()); 222 GetPendingCredentials(&manager)->origin.spec());
115 EXPECT_EQ(observed_form()->signon_realm, 223 EXPECT_EQ(observed_form()->signon_realm,
116 GetPendingCredentials(manager)->signon_realm); 224 GetPendingCredentials(&manager)->signon_realm);
117 EXPECT_TRUE(GetPendingCredentials(manager)->preferred); 225 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
118 EXPECT_EQ(new_pass, 226 EXPECT_EQ(new_pass,
119 GetPendingCredentials(manager)->password_value); 227 GetPendingCredentials(&manager)->password_value);
120 EXPECT_EQ(new_user, 228 EXPECT_EQ(new_user,
121 GetPendingCredentials(manager)->username_value); 229 GetPendingCredentials(&manager)->username_value);
122 // Done. 230 // Done.
123 delete manager;
124 } 231 }
125 232
233 TEST_F(PasswordFormManagerTest, TestNewLoginAndUpdateWithoutUsername) {
234 SetUpForNoUsernameTests();
235 PasswordFormManager manager(profile(), NULL, *observed_form(), false);
236 SimulateMatchingPhase(&manager, false);
237
238 // User submits credentials for the observed form.
239 PasswordForm credentials = *observed_form();
240 credentials.username_value = saved_match()->username_value;
241 credentials.password_value = saved_match()->password_value;
242 credentials.preferred = true;
243 manager.ProvisionallySave(credentials);
244 VerifyNewLogin(&manager);
245
246 // Now, suppose the user re-visits the site and wants to save an additional
247 // login for the site with a new password. In this case, the matching phase
248 // will yield the previously saved login.
249 SimulateMatchingPhase(&manager, true);
250
251 // Set up the update login.
252 string16 new_pass = ASCIIToUTF16("newpass2");
253 credentials.password_value = new_pass;
254 manager.ProvisionallySave(credentials);
255
256 // If there is no username, we assume it's an update.
257 EXPECT_FALSE(manager.IsNewLogin());
258
259 // And make sure everything squares up again.
260 EXPECT_EQ(saved_match()->origin.spec(),
261 GetPendingCredentials(&manager)->origin.spec());
262 EXPECT_EQ(saved_match()->signon_realm,
263 GetPendingCredentials(&manager)->signon_realm);
264 EXPECT_TRUE(GetPendingCredentials(&manager)->preferred);
265 EXPECT_EQ(new_pass,
266 GetPendingCredentials(&manager)->password_value);
267 }
268
269
126 TEST_F(PasswordFormManagerTest, TestUpdatePassword) { 270 TEST_F(PasswordFormManagerTest, TestUpdatePassword) {
127 // Create a PasswordFormManager with observed_form, as if we just 271 // Create a PasswordFormManager with observed_form, as if we just
128 // saw this form and need to find matching logins. 272 // saw this form and need to find matching logins.
129 PasswordFormManager* manager = new PasswordFormManager( 273 PasswordFormManager* manager = new PasswordFormManager(
130 profile(), NULL, *observed_form(), false); 274 profile(), NULL, *observed_form(), false);
131 SimulateMatchingPhase(manager, true); 275 SimulateMatchingPhase(manager, true);
132 276
133 // User submits credentials for the observed form using a username previously 277 // User submits credentials for the observed form using a username previously
134 // stored, but a new password. Note that the observed form may have different 278 // stored, but a new password. Note that the observed form may have different
135 // origin URL (as it does in this case) than the saved_match, but we want to 279 // origin URL (as it does in this case) than the saved_match, but we want to
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 // Different paths for action / origin are okay. 317 // Different paths for action / origin are okay.
174 saved_match()->action = GURL("http://www.google.com/b/Login"); 318 saved_match()->action = GURL("http://www.google.com/b/Login");
175 saved_match()->origin = GURL("http://www.google.com/foo"); 319 saved_match()->origin = GURL("http://www.google.com/foo");
176 EXPECT_FALSE(IgnoredResult(manager, saved_match())); 320 EXPECT_FALSE(IgnoredResult(manager, saved_match()));
177 321
178 // Done. 322 // Done.
179 delete manager; 323 delete manager;
180 } 324 }
181 325
182 TEST_F(PasswordFormManagerTest, TestEmptyAction) { 326 TEST_F(PasswordFormManagerTest, TestEmptyAction) {
183 scoped_ptr<PasswordFormManager> manager(new PasswordFormManager( 327 TestEmptyAction();
184 profile(), NULL, *observed_form(), false)); 328 }
185 329
186 saved_match()->action = GURL(); 330 TEST_F(PasswordFormManagerTest, TestEmptyActionWithoutUsername) {
187 SimulateMatchingPhase(manager.get(), true); 331 SetUpForNoUsernameTests();
188 // User logs in with the autofilled username / password from saved_match. 332 TestEmptyAction();
189 PasswordForm login = *observed_form();
190 login.username_value = saved_match()->username_value;
191 login.password_value = saved_match()->password_value;
192 manager->ProvisionallySave(login);
193 EXPECT_FALSE(manager->IsNewLogin());
194 // We bless our saved PasswordForm entry with the action URL of the
195 // observed form.
196 EXPECT_EQ(observed_form()->action,
197 GetPendingCredentials(manager.get())->action);
198 } 333 }
199 334
200 TEST_F(PasswordFormManagerTest, TestValidForms) { 335 TEST_F(PasswordFormManagerTest, TestValidForms) {
201 // User submits credentials for the observed form. 336 TestValidForms();
202 PasswordForm credentials = *observed_form(); 337 }
203 credentials.scheme = PasswordForm::SCHEME_HTML;
204 credentials.username_value = saved_match()->username_value;
205 credentials.password_value = saved_match()->password_value;
206 338
207 // Form with both username_element and password_element. 339 TEST_F(PasswordFormManagerTest, TestValidFormsWithNoUsername) {
208 PasswordFormManager manager1(profile(), NULL, credentials, false); 340 SetUpForNoUsernameTests();
209 SimulateMatchingPhase(&manager1, false); 341 TestValidForms();
210 EXPECT_TRUE(manager1.HasValidPasswordForm());
211
212 // Form without a username_element but with a password_element.
213 credentials.username_element.clear();
214 PasswordFormManager manager2(profile(), NULL, credentials, false);
215 SimulateMatchingPhase(&manager2, false);
216 EXPECT_FALSE(manager2.HasValidPasswordForm());
217
218 // Form without a password_element but with a username_element.
219 credentials.username_element = saved_match()->username_element;
220 credentials.password_element.clear();
221 PasswordFormManager manager3(profile(), NULL, credentials, false);
222 SimulateMatchingPhase(&manager3, false);
223 EXPECT_FALSE(manager3.HasValidPasswordForm());
224
225 // Form with neither a password_element nor a username_element.
226 credentials.username_element.clear();
227 credentials.password_element.clear();
228 PasswordFormManager manager4(profile(), NULL, credentials, false);
229 SimulateMatchingPhase(&manager4, false);
230 EXPECT_FALSE(manager4.HasValidPasswordForm());
231 } 342 }
232 343
233 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) { 344 TEST_F(PasswordFormManagerTest, TestValidFormsBasic) {
234 // User submits credentials for the observed form. 345 TestValidFormsBasic();
346 }
347
348 TEST_F(PasswordFormManagerTest, TestValidFormsBasicWithoutUsername) {
349 SetUpForNoUsernameTests();
350 TestValidFormsBasic();
351 }
352
353 TEST_F(PasswordFormManagerTest, TestVisitOtherForm) {
354 // Create forms haven't username element.
355 SetUpForNoUsernameTests();
356
357 // Save the password for a form with no username element
358 // on http://www.google.com/b/LoginAuth
359 PasswordFormManager manager(profile(), NULL, *observed_form(), false);
360 SimulateMatchingPhase(&manager, false);
235 PasswordForm credentials = *observed_form(); 361 PasswordForm credentials = *observed_form();
236 credentials.scheme = PasswordForm::SCHEME_BASIC;
237 credentials.username_value = saved_match()->username_value; 362 credentials.username_value = saved_match()->username_value;
238 credentials.password_value = saved_match()->password_value; 363 credentials.password_value = saved_match()->password_value;
364 credentials.preferred = true;
365 manager.ProvisionallySave(credentials);
366 VerifyNewLogin(&manager);
239 367
Ilya Sherman 2012/04/26 23:42:42 nit: Please remove this blank line (367)
240 // Form with both username_element and password_element.
241 PasswordFormManager manager1(profile(), NULL, credentials, false);
242 SimulateMatchingPhase(&manager1, false);
243 EXPECT_TRUE(manager1.HasValidPasswordForm());
244
245 // Form without a username_element but with a password_element.
246 credentials.username_element.clear();
247 PasswordFormManager manager2(profile(), NULL, credentials, false);
248 SimulateMatchingPhase(&manager2, false);
249 EXPECT_TRUE(manager2.HasValidPasswordForm());
250
251 // Form without a password_element but with a username_element.
252 credentials.username_element = saved_match()->username_element;
253 credentials.password_element.clear();
254 PasswordFormManager manager3(profile(), NULL, credentials, false);
255 SimulateMatchingPhase(&manager3, false);
256 EXPECT_TRUE(manager3.HasValidPasswordForm());
257
258 // Form with neither a password_element nor a username_element.
259 credentials.username_element.clear();
260 credentials.password_element.clear();
261 PasswordFormManager manager4(profile(), NULL, credentials, false);
262 SimulateMatchingPhase(&manager4, false);
263 EXPECT_TRUE(manager4.HasValidPasswordForm());
264 } 368 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_form_manager.cc ('k') | chrome/renderer/autofill/password_autofill_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698