| OLD | NEW |
| 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/scoped_observer.h" | 9 #include "base/scoped_observer.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 OnGetPasswordStoreResultsConstRef(results.get()); | 69 OnGetPasswordStoreResultsConstRef(results.get()); |
| 70 } | 70 } |
| 71 }; | 71 }; |
| 72 | 72 |
| 73 class MockPasswordStoreObserver : public PasswordStore::Observer { | 73 class MockPasswordStoreObserver : public PasswordStore::Observer { |
| 74 public: | 74 public: |
| 75 MOCK_METHOD1(OnLoginsChanged, | 75 MOCK_METHOD1(OnLoginsChanged, |
| 76 void(const password_manager::PasswordStoreChangeList& changes)); | 76 void(const password_manager::PasswordStoreChangeList& changes)); |
| 77 }; | 77 }; |
| 78 | 78 |
| 79 // A mock LoginDatabase that simulates a failing Init() method. | |
| 80 class BadLoginDatabase : public password_manager::LoginDatabase { | |
| 81 public: | |
| 82 BadLoginDatabase() : password_manager::LoginDatabase(base::FilePath()) {} | |
| 83 ~BadLoginDatabase() override {} | |
| 84 | |
| 85 // LoginDatabase: | |
| 86 bool Init() override { return false; } | |
| 87 | |
| 88 private: | |
| 89 DISALLOW_COPY_AND_ASSIGN(BadLoginDatabase); | |
| 90 }; | |
| 91 | |
| 92 // A LoginDatabase that simulates an Init() method that takes a long time. | 79 // A LoginDatabase that simulates an Init() method that takes a long time. |
| 93 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { | 80 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { |
| 94 public: | 81 public: |
| 95 // Creates an instance whose Init() method will block until |event| is | 82 // Creates an instance whose Init() method will block until |event| is |
| 96 // signaled. |event| must outlive |this|. | 83 // signaled. |event| must outlive |this|. |
| 97 SlowToInitLoginDatabase(const base::FilePath& db_path, | 84 SlowToInitLoginDatabase(const base::FilePath& db_path, |
| 98 base::WaitableEvent* event) | 85 base::WaitableEvent* event) |
| 99 : password_manager::LoginDatabase(db_path), event_(event) {} | 86 : password_manager::LoginDatabase(db_path), event_(event) {} |
| 100 ~SlowToInitLoginDatabase() override {} | 87 ~SlowToInitLoginDatabase() override {} |
| 101 | 88 |
| 102 // LoginDatabase: | 89 // LoginDatabase: |
| 103 bool Init() override { | 90 bool Init() override { |
| 104 event_->Wait(); | 91 event_->Wait(); |
| 105 return password_manager::LoginDatabase::Init(); | 92 return password_manager::LoginDatabase::Init(); |
| 106 } | 93 } |
| 107 | 94 |
| 108 private: | 95 private: |
| 109 base::WaitableEvent* event_; | 96 base::WaitableEvent* event_; |
| 110 | 97 |
| 111 DISALLOW_COPY_AND_ASSIGN(SlowToInitLoginDatabase); | 98 DISALLOW_COPY_AND_ASSIGN(SlowToInitLoginDatabase); |
| 112 }; | 99 }; |
| 113 | 100 |
| 114 class TestPasswordStoreMac : public PasswordStoreMac { | |
| 115 public: | |
| 116 TestPasswordStoreMac( | |
| 117 scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner, | |
| 118 scoped_refptr<base::SingleThreadTaskRunner> db_thread_runner, | |
| 119 scoped_ptr<crypto::AppleKeychain> keychain, | |
| 120 scoped_ptr<password_manager::LoginDatabase> login_db) | |
| 121 : PasswordStoreMac(main_thread_runner, | |
| 122 db_thread_runner, | |
| 123 keychain.Pass(), | |
| 124 login_db.Pass()) {} | |
| 125 | |
| 126 using PasswordStoreMac::GetBackgroundTaskRunner; | |
| 127 | |
| 128 private: | |
| 129 ~TestPasswordStoreMac() override {} | |
| 130 | |
| 131 DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac); | |
| 132 }; | |
| 133 | |
| 134 #pragma mark - | 101 #pragma mark - |
| 135 | 102 |
| 136 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label. | 103 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label. |
| 137 #define CHECK_FORMS(forms, expectations, i) \ | 104 #define CHECK_FORMS(forms, expectations, i) \ |
| 138 CheckFormsAgainstExpectations(forms, expectations, #forms, i) | 105 CheckFormsAgainstExpectations(forms, expectations, #forms, i) |
| 139 | 106 |
| 140 // Ensures that the data in |forms| match |expectations|, causing test failures | 107 // Ensures that the data in |forms| match |expectations|, causing test failures |
| 141 // for any discrepencies. | 108 // for any discrepencies. |
| 142 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't | 109 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't |
| 143 // matter if |forms| and |expectations| are scrambled. | 110 // matter if |forms| and |expectations| are scrambled. |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 class PasswordStoreMacTest : public testing::Test { | 1170 class PasswordStoreMacTest : public testing::Test { |
| 1204 public: | 1171 public: |
| 1205 PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {} | 1172 PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {} |
| 1206 | 1173 |
| 1207 void SetUp() override { | 1174 void SetUp() override { |
| 1208 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); | 1175 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); |
| 1209 | 1176 |
| 1210 // Ensure that LoginDatabase will use the mock keychain if it needs to | 1177 // Ensure that LoginDatabase will use the mock keychain if it needs to |
| 1211 // encrypt/decrypt a password. | 1178 // encrypt/decrypt a password. |
| 1212 OSCrypt::UseMockKeychain(true); | 1179 OSCrypt::UseMockKeychain(true); |
| 1213 scoped_ptr<password_manager::LoginDatabase> login_db( | 1180 login_db_.reset( |
| 1214 new password_manager::LoginDatabase(test_login_db_file_path())); | 1181 new password_manager::LoginDatabase(test_login_db_file_path())); |
| 1215 CreateAndInitPasswordStore(login_db.Pass()); | 1182 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread")); |
| 1183 ASSERT_TRUE(thread_->Start()); |
| 1184 ASSERT_TRUE(thread_->task_runner()->PostTask( |
| 1185 FROM_HERE, base::Bind(&PasswordStoreMacTest::InitLoginDatabase, |
| 1186 base::Unretained(login_db_.get())))); |
| 1187 CreateAndInitPasswordStore(login_db_.get()); |
| 1216 // Make sure deferred initialization is performed before some tests start | 1188 // Make sure deferred initialization is performed before some tests start |
| 1217 // accessing the |login_db| directly. | 1189 // accessing the |login_db| directly. |
| 1218 FinishAsyncProcessing(); | 1190 FinishAsyncProcessing(); |
| 1219 } | 1191 } |
| 1220 | 1192 |
| 1221 void TearDown() override { | 1193 void TearDown() override { |
| 1222 ClosePasswordStore(); | 1194 ClosePasswordStore(); |
| 1195 thread_.reset(); |
| 1196 login_db_.reset(); |
| 1223 // Whatever a test did, PasswordStoreMac stores only empty password values | 1197 // Whatever a test did, PasswordStoreMac stores only empty password values |
| 1224 // in LoginDatabase. The empty valus do not require encryption and therefore | 1198 // in LoginDatabase. The empty valus do not require encryption and therefore |
| 1225 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the | 1199 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the |
| 1226 // internet passwords. | 1200 // internet passwords. |
| 1227 EXPECT_FALSE(histogram_tester_.GetHistogramSamplesSinceCreation( | 1201 EXPECT_FALSE(histogram_tester_.GetHistogramSamplesSinceCreation( |
| 1228 "OSX.Keychain.Access")); | 1202 "OSX.Keychain.Access")); |
| 1229 } | 1203 } |
| 1230 | 1204 |
| 1231 void CreateAndInitPasswordStore( | 1205 static void InitLoginDatabase(password_manager::LoginDatabase* login_db) { |
| 1232 scoped_ptr<password_manager::LoginDatabase> login_db) { | 1206 ASSERT_TRUE(login_db->Init()); |
| 1233 store_ = new TestPasswordStoreMac( | 1207 } |
| 1234 base::ThreadTaskRunnerHandle::Get(), | 1208 |
| 1235 base::ThreadTaskRunnerHandle::Get(), | 1209 void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) { |
| 1236 make_scoped_ptr<AppleKeychain>(new MockAppleKeychain), login_db.Pass()); | 1210 store_ = new PasswordStoreMac( |
| 1237 ASSERT_TRUE(store_->Init(syncer::SyncableService::StartSyncFlare())); | 1211 base::ThreadTaskRunnerHandle::Get(), nullptr, |
| 1212 make_scoped_ptr<AppleKeychain>(new MockAppleKeychain), login_db); |
| 1213 store_->InitWithTaskRunner(thread_->task_runner()); |
| 1238 } | 1214 } |
| 1239 | 1215 |
| 1240 void ClosePasswordStore() { | 1216 void ClosePasswordStore() { |
| 1241 if (!store_) | 1217 if (!store_) |
| 1242 return; | 1218 return; |
| 1243 | 1219 |
| 1244 store_->Shutdown(); | 1220 store_->Shutdown(); |
| 1245 EXPECT_FALSE(store_->GetBackgroundTaskRunner()); | |
| 1246 base::MessageLoop::current()->RunUntilIdle(); | |
| 1247 store_ = nullptr; | 1221 store_ = nullptr; |
| 1248 } | 1222 } |
| 1249 | 1223 |
| 1250 // Verifies that the given |form| can be properly stored so that it can be | 1224 // Verifies that the given |form| can be properly stored so that it can be |
| 1251 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it | 1225 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it |
| 1252 // can be properly removed. | 1226 // can be properly removed. |
| 1253 void VerifyCredentialLifecycle(const PasswordForm& form) { | 1227 void VerifyCredentialLifecycle(const PasswordForm& form) { |
| 1254 // Run everything twice to make sure no garbage is left behind that would | 1228 // Run everything twice to make sure no garbage is left behind that would |
| 1255 // prevent storing the form a second time. | 1229 // prevent storing the form a second time. |
| 1256 for (size_t iteration = 0; iteration < 2; ++iteration) { | 1230 for (size_t iteration = 0; iteration < 2; ++iteration) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 void FinishAsyncProcessing() { | 1286 void FinishAsyncProcessing() { |
| 1313 // Do a store-level query to wait for all the previously enqueued operations | 1287 // Do a store-level query to wait for all the previously enqueued operations |
| 1314 // to finish. | 1288 // to finish. |
| 1315 MockPasswordStoreConsumer consumer; | 1289 MockPasswordStoreConsumer consumer; |
| 1316 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); | 1290 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); |
| 1317 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(_)) | 1291 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(_)) |
| 1318 .WillOnce(QuitUIMessageLoop()); | 1292 .WillOnce(QuitUIMessageLoop()); |
| 1319 base::MessageLoop::current()->Run(); | 1293 base::MessageLoop::current()->Run(); |
| 1320 } | 1294 } |
| 1321 | 1295 |
| 1322 TestPasswordStoreMac* store() { return store_.get(); } | 1296 PasswordStoreMac* store() { return store_.get(); } |
| 1323 | 1297 |
| 1324 protected: | 1298 protected: |
| 1325 base::MessageLoopForUI message_loop_; | 1299 base::MessageLoopForUI message_loop_; |
| 1326 content::TestBrowserThread ui_thread_; | 1300 content::TestBrowserThread ui_thread_; |
| 1301 // Thread that the synchronous methods are run on. |
| 1302 scoped_ptr<base::Thread> thread_; |
| 1327 | 1303 |
| 1328 base::ScopedTempDir db_dir_; | 1304 base::ScopedTempDir db_dir_; |
| 1329 scoped_refptr<TestPasswordStoreMac> store_; | 1305 scoped_ptr<password_manager::LoginDatabase> login_db_; |
| 1306 scoped_refptr<PasswordStoreMac> store_; |
| 1330 base::HistogramTester histogram_tester_; | 1307 base::HistogramTester histogram_tester_; |
| 1331 }; | 1308 }; |
| 1332 | 1309 |
| 1333 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { | 1310 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { |
| 1334 // Insert a password into both the database and the keychain. | 1311 // Insert a password into both the database and the keychain. |
| 1335 // This is done manually, rather than through store_->AddLogin, because the | 1312 // This is done manually, rather than through store_->AddLogin, because the |
| 1336 // Mock Keychain isn't smart enough to be able to support update generically, | 1313 // Mock Keychain isn't smart enough to be able to support update generically, |
| 1337 // so some.domain.com triggers special handling to test it that make inserting | 1314 // so some.domain.com triggers special handling to test it that make inserting |
| 1338 // fail. | 1315 // fail. |
| 1339 PasswordFormData joint_data = { | 1316 PasswordFormData joint_data = { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1486 EXPECT_EQ(0u, matching_items.size()); | 1463 EXPECT_EQ(0u, matching_items.size()); |
| 1487 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items)); | 1464 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items)); |
| 1488 EXPECT_EQ(0u, matching_items.size()); | 1465 EXPECT_EQ(0u, matching_items.size()); |
| 1489 } | 1466 } |
| 1490 | 1467 |
| 1491 namespace { | 1468 namespace { |
| 1492 | 1469 |
| 1493 class PasswordsChangeObserver : | 1470 class PasswordsChangeObserver : |
| 1494 public password_manager::PasswordStore::Observer { | 1471 public password_manager::PasswordStore::Observer { |
| 1495 public: | 1472 public: |
| 1496 PasswordsChangeObserver(TestPasswordStoreMac* store) : observer_(this) { | 1473 PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) { |
| 1497 observer_.Add(store); | 1474 observer_.Add(store); |
| 1498 } | 1475 } |
| 1499 | 1476 |
| 1500 void WaitAndVerify(PasswordStoreMacTest* test) { | 1477 void WaitAndVerify(PasswordStoreMacTest* test) { |
| 1501 test->FinishAsyncProcessing(); | 1478 test->FinishAsyncProcessing(); |
| 1502 ::testing::Mock::VerifyAndClearExpectations(this); | 1479 ::testing::Mock::VerifyAndClearExpectations(this); |
| 1503 } | 1480 } |
| 1504 | 1481 |
| 1505 // password_manager::PasswordStore::Observer: | 1482 // password_manager::PasswordStore::Observer: |
| 1506 MOCK_METHOD1(OnLoginsChanged, | 1483 MOCK_METHOD1(OnLoginsChanged, |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 } | 1653 } |
| 1677 | 1654 |
| 1678 // Open the store and immediately write to it and try to read it back, without | 1655 // Open the store and immediately write to it and try to read it back, without |
| 1679 // first waiting for the initialization to finish. If tasks are processed in | 1656 // first waiting for the initialization to finish. If tasks are processed in |
| 1680 // order, read/write operations will correctly be performed only after the | 1657 // order, read/write operations will correctly be performed only after the |
| 1681 // initialization has finished. | 1658 // initialization has finished. |
| 1682 TEST_F(PasswordStoreMacTest, StoreIsUsableImmediatelyAfterConstruction) { | 1659 TEST_F(PasswordStoreMacTest, StoreIsUsableImmediatelyAfterConstruction) { |
| 1683 ClosePasswordStore(); | 1660 ClosePasswordStore(); |
| 1684 | 1661 |
| 1685 base::WaitableEvent event(false, false); | 1662 base::WaitableEvent event(false, false); |
| 1686 CreateAndInitPasswordStore(make_scoped_ptr<password_manager::LoginDatabase>( | 1663 login_db_.reset( |
| 1687 new SlowToInitLoginDatabase(test_login_db_file_path(), &event))); | 1664 new SlowToInitLoginDatabase(test_login_db_file_path(), &event)); |
| 1665 ASSERT_TRUE(thread_->task_runner()->PostTask( |
| 1666 FROM_HERE, base::Bind(&PasswordStoreMacTest::InitLoginDatabase, |
| 1667 base::Unretained(login_db_.get())))); |
| 1668 CreateAndInitPasswordStore(login_db_.get()); |
| 1688 | 1669 |
| 1689 PasswordFormData www_form_data = { | 1670 PasswordFormData www_form_data = { |
| 1690 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1671 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| 1691 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1672 "http://www.facebook.com/index.html", "login", L"username", L"password", |
| 1692 L"submit", L"not_joe_user", L"12345", true, false, 1}; | 1673 L"submit", L"not_joe_user", L"12345", true, false, 1}; |
| 1693 scoped_ptr<PasswordForm> form = | 1674 scoped_ptr<PasswordForm> form = |
| 1694 CreatePasswordFormFromDataForTesting(www_form_data); | 1675 CreatePasswordFormFromDataForTesting(www_form_data); |
| 1695 store()->AddLogin(*form); | 1676 store()->AddLogin(*form); |
| 1696 | 1677 |
| 1697 MockPasswordStoreConsumer mock_consumer; | 1678 MockPasswordStoreConsumer mock_consumer; |
| 1698 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer); | 1679 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer); |
| 1699 | 1680 |
| 1700 // Now the read/write tasks are scheduled, let the DB initialization proceed. | 1681 // Now the read/write tasks are scheduled, let the DB initialization proceed. |
| 1701 event.Signal(); | 1682 event.Signal(); |
| 1702 | 1683 |
| 1703 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) | 1684 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
| 1704 .WillOnce(QuitUIMessageLoop()); | 1685 .WillOnce(QuitUIMessageLoop()); |
| 1705 base::MessageLoop::current()->Run(); | 1686 base::MessageLoop::current()->Run(); |
| 1706 EXPECT_TRUE(login_db()); | 1687 EXPECT_TRUE(login_db()); |
| 1707 } | 1688 } |
| 1708 | 1689 |
| 1709 // Verify that operations on a PasswordStore with a bad database cause no | |
| 1710 // explosions, but fail without side effect, return no data and trigger no | |
| 1711 // notifications. | |
| 1712 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) { | |
| 1713 ClosePasswordStore(); | |
| 1714 CreateAndInitPasswordStore( | |
| 1715 make_scoped_ptr<password_manager::LoginDatabase>(new BadLoginDatabase)); | |
| 1716 FinishAsyncProcessing(); | |
| 1717 EXPECT_FALSE(login_db()); | |
| 1718 | |
| 1719 testing::StrictMock<MockPasswordStoreObserver> mock_observer; | |
| 1720 store()->AddObserver(&mock_observer); | |
| 1721 | |
| 1722 // Add a new autofillable login + a blacklisted login. | |
| 1723 PasswordFormData www_form_data = { | |
| 1724 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | |
| 1725 "http://www.facebook.com/index.html", "login", L"username", L"password", | |
| 1726 L"submit", L"not_joe_user", L"12345", true, false, 1}; | |
| 1727 scoped_ptr<PasswordForm> form = | |
| 1728 CreatePasswordFormFromDataForTesting(www_form_data); | |
| 1729 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form)); | |
| 1730 blacklisted_form->signon_realm = "http://foo.example.com"; | |
| 1731 blacklisted_form->origin = GURL("http://foo.example.com/origin"); | |
| 1732 blacklisted_form->action = GURL("http://foo.example.com/action"); | |
| 1733 blacklisted_form->blacklisted_by_user = true; | |
| 1734 store()->AddLogin(*form); | |
| 1735 store()->AddLogin(*blacklisted_form); | |
| 1736 FinishAsyncProcessing(); | |
| 1737 | |
| 1738 // Get all logins; autofillable logins; blacklisted logins. | |
| 1739 MockPasswordStoreConsumer mock_consumer; | |
| 1740 store()->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer); | |
| 1741 ON_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(_)) | |
| 1742 .WillByDefault(QuitUIMessageLoop()); | |
| 1743 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); | |
| 1744 base::MessageLoop::current()->Run(); | |
| 1745 | |
| 1746 store()->GetAutofillableLogins(&mock_consumer); | |
| 1747 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); | |
| 1748 base::MessageLoop::current()->Run(); | |
| 1749 | |
| 1750 store()->GetBlacklistLogins(&mock_consumer); | |
| 1751 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); | |
| 1752 base::MessageLoop::current()->Run(); | |
| 1753 | |
| 1754 // Report metrics. | |
| 1755 store()->ReportMetrics("Test Username", true); | |
| 1756 FinishAsyncProcessing(); | |
| 1757 | |
| 1758 // Change the login. | |
| 1759 form->password_value = base::ASCIIToUTF16("a different password"); | |
| 1760 store()->UpdateLogin(*form); | |
| 1761 FinishAsyncProcessing(); | |
| 1762 | |
| 1763 // Delete one login; a range of logins. | |
| 1764 store()->RemoveLogin(*form); | |
| 1765 store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max()); | |
| 1766 store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max()); | |
| 1767 FinishAsyncProcessing(); | |
| 1768 | |
| 1769 // Verify no notifications are fired during shutdown either. | |
| 1770 ClosePasswordStore(); | |
| 1771 } | |
| 1772 | |
| 1773 // Add a facebook form to the store but not to the keychain. The form is to be | 1690 // Add a facebook form to the store but not to the keychain. The form is to be |
| 1774 // implicitly deleted. However, the observers shouldn't get notified about | 1691 // implicitly deleted. However, the observers shouldn't get notified about |
| 1775 // deletion of non-existent forms like m.facebook.com. | 1692 // deletion of non-existent forms like m.facebook.com. |
| 1776 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { | 1693 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { |
| 1777 testing::StrictMock<MockPasswordStoreObserver> mock_observer; | 1694 testing::StrictMock<MockPasswordStoreObserver> mock_observer; |
| 1778 store()->AddObserver(&mock_observer); | 1695 store()->AddObserver(&mock_observer); |
| 1779 | 1696 |
| 1780 // 1. Add a password for www.facebook.com to the LoginDatabase. | 1697 // 1. Add a password for www.facebook.com to the LoginDatabase. |
| 1781 PasswordFormData www_form_data = { | 1698 PasswordFormData www_form_data = { |
| 1782 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1699 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 // Verify that federated credentials can be stored, retrieved and deleted. | 1751 // Verify that federated credentials can be stored, retrieved and deleted. |
| 1835 TEST_F(PasswordStoreMacTest, StoringAndRetrievingFederatedCredentials) { | 1752 TEST_F(PasswordStoreMacTest, StoringAndRetrievingFederatedCredentials) { |
| 1836 PasswordForm form; | 1753 PasswordForm form; |
| 1837 form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/"; | 1754 form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/"; |
| 1838 form.federation_url = GURL(password_manager::kTestingFederationUrlSpec); | 1755 form.federation_url = GURL(password_manager::kTestingFederationUrlSpec); |
| 1839 form.username_value = base::UTF8ToUTF16("randomusername"); | 1756 form.username_value = base::UTF8ToUTF16("randomusername"); |
| 1840 form.password_value = base::UTF8ToUTF16(""); // No password. | 1757 form.password_value = base::UTF8ToUTF16(""); // No password. |
| 1841 | 1758 |
| 1842 VerifyCredentialLifecycle(form); | 1759 VerifyCredentialLifecycle(form); |
| 1843 } | 1760 } |
| OLD | NEW |