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

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

Issue 1861973002: Revert of 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 form_.skip_zero_click = true;
443 store_->AddLogin(form_);
444 RunAllPendingTasks();
445
446 // Calling 'Store' with a credential that matches |form_| should update
447 // the password without prompting the user.
448 CredentialInfo info(form_, CredentialType::CREDENTIAL_TYPE_PASSWORD);
449 info.password = base::ASCIIToUTF16("Totally new 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 didn't toggle the skip_zero_click flag off.
458 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
459 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
460 }
461
462 TEST_F(CredentialManagerImplTest, CredentialManagerGetOverwriteZeroClick) {
463 // Set the global zero click flag on, and populate the PasswordStore with a
464 // form that's set to skip zero click and has a primary key that won't match
465 // credentials initially created via `store()`.
466 client_->set_zero_click_enabled(true);
467 form_.skip_zero_click = true;
468 form_.username_element = base::ASCIIToUTF16("username-element");
469 form_.password_element = base::ASCIIToUTF16("password-element");
470 form_.signon_realm = "this is a realm";
471 form_.origin = GURL("https://example.com/old_form.html");
472 store_->AddLogin(form_);
473 RunAllPendingTasks();
474
475 std::vector<GURL> federations;
476 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
477 .Times(testing::Exactly(1));
478 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
479
480 bool called = false;
481 mojom::CredentialManagerError error;
482 mojom::CredentialInfoPtr credential;
483 CallGet(false, true, federations,
484 base::Bind(&GetCredentialCallback, &called, &error, &credential));
485
486 RunAllPendingTasks();
487
488 EXPECT_TRUE(called);
489 EXPECT_EQ(mojom::CredentialManagerError::SUCCESS, error);
490
491 // Verify that the update toggled the skip_zero_click flag.
492 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
493 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
494 }
495
496 TEST_F(CredentialManagerImplTest,
497 CredentialManagerSignInWithSavingDisabledForCurrentPage) {
498 CredentialInfo info(form_, CredentialType::CREDENTIAL_TYPE_PASSWORD);
499 EXPECT_CALL(*client_, IsSavingAndFillingEnabledForCurrentPage())
500 .WillRepeatedly(testing::Return(false));
501 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
502 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
503 .Times(testing::Exactly(0));
504
505 bool called = false;
506 CallStore(info, base::Bind(&RespondCallback, &called));
507
508 RunAllPendingTasks();
509
510 EXPECT_TRUE(called);
511 EXPECT_FALSE(client_->pending_manager());
512 }
513
514 TEST_F(CredentialManagerImplTest, CredentialManagerOnRequireUserMediation) {
515 store_->AddLogin(form_);
516 store_->AddLogin(cross_origin_form_);
517 RunAllPendingTasks();
518
519 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
520 EXPECT_EQ(2U, passwords.size());
521 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
522 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
523 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
524 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
525
526 bool called = false;
527 CallRequireUserMediation(base::Bind(&RespondCallback, &called));
528
529 RunAllPendingTasks();
530
531 EXPECT_TRUE(called);
532
533 passwords = store_->stored_passwords();
534 EXPECT_EQ(2U, passwords.size());
535 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
536 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
537 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
538 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
539 }
540
541 TEST_F(CredentialManagerImplTest,
542 CredentialManagerOnRequireUserMediationIncognito) {
543 EXPECT_CALL(*client_, IsOffTheRecord()).WillRepeatedly(testing::Return(true));
544 store_->AddLogin(form_);
545 RunAllPendingTasks();
546
547 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
548 ASSERT_EQ(1U, passwords.size());
549 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
550 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
551
552 bool called = false;
553 CallRequireUserMediation(base::Bind(&RespondCallback, &called));
554 RunAllPendingTasks();
555
556 EXPECT_TRUE(called);
557
558 passwords = store_->stored_passwords();
559 ASSERT_EQ(1U, passwords.size());
560 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
561 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
562 }
563
564 TEST_F(CredentialManagerImplTest,
565 CredentialManagerOnRequireUserMediationWithAffiliation) {
566 store_->AddLogin(form_);
567 store_->AddLogin(cross_origin_form_);
568 store_->AddLogin(affiliated_form1_);
569 store_->AddLogin(affiliated_form2_);
570
571 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
572 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
573
574 std::vector<GURL> federations;
575 std::vector<std::string> affiliated_realms;
576 affiliated_realms.push_back(kTestAndroidRealm1);
577 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
578 ->ExpectCallToGetAffiliatedAndroidRealms(
579 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
580 RunAllPendingTasks();
581
582 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
583 EXPECT_EQ(4U, passwords.size());
584 EXPECT_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
585 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
586 EXPECT_FALSE(passwords[affiliated_form1_.signon_realm][0].skip_zero_click);
587 EXPECT_FALSE(passwords[affiliated_form2_.signon_realm][0].skip_zero_click);
588
589 bool called = false;
590 CallRequireUserMediation(base::Bind(&RespondCallback, &called));
591 RunAllPendingTasks();
592
593 passwords = store_->stored_passwords();
594 EXPECT_EQ(4U, passwords.size());
595 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
596 EXPECT_FALSE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
597 EXPECT_TRUE(passwords[affiliated_form1_.signon_realm][0].skip_zero_click);
598 EXPECT_FALSE(passwords[affiliated_form2_.signon_realm][0].skip_zero_click);
599 }
600
601 TEST_F(CredentialManagerImplTest,
602 CredentialManagerOnRequestCredentialWithEmptyPasswordStore) {
603 std::vector<GURL> federations;
604 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
605 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
606 .Times(testing::Exactly(0));
607 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
608 .Times(testing::Exactly(0));
609 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
610
611 ExpectCredentialType(false, true, federations, mojom::CredentialType::EMPTY);
612 }
613
614 TEST_F(CredentialManagerImplTest,
615 CredentialManagerOnRequestCredentialWithCrossOriginPasswordStore) {
616 store_->AddLogin(cross_origin_form_);
617
618 std::vector<GURL> federations;
619 EXPECT_CALL(*client_, PromptUserToSavePasswordPtr(
620 _, CredentialSourceType::CREDENTIAL_SOURCE_API))
621 .Times(testing::Exactly(0));
622 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
623 .Times(testing::Exactly(0));
624 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
625
626 ExpectCredentialType(false, true, federations, mojom::CredentialType::EMPTY);
627 }
628
629 TEST_F(CredentialManagerImplTest,
630 CredentialManagerOnRequestCredentialWithFullPasswordStore) {
631 client_->set_zero_click_enabled(false);
632 store_->AddLogin(form_);
633
634 std::vector<GURL> federations;
635 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
636 .Times(testing::Exactly(1));
637 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
638
639 bool called = false;
640 mojom::CredentialManagerError error;
641 mojom::CredentialInfoPtr credential;
642 CallGet(false, true, federations,
643 base::Bind(&GetCredentialCallback, &called, &error, &credential));
644
645 RunAllPendingTasks();
646
647 EXPECT_TRUE(called);
648 EXPECT_EQ(mojom::CredentialManagerError::SUCCESS, error);
649 }
650
651 TEST_F(
652 CredentialManagerImplTest,
653 CredentialManagerOnRequestCredentialWithZeroClickOnlyEmptyPasswordStore) {
654 std::vector<GURL> federations;
655 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
656 .Times(testing::Exactly(0));
657 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
658
659 bool called = false;
660 mojom::CredentialManagerError error;
661 mojom::CredentialInfoPtr credential;
662 CallGet(true, true, federations,
663 base::Bind(&GetCredentialCallback, &called, &error, &credential));
664
665 RunAllPendingTasks();
666
667 EXPECT_TRUE(called);
668 EXPECT_EQ(mojom::CredentialManagerError::SUCCESS, error);
669 }
670
671 TEST_F(CredentialManagerImplTest,
672 CredentialManagerOnRequestCredentialWithZeroClickOnlyFullPasswordStore) {
673 store_->AddLogin(form_);
674 client_->set_first_run_seen(true);
675
676 std::vector<GURL> federations;
677
678 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
679
680 ExpectZeroClickSignInSuccess(true, true, federations,
681 mojom::CredentialType::PASSWORD);
682 }
683
684 TEST_F(CredentialManagerImplTest,
685 CredentialManagerOnRequestCredentialWithoutPasswords) {
686 store_->AddLogin(form_);
687 client_->set_first_run_seen(true);
688
689 std::vector<GURL> federations;
690
691 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
692
693 ExpectZeroClickSignInFailure(true, false, federations);
694 }
695
696 TEST_F(CredentialManagerImplTest,
697 CredentialManagerOnRequestCredentialFederatedMatch) {
698 form_.federation_origin = url::Origin(GURL("https://example.com/"));
699 store_->AddLogin(form_);
700 client_->set_first_run_seen(true);
701
702 std::vector<GURL> federations;
703 federations.push_back(GURL("https://example.com/"));
704
705 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
706
707 ExpectZeroClickSignInSuccess(true, true, federations,
708 mojom::CredentialType::FEDERATED);
709 }
710
711 TEST_F(CredentialManagerImplTest,
712 CredentialManagerOnRequestCredentialFederatedNoMatch) {
713 form_.federation_origin = url::Origin(GURL("https://example.com/"));
714 store_->AddLogin(form_);
715 client_->set_first_run_seen(true);
716
717 std::vector<GURL> federations;
718 federations.push_back(GURL("https://not-example.com/"));
719
720 EXPECT_CALL(*client_, NotifyUserCouldBeAutoSignedInPtr(_)).Times(0);
721
722 ExpectZeroClickSignInFailure(true, true, federations);
723 }
724
725 TEST_F(CredentialManagerImplTest,
726 CredentialManagerOnRequestCredentialAffiliatedPasswordMatch) {
727 store_->AddLogin(affiliated_form1_);
728 client_->set_first_run_seen(true);
729 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
730 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
731
732 std::vector<GURL> federations;
733 std::vector<std::string> affiliated_realms;
734 affiliated_realms.push_back(kTestAndroidRealm1);
735 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
736 ->ExpectCallToGetAffiliatedAndroidRealms(
737 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
738
739 // We pass in 'true' for the 'include_passwords' argument to ensure that
740 // password-type credentials are included as potential matches.
741 ExpectZeroClickSignInSuccess(true, true, federations,
742 mojom::CredentialType::PASSWORD);
743 }
744
745 TEST_F(CredentialManagerImplTest,
746 CredentialManagerOnRequestCredentialAffiliatedPasswordNoMatch) {
747 store_->AddLogin(affiliated_form1_);
748 client_->set_first_run_seen(true);
749 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
750 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
751
752 std::vector<GURL> federations;
753 std::vector<std::string> affiliated_realms;
754 affiliated_realms.push_back(kTestAndroidRealm1);
755 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
756 ->ExpectCallToGetAffiliatedAndroidRealms(
757 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
758
759 // We pass in 'false' for the 'include_passwords' argument to ensure that
760 // password-type credentials are excluded as potential matches.
761 ExpectZeroClickSignInFailure(true, false, federations);
762 }
763
764 TEST_F(CredentialManagerImplTest,
765 CredentialManagerOnRequestCredentialAffiliatedFederatedMatch) {
766 affiliated_form1_.federation_origin =
767 url::Origin(GURL("https://example.com/"));
768 store_->AddLogin(affiliated_form1_);
769 client_->set_first_run_seen(true);
770 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
771 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
772
773 std::vector<GURL> federations;
774 federations.push_back(GURL("https://example.com/"));
775
776 std::vector<std::string> affiliated_realms;
777 affiliated_realms.push_back(kTestAndroidRealm1);
778 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
779 ->ExpectCallToGetAffiliatedAndroidRealms(
780 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
781
782 ExpectZeroClickSignInSuccess(true, true, federations,
783 mojom::CredentialType::FEDERATED);
784 }
785
786 TEST_F(CredentialManagerImplTest,
787 CredentialManagerOnRequestCredentialAffiliatedFederatedNoMatch) {
788 affiliated_form1_.federation_origin =
789 url::Origin(GURL("https://example.com/"));
790 store_->AddLogin(affiliated_form1_);
791 client_->set_first_run_seen(true);
792 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
793 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
794
795 std::vector<GURL> federations;
796 federations.push_back(GURL("https://not-example.com/"));
797
798 std::vector<std::string> affiliated_realms;
799 affiliated_realms.push_back(kTestAndroidRealm1);
800 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
801 ->ExpectCallToGetAffiliatedAndroidRealms(
802 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
803
804 ExpectZeroClickSignInFailure(true, true, federations);
805 }
806
807 TEST_F(CredentialManagerImplTest, RequestCredentialWithoutFirstRun) {
808 client_->set_first_run_seen(false);
809
810 store_->AddLogin(form_);
811
812 std::vector<GURL> federations;
813 EXPECT_CALL(*client_,
814 NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_)))
815 .Times(1);
816
817 ExpectZeroClickSignInFailure(true, true, federations);
818 }
819
820 TEST_F(CredentialManagerImplTest, RequestCredentialWithFirstRunAndSkip) {
821 client_->set_first_run_seen(true);
822
823 form_.skip_zero_click = true;
824 store_->AddLogin(form_);
825
826 std::vector<GURL> federations;
827 EXPECT_CALL(*client_,
828 NotifyUserCouldBeAutoSignedInPtr(testing::Pointee(form_)))
829 .Times(1);
830
831 ExpectZeroClickSignInFailure(true, true, federations);
832 }
833
834 TEST_F(CredentialManagerImplTest, RequestCredentialWithTLSErrors) {
835 // If we encounter TLS errors, we won't return credentials.
836 EXPECT_CALL(*client_, DidLastPageLoadEncounterSSLErrors())
837 .WillRepeatedly(testing::Return(true));
838
839 store_->AddLogin(form_);
840
841 std::vector<GURL> federations;
842
843 ExpectZeroClickSignInFailure(true, true, federations);
844 }
845
846 TEST_F(CredentialManagerImplTest,
847 CredentialManagerOnRequestCredentialWithZeroClickOnlyTwoPasswordStore) {
848 store_->AddLogin(form_);
849 store_->AddLogin(origin_path_form_);
850
851 std::vector<GURL> federations;
852 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
853 .Times(testing::Exactly(0));
854 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
855
856 // With two items in the password store, we shouldn't get credentials back.
857 ExpectCredentialType(true, true, federations, mojom::CredentialType::EMPTY);
858 }
859
860 TEST_F(CredentialManagerImplTest,
861 OnRequestCredentialWithZeroClickOnlyAndSkipZeroClickPasswordStore) {
862 form_.skip_zero_click = true;
863 store_->AddLogin(form_);
864 store_->AddLogin(origin_path_form_);
865
866 std::vector<GURL> federations;
867 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
868 .Times(testing::Exactly(0));
869 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
870
871 // With two items in the password store, we shouldn't get credentials back,
872 // even though only one item has |skip_zero_click| set |false|.
873 ExpectCredentialType(true, true, federations, mojom::CredentialType::EMPTY);
874 }
875
876 TEST_F(CredentialManagerImplTest,
877 OnRequestCredentialWithZeroClickOnlyCrossOriginPasswordStore) {
878 store_->AddLogin(cross_origin_form_);
879
880 form_.skip_zero_click = true;
881 store_->AddLogin(form_);
882
883 std::vector<GURL> federations;
884 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
885 .Times(testing::Exactly(0));
886 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
887
888 // We only have cross-origin zero-click credentials; they should not be
889 // returned.
890 ExpectCredentialType(true, true, federations, mojom::CredentialType::EMPTY);
891 }
892
893 TEST_F(CredentialManagerImplTest,
894 CredentialManagerOnRequestCredentialWhileRequestPending) {
895 client_->set_zero_click_enabled(false);
896 store_->AddLogin(form_);
897
898 std::vector<GURL> federations;
899 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
900 .Times(testing::Exactly(0));
901 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
902
903 // 1st request.
904 bool called_1 = false;
905 mojom::CredentialManagerError error_1;
906 mojom::CredentialInfoPtr credential_1;
907 CallGet(
908 false, true, federations,
909 base::Bind(&GetCredentialCallback, &called_1, &error_1, &credential_1));
910 // 2nd request.
911 bool called_2 = false;
912 mojom::CredentialManagerError error_2;
913 mojom::CredentialInfoPtr credential_2;
914 CallGet(
915 false, true, federations,
916 base::Bind(&GetCredentialCallback, &called_2, &error_2, &credential_2));
917
918 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
919 .Times(testing::Exactly(1));
920 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
921
922 // Execute the PasswordStore asynchronousness.
923 RunAllPendingTasks();
924
925 // Check that the second request triggered a rejection.
926 EXPECT_TRUE(called_2);
927 EXPECT_EQ(mojom::CredentialManagerError::PENDINGREQUEST, error_2);
928 EXPECT_TRUE(credential_2.is_null());
929
930 // Check that the first request resolves.
931 EXPECT_TRUE(called_1);
932 EXPECT_EQ(mojom::CredentialManagerError::SUCCESS, error_1);
933 EXPECT_NE(mojom::CredentialType::EMPTY, credential_1->type);
934 }
935
936 TEST_F(CredentialManagerImplTest, ResetSkipZeroClickAfterPrompt) {
937 // Turn on the global zero-click flag, and add two credentials in separate
938 // origins, both set to skip zero-click.
939 client_->set_zero_click_enabled(true);
940 form_.skip_zero_click = true;
941 store_->AddLogin(form_);
942 cross_origin_form_.skip_zero_click = true;
943 store_->AddLogin(cross_origin_form_);
944
945 // Execute the PasswordStore asynchronousness to ensure everything is
946 // written before proceeding.
947 RunAllPendingTasks();
948
949 // Sanity check.
950 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
951 EXPECT_EQ(2U, passwords.size());
952 EXPECT_EQ(1U, passwords[form_.signon_realm].size());
953 EXPECT_EQ(1U, passwords[cross_origin_form_.signon_realm].size());
954 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
955 EXPECT_TRUE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
956
957 // Trigger a request which should return the credential found in |form_|, and
958 // wait for it to process.
959 std::vector<GURL> federations;
960 // Check that the form in the database has been updated. `OnRequestCredential`
961 // generates a call to prompt the user to choose a credential.
962 // MockPasswordManagerClient mocks a user choice, and when users choose a
963 // credential (and have the global zero-click flag enabled), we make sure that
964 // they'll be logged in again next time.
965 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
966 .Times(testing::Exactly(1));
967 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
968
969 bool called = false;
970 mojom::CredentialManagerError error;
971 mojom::CredentialInfoPtr credential;
972 CallGet(false, true, federations,
973 base::Bind(&GetCredentialCallback, &called, &error, &credential));
974
975 RunAllPendingTasks();
976
977 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_FALSE(passwords[form_.signon_realm][0].skip_zero_click);
982 EXPECT_TRUE(passwords[cross_origin_form_.signon_realm][0].skip_zero_click);
983 }
984
985 TEST_F(CredentialManagerImplTest, NoResetSkipZeroClickAfterPromptInIncognito) {
986 EXPECT_CALL(*client_, IsOffTheRecord()).WillRepeatedly(testing::Return(true));
987 // Turn on the global zero-click flag which should be overriden by Incognito.
988 client_->set_zero_click_enabled(true);
989 form_.skip_zero_click = true;
990 store_->AddLogin(form_);
991 RunAllPendingTasks();
992
993 // Sanity check.
994 TestPasswordStore::PasswordMap passwords = store_->stored_passwords();
995 ASSERT_EQ(1U, passwords.size());
996 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
997 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
998
999 // Trigger a request which should return the credential found in |form_|, and
1000 // wait for it to process.
1001 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
1002 .Times(testing::Exactly(1));
1003 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
1004
1005 bool called = false;
1006 mojom::CredentialManagerError error;
1007 mojom::CredentialInfoPtr credential;
1008 CallGet(false, true, std::vector<GURL>(),
1009 base::Bind(&GetCredentialCallback, &called, &error, &credential));
1010
1011 RunAllPendingTasks();
1012
1013 // The form shouldn't become a zero-click one.
1014 passwords = store_->stored_passwords();
1015 ASSERT_EQ(1U, passwords.size());
1016 ASSERT_EQ(1U, passwords[form_.signon_realm].size());
1017 EXPECT_TRUE(passwords[form_.signon_realm][0].skip_zero_click);
1018 }
1019
1020 TEST_F(CredentialManagerImplTest, IncognitoZeroClickRequestCredential) {
1021 EXPECT_CALL(*client_, IsOffTheRecord()).WillRepeatedly(testing::Return(true));
1022 store_->AddLogin(form_);
1023
1024 std::vector<GURL> federations;
1025 EXPECT_CALL(*client_, PromptUserToChooseCredentialsPtr(_, _, _, _))
1026 .Times(testing::Exactly(0));
1027 EXPECT_CALL(*client_, NotifyUserAutoSigninPtr(_)).Times(testing::Exactly(0));
1028
1029 ExpectCredentialType(true, true, federations, mojom::CredentialType::EMPTY);
1030 }
1031
1032 TEST_F(CredentialManagerImplTest, ZeroClickWithAffiliatedFormInPasswordStore) {
1033 // Insert the affiliated form into the store, and mock out the association
1034 // with the current origin. As it's the only form matching the origin, it
1035 // ought to be returned automagically.
1036 store_->AddLogin(affiliated_form1_);
1037
1038 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
1039 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1040
1041 std::vector<GURL> federations;
1042 std::vector<std::string> affiliated_realms;
1043 affiliated_realms.push_back(kTestAndroidRealm1);
1044 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1045 ->ExpectCallToGetAffiliatedAndroidRealms(
1046 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
1047
1048 ExpectZeroClickSignInSuccess(true, true, federations,
1049 mojom::CredentialType::PASSWORD);
1050 }
1051
1052 TEST_F(CredentialManagerImplTest,
1053 ZeroClickWithTwoAffiliatedFormsInPasswordStore) {
1054 // Insert two affiliated forms into the store, and mock out the association
1055 // with the current origin. Multiple forms === no zero-click sign in.
1056 store_->AddLogin(affiliated_form1_);
1057 store_->AddLogin(affiliated_form2_);
1058
1059 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
1060 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1061
1062 std::vector<GURL> federations;
1063 std::vector<std::string> affiliated_realms;
1064 affiliated_realms.push_back(kTestAndroidRealm1);
1065 affiliated_realms.push_back(kTestAndroidRealm2);
1066 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1067 ->ExpectCallToGetAffiliatedAndroidRealms(
1068 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
1069
1070 ExpectZeroClickSignInFailure(true, true, federations);
1071 }
1072
1073 TEST_F(CredentialManagerImplTest,
1074 ZeroClickWithUnaffiliatedFormsInPasswordStore) {
1075 // Insert the affiliated form into the store, but don't mock out the
1076 // association with the current origin. No association === no zero-click sign
1077 // in.
1078 store_->AddLogin(affiliated_form1_);
1079
1080 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
1081 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1082
1083 std::vector<GURL> federations;
1084 std::vector<std::string> affiliated_realms;
1085 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1086 ->ExpectCallToGetAffiliatedAndroidRealms(
1087 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
1088
1089 ExpectZeroClickSignInFailure(true, true, federations);
1090 }
1091
1092 TEST_F(CredentialManagerImplTest,
1093 ZeroClickWithFormAndUnaffiliatedFormsInPasswordStore) {
1094 // Insert the affiliated form into the store, along with a real form for the
1095 // origin, and don't mock out the association with the current origin. No
1096 // association + existing form === zero-click sign in.
1097 store_->AddLogin(form_);
1098 store_->AddLogin(affiliated_form1_);
1099
1100 auto mock_helper = base::WrapUnique(new MockAffiliatedMatchHelper);
1101 store_->SetAffiliatedMatchHelper(std::move(mock_helper));
1102
1103 std::vector<GURL> federations;
1104 std::vector<std::string> affiliated_realms;
1105 static_cast<MockAffiliatedMatchHelper*>(store_->affiliated_match_helper())
1106 ->ExpectCallToGetAffiliatedAndroidRealms(
1107 cm_service_impl_->GetSynthesizedFormForOrigin(), affiliated_realms);
1108
1109 ExpectZeroClickSignInSuccess(true, true, federations,
1110 mojom::CredentialType::PASSWORD);
1111 }
1112
1113 TEST_F(CredentialManagerImplTest, GetSynthesizedFormForOrigin) {
1114 autofill::PasswordForm synthesized =
1115 cm_service_impl_->GetSynthesizedFormForOrigin();
1116 EXPECT_EQ(kTestWebOrigin, synthesized.origin.spec());
1117 EXPECT_EQ(kTestWebOrigin, synthesized.signon_realm);
1118 EXPECT_EQ(autofill::PasswordForm::SCHEME_HTML, synthesized.scheme);
1119 EXPECT_TRUE(synthesized.ssl_valid);
1120 }
1121
1122 } // namespace password_manager
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698