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

Unified Diff: chrome/browser/password_manager/password_store_mac_unittest.cc

Issue 1414463004: Implement origin-based deletion for passwords in PasswordDefaultMac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Addressed all remaining comments. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/password_manager/password_store_mac_unittest.cc
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc
index 996adef9f00ce3b7fb9d8e08f720d365aa852566..bf23b68ede177b34df5204c25da623d1f8492ac7 100644
--- a/chrome/browser/password_manager/password_store_mac_unittest.cc
+++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -21,7 +21,8 @@
#include "components/password_manager/core/browser/login_database.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
-#include "content/public/test/test_browser_thread.h"
+#include "components/password_manager/core/browser/password_store_origin_unittest.h"
+#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "crypto/mock_apple_keychain.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -76,12 +77,6 @@ class MockPasswordStoreConsumer : public PasswordStoreConsumer {
}
};
-class MockPasswordStoreObserver : public PasswordStore::Observer {
- public:
- MOCK_METHOD1(OnLoginsChanged,
- void(const password_manager::PasswordStoreChangeList& changes));
-};
-
// A LoginDatabase that simulates an Init() method that takes a long time.
class SlowToInitLoginDatabase : public password_manager::LoginDatabase {
public:
@@ -174,8 +169,102 @@ PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) {
1, PasswordStoreChange(PasswordStoreChange::ADD, form));
}
+class PasswordStoreMacTestDelegate {
+ public:
+ PasswordStoreMacTestDelegate();
+ ~PasswordStoreMacTestDelegate();
+
+ static void FinishAsyncProcessing() {
vasilii 2015/11/25 18:18:39 Make it out of line.
Timo Reimann 2015/11/26 01:12:52 Done.
+ scoped_refptr<content::MessageLoopRunner> runner =
+ new content::MessageLoopRunner;
+ ASSERT_TRUE(base::ThreadTaskRunnerHandle::Get()->PostTaskAndReply(
vasilii 2015/11/25 18:18:39 You don't sync with the IO thread here. You post t
+ FROM_HERE, base::Bind(&Noop), runner->QuitClosure()));
+ runner->Run();
+ }
+
+ PasswordStoreMac* store() const { return store_.get(); }
+
+ PasswordStoreMac* store() { return store_.get(); }
+
+ private:
+ static void InitLoginDatabase(LoginDatabase* login_db);
+ void Initialize();
+ base::FilePath test_login_db_file_path() const;
+
+ void ClosePasswordStore();
+
+ content::TestBrowserThreadBundle thread_bundle_;
+
+ base::ScopedTempDir db_dir_;
+ scoped_ptr<LoginDatabase> login_db_;
+ scoped_refptr<PasswordStoreMac> store_;
+
+ DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate);
+};
+
+PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate()
+ : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {
vasilii 2015/11/25 18:18:39 You create a real IO thread but use the FILE threa
+ Initialize();
+}
+
+PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() {
+ ClosePasswordStore();
+ login_db_.reset();
+}
+
+void PasswordStoreMacTestDelegate::Initialize() {
+ ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
+
+ // Ensure that LoginDatabase will use the mock keychain if it needs to
+ // encrypt/decrypt a password.
+ OSCrypt::UseMockKeychain(true);
+ login_db_.reset(new LoginDatabase(test_login_db_file_path()));
+ ASSERT_TRUE(BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&PasswordStoreMacTestDelegate::InitLoginDatabase,
+ base::Unretained(login_db_.get()))));
+
+ // Creat and initialize the password store.
+ store_ = new PasswordStoreMac(base::ThreadTaskRunnerHandle::Get(), nullptr,
+ make_scoped_ptr(new MockAppleKeychain));
+ ASSERT_TRUE(BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_,
+ base::ThreadTaskRunnerHandle::Get())));
vasilii 2015/11/25 18:18:39 You set the background task runner as a current ta
+
+ ASSERT_TRUE(BrowserThread::PostTask(
+ BrowserThread::FILE, FROM_HERE,
+ base::Bind(&PasswordStoreMac::set_login_metadata_db, store_,
+ base::Unretained(login_db_.get()))));
+
+ // Make sure deferred initialization is performed before some tests start
+ // accessing the |login_db| directly.
+ FinishAsyncProcessing();
+}
+
vasilii 2015/11/25 18:18:39 // static
Timo Reimann 2015/11/26 01:12:52 I decided to inline the method in the (new) Passwo
+void PasswordStoreMacTestDelegate::InitLoginDatabase(LoginDatabase* login_db) {
+ ASSERT_TRUE(login_db->Init());
+}
+
+base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const {
+ return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
+}
+
+void PasswordStoreMacTestDelegate::ClosePasswordStore() {
+ store_->ShutdownOnUIThread();
+ FinishAsyncProcessing();
+}
+
} // namespace
+namespace password_manager {
+
+INSTANTIATE_TYPED_TEST_CASE_P(Mac,
+ PasswordStoreOriginTest,
+ PasswordStoreMacTestDelegate);
+
+} // namespace password_manager
+
#pragma mark -
class PasswordStoreMacInternalsTest : public testing::Test {
@@ -1175,32 +1264,9 @@ TEST_F(PasswordStoreMacInternalsTest, TestPasswordGetAll) {
class PasswordStoreMacTest : public testing::Test {
public:
- PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {}
-
- void SetUp() override {
- ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
- histogram_tester_.reset(new base::HistogramTester);
-
- // Ensure that LoginDatabase will use the mock keychain if it needs to
- // encrypt/decrypt a password.
- OSCrypt::UseMockKeychain(true);
- login_db_.reset(
- new password_manager::LoginDatabase(test_login_db_file_path()));
- thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
- ASSERT_TRUE(thread_->Start());
- ASSERT_TRUE(thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PasswordStoreMacTest::InitLoginDatabase,
- base::Unretained(login_db_.get()))));
- CreateAndInitPasswordStore(login_db_.get());
- // Make sure deferred initialization is performed before some tests start
- // accessing the |login_db| directly.
- FinishAsyncProcessing();
- }
+ PasswordStoreMacTest() : histogram_tester_(new base::HistogramTester) {}
- void TearDown() override {
- ClosePasswordStore();
- thread_.reset();
- login_db_.reset();
+ ~PasswordStoreMacTest() override {
// Whatever a test did, PasswordStoreMac stores only empty password values
// in LoginDatabase. The empty valus do not require encryption and therefore
// OSCrypt shouldn't call the Keychain. The histogram doesn't cover the
@@ -1210,31 +1276,6 @@ class PasswordStoreMacTest : public testing::Test {
}
}
- static void InitLoginDatabase(password_manager::LoginDatabase* login_db) {
- ASSERT_TRUE(login_db->Init());
- }
-
- void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) {
- store_ = new PasswordStoreMac(
- base::ThreadTaskRunnerHandle::Get(), nullptr,
- make_scoped_ptr<AppleKeychain>(new MockAppleKeychain));
- ASSERT_TRUE(thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_,
- thread_->task_runner())));
-
- ASSERT_TRUE(thread_->task_runner()->PostTask(
- FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_,
- base::Unretained(login_db))));
- }
-
- void ClosePasswordStore() {
- if (!store_)
- return;
-
- store_->ShutdownOnUIThread();
- store_ = nullptr;
- }
-
// Verifies that the given |form| can be properly stored so that it can be
// retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it
// can be properly removed.
@@ -1247,12 +1288,12 @@ class PasswordStoreMacTest : public testing::Test {
MockPasswordStoreConsumer mock_consumer;
EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()))
.WillOnce(QuitUIMessageLoop());
- store()->GetAutofillableLogins(&mock_consumer);
+ delegate_.store()->GetAutofillableLogins(&mock_consumer);
base::MessageLoop::current()->Run();
::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
- store()->AddLogin(form);
- FinishAsyncProcessing();
+ delegate_.store()->AddLogin(form);
+ delegate_.FinishAsyncProcessing();
PasswordForm returned_form;
EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
@@ -1264,7 +1305,7 @@ class PasswordStoreMacTest : public testing::Test {
// item when one is expected. If the logic that stores the Keychain item
// is incorrect, this will wipe the newly added form before the second
// query.
- store()->GetAutofillableLogins(&mock_consumer);
+ delegate_.store()->GetAutofillableLogins(&mock_consumer);
base::MessageLoop::current()->Run();
::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
EXPECT_EQ(form, returned_form);
@@ -1275,53 +1316,35 @@ class PasswordStoreMacTest : public testing::Test {
EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
.WillOnce(
DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
- store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT,
- &mock_consumer);
+ delegate_.store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT,
+ &mock_consumer);
base::MessageLoop::current()->Run();
::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
EXPECT_EQ(form, returned_form);
- store()->RemoveLogin(form);
+ delegate_.store()->RemoveLogin(form);
}
}
- base::FilePath test_login_db_file_path() const {
- return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
- }
-
password_manager::LoginDatabase* login_db() const {
- return store_->login_metadata_db();
+ return delegate_.store()->login_metadata_db();
}
MockAppleKeychain* keychain() {
- return static_cast<MockAppleKeychain*>(store_->keychain());
+ return static_cast<MockAppleKeychain*>(delegate_.store()->keychain());
}
- void FinishAsyncProcessing() {
- scoped_refptr<content::MessageLoopRunner> runner =
- new content::MessageLoopRunner;
- ASSERT_TRUE(thread_->task_runner()->PostTaskAndReply(
- FROM_HERE, base::Bind(&Noop), runner->QuitClosure()));
- runner->Run();
- }
-
- PasswordStoreMac* store() { return store_.get(); }
+ PasswordStoreMacTestDelegate& delegate() { return delegate_; }
vasilii 2015/11/25 18:18:39 I'd make delegate_ private and expose whatever you
Timo Reimann 2015/11/26 01:12:52 Obsolete now as PasswordStoreMacTest doesn't use t
protected:
- base::MessageLoopForUI message_loop_;
- content::TestBrowserThread ui_thread_;
- // Thread that the synchronous methods are run on.
- scoped_ptr<base::Thread> thread_;
-
- base::ScopedTempDir db_dir_;
- scoped_ptr<password_manager::LoginDatabase> login_db_;
- scoped_refptr<PasswordStoreMac> store_;
scoped_ptr<base::HistogramTester> histogram_tester_;
+ PasswordStoreMacTestDelegate delegate_;
};
TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
// Insert a password into both the database and the keychain.
- // This is done manually, rather than through store_->AddLogin, because the
+ // This is done manually, rather than through delegate_.store()->AddLogin,
+ // because the
// Mock Keychain isn't smart enough to be able to support update generically,
// so some.domain.com triggers special handling to test it that make inserting
// fail.
@@ -1382,10 +1405,10 @@ TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
for (unsigned int i = 0; i < arraysize(updates); ++i) {
scoped_ptr<PasswordForm> form =
CreatePasswordFormFromDataForTesting(updates[i].form_data);
- store_->UpdateLogin(*form);
+ delegate_.store()->UpdateLogin(*form);
}
- FinishAsyncProcessing();
+ delegate_.FinishAsyncProcessing();
MacKeychainPasswordFormAdapter keychain_adapter(keychain());
for (unsigned int i = 0; i < arraysize(updates); ++i) {
@@ -1445,7 +1468,7 @@ TEST_F(PasswordStoreMacTest, TestDBKeychainAssociation) {
m_form.origin = GURL("http://m.facebook.com/index.html");
MockPasswordStoreConsumer consumer;
- store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
+ delegate_.store()->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
PasswordForm returned_form;
EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
.WillOnce(
@@ -1460,9 +1483,9 @@ TEST_F(PasswordStoreMacTest, TestDBKeychainAssociation) {
owned_keychain_adapter.AddPassword(m_form);
// 4. Remove both passwords.
- store_->RemoveLogin(*www_form);
- store_->RemoveLogin(m_form);
- FinishAsyncProcessing();
+ delegate_.store()->RemoveLogin(*www_form);
+ delegate_.store()->RemoveLogin(m_form);
+ delegate_.FinishAsyncProcessing();
// No trace of www.facebook.com.
ScopedVector<autofill::PasswordForm> matching_items =
@@ -1489,7 +1512,7 @@ class PasswordsChangeObserver
}
void WaitAndVerify(PasswordStoreMacTest* test) {
- test->FinishAsyncProcessing();
+ test->delegate().FinishAsyncProcessing();
::testing::Mock::VerifyAndClearExpectations(this);
}
@@ -1543,10 +1566,10 @@ void CheckRemoveLoginsBetween(PasswordStoreMacTest* test, bool check_created) {
form_other->date_synced = next_day;
}
- PasswordsChangeObserver observer(test->store());
- test->store()->AddLogin(*form_facebook_old);
- test->store()->AddLogin(*form_facebook);
- test->store()->AddLogin(*form_other);
+ PasswordsChangeObserver observer(test->delegate().store());
+ test->delegate().store()->AddLogin(*form_facebook_old);
+ test->delegate().store()->AddLogin(*form_facebook);
+ test->delegate().store()->AddLogin(*form_other);
EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook_old)));
EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook)));
EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_other)));
@@ -1565,10 +1588,10 @@ void CheckRemoveLoginsBetween(PasswordStoreMacTest* test, bool check_created) {
// Remove facebook.
if (check_created) {
- test->store()->RemoveLoginsCreatedBetween(base::Time(), next_day,
- base::Closure());
+ test->delegate().store()->RemoveLoginsCreatedBetween(base::Time(), next_day,
+ base::Closure());
} else {
- test->store()->RemoveLoginsSyncedBetween(base::Time(), next_day);
+ test->delegate().store()->RemoveLoginsSyncedBetween(base::Time(), next_day);
}
password_manager::PasswordStoreChangeList list;
form_facebook_old->password_value.clear();
@@ -1590,10 +1613,10 @@ void CheckRemoveLoginsBetween(PasswordStoreMacTest* test, bool check_created) {
// Remove form_other.
if (check_created) {
- test->store()->RemoveLoginsCreatedBetween(next_day, base::Time(),
- base::Closure());
+ test->delegate().store()->RemoveLoginsCreatedBetween(next_day, base::Time(),
+ base::Closure());
} else {
- test->store()->RemoveLoginsSyncedBetween(next_day, base::Time());
+ test->delegate().store()->RemoveLoginsSyncedBetween(next_day, base::Time());
}
form_other->password_value.clear();
list.push_back(password_manager::PasswordStoreChange(
@@ -1644,16 +1667,16 @@ TEST_F(PasswordStoreMacTest, TestRemoveLoginsMultiProfile) {
"http://www.facebook.com/index.html", "login", L"username", L"password",
L"submit", L"not_joe_user", L"12345", true, false, 1 };
www_form = CreatePasswordFormFromDataForTesting(www_form_data2);
- store_->AddLogin(*www_form);
- FinishAsyncProcessing();
+ delegate_.store()->AddLogin(*www_form);
+ delegate_.FinishAsyncProcessing();
ScopedVector<PasswordForm> matching_items;
EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
EXPECT_EQ(1u, matching_items.size());
- store_->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
- base::Closure());
- FinishAsyncProcessing();
+ delegate_.store()->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
+ base::Closure());
+ delegate_.FinishAsyncProcessing();
// Check the second facebook form is gone.
EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
@@ -1676,8 +1699,9 @@ TEST_F(PasswordStoreMacTest, TestRemoveLoginsMultiProfile) {
// implicitly deleted. However, the observers shouldn't get notified about
// deletion of non-existent forms like m.facebook.com.
TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) {
- testing::StrictMock<MockPasswordStoreObserver> mock_observer;
- store()->AddObserver(&mock_observer);
+ testing::StrictMock<password_manager::MockPasswordStoreObserver>
+ mock_observer;
+ delegate_.store()->AddObserver(&mock_observer);
// 1. Add a password for www.facebook.com to the LoginDatabase.
PasswordFormData www_form_data = {
@@ -1702,7 +1726,7 @@ TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) {
// The PSL-matched form isn't returned because there is no actual password in
// the keychain.
EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
- store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
+ delegate_.store()->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
base::MessageLoop::current()->Run();
ScopedVector<autofill::PasswordForm> all_forms;
EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms));
@@ -1716,7 +1740,8 @@ TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) {
password_manager::PasswordStoreChange::REMOVE, *www_form));
EXPECT_CALL(mock_observer, OnLoginsChanged(list));
EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
- store_->GetLogins(*www_form, PasswordStore::ALLOW_PROMPT, &consumer);
+ delegate_.store()->GetLogins(*www_form, PasswordStore::ALLOW_PROMPT,
+ &consumer);
base::MessageLoop::current()->Run();
EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms));
EXPECT_EQ(0u, all_forms.size());
@@ -1769,16 +1794,16 @@ TEST_F(PasswordStoreMacTest, ImportFromKeychain) {
blacklisted_form.signon_realm = "http://badsite.com/";
blacklisted_form.blacklisted_by_user = true;
- store()->AddLogin(form1);
- store()->AddLogin(form2);
- store()->AddLogin(blacklisted_form);
- FinishAsyncProcessing();
+ delegate_.store()->AddLogin(form1);
+ delegate_.store()->AddLogin(form2);
+ delegate_.store()->AddLogin(blacklisted_form);
+ delegate_.FinishAsyncProcessing();
ASSERT_TRUE(base::PostTaskAndReplyWithResult(
- thread_->task_runner().get(), FROM_HERE,
- base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
+ base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
+ base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()),
base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
- FinishAsyncProcessing();
+ delegate_.FinishAsyncProcessing();
// The password should be stored in the database by now.
ScopedVector<PasswordForm> matching_items;
@@ -1809,13 +1834,13 @@ TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) {
form1.username_value = ASCIIToUTF16("my_username");
form1.federation_url = GURL("https://accounts.google.com/");
- store()->AddLogin(form1);
- FinishAsyncProcessing();
+ delegate_.store()->AddLogin(form1);
+ delegate_.FinishAsyncProcessing();
ASSERT_TRUE(base::PostTaskAndReplyWithResult(
- thread_->task_runner().get(), FROM_HERE,
- base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
+ base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
vasilii 2015/11/25 18:18:39 You post to the current thread here.
+ base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()),
base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
- FinishAsyncProcessing();
+ delegate_.FinishAsyncProcessing();
ScopedVector<PasswordForm> matching_items;
EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
@@ -1831,8 +1856,8 @@ TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) {
form1.signon_realm = "http://accounts.google.com/";
form1.username_value = ASCIIToUTF16("my_username");
form1.password_value = ASCIIToUTF16("my_password");
- store()->AddLogin(form1);
- FinishAsyncProcessing();
+ delegate_.store()->AddLogin(form1);
+ delegate_.FinishAsyncProcessing();
// Add a second keychain item matching the Database entry.
PasswordForm form2 = form1;
@@ -1843,10 +1868,10 @@ TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) {
keychain()->set_locked(true);
ASSERT_TRUE(base::PostTaskAndReplyWithResult(
- thread_->task_runner().get(), FROM_HERE,
- base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
+ base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
vasilii 2015/11/25 18:18:39 Same here.
+ base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()),
base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED)));
- FinishAsyncProcessing();
+ delegate_.FinishAsyncProcessing();
ScopedVector<PasswordForm> matching_items;
EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));

Powered by Google App Engine
This is Rietveld 408576698