1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/synchronization/waitable_event.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/time.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_form_data.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_store_change.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/password_manager/password_store_x.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/webdata/web_data_service.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/test/signaling_task.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/testing_profile.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_observer_mock.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gmock/include/gmock/gmock.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::WaitableEvent;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::_;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::DoAll;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::ElementsAreArray;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::Pointee;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::Property;
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing testing::WithArg;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing webkit_glue::PasswordForm;
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef std::vector<PasswordForm*> VectorOfForms;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockPasswordStoreConsumer : public PasswordStoreConsumer {
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD2(OnPasswordStoreRequestDone,
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               void(CancelableRequestProvider::Handle,
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    const std::vector<PasswordForm*>&));
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockWebDataServiceConsumer : public WebDataServiceConsumer {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD2(OnWebDataServiceRequestDone, void(WebDataService::Handle,
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                 const WDTypedResult*));
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This class will add and remove a mock notification observer from
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the DB thread.
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass DBThreadObserverHelper
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : public base::RefCountedThreadSafe<DBThreadObserverHelper,
53731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                        BrowserThread::DeleteOnDBThread> {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DBThreadObserverHelper() : done_event_(true, false) {}
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Init() {
58731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::DB,
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        FROM_HERE,
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this, &DBThreadObserverHelper::AddObserverTask));
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    done_event_.Wait();
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~DBThreadObserverHelper() {
67731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.RemoveAll();
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NotificationObserverMock& observer() {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return observer_;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  friend class base::RefCountedThreadSafe<DBThreadObserverHelper>;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void AddObserverTask() {
79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(&observer_,
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationType::LOGINS_CHANGED,
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    done_event_.Signal();
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WaitableEvent done_event_;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationRegistrar registrar_;
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NotificationObserverMock observer_;
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass FailingBackend : public PasswordStoreX::NativeBackend {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool Init() { return true; }
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool AddLogin(const PasswordForm& form) { return false; }
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool UpdateLogin(const PasswordForm& form) { return false; }
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool RemoveLogin(const PasswordForm& form) { return false; }
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool RemoveLoginsCreatedBetween(const base::Time& delete_begin,
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          const base::Time& delete_end) {
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetLogins(const PasswordForm& form, PasswordFormList* forms) {
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetLoginsCreatedBetween(const base::Time& get_begin,
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const base::Time& get_end,
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       PasswordFormList* forms) {
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetAutofillableLogins(PasswordFormList* forms) { return false; }
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetBlacklistLogins(PasswordFormList* forms) { return false; }
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockBackend : public PasswordStoreX::NativeBackend {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool Init() { return true; }
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool AddLogin(const PasswordForm& form) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    all_forms_.push_back(form);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool UpdateLogin(const PasswordForm& form) {
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < all_forms_.size(); ++i)
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (CompareForms(all_forms_[i], form, true))
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        all_forms_[i] = form;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool RemoveLogin(const PasswordForm& form) {
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < all_forms_.size(); ++i)
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (CompareForms(all_forms_[i], form, false))
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        erase(i--);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool RemoveLoginsCreatedBetween(const base::Time& delete_begin,
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          const base::Time& delete_end) {
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < all_forms_.size(); ++i) {
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (delete_begin <= all_forms_[i].date_created &&
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          (delete_end.is_null() || all_forms_[i].date_created < delete_end))
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        erase(i--);
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetLogins(const PasswordForm& form, PasswordFormList* forms) {
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < all_forms_.size(); ++i)
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (all_forms_[i].signon_realm == form.signon_realm)
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        forms->push_back(new PasswordForm(all_forms_[i]));
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetLoginsCreatedBetween(const base::Time& get_begin,
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const base::Time& get_end,
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       PasswordFormList* forms) {
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < all_forms_.size(); ++i)
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (get_begin <= all_forms_[i].date_created &&
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          (get_end.is_null() || all_forms_[i].date_created < get_end))
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        forms->push_back(new PasswordForm(all_forms_[i]));
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetAutofillableLogins(PasswordFormList* forms) {
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < all_forms_.size(); ++i)
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (!all_forms_[i].blacklisted_by_user)
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        forms->push_back(new PasswordForm(all_forms_[i]));
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual bool GetBlacklistLogins(PasswordFormList* forms) {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < all_forms_.size(); ++i)
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (all_forms_[i].blacklisted_by_user)
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        forms->push_back(new PasswordForm(all_forms_[i]));
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void erase(size_t index) {
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (index < all_forms_.size() - 1)
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      all_forms_[index] = all_forms_[all_forms_.size() - 1];
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    all_forms_.pop_back();
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool CompareForms(const PasswordForm& a, const PasswordForm& b, bool update) {
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // An update check doesn't care about the submit element.
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!update && a.submit_element != b.submit_element)
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return a.origin           == b.origin &&
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           a.password_element == b.password_element &&
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           a.signon_realm     == b.signon_realm &&
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           a.username_element == b.username_element &&
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch           a.username_value   == b.username_value;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<PasswordForm> all_forms_;
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockLoginDatabaseReturn {
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD1(OnLoginDatabaseQueryDone,
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               void(const std::vector<PasswordForm*>&));
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass LoginDatabaseQueryTask : public Task {
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoginDatabaseQueryTask(LoginDatabase* login_db,
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         bool autofillable,
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                         MockLoginDatabaseReturn* mock_return)
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      : login_db_(login_db), autofillable_(autofillable),
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        mock_return_(mock_return) {
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Run() {
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<PasswordForm*> forms;
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (autofillable_)
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      login_db_->GetAutofillableLogins(&forms);
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      login_db_->GetBlacklistLogins(&forms);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    mock_return_->OnLoginDatabaseQueryDone(forms);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoginDatabase* login_db_;
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool autofillable_;
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockLoginDatabaseReturn* mock_return_;
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Generate |count| expected logins, either autofillable or blacklisted.
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid InitExpectedForms(bool autofillable, size_t count, VectorOfForms* forms) {
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* domain = autofillable ? "example" : "blacklisted";
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < count; ++i) {
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string realm = StringPrintf("http://%zu.%s.com", i, domain);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string origin = StringPrintf("http://%zu.%s.com/origin", i, domain);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string action = StringPrintf("http://%zu.%s.com/action", i, domain);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PasswordFormData data = {
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      PasswordForm::SCHEME_HTML,
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      realm.c_str(),
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      origin.c_str(),
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      action.c_str(),
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"submit_element",
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"username_element",
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"password_element",
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      autofillable ? L"username_value" : NULL,
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      autofillable ? L"password_value" : NULL,
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      autofillable, false, i + 1 };
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    forms->push_back(CreatePasswordFormFromData(data));
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // anonymous namespace
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// LoginDatabase isn't reference counted, but in these unit tests that won't be
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a problem as it always outlives the threads we post tasks to.
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<>
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct RunnableMethodTraits<LoginDatabase> {
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void RetainCallee(LoginDatabase*) {}
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ReleaseCallee(LoginDatabase*) {}
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum BackendType {
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NO_BACKEND,
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FAILING_BACKEND,
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WORKING_BACKEND
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass PasswordStoreXTest : public testing::TestWithParam<BackendType> {
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PasswordStoreXTest()
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      : ui_thread_(BrowserThread::UI, &message_loop_),
275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        db_thread_(BrowserThread::DB) {
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void SetUp() {
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(db_thread_.Start());
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile_.reset(new TestingProfile());
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    login_db_.reset(new LoginDatabase());
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append("login_test")));
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wds_ = new WebDataService();
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(wds_->Init(temp_dir_.path()));
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void TearDown() {
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wds_->Shutdown();
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask);
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop::current()->Run();
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    db_thread_.Stop();
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PasswordStoreX::NativeBackend* GetBackend() {
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (GetParam()) {
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case FAILING_BACKEND:
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return new FailingBackend();
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case WORKING_BACKEND:
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return new MockBackend();
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return NULL;
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoopForUI message_loop_;
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread ui_thread_;
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread db_thread_;  // PasswordStore, WDS schedule work on this thread.
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<LoginDatabase> login_db_;
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<TestingProfile> profile_;
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<WebDataService> wds_;
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedTempDir temp_dir_;
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochACTION(STLDeleteElements0) {
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteContainerPointers(arg0.begin(), arg0.end());
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochACTION(QuitUIMessageLoop) {
324731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Quit();
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMATCHER(EmptyWDResult, "") {
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return static_cast<const WDResult<std::vector<PasswordForm*> >*>(
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      arg)->GetValue().empty();
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_P(PasswordStoreXTest, WDSMigration) {
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VectorOfForms expected_autofillable;
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitExpectedForms(true, 5, &expected_autofillable);
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VectorOfForms expected_blacklisted;
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitExpectedForms(false, 5, &expected_blacklisted);
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Populate the WDS with logins that should be migrated.
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (VectorOfForms::iterator it = expected_autofillable.begin();
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != expected_autofillable.end(); ++it) {
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wds_->AddLogin(**it);
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (VectorOfForms::iterator it = expected_blacklisted.begin();
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != expected_blacklisted.end(); ++it) {
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wds_->AddLogin(**it);
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The WDS schedules tasks to run on the DB thread so we schedule yet another
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // task to notify us that it's safe to carry on with the test.
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WaitableEvent done(false, false);
353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initializing the PasswordStore should trigger a migration.
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<PasswordStoreX> store(
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new PasswordStoreX(login_db_.release(),
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           profile_.get(),
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           wds_.get(),
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           GetBackend()));
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->Init();
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the migration preference has not been initialized.
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(NULL == profile_->GetPrefs()->FindPreference(
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs::kLoginDatabaseMigrated));
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Again, the WDS schedules tasks to run on the DB thread, so schedule a task
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to signal us when it is safe to continue.
371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Let the WDS callbacks proceed so the logins can be migrated.
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockPasswordStoreConsumer consumer;
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we quit the MessageLoop even if the test fails.
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ON_CALL(consumer, OnPasswordStoreRequestDone(_, _))
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillByDefault(QuitUIMessageLoop());
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The autofillable forms should have been migrated from the WDS to the login
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // database.
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(consumer,
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OnPasswordStoreRequestDone(_,
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ContainsAllPasswordForms(expected_autofillable)))
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->GetAutofillableLogins(&consumer);
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The blacklisted forms should have been migrated from the WDS to the login
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // database.
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(consumer,
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OnPasswordStoreRequestDone(_,
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ContainsAllPasswordForms(expected_blacklisted)))
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->GetBlacklistLogins(&consumer);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the migration updated the migrated preference.
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(profile_->GetPrefs()->GetBoolean(prefs::kLoginDatabaseMigrated));
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockWebDataServiceConsumer wds_consumer;
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No autofillable logins should be left in the WDS.
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(wds_consumer,
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OnWebDataServiceRequestDone(_, EmptyWDResult()));
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  wds_->GetAutofillableLogins(&wds_consumer);
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the WDS methods to execute on the DB thread.
416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Handle the callback from the WDS.
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Likewise, no blacklisted logins should be left in the WDS.
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(wds_consumer,
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OnWebDataServiceRequestDone(_, EmptyWDResult()));
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  wds_->GetBlacklistLogins(&wds_consumer);
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the WDS methods to execute on the DB thread.
430731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
431731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Handle the callback from the WDS.
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteElements(&expected_autofillable);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteElements(&expected_blacklisted);
4393dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen
4403dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  store->Shutdown();
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_P(PasswordStoreXTest, WDSMigrationAlreadyDone) {
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PasswordFormData wds_data[] = {
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    { PasswordForm::SCHEME_HTML,
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "http://bar.example.com",
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "http://bar.example.com/origin",
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "http://bar.example.com/action",
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"submit_element",
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"username_element",
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"password_element",
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"username_value",
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      L"password_value",
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      true, false, 1 },
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VectorOfForms unexpected_autofillable;
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(wds_data); ++i) {
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    unexpected_autofillable.push_back(
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        CreatePasswordFormFromData(wds_data[i]));
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Populate the WDS with logins that should be migrated.
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (VectorOfForms::iterator it = unexpected_autofillable.begin();
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != unexpected_autofillable.end(); ++it) {
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    wds_->AddLogin(**it);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The WDS schedules tasks to run on the DB thread so we schedule yet another
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // task to notify us that it's safe to carry on with the test.
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WaitableEvent done(false, false);
472731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
473731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Prentend that the migration has already taken place.
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            true);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initializing the PasswordStore shouldn't trigger a migration.
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<PasswordStoreX> store(
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new PasswordStoreX(login_db_.release(),
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           profile_.get(),
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           wds_.get(),
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           GetBackend()));
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->Init();
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockPasswordStoreConsumer consumer;
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we quit the MessageLoop even if the test fails.
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ON_CALL(consumer, OnPasswordStoreRequestDone(_, _))
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillByDefault(QuitUIMessageLoop());
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // No forms should be migrated.
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VectorOfForms empty;
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(consumer,
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OnPasswordStoreRequestDone(_,
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ContainsAllPasswordForms(empty)))
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillOnce(QuitUIMessageLoop());
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->GetAutofillableLogins(&consumer);
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteElements(&unexpected_autofillable);
5043dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen
5053dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  store->Shutdown();
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_P(PasswordStoreXTest, Notifications) {
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pretend that the migration has already taken place.
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            true);
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initializing the PasswordStore shouldn't trigger a migration.
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<PasswordStoreX> store(
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new PasswordStoreX(login_db_.release(),
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           profile_.get(),
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           wds_.get(),
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           GetBackend()));
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->Init();
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PasswordFormData form_data =
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  { PasswordForm::SCHEME_HTML,
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "http://bar.example.com",
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "http://bar.example.com/origin",
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    "http://bar.example.com/action",
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    L"submit_element",
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    L"username_element",
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    L"password_element",
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    L"username_value",
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    L"password_value",
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    true, false, 1 };
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(form_data));
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<DBThreadObserverHelper> helper = new DBThreadObserverHelper;
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  helper->Init();
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PasswordStoreChange expected_add_changes[] = {
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PasswordStoreChange(PasswordStoreChange::ADD, *form),
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(helper->observer(),
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              Observe(NotificationType(NotificationType::LOGINS_CHANGED),
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      NotificationService::AllSources(),
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      Property(&Details<const PasswordStoreChangeList>::ptr,
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Pointee(ElementsAreArray(
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   expected_add_changes)))));
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Adding a login should trigger a notification.
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->AddLogin(*form);
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The PasswordStore schedules tasks to run on the DB thread so we schedule
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // yet another task to notify us that it's safe to carry on with the test.
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WaitableEvent done(false, false);
554731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
555731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Change the password.
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  form->password_value = WideToUTF16(L"a different password");
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PasswordStoreChange expected_update_changes[] = {
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PasswordStoreChange(PasswordStoreChange::UPDATE, *form),
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(helper->observer(),
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              Observe(NotificationType(NotificationType::LOGINS_CHANGED),
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      NotificationService::AllSources(),
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      Property(&Details<const PasswordStoreChangeList>::ptr,
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Pointee(ElementsAreArray(
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   expected_update_changes)))));
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Updating the login with the new password should trigger a notification.
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->UpdateLogin(*form);
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for PasswordStore to send the notification.
576731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
577731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const PasswordStoreChange expected_delete_changes[] = {
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    PasswordStoreChange(PasswordStoreChange::REMOVE, *form),
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(helper->observer(),
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              Observe(NotificationType(NotificationType::LOGINS_CHANGED),
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      NotificationService::AllSources(),
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                      Property(&Details<const PasswordStoreChangeList>::ptr,
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               Pointee(ElementsAreArray(
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   expected_delete_changes)))));
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Deleting the login should trigger a notification.
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->RemoveLogin(*form);
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for PasswordStore to send the notification.
595731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
596731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
5983dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen
5993dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  store->Shutdown();
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_P(PasswordStoreXTest, NativeMigration) {
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VectorOfForms expected_autofillable;
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitExpectedForms(true, 50, &expected_autofillable);
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VectorOfForms expected_blacklisted;
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitExpectedForms(false, 50, &expected_blacklisted);
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the initial size of the login DB file, before we populate it.
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This will be used later to make sure it gets back to this size.
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const FilePath login_db_file = temp_dir_.path().Append("login_test");
6123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::PlatformFileInfo db_file_start_info;
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_start_info));
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LoginDatabase* login_db = login_db_.get();
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Populate the login DB with logins that should be migrated.
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (VectorOfForms::iterator it = expected_autofillable.begin();
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != expected_autofillable.end(); ++it) {
620731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(BrowserThread::DB,
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           FROM_HERE,
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           NewRunnableMethod(login_db,
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             &LoginDatabase::AddLogin,
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             **it));
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (VectorOfForms::iterator it = expected_blacklisted.begin();
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != expected_blacklisted.end(); ++it) {
628731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(BrowserThread::DB,
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           FROM_HERE,
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           NewRunnableMethod(login_db,
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             &LoginDatabase::AddLogin,
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             **it));
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Schedule another task on the DB thread to notify us that it's safe to
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // carry on with the test.
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  WaitableEvent done(false, false);
638731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
639731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get the new size of the login DB file. We expect it to be larger.
6433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::PlatformFileInfo db_file_full_info;
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_full_info));
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_GT(db_file_full_info.size, db_file_start_info.size);
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Pretend that the WDS migration has already taken place.
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            true);
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initializing the PasswordStore shouldn't trigger a native migration (yet).
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<PasswordStoreX> store(
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new PasswordStoreX(login_db_.release(),
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           profile_.get(),
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           wds_.get(),
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           GetBackend()));
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->Init();
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockPasswordStoreConsumer consumer;
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure we quit the MessageLoop even if the test fails.
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ON_CALL(consumer, OnPasswordStoreRequestDone(_, _))
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillByDefault(QuitUIMessageLoop());
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The autofillable forms should have been migrated to the native backend.
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(consumer,
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OnPasswordStoreRequestDone(_,
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ContainsAllPasswordForms(expected_autofillable)))
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->GetAutofillableLogins(&consumer);
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The blacklisted forms should have been migrated to the native backend.
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_CALL(consumer,
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      OnPasswordStoreRequestDone(_,
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ContainsAllPasswordForms(expected_blacklisted)))
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop()));
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  store->GetBlacklistLogins(&consumer);
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->Run();
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  VectorOfForms empty;
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockLoginDatabaseReturn ld_return;
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetParam() == WORKING_BACKEND) {
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // No autofillable logins should be left in the login DB.
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(ld_return,
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty)));
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The autofillable logins should still be in the login DB.
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(ld_return,
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                OnLoginDatabaseQueryDone(
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    ContainsAllPasswordForms(expected_autofillable)))
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(WithArg<0>(STLDeleteElements0()));
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
698731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new LoginDatabaseQueryTask(login_db, true, &ld_return));
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the login DB methods to execute on the DB thread.
702731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
703731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetParam() == WORKING_BACKEND) {
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Likewise, no blacklisted logins should be left in the login DB.
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(ld_return,
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty)));
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The blacklisted logins should still be in the login DB.
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(ld_return,
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                OnLoginDatabaseQueryDone(
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    ContainsAllPasswordForms(expected_blacklisted)))
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(WithArg<0>(STLDeleteElements0()));
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
718731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new LoginDatabaseQueryTask(login_db, false, &ld_return));
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Wait for the login DB methods to execute on the DB thread.
722731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(BrowserThread::DB, FROM_HERE,
723731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SignalingTask(&done));
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  done.Wait();
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetParam() == WORKING_BACKEND) {
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If the migration succeeded, then not only should there be no logins left
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // in the login DB, but also the file should have been deleted and then
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // recreated. We approximate checking for this by checking that the file
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // size is equal to the size before we populated it, even though it was
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // larger after populating it.
7323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    base::PlatformFileInfo db_file_end_info;
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_end_info));
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(db_file_start_info.size, db_file_end_info.size);
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteElements(&expected_autofillable);
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  STLDeleteElements(&expected_blacklisted);
7393dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen
7403dff810fe0cc4962a5fa554318e9bf8bc45f5274Kristian Monsen  store->Shutdown();
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochINSTANTIATE_TEST_CASE_P(NoBackend,
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        PasswordStoreXTest,
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        testing::Values(NO_BACKEND));
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochINSTANTIATE_TEST_CASE_P(FailingBackend,
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        PasswordStoreXTest,
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        testing::Values(FAILING_BACKEND));
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochINSTANTIATE_TEST_CASE_P(WorkingBackend,
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        PasswordStoreXTest,
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        testing::Values(WORKING_BACKEND));
752