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

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

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

Powered by Google App Engine
This is Rietveld 408576698