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