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

Side by Side Diff: components/password_manager/content/browser/credential_manager_dispatcher_unittest.cc

Issue 1762603002: Switch components/password_manager code from IPC messages to Mojo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add browsertests. Created 4 years, 9 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 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.
4
5 #include "components/password_manager/content/browser/credential_manager_dispatc her.h"
6
7 #include <stdint.h>
8
9 #include <string>
10 #include <tuple>
11 #include <vector>
12
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/macros.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string16.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/thread_task_runner_handle.h"
20 #include "components/password_manager/content/common/credential_manager_messages .h"
21 #include "components/password_manager/core/browser/credential_manager_password_f orm_manager.h"
22 #include "components/password_manager/core/browser/mock_affiliated_match_helper. h"
23 #include "components/password_manager/core/browser/password_manager.h"
24 #include "components/password_manager/core/browser/stub_password_manager_client. h"
25 #include "components/password_manager/core/browser/stub_password_manager_driver. h"
26 #include "components/password_manager/core/browser/test_password_store.h"
27 #include "components/password_manager/core/common/credential_manager_types.h"
28 #include "components/password_manager/core/common/password_manager_pref_names.h"
29 #include "components/prefs/pref_registry_simple.h"
30 #include "components/prefs/testing_pref_service.h"
31 #include "content/public/browser/web_contents.h"
32 #include "content/public/test/mock_render_process_host.h"
33 #include "content/public/test/test_renderer_host.h"
34 #include "testing/gmock/include/gmock/gmock.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36
37 using content::BrowserContext;
38 using content::WebContents;
39
40 using testing::_;
41
42 namespace password_manager {
43
44 namespace {
45
46 // Chosen by fair dice roll. Guaranteed to be random.
47 const int kRequestId = 4;
48
49 const char kTestWebOrigin[] = "https://example.com/";
50 const char kTestAndroidRealm1[] = "android://hash@com.example.one.android/";
51 const char kTestAndroidRealm2[] = "android://hash@com.example.two.android/";
52
53 class MockPasswordManagerClient : public StubPasswordManagerClient {
54 public:
55 MOCK_CONST_METHOD0(IsSavingAndFillingEnabledForCurrentPage, bool());
56 MOCK_CONST_METHOD0(IsOffTheRecord, bool());
57 MOCK_CONST_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
58 MOCK_METHOD1(NotifyUserAutoSigninPtr,
59 bool(const std::vector<autofill::PasswordForm*>& local_forms));
60 MOCK_METHOD1(NotifyUserCouldBeAutoSignedInPtr,
61 bool(autofill::PasswordForm* form));
62 MOCK_METHOD2(PromptUserToSavePasswordPtr,
63 void(PasswordFormManager*, CredentialSourceType type));
64 MOCK_METHOD4(PromptUserToChooseCredentialsPtr,
65 bool(const std::vector<autofill::PasswordForm*>& local_forms,
66 const std::vector<autofill::PasswordForm*>& federated_forms,
67 const GURL& origin,
68 base::Callback<void(const CredentialInfo&)> callback));
69
70 explicit MockPasswordManagerClient(PasswordStore* store) : store_(store) {
71 prefs_.registry()->RegisterBooleanPref(prefs::kCredentialsEnableAutosignin,
72 true);
73 prefs_.registry()->RegisterBooleanPref(
74 prefs::kWasAutoSignInFirstRunExperienceShown, true);
75 }
76 ~MockPasswordManagerClient() override {}
77
78 bool PromptUserToSaveOrUpdatePassword(scoped_ptr<PasswordFormManager> manager,
79 CredentialSourceType type,
80 bool update_password) override {
81 manager_.swap(manager);
82 PromptUserToSavePasswordPtr(manager_.get(), type);
83 return true;
84 }
85
86 void NotifyUserCouldBeAutoSignedIn(
87 scoped_ptr<autofill::PasswordForm> form) override {
88 NotifyUserCouldBeAutoSignedInPtr(form.get());
89 }
90
91 PasswordStore* GetPasswordStore() const override { return store_; }
92
93 PrefService* GetPrefs() override { return &prefs_; }
94
95 bool PromptUserToChooseCredentials(
96 ScopedVector<autofill::PasswordForm> local_forms,
97 ScopedVector<autofill::PasswordForm> federated_forms,
98 const GURL& origin,
99 base::Callback<void(const CredentialInfo&)> callback) {
100 EXPECT_FALSE(local_forms.empty() && federated_forms.empty());
101 CredentialInfo info(
102 local_forms.empty() ? *federated_forms[0] : *local_forms[0],
103 local_forms.empty() ? CredentialType::CREDENTIAL_TYPE_FEDERATED
104 : CredentialType::CREDENTIAL_TYPE_PASSWORD);
105 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
106 base::Bind(callback, info));
107 PromptUserToChooseCredentialsPtr(local_forms.get(), federated_forms.get(),
108 origin, callback);
109 return true;
110 }
111
112 void NotifyUserAutoSignin(
113 ScopedVector<autofill::PasswordForm> local_forms) override {
114 EXPECT_FALSE(local_forms.empty());
115 NotifyUserAutoSigninPtr(local_forms.get());
116 }
117
118 PasswordFormManager* pending_manager() const { return manager_.get(); }
119
120 void set_zero_click_enabled(bool zero_click_enabled) {
121 prefs_.SetBoolean(prefs::kCredentialsEnableAutosignin, zero_click_enabled);
122 }
123
124 void set_first_run_seen(bool first_run_seen) {
125 prefs_.SetBoolean(prefs::kWasAutoSignInFirstRunExperienceShown,
126 first_run_seen);
127 }
128
129 private:
130 TestingPrefServiceSimple prefs_;
131 PasswordStore* store_;
132 scoped_ptr<PasswordFormManager> manager_;
133
134 DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerClient);
135 };
136
137 class TestCredentialManagerDispatcher : public CredentialManagerDispatcher {
138 public:
139 TestCredentialManagerDispatcher(content::WebContents* web_contents,
140 PasswordManagerClient* client,
141 PasswordManagerDriver* driver);
142
143 private:
144 base::WeakPtr<PasswordManagerDriver> GetDriver() override;
145
146 base::WeakPtr<PasswordManagerDriver> driver_;
147 };
148
149 TestCredentialManagerDispatcher::TestCredentialManagerDispatcher(
150 content::WebContents* web_contents,
151 PasswordManagerClient* client,
152 PasswordManagerDriver* driver)
153 : CredentialManagerDispatcher(web_contents, client),
154 driver_(driver->AsWeakPtr()) {}
155
156 base::WeakPtr<PasswordManagerDriver>
157 TestCredentialManagerDispatcher::GetDriver() {
158 return driver_;
159 }
160
161 void RunAllPendingTasks() {
162 base::RunLoop run_loop;
163 base::MessageLoop::current()->PostTask(
164 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
165 run_loop.Run();
166 }
167
168 class SlightlyLessStubbyPasswordManagerDriver
169 : public StubPasswordManagerDriver {
170 public:
171 explicit SlightlyLessStubbyPasswordManagerDriver(
172 PasswordManagerClient* client)
173 : password_manager_(client) {}
174
175 PasswordManager* GetPasswordManager() override { return &password_manager_; }
176
177 private:
178 PasswordManager password_manager_;
179 };
180
181 } // namespace
182
183 class CredentialManagerDispatcherTest
184 : public content::RenderViewHostTestHarness {
185 public:
186 CredentialManagerDispatcherTest() {}
187
188 void SetUp() override {
189 content::RenderViewHostTestHarness::SetUp();
190 store_ = new TestPasswordStore;
191 client_.reset(
192 new testing::NiceMock<MockPasswordManagerClient>(store_.get()));
193 stub_driver_.reset(
194 new SlightlyLessStubbyPasswordManagerDriver(client_.get()));
195 dispatcher_.reset(new TestCredentialManagerDispatcher(
196 web_contents(), client_.get(), stub_driver_.get()));
197 ON_CALL(*client_, IsSavingAndFillingEnabledForCurrentPage())
198 .WillByDefault(testing::Return(true));
199 ON_CALL(*client_, IsOffTheRecord()).WillByDefault(testing::Return(false));
200 ON_CALL(*client_, DidLastPageLoadEncounterSSLErrors())
201 .WillByDefault(testing::Return(false));
202
203 NavigateAndCommit(GURL("https://example.com/test.html"));
204
205 form_.username_value = base::ASCIIToUTF16("Username");
206 form_.display_name = base::ASCIIToUTF16("Display Name");
207 form_.password_value = base::ASCIIToUTF16("Password");
208 form_.origin = web_contents()->GetLastCommittedURL().GetOrigin();
209 form_.signon_realm = form_.origin.spec();
210 form_.scheme = autofill::PasswordForm::SCHEME_HTML;
211 form_.skip_zero_click = false;
212 form_.ssl_valid = true;
213
214 affiliated_form1_.username_value = base::ASCIIToUTF16("Affiliated 1");
215 affiliated_form1_.display_name = base::ASCIIToUTF16("Display Name");
216 affiliated_form1_.password_value = base::ASCIIToUTF16("Password");
217 affiliated_form1_.origin = GURL();
218 affiliated_form1_.signon_realm = kTestAndroidRealm1;
219 affiliated_form1_.scheme = autofill::PasswordForm::SCHEME_HTML;
220 affiliated_form1_.skip_zero_click = false;
221 affiliated_form1_.ssl_valid = true;
222
223 affiliated_form2_.username_value = base::ASCIIToUTF16("Affiliated 2");
224 affiliated_form2_.display_name = base::ASCIIToUTF16("Display Name");
225 affiliated_form2_.password_value = base::ASCIIToUTF16("Password");
226 affiliated_form2_.origin = GURL();
227 affiliated_form2_.signon_realm = kTestAndroidRealm2;
228 affiliated_form2_.scheme = autofill::PasswordForm::SCHEME_HTML;
229 affiliated_form2_.skip_zero_click = false;
230 affiliated_form2_.ssl_valid = true;
231
232 origin_path_form_.username_value = base::ASCIIToUTF16("Username 2");
233 origin_path_form_.display_name = base::ASCIIToUTF16("Display Name 2");
234 origin_path_form_.password_value = base::ASCIIToUTF16("Password 2");
235 origin_path_form_.origin = GURL("https://example.com/path");
236 origin_path_form_.signon_realm = origin_path_form_.origin.spec();
237 origin_path_form_.scheme = autofill::PasswordForm::SCHEME_HTML;
238 origin_path_form_.skip_zero_click = false;
239
240 cross_origin_form_.username_value = base::ASCIIToUTF16("Username");
241 cross_origin_form_.display_name = base::ASCIIToUTF16("Display Name");
242 cross_origin_form_.password_value = base::ASCIIToUTF16("Password");
243 cross_origin_form_.origin = GURL("https://example.net/");
244 cross_origin_form_.signon_realm = cross_origin_form_.origin.spec();
245 cross_origin_form_.scheme = autofill::PasswordForm::SCHEME_HTML;
246 cross_origin_form_.skip_zero_click = false;
247
248 store_->Clear();
249 EXPECT_TRUE(store_->IsEmpty());
250 }
251
252 void TearDown() override {
253 store_->ShutdownOnUIThread();
254 content::RenderViewHostTestHarness::TearDown();
255 }
256
257 void ExpectZeroClickSignInFailure() {
258 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
259 .Times(testing::Exactly(0));
260 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_))
261 .Times(testing::Exactly(0));
262
263 RunAllPendingTasks();
264
265 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
266 const IPC::Message* message =
267 process()->sink().GetFirstMessageMatching(kMsgID);
268 ASSERT_TRUE(message);
269 CredentialManagerMsg_SendCredential::Param send_param;
270 CredentialManagerMsg_SendCredential::Read(message, &send_param);
271
272 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
273 std::get<1>(send_param).type);
274 }
275
276 void ExpectZeroClickSignInSuccess(CredentialType type) {
277 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
278 .Times(testing::Exactly(0));
279 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_))
280 .Times(testing::Exactly(1));
281
282 RunAllPendingTasks();
283
284 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
285 const IPC::Message* message =
286 process()->sink().GetFirstMessageMatching(kMsgID);
287 ASSERT_TRUE(message);
288 CredentialManagerMsg_SendCredential::Param send_param;
289 CredentialManagerMsg_SendCredential::Read(message, &send_param);
290
291 EXPECT_EQ(type, std::get<1>(send_param).type);
292 }
293
294 CredentialManagerDispatcher* dispatcher() { return dispatcher_.get(); }
295
296 protected:
297 autofill::PasswordForm form_;
298 autofill::PasswordForm affiliated_form1_;
299 autofill::PasswordForm affiliated_form2_;
300 autofill::PasswordForm origin_path_form_;
301 autofill::PasswordForm cross_origin_form_;
302 scoped_refptr<TestPasswordStore> store_;
303 scoped_ptr<testing::NiceMock<MockPasswordManagerClient>> client_;
304 scoped_ptr<SlightlyLessStubbyPasswordManagerDriver> stub_driver_;
305 scoped_ptr<CredentialManagerDispatcher> dispatcher_;
306 };
307
308 TEST_F(CredentialManagerDispatcherTest, IsZeroClickAllowed) {
309 // IsZeroClickAllowed is uneffected by the first-run status.
310 client_->set_zero_click_enabled(true);
311 client_->set_first_run_seen(true);
312 EXPECT_TRUE(dispatcher()->IsZeroClickAllowed());
313
314 client_->set_zero_click_enabled(true);
315 client_->set_first_run_seen(false);
316 EXPECT_TRUE(dispatcher()->IsZeroClickAllowed());
317
318 client_->set_zero_click_enabled(false);
319 client_->set_first_run_seen(true);
320 EXPECT_FALSE(dispatcher()->IsZeroClickAllowed());
321
322 client_->set_zero_click_enabled(false);
323 client_->set_first_run_seen(false);
324 EXPECT_FALSE(dispatcher()->IsZeroClickAllowed());
325 }
326
327 TEST_F(CredentialManagerDispatcherTest, CredentialManagerOnStore) {
328 CredentialInfo info(form_, CredentialType::CREDENTIAL_TYPE_PASSWORD);
329 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
330 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
331 .Times(testing::Exactly(1));
332
333 dispatcher()->OnStore(kRequestId, info);
334
335 const uint32_t kMsgID = CredentialManagerMsg_AcknowledgeStore::ID;
336 const IPC::Message* message =
337 process()->sink().GetFirstMessageMatching(kMsgID);
338 EXPECT_TRUE(message);
339 process()->sink().ClearMessages();
340
341 // Allow the PasswordFormManager to talk to the password store, determine
342 // that the form is new, and set it as pending.
343 RunAllPendingTasks();
344
345 EXPECT_TRUE(client_->pending_manager()->HasCompletedMatching());
346
347 autofill::PasswordForm new_form =
348 client_->pending_manager()->pending_credentials();
349 EXPECT_EQ(form_.username_value, new_form.username_value);
350 EXPECT_EQ(form_.display_name, new_form.display_name);
351 EXPECT_EQ(form_.password_value, new_form.password_value);
352 EXPECT_EQ(form_.origin, new_form.origin);
353 EXPECT_EQ(form_.signon_realm, new_form.signon_realm);
354 EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML, new_form.scheme);
355 }
356
357 TEST_F(CredentialManagerDispatcherTest, CredentialManagerStoreOverwrite) {
358 // Populate the PasswordStore with a form.
359 store_->AddLogin(form_);
360 RunAllPendingTasks();
361
362 // Calling 'OnStore' with a credential that matches |form_| should update
363 // the password without prompting the user.
364 CredentialInfo info(form_, CredentialType::CREDENTIAL_TYPE_PASSWORD);
365 info.password = base::ASCIIToUTF16("Totally new password.");
366 dispatcher()->OnStore(kRequestId, info);
367
368 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
369 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
370 .Times(testing::Exactly(0));
371
372 const uint32_t kMsgID = CredentialManagerMsg_AcknowledgeStore::ID;
373 const IPC::Message* message =
374 process()->sink().GetFirstMessageMatching(kMsgID);
375 EXPECT_TRUE(message);
376 process()->sink().ClearMessages();
377
378 // Allow the PasswordFormManager to talk to the password store, determine
379 // the form is a match for an existing form, and update the PasswordStore.
380 RunAllPendingTasks();
381
382 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
383 EXPECT_EQ(1U, passwords.size());
384 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
385 EXPECT_EQ(base::ASCIIToUTF16("Totally new password."),
386 passwords[form_.signon_realm][0].password_value);
387 }
388
389 TEST_F(CredentialManagerDispatcherTest,
390 CredentialManagerStoreOverwriteZeroClick) {
391 // Set the global zero click flag on, and populate the PasswordStore with a
392 // form that's set to skip zero click.
393 client_->set_zero_click_enabled(true);
394 form_.skip_zero_click = true;
395 store_->AddLogin(form_);
396 RunAllPendingTasks();
397
398 // Calling 'OnStore' with a credential that matches |form_| should update
399 // the password without prompting the user.
400 CredentialInfo info(form_, CredentialType::CREDENTIAL_TYPE_PASSWORD);
401 info.password = base::ASCIIToUTF16("Totally new password.");
402 dispatcher()->OnStore(kRequestId, info);
403 process()->sink().ClearMessages();
404
405 // Allow the PasswordFormManager to talk to the password store, determine
406 // the form is a match for an existing form, and update the PasswordStore.
407 RunAllPendingTasks();
408
409 // Verify that the update didn't toggle the skip_zero_click flag off.
410 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
411 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
412 }
413
414 TEST_F(CredentialManagerDispatcherTest,
415 CredentialManagerSignInWithSavingDisabledForCurrentPage) {
416 CredentialInfo info(form_, CredentialType::CREDENTIAL_TYPE_PASSWORD);
417 EXPECT_CALL(*client_, IsSavingAndFillingEnabledForCurrentPage())
418 .WillRepeatedly(testing::Return(false));
419 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
420 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
421 .Times(testing::Exactly(0));
422
423 dispatcher()->OnStore(kRequestId, info);
424
425 const uint32_t kMsgID = CredentialManagerMsg_AcknowledgeStore::ID;
426 const IPC::Message* message =
427 process()->sink().GetFirstMessageMatching(kMsgID);
428 EXPECT_TRUE(message);
429 process()->sink().ClearMessages();
430
431 RunAllPendingTasks();
432
433 EXPECT_FALSE(client_->pending_manager());
434 }
435
436 TEST_F(CredentialManagerDispatcherTest,
437 CredentialManagerOnRequireUserMediation) {
438 store_->AddLogin(form_);
439 store_->AddLogin(cross_origin_form_);
440 RunAllPendingTasks();
441
442 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
443 EXPECT_EQ(2U, passwords.size());
444 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
445 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
446 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
447 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
448
449 dispatcher()->OnRequireUserMediation(kRequestId);
450 RunAllPendingTasks();
451
452 const uint32_t kMsgID =
453 CredentialManagerMsg_AcknowledgeRequireUserMediation::ID;
454 const IPC::Message* message =
455 process()->sink().GetFirstMessageMatching(kMsgID);
456 EXPECT_TRUE(message);
457 process()->sink().ClearMessages();
458
459 passwords = store_->stored_passwords();
460 EXPECT_EQ(2U, passwords.size());
461 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
462 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
463 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
464 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
465 }
466
467 TEST_F(CredentialManagerDispatcherTest,
468 CredentialManagerOnRequireUserMediationIncognito) {
469 EXPECT_CALL(*client_, IsOffTheRecord()).WillRepeatedly(testing::Return(true));
470 store_->AddLogin(form_);
471 RunAllPendingTasks();
472
473 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
474 ASSERT_EQ(1U, passwords.size());
475 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
476 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
477
478 dispatcher()->OnRequireUserMediation(kRequestId);
479 RunAllPendingTasks();
480
481 const uint32_t kMsgID =
482 CredentialManagerMsg_AcknowledgeRequireUserMediation::ID;
483 const IPC::Message* message =
484 process()->sink().GetFirstMessageMatching(kMsgID);
485 EXPECT_TRUE(message);
486 process()->sink().ClearMessages();
487
488 passwords = store_->stored_passwords();
489 ASSERT_EQ(1U, passwords.size());
490 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
491 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
492 }
493
494 TEST_F(CredentialManagerDispatcherTest,
495 CredentialManagerOnRequireUserMediationWithAffiliation) {
496 store_->AddLogin(form_);
497 store_->AddLogin(cross_origin_form_);
498 store_->AddLogin(affiliated_form1_);
499 store_->AddLogin(affiliated_form2_);
500
501 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
502 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
503
504 std::vector<GURL> federations;
505 std::vector<std::string> affiliated_realms;
506 affiliated_realms.push_back(kTestAndroidRealm1);
507 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
508 ->ExpectCallToGetAffiliatedAndroidRealms(
509 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
510 RunAllPendingTasks();
511
512 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
513 EXPECT_EQ(4U, passwords.size());
514 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
515 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
516 EXPECT_FALSE(passwords[affiliated_form1_.signon_realm][0].skip_zero_click);
517 EXPECT_FALSE(passwords[affiliated_form2_.signon_realm][0].skip_zero_click);
518
519 dispatcher()->OnRequireUserMediation(kRequestId);
520 RunAllPendingTasks();
521 process()->sink().ClearMessages();
522
523 passwords = store_->stored_passwords();
524 EXPECT_EQ(4U, passwords.size());
525 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
526 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
527 EXPECT_TRUE(passwords[affiliated_form1_.signon_realm][0].skip_zero_click);
528 EXPECT_FALSE(passwords[affiliated_form2_.signon_realm][0].skip_zero_click);
529 }
530
531 TEST_F(CredentialManagerDispatcherTest,
532 CredentialManagerOnRequestCredentialWithEmptyPasswordStore) {
533 std::vector<GURL> federations;
534 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
535 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
536 .Times(testing::Exactly(0));
537 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
538 .Times(testing::Exactly(0));
539 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
540
541 dispatcher()->OnRequestCredential(kRequestId, false, true, federations);
542
543 RunAllPendingTasks();
544
545 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
546 const IPC::Message* message =
547 process()->sink().GetFirstMessageMatching(kMsgID);
548 EXPECT_TRUE(message);
549 CredentialManagerMsg_SendCredential::Param param;
550 CredentialManagerMsg_SendCredential::Read(message, &param);
551 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY, std::get<1>(param).type);
552 process()->sink().ClearMessages();
553 }
554
555 TEST_F(CredentialManagerDispatcherTest,
556 CredentialManagerOnRequestCredentialWithCrossOriginPasswordStore) {
557 store_->AddLogin(cross_origin_form_);
558
559 std::vector<GURL> federations;
560 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
561 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
562 .Times(testing::Exactly(0));
563 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
564 .Times(testing::Exactly(0));
565 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
566
567 dispatcher()->OnRequestCredential(kRequestId, false, true, federations);
568
569 RunAllPendingTasks();
570
571 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
572 const IPC::Message* message =
573 process()->sink().GetFirstMessageMatching(kMsgID);
574 EXPECT_TRUE(message);
575 CredentialManagerMsg_SendCredential::Param param;
576 CredentialManagerMsg_SendCredential::Read(message, &param);
577 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY, std::get<1>(param).type);
578 process()->sink().ClearMessages();
579 }
580
581 TEST_F(CredentialManagerDispatcherTest,
582 CredentialManagerOnRequestCredentialWithFullPasswordStore) {
583 client_->set_zero_click_enabled(false);
584 store_->AddLogin(form_);
585
586 std::vector<GURL> federations;
587 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
588 .Times(testing::Exactly(1));
589 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
590
591 dispatcher()->OnRequestCredential(kRequestId, false, true, federations);
592
593 RunAllPendingTasks();
594
595 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
596 const IPC::Message* message =
597 process()->sink().GetFirstMessageMatching(kMsgID);
598 EXPECT_TRUE(message);
599 }
600
601 TEST_F(
602 CredentialManagerDispatcherTest,
603 CredentialManagerOnRequestCredentialWithZeroClickOnlyEmptyPasswordStore) {
604 std::vector<GURL> federations;
605 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
606 .Times(testing::Exactly(0));
607 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
608
609 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
610
611 RunAllPendingTasks();
612
613 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
614 const IPC::Message* message =
615 process()->sink().GetFirstMessageMatching(kMsgID);
616 EXPECT_TRUE(message);
617 CredentialManagerMsg_SendCredential::Param send_param;
618 CredentialManagerMsg_SendCredential::Read(message, &send_param);
619 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
620 std::get<1>(send_param).type);
621 }
622
623 TEST_F(CredentialManagerDispatcherTest,
624 CredentialManagerOnRequestCredentialWithZeroClickOnlyFullPasswordStore) {
625 store_->AddLogin(form_);
626 client_->set_first_run_seen(true);
627
628 std::vector<GURL> federations;
629
630 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
631 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
632
633 ExpectZeroClickSignInSuccess(CredentialType::CREDENTIAL_TYPE_PASSWORD);
634 }
635
636 TEST_F(CredentialManagerDispatcherTest,
637 CredentialManagerOnRequestCredentialWithoutPasswords) {
638 store_->AddLogin(form_);
639 client_->set_first_run_seen(true);
640
641 std::vector<GURL> federations;
642
643 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
644 dispatcher()->OnRequestCredential(kRequestId, true, false, federations);
645
646 ExpectZeroClickSignInFailure();
647 }
648
649 TEST_F(CredentialManagerDispatcherTest,
650 CredentialManagerOnRequestCredentialFederatedMatch) {
651 form_.federation_origin = url::Origin(GURL("https://example.com/"));
652 store_->AddLogin(form_);
653 client_->set_first_run_seen(true);
654
655 std::vector<GURL> federations;
656 federations.push_back(GURL("https://example.com/"));
657
658 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
659 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
660
661 ExpectZeroClickSignInSuccess(CredentialType::CREDENTIAL_TYPE_FEDERATED);
662 }
663
664 TEST_F(CredentialManagerDispatcherTest,
665 CredentialManagerOnRequestCredentialFederatedNoMatch) {
666 form_.federation_origin = url::Origin(GURL("https://example.com/"));
667 store_->AddLogin(form_);
668 client_->set_first_run_seen(true);
669
670 std::vector<GURL> federations;
671 federations.push_back(GURL("https://not-example.com/"));
672
673 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
674 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
675
676 ExpectZeroClickSignInFailure();
677 }
678
679 TEST_F(CredentialManagerDispatcherTest,
680 CredentialManagerOnRequestCredentialAffiliatedPasswordMatch) {
681 store_->AddLogin(affiliated_form1_);
682 client_->set_first_run_seen(true);
683 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
684 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
685
686 std::vector<GURL> federations;
687 std::vector<std::string> affiliated_realms;
688 affiliated_realms.push_back(kTestAndroidRealm1);
689 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
690 ->ExpectCallToGetAffiliatedAndroidRealms(
691 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
692
693 // We pass in 'true' for the 'include_passwords' argument to ensure that
694 // password-type credentials are included as potential matches.
695 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
696
697 ExpectZeroClickSignInSuccess(CredentialType::CREDENTIAL_TYPE_PASSWORD);
698 }
699
700 TEST_F(CredentialManagerDispatcherTest,
701 CredentialManagerOnRequestCredentialAffiliatedPasswordNoMatch) {
702 store_->AddLogin(affiliated_form1_);
703 client_->set_first_run_seen(true);
704 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
705 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
706
707 std::vector<GURL> federations;
708 std::vector<std::string> affiliated_realms;
709 affiliated_realms.push_back(kTestAndroidRealm1);
710 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
711 ->ExpectCallToGetAffiliatedAndroidRealms(
712 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
713
714 // We pass in 'false' for the 'include_passwords' argument to ensure that
715 // password-type credentials are excluded as potential matches.
716 dispatcher()->OnRequestCredential(kRequestId, true, false, federations);
717
718 ExpectZeroClickSignInFailure();
719 }
720
721 TEST_F(CredentialManagerDispatcherTest,
722 CredentialManagerOnRequestCredentialAffiliatedFederatedMatch) {
723 affiliated_form1_.federation_origin =
724 url::Origin(GURL("https://example.com/"));
725 store_->AddLogin(affiliated_form1_);
726 client_->set_first_run_seen(true);
727 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
728 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
729
730 std::vector<GURL> federations;
731 federations.push_back(GURL("https://example.com/"));
732
733 std::vector<std::string> affiliated_realms;
734 affiliated_realms.push_back(kTestAndroidRealm1);
735 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
736 ->ExpectCallToGetAffiliatedAndroidRealms(
737 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
738
739 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
740
741 ExpectZeroClickSignInSuccess(CredentialType::CREDENTIAL_TYPE_FEDERATED);
742 }
743
744 TEST_F(CredentialManagerDispatcherTest,
745 CredentialManagerOnRequestCredentialAffiliatedFederatedNoMatch) {
746 affiliated_form1_.federation_origin =
747 url::Origin(GURL("https://example.com/"));
748 store_->AddLogin(affiliated_form1_);
749 client_->set_first_run_seen(true);
750 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
751 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
752
753 std::vector<GURL> federations;
754 federations.push_back(GURL("https://not-example.com/"));
755
756 std::vector<std::string> affiliated_realms;
757 affiliated_realms.push_back(kTestAndroidRealm1);
758 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
759 ->ExpectCallToGetAffiliatedAndroidRealms(
760 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
761
762 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
763
764 ExpectZeroClickSignInFailure();
765 }
766
767 TEST_F(CredentialManagerDispatcherTest, RequestCredentialWithoutFirstRun) {
768 client_->set_first_run_seen(false);
769
770 store_->AddLogin(form_);
771
772 std::vector<GURL> federations;
773 EXPECT_CALL(*client_,
774 NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_)))
775 .Times(1);
776 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
777
778 ExpectZeroClickSignInFailure();
779 }
780
781 TEST_F(CredentialManagerDispatcherTest, RequestCredentialWithFirstRunAndSkip) {
782 client_->set_first_run_seen(true);
783
784 form_.skip_zero_click = true;
785 store_->AddLogin(form_);
786
787 std::vector<GURL> federations;
788 EXPECT_CALL(*client_,
789 NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_)))
790 .Times(1);
791 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
792
793 ExpectZeroClickSignInFailure();
794 }
795
796 TEST_F(CredentialManagerDispatcherTest, RequestCredentialWithTLSErrors) {
797 // If we encounter TLS errors, we won't return credentials.
798 EXPECT_CALL(*client_, DidLastPageLoadEncounterSSLErrors())
799 .WillRepeatedly(testing::Return(true));
800
801 store_->AddLogin(form_);
802
803 std::vector<GURL> federations;
804 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
805
806 ExpectZeroClickSignInFailure();
807 }
808
809 TEST_F(CredentialManagerDispatcherTest,
810 CredentialManagerOnRequestCredentialWithZeroClickOnlyTwoPasswordStore) {
811 store_->AddLogin(form_);
812 store_->AddLogin(origin_path_form_);
813
814 std::vector<GURL> federations;
815 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
816 .Times(testing::Exactly(0));
817 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
818
819 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
820
821 RunAllPendingTasks();
822
823 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
824 const IPC::Message* message =
825 process()->sink().GetFirstMessageMatching(kMsgID);
826 EXPECT_TRUE(message);
827 CredentialManagerMsg_SendCredential::Param send_param;
828 CredentialManagerMsg_SendCredential::Read(message, &send_param);
829
830 // With two items in the password store, we shouldn't get credentials back.
831 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
832 std::get<1>(send_param).type);
833 }
834
835 TEST_F(CredentialManagerDispatcherTest,
836 OnRequestCredentialWithZeroClickOnlyAndSkipZeroClickPasswordStore) {
837 form_.skip_zero_click = true;
838 store_->AddLogin(form_);
839 store_->AddLogin(origin_path_form_);
840
841 std::vector<GURL> federations;
842 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
843 .Times(testing::Exactly(0));
844 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
845
846 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
847
848 RunAllPendingTasks();
849
850 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
851 const IPC::Message* message =
852 process()->sink().GetFirstMessageMatching(kMsgID);
853 EXPECT_TRUE(message);
854 CredentialManagerMsg_SendCredential::Param send_param;
855 CredentialManagerMsg_SendCredential::Read(message, &send_param);
856
857 // With two items in the password store, we shouldn't get credentials back,
858 // even though only one item has |skip_zero_click| set |false|.
859 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
860 std::get<1>(send_param).type);
861 }
862
863 TEST_F(CredentialManagerDispatcherTest,
864 OnRequestCredentialWithZeroClickOnlyCrossOriginPasswordStore) {
865 store_->AddLogin(cross_origin_form_);
866
867 form_.skip_zero_click = true;
868 store_->AddLogin(form_);
869
870 std::vector<GURL> federations;
871 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
872 .Times(testing::Exactly(0));
873 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
874
875 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
876
877 RunAllPendingTasks();
878
879 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
880 const IPC::Message* message =
881 process()->sink().GetFirstMessageMatching(kMsgID);
882 EXPECT_TRUE(message);
883 CredentialManagerMsg_SendCredential::Param send_param;
884 CredentialManagerMsg_SendCredential::Read(message, &send_param);
885
886 // We only have cross-origin zero-click credentials; they should not be
887 // returned.
888 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY,
889 std::get<1>(send_param).type);
890 }
891
892 TEST_F(CredentialManagerDispatcherTest,
893 CredentialManagerOnRequestCredentialWhileRequestPending) {
894 client_->set_zero_click_enabled(false);
895 store_->AddLogin(form_);
896
897 std::vector<GURL> federations;
898 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
899 .Times(testing::Exactly(0));
900 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
901
902 dispatcher()->OnRequestCredential(kRequestId, false, true, federations);
903 dispatcher()->OnRequestCredential(kRequestId + 1, false, true, federations);
904
905 // Check that the second request triggered a rejection.
906 uint32_t kMsgID = CredentialManagerMsg_RejectCredentialRequest::ID;
907 const IPC::Message* message =
908 process()->sink().GetFirstMessageMatching(kMsgID);
909 EXPECT_TRUE(message);
910
911 CredentialManagerMsg_RejectCredentialRequest::Param reject_param;
912 CredentialManagerMsg_RejectCredentialRequest::Read(message, &reject_param);
913 EXPECT_EQ(blink::WebCredentialManagerPendingRequestError,
914 std::get<1>(reject_param));
915 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
916 .Times(testing::Exactly(1));
917 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
918
919 process()->sink().ClearMessages();
920
921 // Execute the PasswordStore asynchronousness.
922 RunAllPendingTasks();
923
924 // Check that the first request resolves.
925 kMsgID = CredentialManagerMsg_SendCredential::ID;
926 message = process()->sink().GetFirstMessageMatching(kMsgID);
927 EXPECT_TRUE(message);
928 CredentialManagerMsg_SendCredential::Param send_param;
929 CredentialManagerMsg_SendCredential::Read(message, &send_param);
930 EXPECT_NE(CredentialType::CREDENTIAL_TYPE_EMPTY,
931 std::get<1>(send_param).type);
932 process()->sink().ClearMessages();
933 }
934
935 TEST_F(CredentialManagerDispatcherTest, ResetSkipZeroClickAfterPrompt) {
936 // Turn on the global zero-click flag, and add two credentials in separate
937 // origins, both set to skip zero-click.
938 client_->set_zero_click_enabled(true);
939 form_.skip_zero_click = true;
940 store_->AddLogin(form_);
941 cross_origin_form_.skip_zero_click = true;
942 store_->AddLogin(cross_origin_form_);
943
944 // Execute the PasswordStore asynchronousness to ensure everything is
945 // written before proceeding.
946 RunAllPendingTasks();
947
948 // Sanity check.
949 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
950 EXPECT_EQ(2U, passwords.size());
951 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
952 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
953 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
954 EXPECT_TRUE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
955
956 // Trigger a request which should return the credential found in |form_|, and
957 // wait for it to process.
958 std::vector<GURL> federations;
959 // Check that the form in the database has been updated. `OnRequestCredential`
960 // generates a call to prompt the user to choose a credential.
961 // MockPasswordManagerClient mocks a user choice, and when users choose a
962 // credential (and have the global zero-click flag enabled), we make sure that
963 // they'll be logged in again next time.
964 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
965 .Times(testing::Exactly(1));
966 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
967
968 dispatcher()->OnRequestCredential(kRequestId, false, true, federations);
969 RunAllPendingTasks();
970
971 passwords = store_->stored_passwords();
972 EXPECT_EQ(2U, passwords.size());
973 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
974 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
975 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
976 EXPECT_TRUE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
977 }
978
979 TEST_F(CredentialManagerDispatcherTest,
980 NoResetSkipZeroClickAfterPromptInIncognito) {
981 EXPECT_CALL(*client_, IsOffTheRecord()).WillRepeatedly(testing::Return(true));
982 // Turn on the global zero-click flag which should be overriden by Incognito.
983 client_->set_zero_click_enabled(true);
984 form_.skip_zero_click = true;
985 store_->AddLogin(form_);
986 RunAllPendingTasks();
987
988 // Sanity check.
989 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
990 ASSERT_EQ(1U, passwords.size());
991 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
992 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
993
994 // Trigger a request which should return the credential found in |form_|, and
995 // wait for it to process.
996 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
997 .Times(testing::Exactly(1));
998 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
999
1000 dispatcher()->OnRequestCredential(kRequestId, false, true,
1001 std::vector<GURL>());
1002 RunAllPendingTasks();
1003
1004 // The form shouldn't become a zero-click one.
1005 passwords = store_->stored_passwords();
1006 ASSERT_EQ(1U, passwords.size());
1007 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
1008 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
1009 }
1010
1011 TEST_F(CredentialManagerDispatcherTest, IncognitoZeroClickRequestCredential) {
1012 EXPECT_CALL(*client_, IsOffTheRecord()).WillRepeatedly(testing::Return(true));
1013 store_->AddLogin(form_);
1014
1015 std::vector<GURL> federations;
1016 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
1017 .Times(testing::Exactly(0));
1018 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
1019
1020 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
1021
1022 RunAllPendingTasks();
1023
1024 const uint32_t kMsgID = CredentialManagerMsg_SendCredential::ID;
1025 const IPC::Message* message =
1026 process()->sink().GetFirstMessageMatching(kMsgID);
1027 ASSERT_TRUE(message);
1028 CredentialManagerMsg_SendCredential::Param param;
1029 CredentialManagerMsg_SendCredential::Read(message, &param);
1030 EXPECT_EQ(CredentialType::CREDENTIAL_TYPE_EMPTY, std::get<1>(param).type);
1031 }
1032
1033 TEST_F(CredentialManagerDispatcherTest,
1034 ZeroClickWithAffiliatedFormInPasswordStore) {
1035 // Insert the affiliated form into the store, and mock out the association
1036 // with the current origin. As it's the only form matching the origin, it
1037 // ought to be returned automagically.
1038 store_->AddLogin(affiliated_form1_);
1039
1040 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
1041 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1042
1043 std::vector<GURL> federations;
1044 std::vector<std::string> affiliated_realms;
1045 affiliated_realms.push_back(kTestAndroidRealm1);
1046 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1047 ->ExpectCallToGetAffiliatedAndroidRealms(
1048 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
1049
1050 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
1051
1052 ExpectZeroClickSignInSuccess(CredentialType::CREDENTIAL_TYPE_PASSWORD);
1053 }
1054
1055 TEST_F(CredentialManagerDispatcherTest,
1056 ZeroClickWithTwoAffiliatedFormsInPasswordStore) {
1057 // Insert two affiliated forms into the store, and mock out the association
1058 // with the current origin. Multiple forms === no zero-click sign in.
1059 store_->AddLogin(affiliated_form1_);
1060 store_->AddLogin(affiliated_form2_);
1061
1062 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
1063 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1064
1065 std::vector<GURL> federations;
1066 std::vector<std::string> affiliated_realms;
1067 affiliated_realms.push_back(kTestAndroidRealm1);
1068 affiliated_realms.push_back(kTestAndroidRealm2);
1069 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1070 ->ExpectCallToGetAffiliatedAndroidRealms(
1071 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
1072
1073 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
1074
1075 ExpectZeroClickSignInFailure();
1076 }
1077
1078 TEST_F(CredentialManagerDispatcherTest,
1079 ZeroClickWithUnaffiliatedFormsInPasswordStore) {
1080 // Insert the affiliated form into the store, but don't mock out the
1081 // association with the current origin. No association === no zero-click sign
1082 // in.
1083 store_->AddLogin(affiliated_form1_);
1084
1085 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
1086 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1087
1088 std::vector<GURL> federations;
1089 std::vector<std::string> affiliated_realms;
1090 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1091 ->ExpectCallToGetAffiliatedAndroidRealms(
1092 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
1093
1094 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
1095
1096 ExpectZeroClickSignInFailure();
1097 }
1098
1099 TEST_F(CredentialManagerDispatcherTest,
1100 ZeroClickWithFormAndUnaffiliatedFormsInPasswordStore) {
1101 // Insert the affiliated form into the store, along with a real form for the
1102 // origin, and don't mock out the association with the current origin. No
1103 // association + existing form === zero-click sign in.
1104 store_->AddLogin(form_);
1105 store_->AddLogin(affiliated_form1_);
1106
1107 auto mock_helper = make_scoped_ptr(new MockAffiliatedMatchHelper);
1108 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1109
1110 std::vector<GURL> federations;
1111 std::vector<std::string> affiliated_realms;
1112 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1113 ->ExpectCallToGetAffiliatedAndroidRealms(
1114 dispatcher_->GetSynthesizedFormForOrigin(), affiliated_realms);
1115
1116 dispatcher()->OnRequestCredential(kRequestId, true, true, federations);
1117
1118 ExpectZeroClickSignInSuccess(CredentialType::CREDENTIAL_TYPE_PASSWORD);
1119 }
1120
1121 TEST_F(CredentialManagerDispatcherTest, GetSynthesizedFormForOrigin) {
1122 autofill::PasswordForm synthesized =
1123 dispatcher_->GetSynthesizedFormForOrigin();
1124 EXPECT_EQ(kTestWebOrigin, synthesized.origin.spec());
1125 EXPECT_EQ(kTestWebOrigin, synthesized.signon_realm);
1126 EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML, synthesized.scheme);
1127 EXPECT_TRUE(synthesized.ssl_valid);
1128 }
1129
1130 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698