OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" | 5 #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 #include "components/password_manager/core/common/password_manager_pref_names.h" | 28 #include "components/password_manager/core/common/password_manager_pref_names.h" |
29 #include "components/password_manager/core/common/password_manager_ui.h" | 29 #include "components/password_manager/core/common/password_manager_ui.h" |
30 #include "components/prefs/pref_service.h" | 30 #include "components/prefs/pref_service.h" |
31 #include "components/variations/variations_associated_data.h" | 31 #include "components/variations/variations_associated_data.h" |
32 #include "content/public/browser/web_contents.h" | 32 #include "content/public/browser/web_contents.h" |
33 #include "content/public/test/test_browser_thread_bundle.h" | 33 #include "content/public/test/test_browser_thread_bundle.h" |
34 #include "content/public/test/web_contents_tester.h" | 34 #include "content/public/test/web_contents_tester.h" |
35 #include "testing/gmock/include/gmock/gmock.h" | 35 #include "testing/gmock/include/gmock/gmock.h" |
36 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
37 | 37 |
| 38 using password_bubble_experiment::kBrandingExperimentName; |
38 using password_bubble_experiment::kChromeSignInPasswordPromoExperimentName; | 39 using password_bubble_experiment::kChromeSignInPasswordPromoExperimentName; |
39 using password_bubble_experiment::kChromeSignInPasswordPromoThresholdParam; | 40 using password_bubble_experiment::kChromeSignInPasswordPromoThresholdParam; |
| 41 using password_bubble_experiment::kSmartLockBrandingGroupName; |
| 42 using password_bubble_experiment::kSmartLockBrandingSavePromptOnlyGroupName; |
40 using ::testing::AnyNumber; | 43 using ::testing::AnyNumber; |
41 using ::testing::Return; | 44 using ::testing::Return; |
42 using ::testing::ReturnRef; | 45 using ::testing::ReturnRef; |
43 using ::testing::_; | 46 using ::testing::_; |
44 | 47 |
45 namespace { | 48 namespace { |
46 | 49 |
47 constexpr char kFakeGroup[] = "FakeGroup"; | 50 const char kFakeGroup[] = "FakeGroup"; |
48 constexpr char kSignInPromoCountTilNoThanksMetric[] = | 51 const char kSignInPromoCountTilNoThanksMetric[] = |
49 "PasswordManager.SignInPromoCountTilNoThanks"; | 52 "PasswordManager.SignInPromoCountTilNoThanks"; |
50 constexpr char kSignInPromoCountTilSignInMetric[] = | 53 const char kSignInPromoCountTilSignInMetric[] = |
51 "PasswordManager.SignInPromoCountTilSignIn"; | 54 "PasswordManager.SignInPromoCountTilSignIn"; |
52 constexpr char kSignInPromoDismissalCountMetric[] = | 55 const char kSignInPromoDismissalCountMetric[] = |
53 "PasswordManager.SignInPromoDismissalCount"; | 56 "PasswordManager.SignInPromoDismissalCount"; |
54 constexpr char kSignInPromoDismissalReasonMetric[] = | 57 const char kSignInPromoDismissalReasonMetric[] = "PasswordManager.SignInPromo"; |
55 "PasswordManager.SignInPromo"; | 58 const char kSiteOrigin[] = "http://example.com/login"; |
56 constexpr char kSiteOrigin[] = "http://example.com/login"; | 59 const char kUsername[] = "Admin"; |
57 constexpr char kUsername[] = "Admin"; | 60 const char kUIDismissalReasonMetric[] = "PasswordManager.UIDismissalReason"; |
58 constexpr char kUIDismissalReasonMetric[] = "PasswordManager.UIDismissalReason"; | |
59 | 61 |
60 class TestSyncService : public browser_sync::ProfileSyncServiceMock { | 62 class TestSyncService : public browser_sync::ProfileSyncServiceMock { |
61 public: | 63 public: |
62 enum class SyncedTypes { ALL, NONE }; | |
63 | |
64 explicit TestSyncService(Profile* profile) | 64 explicit TestSyncService(Profile* profile) |
65 : browser_sync::ProfileSyncServiceMock( | 65 : browser_sync::ProfileSyncServiceMock( |
66 CreateProfileSyncServiceParamsForTest(profile)), | 66 CreateProfileSyncServiceParamsForTest(profile)), |
67 synced_types_(SyncedTypes::NONE) {} | 67 smartlock_enabled_(false) {} |
68 ~TestSyncService() override {} | 68 ~TestSyncService() override {} |
69 | 69 |
70 // FakeSyncService: | 70 // FakeSyncService: |
71 bool IsFirstSetupComplete() const override { return true; } | 71 bool IsFirstSetupComplete() const override { return true; } |
72 bool IsSyncAllowed() const override { return true; } | 72 bool IsSyncAllowed() const override { return true; } |
73 bool IsSyncActive() const override { return true; } | 73 bool IsSyncActive() const override { return true; } |
74 syncer::ModelTypeSet GetActiveDataTypes() const override { | 74 syncer::ModelTypeSet GetActiveDataTypes() const override { |
75 switch (synced_types_) { | 75 return smartlock_enabled_ ? syncer::ModelTypeSet::All() |
76 case SyncedTypes::ALL: | 76 : syncer::ModelTypeSet(); |
77 return syncer::ModelTypeSet::All(); | |
78 case SyncedTypes::NONE: | |
79 return syncer::ModelTypeSet(); | |
80 } | |
81 NOTREACHED(); | |
82 return syncer::ModelTypeSet(); | |
83 } | 77 } |
84 bool CanSyncStart() const override { return true; } | 78 bool CanSyncStart() const override { return true; } |
85 syncer::ModelTypeSet GetPreferredDataTypes() const override { | 79 syncer::ModelTypeSet GetPreferredDataTypes() const override { |
86 return GetActiveDataTypes(); | 80 return GetActiveDataTypes(); |
87 } | 81 } |
88 bool IsUsingSecondaryPassphrase() const override { return false; } | 82 bool IsUsingSecondaryPassphrase() const override { return false; } |
89 | 83 |
90 void set_synced_types(SyncedTypes synced_types) { | 84 void set_smartlock_enabled(bool smartlock_enabled) { |
91 synced_types_ = synced_types; | 85 smartlock_enabled_ = smartlock_enabled; |
92 } | 86 } |
93 | 87 |
94 private: | 88 private: |
95 SyncedTypes synced_types_; | 89 bool smartlock_enabled_; |
96 }; | 90 }; |
97 | 91 |
98 std::unique_ptr<KeyedService> TestingSyncFactoryFunction( | 92 std::unique_ptr<KeyedService> TestingSyncFactoryFunction( |
99 content::BrowserContext* context) { | 93 content::BrowserContext* context) { |
100 return base::MakeUnique<TestSyncService>(static_cast<Profile*>(context)); | 94 return base::MakeUnique<TestSyncService>(static_cast<Profile*>(context)); |
101 } | 95 } |
102 | 96 |
103 } // namespace | 97 } // namespace |
104 | 98 |
105 class ManagePasswordsBubbleModelTest : public ::testing::Test { | 99 class ManagePasswordsBubbleModelTest : public ::testing::Test { |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 313 |
320 TEST_F(ManagePasswordsBubbleModelTest, ClickUpdate) { | 314 TEST_F(ManagePasswordsBubbleModelTest, ClickUpdate) { |
321 PretendUpdatePasswordWaiting(); | 315 PretendUpdatePasswordWaiting(); |
322 | 316 |
323 autofill::PasswordForm form; | 317 autofill::PasswordForm form; |
324 EXPECT_CALL(*controller(), UpdatePassword(form)); | 318 EXPECT_CALL(*controller(), UpdatePassword(form)); |
325 model()->OnUpdateClicked(form); | 319 model()->OnUpdateClicked(form); |
326 DestroyModel(); | 320 DestroyModel(); |
327 } | 321 } |
328 | 322 |
| 323 TEST_F(ManagePasswordsBubbleModelTest, ShowSmartLockWarmWelcome) { |
| 324 TestSyncService* sync_service = static_cast<TestSyncService*>( |
| 325 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 326 profile(), &TestingSyncFactoryFunction)); |
| 327 sync_service->set_smartlock_enabled(true); |
| 328 base::FieldTrialList::CreateFieldTrial(kBrandingExperimentName, |
| 329 kSmartLockBrandingGroupName); |
| 330 |
| 331 PretendPasswordWaiting(); |
| 332 |
| 333 EXPECT_TRUE(model()->ShouldShowGoogleSmartLockWelcome()); |
| 334 EXPECT_CALL(*GetStore(), AddSiteStatsImpl(_)); |
| 335 DestroyModel(); |
| 336 PretendPasswordWaiting(); |
| 337 |
| 338 EXPECT_FALSE(model()->ShouldShowGoogleSmartLockWelcome()); |
| 339 EXPECT_TRUE(prefs()->GetBoolean( |
| 340 password_manager::prefs::kWasSavePrompFirstRunExperienceShown)); |
| 341 } |
| 342 |
| 343 TEST_F(ManagePasswordsBubbleModelTest, OmitSmartLockWarmWelcome) { |
| 344 TestSyncService* sync_service = static_cast<TestSyncService*>( |
| 345 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
| 346 profile(), &TestingSyncFactoryFunction)); |
| 347 sync_service->set_smartlock_enabled(false); |
| 348 base::FieldTrialList::CreateFieldTrial(kBrandingExperimentName, |
| 349 kSmartLockBrandingGroupName); |
| 350 |
| 351 PretendPasswordWaiting(); |
| 352 |
| 353 EXPECT_FALSE(model()->ShouldShowGoogleSmartLockWelcome()); |
| 354 EXPECT_CALL(*GetStore(), AddSiteStatsImpl(_)); |
| 355 DestroyModel(); |
| 356 PretendPasswordWaiting(); |
| 357 |
| 358 EXPECT_FALSE(model()->ShouldShowGoogleSmartLockWelcome()); |
| 359 EXPECT_FALSE(prefs()->GetBoolean( |
| 360 password_manager::prefs::kWasSavePrompFirstRunExperienceShown)); |
| 361 } |
| 362 |
329 TEST_F(ManagePasswordsBubbleModelTest, OnBrandLinkClicked) { | 363 TEST_F(ManagePasswordsBubbleModelTest, OnBrandLinkClicked) { |
330 PretendPasswordWaiting(); | 364 PretendPasswordWaiting(); |
331 | 365 |
332 EXPECT_CALL(*controller(), NavigateToSmartLockHelpPage()); | 366 EXPECT_CALL(*controller(), NavigateToSmartLockHelpPage()); |
333 model()->OnBrandLinkClicked(); | 367 model()->OnBrandLinkClicked(); |
334 } | 368 } |
335 | 369 |
336 TEST_F(ManagePasswordsBubbleModelTest, SuppressSignInPromo) { | 370 TEST_F(ManagePasswordsBubbleModelTest, SuppressSignInPromo) { |
337 base::HistogramTester histogram_tester; | 371 base::HistogramTester histogram_tester; |
338 PretendPasswordWaiting(); | 372 PretendPasswordWaiting(); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 password_manager::metrics_util::CHROME_SIGNIN_DISMISSED, 1); | 461 password_manager::metrics_util::CHROME_SIGNIN_DISMISSED, 1); |
428 histogram_tester.ExpectTotalCount(kSignInPromoCountTilSignInMetric, 0); | 462 histogram_tester.ExpectTotalCount(kSignInPromoCountTilSignInMetric, 0); |
429 histogram_tester.ExpectTotalCount(kSignInPromoCountTilNoThanksMetric, 0); | 463 histogram_tester.ExpectTotalCount(kSignInPromoCountTilNoThanksMetric, 0); |
430 histogram_tester.ExpectUniqueSample(kSignInPromoDismissalCountMetric, 1, 1); | 464 histogram_tester.ExpectUniqueSample(kSignInPromoDismissalCountMetric, 1, 1); |
431 EXPECT_FALSE(prefs()->GetBoolean( | 465 EXPECT_FALSE(prefs()->GetBoolean( |
432 password_manager::prefs::kWasSignInPasswordPromoClicked)); | 466 password_manager::prefs::kWasSignInPasswordPromoClicked)); |
433 } | 467 } |
434 | 468 |
435 namespace { | 469 namespace { |
436 | 470 |
| 471 enum class SmartLockStatus { ENABLE, DISABLE }; |
| 472 |
437 struct TitleTestCase { | 473 struct TitleTestCase { |
438 TestSyncService::SyncedTypes synced_types; | 474 const char* experiment_group; |
| 475 SmartLockStatus smartlock_status; |
439 const char* expected_title; | 476 const char* expected_title; |
440 }; | 477 }; |
441 | 478 |
442 } // namespace | 479 } // namespace |
443 | 480 |
444 class ManagePasswordsBubbleModelTitleTest | 481 class ManagePasswordsBubbleModelTitleTest |
445 : public ManagePasswordsBubbleModelTest, | 482 : public ManagePasswordsBubbleModelTest, |
446 public ::testing::WithParamInterface<TitleTestCase> {}; | 483 public ::testing::WithParamInterface<TitleTestCase> {}; |
447 | 484 |
448 TEST_P(ManagePasswordsBubbleModelTitleTest, BrandedTitleOnSaving) { | 485 TEST_P(ManagePasswordsBubbleModelTitleTest, BrandedTitleOnSaving) { |
449 TitleTestCase test_case = GetParam(); | 486 TitleTestCase test_case = GetParam(); |
450 TestSyncService* sync_service = static_cast<TestSyncService*>( | 487 TestSyncService* sync_service = static_cast<TestSyncService*>( |
451 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( | 488 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
452 profile(), &TestingSyncFactoryFunction)); | 489 profile(), &TestingSyncFactoryFunction)); |
453 sync_service->set_synced_types(test_case.synced_types); | 490 sync_service->set_smartlock_enabled(test_case.smartlock_status == |
| 491 SmartLockStatus::ENABLE); |
| 492 if (test_case.experiment_group) { |
| 493 base::FieldTrialList::CreateFieldTrial(kBrandingExperimentName, |
| 494 test_case.experiment_group); |
| 495 } |
454 | 496 |
455 PretendPasswordWaiting(); | 497 PretendPasswordWaiting(); |
456 EXPECT_THAT(base::UTF16ToUTF8(model()->title()), | 498 EXPECT_THAT(base::UTF16ToUTF8(model()->title()), |
457 testing::HasSubstr(test_case.expected_title)); | 499 testing::HasSubstr(test_case.expected_title)); |
458 } | 500 } |
459 | 501 |
460 namespace { | 502 namespace { |
461 | 503 |
462 // Below, "Chrom" is the common prefix of Chromium and Google Chrome. Ideally, | 504 // Below, "Chrom" is the common prefix of Chromium and Google Chrome. Ideally, |
463 // we would use the localised strings, but ResourceBundle does not get | 505 // we would use the localised strings, but ResourceBundle does not get |
464 // initialised for this unittest. | 506 // initialised for this unittest. |
465 constexpr TitleTestCase kTitleTestCases[] = { | 507 const TitleTestCase kTitleTestCases[] = { |
466 {TestSyncService::SyncedTypes::ALL, "Google Smart Lock"}, | 508 {kSmartLockBrandingGroupName, SmartLockStatus::ENABLE, "Google Smart Lock"}, |
467 {TestSyncService::SyncedTypes::NONE, "Chrom"}, | 509 {kSmartLockBrandingSavePromptOnlyGroupName, SmartLockStatus::ENABLE, |
| 510 "Google Smart Lock"}, |
| 511 {nullptr, SmartLockStatus::ENABLE, "Chrom"}, |
| 512 {"Default", SmartLockStatus::ENABLE, "Chrom"}, |
| 513 {kSmartLockBrandingGroupName, SmartLockStatus::DISABLE, "Chrom"}, |
| 514 {kSmartLockBrandingSavePromptOnlyGroupName, SmartLockStatus::DISABLE, |
| 515 "Chrom"}, |
| 516 {"Default", SmartLockStatus::DISABLE, "Chrom"}, |
| 517 {nullptr, SmartLockStatus::DISABLE, "Chrom"}, |
468 }; | 518 }; |
469 | 519 |
470 } // namespace | 520 } // namespace |
471 | 521 |
472 INSTANTIATE_TEST_CASE_P(Default, | 522 INSTANTIATE_TEST_CASE_P(Default, |
473 ManagePasswordsBubbleModelTitleTest, | 523 ManagePasswordsBubbleModelTitleTest, |
474 ::testing::ValuesIn(kTitleTestCases)); | 524 ::testing::ValuesIn(kTitleTestCases)); |
475 | 525 |
| 526 namespace { |
| 527 |
| 528 enum class ManageLinkTarget { EXTERNAL_PASSWORD_MANAGER, SETTINGS_PAGE }; |
| 529 |
| 530 struct ManageLinkTestCase { |
| 531 const char* experiment_group; |
| 532 SmartLockStatus smartlock_status; |
| 533 ManageLinkTarget expected_target; |
| 534 }; |
| 535 |
| 536 } // namespace |
| 537 |
476 class ManagePasswordsBubbleModelManageLinkTest | 538 class ManagePasswordsBubbleModelManageLinkTest |
477 : public ManagePasswordsBubbleModelTest, | 539 : public ManagePasswordsBubbleModelTest, |
478 public ::testing::WithParamInterface<TestSyncService::SyncedTypes> {}; | 540 public ::testing::WithParamInterface<ManageLinkTestCase> {}; |
479 | 541 |
480 TEST_P(ManagePasswordsBubbleModelManageLinkTest, OnManageLinkClicked) { | 542 TEST_P(ManagePasswordsBubbleModelManageLinkTest, OnManageLinkClicked) { |
| 543 ManageLinkTestCase test_case = GetParam(); |
481 TestSyncService* sync_service = static_cast<TestSyncService*>( | 544 TestSyncService* sync_service = static_cast<TestSyncService*>( |
482 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( | 545 ProfileSyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( |
483 profile(), &TestingSyncFactoryFunction)); | 546 profile(), &TestingSyncFactoryFunction)); |
484 sync_service->set_synced_types(GetParam()); | 547 sync_service->set_smartlock_enabled(test_case.smartlock_status == |
| 548 SmartLockStatus::ENABLE); |
| 549 if (test_case.experiment_group) { |
| 550 base::FieldTrialList::CreateFieldTrial(kBrandingExperimentName, |
| 551 test_case.experiment_group); |
| 552 } |
485 | 553 |
486 PretendManagingPasswords(); | 554 PretendManagingPasswords(); |
487 | 555 |
488 EXPECT_CALL(*controller(), NavigateToPasswordManagerSettingsPage()); | 556 switch (test_case.expected_target) { |
| 557 case ManageLinkTarget::EXTERNAL_PASSWORD_MANAGER: |
| 558 EXPECT_CALL(*controller(), NavigateToExternalPasswordManager()); |
| 559 break; |
| 560 case ManageLinkTarget::SETTINGS_PAGE: |
| 561 EXPECT_CALL(*controller(), NavigateToPasswordManagerSettingsPage()); |
| 562 break; |
| 563 } |
489 | 564 |
490 model()->OnManageLinkClicked(); | 565 model()->OnManageLinkClicked(); |
491 } | 566 } |
492 | 567 |
| 568 namespace { |
| 569 |
| 570 const ManageLinkTestCase kManageLinkTestCases[] = { |
| 571 {kSmartLockBrandingGroupName, SmartLockStatus::ENABLE, |
| 572 ManageLinkTarget::EXTERNAL_PASSWORD_MANAGER}, |
| 573 {kSmartLockBrandingSavePromptOnlyGroupName, SmartLockStatus::ENABLE, |
| 574 ManageLinkTarget::SETTINGS_PAGE}, |
| 575 {nullptr, SmartLockStatus::ENABLE, ManageLinkTarget::SETTINGS_PAGE}, |
| 576 {"Default", SmartLockStatus::ENABLE, ManageLinkTarget::SETTINGS_PAGE}, |
| 577 {kSmartLockBrandingGroupName, SmartLockStatus::DISABLE, |
| 578 ManageLinkTarget::SETTINGS_PAGE}, |
| 579 {kSmartLockBrandingSavePromptOnlyGroupName, SmartLockStatus::DISABLE, |
| 580 ManageLinkTarget::SETTINGS_PAGE}, |
| 581 {nullptr, SmartLockStatus::DISABLE, ManageLinkTarget::SETTINGS_PAGE}, |
| 582 {"Default", SmartLockStatus::DISABLE, ManageLinkTarget::SETTINGS_PAGE}, |
| 583 }; |
| 584 |
| 585 } // namespace |
| 586 |
493 INSTANTIATE_TEST_CASE_P(Default, | 587 INSTANTIATE_TEST_CASE_P(Default, |
494 ManagePasswordsBubbleModelManageLinkTest, | 588 ManagePasswordsBubbleModelManageLinkTest, |
495 ::testing::Values(TestSyncService::SyncedTypes::ALL, | 589 ::testing::ValuesIn(kManageLinkTestCases)); |
496 TestSyncService::SyncedTypes::NONE)); | |
OLD | NEW |