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

Side by Side Diff: ios/chrome/browser/passwords/credential_manager_unittest.mm

Issue 2152593002: Upstream password manager unit tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix GYP Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ios/chrome/browser/passwords/credential_manager.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/mac/bind_objc_block.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/strings/sys_string_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "components/password_manager/core/browser/password_bubble_experiment.h"
16 #include "components/password_manager/core/browser/stub_password_manager_client. h"
17 #include "components/password_manager/core/browser/stub_password_manager_driver. h"
18 #include "components/password_manager/core/browser/test_password_store.h"
19 #include "components/password_manager/core/common/credential_manager_types.h"
20 #include "components/password_manager/core/common/password_manager_pref_names.h"
21 #include "components/prefs/pref_registry_simple.h"
22 #include "components/prefs/testing_pref_service.h"
23 #import "ios/web/public/web_state/web_state.h"
24 #import "ios/chrome/browser/passwords/js_credential_manager.h"
25 #import "ios/testing/ocmock_complex_type_helper.h"
26 #import "ios/web/public/test/web_test_with_web_state.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/gtest_mac.h"
30 #include "third_party/ocmock/OCMock/OCMock.h"
31 #include "third_party/ocmock/gtest_support.h"
32 #include "url/gurl.h"
33
34 using testing::Return;
35
36 namespace {
37 // Type of a function invoked when a promise is resolved.
38 typedef void (^ResolvePromiseBlock)(NSInteger request_id,
39 const web::Credential& credential);
40 } // namespace
41
42 // A helper to mock methods that have C++ object parameters.
43 @interface MockJSCredentialManager : OCMockComplexTypeHelper
44 @end
45
46 @implementation MockJSCredentialManager
47 - (void)resolvePromiseWithRequestID:(NSInteger)requestID
48 credential:(const web::Credential&)credential
49 completionHandler:(void (^)(BOOL))completionHandler {
50 static_cast<ResolvePromiseBlock>([self blockForSelector:_cmd])(requestID,
51 credential);
52 completionHandler(YES);
53 }
54 @end
55
56 namespace {
57
58 // Returns a test credential.
59 autofill::PasswordForm GetTestPasswordForm1(bool zero_click_allowed) {
60 autofill::PasswordForm form;
61 form.username_value = base::ASCIIToUTF16("foo");
62 form.password_value = base::ASCIIToUTF16("bar");
63 form.skip_zero_click = !zero_click_allowed;
64 form.ssl_valid = true;
65 form.type = autofill::PasswordForm::Type::TYPE_API;
66 return form;
67 }
68
69 // Returns a test credential matching |GetTestPasswordForm1()|.
70 web::Credential GetTestWebCredential1(bool zero_click_allowed) {
71 web::Credential credential;
72 autofill::PasswordForm form(GetTestPasswordForm1(zero_click_allowed));
73 credential.type = web::CredentialType::CREDENTIAL_TYPE_PASSWORD;
74 credential.id = form.username_value;
75 credential.password = form.password_value;
76 return credential;
77 }
78
79 // Returns a different test credential.
80 autofill::PasswordForm GetTestPasswordForm2(bool zero_click_allowed) {
81 autofill::PasswordForm form;
82 form.username_value = base::ASCIIToUTF16("baz");
83 form.password_value = base::ASCIIToUTF16("bah");
84 form.skip_zero_click = !zero_click_allowed;
85 form.ssl_valid = true;
86 return form;
87 }
88
89 // Returns a test credential matching |GetTestPasswordForm2()|.
90 web::Credential GetTestWebCredential2(bool zero_click_allowed) {
91 web::Credential credential;
92 autofill::PasswordForm form(GetTestPasswordForm2(zero_click_allowed));
93 credential.type = web::CredentialType::CREDENTIAL_TYPE_PASSWORD;
94 credential.id = form.username_value;
95 credential.password = form.password_value;
96 return credential;
97 }
98
99 typedef BOOL (^StringPredicate)(NSString*);
100
101 // Returns a block that takes a string argument and returns whether it is equal
102 // to |string|.
103 StringPredicate EqualsString(const char* string) {
104 return [[^BOOL(NSString* other) {
105 return [base::SysUTF8ToNSString(string) isEqualToString:other];
106 } copy] autorelease];
107 }
108
109 // A stub PasswordManagerClient for testing.
110 class StubPasswordManagerClient
111 : public password_manager::StubPasswordManagerClient {
112 public:
113 StubPasswordManagerClient()
114 : password_manager::StubPasswordManagerClient(),
115 password_store_(nullptr) {
116 prefs_.registry()->RegisterBooleanPref(
117 password_manager::prefs::kCredentialsEnableAutosignin, false);
118 password_bubble_experiment::RegisterPrefs(prefs_.registry());
119 }
120
121 ~StubPasswordManagerClient() override {
122 if (password_store_)
123 password_store_->ShutdownOnUIThread();
124 }
125
126 MOCK_CONST_METHOD0(IsSavingAndFillingEnabledForCurrentPage, bool());
127
128 void SetPasswordStore(
129 scoped_refptr<password_manager::PasswordStore> password_store) {
130 password_store_ = password_store;
131 }
132
133 password_manager::PasswordStore* GetPasswordStore() const override {
134 return password_store_.get();
135 }
136
137 void SetUserChosenCredential(
138 const password_manager::CredentialInfo& credential) {
139 user_chosen_credential_ = credential;
140 }
141
142 bool PromptUserToChooseCredentials(
143 ScopedVector<autofill::PasswordForm> local_forms,
144 ScopedVector<autofill::PasswordForm> federated_forms,
145 const GURL& origin,
146 const CredentialsCallback& callback) override {
147 return false;
148 }
149
150 bool PromptUserToSaveOrUpdatePassword(
151 std::unique_ptr<password_manager::PasswordFormManager> form_to_save,
152 password_manager::CredentialSourceType type,
153 bool update_password) override {
154 if (!update_password)
155 saved_form_ = std::move(form_to_save);
156 return true;
157 }
158
159 PrefService* GetPrefs() override { return &prefs_; }
160
161 password_manager::PasswordFormManager* saved_form() {
162 return saved_form_.get();
163 }
164
165 private:
166 // PrefService for testing.
167 TestingPrefServiceSimple prefs_;
168
169 // PasswordStore for testing.
170 scoped_refptr<password_manager::PasswordStore> password_store_;
171
172 // The password form shown to the user for saving.
173 std::unique_ptr<password_manager::PasswordFormManager> saved_form_;
174
175 // The credential to be returned to callers of PromptUserToChooseCredentials.
176 password_manager::CredentialInfo user_chosen_credential_;
177
178 DISALLOW_COPY_AND_ASSIGN(StubPasswordManagerClient);
179 };
180
181 // Tests for CredentialManager.
182 class CredentialManagerTest : public web::WebTestWithWebState {
183 public:
184 CredentialManagerTest() {}
185 ~CredentialManagerTest() override {}
186
187 void SetUp() override {
188 web::WebTestWithWebState::SetUp();
189 id originalMock =
190 [OCMockObject niceMockForClass:[JSCredentialManager class]];
191 mock_js_credential_manager_.reset([[MockJSCredentialManager alloc]
192 initWithRepresentedObject:originalMock]);
193 credential_manager_.reset(new CredentialManager(
194 web_state(), &stub_client_, &stub_driver_,
195 static_cast<id>(mock_js_credential_manager_.get())));
196 }
197
198 // Sets up an expectation that the promise identified by |request_id| will be
199 // resolved with |credential|. |verified| must point to a variable that will
200 // be checked by the caller to ensure that the expectations were run. (This
201 // is necessary because OCMock doesn't handle methods with C++ object
202 // parameters.)
203 void ExpectPromiseResolved(bool* verified,
204 int request_id,
205 const web::Credential& credential) {
206 SEL selector =
207 @selector(resolvePromiseWithRequestID:credential:completionHandler:);
208 web::Credential strong_credential(credential);
209 [mock_js_credential_manager_
210 onSelector:selector
211 callBlockExpectation:^(NSInteger block_request_id,
212 const web::Credential& block_credential) {
213 EXPECT_EQ(request_id, block_request_id);
214 EXPECT_TRUE(CredentialsEqual(strong_credential, block_credential));
215 *verified = true;
216 }];
217 }
218
219 // Same as |ExpectPromiseResolved(bool*, int, const web::Credential&)| but
220 // does not expect a credential to be passed.
221 void ExpectPromiseResolved(int request_id) {
222 [[[mock_js_credential_manager_ representedObject] expect]
223 resolvePromiseWithRequestID:request_id
224 completionHandler:nil];
225 }
226
227 // Clears the expectations set up by |ExpectPromiseResolved()|.
228 void ClearPromiseResolutionExpectations() {
229 SEL selector =
230 @selector(resolvePromiseWithRequestID:credential:completionHandler:);
231 [mock_js_credential_manager_ removeBlockExpectationOnSelector:selector];
232 }
233
234 // Sets up an expectation that the promise identified by |request_id| will be
235 // rejected with the given |error_type| and |message|. The caller should use
236 // EXPECT_OCMOCK_VERIFY to verify that the expectations were run.
237 void ExpectPromiseRejected(int request_id,
238 const char* error_type,
239 const char* message) {
240 [[[mock_js_credential_manager_ representedObject] expect]
241 rejectPromiseWithRequestID:request_id
242 errorType:[OCMArg
243 checkWithBlock:EqualsString(error_type)]
244 message:[OCMArg checkWithBlock:EqualsString(message)]
245 completionHandler:[OCMArg any]];
246 }
247
248 protected:
249 // Mock for PasswordManagerClient.
250 StubPasswordManagerClient stub_client_;
251
252 // Stub for PasswordManagerDriver.
253 password_manager::StubPasswordManagerDriver stub_driver_;
254
255 // Mock for JSCredentialManager.
256 base::scoped_nsobject<MockJSCredentialManager> mock_js_credential_manager_;
257
258 // CredentialManager for testing.
259 std::unique_ptr<CredentialManager> credential_manager_;
260
261 private:
262 explicit CredentialManagerTest(const CredentialManagerTest&) = delete;
263 CredentialManagerTest& operator=(const CredentialManagerTest&) = delete;
264 };
265
266 // Tests that a credential request is rejected properly when the PasswordStore
267 // is unavailable.
268 TEST_F(CredentialManagerTest, RequestRejectedWhenPasswordStoreUnavailable) {
269 // Clear the password store.
270 stub_client_.SetPasswordStore(nullptr);
271
272 // Requesting a credential should reject the request with an error.
273 const int request_id = 0;
274 ExpectPromiseRejected(request_id,
275 kCredentialsPasswordStoreUnavailableErrorType,
276 kCredentialsPasswordStoreUnavailableErrorMessage);
277 credential_manager_->CredentialsRequested(request_id,
278 GURL("http://foo.com/login"), false,
279 std::vector<std::string>(), true);
280
281 // Pump the message loop and verify.
282 WaitForBackgroundTasks();
283 EXPECT_OCMOCK_VERIFY([mock_js_credential_manager_ representedObject]);
284 }
285
286 // Tests that a credential request is rejected when another request is pending.
287 TEST_F(CredentialManagerTest, RequestRejectedWhenExistingRequestIsPending) {
288 // Set a password store, but prevent requests from completing.
289 stub_client_.SetPasswordStore(new password_manager::TestPasswordStore);
290
291 // Make an initial request. Don't pump the message loop, so that the task
292 // doesn't complete. Expect the request to resolve with an empty credential
293 // after the message loop is pumped.
294 const int first_request_id = 0;
295 bool first_verified = false;
296 ExpectPromiseResolved(&first_verified, first_request_id, web::Credential());
297 credential_manager_->CredentialsRequested(first_request_id,
298 GURL("http://foo.com/login"), false,
299 std::vector<std::string>(), true);
300
301 // Making a second request and then pumping the message loop should reject the
302 // request with an error.
303 const int second_request_id = 0;
304 ExpectPromiseRejected(second_request_id, kCredentialsPendingRequestErrorType,
305 kCredentialsPendingRequestErrorMessage);
306 credential_manager_->CredentialsRequested(second_request_id,
307 GURL("http://foo.com/login"), false,
308 std::vector<std::string>(), true);
309
310 // Pump the message loop and verify.
311 WaitForBackgroundTasks();
312 EXPECT_TRUE(first_verified);
313 EXPECT_OCMOCK_VERIFY([mock_js_credential_manager_ representedObject]);
314 }
315
316 // Tests that a zero-click credential request is resolved properly with an empty
317 // credential when zero-click sign-in is disabled.
318 TEST_F(CredentialManagerTest,
319 ZeroClickRequestResolvedWithEmptyCredentialWhenZeroClickSignInDisabled) {
320 // Set a password store, but request a zero-click credential with zero-click
321 // disabled.
322 stub_client_.SetPasswordStore(new password_manager::TestPasswordStore);
323 const bool zero_click = true;
324 static_cast<TestingPrefServiceSimple*>(stub_client_.GetPrefs())
325 ->SetUserPref(password_manager::prefs::kCredentialsEnableAutosignin,
326 new base::FundamentalValue(!zero_click));
327
328 // Requesting a zero-click credential should immediately resolve the request
329 // with an empty credential.
330 const int request_id = 0;
331 bool verified = false;
332 ExpectPromiseResolved(&verified, request_id, web::Credential());
333 credential_manager_->CredentialsRequested(
334 request_id, GURL("http://foo.com/login"), zero_click,
335 std::vector<std::string>(), true);
336
337 // Pump the message loop and verify.
338 WaitForBackgroundTasks();
339 EXPECT_TRUE(verified);
340 }
341
342 // Tests that a credential request is properly resolved with an empty credential
343 // when no credentials are available.
344 TEST_F(CredentialManagerTest,
345 RequestResolvedWithEmptyCredentialWhenNoneAvailable) {
346 // Set a password store with no credentials, enable zero-click, and request a
347 // zero-click credential.
348 stub_client_.SetPasswordStore(new password_manager::TestPasswordStore);
349 const bool zero_click = true;
350 static_cast<TestingPrefServiceSimple*>(stub_client_.GetPrefs())
351 ->SetUserPref(password_manager::prefs::kCredentialsEnableAutosignin,
352 new base::FundamentalValue(zero_click));
353
354 // Requesting a zero-click credential should try to retrieve PasswordForms
355 // from the PasswordStore and resolve the request with an empty Credential
356 // when none are found.
357 const int request_id = 0;
358 bool verified = false;
359 ExpectPromiseResolved(&verified, request_id, web::Credential());
360 credential_manager_->CredentialsRequested(
361 request_id, GURL("http://foo.com/login"), zero_click,
362 std::vector<std::string>(), true);
363
364 // Pump the message loop and verify.
365 WaitForBackgroundTasks();
366 EXPECT_TRUE(verified);
367 }
368
369 // Tests that a zero-click credential request properly resolves.
370 TEST_F(CredentialManagerTest, ZeroClickRequestResolved) {
371 // Set a password store with a credential, enable zero-click, and request a
372 // zero-click credential.
373 scoped_refptr<password_manager::TestPasswordStore> store(
374 new password_manager::TestPasswordStore);
375 const bool zero_click = true;
376 store->AddLogin(GetTestPasswordForm1(zero_click));
377 stub_client_.SetPasswordStore(store);
378 static_cast<TestingPrefServiceSimple*>(stub_client_.GetPrefs())
379 ->SetUserPref(password_manager::prefs::kCredentialsEnableAutosignin,
380 new base::FundamentalValue(zero_click));
381 // Without the first run experience, the zero-click credentials won't be
382 // passed to the site.
383 static_cast<TestingPrefServiceSimple*>(stub_client_.GetPrefs())
384 ->SetUserPref(
385 password_manager::prefs::kWasAutoSignInFirstRunExperienceShown,
386 new base::FundamentalValue(true));
387 WaitForBackgroundTasks();
388
389 // Requesting a zero-click credential should retrieve a PasswordForm from the
390 // PasswordStore and resolve the request with a corresponding Credential.
391 const int request_id = 0;
392 bool verified = false;
393 ExpectPromiseResolved(&verified, request_id,
394 GetTestWebCredential1(zero_click));
395 credential_manager_->CredentialsRequested(
396 request_id, GURL("http://foo.com/login"), zero_click,
397 std::vector<std::string>(), true);
398
399 // Pump the message loop and verify.
400 WaitForBackgroundTasks();
401 EXPECT_TRUE(verified);
402 }
403
404 // Tests that a credential request properly resolves.
405 // TODO(crbug.com/598851): Reenabled this test.
406 TEST_F(CredentialManagerTest, DISABLED_RequestResolved) {
407 // Set a password store with two credentials and set a credential to be
408 // returned by the PasswordManagerClient as if chosen by the user.
409 scoped_refptr<password_manager::TestPasswordStore> store(
410 new password_manager::TestPasswordStore);
411 const bool zero_click = false;
412 store->AddLogin(GetTestPasswordForm1(zero_click));
413 store->AddLogin(GetTestPasswordForm2(zero_click));
414 stub_client_.SetPasswordStore(store);
415 stub_client_.SetUserChosenCredential(password_manager::CredentialInfo(
416 GetTestPasswordForm2(zero_click),
417 password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD));
418 WaitForBackgroundTasks();
419
420 // Request a credential. The request should be resolved with the credential
421 // set on the stub client.
422 const int request_id = 0;
423 bool verified = false;
424 ExpectPromiseResolved(&verified, request_id,
425 GetTestWebCredential2(zero_click));
426 credential_manager_->CredentialsRequested(
427 request_id, GURL("http://foo.com/login"), zero_click,
428 std::vector<std::string>(), true);
429
430 // Pump the message loop and verify.
431 WaitForBackgroundTasks();
432 EXPECT_TRUE(verified);
433 }
434
435 // Tests that two requests back-to-back succeed when they wait to be resolved.
436 // TODO(crbug.com/598851): Reenable this test.
437 TEST_F(CredentialManagerTest, DISABLED_ConsecutiveRequestsResolve) {
438 // Set a password store with two credentials and set a credential to be
439 // returned by the PasswordManagerClient as if chosen by the user.
440 scoped_refptr<password_manager::TestPasswordStore> store(
441 new password_manager::TestPasswordStore);
442 const bool zero_click = false;
443 store->AddLogin(GetTestPasswordForm1(zero_click));
444 stub_client_.SetPasswordStore(store);
445 stub_client_.SetUserChosenCredential(password_manager::CredentialInfo(
446 GetTestPasswordForm1(zero_click),
447 password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD));
448 WaitForBackgroundTasks();
449
450 // Request a credential. The request should be resolved with the credential
451 // set on the stub client.
452 const int first_request_id = 0;
453 bool first_verified = false;
454 ExpectPromiseResolved(&first_verified, first_request_id,
455 GetTestWebCredential1(zero_click));
456 credential_manager_->CredentialsRequested(
457 first_request_id, GURL("http://foo.com/login"), zero_click,
458 std::vector<std::string>(), true);
459
460 // Pump the message loop and verify.
461 WaitForBackgroundTasks();
462 EXPECT_TRUE(first_verified);
463
464 ClearPromiseResolutionExpectations();
465
466 // Make a second request. It should be resolved again.
467 const int second_request_id = 1;
468 bool second_verified = false;
469 ExpectPromiseResolved(&second_verified, second_request_id,
470 GetTestWebCredential1(zero_click));
471 credential_manager_->CredentialsRequested(
472 second_request_id, GURL("http://foo.com/login"), zero_click,
473 std::vector<std::string>(), true);
474
475 // Pump the message loop and verify.
476 WaitForBackgroundTasks();
477 EXPECT_TRUE(second_verified);
478 }
479
480 // Tests that notifySignedIn prompts the user to save a password.
481 TEST_F(CredentialManagerTest,
482 SignInResolvesAndPromptsUserWhenSavingEnabledAndNotBlacklisted) {
483 // Set a password store so the PasswordFormManager can retrieve credentials.
484 scoped_refptr<password_manager::TestPasswordStore> store(
485 new password_manager::TestPasswordStore);
486 stub_client_.SetPasswordStore(store);
487 const bool saving_enabled = true;
488 EXPECT_CALL(stub_client_, IsSavingAndFillingEnabledForCurrentPage())
489 .WillOnce(Return(saving_enabled))
490 .WillOnce(Return(saving_enabled));
491
492 // Notify the browser that the user signed in.
493 const int request_id = 0;
494 ExpectPromiseResolved(request_id);
495 const bool zero_click = false;
496 credential_manager_->SignedIn(request_id, GURL("http://foo.com/login"),
497 GetTestWebCredential1(zero_click));
498
499 // Pump the message loop and verify.
500 WaitForBackgroundTasks();
501 autofill::PasswordForm expected_observed_form(
502 GetTestPasswordForm1(zero_click));
503 expected_observed_form.username_value.clear();
504 expected_observed_form.password_value.clear();
505 EXPECT_EQ(expected_observed_form, stub_client_.saved_form()->observed_form());
506 }
507
508 // Tests that notifySignedIn doesn't prompt the user to save a password when the
509 // password manager is disabled for the current page.
510 TEST_F(CredentialManagerTest,
511 SignInResolvesAndDoesNotPromptsUserWhenSavingDisabledAndNotBlacklisted) {
512 // Disable saving.
513 scoped_refptr<password_manager::TestPasswordStore> store(
514 new password_manager::TestPasswordStore);
515 stub_client_.SetPasswordStore(store);
516 const bool saving_enabled = false;
517 EXPECT_CALL(stub_client_, IsSavingAndFillingEnabledForCurrentPage())
518 .WillOnce(Return(saving_enabled));
519
520 // Notify the browser that the user signed in.
521 const int request_id = 0;
522 ExpectPromiseResolved(request_id);
523 const bool zero_click = false;
524 credential_manager_->SignedIn(request_id, GURL("http://foo.com/login"),
525 GetTestWebCredential1(zero_click));
526
527 // Pump the message loop and verify that no form was saved.
528 WaitForBackgroundTasks();
529 EXPECT_FALSE(stub_client_.saved_form());
530 }
531
532 // Tests that notifySignedIn doesn't prompt the user to save a password when the
533 // submitted form is blacklisted by the password manager.
534 TEST_F(CredentialManagerTest,
535 SignInResolvesAndDoesNotPromptUserWhenSavingEnabledAndBlacklisted) {
536 // Disable saving.
537 scoped_refptr<password_manager::TestPasswordStore> store(
538 new password_manager::TestPasswordStore);
539 stub_client_.SetPasswordStore(store);
540 const bool saving_enabled = true;
541 EXPECT_CALL(stub_client_, IsSavingAndFillingEnabledForCurrentPage())
542 .WillOnce(Return(saving_enabled))
543 .WillOnce(Return(saving_enabled));
544
545 // Save the credential that will be signed in and mark it blacklisted.
546 const bool zero_click = false;
547 autofill::PasswordForm blacklisted_form(GetTestPasswordForm1(zero_click));
548 blacklisted_form.blacklisted_by_user = true;
549 store->AddLogin(blacklisted_form);
550 WaitForBackgroundTasks();
551
552 // Notify the browser that the user signed in.
553 const int request_id = 0;
554 ExpectPromiseResolved(request_id);
555 credential_manager_->SignedIn(request_id, GURL("http://foo.com/login"),
556 GetTestWebCredential1(zero_click));
557
558 // Pump the message loop and verify that no form was saved.
559 WaitForBackgroundTasks();
560 EXPECT_FALSE(stub_client_.saved_form());
561 }
562
563 // Tests that notifySignedOut marks credentials as non-zero-click.
564 TEST_F(CredentialManagerTest, SignOutResolvesAndMarksFormsNonZeroClick) {
565 // Create two zero-click credentials for the current page.
566 std::string current_origin(credential_manager_->GetOrigin().spec());
567 autofill::PasswordForm form1(GetTestPasswordForm1(true));
568 form1.signon_realm = current_origin;
569 autofill::PasswordForm form2(GetTestPasswordForm2(true));
570 form2.signon_realm = current_origin;
571
572 // Add both credentials to the store.
573 scoped_refptr<password_manager::TestPasswordStore> store(
574 new password_manager::TestPasswordStore);
575 stub_client_.SetPasswordStore(store);
576 store->AddLogin(form1);
577 store->AddLogin(form2);
578 WaitForBackgroundTasks();
579
580 // Check that both credentials in the store are zero-click.
581 EXPECT_EQ(1U, store->stored_passwords().size());
582 const std::vector<autofill::PasswordForm>& passwords_before_signout =
583 store->stored_passwords().find(current_origin)->second;
584 EXPECT_EQ(2U, passwords_before_signout.size());
585 for (const autofill::PasswordForm& form : passwords_before_signout)
586 EXPECT_FALSE(form.skip_zero_click);
587
588 // Sign out the current origin, which has credentials, and a second origin,
589 // which doesnt.
590 const int first_request_id = 0;
591 ExpectPromiseResolved(first_request_id);
592 credential_manager_->SignedOut(first_request_id,
593 credential_manager_->GetOrigin());
594 const int second_request_id = 1;
595 ExpectPromiseResolved(second_request_id);
596 credential_manager_->SignedOut(second_request_id, GURL("https://foo.com"));
597
598 // Pump the message loop to let the promises resolve. Check that the
599 // credentials in the store are now non-zero-click and that signing out an
600 // origin with no credentials had no effect.
601 WaitForBackgroundTasks();
602 EXPECT_EQ(1U, store->stored_passwords().size());
603 const std::vector<autofill::PasswordForm>& passwords_after_signout =
604 store->stored_passwords().find(current_origin)->second;
605 EXPECT_EQ(2U, passwords_after_signout.size());
606 for (const autofill::PasswordForm& form : passwords_after_signout)
607 EXPECT_TRUE(form.skip_zero_click);
608 }
609
610 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698