1 // Copyright (c) 2012 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 <string>
6
7 #include "base/prefs/json_pref_store.h"
8 #include "base/prefs/mock_pref_change_callback.h"
9 #include "base/prefs/pref_change_registrar.h"
10 #include "base/prefs/pref_registry_simple.h"
11 #include "base/prefs/pref_value_store.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "base/prefs/testing_pref_store.h"
14 #include "base/values.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 using testing::_;
19 using testing::Mock;
20
21 const char kPrefName[] = "pref.name";
22
TEST(PrefServiceTest,NoObserverFire)23 TEST(PrefServiceTest, NoObserverFire) {
24 TestingPrefServiceSimple prefs;
25
26 const char pref_name[] = "homepage";
27 prefs.registry()->RegisterStringPref(pref_name, std::string());
28
29 const char new_pref_value[] = "http://www.google.com/";
30 MockPrefChangeCallback obs(&prefs);
31 PrefChangeRegistrar registrar;
32 registrar.Init(&prefs);
33 registrar.Add(pref_name, obs.GetCallback());
34
35 // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged.
36 const base::StringValue expected_value(new_pref_value);
37 obs.Expect(pref_name, &expected_value);
38 prefs.SetString(pref_name, new_pref_value);
39 Mock::VerifyAndClearExpectations(&obs);
40
41 // Setting the pref to the same value should not set the pref value a second
42 // time.
43 EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0);
44 prefs.SetString(pref_name, new_pref_value);
45 Mock::VerifyAndClearExpectations(&obs);
46
47 // Clearing the pref should cause the pref to fire.
48 const base::StringValue expected_default_value((std::string()));
49 obs.Expect(pref_name, &expected_default_value);
50 prefs.ClearPref(pref_name);
51 Mock::VerifyAndClearExpectations(&obs);
52
53 // Clearing the pref again should not cause the pref to fire.
54 EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0);
55 prefs.ClearPref(pref_name);
56 Mock::VerifyAndClearExpectations(&obs);
57 }
58
TEST(PrefServiceTest,HasPrefPath)59 TEST(PrefServiceTest, HasPrefPath) {
60 TestingPrefServiceSimple prefs;
61
62 const char path[] = "fake.path";
63
64 // Shouldn't initially have a path.
65 EXPECT_FALSE(prefs.HasPrefPath(path));
66
67 // Register the path. This doesn't set a value, so the path still shouldn't
68 // exist.
69 prefs.registry()->RegisterStringPref(path, std::string());
70 EXPECT_FALSE(prefs.HasPrefPath(path));
71
72 // Set a value and make sure we have a path.
73 prefs.SetString(path, "blah");
74 EXPECT_TRUE(prefs.HasPrefPath(path));
75 }
76
TEST(PrefServiceTest,Observers)77 TEST(PrefServiceTest, Observers) {
78 const char pref_name[] = "homepage";
79
80 TestingPrefServiceSimple prefs;
81 prefs.SetUserPref(pref_name,
82 new base::StringValue("http://www.cnn.com"));
83 prefs.registry()->RegisterStringPref(pref_name, std::string());
84
85 const char new_pref_value[] = "http://www.google.com/";
86 const base::StringValue expected_new_pref_value(new_pref_value);
87 MockPrefChangeCallback obs(&prefs);
88 PrefChangeRegistrar registrar;
89 registrar.Init(&prefs);
90 registrar.Add(pref_name, obs.GetCallback());
91
92 PrefChangeRegistrar registrar_two;
93 registrar_two.Init(&prefs);
94
95 // This should fire the checks in MockPrefChangeCallback::OnPreferenceChanged.
96 obs.Expect(pref_name, &expected_new_pref_value);
97 prefs.SetString(pref_name, new_pref_value);
98 Mock::VerifyAndClearExpectations(&obs);
99
100 // Now try adding a second pref observer.
101 const char new_pref_value2[] = "http://www.youtube.com/";
102 const base::StringValue expected_new_pref_value2(new_pref_value2);
103 MockPrefChangeCallback obs2(&prefs);
104 obs.Expect(pref_name, &expected_new_pref_value2);
105 obs2.Expect(pref_name, &expected_new_pref_value2);
106 registrar_two.Add(pref_name, obs2.GetCallback());
107 // This should fire the checks in obs and obs2.
108 prefs.SetString(pref_name, new_pref_value2);
109 Mock::VerifyAndClearExpectations(&obs);
110 Mock::VerifyAndClearExpectations(&obs2);
111
112 // Set a recommended value.
113 const base::StringValue recommended_pref_value("http://www.gmail.com/");
114 obs.Expect(pref_name, &expected_new_pref_value2);
115 obs2.Expect(pref_name, &expected_new_pref_value2);
116 // This should fire the checks in obs and obs2 but with an unchanged value
117 // as the recommended value is being overridden by the user-set value.
118 prefs.SetRecommendedPref(pref_name, recommended_pref_value.DeepCopy());
119 Mock::VerifyAndClearExpectations(&obs);
120 Mock::VerifyAndClearExpectations(&obs2);
121
122 // Make sure obs2 still works after removing obs.
123 registrar.Remove(pref_name);
124 EXPECT_CALL(obs, OnPreferenceChanged(_)).Times(0);
125 obs2.Expect(pref_name, &expected_new_pref_value);
126 // This should only fire the observer in obs2.
127 prefs.SetString(pref_name, new_pref_value);
128 Mock::VerifyAndClearExpectations(&obs);
129 Mock::VerifyAndClearExpectations(&obs2);
130 }
131
132 // Make sure that if a preference changes type, so the wrong type is stored in
133 // the user pref file, it uses the correct fallback value instead.
TEST(PrefServiceTest,GetValueChangedType)134 TEST(PrefServiceTest, GetValueChangedType) {
135 const int kTestValue = 10;
136 TestingPrefServiceSimple prefs;
137 prefs.registry()->RegisterIntegerPref(kPrefName, kTestValue);
138
139 // Check falling back to a recommended value.
140 prefs.SetUserPref(kPrefName,
141 new base::StringValue("not an integer"));
142 const PrefService::Preference* pref = prefs.FindPreference(kPrefName);
143 ASSERT_TRUE(pref);
144 const base::Value* value = pref->GetValue();
145 ASSERT_TRUE(value);
146 EXPECT_EQ(base::Value::TYPE_INTEGER, value->GetType());
147 int actual_int_value = -1;
148 EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
149 EXPECT_EQ(kTestValue, actual_int_value);
150 }
151
TEST(PrefServiceTest,GetValueAndGetRecommendedValue)152 TEST(PrefServiceTest, GetValueAndGetRecommendedValue) {
153 const int kDefaultValue = 5;
154 const int kUserValue = 10;
155 const int kRecommendedValue = 15;
156 TestingPrefServiceSimple prefs;
157 prefs.registry()->RegisterIntegerPref(kPrefName, kDefaultValue);
158
159 // Create pref with a default value only.
160 const PrefService::Preference* pref = prefs.FindPreference(kPrefName);
161 ASSERT_TRUE(pref);
162
163 // Check that GetValue() returns the default value.
164 const base::Value* value = pref->GetValue();
165 ASSERT_TRUE(value);
166 EXPECT_EQ(base::Value::TYPE_INTEGER, value->GetType());
167 int actual_int_value = -1;
168 EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
169 EXPECT_EQ(kDefaultValue, actual_int_value);
170
171 // Check that GetRecommendedValue() returns no value.
172 value = pref->GetRecommendedValue();
173 ASSERT_FALSE(value);
174
175 // Set a user-set value.
176 prefs.SetUserPref(kPrefName, new base::FundamentalValue(kUserValue));
177
178 // Check that GetValue() returns the user-set value.
179 value = pref->GetValue();
180 ASSERT_TRUE(value);
181 EXPECT_EQ(base::Value::TYPE_INTEGER, value->GetType());
182 actual_int_value = -1;
183 EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
184 EXPECT_EQ(kUserValue, actual_int_value);
185
186 // Check that GetRecommendedValue() returns no value.
187 value = pref->GetRecommendedValue();
188 ASSERT_FALSE(value);
189
190 // Set a recommended value.
191 prefs.SetRecommendedPref(kPrefName,
192 new base::FundamentalValue(kRecommendedValue));
193
194 // Check that GetValue() returns the user-set value.
195 value = pref->GetValue();
196 ASSERT_TRUE(value);
197 EXPECT_EQ(base::Value::TYPE_INTEGER, value->GetType());
198 actual_int_value = -1;
199 EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
200 EXPECT_EQ(kUserValue, actual_int_value);
201
202 // Check that GetRecommendedValue() returns the recommended value.
203 value = pref->GetRecommendedValue();
204 ASSERT_TRUE(value);
205 EXPECT_EQ(base::Value::TYPE_INTEGER, value->GetType());
206 actual_int_value = -1;
207 EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
208 EXPECT_EQ(kRecommendedValue, actual_int_value);
209
210 // Remove the user-set value.
211 prefs.RemoveUserPref(kPrefName);
212
213 // Check that GetValue() returns the recommended value.
214 value = pref->GetValue();
215 ASSERT_TRUE(value);
216 EXPECT_EQ(base::Value::TYPE_INTEGER, value->GetType());
217 actual_int_value = -1;
218 EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
219 EXPECT_EQ(kRecommendedValue, actual_int_value);
220
221 // Check that GetRecommendedValue() returns the recommended value.
222 value = pref->GetRecommendedValue();
223 ASSERT_TRUE(value);
224 EXPECT_EQ(base::Value::TYPE_INTEGER, value->GetType());
225 actual_int_value = -1;
226 EXPECT_TRUE(value->GetAsInteger(&actual_int_value));
227 EXPECT_EQ(kRecommendedValue, actual_int_value);
228 }
229
230 class PrefServiceSetValueTest : public testing::Test {
231 protected:
232 static const char kName[];
233 static const char kValue[];
234
PrefServiceSetValueTest()235 PrefServiceSetValueTest() : observer_(&prefs_) {}
236
237 TestingPrefServiceSimple prefs_;
238 MockPrefChangeCallback observer_;
239 };
240
241 const char PrefServiceSetValueTest::kName[] = "name";
242 const char PrefServiceSetValueTest::kValue[] = "value";
243
TEST_F(PrefServiceSetValueTest,SetStringValue)244 TEST_F(PrefServiceSetValueTest, SetStringValue) {
245 const char default_string[] = "default";
246 const base::StringValue default_value(default_string);
247 prefs_.registry()->RegisterStringPref(kName, default_string);
248
249 PrefChangeRegistrar registrar;
250 registrar.Init(&prefs_);
251 registrar.Add(kName, observer_.GetCallback());
252
253 // Changing the controlling store from default to user triggers notification.
254 observer_.Expect(kName, &default_value);
255 prefs_.Set(kName, default_value);
256 Mock::VerifyAndClearExpectations(&observer_);
257
258 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
259 prefs_.Set(kName, default_value);
260 Mock::VerifyAndClearExpectations(&observer_);
261
262 base::StringValue new_value(kValue);
263 observer_.Expect(kName, &new_value);
264 prefs_.Set(kName, new_value);
265 Mock::VerifyAndClearExpectations(&observer_);
266 }
267
TEST_F(PrefServiceSetValueTest,SetDictionaryValue)268 TEST_F(PrefServiceSetValueTest, SetDictionaryValue) {
269 prefs_.registry()->RegisterDictionaryPref(kName);
270 PrefChangeRegistrar registrar;
271 registrar.Init(&prefs_);
272 registrar.Add(kName, observer_.GetCallback());
273
274 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
275 prefs_.RemoveUserPref(kName);
276 Mock::VerifyAndClearExpectations(&observer_);
277
278 base::DictionaryValue new_value;
279 new_value.SetString(kName, kValue);
280 observer_.Expect(kName, &new_value);
281 prefs_.Set(kName, new_value);
282 Mock::VerifyAndClearExpectations(&observer_);
283
284 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
285 prefs_.Set(kName, new_value);
286 Mock::VerifyAndClearExpectations(&observer_);
287
288 base::DictionaryValue empty;
289 observer_.Expect(kName, &empty);
290 prefs_.Set(kName, empty);
291 Mock::VerifyAndClearExpectations(&observer_);
292 }
293
TEST_F(PrefServiceSetValueTest,SetListValue)294 TEST_F(PrefServiceSetValueTest, SetListValue) {
295 prefs_.registry()->RegisterListPref(kName);
296 PrefChangeRegistrar registrar;
297 registrar.Init(&prefs_);
298 registrar.Add(kName, observer_.GetCallback());
299
300 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
301 prefs_.RemoveUserPref(kName);
302 Mock::VerifyAndClearExpectations(&observer_);
303
304 base::ListValue new_value;
305 new_value.Append(new base::StringValue(kValue));
306 observer_.Expect(kName, &new_value);
307 prefs_.Set(kName, new_value);
308 Mock::VerifyAndClearExpectations(&observer_);
309
310 EXPECT_CALL(observer_, OnPreferenceChanged(_)).Times(0);
311 prefs_.Set(kName, new_value);
312 Mock::VerifyAndClearExpectations(&observer_);
313
314 base::ListValue empty;
315 observer_.Expect(kName, &empty);
316 prefs_.Set(kName, empty);
317 Mock::VerifyAndClearExpectations(&observer_);
318 }
319