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
18using testing::_;
19using testing::Mock;
20
21const char kPrefName[] = "pref.name";
22
23TEST(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
59TEST(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
77TEST(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.
134TEST(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
152TEST(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
230class PrefServiceSetValueTest : public testing::Test {
231 protected:
232  static const char kName[];
233  static const char kValue[];
234
235  PrefServiceSetValueTest() : observer_(&prefs_) {}
236
237  TestingPrefServiceSimple prefs_;
238  MockPrefChangeCallback observer_;
239};
240
241const char PrefServiceSetValueTest::kName[] = "name";
242const char PrefServiceSetValueTest::kValue[] = "value";
243
244TEST_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
268TEST_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
294TEST_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