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

Side by Side Diff: chrome/browser/password_manager/password_store_mac_unittest.cc

Issue 838453003: Open the LoginDatabase on the DB thread, not the UI thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Mac namespace fixes. Created 5 years, 11 months 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/password_manager/password_store_mac.h" 5 #include "chrome/browser/password_manager/password_store_mac.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/files/scoped_temp_dir.h" 8 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/scoped_vector.h" 9 #include "base/memory/scoped_vector.h"
10 #include "base/scoped_observer.h" 10 #include "base/scoped_observer.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/password_manager/password_store_mac_internal.h" 14 #include "chrome/browser/password_manager/password_store_mac_internal.h"
15 #include "chrome/common/chrome_paths.h" 15 #include "chrome/common/chrome_paths.h"
16 #include "components/password_manager/core/browser/login_database.h"
16 #include "components/password_manager/core/browser/password_store_consumer.h" 17 #include "components/password_manager/core/browser/password_store_consumer.h"
17 #include "content/public/test/test_browser_thread.h" 18 #include "content/public/test/test_browser_thread.h"
18 #include "crypto/mock_apple_keychain.h" 19 #include "crypto/mock_apple_keychain.h"
19 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
21 22
22 using autofill::PasswordForm; 23 using autofill::PasswordForm;
23 using base::ASCIIToUTF16; 24 using base::ASCIIToUTF16;
24 using base::WideToUTF16; 25 using base::WideToUTF16;
25 using content::BrowserThread; 26 using content::BrowserThread;
(...skipping 27 matching lines...) Expand all
53 54
54 ACTION(STLDeleteElements0) { 55 ACTION(STLDeleteElements0) {
55 STLDeleteContainerPointers(arg0.begin(), arg0.end()); 56 STLDeleteContainerPointers(arg0.begin(), arg0.end());
56 } 57 }
57 58
58 ACTION(QuitUIMessageLoop) { 59 ACTION(QuitUIMessageLoop) {
59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
60 base::MessageLoop::current()->Quit(); 61 base::MessageLoop::current()->Quit();
61 } 62 }
62 63
64 class MockPasswordStoreObserver : public PasswordStore::Observer {
65 public:
66 MOCK_METHOD1(OnLoginsChanged,
67 void(const password_manager::PasswordStoreChangeList& changes));
68 };
69
63 class TestPasswordStoreMac : public PasswordStoreMac { 70 class TestPasswordStoreMac : public PasswordStoreMac {
64 public: 71 public:
65 TestPasswordStoreMac( 72 TestPasswordStoreMac(
66 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, 73 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
67 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner, 74 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner,
68 crypto::AppleKeychain* keychain, 75 crypto::AppleKeychain* keychain,
69 LoginDatabase* login_db) 76 const base::FilePath& login_db_file_path)
70 : PasswordStoreMac(main_thread_runner, 77 : PasswordStoreMac(main_thread_runner,
71 db_thread_runner, 78 db_thread_runner,
72 keychain, 79 keychain,
73 login_db) { 80 login_db_file_path) {
74 } 81 }
75 82
76 using PasswordStoreMac::GetBackgroundTaskRunner; 83 using PasswordStoreMac::GetBackgroundTaskRunner;
77 84
78 private: 85 private:
79 ~TestPasswordStoreMac() override {} 86 ~TestPasswordStoreMac() override {}
80 87
81 DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac); 88 DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac);
82 }; 89 };
83 90
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 std::vector<PasswordForm*> owned_passwords = 1049 std::vector<PasswordForm*> owned_passwords =
1043 owned_keychain_adapter.GetAllPasswordFormPasswords(); 1050 owned_keychain_adapter.GetAllPasswordFormPasswords();
1044 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); 1051 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
1045 STLDeleteElements(&owned_passwords); 1052 STLDeleteElements(&owned_passwords);
1046 } 1053 }
1047 1054
1048 #pragma mark - 1055 #pragma mark -
1049 1056
1050 class PasswordStoreMacTest : public testing::Test { 1057 class PasswordStoreMacTest : public testing::Test {
1051 public: 1058 public:
1052 PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {} 1059 PasswordStoreMacTest()
1060 : ui_thread_(BrowserThread::UI, &message_loop_), keychain_(nullptr) {}
1053 1061
1054 void SetUp() override { 1062 void SetUp() override {
1055 login_db_ = new LoginDatabase();
1056 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); 1063 ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
1057 base::FilePath db_file = db_dir_.path().AppendASCII("login.db");
1058 ASSERT_TRUE(login_db_->Init(db_file));
1059 1064
1060 keychain_ = new MockAppleKeychain(); 1065 keychain_ = new MockAppleKeychain();
1061 1066
1062 store_ = new TestPasswordStoreMac( 1067 store_ = new TestPasswordStoreMac(
1063 base::MessageLoopProxy::current(), 1068 base::MessageLoopProxy::current(),
1064 base::MessageLoopProxy::current(), 1069 base::MessageLoopProxy::current(),
1065 keychain_, 1070 keychain_,
1066 login_db_); 1071 test_login_db_file_path());
1067 ASSERT_TRUE(store_->Init(syncer::SyncableService::StartSyncFlare())); 1072 ASSERT_TRUE(store_->Init(syncer::SyncableService::StartSyncFlare()));
1068 } 1073 }
1069 1074
1070 void TearDown() override { 1075 void TearDown() override {
1071 store_->Shutdown(); 1076 store_->Shutdown();
1072 EXPECT_FALSE(store_->GetBackgroundTaskRunner().get()); 1077 EXPECT_FALSE(store_->GetBackgroundTaskRunner().get());
1073 } 1078 }
1074 1079
1080 base::FilePath test_login_db_file_path() const {
1081 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
1082 }
1083
1084 password_manager::LoginDatabase* login_db() const {
1085 return store_->login_metadata_db();
1086 }
1087
1075 void WaitForStoreUpdate() { 1088 void WaitForStoreUpdate() {
1076 // Do a store-level query to wait for all the operations above to be done. 1089 // Do a store-level query to wait for all the operations above to be done.
1077 MockPasswordStoreConsumer consumer; 1090 MockPasswordStoreConsumer consumer;
1078 EXPECT_CALL(consumer, OnGetPasswordStoreResults(_)) 1091 EXPECT_CALL(consumer, OnGetPasswordStoreResults(_))
1079 .WillOnce(DoAll(WithArg<0>(STLDeleteElements0()), QuitUIMessageLoop())); 1092 .WillOnce(DoAll(WithArg<0>(STLDeleteElements0()), QuitUIMessageLoop()));
1080 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); 1093 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer);
1081 base::MessageLoop::current()->Run(); 1094 base::MessageLoop::current()->Run();
1082 } 1095 }
1083 1096
1084 TestPasswordStoreMac* store() { return store_.get(); } 1097 TestPasswordStoreMac* store() { return store_.get(); }
1085 1098
1086 MockAppleKeychain* keychain() { return keychain_; } 1099 MockAppleKeychain* keychain() { return keychain_; }
1087 1100
1088 protected: 1101 protected:
1089 base::MessageLoopForUI message_loop_; 1102 base::MessageLoopForUI message_loop_;
1090 content::TestBrowserThread ui_thread_; 1103 content::TestBrowserThread ui_thread_;
1091 1104
1092 MockAppleKeychain* keychain_; // Owned by store_. 1105 MockAppleKeychain* keychain_; // Owned by store_.
1093 LoginDatabase* login_db_; // Owned by store_.
1094 scoped_refptr<TestPasswordStoreMac> store_; 1106 scoped_refptr<TestPasswordStoreMac> store_;
1095 base::ScopedTempDir db_dir_; 1107 base::ScopedTempDir db_dir_;
1096 }; 1108 };
1097 1109
1098 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { 1110 TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
1099 // Insert a password into both the database and the keychain. 1111 // Insert a password into both the database and the keychain.
1100 // This is done manually, rather than through store_->AddLogin, because the 1112 // This is done manually, rather than through store_->AddLogin, because the
1101 // Mock Keychain isn't smart enough to be able to support update generically, 1113 // Mock Keychain isn't smart enough to be able to support update generically,
1102 // so some.domain.com triggers special handling to test it that make inserting 1114 // so some.domain.com triggers special handling to test it that make inserting
1103 // fail. 1115 // fail.
1104 PasswordFormData joint_data = { 1116 PasswordFormData joint_data = {
1105 PasswordForm::SCHEME_HTML, "http://some.domain.com/", 1117 PasswordForm::SCHEME_HTML, "http://some.domain.com/",
1106 "http://some.domain.com/insecure.html", "login.cgi", 1118 "http://some.domain.com/insecure.html", "login.cgi",
1107 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 1119 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
1108 }; 1120 };
1109 scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data)); 1121 scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data));
1110 login_db_->AddLogin(*joint_form); 1122 login_db()->AddLogin(*joint_form);
1111 MockAppleKeychain::KeychainTestData joint_keychain_data = { 1123 MockAppleKeychain::KeychainTestData joint_keychain_data = {
1112 kSecAuthenticationTypeHTMLForm, "some.domain.com", 1124 kSecAuthenticationTypeHTMLForm, "some.domain.com",
1113 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", 1125 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z",
1114 "joe_user", "sekrit", false }; 1126 "joe_user", "sekrit", false };
1115 keychain_->AddTestItem(joint_keychain_data); 1127 keychain_->AddTestItem(joint_keychain_data);
1116 1128
1117 // Insert a password into the keychain only. 1129 // Insert a password into the keychain only.
1118 MockAppleKeychain::KeychainTestData keychain_only_data = { 1130 MockAppleKeychain::KeychainTestData keychain_only_data = {
1119 kSecAuthenticationTypeHTMLForm, "keychain.only.com", 1131 kSecAuthenticationTypeHTMLForm, "keychain.only.com",
1120 kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z", 1132 kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z",
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 if (updates[i].password) { 1185 if (updates[i].password) {
1174 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; 1186 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i;
1175 if (matching_items.size() >= 1) 1187 if (matching_items.size() >= 1)
1176 EXPECT_EQ(ASCIIToUTF16(updates[i].password), 1188 EXPECT_EQ(ASCIIToUTF16(updates[i].password),
1177 matching_items[0]->password_value) << "iteration " << i; 1189 matching_items[0]->password_value) << "iteration " << i;
1178 } else { 1190 } else {
1179 EXPECT_EQ(0U, matching_items.size()) << "iteration " << i; 1191 EXPECT_EQ(0U, matching_items.size()) << "iteration " << i;
1180 } 1192 }
1181 STLDeleteElements(&matching_items); 1193 STLDeleteElements(&matching_items);
1182 1194
1183 login_db_->GetLogins(*query_form, &matching_items); 1195 login_db()->GetLogins(*query_form, &matching_items);
1184 EXPECT_EQ(updates[i].password ? 1U : 0U, matching_items.size()) 1196 EXPECT_EQ(updates[i].password ? 1U : 0U, matching_items.size())
1185 << "iteration " << i; 1197 << "iteration " << i;
1186 STLDeleteElements(&matching_items); 1198 STLDeleteElements(&matching_items);
1187 } 1199 }
1188 } 1200 }
1189 1201
1190 TEST_F(PasswordStoreMacTest, TestDBKeychainAssociation) { 1202 TEST_F(PasswordStoreMacTest, TestDBKeychainAssociation) {
1191 // Tests that association between the keychain and login database parts of a 1203 // Tests that association between the keychain and login database parts of a
1192 // password added by fuzzy (PSL) matching works. 1204 // password added by fuzzy (PSL) matching works.
1193 // 1. Add a password for www.facebook.com 1205 // 1. Add a password for www.facebook.com
1194 // 2. Get a password for m.facebook.com. This fuzzy matches and returns the 1206 // 2. Get a password for m.facebook.com. This fuzzy matches and returns the
1195 // www.facebook.com password. 1207 // www.facebook.com password.
1196 // 3. Add the returned password for m.facebook.com. 1208 // 3. Add the returned password for m.facebook.com.
1197 // 4. Remove both passwords. 1209 // 4. Remove both passwords.
1198 // -> check: that both are gone from the login DB and the keychain 1210 // -> check: that both are gone from the login DB and the keychain
1199 // This test should in particular ensure that we don't keep passwords in the 1211 // This test should in particular ensure that we don't keep passwords in the
1200 // keychain just before we think we still have other (fuzzy-)matching entries 1212 // keychain just before we think we still have other (fuzzy-)matching entries
1201 // for them in the login database. (For example, here if we deleted the 1213 // for them in the login database. (For example, here if we deleted the
1202 // www.facebook.com password from the login database, we should not be blocked 1214 // www.facebook.com password from the login database, we should not be blocked
1203 // from deleting it from the keystore just becaus the m.facebook.com password 1215 // from deleting it from the keystore just becaus the m.facebook.com password
1204 // fuzzy-matches the www.facebook.com one.) 1216 // fuzzy-matches the www.facebook.com one.)
1205 1217
1206 // 1. Add a password for www.facebook.com 1218 // 1. Add a password for www.facebook.com
1207 PasswordFormData www_form_data = { 1219 PasswordFormData www_form_data = {
1208 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1220 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1209 "http://www.facebook.com/index.html", "login", 1221 "http://www.facebook.com/index.html", "login",
1210 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 1222 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
1211 }; 1223 };
1212 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data)); 1224 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data));
1213 login_db_->AddLogin(*www_form); 1225 login_db()->AddLogin(*www_form);
1214 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); 1226 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_);
1215 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 1227 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
1216 owned_keychain_adapter.AddPassword(*www_form); 1228 owned_keychain_adapter.AddPassword(*www_form);
1217 1229
1218 // 2. Get a password for m.facebook.com. 1230 // 2. Get a password for m.facebook.com.
1219 PasswordForm m_form(*www_form); 1231 PasswordForm m_form(*www_form);
1220 m_form.signon_realm = "http://m.facebook.com"; 1232 m_form.signon_realm = "http://m.facebook.com";
1221 m_form.origin = GURL("http://m.facebook.com/index.html"); 1233 m_form.origin = GURL("http://m.facebook.com/index.html");
1222 MockPasswordStoreConsumer consumer; 1234 MockPasswordStoreConsumer consumer;
1223 EXPECT_CALL(consumer, OnGetPasswordStoreResults(_)).WillOnce(DoAll( 1235 EXPECT_CALL(consumer, OnGetPasswordStoreResults(_)).WillOnce(DoAll(
1224 WithArg<0>(Invoke(&consumer, &MockPasswordStoreConsumer::CopyElements)), 1236 WithArg<0>(Invoke(&consumer, &MockPasswordStoreConsumer::CopyElements)),
1225 WithArg<0>(STLDeleteElements0()), 1237 WithArg<0>(STLDeleteElements0()),
1226 QuitUIMessageLoop())); 1238 QuitUIMessageLoop()));
1227 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); 1239 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
1228 base::MessageLoop::current()->Run(); 1240 base::MessageLoop::current()->Run();
1229 EXPECT_EQ(1u, consumer.last_result.size()); 1241 EXPECT_EQ(1u, consumer.last_result.size());
1230 1242
1231 // 3. Add the returned password for m.facebook.com. 1243 // 3. Add the returned password for m.facebook.com.
1232 login_db_->AddLogin(consumer.last_result[0]); 1244 login_db()->AddLogin(consumer.last_result[0]);
1233 owned_keychain_adapter.AddPassword(m_form); 1245 owned_keychain_adapter.AddPassword(m_form);
1234 1246
1235 // 4. Remove both passwords. 1247 // 4. Remove both passwords.
1236 store_->RemoveLogin(*www_form); 1248 store_->RemoveLogin(*www_form);
1237 store_->RemoveLogin(m_form); 1249 store_->RemoveLogin(m_form);
1238 WaitForStoreUpdate(); 1250 WaitForStoreUpdate();
1239 1251
1240 std::vector<PasswordForm*> matching_items; 1252 std::vector<PasswordForm*> matching_items;
1241 // No trace of www.facebook.com. 1253 // No trace of www.facebook.com.
1242 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1254 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1243 www_form->signon_realm, www_form->scheme); 1255 www_form->signon_realm, www_form->scheme);
1244 EXPECT_EQ(0u, matching_items.size()); 1256 EXPECT_EQ(0u, matching_items.size());
1245 login_db_->GetLogins(*www_form, &matching_items); 1257 login_db()->GetLogins(*www_form, &matching_items);
1246 EXPECT_EQ(0u, matching_items.size()); 1258 EXPECT_EQ(0u, matching_items.size());
1247 // No trace of m.facebook.com. 1259 // No trace of m.facebook.com.
1248 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1260 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1249 m_form.signon_realm, m_form.scheme); 1261 m_form.signon_realm, m_form.scheme);
1250 EXPECT_EQ(0u, matching_items.size()); 1262 EXPECT_EQ(0u, matching_items.size());
1251 login_db_->GetLogins(m_form, &matching_items); 1263 login_db()->GetLogins(m_form, &matching_items);
1252 EXPECT_EQ(0u, matching_items.size()); 1264 EXPECT_EQ(0u, matching_items.size());
1253 } 1265 }
1254 1266
1255 namespace { 1267 namespace {
1256 1268
1257 class PasswordsChangeObserver : 1269 class PasswordsChangeObserver :
1258 public password_manager::PasswordStore::Observer { 1270 public password_manager::PasswordStore::Observer {
1259 public: 1271 public:
1260 PasswordsChangeObserver(TestPasswordStoreMac* store) : observer_(this) { 1272 PasswordsChangeObserver(TestPasswordStoreMac* store) : observer_(this) {
1261 observer_.Add(store); 1273 observer_.Add(store);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 // Add a password from the current profile. 1423 // Add a password from the current profile.
1412 PasswordFormData www_form_data2 = { 1424 PasswordFormData www_form_data2 = {
1413 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1425 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1414 "http://www.facebook.com/index.html", "login", L"username", L"password", 1426 "http://www.facebook.com/index.html", "login", L"username", L"password",
1415 L"submit", L"not_joe_user", L"12345", true, false, 1 }; 1427 L"submit", L"not_joe_user", L"12345", true, false, 1 };
1416 www_form.reset(CreatePasswordFormFromData(www_form_data2)); 1428 www_form.reset(CreatePasswordFormFromData(www_form_data2));
1417 store_->AddLogin(*www_form); 1429 store_->AddLogin(*www_form);
1418 WaitForStoreUpdate(); 1430 WaitForStoreUpdate();
1419 1431
1420 ScopedVector<PasswordForm> matching_items; 1432 ScopedVector<PasswordForm> matching_items;
1421 login_db_->GetLogins(*www_form, &matching_items.get()); 1433 login_db()->GetLogins(*www_form, &matching_items.get());
1422 EXPECT_EQ(1u, matching_items.size()); 1434 EXPECT_EQ(1u, matching_items.size());
1423 matching_items.clear(); 1435 matching_items.clear();
1424 1436
1425 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time()); 1437 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time());
1426 WaitForStoreUpdate(); 1438 WaitForStoreUpdate();
1427 1439
1428 // Check the second facebook form is gone. 1440 // Check the second facebook form is gone.
1429 login_db_->GetLogins(*www_form, &matching_items.get()); 1441 login_db()->GetLogins(*www_form, &matching_items.get());
1430 EXPECT_EQ(0u, matching_items.size()); 1442 EXPECT_EQ(0u, matching_items.size());
1431 1443
1432 // Check the first facebook form is still there. 1444 // Check the first facebook form is still there.
1433 matching_items.get() = owned_keychain_adapter.PasswordsFillingForm( 1445 matching_items.get() = owned_keychain_adapter.PasswordsFillingForm(
1434 www_form->signon_realm, www_form->scheme); 1446 www_form->signon_realm, www_form->scheme);
1435 ASSERT_EQ(1u, matching_items.size()); 1447 ASSERT_EQ(1u, matching_items.size());
1436 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value); 1448 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value);
1437 matching_items.clear(); 1449 matching_items.clear();
1438 1450
1439 // Check the third-party password is still there. 1451 // Check the third-party password is still there.
1440 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); 1452 owned_keychain_adapter.SetFindsOnlyOwnedItems(false);
1441 matching_items.get() = owned_keychain_adapter.PasswordsFillingForm( 1453 matching_items.get() = owned_keychain_adapter.PasswordsFillingForm(
1442 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML); 1454 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML);
1443 ASSERT_EQ(1u, matching_items.size()); 1455 ASSERT_EQ(1u, matching_items.size());
1444 } 1456 }
1457
1458 // Verify that operations on a PasswordStore with a bad database cause no
1459 // explosions, but fail without side effect, return no data and trigger no
1460 // notifications.
1461 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) {
1462 store_ = new PasswordStoreMac(base::MessageLoopProxy::current(),
1463 base::MessageLoopProxy::current(), keychain_,
1464 test_login_db_file_path());
1465
1466 password_manager::LoginDatabase::set_simulate_init_failure_for_testing(true);
1467 store_->Init(syncer::SyncableService::StartSyncFlare());
1468 base::MessageLoop::current()->RunUntilIdle();
1469 password_manager::LoginDatabase::set_simulate_init_failure_for_testing(false);
1470 ASSERT_EQ(nullptr, store_->login_metadata_db());
1471
1472 testing::StrictMock<MockPasswordStoreObserver> mock_observer;
1473 store_->AddObserver(&mock_observer);
1474
1475 // Add a new autofillable login + a blacklisted login.
1476 PasswordFormData www_form_data = {
1477 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1478 "http://www.facebook.com/index.html", "login", L"username", L"password",
1479 L"submit", L"not_joe_user", L"12345", true, false, 1 };
1480 scoped_ptr<PasswordForm> form(
1481 CreatePasswordFormFromData(www_form_data));
1482 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form));
1483 blacklisted_form->signon_realm = "http://foo.example.com";
1484 blacklisted_form->origin = GURL("http://foo.example.com/origin");
1485 blacklisted_form->action = GURL("http://foo.example.com/action");
1486 blacklisted_form->blacklisted_by_user = true;
1487 store_->AddLogin(*form);
1488 store_->AddLogin(*blacklisted_form);
1489 base::MessageLoop::current()->RunUntilIdle();
1490
1491 // Get all logins; autofillable logins; blacklisted logins.
1492 testing::StrictMock<MockPasswordStoreConsumer> mock_consumer;
1493 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResults(testing::ElementsAre()));
1494 store_->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer);
1495 base::MessageLoop::current()->RunUntilIdle();
1496 testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1497 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResults(testing::ElementsAre()));
1498 store_->GetAutofillableLogins(&mock_consumer);
1499 base::MessageLoop::current()->RunUntilIdle();
1500 testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1501 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResults(testing::ElementsAre()));
1502 store_->GetBlacklistLogins(&mock_consumer);
1503 base::MessageLoop::current()->RunUntilIdle();
1504
1505 // Report metrics.
1506 store_->ReportMetrics("Test Username", true);
1507 base::MessageLoop::current()->RunUntilIdle();
1508
1509 // Change the login.
1510 form->password_value = base::ASCIIToUTF16("a different password");
1511 store_->UpdateLogin(*form);
1512 base::MessageLoop::current()->RunUntilIdle();
1513
1514 // Delete one login; a range of logins.
1515 store_->RemoveLogin(*form);
1516 base::MessageLoop::current()->RunUntilIdle();
1517 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max());
1518 base::MessageLoop::current()->RunUntilIdle();
1519 store_->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max());
1520 base::MessageLoop::current()->RunUntilIdle();
1521
1522 // Ensure no notifications and no explosions during shutdown either.
1523 store_->RemoveObserver(&mock_observer);
1524 store_->Shutdown();
1525 base::MessageLoop::current()->RunUntilIdle();
1526 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698