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

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

Issue 1874001: Migrate web data service logins to the login database correctly on win. (Closed)
Patch Set: Fix PSW::OnWeb Created 10 years, 7 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
« no previous file with comments | « chrome/browser/password_manager/password_store_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 <windows.h> 5 #include <windows.h>
6 #include <wincrypt.h> 6 #include <wincrypt.h>
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/scoped_ptr.h" 11 #include "base/scoped_ptr.h"
12 #include "base/scoped_temp_dir.h" 12 #include "base/scoped_temp_dir.h"
13 #include "base/time.h" 13 #include "base/time.h"
14 #include "base/waitable_event.h" 14 #include "base/waitable_event.h"
15 #include "chrome/browser/chrome_thread.h" 15 #include "chrome/browser/chrome_thread.h"
16 #include "chrome/browser/password_manager/password_form_data.h" 16 #include "chrome/browser/password_manager/password_form_data.h"
17 #include "chrome/browser/password_manager/password_store_win.h" 17 #include "chrome/browser/password_manager/password_store_win.h"
18 #include "chrome/browser/password_manager/ie7_password.h" 18 #include "chrome/browser/password_manager/ie7_password.h"
19 #include "chrome/common/pref_names.h" 19 #include "chrome/common/pref_names.h"
20 #include "chrome/test/testing_profile.h" 20 #include "chrome/test/testing_profile.h"
21 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
23 23
24 using base::WaitableEvent; 24 using base::WaitableEvent;
25 using testing::_; 25 using testing::_;
26 using testing::DoAll;
27 using testing::WithArg;
26 using webkit_glue::PasswordForm; 28 using webkit_glue::PasswordForm;
27 29
28 namespace { 30 namespace {
29 31
30 class MockPasswordStoreConsumer : public PasswordStoreConsumer { 32 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
31 public: 33 public:
32 MOCK_METHOD2(OnPasswordStoreRequestDone, 34 MOCK_METHOD2(OnPasswordStoreRequestDone,
33 void(int, const std::vector<webkit_glue::PasswordForm*>&)); 35 void(int, const std::vector<webkit_glue::PasswordForm*>&));
34 }; 36 };
35 37
36 class MockWebDataServiceConsumer : public WebDataServiceConsumer { 38 class MockWebDataServiceConsumer : public WebDataServiceConsumer {
37 public: 39 public:
38 MOCK_METHOD2(OnWebDataServiceRequestDone, 40 MOCK_METHOD2(OnWebDataServiceRequestDone,
39 void(WebDataService::Handle, const WDTypedResult*)); 41 void(WebDataService::Handle, const WDTypedResult*));
40 }; 42 };
41 43
42 class SignalingTask : public Task { 44 class SignalingTask : public Task {
43 public: 45 public:
44 explicit SignalingTask(WaitableEvent* event) : event_(event) { 46 explicit SignalingTask(WaitableEvent* event) : event_(event) {
45 } 47 }
46 virtual void Run() { 48 virtual void Run() {
47 event_->Signal(); 49 event_->Signal();
48 } 50 }
49 private: 51 private:
50 WaitableEvent* event_; 52 WaitableEvent* event_;
51 }; 53 };
52 54
53 } // anonymous namespace 55 } // anonymous namespace
54 56
57 typedef std::vector<PasswordForm*> VectorOfForms;
58
55 class PasswordStoreWinTest : public testing::Test { 59 class PasswordStoreWinTest : public testing::Test {
56 protected: 60 protected:
57 PasswordStoreWinTest() 61 PasswordStoreWinTest()
58 : ui_thread_(ChromeThread::UI, &message_loop_), 62 : ui_thread_(ChromeThread::UI, &message_loop_),
59 db_thread_(ChromeThread::DB) { 63 db_thread_(ChromeThread::DB) {
60 } 64 }
61 65
62 bool CreateIE7PasswordInfo(const std::wstring& url, const base::Time& created, 66 bool CreateIE7PasswordInfo(const std::wstring& url, const base::Time& created,
63 IE7PasswordInfo* info) { 67 IE7PasswordInfo* info) {
64 // Copied from chrome/browser/importer/importer_unittest.cc 68 // Copied from chrome/browser/importer/importer_unittest.cc
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 MessageLoopForUI message_loop_; 131 MessageLoopForUI message_loop_;
128 ChromeThread ui_thread_; 132 ChromeThread ui_thread_;
129 ChromeThread db_thread_; // PasswordStore, WDS schedule work on this thread. 133 ChromeThread db_thread_; // PasswordStore, WDS schedule work on this thread.
130 134
131 scoped_ptr<LoginDatabase> login_db_; 135 scoped_ptr<LoginDatabase> login_db_;
132 scoped_ptr<TestingProfile> profile_; 136 scoped_ptr<TestingProfile> profile_;
133 scoped_refptr<WebDataService> wds_; 137 scoped_refptr<WebDataService> wds_;
134 ScopedTempDir temp_dir_; 138 ScopedTempDir temp_dir_;
135 }; 139 };
136 140
141 ACTION(STLDeleteElements0) {
142 STLDeleteContainerPointers(arg0.begin(), arg0.end());
143 }
144
137 ACTION(QuitUIMessageLoop) { 145 ACTION(QuitUIMessageLoop) {
138 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 146 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
139 MessageLoop::current()->Quit(); 147 MessageLoop::current()->Quit();
140 } 148 }
141 149
150 MATCHER(EmptyWDResult, "") {
151 return static_cast<const WDResult<std::vector<PasswordForm*> >*>(
152 arg)->GetValue().empty();
153 }
154
142 TEST_F(PasswordStoreWinTest, ConvertIE7Login) { 155 TEST_F(PasswordStoreWinTest, ConvertIE7Login) {
143 IE7PasswordInfo password_info; 156 IE7PasswordInfo password_info;
144 ASSERT_TRUE(CreateIE7PasswordInfo(L"http://example.com/origin", 157 ASSERT_TRUE(CreateIE7PasswordInfo(L"http://example.com/origin",
145 base::Time::FromDoubleT(1), 158 base::Time::FromDoubleT(1),
146 &password_info)); 159 &password_info));
147 160
148 // This IE7 password will be retrieved by the GetLogins call. 161 // This IE7 password will be retrieved by the GetLogins call.
149 wds_->AddIE7Login(password_info); 162 wds_->AddIE7Login(password_info);
150 163
151 // The WDS schedules tasks to run on the DB thread so we schedule yet another 164 // The WDS schedules tasks to run on the DB thread so we schedule yet another
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 330
318 wds_->GetIE7Login(password_info, &wds_consumer); 331 wds_->GetIE7Login(password_info, &wds_consumer);
319 332
320 // Run the MessageLoop twice: once for the GetIE7Login that PasswordStoreWin 333 // Run the MessageLoop twice: once for the GetIE7Login that PasswordStoreWin
321 // schedules on the DB thread and once for the one we just scheduled on the UI 334 // schedules on the DB thread and once for the one we just scheduled on the UI
322 // thread. 335 // thread.
323 MessageLoop::current()->Run(); 336 MessageLoop::current()->Run();
324 MessageLoop::current()->Run(); 337 MessageLoop::current()->Run();
325 338
326 STLDeleteElements(&forms); 339 STLDeleteElements(&forms);
327 } 340 }
341
342 TEST_F(PasswordStoreWinTest, Migration) {
343 PasswordFormData autofillable_data[] = {
344 { PasswordForm::SCHEME_HTML,
345 "http://foo.example.com",
346 "http://foo.example.com/origin",
347 "http://foo.example.com/action",
348 L"submit_element",
349 L"username_element",
350 L"password_element",
351 L"username_value",
352 L"password_value",
353 true, false, 1 },
354 { PasswordForm::SCHEME_HTML,
355 "http://bar.example.com",
356 "http://bar.example.com/origin",
357 "http://bar.example.com/action",
358 L"submit_element",
359 L"username_element",
360 L"password_element",
361 L"username_value",
362 L"password_value",
363 true, false, 2 },
364 { PasswordForm::SCHEME_HTML,
365 "http://baz.example.com",
366 "http://baz.example.com/origin",
367 "http://baz.example.com/action",
368 L"submit_element",
369 L"username_element",
370 L"password_element",
371 L"username_value",
372 L"password_value",
373 true, false, 3 },
374 };
375 PasswordFormData blacklisted_data[] = {
376 { PasswordForm::SCHEME_HTML,
377 "http://blacklisted.example.com",
378 "http://blacklisted.example.com/origin",
379 "http://blacklisted.example.com/action",
380 L"submit_element",
381 L"username_element",
382 L"password_element",
383 NULL,
384 NULL,
385 false, false, 1 },
386 { PasswordForm::SCHEME_HTML,
387 "http://blacklisted2.example.com",
388 "http://blacklisted2.example.com/origin",
389 "http://blacklisted2.example.com/action",
390 L"submit_element",
391 L"username_element",
392 L"password_element",
393 NULL,
394 NULL,
395 false, false, 2 },
396 };
397
398 VectorOfForms expected_autofillable;
399 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(autofillable_data); ++i) {
400 expected_autofillable.push_back(
401 CreatePasswordFormFromData(autofillable_data[i]));
402 }
403
404 VectorOfForms expected_blacklisted;
405 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(blacklisted_data); ++i) {
406 expected_blacklisted.push_back(
407 CreatePasswordFormFromData(blacklisted_data[i]));
408 }
409
410 // Populate the WDS with logins that should be migrated.
411 for (VectorOfForms::iterator it = expected_autofillable.begin();
412 it != expected_autofillable.end(); ++it) {
413 wds_->AddLogin(**it);
414 }
415 for (VectorOfForms::iterator it = expected_blacklisted.begin();
416 it != expected_blacklisted.end(); ++it) {
417 wds_->AddLogin(**it);
418 }
419
420 // The WDS schedules tasks to run on the DB thread so we schedule yet another
421 // task to notify us that it's safe to carry on with the test.
422 WaitableEvent done(false, false);
423 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
424 done.Wait();
425
426 // Initializing the PasswordStore should trigger a migration.
427 scoped_refptr<PasswordStoreWin> store(
428 new PasswordStoreWin(login_db_.release(), profile_.get(), wds_.get()));
429 store->Init();
430
431 // Check that the migration preference has not been initialized;
432 ASSERT_TRUE(NULL == profile_->GetPrefs()->FindPreference(
433 prefs::kLoginDatabaseMigrated));
434
435 // Again, the WDS schedules tasks to run on the DB thread, so schedule a task
436 // to signal us when it is safe to continue.
437 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
438 done.Wait();
439
440 // Let the WDS callbacks proceed so the logins can be migrated.
441 MessageLoop::current()->RunAllPending();
442
443 MockPasswordStoreConsumer consumer;
444
445 // Make sure we quit the MessageLoop even if the test fails.
446 ON_CALL(consumer, OnPasswordStoreRequestDone(_, _))
447 .WillByDefault(QuitUIMessageLoop());
448
449 // The autofillable forms should have been migrated from the WDS to the login
450 // database.
451 EXPECT_CALL(consumer,
452 OnPasswordStoreRequestDone(_,
453 ContainsAllPasswordForms(expected_autofillable)))
454 .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
455
456 store->GetAutofillableLogins(&consumer);
457 MessageLoop::current()->Run();
458
459 // The blacklisted forms should have been migrated from the WDS to the login
460 // database.
461 EXPECT_CALL(consumer,
462 OnPasswordStoreRequestDone(_,
463 ContainsAllPasswordForms(expected_blacklisted)))
464 .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
465
466 store->GetBlacklistLogins(&consumer);
467 MessageLoop::current()->Run();
468
469 // Check that the migration updated the migrated preference.
470 ASSERT_TRUE(profile_->GetPrefs()->GetBoolean(prefs::kLoginDatabaseMigrated));
471
472 MockWebDataServiceConsumer wds_consumer;
473
474 // No autofillable logins should be left in the WDS.
475 EXPECT_CALL(wds_consumer,
476 OnWebDataServiceRequestDone(_, EmptyWDResult()));
477
478 wds_->GetAutofillableLogins(&wds_consumer);
479
480 // Wait for the WDS methods to execute on the DB thread.
481 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
482 done.Wait();
483
484 // Handle the callback from the WDS.
485 MessageLoop::current()->RunAllPending();
486
487 // Likewise, no blacklisted logins should be left in the WDS.
488 EXPECT_CALL(wds_consumer,
489 OnWebDataServiceRequestDone(_, EmptyWDResult()));
490
491 wds_->GetBlacklistLogins(&wds_consumer);
492
493 // Wait for the WDS methods to execute on the DB thread.
494 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
495 done.Wait();
496
497 // Handle the callback from the WDS.
498 MessageLoop::current()->RunAllPending();
499
500 STLDeleteElements(&expected_autofillable);
501 STLDeleteElements(&expected_blacklisted);
502 }
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_store_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698