OLD | NEW |
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 12 matching lines...) Expand all Loading... |
23 #include "testing/gmock/include/gmock/gmock.h" | 23 #include "testing/gmock/include/gmock/gmock.h" |
24 #include "testing/gtest/include/gtest/gtest.h" | 24 #include "testing/gtest/include/gtest/gtest.h" |
25 | 25 |
26 using content::PasswordForm; | 26 using content::PasswordForm; |
27 using testing::_; | 27 using testing::_; |
28 using testing::DoAll; | 28 using testing::DoAll; |
29 using testing::Exactly; | 29 using testing::Exactly; |
30 using testing::Return; | 30 using testing::Return; |
31 using testing::WithArg; | 31 using testing::WithArg; |
32 | 32 |
| 33 namespace { |
| 34 |
33 class MockPasswordManagerDelegate : public PasswordManagerDelegate { | 35 class MockPasswordManagerDelegate : public PasswordManagerDelegate { |
34 public: | 36 public: |
35 MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&)); | 37 MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&)); |
36 MOCK_METHOD1(AddSavePasswordInfoBarIfPermitted, void(PasswordFormManager*)); | 38 MOCK_METHOD1(AddSavePasswordInfoBarIfPermitted, void(PasswordFormManager*)); |
37 MOCK_METHOD0(GetProfile, Profile*()); | 39 MOCK_METHOD0(GetProfile, Profile*()); |
38 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool()); | 40 MOCK_METHOD0(DidLastPageLoadEncounterSSLErrors, bool()); |
39 }; | 41 }; |
40 | 42 |
41 ACTION_P(InvokeConsumer, forms) { | 43 ACTION_P(InvokeConsumer, forms) { |
42 arg0->OnGetPasswordStoreResults(forms); | 44 arg0->OnGetPasswordStoreResults(forms); |
43 } | 45 } |
44 | 46 |
45 ACTION_P(SaveToScopedPtr, scoped) { | 47 ACTION_P(SaveToScopedPtr, scoped) { |
46 scoped->reset(arg0); | 48 scoped->reset(arg0); |
47 } | 49 } |
48 | 50 |
| 51 class TestPasswordManager : public PasswordManager { |
| 52 public: |
| 53 TestPasswordManager(content::WebContents* contents, |
| 54 PasswordManagerDelegate* delegate) |
| 55 : PasswordManager(contents, delegate) {} |
| 56 virtual ~TestPasswordManager() {} |
| 57 |
| 58 virtual void OnPasswordFormSubmitted(const PasswordForm& form) OVERRIDE { |
| 59 PasswordManager::OnPasswordFormSubmitted(form); |
| 60 } |
| 61 |
| 62 static TestPasswordManager* CreateForWebContentsAndDelegate( |
| 63 content::WebContents* contents, |
| 64 PasswordManagerDelegate* delegate) { |
| 65 TestPasswordManager* tpm = new TestPasswordManager(contents, delegate); |
| 66 contents->SetUserData(UserDataKey(), tpm); |
| 67 return tpm; |
| 68 } |
| 69 |
| 70 private: |
| 71 DISALLOW_COPY_AND_ASSIGN(TestPasswordManager); |
| 72 }; |
| 73 |
| 74 } // namespace |
| 75 |
49 class PasswordManagerTest : public ChromeRenderViewHostTestHarness { | 76 class PasswordManagerTest : public ChromeRenderViewHostTestHarness { |
50 protected: | 77 protected: |
51 virtual void SetUp() { | 78 virtual void SetUp() { |
52 ChromeRenderViewHostTestHarness::SetUp(); | 79 ChromeRenderViewHostTestHarness::SetUp(); |
53 store_ = static_cast<MockPasswordStore*>( | 80 store_ = static_cast<MockPasswordStore*>( |
54 PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( | 81 PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( |
55 profile(), MockPasswordStore::Build).get()); | 82 profile(), MockPasswordStore::Build).get()); |
56 | 83 |
57 EXPECT_CALL(delegate_, GetProfile()).WillRepeatedly(Return(profile())); | 84 EXPECT_CALL(delegate_, GetProfile()).WillRepeatedly(Return(profile())); |
58 PasswordManager::CreateForWebContentsAndDelegate( | 85 manager_ = TestPasswordManager::CreateForWebContentsAndDelegate( |
59 web_contents(), &delegate_); | 86 web_contents(), &delegate_); |
60 EXPECT_CALL(delegate_, DidLastPageLoadEncounterSSLErrors()) | 87 EXPECT_CALL(delegate_, DidLastPageLoadEncounterSSLErrors()) |
61 .WillRepeatedly(Return(false)); | 88 .WillRepeatedly(Return(false)); |
62 } | 89 } |
63 | 90 |
64 virtual void TearDown() { | 91 virtual void TearDown() { |
65 store_ = NULL; | 92 store_ = NULL; |
66 ChromeRenderViewHostTestHarness::TearDown(); | 93 ChromeRenderViewHostTestHarness::TearDown(); |
67 } | 94 } |
68 | 95 |
69 PasswordForm MakeSimpleForm() { | 96 PasswordForm MakeSimpleForm() { |
70 PasswordForm form; | 97 PasswordForm form; |
71 form.origin = GURL("http://www.google.com/a/LoginAuth"); | 98 form.origin = GURL("http://www.google.com/a/LoginAuth"); |
72 form.action = GURL("http://www.google.com/a/Login"); | 99 form.action = GURL("http://www.google.com/a/Login"); |
73 form.username_element = ASCIIToUTF16("Email"); | 100 form.username_element = ASCIIToUTF16("Email"); |
74 form.password_element = ASCIIToUTF16("Passwd"); | 101 form.password_element = ASCIIToUTF16("Passwd"); |
75 form.username_value = ASCIIToUTF16("google"); | 102 form.username_value = ASCIIToUTF16("google"); |
76 form.password_value = ASCIIToUTF16("password"); | 103 form.password_value = ASCIIToUTF16("password"); |
77 // Default to true so we only need to add tests in autocomplete=off cases. | 104 // Default to true so we only need to add tests in autocomplete=off cases. |
78 form.password_autocomplete_set = true; | 105 form.password_autocomplete_set = true; |
79 form.submit_element = ASCIIToUTF16("signIn"); | 106 form.submit_element = ASCIIToUTF16("signIn"); |
80 form.signon_realm = "http://www.google.com"; | 107 form.signon_realm = "http://www.google.com"; |
81 return form; | 108 return form; |
82 } | 109 } |
83 | 110 |
84 PasswordManager* manager() { | 111 bool FormsAreEqual(const content::PasswordForm& lhs, |
85 return PasswordManager::FromWebContents(web_contents()); | 112 const content::PasswordForm& rhs) { |
| 113 if (lhs.origin != rhs.origin) |
| 114 return false; |
| 115 if (lhs.action != rhs.action) |
| 116 return false; |
| 117 if (lhs.username_element != rhs.username_element) |
| 118 return false; |
| 119 if (lhs.password_element != rhs.password_element) |
| 120 return false; |
| 121 if (lhs.username_value != rhs.username_value) |
| 122 return false; |
| 123 if (lhs.password_value != rhs.password_value) |
| 124 return false; |
| 125 if (lhs.password_autocomplete_set != rhs.password_autocomplete_set) |
| 126 return false; |
| 127 if (lhs.submit_element != rhs.submit_element) |
| 128 return false; |
| 129 if (lhs.signon_realm != rhs.signon_realm) |
| 130 return false; |
| 131 return true; |
| 132 } |
| 133 |
| 134 TestPasswordManager* manager() { |
| 135 return manager_; |
| 136 } |
| 137 |
| 138 void OnPasswordFormSubmitted(const content::PasswordForm& form) { |
| 139 manager()->OnPasswordFormSubmitted(form); |
| 140 } |
| 141 |
| 142 PasswordManager::PasswordSubmittedCallback SubmissionCallback() { |
| 143 return base::Bind(&PasswordManagerTest::FormSubmitted, |
| 144 base::Unretained(this)); |
| 145 } |
| 146 |
| 147 void FormSubmitted(const content::PasswordForm& form) { |
| 148 submitted_form_ = form; |
86 } | 149 } |
87 | 150 |
88 scoped_refptr<MockPasswordStore> store_; | 151 scoped_refptr<MockPasswordStore> store_; |
| 152 TestPasswordManager* manager_; |
89 MockPasswordManagerDelegate delegate_; // Owned by manager_. | 153 MockPasswordManagerDelegate delegate_; // Owned by manager_. |
| 154 PasswordForm submitted_form_; |
90 }; | 155 }; |
91 | 156 |
92 MATCHER_P(FormMatches, form, "") { | 157 MATCHER_P(FormMatches, form, "") { |
93 return form.signon_realm == arg.signon_realm && | 158 return form.signon_realm == arg.signon_realm && |
94 form.origin == arg.origin && | 159 form.origin == arg.origin && |
95 form.action == arg.action && | 160 form.action == arg.action && |
96 form.username_element == arg.username_element && | 161 form.username_element == arg.username_element && |
97 form.password_element == arg.password_element && | 162 form.password_element == arg.password_element && |
98 form.password_autocomplete_set == | 163 form.password_autocomplete_set == |
99 arg.password_autocomplete_set && | 164 arg.password_autocomplete_set && |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 std::vector<PasswordForm*> result; // Empty password store. | 266 std::vector<PasswordForm*> result; // Empty password store. |
202 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); | 267 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); |
203 EXPECT_CALL(*store_.get(), GetLogins(_, _)) | 268 EXPECT_CALL(*store_.get(), GetLogins(_, _)) |
204 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); | 269 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); |
205 std::vector<PasswordForm> observed; | 270 std::vector<PasswordForm> observed; |
206 PasswordForm form(MakeSimpleForm()); | 271 PasswordForm form(MakeSimpleForm()); |
207 observed.push_back(form); | 272 observed.push_back(form); |
208 manager()->OnPasswordFormsParsed(observed); // The initial load. | 273 manager()->OnPasswordFormsParsed(observed); // The initial load. |
209 manager()->OnPasswordFormsRendered(observed); // The initial layout. | 274 manager()->OnPasswordFormsRendered(observed); // The initial layout. |
210 | 275 |
211 PasswordForm empty_form(form); | 276 // No message from the renderer that a password was submitted. No |
212 empty_form.username_value = string16(); | 277 // expected calls. |
213 empty_form.password_value = string16(); | |
214 content::LoadCommittedDetails details; | |
215 content::FrameNavigateParams params; | |
216 params.password_form = empty_form; | |
217 manager()->DidNavigateAnyFrame(details, params); | |
218 | |
219 // No expected calls. | |
220 EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_)).Times(0); | 278 EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_)).Times(0); |
221 observed.clear(); | 279 observed.clear(); |
222 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. | 280 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. |
223 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. | 281 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. |
224 } | 282 } |
225 | 283 |
226 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateSubframe) { | 284 TEST_F(PasswordManagerTest, FormSubmitAfterNavigateSubframe) { |
227 // Test that navigating a subframe does not prevent us from showing the save | 285 // Test that navigating a subframe does not prevent us from showing the save |
228 // password infobar. | 286 // password infobar. |
229 std::vector<PasswordForm*> result; // Empty password store. | 287 std::vector<PasswordForm*> result; // Empty password store. |
230 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); | 288 EXPECT_CALL(delegate_, FillPasswordForm(_)).Times(Exactly(0)); |
231 EXPECT_CALL(*store_.get(), GetLogins(_, _)) | 289 EXPECT_CALL(*store_.get(), GetLogins(_, _)) |
232 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); | 290 .WillOnce(DoAll(WithArg<1>(InvokeConsumer(result)), Return(1))); |
233 std::vector<PasswordForm> observed; | 291 std::vector<PasswordForm> observed; |
234 PasswordForm form(MakeSimpleForm()); | 292 PasswordForm form(MakeSimpleForm()); |
235 observed.push_back(form); | 293 observed.push_back(form); |
236 manager()->OnPasswordFormsParsed(observed); // The initial load. | 294 manager()->OnPasswordFormsParsed(observed); // The initial load. |
237 manager()->OnPasswordFormsRendered(observed); // The initial layout. | 295 manager()->OnPasswordFormsRendered(observed); // The initial layout. |
238 | 296 |
239 // Simulate navigating a sub-frame. | 297 // Simulate navigating a sub-frame. |
240 content::LoadCommittedDetails details; | 298 content::LoadCommittedDetails details; |
241 details.is_main_frame = false; | |
242 content::FrameNavigateParams params; | 299 content::FrameNavigateParams params; |
243 manager()->DidNavigateAnyFrame(details, params); | 300 manager()->DidNavigateAnyFrame(details, params); |
244 | 301 |
245 // Simulate navigating the real page. | 302 // Simulate submitting the password. |
246 details.is_main_frame = true; | 303 OnPasswordFormSubmitted(form); |
247 params.password_form = form; | |
248 manager()->DidNavigateAnyFrame(details, params); | |
249 | 304 |
250 // Now the password manager waits for the navigation to complete. | 305 // Now the password manager waits for the navigation to complete. |
251 scoped_ptr<PasswordFormManager> form_to_save; | 306 scoped_ptr<PasswordFormManager> form_to_save; |
252 EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_)) | 307 EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_)) |
253 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); | 308 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); |
254 | 309 |
255 observed.clear(); | 310 observed.clear(); |
256 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. | 311 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. |
257 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. | 312 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. |
258 | 313 |
(...skipping 23 matching lines...) Expand all Loading... |
282 std::vector<PasswordForm> observed; | 337 std::vector<PasswordForm> observed; |
283 observed.push_back(first_form); | 338 observed.push_back(first_form); |
284 manager()->OnPasswordFormsParsed(observed); | 339 manager()->OnPasswordFormsParsed(observed); |
285 observed.clear(); | 340 observed.clear(); |
286 manager()->OnPasswordFormsRendered(observed); | 341 manager()->OnPasswordFormsRendered(observed); |
287 | 342 |
288 // Now navigate to a second page. | 343 // Now navigate to a second page. |
289 content::LoadCommittedDetails details; | 344 content::LoadCommittedDetails details; |
290 details.is_main_frame = true; | 345 details.is_main_frame = true; |
291 content::FrameNavigateParams params; | 346 content::FrameNavigateParams params; |
292 manager()->DidNavigateAnyFrame(details, params); | 347 manager()->DidNavigateMainFrame(details, params); |
293 | 348 |
294 // This page contains a form with the same markup, but on a different | 349 // This page contains a form with the same markup, but on a different |
295 // URL. | 350 // URL. |
296 observed.push_back(second_form); | 351 observed.push_back(second_form); |
297 manager()->OnPasswordFormsParsed(observed); | 352 manager()->OnPasswordFormsParsed(observed); |
298 manager()->OnPasswordFormsRendered(observed); | 353 manager()->OnPasswordFormsRendered(observed); |
299 | 354 |
300 // Now submit this form | 355 // Now submit this form |
301 params.password_form = second_form; | 356 OnPasswordFormSubmitted(second_form); |
302 manager()->DidNavigateAnyFrame(details, params); | |
303 | 357 |
304 // Navigation after form submit. | 358 // Navigation after form submit. |
305 scoped_ptr<PasswordFormManager> form_to_save; | 359 scoped_ptr<PasswordFormManager> form_to_save; |
306 EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_)) | 360 EXPECT_CALL(delegate_, AddSavePasswordInfoBarIfPermitted(_)) |
307 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); | 361 .WillOnce(WithArg<0>(SaveToScopedPtr(&form_to_save))); |
308 observed.clear(); | 362 observed.clear(); |
309 manager()->OnPasswordFormsParsed(observed); | 363 manager()->OnPasswordFormsParsed(observed); |
310 manager()->OnPasswordFormsRendered(observed); | 364 manager()->OnPasswordFormsRendered(observed); |
311 | 365 |
312 // Make sure that the saved form matches the second form, not the first. | 366 // Make sure that the saved form matches the second form, not the first. |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 // navigation occurs. | 522 // navigation occurs. |
469 EXPECT_CALL(delegate_, | 523 EXPECT_CALL(delegate_, |
470 AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0)); | 524 AddSavePasswordInfoBarIfPermitted(_)).Times(Exactly(0)); |
471 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); | 525 EXPECT_CALL(*store_.get(), AddLogin(FormMatches(form))); |
472 | 526 |
473 // Now the password manager waits for the navigation to complete. | 527 // Now the password manager waits for the navigation to complete. |
474 observed.clear(); | 528 observed.clear(); |
475 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. | 529 manager()->OnPasswordFormsParsed(observed); // The post-navigation load. |
476 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. | 530 manager()->OnPasswordFormsRendered(observed); // The post-navigation layout. |
477 } | 531 } |
| 532 |
| 533 TEST_F(PasswordManagerTest, SubmissionCallbackTest) { |
| 534 manager()->AddSubmissionCallback(SubmissionCallback()); |
| 535 PasswordForm form = MakeSimpleForm(); |
| 536 OnPasswordFormSubmitted(form); |
| 537 EXPECT_TRUE(FormsAreEqual(form, submitted_form_)); |
| 538 } |
OLD | NEW |