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 |