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/password_bubble_experiment.h" | 5 #include "chrome/browser/ui/passwords/password_bubble_experiment.h" |
6 | 6 |
7 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
9 #include "base/prefs/pref_service.h" | 9 #include "base/prefs/pref_service.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
11 #include "chrome/common/pref_names.h" | 11 #include "chrome/common/pref_names.h" |
12 #include "chrome/test/base/testing_profile.h" | 12 #include "chrome/test/base/testing_profile.h" |
13 #include "components/variations/entropy_provider.h" | 13 #include "components/variations/entropy_provider.h" |
14 #include "components/variations/variations_associated_data.h" | 14 #include "components/variations/variations_associated_data.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 const int kTimeSpanDays = 2; | 19 const char kGroupName[] = "SomeGroupName"; |
20 const int kTimeSpanThreshold = 3; | 20 const int kNopeThreshold = 10; |
21 const int kProbabilityFakeSaves = 0; | |
22 const int kProbabilityHistory = 10; | |
23 | 21 |
24 void SetupTimeSpanExperiment() { | 22 void SetupExperiment() { |
25 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( | 23 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( |
26 password_bubble_experiment::kExperimentName, | 24 password_bubble_experiment::kExperimentName, |
27 password_bubble_experiment::kGroupTimeSpanBased)); | 25 kGroupName)); |
28 std::map<std::string, std::string> params; | 26 std::map<std::string, std::string> params; |
29 params[password_bubble_experiment::kParamTimeSpan] = | 27 params[password_bubble_experiment::kParamNopeThreshold] = |
30 base::IntToString(kTimeSpanDays); | 28 base::IntToString(kNopeThreshold); |
31 params[password_bubble_experiment::kParamTimeSpanNopeThreshold] = | |
32 base::IntToString(kTimeSpanThreshold); | |
33 ASSERT_TRUE(variations::AssociateVariationParams( | 29 ASSERT_TRUE(variations::AssociateVariationParams( |
34 password_bubble_experiment::kExperimentName, | 30 password_bubble_experiment::kExperimentName, |
35 password_bubble_experiment::kGroupTimeSpanBased, | 31 kGroupName, |
36 params)); | 32 params)); |
37 } | 33 } |
38 | 34 |
39 void SetupProbabilityExperiment() { | |
40 ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( | |
41 password_bubble_experiment::kExperimentName, | |
42 password_bubble_experiment::kGroupProbabilityBased)); | |
43 std::map<std::string, std::string> params; | |
44 params[password_bubble_experiment::kParamProbabilityFakeSaves] = | |
45 base::IntToString(kProbabilityFakeSaves); | |
46 params[password_bubble_experiment::kParamProbabilityInteractionsCount] = | |
47 base::IntToString(kProbabilityHistory); | |
48 ASSERT_TRUE(variations::AssociateVariationParams( | |
49 password_bubble_experiment::kExperimentName, | |
50 password_bubble_experiment::kGroupProbabilityBased, | |
51 params)); | |
52 } | |
53 | |
54 } // namespace | 35 } // namespace |
55 | 36 |
56 class PasswordBubbleExperimentTest : public testing::Test { | 37 class PasswordBubbleExperimentTest : public testing::Test { |
57 public: | 38 public: |
58 void SetUp() override { | 39 void SetUp() override { |
59 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 40 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
60 profile_.reset(new TestingProfile(temp_dir_.path())); | 41 profile_.reset(new TestingProfile(temp_dir_.path())); |
61 | 42 |
62 field_trial_list_.reset(new base::FieldTrialList( | 43 field_trial_list_.reset(new base::FieldTrialList( |
63 new metrics::SHA1EntropyProvider("foo"))); | 44 new metrics::SHA1EntropyProvider("foo"))); |
| 45 } |
| 46 |
| 47 void TearDown() override { |
64 variations::testing::ClearAllVariationParams(); | 48 variations::testing::ClearAllVariationParams(); |
65 } | 49 } |
66 | 50 |
67 PrefService* prefs() { return profile_->GetPrefs(); } | 51 PrefService* prefs() { return profile_->GetPrefs(); } |
68 | 52 |
69 private: | 53 private: |
70 base::ScopedTempDir temp_dir_; | 54 base::ScopedTempDir temp_dir_; |
71 scoped_ptr<TestingProfile> profile_; | 55 scoped_ptr<TestingProfile> profile_; |
72 scoped_ptr<base::FieldTrialList> field_trial_list_; | 56 scoped_ptr<base::FieldTrialList> field_trial_list_; |
73 }; | 57 }; |
74 | 58 |
75 TEST_F(PasswordBubbleExperimentTest, TimeSpan) { | 59 TEST_F(PasswordBubbleExperimentTest, NoExperiment) { |
76 SetupTimeSpanExperiment(); | 60 EXPECT_FALSE( |
| 61 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
| 62 for (int i = 0; i <= kNopeThreshold; ++i) { |
| 63 password_bubble_experiment::RecordBubbleClosed( |
| 64 prefs(), password_manager::metrics_util::CLICKED_NOPE); |
| 65 EXPECT_FALSE( |
| 66 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
| 67 } |
| 68 } |
77 | 69 |
78 EXPECT_TRUE(password_bubble_experiment::ShouldShowBubble(prefs())); | 70 TEST_F(PasswordBubbleExperimentTest, WithExperiment) { |
79 // Don't save password enough times. | 71 SetupExperiment(); |
80 for (int i = 0; i < kTimeSpanThreshold; ++i) { | 72 |
81 password_manager::metrics_util::UIDismissalReason reason = i % 2 ? | 73 // Repeatedly click "Never". It shouldn't affect the state. |
82 password_manager::metrics_util::NO_DIRECT_INTERACTION : | 74 for (int i = 0; i < kNopeThreshold; ++i) { |
| 75 password_manager::metrics_util::UIDismissalReason reason = |
| 76 password_manager::metrics_util::CLICKED_NEVER; |
| 77 password_bubble_experiment::RecordBubbleClosed(prefs(), reason); |
| 78 } |
| 79 EXPECT_FALSE( |
| 80 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
| 81 // Repeatedly refuse to save password, for |kNopeThreshold|-1 times. |
| 82 for (int i = 0; i < kNopeThreshold - 1; ++i) { |
| 83 password_manager::metrics_util::UIDismissalReason reason = |
83 password_manager::metrics_util::CLICKED_NOPE; | 84 password_manager::metrics_util::CLICKED_NOPE; |
84 password_bubble_experiment::RecordBubbleClosed(prefs(), reason); | 85 password_bubble_experiment::RecordBubbleClosed(prefs(), reason); |
85 } | 86 } |
86 EXPECT_FALSE(password_bubble_experiment::ShouldShowBubble(prefs())); | 87 EXPECT_FALSE( |
| 88 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
87 | 89 |
88 // Save password many times. It doesn't bring the bubble back while the time | 90 // Refuse to save once more to make Never the default button. |
89 // span isn't over. | |
90 for (int i = 0; i < 2*kTimeSpanThreshold; ++i) { | |
91 password_bubble_experiment::RecordBubbleClosed( | |
92 prefs(), | |
93 password_manager::metrics_util::CLICKED_SAVE); | |
94 } | |
95 EXPECT_FALSE(password_bubble_experiment::ShouldShowBubble(prefs())); | |
96 } | |
97 | |
98 TEST_F(PasswordBubbleExperimentTest, TimeSpanOver) { | |
99 SetupTimeSpanExperiment(); | |
100 | |
101 base::Time past_interval = | |
102 base::Time::Now() - base::TimeDelta::FromDays(kTimeSpanDays + 1); | |
103 prefs()->SetInt64(prefs::kPasswordBubbleTimeStamp, | |
104 past_interval.ToInternalValue()); | |
105 prefs()->SetInteger(prefs::kPasswordBubbleNopesCount, kTimeSpanThreshold); | |
106 // The time span is over. The bubble should be shown. | |
107 EXPECT_TRUE(password_bubble_experiment::ShouldShowBubble(prefs())); | |
108 EXPECT_EQ(0, prefs()->GetInteger(prefs::kPasswordBubbleNopesCount)); | |
109 | |
110 // Set the old time span again and record "Nope". The counter restarts from 0. | |
111 prefs()->SetInt64(prefs::kPasswordBubbleTimeStamp, | |
112 past_interval.ToInternalValue()); | |
113 password_bubble_experiment::RecordBubbleClosed( | 91 password_bubble_experiment::RecordBubbleClosed( |
114 prefs(), password_manager::metrics_util::CLICKED_NOPE); | 92 prefs(), password_manager::metrics_util::CLICKED_NOPE); |
115 EXPECT_TRUE(password_bubble_experiment::ShouldShowBubble(prefs())); | 93 EXPECT_TRUE( |
116 EXPECT_EQ(1, prefs()->GetInteger(prefs::kPasswordBubbleNopesCount)); | 94 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
117 } | 95 password_bubble_experiment::RecordBubbleClosed( |
| 96 prefs(), password_manager::metrics_util::CLICKED_SAVE); |
| 97 EXPECT_FALSE( |
| 98 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
118 | 99 |
119 TEST_F(PasswordBubbleExperimentTest, Probability) { | 100 // Repeatedly refuse to save password, for |kNopeThreshold| times. |
120 SetupProbabilityExperiment(); | 101 for (int i = 0; i < kNopeThreshold; ++i) { |
121 | 102 password_manager::metrics_util::UIDismissalReason reason = |
122 EXPECT_TRUE(password_bubble_experiment::ShouldShowBubble(prefs())); | |
123 // Don't save password enough times. | |
124 for (int i = 0; i < kProbabilityHistory; ++i) { | |
125 password_manager::metrics_util::UIDismissalReason reason = i % 2 ? | |
126 password_manager::metrics_util::NO_DIRECT_INTERACTION : | |
127 password_manager::metrics_util::CLICKED_NOPE; | 103 password_manager::metrics_util::CLICKED_NOPE; |
128 password_bubble_experiment::RecordBubbleClosed(prefs(), reason); | 104 password_bubble_experiment::RecordBubbleClosed(prefs(), reason); |
129 } | 105 } |
130 EXPECT_FALSE(password_bubble_experiment::ShouldShowBubble(prefs())); | 106 EXPECT_TRUE( |
131 | 107 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
132 // Save password enough times. | 108 // Repeatedly click "Never". It shouldn't affect the state. |
133 for (int i = 0; i < kProbabilityHistory; ++i) { | 109 for (int i = 0; i < kNopeThreshold; ++i) { |
134 password_bubble_experiment::RecordBubbleClosed( | 110 password_manager::metrics_util::UIDismissalReason reason = |
135 prefs(), | 111 password_manager::metrics_util::CLICKED_NEVER; |
136 password_manager::metrics_util::CLICKED_SAVE); | 112 password_bubble_experiment::RecordBubbleClosed(prefs(), reason); |
137 } | 113 } |
138 EXPECT_TRUE(password_bubble_experiment::ShouldShowBubble(prefs())); | 114 EXPECT_TRUE( |
| 115 password_bubble_experiment::ShouldShowNeverForThisSiteDefault(prefs())); |
139 } | 116 } |
OLD | NEW |