1 // Copyright 2019 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/core/browser/password_generation_manager.h"
6
7 #include "base/memory/scoped_refptr.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "base/test/metrics/histogram_tester.h"
10 #include "base/test/simple_test_clock.h"
11 #include "base/test/task_environment.h"
12 #include "components/password_manager/core/browser/fake_form_fetcher.h"
13 #include "components/password_manager/core/browser/form_saver_impl.h"
14 #include "components/password_manager/core/browser/mock_password_store.h"
15 #include "components/password_manager/core/browser/password_form_manager_for_ui.h"
16 #include "components/password_manager/core/browser/stub_password_manager_client.h"
17 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
18 #include "components/password_manager/core/common/password_manager_features.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace password_manager {
23 namespace {
24
25 using autofill::PasswordForm;
26 using base::ASCIIToUTF16;
27 using testing::_;
28 using testing::ElementsAre;
29 using testing::Field;
30 using testing::IsEmpty;
31 using testing::Key;
32 using testing::Pointee;
33
34 constexpr char kURL[] = "https://example.in/login";
35 constexpr char kSubdomainURL[] = "https://m.example.in/login";
36 constexpr time_t kTime = 123456789;
37 constexpr time_t kAnotherTime = 987654321;
38
39 // Creates a dummy saved credential.
CreateSaved()40 PasswordForm CreateSaved() {
41 PasswordForm form;
42 form.origin = GURL(kURL);
43 form.signon_realm = form.origin.spec();
44 form.action = GURL("https://login.example.org");
45 form.username_value = ASCIIToUTF16("old_username");
46 form.password_value = ASCIIToUTF16("12345");
47 return form;
48 }
49
CreateSavedFederated()50 PasswordForm CreateSavedFederated() {
51 autofill::PasswordForm federated;
52 federated.origin = GURL(kURL);
53 federated.signon_realm = "federation://example.in/google.com";
54 federated.type = autofill::PasswordForm::Type::kApi;
55 federated.federation_origin =
56 url::Origin::Create(GURL("https://google.com/"));
57 federated.username_value = ASCIIToUTF16("federated_username");
58 return federated;
59 }
60
61 // Creates a dummy saved PSL credential.
CreateSavedPSL()62 PasswordForm CreateSavedPSL() {
63 PasswordForm form;
64 form.origin = GURL(kSubdomainURL);
65 form.signon_realm = form.origin.spec();
66 form.action = GURL("https://login.example.org");
67 form.username_value = ASCIIToUTF16("old_username2");
68 form.password_value = ASCIIToUTF16("passw0rd");
69 form.is_public_suffix_match = true;
70 return form;
71 }
72
73 // Creates a dummy generated password.
CreateGenerated()74 PasswordForm CreateGenerated() {
75 PasswordForm form;
76 form.origin = GURL(kURL);
77 form.signon_realm = form.origin.spec();
78 form.action = GURL("https://signup.example.org");
79 form.username_value = ASCIIToUTF16("MyName");
80 form.password_value = ASCIIToUTF16("Strong password");
81 form.type = autofill::PasswordForm::Type::kGenerated;
82 return form;
83 }
84
85 MATCHER_P(FormHasUniqueKey, key, "") {
86 return ArePasswordFormUniqueKeysEqual(arg, key);
87 }
88
89 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
90 public:
91 MOCK_METHOD1(GeneratedPasswordAccepted, void(const base::string16& password));
92 };
93
94 class MockPasswordManagerClient : public StubPasswordManagerClient {
95 public:
96 bool PromptUserToSaveOrUpdatePassword(
97 std::unique_ptr<PasswordFormManagerForUI> form_to_save,
98 bool update_password) override;
99
100 MOCK_METHOD1(PromptUserToSaveOrUpdatePasswordMock,
101 bool(bool update_password));
102
MoveForm()103 std::unique_ptr<PasswordFormManagerForUI> MoveForm() {
104 return std::move(form_to_save_);
105 }
106
107 private:
108 std::unique_ptr<PasswordFormManagerForUI> form_to_save_;
109 };
110
PromptUserToSaveOrUpdatePassword(std::unique_ptr<PasswordFormManagerForUI> form_to_save,bool update_password)111 bool MockPasswordManagerClient::PromptUserToSaveOrUpdatePassword(
112 std::unique_ptr<PasswordFormManagerForUI> form_to_save,
113 bool update_password) {
114 form_to_save_ = std::move(form_to_save);
115 return PromptUserToSaveOrUpdatePasswordMock(update_password);
116 }
117
118 class PasswordGenerationManagerTest : public testing::Test {
119 public:
120 PasswordGenerationManagerTest();
121 ~PasswordGenerationManagerTest() override;
122
store()123 MockPasswordStore& store() { return *mock_store_; }
manager()124 PasswordGenerationManager& manager() { return generation_manager_; }
form_saver()125 FormSaverImpl& form_saver() { return form_saver_; }
client()126 MockPasswordManagerClient& client() { return client_; }
127
128 // Immitates user accepting the password that can't be immediately presaved.
129 // The returned value represents the UI model for the update bubble.
130 std::unique_ptr<PasswordFormManagerForUI> SetUpOverwritingUI(
131 base::WeakPtr<PasswordManagerDriver> driver);
132
133 private:
134 // For the MockPasswordStore.
135 base::test::TaskEnvironment task_environment_;
136 scoped_refptr<MockPasswordStore> mock_store_;
137 // Test with the real form saver for better robustness.
138 FormSaverImpl form_saver_;
139 MockPasswordManagerClient client_;
140 PasswordGenerationManager generation_manager_;
141 };
142
PasswordGenerationManagerTest()143 PasswordGenerationManagerTest::PasswordGenerationManagerTest()
144 : mock_store_(new testing::StrictMock<MockPasswordStore>()),
145 form_saver_(mock_store_.get()),
146 generation_manager_(&client_) {
147 auto clock = std::make_unique<base::SimpleTestClock>();
148 clock->SetNow(base::Time::FromTimeT(kTime));
149 generation_manager_.set_clock(std::move(clock));
150 }
151
~PasswordGenerationManagerTest()152 PasswordGenerationManagerTest::~PasswordGenerationManagerTest() {
153 mock_store_->ShutdownOnUIThread();
154 }
155
156 std::unique_ptr<PasswordFormManagerForUI>
SetUpOverwritingUI(base::WeakPtr<PasswordManagerDriver> driver)157 PasswordGenerationManagerTest::SetUpOverwritingUI(
158 base::WeakPtr<PasswordManagerDriver> driver) {
159 PasswordForm generated = CreateGenerated();
160 PasswordForm saved = CreateSaved();
161 generated.username_value = ASCIIToUTF16("");
162 saved.username_value = ASCIIToUTF16("");
163 const PasswordForm federated = CreateSavedFederated();
164 FakeFormFetcher fetcher;
165 fetcher.SetNonFederated({&saved});
166 fetcher.set_federated({&federated});
167
168 EXPECT_CALL(client_, PromptUserToSaveOrUpdatePasswordMock(true))
169 .WillOnce(testing::Return(true));
170 manager().GeneratedPasswordAccepted(
171 std::move(generated), fetcher.GetNonFederatedMatches(),
172 fetcher.GetFederatedMatches(), std::move(driver));
173 return client_.MoveForm();
174 }
175
176 // Check that accepting a generated password simply relays the message to the
177 // driver.
TEST_F(PasswordGenerationManagerTest,GeneratedPasswordAccepted_EmptyStore)178 TEST_F(PasswordGenerationManagerTest, GeneratedPasswordAccepted_EmptyStore) {
179 base::HistogramTester histogram_tester;
180 PasswordForm generated = CreateGenerated();
181 MockPasswordManagerDriver driver;
182 FakeFormFetcher fetcher;
183
184 EXPECT_CALL(driver, GeneratedPasswordAccepted(generated.password_value));
185 manager().GeneratedPasswordAccepted(
186 std::move(generated), fetcher.GetNonFederatedMatches(),
187 fetcher.GetFederatedMatches(), driver.AsWeakPtr());
188 EXPECT_FALSE(manager().HasGeneratedPassword());
189 histogram_tester.ExpectUniqueSample(
190 "PasswordGeneration.PresaveConflict",
191 metrics_util::GenerationPresaveConflict::kNoUsernameConflict, 1);
192 }
193
194 // In case of accepted password conflicts with an existing username the
195 // credential can be presaved with an empty one. Thus, no conflict happens and
196 // the driver should be notified directly.
TEST_F(PasswordGenerationManagerTest,GeneratedPasswordAccepted_Conflict)197 TEST_F(PasswordGenerationManagerTest, GeneratedPasswordAccepted_Conflict) {
198 base::HistogramTester histogram_tester;
199 PasswordForm generated = CreateGenerated();
200 const PasswordForm saved = CreateSaved();
201 generated.username_value = saved.username_value;
202 MockPasswordManagerDriver driver;
203 FakeFormFetcher fetcher;
204 fetcher.SetNonFederated({&saved});
205
206 EXPECT_CALL(driver, GeneratedPasswordAccepted(generated.password_value));
207 manager().GeneratedPasswordAccepted(
208 std::move(generated), fetcher.GetNonFederatedMatches(),
209 fetcher.GetFederatedMatches(), driver.AsWeakPtr());
210 EXPECT_FALSE(manager().HasGeneratedPassword());
211 histogram_tester.ExpectUniqueSample(
212 "PasswordGeneration.PresaveConflict",
213 metrics_util::GenerationPresaveConflict::kNoConflictWithEmptyUsername, 1);
214 }
215
TEST_F(PasswordGenerationManagerTest,GeneratedPasswordAccepted_UpdateUI)216 TEST_F(PasswordGenerationManagerTest, GeneratedPasswordAccepted_UpdateUI) {
217 base::HistogramTester histogram_tester;
218 MockPasswordManagerDriver driver;
219 EXPECT_CALL(driver, GeneratedPasswordAccepted(_)).Times(0);
220 std::unique_ptr<PasswordFormManagerForUI> ui_form =
221 SetUpOverwritingUI(driver.AsWeakPtr());
222 ASSERT_TRUE(ui_form);
223 EXPECT_EQ(GURL(kURL), ui_form->GetOrigin());
224 EXPECT_THAT(
225 ui_form->GetBestMatches(),
226 ElementsAre(Field(&PasswordForm::username_value, ASCIIToUTF16(""))));
227 EXPECT_THAT(ui_form->GetFederatedMatches(),
228 ElementsAre(Pointee(CreateSavedFederated())));
229 EXPECT_EQ(ASCIIToUTF16(""), ui_form->GetPendingCredentials().username_value);
230 EXPECT_EQ(CreateGenerated().password_value,
231 ui_form->GetPendingCredentials().password_value);
232 EXPECT_THAT(ui_form->GetInteractionsStats(), IsEmpty());
233 EXPECT_FALSE(ui_form->IsBlacklisted());
234 histogram_tester.ExpectUniqueSample(
235 "PasswordGeneration.PresaveConflict",
236 metrics_util::GenerationPresaveConflict::kConflictWithEmptyUsername, 1);
237 }
238
TEST_F(PasswordGenerationManagerTest,GeneratedPasswordAccepted_UpdateUIDismissed)239 TEST_F(PasswordGenerationManagerTest,
240 GeneratedPasswordAccepted_UpdateUIDismissed) {
241 MockPasswordManagerDriver driver;
242 EXPECT_CALL(driver, GeneratedPasswordAccepted(_)).Times(0);
243 std::unique_ptr<PasswordFormManagerForUI> ui_form =
244 SetUpOverwritingUI(driver.AsWeakPtr());
245 ASSERT_TRUE(ui_form);
246 ui_form->OnNoInteraction(true);
247 }
248
TEST_F(PasswordGenerationManagerTest,GeneratedPasswordAccepted_UpdateUINope)249 TEST_F(PasswordGenerationManagerTest, GeneratedPasswordAccepted_UpdateUINope) {
250 MockPasswordManagerDriver driver;
251 EXPECT_CALL(driver, GeneratedPasswordAccepted(_)).Times(0);
252 std::unique_ptr<PasswordFormManagerForUI> ui_form =
253 SetUpOverwritingUI(driver.AsWeakPtr());
254 ASSERT_TRUE(ui_form);
255 ui_form->OnNopeUpdateClicked();
256 }
257
TEST_F(PasswordGenerationManagerTest,GeneratedPasswordAccepted_UpdateUINever)258 TEST_F(PasswordGenerationManagerTest, GeneratedPasswordAccepted_UpdateUINever) {
259 MockPasswordManagerDriver driver;
260 EXPECT_CALL(driver, GeneratedPasswordAccepted(_)).Times(0);
261 std::unique_ptr<PasswordFormManagerForUI> ui_form =
262 SetUpOverwritingUI(driver.AsWeakPtr());
263 ASSERT_TRUE(ui_form);
264 ui_form->OnNeverClicked();
265 }
266
TEST_F(PasswordGenerationManagerTest,GeneratedPasswordAccepted_UpdateUISave)267 TEST_F(PasswordGenerationManagerTest, GeneratedPasswordAccepted_UpdateUISave) {
268 MockPasswordManagerDriver driver;
269 std::unique_ptr<PasswordFormManagerForUI> ui_form =
270 SetUpOverwritingUI(driver.AsWeakPtr());
271 ASSERT_TRUE(ui_form);
272 EXPECT_CALL(driver,
273 GeneratedPasswordAccepted(CreateGenerated().password_value));
274 ui_form->Save();
275 }
276
277 // Check that presaving a password for the first time results in adding it.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_New)278 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_New) {
279 const PasswordForm generated = CreateGenerated();
280 PasswordForm generated_with_date = generated;
281 generated_with_date.date_created = base::Time::FromTimeT(kTime);
282
283 EXPECT_CALL(store(), AddLogin(generated_with_date));
284 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
285 EXPECT_TRUE(manager().HasGeneratedPassword());
286 }
287
288 // Check that presaving a password for the second time results in updating it.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_Replace)289 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_Replace) {
290 PasswordForm generated = CreateGenerated();
291 PasswordForm generated_with_date = generated;
292 generated_with_date.date_created = base::Time::FromTimeT(kTime);
293
294 EXPECT_CALL(store(), AddLogin(generated_with_date));
295 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
296
297 PasswordForm generated_updated = generated;
298 generated_updated.password_value = ASCIIToUTF16("newgenpwd");
299 generated_with_date = generated_updated;
300 generated_with_date.date_created = base::Time::FromTimeT(kTime);
301 EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(generated_with_date,
302 FormHasUniqueKey(generated)));
303 manager().PresaveGeneratedPassword(generated_updated, {}, &form_saver());
304 EXPECT_TRUE(manager().HasGeneratedPassword());
305 }
306
307 // Check that presaving a password for the third time results in updating it.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_ReplaceTwice)308 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_ReplaceTwice) {
309 PasswordForm generated = CreateGenerated();
310 PasswordForm generated_with_date = generated;
311 generated_with_date.date_created = base::Time::FromTimeT(kTime);
312
313 EXPECT_CALL(store(), AddLogin(generated_with_date));
314 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
315
316 PasswordForm generated_updated = generated;
317 generated_updated.password_value = ASCIIToUTF16("newgenpwd");
318 generated_with_date = generated_updated;
319 generated_with_date.date_created = base::Time::FromTimeT(kTime);
320 EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(generated_with_date,
321 FormHasUniqueKey(generated)));
322 manager().PresaveGeneratedPassword(generated_updated, {}, &form_saver());
323
324 generated = generated_updated;
325 generated_updated.password_value = ASCIIToUTF16("newgenpwd2");
326 generated_updated.username_value = ASCIIToUTF16("newusername");
327 generated_with_date = generated_updated;
328 generated_with_date.date_created = base::Time::FromTimeT(kTime);
329 EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(generated_with_date,
330 FormHasUniqueKey(generated)));
331 manager().PresaveGeneratedPassword(generated_updated, {}, &form_saver());
332 EXPECT_TRUE(manager().HasGeneratedPassword());
333 }
334
335 // Check that presaving a password with a known username results in clearing the
336 // username.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_WithConflict)337 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_WithConflict) {
338 const PasswordForm generated = CreateGenerated();
339
340 PasswordForm saved = CreateSaved();
341 saved.username_value = generated.username_value;
342
343 PasswordForm generated_with_date = generated;
344 generated_with_date.date_created = base::Time::FromTimeT(kTime);
345 generated_with_date.username_value.clear();
346
347 EXPECT_CALL(store(), AddLogin(generated_with_date));
348 manager().PresaveGeneratedPassword(generated, {&saved}, &form_saver());
349 EXPECT_TRUE(manager().HasGeneratedPassword());
350 }
351
352 // Check that presaving a password with an unknown username saves it as is.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_WithoutConflict)353 TEST_F(PasswordGenerationManagerTest,
354 PresaveGeneratedPassword_WithoutConflict) {
355 const PasswordForm generated = CreateGenerated();
356 PasswordForm generated_with_date = generated;
357 generated_with_date.date_created = base::Time::FromTimeT(kTime);
358
359 const PasswordForm saved = CreateSaved();
360 EXPECT_CALL(store(), AddLogin(generated_with_date));
361 manager().PresaveGeneratedPassword(generated, {&saved}, &form_saver());
362 EXPECT_TRUE(manager().HasGeneratedPassword());
363 }
364
365 // Check that presaving a password followed by a call to save a pending
366 // credential (as new) results in replacing the presaved password with the
367 // pending one.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_ThenSaveAsNew)368 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_ThenSaveAsNew) {
369 const PasswordForm generated = CreateGenerated();
370
371 EXPECT_CALL(store(), AddLogin(_));
372 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
373
374 // User edits after submission.
375 PasswordForm pending = generated;
376 pending.password_value = ASCIIToUTF16("edited_password");
377 pending.username_value = ASCIIToUTF16("edited_username");
378 PasswordForm generated_with_date = pending;
379 generated_with_date.date_created = base::Time::FromTimeT(kTime);
380 generated_with_date.date_last_used = base::Time::FromTimeT(kTime);
381 EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(generated_with_date,
382 FormHasUniqueKey(generated)));
383 manager().CommitGeneratedPassword(pending, {} /* matches */,
384 base::string16() /* old_password */,
385 &form_saver());
386 EXPECT_TRUE(manager().HasGeneratedPassword());
387 }
388
389 // Check that presaving a password followed by a call to save a pending
390 // credential (as update) results in replacing the presaved password with the
391 // pending one.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_ThenUpdate)392 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_ThenUpdate) {
393 PasswordForm generated = CreateGenerated();
394
395 PasswordForm related_password = CreateSaved();
396 related_password.username_value = ASCIIToUTF16("username");
397 related_password.username_element = ASCIIToUTF16("username_field");
398 related_password.password_value = ASCIIToUTF16("old password");
399
400 PasswordForm related_psl_password = CreateSavedPSL();
401 related_psl_password.username_value = ASCIIToUTF16("username");
402 related_psl_password.password_value = ASCIIToUTF16("old password");
403
404 PasswordForm unrelated_password = CreateSaved();
405 unrelated_password.username_value = ASCIIToUTF16("another username");
406 unrelated_password.password_value = ASCIIToUTF16("some password");
407
408 PasswordForm unrelated_psl_password = CreateSavedPSL();
409 unrelated_psl_password.username_value = ASCIIToUTF16("another username");
410 unrelated_psl_password.password_value = ASCIIToUTF16("some password");
411
412 EXPECT_CALL(store(), AddLogin(_));
413 const std::vector<const autofill::PasswordForm*> matches = {
414 &related_password, &related_psl_password, &unrelated_password,
415 &unrelated_psl_password};
416 manager().PresaveGeneratedPassword(generated, matches, &form_saver());
417
418 generated.username_value = ASCIIToUTF16("username");
419 PasswordForm generated_with_date = generated;
420 generated_with_date.date_created = base::Time::FromTimeT(kTime);
421 generated_with_date.date_last_used = base::Time::FromTimeT(kTime);
422
423 EXPECT_CALL(store(),
424 UpdateLoginWithPrimaryKey(generated_with_date,
425 FormHasUniqueKey(CreateGenerated())));
426
427 PasswordForm related_password_expected = related_password;
428 related_password_expected.password_value = generated.password_value;
429 EXPECT_CALL(store(), UpdateLogin(related_password_expected));
430
431 PasswordForm related_psl_password_expected = related_psl_password;
432 related_psl_password_expected.password_value = generated.password_value;
433 EXPECT_CALL(store(), UpdateLogin(related_psl_password_expected));
434
435 manager().CommitGeneratedPassword(
436 generated, matches, ASCIIToUTF16("old password"), &form_saver());
437 EXPECT_TRUE(manager().HasGeneratedPassword());
438 }
439
440 // Check that removing a presaved password removes the presaved password.
TEST_F(PasswordGenerationManagerTest,PasswordNoLongerGenerated)441 TEST_F(PasswordGenerationManagerTest, PasswordNoLongerGenerated) {
442 PasswordForm generated = CreateGenerated();
443
444 EXPECT_CALL(store(), AddLogin(_));
445 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
446
447 generated.date_created = base::Time::FromTimeT(kTime);
448 EXPECT_CALL(store(), RemoveLogin(generated));
449 manager().PasswordNoLongerGenerated(&form_saver());
450 EXPECT_FALSE(manager().HasGeneratedPassword());
451 }
452
453 // Check that removing the presaved password and then presaving again results in
454 // adding the second presaved password as new.
TEST_F(PasswordGenerationManagerTest,PasswordNoLongerGenerated_AndPresaveAgain)455 TEST_F(PasswordGenerationManagerTest,
456 PasswordNoLongerGenerated_AndPresaveAgain) {
457 PasswordForm generated = CreateGenerated();
458 PasswordForm generated_with_date = generated;
459 generated_with_date.date_created = base::Time::FromTimeT(kTime);
460
461 EXPECT_CALL(store(), AddLogin(generated_with_date));
462 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
463
464 EXPECT_CALL(store(), RemoveLogin(generated_with_date));
465 manager().PasswordNoLongerGenerated(&form_saver());
466
467 generated.username_value = ASCIIToUTF16("newgenusername");
468 generated.password_value = ASCIIToUTF16("newgenpwd");
469 generated_with_date = generated;
470 generated_with_date.date_created = base::Time::FromTimeT(kTime);
471 EXPECT_CALL(store(), AddLogin(generated_with_date));
472 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
473 EXPECT_TRUE(manager().HasGeneratedPassword());
474 }
475
476 // Check that presaving a password once in original and then once in clone
477 // results in the clone calling update, not a fresh save.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_CloneUpdates)478 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_CloneUpdates) {
479 PasswordForm generated = CreateGenerated();
480 PasswordForm generated_with_date = generated;
481 generated_with_date.date_created = base::Time::FromTimeT(kTime);
482
483 EXPECT_CALL(store(), AddLogin(generated_with_date));
484 manager().PresaveGeneratedPassword(generated, {}, &form_saver());
485
486 std::unique_ptr<PasswordGenerationManager> cloned_state = manager().Clone();
487 std::unique_ptr<base::SimpleTestClock> clock(new base::SimpleTestClock);
488 clock->SetNow(base::Time::FromTimeT(kAnotherTime));
489 cloned_state->set_clock(std::move(clock));
490
491 EXPECT_TRUE(cloned_state->HasGeneratedPassword());
492 PasswordForm generated_updated = generated;
493 generated_updated.username_value = ASCIIToUTF16("newname");
494 generated_with_date = generated_updated;
495 generated_with_date.date_created = base::Time::FromTimeT(kAnotherTime);
496 EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(generated_with_date,
497 FormHasUniqueKey(generated)));
498 cloned_state->PresaveGeneratedPassword(generated_updated, {}, &form_saver());
499 EXPECT_TRUE(cloned_state->HasGeneratedPassword());
500 }
501
502 // Check that a clone can still work after the original is destroyed.
TEST_F(PasswordGenerationManagerTest,PresaveGeneratedPassword_CloneSurvives)503 TEST_F(PasswordGenerationManagerTest, PresaveGeneratedPassword_CloneSurvives) {
504 auto original = std::make_unique<PasswordGenerationManager>(&client());
505 const PasswordForm generated = CreateGenerated();
506
507 EXPECT_CALL(store(), AddLogin(_));
508 original->PresaveGeneratedPassword(generated, {}, &form_saver());
509
510 std::unique_ptr<PasswordGenerationManager> cloned_manager = original->Clone();
511 original.reset();
512 EXPECT_CALL(store(), UpdateLoginWithPrimaryKey(_, _));
513 cloned_manager->PresaveGeneratedPassword(generated, {}, &form_saver());
514 }
515
516 } // namespace
517 } // namespace password_manager
518