1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/passwords/manage_passwords_state.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "components/password_manager/core/browser/password_form_manager.h"
9 #include "components/password_manager/core/browser/stub_password_manager_client.h"
10 #include "components/password_manager/core/common/credential_manager_types.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
15 using ::testing::Contains
;
16 using ::testing::ElementsAre
;
17 using ::testing::IsEmpty
;
19 using ::testing::Pointee
;
20 using ::testing::UnorderedElementsAre
;
24 class ManagePasswordsStateTest
: public testing::Test
{
26 void SetUp() override
{
27 test_local_form_
.origin
= GURL("http://example.com");
28 test_local_form_
.username_value
= base::ASCIIToUTF16("username");
29 test_local_form_
.password_value
= base::ASCIIToUTF16("12345");
31 test_submitted_form_
= test_local_form_
;
32 test_submitted_form_
.username_value
= base::ASCIIToUTF16("new one");
33 test_submitted_form_
.password_value
= base::ASCIIToUTF16("asdfjkl;");
35 test_federated_form_
.origin
= GURL("https://idp.com");
36 test_federated_form_
.username_value
= base::ASCIIToUTF16("username");
38 passwords_data_
.set_client(&client_
);
41 autofill::PasswordForm
& test_local_form() { return test_local_form_
; }
42 autofill::PasswordForm
& test_submitted_form() { return test_submitted_form_
; }
43 autofill::PasswordForm
& test_federated_form() { return test_federated_form_
; }
44 ManagePasswordsState
& passwords_data() { return passwords_data_
; }
46 // Returns a PasswordFormManager containing test_local_form() as a best match.
47 scoped_ptr
<password_manager::PasswordFormManager
> CreateFormManager();
49 // Pushes irrelevant updates to |passwords_data_| and checks that they don't
51 void TestNoisyUpdates();
53 // Pushes both relevant and irrelevant updates to |passwords_data_|.
54 void TestAllUpdates();
56 // Pushes a blacklisted form and checks that it doesn't affect the state.
57 void TestBlacklistedUpdates();
59 MOCK_METHOD1(OnChooseCredential
,
60 void(const password_manager::CredentialInfo
&));
63 password_manager::StubPasswordManagerClient client_
;
65 ManagePasswordsState passwords_data_
;
66 autofill::PasswordForm test_local_form_
;
67 autofill::PasswordForm test_submitted_form_
;
68 autofill::PasswordForm test_federated_form_
;
71 scoped_ptr
<password_manager::PasswordFormManager
>
72 ManagePasswordsStateTest::CreateFormManager() {
73 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
74 new password_manager::PasswordFormManager(
76 base::WeakPtr
<password_manager::PasswordManagerDriver
>(),
77 test_local_form(), false));
78 test_form_manager
->SimulateFetchMatchingLoginsFromPasswordStore();
79 ScopedVector
<autofill::PasswordForm
> stored_forms
;
80 stored_forms
.push_back(new autofill::PasswordForm(test_local_form()));
81 test_form_manager
->OnGetPasswordStoreResults(stored_forms
.Pass());
82 EXPECT_EQ(1u, test_form_manager
->best_matches().size());
83 EXPECT_EQ(test_local_form(),
84 *test_form_manager
->best_matches().begin()->second
);
85 return test_form_manager
.Pass();
88 void ManagePasswordsStateTest::TestNoisyUpdates() {
89 const std::vector
<const autofill::PasswordForm
*> forms
=
90 passwords_data_
.GetCurrentForms();
91 const std::vector
<const autofill::PasswordForm
*> federated_forms
=
92 passwords_data_
.federated_credentials_forms();
93 const password_manager::ui::State state
= passwords_data_
.state();
94 const GURL origin
= passwords_data_
.origin();
97 autofill::PasswordForm form
;
98 form
.origin
= GURL("http://3rdparty.com");
99 form
.username_value
= base::ASCIIToUTF16("username");
100 form
.password_value
= base::ASCIIToUTF16("12345");
101 password_manager::PasswordStoreChange
change(
102 password_manager::PasswordStoreChange::ADD
, form
);
103 password_manager::PasswordStoreChangeList
list(1, change
);
104 passwords_data().ProcessLoginsChanged(list
);
105 EXPECT_EQ(forms
, passwords_data().GetCurrentForms());
106 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
107 EXPECT_EQ(state
, passwords_data().state());
108 EXPECT_EQ(origin
, passwords_data().origin());
111 form
.password_value
= base::ASCIIToUTF16("password");
112 list
[0] = password_manager::PasswordStoreChange(
113 password_manager::PasswordStoreChange::UPDATE
, form
);
114 passwords_data().ProcessLoginsChanged(list
);
115 EXPECT_EQ(forms
, passwords_data().GetCurrentForms());
116 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
117 EXPECT_EQ(state
, passwords_data().state());
118 EXPECT_EQ(origin
, passwords_data().origin());
121 list
[0] = password_manager::PasswordStoreChange(
122 password_manager::PasswordStoreChange::REMOVE
, form
);
123 passwords_data().ProcessLoginsChanged(list
);
124 EXPECT_EQ(forms
, passwords_data().GetCurrentForms());
125 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
126 EXPECT_EQ(state
, passwords_data().state());
127 EXPECT_EQ(origin
, passwords_data().origin());
130 void ManagePasswordsStateTest::TestAllUpdates() {
131 const std::vector
<const autofill::PasswordForm
*> forms
=
132 passwords_data_
.GetCurrentForms();
133 const std::vector
<const autofill::PasswordForm
*> federated_forms
=
134 passwords_data_
.federated_credentials_forms();
135 const password_manager::ui::State state
= passwords_data_
.state();
136 const GURL origin
= passwords_data_
.origin();
137 EXPECT_NE(GURL::EmptyGURL(), origin
);
140 autofill::PasswordForm form
;
141 form
.origin
= origin
;
142 form
.username_value
= base::ASCIIToUTF16("user15");
143 form
.password_value
= base::ASCIIToUTF16("12345");
144 password_manager::PasswordStoreChange
change(
145 password_manager::PasswordStoreChange::ADD
, form
);
146 password_manager::PasswordStoreChangeList
list(1, change
);
147 passwords_data().ProcessLoginsChanged(list
);
148 EXPECT_THAT(passwords_data().GetCurrentForms(), Contains(Pointee(form
)));
149 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
150 EXPECT_EQ(state
, passwords_data().state());
151 EXPECT_EQ(origin
, passwords_data().origin());
154 form
.password_value
= base::ASCIIToUTF16("password");
155 list
[0] = password_manager::PasswordStoreChange(
156 password_manager::PasswordStoreChange::UPDATE
, form
);
157 passwords_data().ProcessLoginsChanged(list
);
158 EXPECT_THAT(passwords_data().GetCurrentForms(), Contains(Pointee(form
)));
159 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
160 EXPECT_EQ(state
, passwords_data().state());
161 EXPECT_EQ(origin
, passwords_data().origin());
164 list
[0] = password_manager::PasswordStoreChange(
165 password_manager::PasswordStoreChange::REMOVE
, form
);
166 passwords_data().ProcessLoginsChanged(list
);
167 EXPECT_EQ(forms
, passwords_data().GetCurrentForms());
168 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
169 EXPECT_EQ(state
, passwords_data().state());
170 EXPECT_EQ(origin
, passwords_data().origin());
175 void ManagePasswordsStateTest::TestBlacklistedUpdates() {
176 const std::vector
<const autofill::PasswordForm
*> forms
=
177 passwords_data_
.GetCurrentForms();
178 const std::vector
<const autofill::PasswordForm
*> federated_forms
=
179 passwords_data_
.federated_credentials_forms();
180 const password_manager::ui::State state
= passwords_data_
.state();
181 const GURL origin
= passwords_data_
.origin();
182 EXPECT_NE(GURL::EmptyGURL(), origin
);
184 // Process the blacklisted form.
185 autofill::PasswordForm blacklisted
;
186 blacklisted
.blacklisted_by_user
= true;
187 blacklisted
.origin
= origin
;
188 password_manager::PasswordStoreChangeList list
;
189 list
.push_back(password_manager::PasswordStoreChange(
190 password_manager::PasswordStoreChange::ADD
, blacklisted
));
191 passwords_data().ProcessLoginsChanged(list
);
192 EXPECT_EQ(forms
, passwords_data().GetCurrentForms());
193 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
194 EXPECT_EQ(state
, passwords_data().state());
195 EXPECT_EQ(origin
, passwords_data().origin());
197 // Delete the blacklisted form.
198 list
[0] = password_manager::PasswordStoreChange(
199 password_manager::PasswordStoreChange::REMOVE
, blacklisted
);
200 passwords_data().ProcessLoginsChanged(list
);
201 EXPECT_EQ(forms
, passwords_data().GetCurrentForms());
202 EXPECT_EQ(federated_forms
, passwords_data().federated_credentials_forms());
203 EXPECT_EQ(state
, passwords_data().state());
204 EXPECT_EQ(origin
, passwords_data().origin());
207 TEST_F(ManagePasswordsStateTest
, DefaultState
) {
208 EXPECT_THAT(passwords_data().GetCurrentForms(), IsEmpty());
209 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
210 EXPECT_EQ(password_manager::ui::INACTIVE_STATE
, passwords_data().state());
211 EXPECT_EQ(GURL::EmptyGURL(), passwords_data().origin());
212 EXPECT_FALSE(passwords_data().form_manager());
217 TEST_F(ManagePasswordsStateTest
, PasswordSubmitted
) {
218 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
219 CreateFormManager());
220 test_form_manager
->ProvisionallySave(
221 test_submitted_form(),
222 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
223 passwords_data().OnPendingPassword(test_form_manager
.Pass());
225 EXPECT_THAT(passwords_data().GetCurrentForms(),
226 ElementsAre(Pointee(test_local_form())));
227 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
228 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE
,
229 passwords_data().state());
230 EXPECT_EQ(test_submitted_form().origin
, passwords_data().origin());
231 ASSERT_TRUE(passwords_data().form_manager());
232 EXPECT_EQ(test_submitted_form(),
233 passwords_data().form_manager()->pending_credentials());
237 TEST_F(ManagePasswordsStateTest
, PasswordSaved
) {
238 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
239 CreateFormManager());
240 test_form_manager
->ProvisionallySave(
241 test_submitted_form(),
242 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
243 passwords_data().OnPendingPassword(test_form_manager
.Pass());
244 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE
,
245 passwords_data().state());
247 passwords_data().TransitionToState(password_manager::ui::MANAGE_STATE
);
248 EXPECT_THAT(passwords_data().GetCurrentForms(),
249 ElementsAre(Pointee(test_local_form())));
250 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
251 EXPECT_EQ(password_manager::ui::MANAGE_STATE
,
252 passwords_data().state());
253 EXPECT_EQ(test_submitted_form().origin
, passwords_data().origin());
257 TEST_F(ManagePasswordsStateTest
, OnRequestCredentials
) {
258 ScopedVector
<autofill::PasswordForm
> local_credentials
;
259 local_credentials
.push_back(new autofill::PasswordForm(test_local_form()));
260 ScopedVector
<autofill::PasswordForm
> federated_credentials
;
261 federated_credentials
.push_back(
262 new autofill::PasswordForm(test_federated_form()));
263 const GURL origin
= test_local_form().origin
;
264 passwords_data().OnRequestCredentials(local_credentials
.Pass(),
265 federated_credentials
.Pass(), origin
);
266 passwords_data().set_credentials_callback(
267 base::Bind(&ManagePasswordsStateTest::OnChooseCredential
,
268 base::Unretained(this)));
269 EXPECT_THAT(passwords_data().GetCurrentForms(),
270 ElementsAre(Pointee(test_local_form())));
271 EXPECT_THAT(passwords_data().federated_credentials_forms(),
272 ElementsAre(Pointee(test_federated_form())));
273 EXPECT_EQ(password_manager::ui::CREDENTIAL_REQUEST_STATE
,
274 passwords_data().state());
275 EXPECT_EQ(origin
, passwords_data().origin());
278 password_manager::CredentialInfo
credential_info(
280 password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD
);
281 EXPECT_CALL(*this, OnChooseCredential(_
))
282 .WillOnce(testing::SaveArg
<0>(&credential_info
));
283 passwords_data().TransitionToState(password_manager::ui::MANAGE_STATE
);
284 EXPECT_EQ(password_manager::CredentialType::CREDENTIAL_TYPE_EMPTY
,
285 credential_info
.type
);
286 EXPECT_TRUE(passwords_data().credentials_callback().is_null());
287 EXPECT_THAT(passwords_data().GetCurrentForms(),
288 ElementsAre(Pointee(test_local_form())));
289 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
290 EXPECT_EQ(password_manager::ui::MANAGE_STATE
, passwords_data().state());
291 EXPECT_EQ(origin
, passwords_data().origin());
295 TEST_F(ManagePasswordsStateTest
, AutoSignin
) {
296 ScopedVector
<autofill::PasswordForm
> local_credentials
;
297 local_credentials
.push_back(new autofill::PasswordForm(test_local_form()));
298 passwords_data().OnAutoSignin(local_credentials
.Pass());
299 EXPECT_THAT(passwords_data().GetCurrentForms(),
300 ElementsAre(Pointee(test_local_form())));
301 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
302 EXPECT_EQ(password_manager::ui::AUTO_SIGNIN_STATE
, passwords_data().state());
303 EXPECT_EQ(test_local_form().origin
, passwords_data().origin());
306 passwords_data().TransitionToState(password_manager::ui::MANAGE_STATE
);
307 EXPECT_THAT(passwords_data().GetCurrentForms(),
308 ElementsAre(Pointee(test_local_form())));
309 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
310 EXPECT_EQ(password_manager::ui::MANAGE_STATE
, passwords_data().state());
311 EXPECT_EQ(test_local_form().origin
, passwords_data().origin());
315 TEST_F(ManagePasswordsStateTest
, AutomaticPasswordSave
) {
316 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
317 CreateFormManager());
318 test_form_manager
->ProvisionallySave(
319 test_submitted_form(),
320 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
322 passwords_data().OnAutomaticPasswordSave(test_form_manager
.Pass());
323 EXPECT_EQ(password_manager::ui::CONFIRMATION_STATE
, passwords_data().state());
324 EXPECT_EQ(test_submitted_form().origin
, passwords_data().origin());
325 ASSERT_TRUE(passwords_data().form_manager());
326 EXPECT_EQ(test_submitted_form(),
327 passwords_data().form_manager()->pending_credentials());
330 passwords_data().TransitionToState(password_manager::ui::MANAGE_STATE
);
331 EXPECT_THAT(passwords_data().GetCurrentForms(),
332 UnorderedElementsAre(Pointee(test_local_form()),
333 Pointee(test_submitted_form())));
334 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
335 EXPECT_EQ(password_manager::ui::MANAGE_STATE
, passwords_data().state());
336 EXPECT_EQ(test_submitted_form().origin
, passwords_data().origin());
340 TEST_F(ManagePasswordsStateTest
, PasswordAutofilled
) {
341 autofill::PasswordFormMap password_form_map
;
342 password_form_map
.insert(
343 test_local_form().username_value
,
344 make_scoped_ptr(new autofill::PasswordForm(test_local_form())));
345 passwords_data().OnPasswordAutofilled(password_form_map
);
347 EXPECT_THAT(passwords_data().GetCurrentForms(),
348 ElementsAre(Pointee(test_local_form())));
349 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
350 EXPECT_EQ(password_manager::ui::MANAGE_STATE
, passwords_data().state());
351 EXPECT_EQ(test_local_form().origin
, passwords_data().origin());
353 // |passwords_data| should hold a separate copy of test_local_form().
354 EXPECT_THAT(passwords_data().GetCurrentForms(),
355 Not(Contains(&test_local_form())));
359 TEST_F(ManagePasswordsStateTest
, InactiveOnPSLMatched
) {
360 autofill::PasswordForm psl_matched_test_form
= test_local_form();
361 psl_matched_test_form
.original_signon_realm
= "http://pslmatched.example.com";
362 autofill::PasswordFormMap password_form_map
;
363 password_form_map
.insert(
364 psl_matched_test_form
.username_value
,
365 make_scoped_ptr(new autofill::PasswordForm(psl_matched_test_form
)));
366 passwords_data().OnPasswordAutofilled(password_form_map
);
368 EXPECT_THAT(passwords_data().GetCurrentForms(), IsEmpty());
369 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
370 EXPECT_EQ(password_manager::ui::INACTIVE_STATE
, passwords_data().state());
371 EXPECT_EQ(GURL::EmptyGURL(), passwords_data().origin());
372 EXPECT_FALSE(passwords_data().form_manager());
375 TEST_F(ManagePasswordsStateTest
, OnInactive
) {
376 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
377 CreateFormManager());
378 test_form_manager
->ProvisionallySave(
379 test_submitted_form(),
380 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
381 passwords_data().OnPendingPassword(test_form_manager
.Pass());
382 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE
,
383 passwords_data().state());
384 passwords_data().OnInactive();
385 EXPECT_THAT(passwords_data().GetCurrentForms(), IsEmpty());
386 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
387 EXPECT_EQ(password_manager::ui::INACTIVE_STATE
, passwords_data().state());
388 EXPECT_EQ(GURL::EmptyGURL(), passwords_data().origin());
389 EXPECT_FALSE(passwords_data().form_manager());
393 TEST_F(ManagePasswordsStateTest
, PendingPasswordAddBlacklisted
) {
394 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
395 CreateFormManager());
396 test_form_manager
->ProvisionallySave(
397 test_submitted_form(),
398 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
399 passwords_data().OnPendingPassword(test_form_manager
.Pass());
400 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_STATE
,
401 passwords_data().state());
403 TestBlacklistedUpdates();
406 TEST_F(ManagePasswordsStateTest
, RequestCredentialsAddBlacklisted
) {
407 ScopedVector
<autofill::PasswordForm
> local_credentials
;
408 local_credentials
.push_back(new autofill::PasswordForm(test_local_form()));
409 ScopedVector
<autofill::PasswordForm
> federated_credentials
;
410 federated_credentials
.push_back(
411 new autofill::PasswordForm(test_federated_form()));
412 const GURL origin
= test_local_form().origin
;
413 passwords_data().OnRequestCredentials(local_credentials
.Pass(),
414 federated_credentials
.Pass(), origin
);
415 passwords_data().set_credentials_callback(
416 base::Bind(&ManagePasswordsStateTest::OnChooseCredential
,
417 base::Unretained(this)));
418 EXPECT_EQ(password_manager::ui::CREDENTIAL_REQUEST_STATE
,
419 passwords_data().state());
421 TestBlacklistedUpdates();
424 TEST_F(ManagePasswordsStateTest
, AutoSigninAddBlacklisted
) {
425 ScopedVector
<autofill::PasswordForm
> local_credentials
;
426 local_credentials
.push_back(new autofill::PasswordForm(test_local_form()));
427 passwords_data().OnAutoSignin(local_credentials
.Pass());
428 EXPECT_EQ(password_manager::ui::AUTO_SIGNIN_STATE
, passwords_data().state());
430 TestBlacklistedUpdates();
433 TEST_F(ManagePasswordsStateTest
, AutomaticPasswordSaveAddBlacklisted
) {
434 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
435 CreateFormManager());
436 test_form_manager
->ProvisionallySave(
437 test_submitted_form(),
438 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
439 passwords_data().OnAutomaticPasswordSave(test_form_manager
.Pass());
440 EXPECT_EQ(password_manager::ui::CONFIRMATION_STATE
, passwords_data().state());
442 TestBlacklistedUpdates();
445 TEST_F(ManagePasswordsStateTest
, BackgroundAutofilledAddBlacklisted
) {
446 autofill::PasswordFormMap password_form_map
;
447 password_form_map
.insert(
448 test_local_form().username_value
,
449 make_scoped_ptr(new autofill::PasswordForm(test_local_form())));
450 passwords_data().OnPasswordAutofilled(password_form_map
);
451 EXPECT_EQ(password_manager::ui::MANAGE_STATE
, passwords_data().state());
453 TestBlacklistedUpdates();
456 TEST_F(ManagePasswordsStateTest
, PasswordUpdateAddBlacklisted
) {
457 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
458 CreateFormManager());
459 test_form_manager
->ProvisionallySave(
460 test_submitted_form(),
461 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
462 passwords_data().OnUpdatePassword(test_form_manager
.Pass());
463 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE
,
464 passwords_data().state());
466 TestBlacklistedUpdates();
469 TEST_F(ManagePasswordsStateTest
, PasswordUpdateSubmitted
) {
470 scoped_ptr
<password_manager::PasswordFormManager
> test_form_manager(
471 CreateFormManager());
472 test_form_manager
->ProvisionallySave(
473 test_submitted_form(),
474 password_manager::PasswordFormManager::IGNORE_OTHER_POSSIBLE_USERNAMES
);
475 passwords_data().OnUpdatePassword(test_form_manager
.Pass());
477 EXPECT_THAT(passwords_data().GetCurrentForms(),
478 ElementsAre(Pointee(test_local_form())));
479 EXPECT_THAT(passwords_data().federated_credentials_forms(), IsEmpty());
480 EXPECT_EQ(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE
,
481 passwords_data().state());
482 EXPECT_EQ(test_submitted_form().origin
, passwords_data().origin());
483 ASSERT_TRUE(passwords_data().form_manager());
484 EXPECT_EQ(test_submitted_form(),
485 passwords_data().form_manager()->pending_credentials());