Move Tuple to base namespace.
[chromium-blink-merge.git] / components / password_manager / content / browser / credential_manager_dispatcher_unittest.cc
blob56452f496916367321cd7a2ff383b5f4ab3e3634
1 // Copyright 2014 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.
5 #include "components/password_manager/content/browser/credential_manager_dispatcher.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/prefs/pref_registry_simple.h"
10 #include "base/prefs/testing_pref_service.h"
11 #include "base/run_loop.h"
12 #include "base/strings/string16.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "components/password_manager/content/common/credential_manager_messages.h"
15 #include "components/password_manager/core/browser/credential_manager_password_form_manager.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 "content/public/browser/web_contents.h"
22 #include "content/public/test/mock_render_process_host.h"
23 #include "content/public/test/test_renderer_host.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 using content::BrowserContext;
28 using content::WebContents;
30 using testing::_;
32 namespace {
34 // Chosen by fair dice roll. Guaranteed to be random.
35 const int kRequestId = 4;
37 class MockPasswordManagerClient
38 : public password_manager::StubPasswordManagerClient {
39 public:
40 MOCK_CONST_METHOD0(IsSavingEnabledForCurrentPage, bool());
41 MOCK_CONST_METHOD0(IsOffTheRecord, bool());
42 MOCK_METHOD1(NotifyUserAutoSigninPtr,
43 bool(const std::vector<autofill::PasswordForm*>& local_forms));
44 MOCK_METHOD2(PromptUserToSavePasswordPtr,
45 void(password_manager::PasswordFormManager*,
46 password_manager::CredentialSourceType type));
47 MOCK_METHOD4(PromptUserToChooseCredentialsPtr,
48 bool(const std::vector<autofill::PasswordForm*>& local_forms,
49 const std::vector<autofill::PasswordForm*>& federated_forms,
50 const GURL& origin,
51 base::Callback<void(
52 const password_manager::CredentialInfo&)> callback));
54 MockPasswordManagerClient(password_manager::PasswordStore* store)
55 : store_(store) {
56 prefs_.registry()->RegisterBooleanPref(
57 password_manager::prefs::kPasswordManagerAutoSignin, true);
59 ~MockPasswordManagerClient() override {}
61 bool PromptUserToSavePassword(
62 scoped_ptr<password_manager::PasswordFormManager> manager,
63 password_manager::CredentialSourceType type) override {
64 manager_.swap(manager);
65 PromptUserToSavePasswordPtr(manager_.get(), type);
66 return true;
69 password_manager::PasswordStore* GetPasswordStore() const override {
70 return store_;
73 PrefService* GetPrefs() override { return &prefs_; }
75 bool PromptUserToChooseCredentials(
76 ScopedVector<autofill::PasswordForm> local_forms,
77 ScopedVector<autofill::PasswordForm> federated_forms,
78 const GURL& origin,
79 base::Callback<void(const password_manager::CredentialInfo&)> callback) {
80 EXPECT_FALSE(local_forms.empty() && federated_forms.empty());
81 password_manager::CredentialInfo info(
82 local_forms.empty() ? *federated_forms[0] : *local_forms[0],
83 local_forms.empty()
84 ? password_manager::CredentialType::CREDENTIAL_TYPE_FEDERATED
85 : password_manager::CredentialType::CREDENTIAL_TYPE_LOCAL);
86 base::MessageLoop::current()->PostTask(FROM_HERE,
87 base::Bind(callback, info));
88 PromptUserToChooseCredentialsPtr(local_forms.get(), federated_forms.get(),
89 origin, callback);
90 return true;
93 void NotifyUserAutoSignin(
94 ScopedVector<autofill::PasswordForm> local_forms) override {
95 EXPECT_FALSE(local_forms.empty());
96 NotifyUserAutoSigninPtr(local_forms.get());
99 password_manager::PasswordFormManager* pending_manager() const {
100 return manager_.get();
103 void set_zero_click_enabled(bool zero_click_enabled) {
104 prefs_.SetBoolean(password_manager::prefs::kPasswordManagerAutoSignin,
105 zero_click_enabled);
108 private:
109 TestingPrefServiceSimple prefs_;
110 password_manager::PasswordStore* store_;
111 scoped_ptr<password_manager::PasswordFormManager> manager_;
113 DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerClient);
116 class TestCredentialManagerDispatcher
117 : public password_manager::CredentialManagerDispatcher {
118 public:
119 TestCredentialManagerDispatcher(
120 content::WebContents* web_contents,
121 password_manager::PasswordManagerClient* client,
122 password_manager::PasswordManagerDriver* driver);
124 private:
125 base::WeakPtr<password_manager::PasswordManagerDriver> GetDriver() override;
127 base::WeakPtr<password_manager::PasswordManagerDriver> driver_;
130 TestCredentialManagerDispatcher::TestCredentialManagerDispatcher(
131 content::WebContents* web_contents,
132 password_manager::PasswordManagerClient* client,
133 password_manager::PasswordManagerDriver* driver)
134 : CredentialManagerDispatcher(web_contents, client),
135 driver_(driver->AsWeakPtr()) {
138 base::WeakPtr<password_manager::PasswordManagerDriver>
139 TestCredentialManagerDispatcher::GetDriver() {
140 return driver_;
143 void RunAllPendingTasks() {
144 base::RunLoop run_loop;
145 base::MessageLoop::current()->PostTask(
146 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
147 run_loop.Run();
150 } // namespace
152 namespace password_manager {
154 class CredentialManagerDispatcherTest
155 : public content::RenderViewHostTestHarness {
156 public:
157 CredentialManagerDispatcherTest() {}
159 void SetUp() override {
160 content::RenderViewHostTestHarness::SetUp();
161 store_ = new TestPasswordStore;
162 client_.reset(new MockPasswordManagerClient(store_.get()));
163 dispatcher_.reset(new TestCredentialManagerDispatcher(
164 web_contents(), client_.get(), &stub_driver_));
165 ON_CALL(*client_, IsSavingEnabledForCurrentPage())
166 .WillByDefault(testing::Return(true));
167 ON_CALL(*client_, IsOffTheRecord()).WillByDefault(testing::Return(false));
169 NavigateAndCommit(GURL("https://example.com/test.html"));
171 form_.username_value = base::ASCIIToUTF16("Username");
172 form_.display_name = base::ASCIIToUTF16("Display Name");
173 form_.password_value = base::ASCIIToUTF16("Password");
174 form_.origin = web_contents()->GetLastCommittedURL().GetOrigin();
175 form_.signon_realm = form_.origin.spec();
176 form_.scheme = autofill::PasswordForm::SCHEME_HTML;
177 form_.skip_zero_click = false;
179 origin_path_form_.username_value = base::ASCIIToUTF16("Username 2");
180 origin_path_form_.display_name = base::ASCIIToUTF16("Display Name 2");
181 origin_path_form_.password_value = base::ASCIIToUTF16("Password 2");
182 origin_path_form_.origin = GURL("https://example.com/path");
183 origin_path_form_.signon_realm = origin_path_form_.origin.spec();
184 origin_path_form_.scheme = autofill::PasswordForm::SCHEME_HTML;
185 origin_path_form_.skip_zero_click = false;
187 cross_origin_form_.username_value = base::ASCIIToUTF16("Username");
188 cross_origin_form_.display_name = base::ASCIIToUTF16("Display Name");
189 cross_origin_form_.password_value = base::ASCIIToUTF16("Password");
190 cross_origin_form_.origin = GURL("https://example.net/");
191 cross_origin_form_.signon_realm = cross_origin_form_.origin.spec();
192 cross_origin_form_.scheme = autofill::PasswordForm::SCHEME_HTML;
193 cross_origin_form_.skip_zero_click = false;
195 store_->Clear();
196 EXPECT_TRUE(store_->IsEmpty());
199 void TearDown() override {
200 store_->Shutdown();
201 content::RenderViewHostTestHarness::TearDown();
204 CredentialManagerDispatcher* dispatcher() { return dispatcher_.get(); }
206 protected:
207 autofill::PasswordForm form_;
208 autofill::PasswordForm origin_path_form_;
209 autofill::PasswordForm cross_origin_form_;
210 scoped_refptr<TestPasswordStore> store_;
211 scoped_ptr<MockPasswordManagerClient> client_;
212 StubPasswordManagerDriver stub_driver_;
213 scoped_ptr<CredentialManagerDispatcher> dispatcher_;
216 TEST_F(CredentialManagerDispatcherTest, CredentialManagerOnNotifyFailedSignIn) {
217 CredentialInfo info;
218 info.type = CredentialType::CREDENTIAL_TYPE_LOCAL;
219 dispatcher()->OnNotifyFailedSignIn(kRequestId, info);
221 const uint32 kMsgID = CredentialManagerMsg_AcknowledgeFailedSignIn::ID;
222 const IPC::Message* message =
223 process()->sink().GetFirstMessageMatching(kMsgID);
224 EXPECT_TRUE(message);
225 process()->sink().ClearMessages();
228 TEST_F(CredentialManagerDispatcherTest, CredentialManagerOnNotifySignedIn) {
229 CredentialInfo info(form_,
230 password_manager::CredentialType::CREDENTIAL_TYPE_LOCAL);
231 EXPECT_CALL(
232 *client_,
233 PromptUserToSavePasswordPtr(
234 _, password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API))
235 .Times(testing::Exactly(1));
237 dispatcher()->OnNotifySignedIn(kRequestId, info);
239 const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedIn::ID;
240 const IPC::Message* message =
241 process()->sink().GetFirstMessageMatching(kMsgID);
242 EXPECT_TRUE(message);
243 process()->sink().ClearMessages();
245 // Allow the PasswordFormManager to talk to the password store, determine
246 // that the form is new, and set it as pending.
247 RunAllPendingTasks();
249 EXPECT_TRUE(client_->pending_manager()->HasCompletedMatching());
251 autofill::PasswordForm new_form =
252 client_->pending_manager()->pending_credentials();
253 EXPECT_EQ(form_.username_value, new_form.username_value);
254 EXPECT_EQ(form_.display_name, new_form.display_name);
255 EXPECT_EQ(form_.password_value, new_form.password_value);
256 EXPECT_EQ(form_.origin, new_form.origin);
257 EXPECT_EQ(form_.signon_realm, new_form.signon_realm);
258 EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML, new_form.scheme);
261 TEST_F(CredentialManagerDispatcherTest,
262 CredentialManagerSignInWithSavingDisabledForCurrentPage) {
263 CredentialInfo info(form_, CredentialType::CREDENTIAL_TYPE_LOCAL);
264 EXPECT_CALL(*client_, IsSavingEnabledForCurrentPage())
265 .WillRepeatedly(testing::Return(false));
266 EXPECT_CALL(
267 *client_,
268 PromptUserToSavePasswordPtr(
269 _, password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API))
270 .Times(testing::Exactly(0));
272 dispatcher()->OnNotifySignedIn(kRequestId, info);
274 const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedIn::ID;
275 const IPC::Message* message =
276 process()->sink().GetFirstMessageMatching(kMsgID);
277 EXPECT_TRUE(message);
278 process()->sink().ClearMessages();
280 RunAllPendingTasks();
282 EXPECT_FALSE(client_->pending_manager());
285 TEST_F(CredentialManagerDispatcherTest, CredentialManagerOnNotifySignedOut) {
286 store_->AddLogin(form_);
287 store_->AddLogin(cross_origin_form_);
288 RunAllPendingTasks();
290 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
291 EXPECT_EQ(2U, passwords.size());
292 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
293 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
294 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
295 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
297 dispatcher()->OnNotifySignedOut(kRequestId);
298 RunAllPendingTasks();
300 const uint32 kMsgID = CredentialManagerMsg_AcknowledgeSignedOut::ID;
301 const IPC::Message* message =
302 process()->sink().GetFirstMessageMatching(kMsgID);
303 EXPECT_TRUE(message);
304 process()->sink().ClearMessages();
306 passwords = store_->stored_passwords();
307 EXPECT_EQ(2U, passwords.size());
308 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
309 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
310 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
311 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
314 TEST_F(CredentialManagerDispatcherTest,
315 CredentialManagerOnRequestCredentialWithEmptyPasswordStore) {
316 std::vector<GURL> federations;
317 EXPECT_CALL(
318 *client_,
319 PromptUserToSavePasswordPtr(
320 _, password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API))
321 .Times(testing::Exactly(0));
322 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
323 .Times(testing::Exactly(0));
324 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
326 dispatcher()->OnRequestCredential(kRequestId, false, federations);
328 RunAllPendingTasks();
330 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
331 const IPC::Message* message =
332 process()->sink().GetFirstMessageMatching(kMsgID);
333 EXPECT_TRUE(message);
334 CredentialManagerMsg_SendCredential::Param param;
335 CredentialManagerMsg_SendCredential::Read(message, &param);
336 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY, base::get<1>(param).type);
337 process()->sink().ClearMessages();
340 TEST_F(CredentialManagerDispatcherTest,
341 CredentialManagerOnRequestCredentialWithCrossOriginPasswordStore) {
342 store_->AddLogin(cross_origin_form_);
344 std::vector<GURL> federations;
345 EXPECT_CALL(
346 *client_,
347 PromptUserToSavePasswordPtr(
348 _, password_manager::CredentialSourceType::CREDENTIAL_SOURCE_API))
349 .Times(testing::Exactly(0));
350 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
351 .Times(testing::Exactly(0));
352 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
354 dispatcher()->OnRequestCredential(kRequestId, false, federations);
356 RunAllPendingTasks();
358 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
359 const IPC::Message* message =
360 process()->sink().GetFirstMessageMatching(kMsgID);
361 EXPECT_TRUE(message);
362 CredentialManagerMsg_SendCredential::Param param;
363 CredentialManagerMsg_SendCredential::Read(message, &param);
364 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY, base::get<1>(param).type);
365 process()->sink().ClearMessages();
368 TEST_F(CredentialManagerDispatcherTest,
369 CredentialManagerOnRequestCredentialWithFullPasswordStore) {
370 client_->set_zero_click_enabled(false);
371 store_->AddLogin(form_);
373 std::vector<GURL> federations;
374 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
375 .Times(testing::Exactly(1));
376 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
378 dispatcher()->OnRequestCredential(kRequestId, false, federations);
380 RunAllPendingTasks();
382 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
383 const IPC::Message* message =
384 process()->sink().GetFirstMessageMatching(kMsgID);
385 EXPECT_TRUE(message);
388 TEST_F(
389 CredentialManagerDispatcherTest,
390 CredentialManagerOnRequestCredentialWithZeroClickOnlyEmptyPasswordStore) {
391 std::vector<GURL> federations;
392 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
393 .Times(testing::Exactly(0));
394 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
396 dispatcher()->OnRequestCredential(kRequestId, true, federations);
398 RunAllPendingTasks();
400 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
401 const IPC::Message* message =
402 process()->sink().GetFirstMessageMatching(kMsgID);
403 EXPECT_TRUE(message);
404 CredentialManagerMsg_SendCredential::Param send_param;
405 CredentialManagerMsg_SendCredential::Read(message, &send_param);
406 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
407 base::get<1>(send_param).type);
410 TEST_F(CredentialManagerDispatcherTest,
411 CredentialManagerOnRequestCredentialWithZeroClickOnlyFullPasswordStore) {
412 store_->AddLogin(form_);
414 std::vector<GURL> federations;
415 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
416 .Times(testing::Exactly(0));
417 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(1));
419 dispatcher()->OnRequestCredential(kRequestId, true, federations);
421 RunAllPendingTasks();
423 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
424 const IPC::Message* message =
425 process()->sink().GetFirstMessageMatching(kMsgID);
426 EXPECT_TRUE(message);
427 CredentialManagerMsg_SendCredential::Param send_param;
428 CredentialManagerMsg_SendCredential::Read(message, &send_param);
429 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_LOCAL,
430 base::get<1>(send_param).type);
433 TEST_F(CredentialManagerDispatcherTest,
434 CredentialManagerOnRequestCredentialWithZeroClickOnlyTwoPasswordStore) {
435 store_->AddLogin(form_);
436 store_->AddLogin(origin_path_form_);
438 std::vector<GURL> federations;
439 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
440 .Times(testing::Exactly(0));
441 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
443 dispatcher()->OnRequestCredential(kRequestId, true, federations);
445 RunAllPendingTasks();
447 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
448 const IPC::Message* message =
449 process()->sink().GetFirstMessageMatching(kMsgID);
450 EXPECT_TRUE(message);
451 CredentialManagerMsg_SendCredential::Param send_param;
452 CredentialManagerMsg_SendCredential::Read(message, &send_param);
454 // With two items in the password store, we shouldn't get credentials back.
455 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
456 base::get<1>(send_param).type);
459 TEST_F(CredentialManagerDispatcherTest,
460 OnRequestCredentialWithZeroClickOnlyOnePasswordStore) {
461 form_.skip_zero_click = true;
462 store_->AddLogin(form_);
463 store_->AddLogin(origin_path_form_);
465 std::vector<GURL> federations;
466 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
467 .Times(testing::Exactly(0));
468 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(1));
470 dispatcher()->OnRequestCredential(kRequestId, true, federations);
472 RunAllPendingTasks();
474 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
475 const IPC::Message* message =
476 process()->sink().GetFirstMessageMatching(kMsgID);
477 EXPECT_TRUE(message);
478 CredentialManagerMsg_SendCredential::Param send_param;
479 CredentialManagerMsg_SendCredential::Read(message, &send_param);
481 // We should get |origin_path_form_| back, as |form_| is marked as skipping
482 // zero-click.
483 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_LOCAL,
484 base::get<1>(send_param).type);
485 EXPECT_EQ(origin_path_form_.username_value, base::get<1>(send_param).id);
486 EXPECT_EQ(origin_path_form_.display_name, base::get<1>(send_param).name);
487 EXPECT_EQ(origin_path_form_.password_value,
488 base::get<1>(send_param).password);
491 TEST_F(CredentialManagerDispatcherTest,
492 OnRequestCredentialWithZeroClickOnlyCrossOriginPasswordStore) {
493 store_->AddLogin(cross_origin_form_);
495 form_.skip_zero_click = true;
496 store_->AddLogin(form_);
498 std::vector<GURL> federations;
499 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
500 .Times(testing::Exactly(0));
501 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
503 dispatcher()->OnRequestCredential(kRequestId, true, federations);
505 RunAllPendingTasks();
507 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
508 const IPC::Message* message =
509 process()->sink().GetFirstMessageMatching(kMsgID);
510 EXPECT_TRUE(message);
511 CredentialManagerMsg_SendCredential::Param send_param;
512 CredentialManagerMsg_SendCredential::Read(message, &send_param);
514 // We only have cross-origin zero-click credentials; they should not be
515 // returned.
516 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
517 base::get<1>(send_param).type);
520 TEST_F(CredentialManagerDispatcherTest,
521 CredentialManagerOnRequestCredentialWhileRequestPending) {
522 client_->set_zero_click_enabled(false);
523 store_->AddLogin(form_);
525 std::vector<GURL> federations;
526 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
527 .Times(testing::Exactly(0));
528 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
530 dispatcher()->OnRequestCredential(kRequestId, false, federations);
531 dispatcher()->OnRequestCredential(kRequestId, false, federations);
533 // Check that the second request triggered a rejection.
534 uint32 kMsgID = CredentialManagerMsg_RejectCredentialRequest::ID;
535 const IPC::Message* message =
536 process()->sink().GetFirstMessageMatching(kMsgID);
537 EXPECT_TRUE(message);
539 CredentialManagerMsg_RejectCredentialRequest::Param reject_param;
540 CredentialManagerMsg_RejectCredentialRequest::Read(message, &reject_param);
541 EXPECT_EQ(blink::WebCredentialManagerError::ErrorTypePendingRequest,
542 base::get<1>(reject_param));
543 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
544 .Times(testing::Exactly(1));
545 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
547 process()->sink().ClearMessages();
549 // Execute the PasswordStore asynchronousness.
550 RunAllPendingTasks();
552 // Check that the first request resolves.
553 kMsgID = CredentialManagerMsg_SendCredential::ID;
554 message = process()->sink().GetFirstMessageMatching(kMsgID);
555 EXPECT_TRUE(message);
556 CredentialManagerMsg_SendCredential::Param send_param;
557 CredentialManagerMsg_SendCredential::Read(message, &send_param);
558 EXPECT_NE(CredentialType::CREDENTIAL_TYPE_EMPTY,
559 base::get<1>(send_param).type);
560 process()->sink().ClearMessages();
563 TEST_F(CredentialManagerDispatcherTest, ResetSkipZeroClickAfterPrompt) {
564 // Turn on the global zero-click flag, and add two credentials in separate
565 // origins, both set to skip zero-click.
566 client_->set_zero_click_enabled(true);
567 form_.skip_zero_click = true;
568 store_->AddLogin(form_);
569 cross_origin_form_.skip_zero_click = true;
570 store_->AddLogin(cross_origin_form_);
572 // Execute the PasswordStore asynchronousness to ensure everything is
573 // written before proceeding.
574 RunAllPendingTasks();
576 // Sanity check.
577 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
578 EXPECT_EQ(2U, passwords.size());
579 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
580 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
581 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
582 EXPECT_TRUE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
584 // Trigger a request which should return the credential found in |form_|, and
585 // wait for it to process.
586 std::vector<GURL> federations;
587 // Check that the form in the database has been updated. `OnRequestCredential`
588 // generates a call to prompt the user to choose a credential.
589 // MockPasswordManagerClient mocks a user choice, and when users choose a
590 // credential (and have the global zero-click flag enabled), we make sure that
591 // they'll be logged in again next time.
592 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
593 .Times(testing::Exactly(1));
594 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
596 dispatcher()->OnRequestCredential(kRequestId, false, federations);
597 RunAllPendingTasks();
599 passwords = store_->stored_passwords();
600 EXPECT_EQ(2U, passwords.size());
601 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
602 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
603 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
604 EXPECT_TRUE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
607 TEST_F(CredentialManagerDispatcherTest, IncognitoZeroClickRequestCredential) {
608 EXPECT_CALL(*client_, IsOffTheRecord()).WillRepeatedly(testing::Return(true));
609 store_->AddLogin(form_);
611 std::vector<GURL> federations;
612 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
613 .Times(testing::Exactly(0));
614 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
616 dispatcher()->OnRequestCredential(kRequestId, true, federations);
618 RunAllPendingTasks();
620 const uint32 kMsgID = CredentialManagerMsg_SendCredential::ID;
621 const IPC::Message* message =
622 process()->sink().GetFirstMessageMatching(kMsgID);
623 ASSERT_TRUE(message);
624 CredentialManagerMsg_SendCredential::Param param;
625 CredentialManagerMsg_SendCredential::Read(message, &param);
626 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY, base::get<1>(param).type);
629 } // namespace password_manager