password_store_x_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/platform_file.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/scoped_temp_dir.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_form_data.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_change.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_consumer.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/password_manager/password_store_x.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/pref_service.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_browser_process.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/mock_notification_observer.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_browser_thread.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::WaitableEvent; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::ElementsAreArray; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Pointee; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Property; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::WithArg; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::PasswordForm; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<PasswordForm*> VectorOfForms; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockPasswordStoreConsumer : public PasswordStoreConsumer { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD2(OnPasswordStoreRequestDone, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void(CancelableRequestProvider::Handle, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<PasswordForm*>&)); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class will add and remove a mock notification observer from 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the DB thread. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DBThreadObserverHelper 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe<DBThreadObserverHelper, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DeleteOnDBThread> { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBThreadObserverHelper() : done_event_(true, false) {} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Init(PasswordStore* password_store) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DB, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DBThreadObserverHelper::AddObserverTask, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, make_scoped_refptr(password_store))); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_event_.Wait(); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::MockNotificationObserver& observer() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return observer_; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct BrowserThread::DeleteOnThread<BrowserThread::DB>; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::DeleteHelper<DBThreadObserverHelper>; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DBThreadObserverHelper() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.RemoveAll(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddObserverTask(PasswordStore* password_store) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(&observer_, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_LOGINS_CHANGED, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<PasswordStore>(password_store)); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_event_.Signal(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent done_event_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationRegistrar registrar_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::MockNotificationObserver observer_; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FailingBackend : public PasswordStoreX::NativeBackend { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Init() { return true; } 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool AddLogin(const PasswordForm& form) { return false; } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool UpdateLogin(const PasswordForm& form) { return false; } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RemoveLogin(const PasswordForm& form) { return false; } 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RemoveLoginsCreatedBetween(const base::Time& delete_begin, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& delete_end) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetLogins(const PasswordForm& form, PasswordFormList* forms) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetLoginsCreatedBetween(const base::Time& get_begin, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& get_end, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordFormList* forms) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetAutofillableLogins(PasswordFormList* forms) { return false; } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetBlacklistLogins(PasswordFormList* forms) { return false; } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockBackend : public PasswordStoreX::NativeBackend { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Init() { return true; } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool AddLogin(const PasswordForm& form) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_forms_.push_back(form); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool UpdateLogin(const PasswordForm& form) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < all_forms_.size(); ++i) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CompareForms(all_forms_[i], form, true)) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_forms_[i] = form; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RemoveLogin(const PasswordForm& form) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < all_forms_.size(); ++i) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CompareForms(all_forms_[i], form, false)) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) erase(i--); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RemoveLoginsCreatedBetween(const base::Time& delete_begin, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& delete_end) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < all_forms_.size(); ++i) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delete_begin <= all_forms_[i].date_created && 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (delete_end.is_null() || all_forms_[i].date_created < delete_end)) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) erase(i--); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetLogins(const PasswordForm& form, PasswordFormList* forms) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < all_forms_.size(); ++i) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (all_forms_[i].signon_realm == form.signon_realm) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms->push_back(new PasswordForm(all_forms_[i])); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetLoginsCreatedBetween(const base::Time& get_begin, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& get_end, 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordFormList* forms) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < all_forms_.size(); ++i) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (get_begin <= all_forms_[i].date_created && 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (get_end.is_null() || all_forms_[i].date_created < get_end)) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms->push_back(new PasswordForm(all_forms_[i])); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetAutofillableLogins(PasswordFormList* forms) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < all_forms_.size(); ++i) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!all_forms_[i].blacklisted_by_user) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms->push_back(new PasswordForm(all_forms_[i])); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetBlacklistLogins(PasswordFormList* forms) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < all_forms_.size(); ++i) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (all_forms_[i].blacklisted_by_user) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms->push_back(new PasswordForm(all_forms_[i])); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void erase(size_t index) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index < all_forms_.size() - 1) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_forms_[index] = all_forms_[all_forms_.size() - 1]; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) all_forms_.pop_back(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CompareForms(const PasswordForm& a, const PasswordForm& b, bool update) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An update check doesn't care about the submit element. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!update && a.submit_element != b.submit_element) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return a.origin == b.origin && 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.password_element == b.password_element && 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.signon_realm == b.signon_realm && 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.username_element == b.username_element && 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) a.username_value == b.username_value; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm> all_forms_; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockLoginDatabaseReturn { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(OnLoginDatabaseQueryDone, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void(const std::vector<PasswordForm*>&)); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoginDatabaseQueryCallback(LoginDatabase* login_db, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool autofillable, 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockLoginDatabaseReturn* mock_return) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PasswordForm*> forms; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (autofillable) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_db->GetAutofillableLogins(&forms); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_db->GetBlacklistLogins(&forms); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mock_return->OnLoginDatabaseQueryDone(forms); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generate |count| expected logins, either auto-fillable or blacklisted. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitExpectedForms(bool autofillable, size_t count, VectorOfForms* forms) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* domain = autofillable ? "example" : "blacklisted"; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < count; ++i) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string realm = base::StringPrintf("http://%zu.%s.com", i, domain); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string origin = base::StringPrintf("http://%zu.%s.com/origin", 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, domain); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string action = base::StringPrintf("http://%zu.%s.com/action", 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i, domain); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordFormData data = { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordForm::SCHEME_HTML, 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) realm.c_str(), 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin.c_str(), 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action.c_str(), 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"submit_element", 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"username_element", 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"password_element", 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) autofillable ? L"username_value" : NULL, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) autofillable ? L"password_value" : NULL, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) autofillable, false, i + 1 }; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) forms->push_back(CreatePasswordFormFromData(data)); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BackendType { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_BACKEND, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FAILING_BACKEND, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WORKING_BACKEND 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PasswordStoreXTest : public testing::TestWithParam<BackendType> { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreXTest() 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ui_thread_(BrowserThread::UI, &message_loop_), 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_thread_(BrowserThread::DB) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(db_thread_.Start()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.reset(new TestingProfile()); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) login_db_.reset(new LoginDatabase()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append("login_test"))); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->PostTask(FROM_HERE, MessageLoop::QuitClosure()); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->Run(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_thread_.Stop(); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreX::NativeBackend* GetBackend() { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (GetParam()) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FAILING_BACKEND: 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new FailingBackend(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case WORKING_BACKEND: 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new MockBackend(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoopForUI message_loop_; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread ui_thread_; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // PasswordStore, WDS schedule work on this thread. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::TestBrowserThread db_thread_; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<LoginDatabase> login_db_; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<TestingProfile> profile_; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedTempDir temp_dir_; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION(STLDeleteElements0) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPointers(arg0.begin(), arg0.end()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ACTION(QuitUIMessageLoop) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->Quit(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(PasswordStoreXTest, Notifications) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PasswordStoreX> store( 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new PasswordStoreX(login_db_.release(), 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.get(), 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBackend())); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->Init(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordFormData form_data = 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { PasswordForm::SCHEME_HTML, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "http://bar.example.com", 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "http://bar.example.com/origin", 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "http://bar.example.com/action", 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"submit_element", 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"username_element", 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"password_element", 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"username_value", 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"password_value", 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true, false, 1 }; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(form_data)); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<DBThreadObserverHelper> helper = new DBThreadObserverHelper; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) helper->Init(store); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PasswordStoreChange expected_add_changes[] = { 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreChange(PasswordStoreChange::ADD, *form), 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(helper->observer(), 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Observe(int(chrome::NOTIFICATION_LOGINS_CHANGED), 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<PasswordStore>(store), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Property(&content::Details<const PasswordStoreChangeList>::ptr, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pointee(ElementsAreArray( 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_add_changes))))); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adding a login should trigger a notification. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->AddLogin(*form); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The PasswordStore schedules tasks to run on the DB thread so we schedule 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // yet another task to notify us that it's safe to carry on with the test. 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent done(false, false); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, base::Unretained(&done))); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the password. 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) form->password_value = WideToUTF16(L"a different password"); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PasswordStoreChange expected_update_changes[] = { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreChange(PasswordStoreChange::UPDATE, *form), 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(helper->observer(), 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Observe(int(chrome::NOTIFICATION_LOGINS_CHANGED), 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<PasswordStore>(store), 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Property(&content::Details<const PasswordStoreChangeList>::ptr, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pointee(ElementsAreArray( 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_update_changes))))); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Updating the login with the new password should trigger a notification. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->UpdateLogin(*form); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for PasswordStore to send the notification. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, base::Unretained(&done))); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PasswordStoreChange expected_delete_changes[] = { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreChange(PasswordStoreChange::REMOVE, *form), 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(helper->observer(), 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Observe(int(chrome::NOTIFICATION_LOGINS_CHANGED), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<PasswordStore>(store), 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Property(&content::Details<const PasswordStoreChangeList>::ptr, 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pointee(ElementsAreArray( 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_delete_changes))))); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deleting the login should trigger a notification. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->RemoveLogin(*form); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for PasswordStore to send the notification. 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, base::Unretained(&done))); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Public in PasswordStore, protected in PasswordStoreX. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<PasswordStore*>(store)->ShutdownOnUIThread(); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(PasswordStoreXTest, NativeMigration) { 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VectorOfForms expected_autofillable; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitExpectedForms(true, 50, &expected_autofillable); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VectorOfForms expected_blacklisted; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitExpectedForms(false, 50, &expected_blacklisted); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the initial size of the login DB file, before we populate it. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will be used later to make sure it gets back to this size. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FilePath login_db_file = temp_dir_.path().Append("login_test"); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileInfo db_file_start_info; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_start_info)); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoginDatabase* login_db = login_db_.get(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Populate the login DB with logins that should be migrated. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (VectorOfForms::iterator it = expected_autofillable.begin(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != expected_autofillable.end(); ++it) { 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IgnoreResult(&LoginDatabase::AddLogin), 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(login_db), **it)); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (VectorOfForms::iterator it = expected_blacklisted.begin(); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != expected_blacklisted.end(); ++it) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IgnoreResult(&LoginDatabase::AddLogin), 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(login_db), **it)); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Schedule another task on the DB thread to notify us that it's safe to 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // carry on with the test. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent done(false, false); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, base::Unretained(&done))); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the new size of the login DB file. We expect it to be larger. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileInfo db_file_full_info; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_full_info)); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(db_file_full_info.size, db_file_start_info.size); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializing the PasswordStore shouldn't trigger a native migration (yet). 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PasswordStoreX> store( 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new PasswordStoreX(login_db_.release(), 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_.get(), 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetBackend())); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->Init(); 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockPasswordStoreConsumer consumer; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we quit the MessageLoop even if the test fails. 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillByDefault(QuitUIMessageLoop()); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The autofillable forms should have been migrated to the native backend. 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(consumer, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPasswordStoreRequestDone(_, 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContainsAllPasswordForms(expected_autofillable))) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->GetAutofillableLogins(&consumer); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->Run(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The blacklisted forms should have been migrated to the native backend. 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(consumer, 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPasswordStoreRequestDone(_, 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContainsAllPasswordForms(expected_blacklisted))) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(DoAll(WithArg<1>(STLDeleteElements0()), QuitUIMessageLoop())); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) store->GetBlacklistLogins(&consumer); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop::current()->Run(); 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VectorOfForms empty; 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockLoginDatabaseReturn ld_return; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetParam() == WORKING_BACKEND) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No autofillable logins should be left in the login DB. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ld_return, 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty))); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The autofillable logins should still be in the login DB. 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ld_return, 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnLoginDatabaseQueryDone( 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContainsAllPasswordForms(expected_autofillable))) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(WithArg<0>(STLDeleteElements0())); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DB, FROM_HERE, 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LoginDatabaseQueryCallback, login_db, true, &ld_return)); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for the login DB methods to execute on the DB thread. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, base::Unretained(&done))); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetParam() == WORKING_BACKEND) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Likewise, no blacklisted logins should be left in the login DB. 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ld_return, 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnLoginDatabaseQueryDone(ContainsAllPasswordForms(empty))); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The blacklisted logins should still be in the login DB. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(ld_return, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnLoginDatabaseQueryDone( 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContainsAllPasswordForms(expected_blacklisted))) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .WillOnce(WithArg<0>(STLDeleteElements0())); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::DB, FROM_HERE, 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&LoginDatabaseQueryCallback, login_db, false, &ld_return)); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for the login DB methods to execute on the DB thread. 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, base::Unretained(&done))); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done.Wait(); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GetParam() == WORKING_BACKEND) { 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the migration succeeded, then not only should there be no logins left 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the login DB, but also the file should have been deleted and then 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // recreated. We approximate checking for this by checking that the file 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size is equal to the size before we populated it, even though it was 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // larger after populating it. 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformFileInfo db_file_end_info; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(file_util::GetFileInfo(login_db_file, &db_file_end_info)); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(db_file_start_info.size, db_file_end_info.size); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&expected_autofillable); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&expected_blacklisted); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Public in PasswordStore, protected in PasswordStoreX. 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<PasswordStore*>(store)->ShutdownOnUIThread(); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(NoBackend, 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreXTest, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::Values(NO_BACKEND)); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(FailingBackend, 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreXTest, 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::Values(FAILING_BACKEND)); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(WorkingBackend, 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PasswordStoreXTest, 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) testing::Values(WORKING_BACKEND)); 548