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

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

Issue 2806002: Linux: refactor GNOME Keyring and KWallet integration to allow migration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 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
« no previous file with comments | « chrome/browser/password_manager/password_store_x.cc ('k') | chrome/chrome_browser.gypi » ('j') | 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 "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/scoped_temp_dir.h"
6 #include "base/stl_util-inl.h" 7 #include "base/stl_util-inl.h"
7 #include "base/string_util.h" 8 #include "base/string_util.h"
8 #include "base/scoped_temp_dir.h"
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/waitable_event.h" 10 #include "base/waitable_event.h"
11 #include "chrome/browser/password_manager/password_form_data.h"
11 #include "chrome/browser/password_manager/password_store_change.h" 12 #include "chrome/browser/password_manager/password_store_change.h"
12 #include "chrome/browser/password_manager/password_store_default.h" 13 #include "chrome/browser/password_manager/password_store_x.h"
13 #include "chrome/browser/password_manager/password_form_data.h"
14 #include "chrome/browser/webdata/web_data_service.h" 14 #include "chrome/browser/webdata/web_data_service.h"
15 #include "chrome/common/notification_service.h" 15 #include "chrome/common/notification_service.h"
16 #include "chrome/common/pref_names.h" 16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/testing_profile.h" 17 #include "chrome/test/testing_profile.h"
18 #include "testing/gmock/include/gmock/gmock.h" 18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
20 20
21 using base::WaitableEvent; 21 using base::WaitableEvent;
22 using testing::_; 22 using testing::_;
23 using testing::DoAll; 23 using testing::DoAll;
24 using testing::ElementsAreArray; 24 using testing::ElementsAreArray;
25 using testing::Pointee; 25 using testing::Pointee;
26 using testing::Property; 26 using testing::Property;
27 using testing::WithArg; 27 using testing::WithArg;
28 using webkit_glue::PasswordForm; 28 using webkit_glue::PasswordForm;
29 29
30 namespace { 30 namespace {
31 31
32 class MockPasswordStoreConsumer : public PasswordStoreConsumer { 32 class MockPasswordStoreConsumer : public PasswordStoreConsumer {
33 public: 33 public:
34 MOCK_METHOD2(OnPasswordStoreRequestDone, 34 MOCK_METHOD2(OnPasswordStoreRequestDone,
35 void(int, const std::vector<webkit_glue::PasswordForm*>&)); 35 void(int, const std::vector<PasswordForm*>&));
36 }; 36 };
37 37
38 class MockWebDataServiceConsumer : public WebDataServiceConsumer { 38 class MockWebDataServiceConsumer : public WebDataServiceConsumer {
39 public: 39 public:
40 MOCK_METHOD2(OnWebDataServiceRequestDone, void(WebDataService::Handle, 40 MOCK_METHOD2(OnWebDataServiceRequestDone, void(WebDataService::Handle,
41 const WDTypedResult*)); 41 const WDTypedResult*));
42 }; 42 };
43 43
44 class SignalingTask : public Task { 44 class SignalingTask : public Task {
45 public: 45 public:
46 explicit SignalingTask(WaitableEvent* event) : event_(event) { 46 explicit SignalingTask(WaitableEvent* event) : event_(event) {
47 } 47 }
48 virtual void Run() { 48 virtual void Run() {
49 event_->Signal(); 49 event_->Signal();
50 } 50 }
51 private: 51 private:
52 WaitableEvent* event_; 52 WaitableEvent* event_;
53 }; 53 };
54 54
55 class MockNotificationObserver : public NotificationObserver { 55 class MockNotificationObserver : public NotificationObserver {
56 public: 56 public:
57 MOCK_METHOD3(Observe, void(NotificationType, 57 MOCK_METHOD3(Observe, void(NotificationType,
58 const NotificationSource&, 58 const NotificationSource&,
59 const NotificationDetails&)); 59 const NotificationDetails&));
60 }; 60 };
61 61
62 // This class will add and remove a mock notification observer from 62 // This class will add and remove a mock notification observer from
63 // the DB thread. 63 // the DB thread.
64 class DBThreadObserverHelper : 64 class DBThreadObserverHelper
65 public base::RefCountedThreadSafe<DBThreadObserverHelper, 65 : public base::RefCountedThreadSafe<DBThreadObserverHelper,
66 ChromeThread::DeleteOnDBThread> { 66 ChromeThread::DeleteOnDBThread> {
67 public: 67 public:
68 DBThreadObserverHelper() : done_event_(true, false) {} 68 DBThreadObserverHelper() : done_event_(true, false) {}
69 69
70 void Init() { 70 void Init() {
71 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 71 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
72 ChromeThread::PostTask( 72 ChromeThread::PostTask(
73 ChromeThread::DB, 73 ChromeThread::DB,
74 FROM_HERE, 74 FROM_HERE,
75 NewRunnableMethod(this, &DBThreadObserverHelper::AddObserverTask)); 75 NewRunnableMethod(this, &DBThreadObserverHelper::AddObserverTask));
76 done_event_.Wait(); 76 done_event_.Wait();
(...skipping 17 matching lines...) Expand all
94 NotificationType::LOGINS_CHANGED, 94 NotificationType::LOGINS_CHANGED,
95 NotificationService::AllSources()); 95 NotificationService::AllSources());
96 done_event_.Signal(); 96 done_event_.Signal();
97 } 97 }
98 98
99 WaitableEvent done_event_; 99 WaitableEvent done_event_;
100 NotificationRegistrar registrar_; 100 NotificationRegistrar registrar_;
101 MockNotificationObserver observer_; 101 MockNotificationObserver observer_;
102 }; 102 };
103 103
104 class FailingBackend : public PasswordStoreX::NativeBackend {
105 public:
106 virtual bool Init() { return true; }
107
108 virtual bool AddLogin(const PasswordForm& form) { return false; }
109 virtual bool UpdateLogin(const PasswordForm& form) { return false; }
110 virtual bool RemoveLogin(const PasswordForm& form) { return false; }
111
112 virtual bool RemoveLoginsCreatedBetween(const base::Time& delete_begin,
113 const base::Time& delete_end) {
114 return false;
115 }
116
117 virtual bool GetLogins(const PasswordForm& form, PasswordFormList* forms) {
118 return false;
119 }
120
121 virtual bool GetLoginsCreatedBetween(const base::Time& get_begin,
122 const base::Time& get_end,
123 PasswordFormList* forms) {
124 return false;
125 }
126
127 virtual bool GetAutofillableLogins(PasswordFormList* forms) { return false; }
128 virtual bool GetBlacklistLogins(PasswordFormList* forms) { return false; }
129 };
130
131 class MockBackend : public PasswordStoreX::NativeBackend {
132 public:
133 virtual bool Init() { return true; }
134
135 virtual bool AddLogin(const PasswordForm& form) {
136 all_forms_.push_back(form);
137 return true;
138 }
139
140 virtual bool UpdateLogin(const PasswordForm& form) {
141 for (size_t i = 0; i < all_forms_.size(); ++i)
142 if (CompareForms(all_forms_[i], form, true))
143 all_forms_[i] = form;
144 return true;
145 }
146
147 virtual bool RemoveLogin(const PasswordForm& form) {
148 for (size_t i = 0; i < all_forms_.size(); ++i)
149 if (CompareForms(all_forms_[i], form, false))
150 erase(i--);
151 return true;
152 }
153
154 virtual bool RemoveLoginsCreatedBetween(const base::Time& delete_begin,
155 const base::Time& delete_end) {
156 for (size_t i = 0; i < all_forms_.size(); ++i) {
157 if (delete_begin <= all_forms_[i].date_created &&
158 (delete_end.is_null() || all_forms_[i].date_created < delete_end))
159 erase(i--);
160 }
161 return true;
162 }
163
164 virtual bool GetLogins(const PasswordForm& form, PasswordFormList* forms) {
165 for (size_t i = 0; i < all_forms_.size(); ++i)
166 if (all_forms_[i].signon_realm == form.signon_realm)
167 forms->push_back(new PasswordForm(all_forms_[i]));
168 return true;
169 }
170
171 virtual bool GetLoginsCreatedBetween(const base::Time& get_begin,
172 const base::Time& get_end,
173 PasswordFormList* forms) {
174 for (size_t i = 0; i < all_forms_.size(); ++i)
175 if (get_begin <= all_forms_[i].date_created &&
176 (get_end.is_null() || all_forms_[i].date_created < get_end))
177 forms->push_back(new PasswordForm(all_forms_[i]));
178 return true;
179 }
180
181 virtual bool GetAutofillableLogins(PasswordFormList* forms) {
182 for (size_t i = 0; i < all_forms_.size(); ++i)
183 if (!all_forms_[i].blacklisted_by_user)
184 forms->push_back(new PasswordForm(all_forms_[i]));
185 return true;
186 }
187
188 virtual bool GetBlacklistLogins(PasswordFormList* forms) {
189 for (size_t i = 0; i < all_forms_.size(); ++i)
190 if (all_forms_[i].blacklisted_by_user)
191 forms->push_back(new PasswordForm(all_forms_[i]));
192 return true;
193 }
194
195 private:
196 void erase(size_t index) {
197 if (index < all_forms_.size() - 1)
198 all_forms_[index] = all_forms_[all_forms_.size() - 1];
199 all_forms_.pop_back();
200 }
201
202 bool CompareForms(const PasswordForm& a, const PasswordForm& b, bool update) {
203 // An update check doesn't care about the submit element.
204 if (!update && a.submit_element != b.submit_element)
205 return false;
206 return a.origin == b.origin &&
207 a.password_element == b.password_element &&
208 a.signon_realm == b.signon_realm &&
209 a.username_element == b.username_element &&
210 a.username_value == b.username_value;
211 }
212
213 std::vector<PasswordForm> all_forms_;
214 };
215
216 class MockLoginDatabaseReturn {
217 public:
218 MOCK_METHOD1(OnLoginDatabaseQueryDone,
219 void(const std::vector<PasswordForm*>&));
220 };
221
222 class LoginDatabaseQueryTask : public Task {
223 public:
224 LoginDatabaseQueryTask(LoginDatabase* login_db,
225 bool autofillable,
226 MockLoginDatabaseReturn* mock_return)
227 : login_db_(login_db), autofillable_(autofillable),
228 mock_return_(mock_return) {
229 }
230
231 virtual void Run() {
232 std::vector<PasswordForm*> forms;
233 if (autofillable_)
234 login_db_->GetAutofillableLogins(&forms);
235 else
236 login_db_->GetBlacklistLogins(&forms);
237 mock_return_->OnLoginDatabaseQueryDone(forms);
238 }
239
240 private:
241 LoginDatabase* login_db_;
242 bool autofillable_;
243 MockLoginDatabaseReturn* mock_return_;
244 };
245
246 const PasswordFormData g_autofillable_data[] = {
247 { PasswordForm::SCHEME_HTML,
248 "http://foo.example.com",
249 "http://foo.example.com/origin",
250 "http://foo.example.com/action",
251 L"submit_element",
252 L"username_element",
253 L"password_element",
254 L"username_value",
255 L"password_value",
256 true, false, 1 },
257 { PasswordForm::SCHEME_HTML,
258 "http://bar.example.com",
259 "http://bar.example.com/origin",
260 "http://bar.example.com/action",
261 L"submit_element",
262 L"username_element",
263 L"password_element",
264 L"username_value",
265 L"password_value",
266 true, false, 2 },
267 { PasswordForm::SCHEME_HTML,
268 "http://baz.example.com",
269 "http://baz.example.com/origin",
270 "http://baz.example.com/action",
271 L"submit_element",
272 L"username_element",
273 L"password_element",
274 L"username_value",
275 L"password_value",
276 true, false, 3 },
277 };
278 const PasswordFormData g_blacklisted_data[] = {
279 { PasswordForm::SCHEME_HTML,
280 "http://blacklisted.example.com",
281 "http://blacklisted.example.com/origin",
282 "http://blacklisted.example.com/action",
283 L"submit_element",
284 L"username_element",
285 L"password_element",
286 NULL,
287 NULL,
288 false, false, 1 },
289 { PasswordForm::SCHEME_HTML,
290 "http://blacklisted2.example.com",
291 "http://blacklisted2.example.com/origin",
292 "http://blacklisted2.example.com/action",
293 L"submit_element",
294 L"username_element",
295 L"password_element",
296 NULL,
297 NULL,
298 false, false, 2 },
299 };
300
104 } // anonymous namespace 301 } // anonymous namespace
105 302
106 typedef std::vector<PasswordForm*> VectorOfForms; 303 typedef std::vector<PasswordForm*> VectorOfForms;
107 304
108 class PasswordStoreDefaultTest : public testing::Test { 305 // LoginDatabase isn't reference counted, but in these unit tests that won't be
306 // a problem as it always outlives the threads we post tasks to.
307 template<>
308 struct RunnableMethodTraits<LoginDatabase> {
309 void RetainCallee(LoginDatabase*) {}
310 void ReleaseCallee(LoginDatabase*) {}
311 };
312
313 enum BackendType {
314 NO_BACKEND,
315 FAILING_BACKEND,
316 WORKING_BACKEND
317 };
318
319 class PasswordStoreXTest : public testing::TestWithParam<BackendType> {
109 protected: 320 protected:
110 PasswordStoreDefaultTest() 321 PasswordStoreXTest()
111 : ui_thread_(ChromeThread::UI, &message_loop_), 322 : ui_thread_(ChromeThread::UI, &message_loop_),
112 db_thread_(ChromeThread::DB) { 323 db_thread_(ChromeThread::DB) {
113 } 324 }
114 325
115 virtual void SetUp() { 326 virtual void SetUp() {
116 ASSERT_TRUE(db_thread_.Start()); 327 ASSERT_TRUE(db_thread_.Start());
117 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 328 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
118 329
119 profile_.reset(new TestingProfile()); 330 profile_.reset(new TestingProfile());
120 331
121 login_db_.reset(new LoginDatabase()); 332 login_db_.reset(new LoginDatabase());
122 ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append( 333 ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append(
123 FILE_PATH_LITERAL("login_test")))); 334 FILE_PATH_LITERAL("login_test"))));
124 335
125 wds_ = new WebDataService(); 336 wds_ = new WebDataService();
126 ASSERT_TRUE(wds_->Init(temp_dir_.path())); 337 ASSERT_TRUE(wds_->Init(temp_dir_.path()));
127 } 338 }
128 339
129 virtual void TearDown() { 340 virtual void TearDown() {
130 wds_->Shutdown(); 341 wds_->Shutdown();
131 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask); 342 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask);
132 MessageLoop::current()->Run(); 343 MessageLoop::current()->Run();
133 db_thread_.Stop(); 344 db_thread_.Stop();
134 } 345 }
135 346
347 PasswordStoreX::NativeBackend* GetBackend() {
348 switch (GetParam()) {
349 case FAILING_BACKEND:
350 return new FailingBackend();
351 case WORKING_BACKEND:
352 return new MockBackend();
353 default:
354 return NULL;
355 }
356 }
357
136 MessageLoopForUI message_loop_; 358 MessageLoopForUI message_loop_;
137 ChromeThread ui_thread_; 359 ChromeThread ui_thread_;
138 ChromeThread db_thread_; // PasswordStore, WDS schedule work on this thread. 360 ChromeThread db_thread_; // PasswordStore, WDS schedule work on this thread.
139 361
140 scoped_ptr<LoginDatabase> login_db_; 362 scoped_ptr<LoginDatabase> login_db_;
141 scoped_ptr<TestingProfile> profile_; 363 scoped_ptr<TestingProfile> profile_;
142 scoped_refptr<WebDataService> wds_; 364 scoped_refptr<WebDataService> wds_;
143 ScopedTempDir temp_dir_; 365 ScopedTempDir temp_dir_;
144 }; 366 };
145 367
146 ACTION(STLDeleteElements0) { 368 ACTION(STLDeleteElements0) {
147 STLDeleteContainerPointers(arg0.begin(), arg0.end()); 369 STLDeleteContainerPointers(arg0.begin(), arg0.end());
148 } 370 }
149 371
150 ACTION(QuitUIMessageLoop) { 372 ACTION(QuitUIMessageLoop) {
151 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 373 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
152 MessageLoop::current()->Quit(); 374 MessageLoop::current()->Quit();
153 } 375 }
154 376
155 MATCHER(EmptyWDResult, "") { 377 MATCHER(EmptyWDResult, "") {
156 return static_cast<const WDResult<std::vector<PasswordForm*> >*>( 378 return static_cast<const WDResult<std::vector<PasswordForm*> >*>(
157 arg)->GetValue().empty(); 379 arg)->GetValue().empty();
158 } 380 }
159 381
160 TEST_F(PasswordStoreDefaultTest, Migration) { 382 TEST_P(PasswordStoreXTest, WDSMigration) {
161 PasswordFormData autofillable_data[] = {
162 { PasswordForm::SCHEME_HTML,
163 "http://foo.example.com",
164 "http://foo.example.com/origin",
165 "http://foo.example.com/action",
166 L"submit_element",
167 L"username_element",
168 L"password_element",
169 L"username_value",
170 L"password_value",
171 true, false, 1 },
172 { PasswordForm::SCHEME_HTML,
173 "http://bar.example.com",
174 "http://bar.example.com/origin",
175 "http://bar.example.com/action",
176 L"submit_element",
177 L"username_element",
178 L"password_element",
179 L"username_value",
180 L"password_value",
181 true, false, 2 },
182 { PasswordForm::SCHEME_HTML,
183 "http://baz.example.com",
184 "http://baz.example.com/origin",
185 "http://baz.example.com/action",
186 L"submit_element",
187 L"username_element",
188 L"password_element",
189 L"username_value",
190 L"password_value",
191 true, false, 3 },
192 };
193 PasswordFormData blacklisted_data[] = {
194 { PasswordForm::SCHEME_HTML,
195 "http://blacklisted.example.com",
196 "http://blacklisted.example.com/origin",
197 "http://blacklisted.example.com/action",
198 L"submit_element",
199 L"username_element",
200 L"password_element",
201 NULL,
202 NULL,
203 false, false, 1 },
204 { PasswordForm::SCHEME_HTML,
205 "http://blacklisted2.example.com",
206 "http://blacklisted2.example.com/origin",
207 "http://blacklisted2.example.com/action",
208 L"submit_element",
209 L"username_element",
210 L"password_element",
211 NULL,
212 NULL,
213 false, false, 2 },
214 };
215
216 VectorOfForms expected_autofillable; 383 VectorOfForms expected_autofillable;
217 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(autofillable_data); ++i) { 384 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_autofillable_data); ++i) {
218 expected_autofillable.push_back( 385 expected_autofillable.push_back(
219 CreatePasswordFormFromData(autofillable_data[i])); 386 CreatePasswordFormFromData(g_autofillable_data[i]));
220 } 387 }
221 388
222 VectorOfForms expected_blacklisted; 389 VectorOfForms expected_blacklisted;
223 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(blacklisted_data); ++i) { 390 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_blacklisted_data); ++i) {
224 expected_blacklisted.push_back( 391 expected_blacklisted.push_back(
225 CreatePasswordFormFromData(blacklisted_data[i])); 392 CreatePasswordFormFromData(g_blacklisted_data[i]));
226 } 393 }
227 394
228 // Populate the WDS with logins that should be migrated. 395 // Populate the WDS with logins that should be migrated.
229 for (VectorOfForms::iterator it = expected_autofillable.begin(); 396 for (VectorOfForms::iterator it = expected_autofillable.begin();
230 it != expected_autofillable.end(); ++it) { 397 it != expected_autofillable.end(); ++it) {
231 wds_->AddLogin(**it); 398 wds_->AddLogin(**it);
232 } 399 }
233 for (VectorOfForms::iterator it = expected_blacklisted.begin(); 400 for (VectorOfForms::iterator it = expected_blacklisted.begin();
234 it != expected_blacklisted.end(); ++it) { 401 it != expected_blacklisted.end(); ++it) {
235 wds_->AddLogin(**it); 402 wds_->AddLogin(**it);
236 } 403 }
237 404
238 // The WDS schedules tasks to run on the DB thread so we schedule yet another 405 // The WDS schedules tasks to run on the DB thread so we schedule yet another
239 // task to notify us that it's safe to carry on with the test. 406 // task to notify us that it's safe to carry on with the test.
240 WaitableEvent done(false, false); 407 WaitableEvent done(false, false);
241 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 408 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
242 done.Wait(); 409 done.Wait();
243 410
244 // Initializing the PasswordStore should trigger a migration. 411 // Initializing the PasswordStore should trigger a migration.
245 scoped_refptr<PasswordStoreDefault> store( 412 scoped_refptr<PasswordStoreX> store(
246 new PasswordStoreDefault(login_db_.release(), profile_.get(), wds_.get())) ; 413 new PasswordStoreX(login_db_.release(),
414 profile_.get(),
415 wds_.get(),
416 GetBackend()));
247 store->Init(); 417 store->Init();
248 418
249 // Check that the migration preference has not been initialized; 419 // Check that the migration preference has not been initialized.
250 ASSERT_TRUE(NULL == profile_->GetPrefs()->FindPreference( 420 ASSERT_TRUE(NULL == profile_->GetPrefs()->FindPreference(
251 prefs::kLoginDatabaseMigrated)); 421 prefs::kLoginDatabaseMigrated));
252 422
253 // Again, the WDS schedules tasks to run on the DB thread, so schedule a task 423 // Again, the WDS schedules tasks to run on the DB thread, so schedule a task
254 // to signal us when it is safe to continue. 424 // to signal us when it is safe to continue.
255 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 425 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
256 done.Wait(); 426 done.Wait();
257 427
258 // Let the WDS callbacks proceed so the logins can be migrated. 428 // Let the WDS callbacks proceed so the logins can be migrated.
259 MessageLoop::current()->RunAllPending(); 429 MessageLoop::current()->RunAllPending();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 482 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
313 done.Wait(); 483 done.Wait();
314 484
315 // Handle the callback from the WDS. 485 // Handle the callback from the WDS.
316 MessageLoop::current()->RunAllPending(); 486 MessageLoop::current()->RunAllPending();
317 487
318 STLDeleteElements(&expected_autofillable); 488 STLDeleteElements(&expected_autofillable);
319 STLDeleteElements(&expected_blacklisted); 489 STLDeleteElements(&expected_blacklisted);
320 } 490 }
321 491
322 TEST_F(PasswordStoreDefaultTest, MigrationAlreadyDone) { 492 TEST_P(PasswordStoreXTest, WDSMigrationAlreadyDone) {
323 PasswordFormData wds_data[] = { 493 PasswordFormData wds_data[] = {
324 { PasswordForm::SCHEME_HTML, 494 { PasswordForm::SCHEME_HTML,
325 "http://bar.example.com", 495 "http://bar.example.com",
326 "http://bar.example.com/origin", 496 "http://bar.example.com/origin",
327 "http://bar.example.com/action", 497 "http://bar.example.com/action",
328 L"submit_element", 498 L"submit_element",
329 L"username_element", 499 L"username_element",
330 L"password_element", 500 L"password_element",
331 L"username_value", 501 L"username_value",
332 L"password_value", 502 L"password_value",
(...skipping 16 matching lines...) Expand all
349 // task to notify us that it's safe to carry on with the test. 519 // task to notify us that it's safe to carry on with the test.
350 WaitableEvent done(false, false); 520 WaitableEvent done(false, false);
351 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 521 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
352 done.Wait(); 522 done.Wait();
353 523
354 // Prentend that the migration has already taken place. 524 // Prentend that the migration has already taken place.
355 profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, 525 profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
356 true); 526 true);
357 527
358 // Initializing the PasswordStore shouldn't trigger a migration. 528 // Initializing the PasswordStore shouldn't trigger a migration.
359 scoped_refptr<PasswordStoreDefault> store( 529 scoped_refptr<PasswordStoreX> store(
360 new PasswordStoreDefault(login_db_.release(), profile_.get(), 530 new PasswordStoreX(login_db_.release(),
361 wds_.get())); 531 profile_.get(),
532 wds_.get(),
533 GetBackend()));
362 store->Init(); 534 store->Init();
363 535
364 MockPasswordStoreConsumer consumer; 536 MockPasswordStoreConsumer consumer;
365 // Make sure we quit the MessageLoop even if the test fails. 537 // Make sure we quit the MessageLoop even if the test fails.
366 ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)) 538 ON_CALL(consumer, OnPasswordStoreRequestDone(_, _))
367 .WillByDefault(QuitUIMessageLoop()); 539 .WillByDefault(QuitUIMessageLoop());
368 540
369 // No forms should be migrated. 541 // No forms should be migrated.
370 VectorOfForms empty; 542 VectorOfForms empty;
371 EXPECT_CALL(consumer, 543 EXPECT_CALL(consumer,
372 OnPasswordStoreRequestDone(_, 544 OnPasswordStoreRequestDone(_,
373 ContainsAllPasswordForms(empty))) 545 ContainsAllPasswordForms(empty)))
374 .WillOnce(QuitUIMessageLoop()); 546 .WillOnce(QuitUIMessageLoop());
375 547
376 store->GetAutofillableLogins(&consumer); 548 store->GetAutofillableLogins(&consumer);
377 MessageLoop::current()->Run(); 549 MessageLoop::current()->Run();
378 550
379 STLDeleteElements(&unexpected_autofillable); 551 STLDeleteElements(&unexpected_autofillable);
380 } 552 }
381 553
382 TEST_F(PasswordStoreDefaultTest, Notifications) { 554 TEST_P(PasswordStoreXTest, Notifications) {
383 // Prentend that the migration has already taken place. 555 // Pretend that the migration has already taken place.
384 profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, 556 profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
385 true); 557 true);
386 558
387 // Initializing the PasswordStore shouldn't trigger a migration. 559 // Initializing the PasswordStore shouldn't trigger a migration.
388 scoped_refptr<PasswordStoreDefault> store( 560 scoped_refptr<PasswordStoreX> store(
389 new PasswordStoreDefault(login_db_.release(), profile_.get(), 561 new PasswordStoreX(login_db_.release(),
390 wds_.get())); 562 profile_.get(),
563 wds_.get(),
564 GetBackend()));
391 store->Init(); 565 store->Init();
392 566
393 PasswordFormData form_data = 567 PasswordFormData form_data =
394 { PasswordForm::SCHEME_HTML, 568 { PasswordForm::SCHEME_HTML,
395 "http://bar.example.com", 569 "http://bar.example.com",
396 "http://bar.example.com/origin", 570 "http://bar.example.com/origin",
397 "http://bar.example.com/action", 571 "http://bar.example.com/action",
398 L"submit_element", 572 L"submit_element",
399 L"username_element", 573 L"username_element",
400 L"password_element", 574 L"password_element",
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 Pointee(ElementsAreArray( 632 Pointee(ElementsAreArray(
459 expected_delete_changes))))); 633 expected_delete_changes)))));
460 634
461 // Deleting the login should trigger a notification. 635 // Deleting the login should trigger a notification.
462 store->RemoveLogin(*form); 636 store->RemoveLogin(*form);
463 637
464 // Wait for PasswordStore to send the notification. 638 // Wait for PasswordStore to send the notification.
465 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); 639 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
466 done.Wait(); 640 done.Wait();
467 } 641 }
642
643 TEST_P(PasswordStoreXTest, NativeMigration) {
644 VectorOfForms expected_autofillable;
645 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_autofillable_data); ++i) {
646 expected_autofillable.push_back(
647 CreatePasswordFormFromData(g_autofillable_data[i]));
648 }
649
650 VectorOfForms expected_blacklisted;
651 for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(g_blacklisted_data); ++i) {
652 expected_blacklisted.push_back(
653 CreatePasswordFormFromData(g_blacklisted_data[i]));
654 }
655
656 LoginDatabase* login_db = login_db_.get();
657
658 // Populate the login DB with logins that should be migrated.
659 for (VectorOfForms::iterator it = expected_autofillable.begin();
660 it != expected_autofillable.end(); ++it) {
661 ChromeThread::PostTask(ChromeThread::DB,
662 FROM_HERE,
663 NewRunnableMethod(login_db,
664 &LoginDatabase::AddLogin,
665 **it));
666 }
667 for (VectorOfForms::iterator it = expected_blacklisted.begin();
668 it != expected_blacklisted.end(); ++it) {
669 ChromeThread::PostTask(ChromeThread::DB,
670 FROM_HERE,
671 NewRunnableMethod(login_db,
672 &LoginDatabase::AddLogin,
673 **it));
674 }
675
676 // Schedule another task on the DB thread to notify us that it's safe to
677 // carry on with the test.
678 WaitableEvent done(false, false);
679 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
680 done.Wait();
681
682 // Pretend that the WDS migration has already taken place.
683 profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
684 true);
685
686 // Initializing the PasswordStore shouldn't trigger a native migration (yet).
687 scoped_refptr<PasswordStoreX> store(
688 new PasswordStoreX(login_db_.release(),
689 profile_.get(),
690 wds_.get(),
691 GetBackend()));
692 store->Init();
693
694 MockPasswordStoreConsumer consumer;
695
696 // Make sure we quit the MessageLoop even if the test fails.
697 ON_CALL(consumer, OnPasswordStoreRequestDone(_, _))
698 .WillByDefault(QuitUIMessageLoop());
699
700 // The autofillable forms should have been migrated to the native backend.
701 EXPECT_CALL(consumer,
702 OnPasswordStoreRequestDone(_,
703 ContainsAllPasswordForms(expected_autofillable)))
704 .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
705
706 store->GetAutofillableLogins(&consumer);
707 MessageLoop::current()->Run();
708
709 // The blacklisted forms should have been migrated to the native backend.
710 EXPECT_CALL(consumer,
711 OnPasswordStoreRequestDone(_,
712 ContainsAllPasswordForms(expected_blacklisted)))
713 .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
714
715 store->GetBlacklistLogins(&consumer);
716 MessageLoop::current()->Run();
717
718 VectorOfForms empty;
719 MockLoginDatabaseReturn ld_return;
720
721 if (GetParam() == WORKING_BACKEND) {
722 // No autofillable logins should be left in the login DB.
723 EXPECT_CALL(ld_return,
724 OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty)));
725 } else {
726 // The autofillable logins should still be in the login DB.
727 EXPECT_CALL(ld_return,
728 OnLoginDatabaseQueryDone(
729 ContainsAllPasswordForms(expected_autofillable)))
730 .WillOnce(WithArg<0>(STLDeleteElements0()));
731 }
732
733 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE,
734 new LoginDatabaseQueryTask(login_db, true, &ld_return));
735
736 // Wait for the login DB methods to execute on the DB thread.
737 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
738 done.Wait();
739
740 if (GetParam() == WORKING_BACKEND) {
741 // Likewise, no blacklisted logins should be left in the login DB.
742 EXPECT_CALL(ld_return,
743 OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty)));
744 } else {
745 // The blacklisted logins should still be in the login DB.
746 EXPECT_CALL(ld_return,
747 OnLoginDatabaseQueryDone(
748 ContainsAllPasswordForms(expected_blacklisted)))
749 .WillOnce(WithArg<0>(STLDeleteElements0()));
750 }
751
752 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE,
753 new LoginDatabaseQueryTask(login_db, false, &ld_return));
754
755 // Wait for the login DB methods to execute on the DB thread.
756 ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done));
757 done.Wait();
758
759 STLDeleteElements(&expected_autofillable);
760 STLDeleteElements(&expected_blacklisted);
761 }
762
763 INSTANTIATE_TEST_CASE_P(NoBackend,
764 PasswordStoreXTest,
765 testing::Values(NO_BACKEND));
766 INSTANTIATE_TEST_CASE_P(FailingBackend,
767 PasswordStoreXTest,
768 testing::Values(FAILING_BACKEND));
769 INSTANTIATE_TEST_CASE_P(WorkingBackend,
770 PasswordStoreXTest,
771 testing::Values(WORKING_BACKEND));
OLDNEW
« no previous file with comments | « chrome/browser/password_manager/password_store_x.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698