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" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/synchronization/waitable_event.h" | 13 #include "base/synchronization/waitable_event.h" |
14 #include "chrome/browser/password_manager/password_store_mac_internal.h" | 14 #include "chrome/browser/password_manager/password_store_mac_internal.h" |
15 #include "chrome/common/chrome_paths.h" | 15 #include "chrome/common/chrome_paths.h" |
16 #include "components/password_manager/core/browser/login_database.h" | 16 #include "components/password_manager/core/browser/login_database.h" |
| 17 #include "components/password_manager/core/browser/password_form_data.h" |
17 #include "components/password_manager/core/browser/password_store_consumer.h" | 18 #include "components/password_manager/core/browser/password_store_consumer.h" |
18 #include "content/public/test/test_browser_thread.h" | 19 #include "content/public/test/test_browser_thread.h" |
19 #include "crypto/mock_apple_keychain.h" | 20 #include "crypto/mock_apple_keychain.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 | 23 |
23 using autofill::PasswordForm; | 24 using autofill::PasswordForm; |
24 using base::ASCIIToUTF16; | 25 using base::ASCIIToUTF16; |
25 using base::WideToUTF16; | 26 using base::WideToUTF16; |
26 using content::BrowserThread; | 27 using content::BrowserThread; |
27 using crypto::MockAppleKeychain; | 28 using crypto::MockAppleKeychain; |
28 using internal_keychain_helpers::FormsMatchForMerge; | 29 using internal_keychain_helpers::FormsMatchForMerge; |
29 using internal_keychain_helpers::STRICT_FORM_MATCH; | 30 using internal_keychain_helpers::STRICT_FORM_MATCH; |
30 using password_manager::LoginDatabase; | 31 using password_manager::LoginDatabase; |
31 using password_manager::PasswordStore; | 32 using password_manager::PasswordStore; |
32 using password_manager::PasswordStoreConsumer; | 33 using password_manager::PasswordStoreConsumer; |
33 using testing::_; | 34 using testing::_; |
34 using testing::DoAll; | 35 using testing::DoAll; |
35 using testing::Invoke; | 36 using testing::Invoke; |
| 37 using testing::IsEmpty; |
| 38 using testing::SizeIs; |
36 using testing::WithArg; | 39 using testing::WithArg; |
37 | 40 |
38 namespace { | 41 namespace { |
39 | 42 |
40 ACTION(STLDeleteElements0) { | |
41 STLDeleteContainerPointers(arg0.begin(), arg0.end()); | |
42 } | |
43 | |
44 ACTION(QuitUIMessageLoop) { | 43 ACTION(QuitUIMessageLoop) { |
45 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
46 base::MessageLoop::current()->Quit(); | 45 base::MessageLoop::current()->Quit(); |
47 } | 46 } |
48 | 47 |
| 48 // From the mock's argument #0 of type const std::vector<PasswordForm*>& takes |
| 49 // the first form and copies it to the form pointed to by |target_form_ptr|. |
| 50 ACTION_P(SaveACopyOfFirstForm, target_form_ptr) { |
| 51 ASSERT_FALSE(arg0.empty()); |
| 52 *target_form_ptr = *arg0[0]; |
| 53 } |
| 54 |
49 class MockPasswordStoreConsumer : public PasswordStoreConsumer { | 55 class MockPasswordStoreConsumer : public PasswordStoreConsumer { |
50 public: | 56 public: |
51 MOCK_METHOD1(OnGetPasswordStoreResults, | 57 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, |
52 void(const std::vector<autofill::PasswordForm*>&)); | 58 void(const std::vector<PasswordForm*>&)); |
53 | 59 |
54 void CopyElements(const std::vector<autofill::PasswordForm*>& forms) { | 60 // GMock cannot mock methods with move-only args. |
55 last_result.clear(); | 61 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { |
56 for (size_t i = 0; i < forms.size(); ++i) { | 62 OnGetPasswordStoreResultsConstRef(results.get()); |
57 last_result.push_back(*forms[i]); | |
58 } | |
59 } | 63 } |
60 | |
61 // Runs the current thread's message loop until OnGetPasswordStoreResults() | |
62 // is posted to it. This method should be called immediately after GetLogins, | |
63 // without pumping the message loop in-between. | |
64 void WaitOnGetPasswordStoreResults() { | |
65 EXPECT_CALL(*this, OnGetPasswordStoreResults(_)).WillOnce(DoAll( | |
66 WithArg<0>(Invoke(this, &MockPasswordStoreConsumer::CopyElements)), | |
67 WithArg<0>(STLDeleteElements0()), | |
68 QuitUIMessageLoop())); | |
69 base::MessageLoop::current()->Run(); | |
70 } | |
71 | |
72 std::vector<PasswordForm> last_result; | |
73 }; | 64 }; |
74 | 65 |
75 class MockPasswordStoreObserver : public PasswordStore::Observer { | 66 class MockPasswordStoreObserver : public PasswordStore::Observer { |
76 public: | 67 public: |
77 MOCK_METHOD1(OnLoginsChanged, | 68 MOCK_METHOD1(OnLoginsChanged, |
78 void(const password_manager::PasswordStoreChangeList& changes)); | 69 void(const password_manager::PasswordStoreChangeList& changes)); |
79 }; | 70 }; |
80 | 71 |
81 // A mock LoginDatabase that simulates a failing Init() method. | 72 // A mock LoginDatabase that simulates a failing Init() method. |
82 class BadLoginDatabase : public password_manager::LoginDatabase { | 73 class BadLoginDatabase : public password_manager::LoginDatabase { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 login_db.Pass()) {} | 117 login_db.Pass()) {} |
127 | 118 |
128 using PasswordStoreMac::GetBackgroundTaskRunner; | 119 using PasswordStoreMac::GetBackgroundTaskRunner; |
129 | 120 |
130 private: | 121 private: |
131 ~TestPasswordStoreMac() override {} | 122 ~TestPasswordStoreMac() override {} |
132 | 123 |
133 DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac); | 124 DISALLOW_COPY_AND_ASSIGN(TestPasswordStoreMac); |
134 }; | 125 }; |
135 | 126 |
136 } // namespace | |
137 | |
138 #pragma mark - | |
139 | |
140 class PasswordStoreMacInternalsTest : public testing::Test { | |
141 public: | |
142 void SetUp() override { | |
143 MockAppleKeychain::KeychainTestData test_data[] = { | |
144 // Basic HTML form. | |
145 { kSecAuthenticationTypeHTMLForm, "some.domain.com", | |
146 kSecProtocolTypeHTTP, NULL, 0, NULL, "20020601171500Z", | |
147 "joe_user", "sekrit", false }, | |
148 // HTML form with path. | |
149 { kSecAuthenticationTypeHTMLForm, "some.domain.com", | |
150 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "19991231235959Z", | |
151 "joe_user", "sekrit", false }, | |
152 // Secure HTML form with path. | |
153 { kSecAuthenticationTypeHTMLForm, "some.domain.com", | |
154 kSecProtocolTypeHTTPS, "/secure.html", 0, NULL, "20100908070605Z", | |
155 "secure_user", "password", false }, | |
156 // True negative item. | |
157 { kSecAuthenticationTypeHTMLForm, "dont.remember.com", | |
158 kSecProtocolTypeHTTP, NULL, 0, NULL, "20000101000000Z", | |
159 "", "", true }, | |
160 // De-facto negative item, type one. | |
161 { kSecAuthenticationTypeHTMLForm, "dont.remember.com", | |
162 kSecProtocolTypeHTTP, NULL, 0, NULL, "20000101000000Z", | |
163 "Password Not Stored", "", false }, | |
164 // De-facto negative item, type two. | |
165 { kSecAuthenticationTypeHTMLForm, "dont.remember.com", | |
166 kSecProtocolTypeHTTPS, NULL, 0, NULL, "20000101000000Z", | |
167 "Password Not Stored", " ", false }, | |
168 // HTTP auth basic, with port and path. | |
169 { kSecAuthenticationTypeHTTPBasic, "some.domain.com", | |
170 kSecProtocolTypeHTTP, "/insecure.html", 4567, "low_security", | |
171 "19980330100000Z", | |
172 "basic_auth_user", "basic", false }, | |
173 // HTTP auth digest, secure. | |
174 { kSecAuthenticationTypeHTTPDigest, "some.domain.com", | |
175 kSecProtocolTypeHTTPS, NULL, 0, "high_security", "19980330100000Z", | |
176 "digest_auth_user", "digest", false }, | |
177 // An FTP password with an invalid date, for edge-case testing. | |
178 { kSecAuthenticationTypeDefault, "a.server.com", | |
179 kSecProtocolTypeFTP, NULL, 0, NULL, "20010203040", | |
180 "abc", "123", false }, | |
181 }; | |
182 | |
183 keychain_ = new MockAppleKeychain(); | |
184 | |
185 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | |
186 keychain_->AddTestItem(test_data[i]); | |
187 } | |
188 } | |
189 | |
190 void TearDown() override { | |
191 ExpectCreatesAndFreesBalanced(); | |
192 ExpectCreatorCodesSet(); | |
193 delete keychain_; | |
194 } | |
195 | |
196 protected: | |
197 // Causes a test failure unless everything returned from keychain_'s | |
198 // ItemCopyAttributesAndData, SearchCreateFromAttributes, and SearchCopyNext | |
199 // was correctly freed. | |
200 void ExpectCreatesAndFreesBalanced() { | |
201 EXPECT_EQ(0, keychain_->UnfreedSearchCount()); | |
202 EXPECT_EQ(0, keychain_->UnfreedKeychainItemCount()); | |
203 EXPECT_EQ(0, keychain_->UnfreedAttributeDataCount()); | |
204 } | |
205 | |
206 // Causes a test failure unless any Keychain items added during the test have | |
207 // their creator code set. | |
208 void ExpectCreatorCodesSet() { | |
209 EXPECT_TRUE(keychain_->CreatorCodesSetForAddedItems()); | |
210 } | |
211 | |
212 MockAppleKeychain* keychain_; | |
213 }; | |
214 | |
215 #pragma mark - | 127 #pragma mark - |
216 | 128 |
217 // Struct used for creation of PasswordForms from static arrays of data. | 129 // Struct used for creation of PasswordForms from static arrays of data. |
218 struct PasswordFormData { | 130 struct PasswordFormData { |
219 const PasswordForm::Scheme scheme; | 131 const PasswordForm::Scheme scheme; |
220 const char* signon_realm; | 132 const char* signon_realm; |
221 const char* origin; | 133 const char* origin; |
222 const char* action; | 134 const char* action; |
223 const wchar_t* submit_element; | 135 const wchar_t* submit_element; |
224 const wchar_t* username_element; | 136 const wchar_t* username_element; |
225 const wchar_t* password_element; | 137 const wchar_t* password_element; |
226 const wchar_t* username_value; // Set to NULL for a blacklist entry. | 138 const wchar_t* username_value; // Set to NULL for a blacklist entry. |
227 const wchar_t* password_value; | 139 const wchar_t* password_value; |
228 const bool preferred; | 140 const bool preferred; |
229 const bool ssl_valid; | 141 const bool ssl_valid; |
230 const double creation_time; | 142 const double creation_time; |
231 }; | 143 }; |
232 | 144 |
233 // Creates and returns a new PasswordForm built from form_data. Caller is | 145 // Creates and returns a new PasswordForm built from form_data. |
234 // responsible for deleting the object when finished with it. | 146 scoped_ptr<PasswordForm> CreatePasswordFormFromData( |
235 static PasswordForm* CreatePasswordFormFromData( | |
236 const PasswordFormData& form_data) { | 147 const PasswordFormData& form_data) { |
237 PasswordForm* form = new PasswordForm(); | 148 scoped_ptr<PasswordForm> form(new PasswordForm()); |
238 form->scheme = form_data.scheme; | 149 form->scheme = form_data.scheme; |
239 form->preferred = form_data.preferred; | 150 form->preferred = form_data.preferred; |
240 form->ssl_valid = form_data.ssl_valid; | 151 form->ssl_valid = form_data.ssl_valid; |
241 form->date_created = base::Time::FromDoubleT(form_data.creation_time); | 152 form->date_created = base::Time::FromDoubleT(form_data.creation_time); |
242 form->date_synced = form->date_created + base::TimeDelta::FromDays(1); | 153 form->date_synced = form->date_created + base::TimeDelta::FromDays(1); |
243 if (form_data.signon_realm) | 154 if (form_data.signon_realm) |
244 form->signon_realm = std::string(form_data.signon_realm); | 155 form->signon_realm = std::string(form_data.signon_realm); |
245 if (form_data.origin) | 156 if (form_data.origin) |
246 form->origin = GURL(form_data.origin); | 157 form->origin = GURL(form_data.origin); |
247 if (form_data.action) | 158 if (form_data.action) |
248 form->action = GURL(form_data.action); | 159 form->action = GURL(form_data.action); |
249 if (form_data.submit_element) | 160 if (form_data.submit_element) |
250 form->submit_element = WideToUTF16(form_data.submit_element); | 161 form->submit_element = WideToUTF16(form_data.submit_element); |
251 if (form_data.username_element) | 162 if (form_data.username_element) |
252 form->username_element = WideToUTF16(form_data.username_element); | 163 form->username_element = WideToUTF16(form_data.username_element); |
253 if (form_data.password_element) | 164 if (form_data.password_element) |
254 form->password_element = WideToUTF16(form_data.password_element); | 165 form->password_element = WideToUTF16(form_data.password_element); |
255 if (form_data.username_value) { | 166 if (form_data.username_value) { |
256 form->username_value = WideToUTF16(form_data.username_value); | 167 form->username_value = WideToUTF16(form_data.username_value); |
257 form->display_name = form->username_value; | 168 form->display_name = form->username_value; |
258 form->skip_zero_click = true; | 169 form->skip_zero_click = true; |
259 if (form_data.password_value) | 170 if (form_data.password_value) |
260 form->password_value = WideToUTF16(form_data.password_value); | 171 form->password_value = WideToUTF16(form_data.password_value); |
261 } else { | 172 } else { |
262 form->blacklisted_by_user = true; | 173 form->blacklisted_by_user = true; |
263 } | 174 } |
264 form->avatar_url = GURL("https://accounts.google.com/Avatar"); | 175 form->avatar_url = GURL("https://accounts.google.com/Avatar"); |
265 form->federation_url = GURL("https://accounts.google.com/login"); | 176 form->federation_url = GURL("https://accounts.google.com/login"); |
266 return form; | 177 return form.Pass(); |
267 } | 178 } |
268 | 179 |
269 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label. | 180 // Macro to simplify calling CheckFormsAgainstExpectations with a useful label. |
270 #define CHECK_FORMS(forms, expectations, i) \ | 181 #define CHECK_FORMS(forms, expectations, i) \ |
271 CheckFormsAgainstExpectations(forms, expectations, #forms, i) | 182 CheckFormsAgainstExpectations(forms, expectations, #forms, i) |
272 | 183 |
273 // Ensures that the data in |forms| match |expectations|, causing test failures | 184 // Ensures that the data in |forms| match |expectations|, causing test failures |
274 // for any discrepencies. | 185 // for any discrepencies. |
275 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't | 186 // TODO(stuartmorgan): This is current order-dependent; ideally it shouldn't |
276 // matter if |forms| and |expectations| are scrambled. | 187 // matter if |forms| and |expectations| are scrambled. |
277 static void CheckFormsAgainstExpectations( | 188 void CheckFormsAgainstExpectations( |
278 const std::vector<PasswordForm*>& forms, | 189 const std::vector<PasswordForm*>& forms, |
279 const std::vector<PasswordFormData*>& expectations, | 190 const std::vector<PasswordFormData*>& expectations, |
280 const char* forms_label, unsigned int test_number) { | 191 const char* forms_label, |
| 192 unsigned int test_number) { |
281 const unsigned int kBufferSize = 128; | 193 const unsigned int kBufferSize = 128; |
282 char test_label[kBufferSize]; | 194 char test_label[kBufferSize]; |
283 snprintf(test_label, kBufferSize, "%s in test %u", forms_label, test_number); | 195 snprintf(test_label, kBufferSize, "%s in test %u", forms_label, test_number); |
284 | 196 |
285 EXPECT_EQ(expectations.size(), forms.size()) << test_label; | 197 EXPECT_EQ(expectations.size(), forms.size()) << test_label; |
286 if (expectations.size() != forms.size()) | 198 if (expectations.size() != forms.size()) |
287 return; | 199 return; |
288 | 200 |
289 for (unsigned int i = 0; i < expectations.size(); ++i) { | 201 for (unsigned int i = 0; i < expectations.size(); ++i) { |
290 snprintf(test_label, kBufferSize, "%s in test %u, item %u", | 202 snprintf(test_label, kBufferSize, "%s in test %u, item %u", |
(...skipping 27 matching lines...) Expand all Loading... |
318 EXPECT_DOUBLE_EQ(expectation->creation_time, | 230 EXPECT_DOUBLE_EQ(expectation->creation_time, |
319 form->date_created.ToDoubleT()) << test_label; | 231 form->date_created.ToDoubleT()) << test_label; |
320 base::Time created = base::Time::FromDoubleT(expectation->creation_time); | 232 base::Time created = base::Time::FromDoubleT(expectation->creation_time); |
321 EXPECT_EQ(created + base::TimeDelta::FromDays(1), | 233 EXPECT_EQ(created + base::TimeDelta::FromDays(1), |
322 form->date_synced) << test_label; | 234 form->date_synced) << test_label; |
323 EXPECT_EQ(GURL("https://accounts.google.com/Avatar"), form->avatar_url); | 235 EXPECT_EQ(GURL("https://accounts.google.com/Avatar"), form->avatar_url); |
324 EXPECT_EQ(GURL("https://accounts.google.com/login"), form->federation_url); | 236 EXPECT_EQ(GURL("https://accounts.google.com/login"), form->federation_url); |
325 } | 237 } |
326 } | 238 } |
327 | 239 |
| 240 } // namespace |
| 241 |
| 242 #pragma mark - |
| 243 |
| 244 class PasswordStoreMacInternalsTest : public testing::Test { |
| 245 public: |
| 246 void SetUp() override { |
| 247 MockAppleKeychain::KeychainTestData test_data[] = { |
| 248 // Basic HTML form. |
| 249 {kSecAuthenticationTypeHTMLForm, |
| 250 "some.domain.com", |
| 251 kSecProtocolTypeHTTP, |
| 252 NULL, |
| 253 0, |
| 254 NULL, |
| 255 "20020601171500Z", |
| 256 "joe_user", |
| 257 "sekrit", |
| 258 false}, |
| 259 // HTML form with path. |
| 260 {kSecAuthenticationTypeHTMLForm, |
| 261 "some.domain.com", |
| 262 kSecProtocolTypeHTTP, |
| 263 "/insecure.html", |
| 264 0, |
| 265 NULL, |
| 266 "19991231235959Z", |
| 267 "joe_user", |
| 268 "sekrit", |
| 269 false}, |
| 270 // Secure HTML form with path. |
| 271 {kSecAuthenticationTypeHTMLForm, |
| 272 "some.domain.com", |
| 273 kSecProtocolTypeHTTPS, |
| 274 "/secure.html", |
| 275 0, |
| 276 NULL, |
| 277 "20100908070605Z", |
| 278 "secure_user", |
| 279 "password", |
| 280 false}, |
| 281 // True negative item. |
| 282 {kSecAuthenticationTypeHTMLForm, |
| 283 "dont.remember.com", |
| 284 kSecProtocolTypeHTTP, |
| 285 NULL, |
| 286 0, |
| 287 NULL, |
| 288 "20000101000000Z", |
| 289 "", |
| 290 "", |
| 291 true}, |
| 292 // De-facto negative item, type one. |
| 293 {kSecAuthenticationTypeHTMLForm, |
| 294 "dont.remember.com", |
| 295 kSecProtocolTypeHTTP, |
| 296 NULL, |
| 297 0, |
| 298 NULL, |
| 299 "20000101000000Z", |
| 300 "Password Not Stored", |
| 301 "", |
| 302 false}, |
| 303 // De-facto negative item, type two. |
| 304 {kSecAuthenticationTypeHTMLForm, |
| 305 "dont.remember.com", |
| 306 kSecProtocolTypeHTTPS, |
| 307 NULL, |
| 308 0, |
| 309 NULL, |
| 310 "20000101000000Z", |
| 311 "Password Not Stored", |
| 312 " ", |
| 313 false}, |
| 314 // HTTP auth basic, with port and path. |
| 315 {kSecAuthenticationTypeHTTPBasic, |
| 316 "some.domain.com", |
| 317 kSecProtocolTypeHTTP, |
| 318 "/insecure.html", |
| 319 4567, |
| 320 "low_security", |
| 321 "19980330100000Z", |
| 322 "basic_auth_user", |
| 323 "basic", |
| 324 false}, |
| 325 // HTTP auth digest, secure. |
| 326 {kSecAuthenticationTypeHTTPDigest, |
| 327 "some.domain.com", |
| 328 kSecProtocolTypeHTTPS, |
| 329 NULL, |
| 330 0, |
| 331 "high_security", |
| 332 "19980330100000Z", |
| 333 "digest_auth_user", |
| 334 "digest", |
| 335 false}, |
| 336 // An FTP password with an invalid date, for edge-case testing. |
| 337 {kSecAuthenticationTypeDefault, |
| 338 "a.server.com", |
| 339 kSecProtocolTypeFTP, |
| 340 NULL, |
| 341 0, |
| 342 NULL, |
| 343 "20010203040", |
| 344 "abc", |
| 345 "123", |
| 346 false}, |
| 347 }; |
| 348 |
| 349 keychain_ = new MockAppleKeychain(); |
| 350 |
| 351 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
| 352 keychain_->AddTestItem(test_data[i]); |
| 353 } |
| 354 } |
| 355 |
| 356 void TearDown() override { |
| 357 ExpectCreatesAndFreesBalanced(); |
| 358 ExpectCreatorCodesSet(); |
| 359 delete keychain_; |
| 360 } |
| 361 |
| 362 protected: |
| 363 // Causes a test failure unless everything returned from keychain_'s |
| 364 // ItemCopyAttributesAndData, SearchCreateFromAttributes, and SearchCopyNext |
| 365 // was correctly freed. |
| 366 void ExpectCreatesAndFreesBalanced() { |
| 367 EXPECT_EQ(0, keychain_->UnfreedSearchCount()); |
| 368 EXPECT_EQ(0, keychain_->UnfreedKeychainItemCount()); |
| 369 EXPECT_EQ(0, keychain_->UnfreedAttributeDataCount()); |
| 370 } |
| 371 |
| 372 // Causes a test failure unless any Keychain items added during the test have |
| 373 // their creator code set. |
| 374 void ExpectCreatorCodesSet() { |
| 375 EXPECT_TRUE(keychain_->CreatorCodesSetForAddedItems()); |
| 376 } |
| 377 |
| 378 MockAppleKeychain* keychain_; |
| 379 }; |
| 380 |
328 #pragma mark - | 381 #pragma mark - |
329 | 382 |
330 TEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) { | 383 TEST_F(PasswordStoreMacInternalsTest, TestKeychainToFormTranslation) { |
331 typedef struct { | 384 typedef struct { |
332 const PasswordForm::Scheme scheme; | 385 const PasswordForm::Scheme scheme; |
333 const char* signon_realm; | 386 const char* signon_realm; |
334 const char* origin; | 387 const char* origin; |
335 const wchar_t* username; // Set to NULL to check for a blacklist entry. | 388 const wchar_t* username; // Set to NULL to check for a blacklist entry. |
336 const wchar_t* password; | 389 const wchar_t* password; |
337 const bool ssl_valid; | 390 const bool ssl_valid; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 0, 0 }, | 523 0, 0 }, |
471 // Garbage forms should have no matches. | 524 // Garbage forms should have no matches. |
472 { { PasswordForm::SCHEME_HTML, "foo/bar/baz", | 525 { { PasswordForm::SCHEME_HTML, "foo/bar/baz", |
473 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, | 526 NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, 0 }, 0, 0 }, |
474 }; | 527 }; |
475 | 528 |
476 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 529 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
477 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 530 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
478 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 531 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
479 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 532 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
480 scoped_ptr<PasswordForm> query_form( | 533 scoped_ptr<PasswordForm> query_form = |
481 CreatePasswordFormFromData(test_data[i].data)); | 534 CreatePasswordFormFromData(test_data[i].data); |
482 | 535 |
483 // Check matches treating the form as a fill target. | 536 // Check matches treating the form as a fill target. |
484 ScopedVector<autofill::PasswordForm> matching_items = | 537 ScopedVector<autofill::PasswordForm> matching_items = |
485 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, | 538 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, |
486 query_form->scheme); | 539 query_form->scheme); |
487 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); | 540 EXPECT_EQ(test_data[i].expected_fill_matches, matching_items.size()); |
488 matching_items.clear(); | 541 matching_items.clear(); |
489 | 542 |
490 // Check matches treating the form as a merging target. | 543 // Check matches treating the form as a merging target. |
491 EXPECT_EQ(test_data[i].expected_merge_matches > 0, | 544 EXPECT_EQ(test_data[i].expected_merge_matches > 0, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", | 603 { PasswordForm::SCHEME_BASIC, "http://some.domain.com:4567/low_security", |
551 "http://some.domain.com:4567/insecure.html", | 604 "http://some.domain.com:4567/insecure.html", |
552 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, | 605 NULL, NULL, NULL, NULL, L"basic_auth_user", NULL, true, false, 0 }, |
553 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", | 606 { PasswordForm::SCHEME_DIGEST, "https://some.domain.com/high_security", |
554 "https://some.domain.com", | 607 "https://some.domain.com", |
555 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, | 608 NULL, NULL, NULL, NULL, L"digest_auth_user", NULL, true, true, 0 }, |
556 }; | 609 }; |
557 | 610 |
558 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { | 611 for (unsigned int i = 0; i < arraysize(base_form_data); ++i) { |
559 // Create a base form and make sure we find a match. | 612 // Create a base form and make sure we find a match. |
560 scoped_ptr<PasswordForm> base_form(CreatePasswordFormFromData( | 613 scoped_ptr<PasswordForm> base_form = |
561 base_form_data[i])); | 614 CreatePasswordFormFromData(base_form_data[i]); |
562 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); | 615 EXPECT_TRUE(keychain_adapter.HasPasswordsMergeableWithForm(*base_form)); |
563 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form)); | 616 EXPECT_TRUE(keychain_adapter.HasPasswordExactlyMatchingForm(*base_form)); |
564 | 617 |
565 // Make sure that the matching isn't looser than it should be by checking | 618 // Make sure that the matching isn't looser than it should be by checking |
566 // that slightly altered forms don't match. | 619 // that slightly altered forms don't match. |
567 ScopedVector<autofill::PasswordForm> modified_forms; | 620 ScopedVector<autofill::PasswordForm> modified_forms; |
568 | 621 |
569 modified_forms.push_back(new PasswordForm(*base_form)); | 622 modified_forms.push_back(new PasswordForm(*base_form)); |
570 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); | 623 modified_forms.back()->username_value = ASCIIToUTF16("wrong_user"); |
571 | 624 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 // reported. | 677 // reported. |
625 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", | 678 { { PasswordForm::SCHEME_HTML, "http://some.domain.com", |
626 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, | 679 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, |
627 L"joe_user", L"fail_me", false, false, 0 }, false }, | 680 L"joe_user", L"fail_me", false, false, 0 }, false }, |
628 }; | 681 }; |
629 | 682 |
630 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 683 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
631 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 684 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
632 | 685 |
633 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 686 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
634 scoped_ptr<PasswordForm> in_form( | 687 scoped_ptr<PasswordForm> in_form = |
635 CreatePasswordFormFromData(test_data[i].data)); | 688 CreatePasswordFormFromData(test_data[i].data); |
636 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); | 689 bool add_succeeded = owned_keychain_adapter.AddPassword(*in_form); |
637 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); | 690 EXPECT_EQ(test_data[i].should_succeed, add_succeeded); |
638 if (add_succeeded) { | 691 if (add_succeeded) { |
639 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( | 692 EXPECT_TRUE(owned_keychain_adapter.HasPasswordsMergeableWithForm( |
640 *in_form)); | 693 *in_form)); |
641 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( | 694 EXPECT_TRUE(owned_keychain_adapter.HasPasswordExactlyMatchingForm( |
642 *in_form)); | 695 *in_form)); |
643 } | 696 } |
644 } | 697 } |
645 | 698 |
646 // Test that adding duplicate item updates the existing item. | 699 // Test that adding duplicate item updates the existing item. |
647 { | 700 { |
648 PasswordFormData data = { | 701 PasswordFormData data = { |
649 PasswordForm::SCHEME_HTML, "http://some.domain.com", | 702 PasswordForm::SCHEME_HTML, "http://some.domain.com", |
650 "http://some.domain.com/insecure.html", NULL, | 703 "http://some.domain.com/insecure.html", NULL, |
651 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 | 704 NULL, NULL, NULL, L"joe_user", L"updated_password", false, false, 0 |
652 }; | 705 }; |
653 scoped_ptr<PasswordForm> update_form(CreatePasswordFormFromData(data)); | 706 scoped_ptr<PasswordForm> update_form = CreatePasswordFormFromData(data); |
654 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 707 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
655 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); | 708 EXPECT_TRUE(keychain_adapter.AddPassword(*update_form)); |
656 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); | 709 SecKeychainItemRef keychain_item = reinterpret_cast<SecKeychainItemRef>(2); |
657 PasswordForm stored_form; | 710 PasswordForm stored_form; |
658 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, | 711 internal_keychain_helpers::FillPasswordFormFromKeychainItem(*keychain_, |
659 keychain_item, | 712 keychain_item, |
660 &stored_form, | 713 &stored_form, |
661 true); | 714 true); |
662 EXPECT_EQ(update_form->password_value, stored_form.password_value); | 715 EXPECT_EQ(update_form->password_value, stored_form.password_value); |
663 } | 716 } |
(...skipping 12 matching lines...) Expand all Loading... |
676 // Make sure we don't delete items we don't own. | 729 // Make sure we don't delete items we don't own. |
677 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 730 { { PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
678 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, | 731 "http://some.domain.com/insecure.html", NULL, NULL, NULL, NULL, |
679 L"joe_user", NULL, true, false, 0 }, false }, | 732 L"joe_user", NULL, true, false, 0 }, false }, |
680 }; | 733 }; |
681 | 734 |
682 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); | 735 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain_); |
683 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 736 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
684 | 737 |
685 // Add our test item so that we can delete it. | 738 // Add our test item so that we can delete it. |
686 PasswordForm* add_form = CreatePasswordFormFromData(test_data[0].data); | 739 scoped_ptr<PasswordForm> add_form = |
| 740 CreatePasswordFormFromData(test_data[0].data); |
687 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); | 741 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*add_form)); |
688 delete add_form; | |
689 | 742 |
690 for (unsigned int i = 0; i < arraysize(test_data); ++i) { | 743 for (unsigned int i = 0; i < arraysize(test_data); ++i) { |
691 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( | 744 scoped_ptr<PasswordForm> form = |
692 test_data[i].data)); | 745 CreatePasswordFormFromData(test_data[i].data); |
693 EXPECT_EQ(test_data[i].should_succeed, | 746 EXPECT_EQ(test_data[i].should_succeed, |
694 owned_keychain_adapter.RemovePassword(*form)); | 747 owned_keychain_adapter.RemovePassword(*form)); |
695 | 748 |
696 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); | 749 MacKeychainPasswordFormAdapter keychain_adapter(keychain_); |
697 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); | 750 bool match = keychain_adapter.HasPasswordExactlyMatchingForm(*form); |
698 EXPECT_EQ(test_data[i].should_succeed, !match); | 751 EXPECT_EQ(test_data[i].should_succeed, !match); |
699 } | 752 } |
700 } | 753 } |
701 | 754 |
702 TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) { | 755 TEST_F(PasswordStoreMacInternalsTest, TestFormMatch) { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path); | 936 test_data[DATABASE_INPUT][current_test].push_back(&db_user_1_with_path); |
884 test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); | 937 test_data[MERGE_OUTPUT][current_test].push_back(&merged_user_1); |
885 test_data[MERGE_OUTPUT][current_test].push_back( | 938 test_data[MERGE_OUTPUT][current_test].push_back( |
886 &merged_user_1_with_both_paths); | 939 &merged_user_1_with_both_paths); |
887 | 940 |
888 for (unsigned int test_case = 0; test_case <= current_test; ++test_case) { | 941 for (unsigned int test_case = 0; test_case <= current_test; ++test_case) { |
889 ScopedVector<autofill::PasswordForm> keychain_forms; | 942 ScopedVector<autofill::PasswordForm> keychain_forms; |
890 for (std::vector<PasswordFormData*>::iterator i = | 943 for (std::vector<PasswordFormData*>::iterator i = |
891 test_data[KEYCHAIN_INPUT][test_case].begin(); | 944 test_data[KEYCHAIN_INPUT][test_case].begin(); |
892 i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) { | 945 i != test_data[KEYCHAIN_INPUT][test_case].end(); ++i) { |
893 keychain_forms.push_back(CreatePasswordFormFromData(*(*i))); | 946 keychain_forms.push_back(CreatePasswordFormFromData(*(*i)).release()); |
894 } | 947 } |
895 ScopedVector<autofill::PasswordForm> database_forms; | 948 ScopedVector<autofill::PasswordForm> database_forms; |
896 for (std::vector<PasswordFormData*>::iterator i = | 949 for (std::vector<PasswordFormData*>::iterator i = |
897 test_data[DATABASE_INPUT][test_case].begin(); | 950 test_data[DATABASE_INPUT][test_case].begin(); |
898 i != test_data[DATABASE_INPUT][test_case].end(); ++i) { | 951 i != test_data[DATABASE_INPUT][test_case].end(); ++i) { |
899 database_forms.push_back(CreatePasswordFormFromData(*(*i))); | 952 database_forms.push_back(CreatePasswordFormFromData(*(*i)).release()); |
900 } | 953 } |
901 | 954 |
902 ScopedVector<autofill::PasswordForm> merged_forms; | 955 ScopedVector<autofill::PasswordForm> merged_forms; |
903 internal_keychain_helpers::MergePasswordForms(&keychain_forms, | 956 internal_keychain_helpers::MergePasswordForms(&keychain_forms, |
904 &database_forms, | 957 &database_forms, |
905 &merged_forms); | 958 &merged_forms); |
906 | 959 |
907 CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case], | 960 CHECK_FORMS(keychain_forms.get(), test_data[KEYCHAIN_OUTPUT][test_case], |
908 test_case); | 961 test_case); |
909 CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case], | 962 CHECK_FORMS(database_forms.get(), test_data[DATABASE_OUTPUT][test_case], |
(...skipping 24 matching lines...) Expand all Loading... |
934 "http://dont.remember.com/handlepage.cgi", | 987 "http://dont.remember.com/handlepage.cgi", |
935 L"submit", L"username", L"password", L"joe_user", L"", | 988 L"submit", L"username", L"password", L"joe_user", L"", |
936 true, false, 1240000000 }, | 989 true, false, 1240000000 }, |
937 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 990 { PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
938 "http://some.domain.com/path.html", "http://some.domain.com/action.cgi", | 991 "http://some.domain.com/path.html", "http://some.domain.com/action.cgi", |
939 L"submit", L"username", L"password", NULL, NULL, | 992 L"submit", L"username", L"password", NULL, NULL, |
940 true, false, 1212121212 }, | 993 true, false, 1212121212 }, |
941 }; | 994 }; |
942 ScopedVector<autofill::PasswordForm> database_forms; | 995 ScopedVector<autofill::PasswordForm> database_forms; |
943 for (unsigned int i = 0; i < arraysize(db_data); ++i) { | 996 for (unsigned int i = 0; i < arraysize(db_data); ++i) { |
944 database_forms.push_back(CreatePasswordFormFromData(db_data[i])); | 997 database_forms.push_back(CreatePasswordFormFromData(db_data[i]).release()); |
945 } | 998 } |
946 ScopedVector<autofill::PasswordForm> merged_forms; | 999 ScopedVector<autofill::PasswordForm> merged_forms; |
947 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 1000 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
948 &merged_forms); | 1001 &merged_forms); |
949 EXPECT_EQ(2U, database_forms.size()); | 1002 EXPECT_EQ(2U, database_forms.size()); |
950 ASSERT_EQ(3U, merged_forms.size()); | 1003 ASSERT_EQ(3U, merged_forms.size()); |
951 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value); | 1004 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[0]->password_value); |
952 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value); | 1005 EXPECT_EQ(ASCIIToUTF16("sekrit"), merged_forms[1]->password_value); |
953 EXPECT_TRUE(merged_forms[2]->blacklisted_by_user); | 1006 EXPECT_TRUE(merged_forms[2]->blacklisted_by_user); |
954 } | 1007 } |
955 | 1008 |
956 TEST_F(PasswordStoreMacInternalsTest, TestBlacklistedFiltering) { | 1009 TEST_F(PasswordStoreMacInternalsTest, TestBlacklistedFiltering) { |
957 PasswordFormData db_data[] = { | 1010 PasswordFormData db_data[] = { |
958 { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", | 1011 { PasswordForm::SCHEME_HTML, "http://dont.remember.com/", |
959 "http://dont.remember.com/", | 1012 "http://dont.remember.com/", |
960 "http://dont.remember.com/handlepage.cgi", | 1013 "http://dont.remember.com/handlepage.cgi", |
961 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", | 1014 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", |
962 true, false, 1240000000 }, | 1015 true, false, 1240000000 }, |
963 { PasswordForm::SCHEME_HTML, "https://dont.remember.com/", | 1016 { PasswordForm::SCHEME_HTML, "https://dont.remember.com/", |
964 "https://dont.remember.com/", | 1017 "https://dont.remember.com/", |
965 "https://dont.remember.com/handlepage_secure.cgi", | 1018 "https://dont.remember.com/handlepage_secure.cgi", |
966 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", | 1019 L"submit", L"username", L"password", L"joe_user", L"non_empty_password", |
967 true, false, 1240000000 }, | 1020 true, false, 1240000000 }, |
968 }; | 1021 }; |
969 ScopedVector<autofill::PasswordForm> database_forms; | 1022 ScopedVector<autofill::PasswordForm> database_forms; |
970 for (unsigned int i = 0; i < arraysize(db_data); ++i) { | 1023 for (unsigned int i = 0; i < arraysize(db_data); ++i) { |
971 database_forms.push_back(CreatePasswordFormFromData(db_data[i])); | 1024 database_forms.push_back(CreatePasswordFormFromData(db_data[i]).release()); |
972 } | 1025 } |
973 ScopedVector<autofill::PasswordForm> merged_forms; | 1026 ScopedVector<autofill::PasswordForm> merged_forms; |
974 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, | 1027 internal_keychain_helpers::GetPasswordsForForms(*keychain_, &database_forms, |
975 &merged_forms); | 1028 &merged_forms); |
976 EXPECT_EQ(2U, database_forms.size()); | 1029 EXPECT_EQ(2U, database_forms.size()); |
977 ASSERT_EQ(0U, merged_forms.size()); | 1030 ASSERT_EQ(0U, merged_forms.size()); |
978 } | 1031 } |
979 | 1032 |
980 TEST_F(PasswordStoreMacInternalsTest, TestFillPasswordFormFromKeychainItem) { | 1033 TEST_F(PasswordStoreMacInternalsTest, TestFillPasswordFormFromKeychainItem) { |
981 // When |extract_password_data| is false, the password field must be empty, | 1034 // When |extract_password_data| is false, the password field must be empty, |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, | 1115 "http://web.site.com/path/to/page.html", NULL, NULL, NULL, NULL, |
1063 L"anonymous", L"knock-knock", false, false, 0 }, | 1116 L"anonymous", L"knock-knock", false, false, 0 }, |
1064 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", | 1117 { PasswordForm::SCHEME_BASIC, "http://a.site.com:2222/therealm", |
1065 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, | 1118 "http://a.site.com:2222/", NULL, NULL, NULL, NULL, |
1066 L"username", L"password", false, false, 0 }, | 1119 L"username", L"password", false, false, 0 }, |
1067 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", | 1120 { PasswordForm::SCHEME_DIGEST, "https://digest.site.com/differentrealm", |
1068 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, | 1121 "https://digest.site.com/secure.html", NULL, NULL, NULL, NULL, |
1069 L"testname", L"testpass", false, false, 0 }, | 1122 L"testname", L"testpass", false, false, 0 }, |
1070 }; | 1123 }; |
1071 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { | 1124 for (unsigned int i = 0; i < arraysize(owned_password_data); ++i) { |
1072 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( | 1125 scoped_ptr<PasswordForm> form = |
1073 owned_password_data[i])); | 1126 CreatePasswordFormFromData(owned_password_data[i]); |
1074 owned_keychain_adapter.AddPassword(*form); | 1127 owned_keychain_adapter.AddPassword(*form); |
1075 } | 1128 } |
1076 | 1129 |
1077 ScopedVector<autofill::PasswordForm> all_passwords = | 1130 ScopedVector<autofill::PasswordForm> all_passwords = |
1078 keychain_adapter.GetAllPasswordFormPasswords(); | 1131 keychain_adapter.GetAllPasswordFormPasswords(); |
1079 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); | 1132 EXPECT_EQ(8 + arraysize(owned_password_data), all_passwords.size()); |
1080 | 1133 |
1081 ScopedVector<autofill::PasswordForm> owned_passwords = | 1134 ScopedVector<autofill::PasswordForm> owned_passwords = |
1082 owned_keychain_adapter.GetAllPasswordFormPasswords(); | 1135 owned_keychain_adapter.GetAllPasswordFormPasswords(); |
1083 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); | 1136 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1130 | 1183 |
1131 MockAppleKeychain* keychain() { | 1184 MockAppleKeychain* keychain() { |
1132 return static_cast<MockAppleKeychain*>(store_->keychain()); | 1185 return static_cast<MockAppleKeychain*>(store_->keychain()); |
1133 } | 1186 } |
1134 | 1187 |
1135 void FinishAsyncProcessing() { | 1188 void FinishAsyncProcessing() { |
1136 // Do a store-level query to wait for all the previously enqueued operations | 1189 // Do a store-level query to wait for all the previously enqueued operations |
1137 // to finish. | 1190 // to finish. |
1138 MockPasswordStoreConsumer consumer; | 1191 MockPasswordStoreConsumer consumer; |
1139 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); | 1192 store_->GetLogins(PasswordForm(), PasswordStore::ALLOW_PROMPT, &consumer); |
1140 consumer.WaitOnGetPasswordStoreResults(); | 1193 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(_)) |
| 1194 .WillOnce(QuitUIMessageLoop()); |
| 1195 base::MessageLoop::current()->Run(); |
1141 } | 1196 } |
1142 | 1197 |
1143 TestPasswordStoreMac* store() { return store_.get(); } | 1198 TestPasswordStoreMac* store() { return store_.get(); } |
1144 | 1199 |
1145 protected: | 1200 protected: |
1146 base::MessageLoopForUI message_loop_; | 1201 base::MessageLoopForUI message_loop_; |
1147 content::TestBrowserThread ui_thread_; | 1202 content::TestBrowserThread ui_thread_; |
1148 | 1203 |
1149 base::ScopedTempDir db_dir_; | 1204 base::ScopedTempDir db_dir_; |
1150 scoped_refptr<TestPasswordStoreMac> store_; | 1205 scoped_refptr<TestPasswordStoreMac> store_; |
1151 }; | 1206 }; |
1152 | 1207 |
1153 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { | 1208 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { |
1154 // Insert a password into both the database and the keychain. | 1209 // Insert a password into both the database and the keychain. |
1155 // This is done manually, rather than through store_->AddLogin, because the | 1210 // This is done manually, rather than through store_->AddLogin, because the |
1156 // Mock Keychain isn't smart enough to be able to support update generically, | 1211 // Mock Keychain isn't smart enough to be able to support update generically, |
1157 // so some.domain.com triggers special handling to test it that make inserting | 1212 // so some.domain.com triggers special handling to test it that make inserting |
1158 // fail. | 1213 // fail. |
1159 PasswordFormData joint_data = { | 1214 PasswordFormData joint_data = { |
1160 PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 1215 PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
1161 "http://some.domain.com/insecure.html", "login.cgi", | 1216 "http://some.domain.com/insecure.html", "login.cgi", |
1162 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 | 1217 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 |
1163 }; | 1218 }; |
1164 scoped_ptr<PasswordForm> joint_form(CreatePasswordFormFromData(joint_data)); | 1219 scoped_ptr<PasswordForm> joint_form = CreatePasswordFormFromData(joint_data); |
1165 login_db()->AddLogin(*joint_form); | 1220 login_db()->AddLogin(*joint_form); |
1166 MockAppleKeychain::KeychainTestData joint_keychain_data = { | 1221 MockAppleKeychain::KeychainTestData joint_keychain_data = { |
1167 kSecAuthenticationTypeHTMLForm, "some.domain.com", | 1222 kSecAuthenticationTypeHTMLForm, "some.domain.com", |
1168 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", | 1223 kSecProtocolTypeHTTP, "/insecure.html", 0, NULL, "20020601171500Z", |
1169 "joe_user", "sekrit", false }; | 1224 "joe_user", "sekrit", false }; |
1170 keychain()->AddTestItem(joint_keychain_data); | 1225 keychain()->AddTestItem(joint_keychain_data); |
1171 | 1226 |
1172 // Insert a password into the keychain only. | 1227 // Insert a password into the keychain only. |
1173 MockAppleKeychain::KeychainTestData keychain_only_data = { | 1228 MockAppleKeychain::KeychainTestData keychain_only_data = { |
1174 kSecAuthenticationTypeHTMLForm, "keychain.only.com", | 1229 kSecAuthenticationTypeHTMLForm, "keychain.only.com", |
(...skipping 28 matching lines...) Expand all Loading... |
1203 // case where a form is filled, then the stored login is removed, then the | 1258 // case where a form is filled, then the stored login is removed, then the |
1204 // form is submitted. | 1259 // form is submitted. |
1205 { { PasswordForm::SCHEME_HTML, "http://different.com/", | 1260 { { PasswordForm::SCHEME_HTML, "http://different.com/", |
1206 "http://different.com/index.html", "login.cgi", | 1261 "http://different.com/index.html", "login.cgi", |
1207 L"username", L"password", L"submit", L"abc", L"123", | 1262 L"username", L"password", L"submit", L"abc", L"123", |
1208 true, false, 2 }, | 1263 true, false, 2 }, |
1209 NULL, | 1264 NULL, |
1210 }, | 1265 }, |
1211 }; | 1266 }; |
1212 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1267 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
1213 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData( | 1268 scoped_ptr<PasswordForm> form = |
1214 updates[i].form_data)); | 1269 CreatePasswordFormFromData(updates[i].form_data); |
1215 store_->UpdateLogin(*form); | 1270 store_->UpdateLogin(*form); |
1216 } | 1271 } |
1217 | 1272 |
1218 FinishAsyncProcessing(); | 1273 FinishAsyncProcessing(); |
1219 | 1274 |
1220 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); | 1275 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); |
1221 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1276 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
1222 scoped_ptr<PasswordForm> query_form( | 1277 scoped_ptr<PasswordForm> query_form = |
1223 CreatePasswordFormFromData(updates[i].form_data)); | 1278 CreatePasswordFormFromData(updates[i].form_data); |
1224 | 1279 |
1225 ScopedVector<autofill::PasswordForm> matching_items = | 1280 ScopedVector<autofill::PasswordForm> matching_items = |
1226 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, | 1281 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, |
1227 query_form->scheme); | 1282 query_form->scheme); |
1228 if (updates[i].password) { | 1283 if (updates[i].password) { |
1229 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; | 1284 EXPECT_GT(matching_items.size(), 0U) << "iteration " << i; |
1230 if (matching_items.size() >= 1) | 1285 if (matching_items.size() >= 1) |
1231 EXPECT_EQ(ASCIIToUTF16(updates[i].password), | 1286 EXPECT_EQ(ASCIIToUTF16(updates[i].password), |
1232 matching_items[0]->password_value) << "iteration " << i; | 1287 matching_items[0]->password_value) << "iteration " << i; |
1233 } else { | 1288 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
1256 // www.facebook.com password from the login database, we should not be blocked | 1311 // www.facebook.com password from the login database, we should not be blocked |
1257 // from deleting it from the keystore just becaus the m.facebook.com password | 1312 // from deleting it from the keystore just becaus the m.facebook.com password |
1258 // fuzzy-matches the www.facebook.com one.) | 1313 // fuzzy-matches the www.facebook.com one.) |
1259 | 1314 |
1260 // 1. Add a password for www.facebook.com | 1315 // 1. Add a password for www.facebook.com |
1261 PasswordFormData www_form_data = { | 1316 PasswordFormData www_form_data = { |
1262 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1317 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1263 "http://www.facebook.com/index.html", "login", | 1318 "http://www.facebook.com/index.html", "login", |
1264 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 | 1319 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 |
1265 }; | 1320 }; |
1266 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data)); | 1321 scoped_ptr<PasswordForm> www_form = CreatePasswordFormFromData(www_form_data); |
1267 login_db()->AddLogin(*www_form); | 1322 login_db()->AddLogin(*www_form); |
1268 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); | 1323 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); |
1269 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1324 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
1270 owned_keychain_adapter.AddPassword(*www_form); | 1325 owned_keychain_adapter.AddPassword(*www_form); |
1271 | 1326 |
1272 // 2. Get a password for m.facebook.com. | 1327 // 2. Get a password for m.facebook.com. |
1273 PasswordForm m_form(*www_form); | 1328 PasswordForm m_form(*www_form); |
1274 m_form.signon_realm = "http://m.facebook.com"; | 1329 m_form.signon_realm = "http://m.facebook.com"; |
1275 m_form.origin = GURL("http://m.facebook.com/index.html"); | 1330 m_form.origin = GURL("http://m.facebook.com/index.html"); |
1276 | 1331 |
1277 MockPasswordStoreConsumer consumer; | 1332 MockPasswordStoreConsumer consumer; |
1278 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); | 1333 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); |
1279 consumer.WaitOnGetPasswordStoreResults(); | 1334 PasswordForm returned_form; |
1280 EXPECT_EQ(1u, consumer.last_result.size()); | 1335 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
| 1336 .WillOnce( |
| 1337 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); |
| 1338 base::MessageLoop::current()->Run(); |
1281 | 1339 |
1282 // 3. Add the returned password for m.facebook.com. | 1340 // 3. Add the returned password for m.facebook.com. |
1283 login_db()->AddLogin(consumer.last_result[0]); | 1341 login_db()->AddLogin(returned_form); |
1284 owned_keychain_adapter.AddPassword(m_form); | 1342 owned_keychain_adapter.AddPassword(m_form); |
1285 | 1343 |
1286 // 4. Remove both passwords. | 1344 // 4. Remove both passwords. |
1287 store_->RemoveLogin(*www_form); | 1345 store_->RemoveLogin(*www_form); |
1288 store_->RemoveLogin(m_form); | 1346 store_->RemoveLogin(m_form); |
1289 FinishAsyncProcessing(); | 1347 FinishAsyncProcessing(); |
1290 | 1348 |
1291 // No trace of www.facebook.com. | 1349 // No trace of www.facebook.com. |
1292 ScopedVector<autofill::PasswordForm> matching_items = | 1350 ScopedVector<autofill::PasswordForm> matching_items = |
1293 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, | 1351 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1342 L"password", L"joe_user", L"sekrit", true, false, 0 }; | 1400 L"password", L"joe_user", L"sekrit", true, false, 0 }; |
1343 // The old form doesn't have elements names. | 1401 // The old form doesn't have elements names. |
1344 PasswordFormData www_form_data_facebook_old = { | 1402 PasswordFormData www_form_data_facebook_old = { |
1345 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1403 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1346 "http://www.facebook.com/index.html", "login", L"", L"", | 1404 "http://www.facebook.com/index.html", "login", L"", L"", |
1347 L"", L"joe_user", L"oldsekrit", true, false, 0 }; | 1405 L"", L"joe_user", L"oldsekrit", true, false, 0 }; |
1348 PasswordFormData www_form_data_other = { | 1406 PasswordFormData www_form_data_other = { |
1349 PasswordForm::SCHEME_HTML, "http://different.com/", | 1407 PasswordForm::SCHEME_HTML, "http://different.com/", |
1350 "http://different.com/index.html", "login", L"submit", L"username", | 1408 "http://different.com/index.html", "login", L"submit", L"username", |
1351 L"password", L"different_joe_user", L"sekrit", true, false, 0 }; | 1409 L"password", L"different_joe_user", L"sekrit", true, false, 0 }; |
1352 scoped_ptr<PasswordForm> form_facebook( | 1410 scoped_ptr<PasswordForm> form_facebook = |
1353 CreatePasswordFormFromData(www_form_data_facebook)); | 1411 CreatePasswordFormFromData(www_form_data_facebook); |
1354 scoped_ptr<PasswordForm> form_facebook_old( | 1412 scoped_ptr<PasswordForm> form_facebook_old = |
1355 CreatePasswordFormFromData(www_form_data_facebook_old)); | 1413 CreatePasswordFormFromData(www_form_data_facebook_old); |
1356 scoped_ptr<PasswordForm> form_other( | 1414 scoped_ptr<PasswordForm> form_other = |
1357 CreatePasswordFormFromData(www_form_data_other)); | 1415 CreatePasswordFormFromData(www_form_data_other); |
1358 base::Time now = base::Time::Now(); | 1416 base::Time now = base::Time::Now(); |
1359 // TODO(vasilii): remove the next line once crbug/374132 is fixed. | 1417 // TODO(vasilii): remove the next line once crbug/374132 is fixed. |
1360 now = base::Time::FromTimeT(now.ToTimeT()); | 1418 now = base::Time::FromTimeT(now.ToTimeT()); |
1361 base::Time next_day = now + base::TimeDelta::FromDays(1); | 1419 base::Time next_day = now + base::TimeDelta::FromDays(1); |
1362 if (check_created) { | 1420 if (check_created) { |
1363 form_facebook_old->date_created = now; | 1421 form_facebook_old->date_created = now; |
1364 form_facebook->date_created = next_day; | 1422 form_facebook->date_created = next_day; |
1365 form_other->date_created = next_day; | 1423 form_other->date_created = next_day; |
1366 } else { | 1424 } else { |
1367 form_facebook_old->date_synced = now; | 1425 form_facebook_old->date_synced = now; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 keychain()->AddTestItem(keychain_data); | 1504 keychain()->AddTestItem(keychain_data); |
1447 | 1505 |
1448 // Add a password through the adapter. It has the "Chrome" creator tag. | 1506 // Add a password through the adapter. It has the "Chrome" creator tag. |
1449 // However, it's not referenced by the password database. | 1507 // However, it's not referenced by the password database. |
1450 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); | 1508 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); |
1451 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1509 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
1452 PasswordFormData www_form_data1 = { | 1510 PasswordFormData www_form_data1 = { |
1453 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1511 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1454 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1512 "http://www.facebook.com/index.html", "login", L"username", L"password", |
1455 L"submit", L"joe_user", L"sekrit", true, false, 1 }; | 1513 L"submit", L"joe_user", L"sekrit", true, false, 1 }; |
1456 scoped_ptr<PasswordForm> www_form(CreatePasswordFormFromData(www_form_data1)); | 1514 scoped_ptr<PasswordForm> www_form = |
| 1515 CreatePasswordFormFromData(www_form_data1); |
1457 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); | 1516 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); |
1458 | 1517 |
1459 // Add a password from the current profile. | 1518 // Add a password from the current profile. |
1460 PasswordFormData www_form_data2 = { | 1519 PasswordFormData www_form_data2 = { |
1461 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1520 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1462 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1521 "http://www.facebook.com/index.html", "login", L"username", L"password", |
1463 L"submit", L"not_joe_user", L"12345", true, false, 1 }; | 1522 L"submit", L"not_joe_user", L"12345", true, false, 1 }; |
1464 www_form.reset(CreatePasswordFormFromData(www_form_data2)); | 1523 www_form = CreatePasswordFormFromData(www_form_data2); |
1465 store_->AddLogin(*www_form); | 1524 store_->AddLogin(*www_form); |
1466 FinishAsyncProcessing(); | 1525 FinishAsyncProcessing(); |
1467 | 1526 |
1468 ScopedVector<PasswordForm> matching_items; | 1527 ScopedVector<PasswordForm> matching_items; |
1469 login_db()->GetLogins(*www_form, &matching_items); | 1528 login_db()->GetLogins(*www_form, &matching_items); |
1470 EXPECT_EQ(1u, matching_items.size()); | 1529 EXPECT_EQ(1u, matching_items.size()); |
1471 matching_items.clear(); | 1530 matching_items.clear(); |
1472 | 1531 |
1473 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time()); | 1532 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time()); |
1474 FinishAsyncProcessing(); | 1533 FinishAsyncProcessing(); |
(...skipping 24 matching lines...) Expand all Loading... |
1499 ClosePasswordStore(); | 1558 ClosePasswordStore(); |
1500 | 1559 |
1501 base::WaitableEvent event(false, false); | 1560 base::WaitableEvent event(false, false); |
1502 CreateAndInitPasswordStore(make_scoped_ptr<password_manager::LoginDatabase>( | 1561 CreateAndInitPasswordStore(make_scoped_ptr<password_manager::LoginDatabase>( |
1503 new SlowToInitLoginDatabase(test_login_db_file_path(), &event))); | 1562 new SlowToInitLoginDatabase(test_login_db_file_path(), &event))); |
1504 | 1563 |
1505 PasswordFormData www_form_data = { | 1564 PasswordFormData www_form_data = { |
1506 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1565 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1507 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1566 "http://www.facebook.com/index.html", "login", L"username", L"password", |
1508 L"submit", L"not_joe_user", L"12345", true, false, 1}; | 1567 L"submit", L"not_joe_user", L"12345", true, false, 1}; |
1509 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(www_form_data)); | 1568 scoped_ptr<PasswordForm> form = CreatePasswordFormFromData(www_form_data); |
1510 store()->AddLogin(*form); | 1569 store()->AddLogin(*form); |
1511 | 1570 |
1512 MockPasswordStoreConsumer mock_consumer; | 1571 MockPasswordStoreConsumer mock_consumer; |
1513 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer); | 1572 store()->GetLogins(*form, PasswordStore::ALLOW_PROMPT, &mock_consumer); |
1514 | 1573 |
1515 // Now the read/write tasks are scheduled, let the DB initialization proceed. | 1574 // Now the read/write tasks are scheduled, let the DB initialization proceed. |
1516 event.Signal(); | 1575 event.Signal(); |
1517 | 1576 |
1518 mock_consumer.WaitOnGetPasswordStoreResults(); | 1577 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
1519 EXPECT_EQ(1u, mock_consumer.last_result.size()); | 1578 .WillOnce(QuitUIMessageLoop()); |
| 1579 base::MessageLoop::current()->Run(); |
1520 EXPECT_TRUE(login_db()); | 1580 EXPECT_TRUE(login_db()); |
1521 } | 1581 } |
1522 | 1582 |
1523 // Verify that operations on a PasswordStore with a bad database cause no | 1583 // Verify that operations on a PasswordStore with a bad database cause no |
1524 // explosions, but fail without side effect, return no data and trigger no | 1584 // explosions, but fail without side effect, return no data and trigger no |
1525 // notifications. | 1585 // notifications. |
1526 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) { | 1586 TEST_F(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) { |
1527 ClosePasswordStore(); | 1587 ClosePasswordStore(); |
1528 CreateAndInitPasswordStore( | 1588 CreateAndInitPasswordStore( |
1529 make_scoped_ptr<password_manager::LoginDatabase>(new BadLoginDatabase)); | 1589 make_scoped_ptr<password_manager::LoginDatabase>(new BadLoginDatabase)); |
1530 FinishAsyncProcessing(); | 1590 FinishAsyncProcessing(); |
1531 EXPECT_FALSE(login_db()); | 1591 EXPECT_FALSE(login_db()); |
1532 | 1592 |
1533 testing::StrictMock<MockPasswordStoreObserver> mock_observer; | 1593 testing::StrictMock<MockPasswordStoreObserver> mock_observer; |
1534 store()->AddObserver(&mock_observer); | 1594 store()->AddObserver(&mock_observer); |
1535 | 1595 |
1536 // Add a new autofillable login + a blacklisted login. | 1596 // Add a new autofillable login + a blacklisted login. |
1537 PasswordFormData www_form_data = { | 1597 PasswordFormData www_form_data = { |
1538 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1598 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1539 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1599 "http://www.facebook.com/index.html", "login", L"username", L"password", |
1540 L"submit", L"not_joe_user", L"12345", true, false, 1}; | 1600 L"submit", L"not_joe_user", L"12345", true, false, 1}; |
1541 scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(www_form_data)); | 1601 scoped_ptr<PasswordForm> form = CreatePasswordFormFromData(www_form_data); |
1542 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form)); | 1602 scoped_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form)); |
1543 blacklisted_form->signon_realm = "http://foo.example.com"; | 1603 blacklisted_form->signon_realm = "http://foo.example.com"; |
1544 blacklisted_form->origin = GURL("http://foo.example.com/origin"); | 1604 blacklisted_form->origin = GURL("http://foo.example.com/origin"); |
1545 blacklisted_form->action = GURL("http://foo.example.com/action"); | 1605 blacklisted_form->action = GURL("http://foo.example.com/action"); |
1546 blacklisted_form->blacklisted_by_user = true; | 1606 blacklisted_form->blacklisted_by_user = true; |
1547 store()->AddLogin(*form); | 1607 store()->AddLogin(*form); |
1548 store()->AddLogin(*blacklisted_form); | 1608 store()->AddLogin(*blacklisted_form); |
1549 FinishAsyncProcessing(); | 1609 FinishAsyncProcessing(); |
1550 | 1610 |
1551 // Get all logins; autofillable logins; blacklisted logins. | 1611 // Get all logins; autofillable logins; blacklisted logins. |
1552 MockPasswordStoreConsumer mock_consumer; | 1612 MockPasswordStoreConsumer mock_consumer; |
1553 store()->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer); | 1613 store()->GetLogins(*form, PasswordStore::DISALLOW_PROMPT, &mock_consumer); |
1554 mock_consumer.WaitOnGetPasswordStoreResults(); | 1614 ON_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(_)) |
1555 EXPECT_TRUE(mock_consumer.last_result.empty()); | 1615 .WillByDefault(QuitUIMessageLoop()); |
| 1616 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); |
| 1617 base::MessageLoop::current()->Run(); |
| 1618 |
1556 store()->GetAutofillableLogins(&mock_consumer); | 1619 store()->GetAutofillableLogins(&mock_consumer); |
1557 mock_consumer.WaitOnGetPasswordStoreResults(); | 1620 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); |
1558 EXPECT_TRUE(mock_consumer.last_result.empty()); | 1621 base::MessageLoop::current()->Run(); |
| 1622 |
1559 store()->GetBlacklistLogins(&mock_consumer); | 1623 store()->GetBlacklistLogins(&mock_consumer); |
1560 mock_consumer.WaitOnGetPasswordStoreResults(); | 1624 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); |
1561 EXPECT_TRUE(mock_consumer.last_result.empty()); | 1625 base::MessageLoop::current()->Run(); |
1562 | 1626 |
1563 // Report metrics. | 1627 // Report metrics. |
1564 store()->ReportMetrics("Test Username", true); | 1628 store()->ReportMetrics("Test Username", true); |
1565 FinishAsyncProcessing(); | 1629 FinishAsyncProcessing(); |
1566 | 1630 |
1567 // Change the login. | 1631 // Change the login. |
1568 form->password_value = base::ASCIIToUTF16("a different password"); | 1632 form->password_value = base::ASCIIToUTF16("a different password"); |
1569 store()->UpdateLogin(*form); | 1633 store()->UpdateLogin(*form); |
1570 FinishAsyncProcessing(); | 1634 FinishAsyncProcessing(); |
1571 | 1635 |
1572 // Delete one login; a range of logins. | 1636 // Delete one login; a range of logins. |
1573 store()->RemoveLogin(*form); | 1637 store()->RemoveLogin(*form); |
1574 store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max()); | 1638 store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max()); |
1575 store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max()); | 1639 store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max()); |
1576 FinishAsyncProcessing(); | 1640 FinishAsyncProcessing(); |
1577 | 1641 |
1578 // Verify no notifications are fired during shutdown either. | 1642 // Verify no notifications are fired during shutdown either. |
1579 ClosePasswordStore(); | 1643 ClosePasswordStore(); |
1580 } | 1644 } |
OLD | NEW |