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