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