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