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

Side by Side 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 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 <string> 7 #include <string>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/files/scoped_temp_dir.h" 10 #include "base/files/scoped_temp_dir.h"
11 #include "base/scoped_observer.h" 11 #include "base/scoped_observer.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
16 #include "base/test/histogram_tester.h" 16 #include "base/test/histogram_tester.h"
17 #include "base/thread_task_runner_handle.h" 17 #include "base/thread_task_runner_handle.h"
18 #include "chrome/browser/password_manager/password_store_mac_internal.h" 18 #include "chrome/browser/password_manager/password_store_mac_internal.h"
19 #include "chrome/common/chrome_paths.h" 19 #include "chrome/common/chrome_paths.h"
20 #include "components/os_crypt/os_crypt.h" 20 #include "components/os_crypt/os_crypt.h"
21 #include "components/password_manager/core/browser/login_database.h" 21 #include "components/password_manager/core/browser/login_database.h"
22 #include "components/password_manager/core/browser/password_manager_test_utils.h " 22 #include "components/password_manager/core/browser/password_manager_test_utils.h "
23 #include "components/password_manager/core/browser/password_store_consumer.h" 23 #include "components/password_manager/core/browser/password_store_consumer.h"
24 #include "content/public/test/test_browser_thread.h" 24 #include "components/password_manager/core/browser/password_store_origin_unittes t.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "content/public/test/test_utils.h" 26 #include "content/public/test/test_utils.h"
26 #include "crypto/mock_apple_keychain.h" 27 #include "crypto/mock_apple_keychain.h"
27 #include "testing/gmock/include/gmock/gmock.h" 28 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h" 29 #include "testing/gtest/include/gtest/gtest.h"
29 30
30 using autofill::PasswordForm; 31 using autofill::PasswordForm;
31 using base::ASCIIToUTF16; 32 using base::ASCIIToUTF16;
32 using base::WideToUTF16; 33 using base::WideToUTF16;
33 using content::BrowserThread; 34 using content::BrowserThread;
34 using crypto::MockAppleKeychain; 35 using crypto::MockAppleKeychain;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 public: 70 public:
70 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, 71 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef,
71 void(const std::vector<PasswordForm*>&)); 72 void(const std::vector<PasswordForm*>&));
72 73
73 // GMock cannot mock methods with move-only args. 74 // GMock cannot mock methods with move-only args.
74 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { 75 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override {
75 OnGetPasswordStoreResultsConstRef(results.get()); 76 OnGetPasswordStoreResultsConstRef(results.get());
76 } 77 }
77 }; 78 };
78 79
79 class MockPasswordStoreObserver : public PasswordStore::Observer {
80 public:
81 MOCK_METHOD1(OnLoginsChanged,
82 void(const password_manager::PasswordStoreChangeList& changes));
83 };
84
85 // A LoginDatabase that simulates an Init() method that takes a long time. 80 // A LoginDatabase that simulates an Init() method that takes a long time.
86 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { 81 class SlowToInitLoginDatabase : public password_manager::LoginDatabase {
87 public: 82 public:
88 // Creates an instance whose Init() method will block until |event| is 83 // Creates an instance whose Init() method will block until |event| is
89 // signaled. |event| must outlive |this|. 84 // signaled. |event| must outlive |this|.
90 SlowToInitLoginDatabase(const base::FilePath& db_path, 85 SlowToInitLoginDatabase(const base::FilePath& db_path,
91 base::WaitableEvent* event) 86 base::WaitableEvent* event)
92 : password_manager::LoginDatabase(db_path), event_(event) {} 87 : password_manager::LoginDatabase(db_path), event_(event) {}
93 ~SlowToInitLoginDatabase() override {} 88 ~SlowToInitLoginDatabase() override {}
94 89
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 form->date_synced); 162 form->date_synced);
168 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url); 163 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url);
169 } 164 }
170 } 165 }
171 166
172 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { 167 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) {
173 return PasswordStoreChangeList( 168 return PasswordStoreChangeList(
174 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); 169 1, PasswordStoreChange(PasswordStoreChange::ADD, form));
175 } 170 }
176 171
172 class PasswordStoreMacTestDelegate {
173 public:
174 PasswordStoreMacTestDelegate();
175 ~PasswordStoreMacTestDelegate();
176
177 static void FinishAsyncProcessing() {
vasilii 2015/11/25 18:18:39 Make it out of line.
Timo Reimann 2015/11/26 01:12:52 Done.
178 scoped_refptr<content::MessageLoopRunner> runner =
179 new content::MessageLoopRunner;
180 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
181 FROM_HERE, base::Bind(&Noop), runner->QuitClosure()));
182 runner->Run();
183 }
184
185 PasswordStoreMac* store() const { return store_.get(); }
186
187 PasswordStoreMac* store() { return store_.get(); }
188
189 private:
190 static void InitLoginDatabase(LoginDatabase* login_db);
191 void Initialize();
192 base::FilePath test_login_db_file_path() const;
193
194 void ClosePasswordStore();
195
196 content::TestBrowserThreadBundle thread_bundle_;
197
198 base::ScopedTempDir db_dir_;
199 scoped_ptr<LoginDatabase> login_db_;
200 scoped_refptr<PasswordStoreMac> store_;
201
202 DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate);
203 };
204
205 PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate()
206 : 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
207 Initialize();
208 }
209
210 PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() {
211 ClosePasswordStore();
212 login_db_.reset();
213 }
214
215 void PasswordStoreMacTestDelegate::Initialize() {
216 ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
217
218 // Ensure that LoginDatabase will use the mock keychain if it needs to
219 // encrypt/decrypt a password.
220 OSCrypt::UseMockKeychain(true);
221 login_db_.reset(new LoginDatabase(test_login_db_file_path()));
222 ASSERT_TRUE(BrowserThread::PostTask(
223 BrowserThread::FILE, FROM_HERE,
224 base::Bind(&PasswordStoreMacTestDelegate::InitLoginDatabase,
225 base::Unretained(login_db_.get()))));
226
227 // Creat and initialize the password store.
228 store_ = new PasswordStoreMac(base::ThreadTaskRunnerHandle::Get(), nullptr,
229 make_scoped_ptr(new MockAppleKeychain));
230 ASSERT_TRUE(BrowserThread::PostTask(
231 BrowserThread::FILE, FROM_HERE,
232 base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_,
233 base::ThreadTaskRunnerHandle::Get())));
vasilii 2015/11/25 18:18:39 You set the background task runner as a current ta
234
235 ASSERT_TRUE(BrowserThread::PostTask(
236 BrowserThread::FILE, FROM_HERE,
237 base::Bind(&PasswordStoreMac::set_login_metadata_db, store_,
238 base::Unretained(login_db_.get()))));
239
240 // Make sure deferred initialization is performed before some tests start
241 // accessing the |login_db| directly.
242 FinishAsyncProcessing();
243 }
244
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
245 void PasswordStoreMacTestDelegate::InitLoginDatabase(LoginDatabase* login_db) {
246 ASSERT_TRUE(login_db->Init());
247 }
248
249 base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const {
250 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
251 }
252
253 void PasswordStoreMacTestDelegate::ClosePasswordStore() {
254 store_->ShutdownOnUIThread();
255 FinishAsyncProcessing();
256 }
257
177 } // namespace 258 } // namespace
178 259
260 namespace password_manager {
261
262 INSTANTIATE_TYPED_TEST_CASE_P(Mac,
263 PasswordStoreOriginTest,
264 PasswordStoreMacTestDelegate);
265
266 } // namespace password_manager
267
179 #pragma mark - 268 #pragma mark -
180 269
181 class PasswordStoreMacInternalsTest : public testing::Test { 270 class PasswordStoreMacInternalsTest : public testing::Test {
182 public: 271 public:
183 void SetUp() override { 272 void SetUp() override {
184 MockAppleKeychain::KeychainTestData test_data[] = { 273 MockAppleKeychain::KeychainTestData test_data[] = {
185 // Basic HTML form. 274 // Basic HTML form.
186 {kSecAuthenticationTypeHTMLForm, 275 {kSecAuthenticationTypeHTMLForm,
187 "some.domain.com", 276 "some.domain.com",
188 kSecProtocolTypeHTTP, 277 kSecProtocolTypeHTTP,
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 1257
1169 ScopedVector<autofill::PasswordForm> owned_passwords = 1258 ScopedVector<autofill::PasswordForm> owned_passwords =
1170 owned_keychain_adapter.GetAllPasswordFormPasswords(); 1259 owned_keychain_adapter.GetAllPasswordFormPasswords();
1171 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); 1260 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
1172 } 1261 }
1173 1262
1174 #pragma mark - 1263 #pragma mark -
1175 1264
1176 class PasswordStoreMacTest : public testing::Test { 1265 class PasswordStoreMacTest : public testing::Test {
1177 public: 1266 public:
1178 PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {} 1267 PasswordStoreMacTest() : histogram_tester_(new base::HistogramTester) {}
1179 1268
1180 void SetUp() override { 1269 ~PasswordStoreMacTest() override {
1181 ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
1182 histogram_tester_.reset(new base::HistogramTester);
1183
1184 // Ensure that LoginDatabase will use the mock keychain if it needs to
1185 // encrypt/decrypt a password.
1186 OSCrypt::UseMockKeychain(true);
1187 login_db_.reset(
1188 new password_manager::LoginDatabase(test_login_db_file_path()));
1189 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
1190 ASSERT_TRUE(thread_->Start());
1191 ASSERT_TRUE(thread_->task_runner()->PostTask(
1192 FROM_HERE, base::Bind(&PasswordStoreMacTest::InitLoginDatabase,
1193 base::Unretained(login_db_.get()))));
1194 CreateAndInitPasswordStore(login_db_.get());
1195 // Make sure deferred initialization is performed before some tests start
1196 // accessing the |login_db| directly.
1197 FinishAsyncProcessing();
1198 }
1199
1200 void TearDown() override {
1201 ClosePasswordStore();
1202 thread_.reset();
1203 login_db_.reset();
1204 // Whatever a test did, PasswordStoreMac stores only empty password values 1270 // Whatever a test did, PasswordStoreMac stores only empty password values
1205 // in LoginDatabase. The empty valus do not require encryption and therefore 1271 // in LoginDatabase. The empty valus do not require encryption and therefore
1206 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the 1272 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the
1207 // internet passwords. 1273 // internet passwords.
1208 if (histogram_tester_) { 1274 if (histogram_tester_) {
1209 histogram_tester_->ExpectTotalCount("OSX.Keychain.Access", 0); 1275 histogram_tester_->ExpectTotalCount("OSX.Keychain.Access", 0);
1210 } 1276 }
1211 } 1277 }
1212 1278
1213 static void InitLoginDatabase(password_manager::LoginDatabase* login_db) {
1214 ASSERT_TRUE(login_db->Init());
1215 }
1216
1217 void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) {
1218 store_ = new PasswordStoreMac(
1219 base::ThreadTaskRunnerHandle::Get(), nullptr,
1220 make_scoped_ptr<AppleKeychain>(new MockAppleKeychain));
1221 ASSERT_TRUE(thread_->task_runner()->PostTask(
1222 FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_,
1223 thread_->task_runner())));
1224
1225 ASSERT_TRUE(thread_->task_runner()->PostTask(
1226 FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_,
1227 base::Unretained(login_db))));
1228 }
1229
1230 void ClosePasswordStore() {
1231 if (!store_)
1232 return;
1233
1234 store_->ShutdownOnUIThread();
1235 store_ = nullptr;
1236 }
1237
1238 // Verifies that the given |form| can be properly stored so that it can be 1279 // Verifies that the given |form| can be properly stored so that it can be
1239 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it 1280 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it
1240 // can be properly removed. 1281 // can be properly removed.
1241 void VerifyCredentialLifecycle(const PasswordForm& form) { 1282 void VerifyCredentialLifecycle(const PasswordForm& form) {
1242 // Run everything twice to make sure no garbage is left behind that would 1283 // Run everything twice to make sure no garbage is left behind that would
1243 // prevent storing the form a second time. 1284 // prevent storing the form a second time.
1244 for (size_t iteration = 0; iteration < 2; ++iteration) { 1285 for (size_t iteration = 0; iteration < 2; ++iteration) {
1245 SCOPED_TRACE(testing::Message("Iteration: ") << iteration); 1286 SCOPED_TRACE(testing::Message("Iteration: ") << iteration);
1246 1287
1247 MockPasswordStoreConsumer mock_consumer; 1288 MockPasswordStoreConsumer mock_consumer;
1248 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())) 1289 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()))
1249 .WillOnce(QuitUIMessageLoop()); 1290 .WillOnce(QuitUIMessageLoop());
1250 store()->GetAutofillableLogins(&mock_consumer); 1291 delegate_.store()->GetAutofillableLogins(&mock_consumer);
1251 base::MessageLoop::current()->Run(); 1292 base::MessageLoop::current()->Run();
1252 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); 1293 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1253 1294
1254 store()->AddLogin(form); 1295 delegate_.store()->AddLogin(form);
1255 FinishAsyncProcessing(); 1296 delegate_.FinishAsyncProcessing();
1256 1297
1257 PasswordForm returned_form; 1298 PasswordForm returned_form;
1258 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) 1299 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
1259 .WillOnce( 1300 .WillOnce(
1260 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); 1301 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
1261 1302
1262 // The query operations will also do some housekeeping: they will remove 1303 // The query operations will also do some housekeeping: they will remove
1263 // dangling credentials in the LoginDatabase without a matching Keychain 1304 // dangling credentials in the LoginDatabase without a matching Keychain
1264 // item when one is expected. If the logic that stores the Keychain item 1305 // item when one is expected. If the logic that stores the Keychain item
1265 // is incorrect, this will wipe the newly added form before the second 1306 // is incorrect, this will wipe the newly added form before the second
1266 // query. 1307 // query.
1267 store()->GetAutofillableLogins(&mock_consumer); 1308 delegate_.store()->GetAutofillableLogins(&mock_consumer);
1268 base::MessageLoop::current()->Run(); 1309 base::MessageLoop::current()->Run();
1269 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); 1310 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1270 EXPECT_EQ(form, returned_form); 1311 EXPECT_EQ(form, returned_form);
1271 1312
1272 PasswordForm query_form = form; 1313 PasswordForm query_form = form;
1273 query_form.password_value.clear(); 1314 query_form.password_value.clear();
1274 query_form.username_value.clear(); 1315 query_form.username_value.clear();
1275 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) 1316 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
1276 .WillOnce( 1317 .WillOnce(
1277 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); 1318 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
1278 store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT, 1319 delegate_.store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT,
1279 &mock_consumer); 1320 &mock_consumer);
1280 base::MessageLoop::current()->Run(); 1321 base::MessageLoop::current()->Run();
1281 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); 1322 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1282 EXPECT_EQ(form, returned_form); 1323 EXPECT_EQ(form, returned_form);
1283 1324
1284 store()->RemoveLogin(form); 1325 delegate_.store()->RemoveLogin(form);
1285 } 1326 }
1286 } 1327 }
1287 1328
1288 base::FilePath test_login_db_file_path() const {
1289 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
1290 }
1291
1292 password_manager::LoginDatabase* login_db() const { 1329 password_manager::LoginDatabase* login_db() const {
1293 return store_->login_metadata_db(); 1330 return delegate_.store()->login_metadata_db();
1294 } 1331 }
1295 1332
1296 MockAppleKeychain* keychain() { 1333 MockAppleKeychain* keychain() {
1297 return static_cast<MockAppleKeychain*>(store_->keychain()); 1334 return static_cast<MockAppleKeychain*>(delegate_.store()->keychain());
1298 } 1335 }
1299 1336
1300 void FinishAsyncProcessing() { 1337 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
1301 scoped_refptr<content::MessageLoopRunner> runner =
1302 new content::MessageLoopRunner;
1303 ASSERT_TRUE(thread_->task_runner()->PostTaskAndReply(
1304 FROM_HERE, base::Bind(&Noop), runner->QuitClosure()));
1305 runner->Run();
1306 }
1307
1308 PasswordStoreMac* store() { return store_.get(); }
1309 1338
1310 protected: 1339 protected:
1311 base::MessageLoopForUI message_loop_;
1312 content::TestBrowserThread ui_thread_;
1313 // Thread that the synchronous methods are run on.
1314 scoped_ptr<base::Thread> thread_;
1315
1316 base::ScopedTempDir db_dir_;
1317 scoped_ptr<password_manager::LoginDatabase> login_db_;
1318 scoped_refptr<PasswordStoreMac> store_;
1319 scoped_ptr<base::HistogramTester> histogram_tester_; 1340 scoped_ptr<base::HistogramTester> histogram_tester_;
1341 PasswordStoreMacTestDelegate delegate_;
1320 }; 1342 };
1321 1343
1322 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { 1344 TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
1323 // Insert a password into both the database and the keychain. 1345 // Insert a password into both the database and the keychain.
1324 // This is done manually, rather than through store_->AddLogin, because the 1346 // This is done manually, rather than through delegate_.store()->AddLogin,
1347 // because the
1325 // Mock Keychain isn't smart enough to be able to support update generically, 1348 // Mock Keychain isn't smart enough to be able to support update generically,
1326 // so some.domain.com triggers special handling to test it that make inserting 1349 // so some.domain.com triggers special handling to test it that make inserting
1327 // fail. 1350 // fail.
1328 PasswordFormData joint_data = { 1351 PasswordFormData joint_data = {
1329 PasswordForm::SCHEME_HTML, "http://some.domain.com/", 1352 PasswordForm::SCHEME_HTML, "http://some.domain.com/",
1330 "http://some.domain.com/insecure.html", "login.cgi", 1353 "http://some.domain.com/insecure.html", "login.cgi",
1331 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 1354 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1
1332 }; 1355 };
1333 scoped_ptr<PasswordForm> joint_form = 1356 scoped_ptr<PasswordForm> joint_form =
1334 CreatePasswordFormFromDataForTesting(joint_data); 1357 CreatePasswordFormFromDataForTesting(joint_data);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 { { PasswordForm::SCHEME_HTML, "http://different.com/", 1398 { { PasswordForm::SCHEME_HTML, "http://different.com/",
1376 "http://different.com/index.html", "login.cgi", 1399 "http://different.com/index.html", "login.cgi",
1377 L"username", L"password", L"submit", L"abc", L"123", 1400 L"username", L"password", L"submit", L"abc", L"123",
1378 true, false, 2 }, 1401 true, false, 2 },
1379 NULL, 1402 NULL,
1380 }, 1403 },
1381 }; 1404 };
1382 for (unsigned int i = 0; i < arraysize(updates); ++i) { 1405 for (unsigned int i = 0; i < arraysize(updates); ++i) {
1383 scoped_ptr<PasswordForm> form = 1406 scoped_ptr<PasswordForm> form =
1384 CreatePasswordFormFromDataForTesting(updates[i].form_data); 1407 CreatePasswordFormFromDataForTesting(updates[i].form_data);
1385 store_->UpdateLogin(*form); 1408 delegate_.store()->UpdateLogin(*form);
1386 } 1409 }
1387 1410
1388 FinishAsyncProcessing(); 1411 delegate_.FinishAsyncProcessing();
1389 1412
1390 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); 1413 MacKeychainPasswordFormAdapter keychain_adapter(keychain());
1391 for (unsigned int i = 0; i < arraysize(updates); ++i) { 1414 for (unsigned int i = 0; i < arraysize(updates); ++i) {
1392 scoped_ptr<PasswordForm> query_form = 1415 scoped_ptr<PasswordForm> query_form =
1393 CreatePasswordFormFromDataForTesting(updates[i].form_data); 1416 CreatePasswordFormFromDataForTesting(updates[i].form_data);
1394 1417
1395 ScopedVector<autofill::PasswordForm> matching_items = 1418 ScopedVector<autofill::PasswordForm> matching_items =
1396 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, 1419 keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
1397 query_form->scheme); 1420 query_form->scheme);
1398 if (updates[i].password) { 1421 if (updates[i].password) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); 1461 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain());
1439 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); 1462 owned_keychain_adapter.SetFindsOnlyOwnedItems(true);
1440 owned_keychain_adapter.AddPassword(*www_form); 1463 owned_keychain_adapter.AddPassword(*www_form);
1441 1464
1442 // 2. Get a password for m.facebook.com. 1465 // 2. Get a password for m.facebook.com.
1443 PasswordForm m_form(*www_form); 1466 PasswordForm m_form(*www_form);
1444 m_form.signon_realm = "http://m.facebook.com"; 1467 m_form.signon_realm = "http://m.facebook.com";
1445 m_form.origin = GURL("http://m.facebook.com/index.html"); 1468 m_form.origin = GURL("http://m.facebook.com/index.html");
1446 1469
1447 MockPasswordStoreConsumer consumer; 1470 MockPasswordStoreConsumer consumer;
1448 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); 1471 delegate_.store()->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
1449 PasswordForm returned_form; 1472 PasswordForm returned_form;
1450 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) 1473 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
1451 .WillOnce( 1474 .WillOnce(
1452 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); 1475 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
1453 base::MessageLoop::current()->Run(); 1476 base::MessageLoop::current()->Run();
1454 1477
1455 // 3. Add the returned password for m.facebook.com. 1478 // 3. Add the returned password for m.facebook.com.
1456 returned_form.signon_realm = "http://m.facebook.com"; 1479 returned_form.signon_realm = "http://m.facebook.com";
1457 returned_form.origin = GURL("http://m.facebook.com/index.html"); 1480 returned_form.origin = GURL("http://m.facebook.com/index.html");
1458 EXPECT_EQ(AddChangeForForm(returned_form), 1481 EXPECT_EQ(AddChangeForForm(returned_form),
1459 login_db()->AddLogin(returned_form)); 1482 login_db()->AddLogin(returned_form));
1460 owned_keychain_adapter.AddPassword(m_form); 1483 owned_keychain_adapter.AddPassword(m_form);
1461 1484
1462 // 4. Remove both passwords. 1485 // 4. Remove both passwords.
1463 store_->RemoveLogin(*www_form); 1486 delegate_.store()->RemoveLogin(*www_form);
1464 store_->RemoveLogin(m_form); 1487 delegate_.store()->RemoveLogin(m_form);
1465 FinishAsyncProcessing(); 1488 delegate_.FinishAsyncProcessing();
1466 1489
1467 // No trace of www.facebook.com. 1490 // No trace of www.facebook.com.
1468 ScopedVector<autofill::PasswordForm> matching_items = 1491 ScopedVector<autofill::PasswordForm> matching_items =
1469 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, 1492 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm,
1470 www_form->scheme); 1493 www_form->scheme);
1471 EXPECT_EQ(0u, matching_items.size()); 1494 EXPECT_EQ(0u, matching_items.size());
1472 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); 1495 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
1473 EXPECT_EQ(0u, matching_items.size()); 1496 EXPECT_EQ(0u, matching_items.size());
1474 // No trace of m.facebook.com. 1497 // No trace of m.facebook.com.
1475 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1498 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1476 m_form.signon_realm, m_form.scheme); 1499 m_form.signon_realm, m_form.scheme);
1477 EXPECT_EQ(0u, matching_items.size()); 1500 EXPECT_EQ(0u, matching_items.size());
1478 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items)); 1501 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items));
1479 EXPECT_EQ(0u, matching_items.size()); 1502 EXPECT_EQ(0u, matching_items.size());
1480 } 1503 }
1481 1504
1482 namespace { 1505 namespace {
1483 1506
1484 class PasswordsChangeObserver 1507 class PasswordsChangeObserver
1485 : public password_manager::PasswordStore::Observer { 1508 : public password_manager::PasswordStore::Observer {
1486 public: 1509 public:
1487 explicit PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) { 1510 explicit PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) {
1488 observer_.Add(store); 1511 observer_.Add(store);
1489 } 1512 }
1490 1513
1491 void WaitAndVerify(PasswordStoreMacTest* test) { 1514 void WaitAndVerify(PasswordStoreMacTest* test) {
1492 test->FinishAsyncProcessing(); 1515 test->delegate().FinishAsyncProcessing();
1493 ::testing::Mock::VerifyAndClearExpectations(this); 1516 ::testing::Mock::VerifyAndClearExpectations(this);
1494 } 1517 }
1495 1518
1496 // password_manager::PasswordStore::Observer: 1519 // password_manager::PasswordStore::Observer:
1497 MOCK_METHOD1(OnLoginsChanged, 1520 MOCK_METHOD1(OnLoginsChanged,
1498 void(const password_manager::PasswordStoreChangeList& changes)); 1521 void(const password_manager::PasswordStoreChangeList& changes));
1499 1522
1500 private: 1523 private:
1501 ScopedObserver<password_manager::PasswordStore, PasswordsChangeObserver> 1524 ScopedObserver<password_manager::PasswordStore, PasswordsChangeObserver>
1502 observer_; 1525 observer_;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 if (check_created) { 1559 if (check_created) {
1537 form_facebook_old->date_created = now; 1560 form_facebook_old->date_created = now;
1538 form_facebook->date_created = next_day; 1561 form_facebook->date_created = next_day;
1539 form_other->date_created = next_day; 1562 form_other->date_created = next_day;
1540 } else { 1563 } else {
1541 form_facebook_old->date_synced = now; 1564 form_facebook_old->date_synced = now;
1542 form_facebook->date_synced = next_day; 1565 form_facebook->date_synced = next_day;
1543 form_other->date_synced = next_day; 1566 form_other->date_synced = next_day;
1544 } 1567 }
1545 1568
1546 PasswordsChangeObserver observer(test->store()); 1569 PasswordsChangeObserver observer(test->delegate().store());
1547 test->store()->AddLogin(*form_facebook_old); 1570 test->delegate().store()->AddLogin(*form_facebook_old);
1548 test->store()->AddLogin(*form_facebook); 1571 test->delegate().store()->AddLogin(*form_facebook);
1549 test->store()->AddLogin(*form_other); 1572 test->delegate().store()->AddLogin(*form_other);
1550 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook_old))); 1573 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook_old)));
1551 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook))); 1574 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook)));
1552 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_other))); 1575 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_other)));
1553 observer.WaitAndVerify(test); 1576 observer.WaitAndVerify(test);
1554 1577
1555 // Check the keychain content. 1578 // Check the keychain content.
1556 MacKeychainPasswordFormAdapter owned_keychain_adapter(test->keychain()); 1579 MacKeychainPasswordFormAdapter owned_keychain_adapter(test->keychain());
1557 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); 1580 owned_keychain_adapter.SetFindsOnlyOwnedItems(false);
1558 ScopedVector<PasswordForm> matching_items( 1581 ScopedVector<PasswordForm> matching_items(
1559 owned_keychain_adapter.PasswordsFillingForm(form_facebook->signon_realm, 1582 owned_keychain_adapter.PasswordsFillingForm(form_facebook->signon_realm,
1560 form_facebook->scheme)); 1583 form_facebook->scheme));
1561 EXPECT_EQ(1u, matching_items.size()); 1584 EXPECT_EQ(1u, matching_items.size());
1562 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1585 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1563 form_other->signon_realm, form_other->scheme); 1586 form_other->signon_realm, form_other->scheme);
1564 EXPECT_EQ(1u, matching_items.size()); 1587 EXPECT_EQ(1u, matching_items.size());
1565 1588
1566 // Remove facebook. 1589 // Remove facebook.
1567 if (check_created) { 1590 if (check_created) {
1568 test->store()->RemoveLoginsCreatedBetween(base::Time(), next_day, 1591 test->delegate().store()->RemoveLoginsCreatedBetween(base::Time(), next_day,
1569 base::Closure()); 1592 base::Closure());
1570 } else { 1593 } else {
1571 test->store()->RemoveLoginsSyncedBetween(base::Time(), next_day); 1594 test->delegate().store()->RemoveLoginsSyncedBetween(base::Time(), next_day);
1572 } 1595 }
1573 password_manager::PasswordStoreChangeList list; 1596 password_manager::PasswordStoreChangeList list;
1574 form_facebook_old->password_value.clear(); 1597 form_facebook_old->password_value.clear();
1575 form_facebook->password_value.clear(); 1598 form_facebook->password_value.clear();
1576 list.push_back(password_manager::PasswordStoreChange( 1599 list.push_back(password_manager::PasswordStoreChange(
1577 password_manager::PasswordStoreChange::REMOVE, *form_facebook_old)); 1600 password_manager::PasswordStoreChange::REMOVE, *form_facebook_old));
1578 list.push_back(password_manager::PasswordStoreChange( 1601 list.push_back(password_manager::PasswordStoreChange(
1579 password_manager::PasswordStoreChange::REMOVE, *form_facebook)); 1602 password_manager::PasswordStoreChange::REMOVE, *form_facebook));
1580 EXPECT_CALL(observer, OnLoginsChanged(list)); 1603 EXPECT_CALL(observer, OnLoginsChanged(list));
1581 list.clear(); 1604 list.clear();
1582 observer.WaitAndVerify(test); 1605 observer.WaitAndVerify(test);
1583 1606
1584 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1607 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1585 form_facebook->signon_realm, form_facebook->scheme); 1608 form_facebook->signon_realm, form_facebook->scheme);
1586 EXPECT_EQ(0u, matching_items.size()); 1609 EXPECT_EQ(0u, matching_items.size());
1587 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1610 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1588 form_other->signon_realm, form_other->scheme); 1611 form_other->signon_realm, form_other->scheme);
1589 EXPECT_EQ(1u, matching_items.size()); 1612 EXPECT_EQ(1u, matching_items.size());
1590 1613
1591 // Remove form_other. 1614 // Remove form_other.
1592 if (check_created) { 1615 if (check_created) {
1593 test->store()->RemoveLoginsCreatedBetween(next_day, base::Time(), 1616 test->delegate().store()->RemoveLoginsCreatedBetween(next_day, base::Time(),
1594 base::Closure()); 1617 base::Closure());
1595 } else { 1618 } else {
1596 test->store()->RemoveLoginsSyncedBetween(next_day, base::Time()); 1619 test->delegate().store()->RemoveLoginsSyncedBetween(next_day, base::Time());
1597 } 1620 }
1598 form_other->password_value.clear(); 1621 form_other->password_value.clear();
1599 list.push_back(password_manager::PasswordStoreChange( 1622 list.push_back(password_manager::PasswordStoreChange(
1600 password_manager::PasswordStoreChange::REMOVE, *form_other)); 1623 password_manager::PasswordStoreChange::REMOVE, *form_other));
1601 EXPECT_CALL(observer, OnLoginsChanged(list)); 1624 EXPECT_CALL(observer, OnLoginsChanged(list));
1602 observer.WaitAndVerify(test); 1625 observer.WaitAndVerify(test);
1603 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1626 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1604 form_other->signon_realm, form_other->scheme); 1627 form_other->signon_realm, form_other->scheme);
1605 EXPECT_EQ(0u, matching_items.size()); 1628 EXPECT_EQ(0u, matching_items.size());
1606 } 1629 }
(...skipping 30 matching lines...) Expand all
1637 scoped_ptr<PasswordForm> www_form = 1660 scoped_ptr<PasswordForm> www_form =
1638 CreatePasswordFormFromDataForTesting(www_form_data1); 1661 CreatePasswordFormFromDataForTesting(www_form_data1);
1639 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); 1662 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form));
1640 1663
1641 // Add a password from the current profile. 1664 // Add a password from the current profile.
1642 PasswordFormData www_form_data2 = { 1665 PasswordFormData www_form_data2 = {
1643 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1666 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1644 "http://www.facebook.com/index.html", "login", L"username", L"password", 1667 "http://www.facebook.com/index.html", "login", L"username", L"password",
1645 L"submit", L"not_joe_user", L"12345", true, false, 1 }; 1668 L"submit", L"not_joe_user", L"12345", true, false, 1 };
1646 www_form = CreatePasswordFormFromDataForTesting(www_form_data2); 1669 www_form = CreatePasswordFormFromDataForTesting(www_form_data2);
1647 store_->AddLogin(*www_form); 1670 delegate_.store()->AddLogin(*www_form);
1648 FinishAsyncProcessing(); 1671 delegate_.FinishAsyncProcessing();
1649 1672
1650 ScopedVector<PasswordForm> matching_items; 1673 ScopedVector<PasswordForm> matching_items;
1651 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); 1674 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
1652 EXPECT_EQ(1u, matching_items.size()); 1675 EXPECT_EQ(1u, matching_items.size());
1653 1676
1654 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time(), 1677 delegate_.store()->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
1655 base::Closure()); 1678 base::Closure());
1656 FinishAsyncProcessing(); 1679 delegate_.FinishAsyncProcessing();
1657 1680
1658 // Check the second facebook form is gone. 1681 // Check the second facebook form is gone.
1659 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); 1682 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
1660 EXPECT_EQ(0u, matching_items.size()); 1683 EXPECT_EQ(0u, matching_items.size());
1661 1684
1662 // Check the first facebook form is still there. 1685 // Check the first facebook form is still there.
1663 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1686 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1664 www_form->signon_realm, www_form->scheme); 1687 www_form->signon_realm, www_form->scheme);
1665 ASSERT_EQ(1u, matching_items.size()); 1688 ASSERT_EQ(1u, matching_items.size());
1666 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value); 1689 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value);
1667 1690
1668 // Check the third-party password is still there. 1691 // Check the third-party password is still there.
1669 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); 1692 owned_keychain_adapter.SetFindsOnlyOwnedItems(false);
1670 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1693 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1671 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML); 1694 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML);
1672 ASSERT_EQ(1u, matching_items.size()); 1695 ASSERT_EQ(1u, matching_items.size());
1673 } 1696 }
1674 1697
1675 // Add a facebook form to the store but not to the keychain. The form is to be 1698 // Add a facebook form to the store but not to the keychain. The form is to be
1676 // implicitly deleted. However, the observers shouldn't get notified about 1699 // implicitly deleted. However, the observers shouldn't get notified about
1677 // deletion of non-existent forms like m.facebook.com. 1700 // deletion of non-existent forms like m.facebook.com.
1678 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { 1701 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) {
1679 testing::StrictMock<MockPasswordStoreObserver> mock_observer; 1702 testing::StrictMock<password_manager::MockPasswordStoreObserver>
1680 store()->AddObserver(&mock_observer); 1703 mock_observer;
1704 delegate_.store()->AddObserver(&mock_observer);
1681 1705
1682 // 1. Add a password for www.facebook.com to the LoginDatabase. 1706 // 1. Add a password for www.facebook.com to the LoginDatabase.
1683 PasswordFormData www_form_data = { 1707 PasswordFormData www_form_data = {
1684 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1708 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1685 "http://www.facebook.com/index.html", "login", 1709 "http://www.facebook.com/index.html", "login",
1686 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 1710 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1
1687 }; 1711 };
1688 scoped_ptr<PasswordForm> www_form( 1712 scoped_ptr<PasswordForm> www_form(
1689 CreatePasswordFormFromDataForTesting(www_form_data)); 1713 CreatePasswordFormFromDataForTesting(www_form_data));
1690 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form)); 1714 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form));
1691 1715
1692 // 2. Get a PSL-matched password for m.facebook.com. The observer isn't 1716 // 2. Get a PSL-matched password for m.facebook.com. The observer isn't
1693 // notified because the form isn't in the database. 1717 // notified because the form isn't in the database.
1694 PasswordForm m_form(*www_form); 1718 PasswordForm m_form(*www_form);
1695 m_form.signon_realm = "http://m.facebook.com"; 1719 m_form.signon_realm = "http://m.facebook.com";
1696 m_form.origin = GURL("http://m.facebook.com/index.html"); 1720 m_form.origin = GURL("http://m.facebook.com/index.html");
1697 1721
1698 MockPasswordStoreConsumer consumer; 1722 MockPasswordStoreConsumer consumer;
1699 ON_CALL(consumer, OnGetPasswordStoreResultsConstRef(_)) 1723 ON_CALL(consumer, OnGetPasswordStoreResultsConstRef(_))
1700 .WillByDefault(QuitUIMessageLoop()); 1724 .WillByDefault(QuitUIMessageLoop());
1701 EXPECT_CALL(mock_observer, OnLoginsChanged(_)).Times(0); 1725 EXPECT_CALL(mock_observer, OnLoginsChanged(_)).Times(0);
1702 // The PSL-matched form isn't returned because there is no actual password in 1726 // The PSL-matched form isn't returned because there is no actual password in
1703 // the keychain. 1727 // the keychain.
1704 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); 1728 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
1705 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); 1729 delegate_.store()->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer);
1706 base::MessageLoop::current()->Run(); 1730 base::MessageLoop::current()->Run();
1707 ScopedVector<autofill::PasswordForm> all_forms; 1731 ScopedVector<autofill::PasswordForm> all_forms;
1708 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms)); 1732 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms));
1709 EXPECT_EQ(1u, all_forms.size()); 1733 EXPECT_EQ(1u, all_forms.size());
1710 ::testing::Mock::VerifyAndClearExpectations(&mock_observer); 1734 ::testing::Mock::VerifyAndClearExpectations(&mock_observer);
1711 1735
1712 // 3. Get a password for www.facebook.com. The form is implicitly removed and 1736 // 3. Get a password for www.facebook.com. The form is implicitly removed and
1713 // the observer is notified. 1737 // the observer is notified.
1714 password_manager::PasswordStoreChangeList list; 1738 password_manager::PasswordStoreChangeList list;
1715 list.push_back(password_manager::PasswordStoreChange( 1739 list.push_back(password_manager::PasswordStoreChange(
1716 password_manager::PasswordStoreChange::REMOVE, *www_form)); 1740 password_manager::PasswordStoreChange::REMOVE, *www_form));
1717 EXPECT_CALL(mock_observer, OnLoginsChanged(list)); 1741 EXPECT_CALL(mock_observer, OnLoginsChanged(list));
1718 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); 1742 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()));
1719 store_->GetLogins(*www_form, PasswordStore::ALLOW_PROMPT, &consumer); 1743 delegate_.store()->GetLogins(*www_form, PasswordStore::ALLOW_PROMPT,
1744 &consumer);
1720 base::MessageLoop::current()->Run(); 1745 base::MessageLoop::current()->Run();
1721 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms)); 1746 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms));
1722 EXPECT_EQ(0u, all_forms.size()); 1747 EXPECT_EQ(0u, all_forms.size());
1723 } 1748 }
1724 1749
1725 // Verify that Android app passwords can be stored, retrieved, and deleted. 1750 // Verify that Android app passwords can be stored, retrieved, and deleted.
1726 // Regression test for http://crbug.com/455551 1751 // Regression test for http://crbug.com/455551
1727 TEST_F(PasswordStoreMacTest, StoringAndRetrievingAndroidCredentials) { 1752 TEST_F(PasswordStoreMacTest, StoringAndRetrievingAndroidCredentials) {
1728 PasswordForm form; 1753 PasswordForm form;
1729 form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/"; 1754 form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/";
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1762 form2.origin = GURL("http://facebook.com/Login"); 1787 form2.origin = GURL("http://facebook.com/Login");
1763 form2.signon_realm = "http://facebook.com/"; 1788 form2.signon_realm = "http://facebook.com/";
1764 form2.username_value = ASCIIToUTF16("my_username"); 1789 form2.username_value = ASCIIToUTF16("my_username");
1765 form2.password_value = ASCIIToUTF16("my_password"); 1790 form2.password_value = ASCIIToUTF16("my_password");
1766 1791
1767 PasswordForm blacklisted_form; 1792 PasswordForm blacklisted_form;
1768 blacklisted_form.origin = GURL("http://badsite.com/Login"); 1793 blacklisted_form.origin = GURL("http://badsite.com/Login");
1769 blacklisted_form.signon_realm = "http://badsite.com/"; 1794 blacklisted_form.signon_realm = "http://badsite.com/";
1770 blacklisted_form.blacklisted_by_user = true; 1795 blacklisted_form.blacklisted_by_user = true;
1771 1796
1772 store()->AddLogin(form1); 1797 delegate_.store()->AddLogin(form1);
1773 store()->AddLogin(form2); 1798 delegate_.store()->AddLogin(form2);
1774 store()->AddLogin(blacklisted_form); 1799 delegate_.store()->AddLogin(blacklisted_form);
1775 FinishAsyncProcessing(); 1800 delegate_.FinishAsyncProcessing();
1776 1801
1777 ASSERT_TRUE(base::PostTaskAndReplyWithResult( 1802 ASSERT_TRUE(base::PostTaskAndReplyWithResult(
1778 thread_->task_runner().get(), FROM_HERE, 1803 base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
1779 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), 1804 base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()),
1780 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); 1805 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
1781 FinishAsyncProcessing(); 1806 delegate_.FinishAsyncProcessing();
1782 1807
1783 // The password should be stored in the database by now. 1808 // The password should be stored in the database by now.
1784 ScopedVector<PasswordForm> matching_items; 1809 ScopedVector<PasswordForm> matching_items;
1785 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); 1810 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
1786 ASSERT_EQ(1u, matching_items.size()); 1811 ASSERT_EQ(1u, matching_items.size());
1787 EXPECT_EQ(form1, *matching_items[0]); 1812 EXPECT_EQ(form1, *matching_items[0]);
1788 1813
1789 EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items)); 1814 EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items));
1790 ASSERT_EQ(1u, matching_items.size()); 1815 ASSERT_EQ(1u, matching_items.size());
1791 EXPECT_EQ(form2, *matching_items[0]); 1816 EXPECT_EQ(form2, *matching_items[0]);
(...skipping 10 matching lines...) Expand all
1802 1827
1803 // Import a federated credential while the Keychain is locked. 1828 // Import a federated credential while the Keychain is locked.
1804 TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) { 1829 TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) {
1805 keychain()->set_locked(true); 1830 keychain()->set_locked(true);
1806 PasswordForm form1; 1831 PasswordForm form1;
1807 form1.origin = GURL("http://example.com/Login"); 1832 form1.origin = GURL("http://example.com/Login");
1808 form1.signon_realm = "http://example.com/"; 1833 form1.signon_realm = "http://example.com/";
1809 form1.username_value = ASCIIToUTF16("my_username"); 1834 form1.username_value = ASCIIToUTF16("my_username");
1810 form1.federation_url = GURL("https://accounts.google.com/"); 1835 form1.federation_url = GURL("https://accounts.google.com/");
1811 1836
1812 store()->AddLogin(form1); 1837 delegate_.store()->AddLogin(form1);
1813 FinishAsyncProcessing(); 1838 delegate_.FinishAsyncProcessing();
1814 ASSERT_TRUE(base::PostTaskAndReplyWithResult( 1839 ASSERT_TRUE(base::PostTaskAndReplyWithResult(
1815 thread_->task_runner().get(), FROM_HERE, 1840 base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
vasilii 2015/11/25 18:18:39 You post to the current thread here.
1816 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), 1841 base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()),
1817 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); 1842 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
1818 FinishAsyncProcessing(); 1843 delegate_.FinishAsyncProcessing();
1819 1844
1820 ScopedVector<PasswordForm> matching_items; 1845 ScopedVector<PasswordForm> matching_items;
1821 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); 1846 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
1822 ASSERT_EQ(1u, matching_items.size()); 1847 ASSERT_EQ(1u, matching_items.size());
1823 EXPECT_EQ(form1, *matching_items[0]); 1848 EXPECT_EQ(form1, *matching_items[0]);
1824 } 1849 }
1825 1850
1826 // Try to import while the Keychain is locked but the encryption key had been 1851 // Try to import while the Keychain is locked but the encryption key had been
1827 // read earlier. 1852 // read earlier.
1828 TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) { 1853 TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) {
1829 PasswordForm form1; 1854 PasswordForm form1;
1830 form1.origin = GURL("http://accounts.google.com/LoginAuth"); 1855 form1.origin = GURL("http://accounts.google.com/LoginAuth");
1831 form1.signon_realm = "http://accounts.google.com/"; 1856 form1.signon_realm = "http://accounts.google.com/";
1832 form1.username_value = ASCIIToUTF16("my_username"); 1857 form1.username_value = ASCIIToUTF16("my_username");
1833 form1.password_value = ASCIIToUTF16("my_password"); 1858 form1.password_value = ASCIIToUTF16("my_password");
1834 store()->AddLogin(form1); 1859 delegate_.store()->AddLogin(form1);
1835 FinishAsyncProcessing(); 1860 delegate_.FinishAsyncProcessing();
1836 1861
1837 // Add a second keychain item matching the Database entry. 1862 // Add a second keychain item matching the Database entry.
1838 PasswordForm form2 = form1; 1863 PasswordForm form2 = form1;
1839 form2.origin = GURL("http://accounts.google.com/Login"); 1864 form2.origin = GURL("http://accounts.google.com/Login");
1840 form2.password_value = ASCIIToUTF16("1234"); 1865 form2.password_value = ASCIIToUTF16("1234");
1841 MacKeychainPasswordFormAdapter adapter(keychain()); 1866 MacKeychainPasswordFormAdapter adapter(keychain());
1842 EXPECT_TRUE(adapter.AddPassword(form2)); 1867 EXPECT_TRUE(adapter.AddPassword(form2));
1843 1868
1844 keychain()->set_locked(true); 1869 keychain()->set_locked(true);
1845 ASSERT_TRUE(base::PostTaskAndReplyWithResult( 1870 ASSERT_TRUE(base::PostTaskAndReplyWithResult(
1846 thread_->task_runner().get(), FROM_HERE, 1871 base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE,
vasilii 2015/11/25 18:18:39 Same here.
1847 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), 1872 base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()),
1848 base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED))); 1873 base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED)));
1849 FinishAsyncProcessing(); 1874 delegate_.FinishAsyncProcessing();
1850 1875
1851 ScopedVector<PasswordForm> matching_items; 1876 ScopedVector<PasswordForm> matching_items;
1852 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); 1877 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
1853 ASSERT_EQ(1u, matching_items.size()); 1878 ASSERT_EQ(1u, matching_items.size());
1854 EXPECT_EQ(base::string16(), matching_items[0]->password_value); 1879 EXPECT_EQ(base::string16(), matching_items[0]->password_value);
1855 1880
1856 histogram_tester_->ExpectUniqueSample( 1881 histogram_tester_->ExpectUniqueSample(
1857 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); 1882 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1);
1858 histogram_tester_->ExpectUniqueSample( 1883 histogram_tester_->ExpectUniqueSample(
1859 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); 1884 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1);
1860 histogram_tester_->ExpectUniqueSample( 1885 histogram_tester_->ExpectUniqueSample(
1861 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", 1886 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords",
1862 2, 1); 1887 2, 1);
1863 // Don't test the encryption key access. 1888 // Don't test the encryption key access.
1864 histogram_tester_.reset(); 1889 histogram_tester_.reset();
1865 } 1890 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698