pref_service_unittest.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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 "app/test/data/resource.h"
8#include "base/scoped_ptr.h"
9#include "base/values.h"
10#include "chrome/browser/prefs/dummy_pref_store.h"
11#include "chrome/browser/prefs/pref_change_registrar.h"
12#include "chrome/browser/prefs/pref_value_store.h"
13#include "chrome/common/chrome_paths.h"
14#include "chrome/common/notification_observer_mock.h"
15#include "chrome/common/notification_service.h"
16#include "chrome/common/notification_type.h"
17#include "chrome/common/pref_names.h"
18#include "chrome/test/testing_pref_service.h"
19#include "testing/gmock/include/gmock/gmock.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22using testing::_;
23using testing::Mock;
24using testing::Pointee;
25using testing::Property;
26
27class TestPrefObserver : public NotificationObserver {
28 public:
29  TestPrefObserver(const PrefService* prefs,
30                   const std::string& pref_name,
31                   const std::string& new_pref_value)
32      : observer_fired_(false),
33        prefs_(prefs),
34        pref_name_(pref_name),
35        new_pref_value_(new_pref_value) {
36  }
37  virtual ~TestPrefObserver() {}
38
39  virtual void Observe(NotificationType type,
40                       const NotificationSource& source,
41                       const NotificationDetails& details) {
42    EXPECT_EQ(type.value, NotificationType::PREF_CHANGED);
43    PrefService* prefs_in = Source<PrefService>(source).ptr();
44    EXPECT_EQ(prefs_in, prefs_);
45    std::string* pref_name_in = Details<std::string>(details).ptr();
46    EXPECT_EQ(*pref_name_in, pref_name_);
47    EXPECT_EQ(new_pref_value_, prefs_in->GetString("homepage"));
48    observer_fired_ = true;
49  }
50
51  bool observer_fired() { return observer_fired_; }
52
53  void Reset(const std::string& new_pref_value) {
54    observer_fired_ = false;
55    new_pref_value_ = new_pref_value;
56  }
57
58 private:
59  bool observer_fired_;
60  const PrefService* prefs_;
61  const std::string pref_name_;
62  std::string new_pref_value_;
63};
64
65// TODO(port): port this test to POSIX.
66#if defined(OS_WIN)
67TEST(PrefServiceTest, LocalizedPrefs) {
68  TestingPrefService prefs;
69  const char kBoolean[] = "boolean";
70  const char kInteger[] = "integer";
71  const char kString[] = "string";
72  prefs.RegisterLocalizedBooleanPref(kBoolean, IDS_LOCALE_BOOL);
73  prefs.RegisterLocalizedIntegerPref(kInteger, IDS_LOCALE_INT);
74  prefs.RegisterLocalizedStringPref(kString, IDS_LOCALE_STRING);
75
76  // The locale default should take preference over the user default.
77  EXPECT_FALSE(prefs.GetBoolean(kBoolean));
78  EXPECT_EQ(1, prefs.GetInteger(kInteger));
79  EXPECT_EQ("hello", prefs.GetString(kString));
80
81  prefs.SetBoolean(kBoolean, true);
82  EXPECT_TRUE(prefs.GetBoolean(kBoolean));
83  prefs.SetInteger(kInteger, 5);
84  EXPECT_EQ(5, prefs.GetInteger(kInteger));
85  prefs.SetString(kString, "foo");
86  EXPECT_EQ("foo", prefs.GetString(kString));
87}
88#endif
89
90TEST(PrefServiceTest, NoObserverFire) {
91  TestingPrefService prefs;
92
93  const char pref_name[] = "homepage";
94  prefs.RegisterStringPref(pref_name, "");
95
96  const std::string new_pref_value("http://www.google.com/");
97  TestPrefObserver obs(&prefs, pref_name, new_pref_value);
98
99  PrefChangeRegistrar registrar;
100  registrar.Init(&prefs);
101  registrar.Add(pref_name, &obs);
102  // This should fire the checks in TestPrefObserver::Observe.
103  prefs.SetString(pref_name, new_pref_value);
104
105  // Make sure the observer was actually fired.
106  EXPECT_TRUE(obs.observer_fired());
107
108  // Setting the pref to the same value should not set the pref value a second
109  // time.
110  obs.Reset(new_pref_value);
111  prefs.SetString(pref_name, new_pref_value);
112  EXPECT_FALSE(obs.observer_fired());
113
114  // Clearing the pref should cause the pref to fire.
115  obs.Reset("");
116  prefs.ClearPref(pref_name);
117  EXPECT_TRUE(obs.observer_fired());
118
119  // Clearing the pref again should not cause the pref to fire.
120  obs.Reset("");
121  prefs.ClearPref(pref_name);
122  EXPECT_FALSE(obs.observer_fired());
123}
124
125TEST(PrefServiceTest, HasPrefPath) {
126  TestingPrefService prefs;
127
128  const char path[] = "fake.path";
129
130  // Shouldn't initially have a path.
131  EXPECT_FALSE(prefs.HasPrefPath(path));
132
133  // Register the path. This doesn't set a value, so the path still shouldn't
134  // exist.
135  prefs.RegisterStringPref(path, std::string());
136  EXPECT_FALSE(prefs.HasPrefPath(path));
137
138  // Set a value and make sure we have a path.
139  prefs.SetString(path, "blah");
140  EXPECT_TRUE(prefs.HasPrefPath(path));
141}
142
143TEST(PrefServiceTest, Observers) {
144  const char pref_name[] = "homepage";
145
146  TestingPrefService prefs;
147  prefs.SetUserPref(pref_name, Value::CreateStringValue("http://www.cnn.com"));
148  prefs.RegisterStringPref(pref_name, "");
149
150  const std::string new_pref_value("http://www.google.com/");
151  TestPrefObserver obs(&prefs, pref_name, new_pref_value);
152  PrefChangeRegistrar registrar;
153  registrar.Init(&prefs);
154  registrar.Add(pref_name, &obs);
155  // This should fire the checks in TestPrefObserver::Observe.
156  prefs.SetString(pref_name, new_pref_value);
157
158  // Make sure the tests were actually run.
159  EXPECT_TRUE(obs.observer_fired());
160
161  // Now try adding a second pref observer.
162  const std::string new_pref_value2("http://www.youtube.com/");
163  obs.Reset(new_pref_value2);
164  TestPrefObserver obs2(&prefs, pref_name, new_pref_value2);
165  registrar.Add(pref_name, &obs2);
166  // This should fire the checks in obs and obs2.
167  prefs.SetString(pref_name, new_pref_value2);
168  EXPECT_TRUE(obs.observer_fired());
169  EXPECT_TRUE(obs2.observer_fired());
170
171  // Make sure obs2 still works after removing obs.
172  registrar.Remove(pref_name, &obs);
173  obs.Reset("");
174  obs2.Reset(new_pref_value);
175  // This should only fire the observer in obs2.
176  prefs.SetString(pref_name, new_pref_value);
177  EXPECT_FALSE(obs.observer_fired());
178  EXPECT_TRUE(obs2.observer_fired());
179}
180
181class PrefServiceSetValueTest : public testing::Test {
182 protected:
183  static const char name_[];
184  static const char value_[];
185
186  PrefServiceSetValueTest()
187      : name_string_(name_),
188        null_value_(Value::CreateNullValue()) {}
189
190  void SetExpectNoNotification() {
191    EXPECT_CALL(observer_, Observe(_, _, _)).Times(0);
192  }
193
194  void SetExpectPrefChanged() {
195    EXPECT_CALL(observer_,
196                Observe(NotificationType(NotificationType::PREF_CHANGED), _,
197                        Property(&Details<std::string>::ptr,
198                                 Pointee(name_string_))));
199  }
200
201  TestingPrefService prefs_;
202  std::string name_string_;
203  scoped_ptr<Value> null_value_;
204  NotificationObserverMock observer_;
205};
206
207const char PrefServiceSetValueTest::name_[] = "name";
208const char PrefServiceSetValueTest::value_[] = "value";
209
210TEST_F(PrefServiceSetValueTest, SetStringValue) {
211  const char default_string[] = "default";
212  scoped_ptr<Value> default_value(Value::CreateStringValue(default_string));
213  prefs_.RegisterStringPref(name_, default_string);
214
215  PrefChangeRegistrar registrar;
216  registrar.Init(&prefs_);
217  registrar.Add(name_, &observer_);
218
219  // Changing the controlling store from default to user triggers notification.
220  SetExpectPrefChanged();
221  prefs_.Set(name_, *default_value);
222  Mock::VerifyAndClearExpectations(&observer_);
223
224  SetExpectNoNotification();
225  prefs_.Set(name_, *default_value);
226  Mock::VerifyAndClearExpectations(&observer_);
227
228  scoped_ptr<Value> new_value(Value::CreateStringValue(value_));
229  SetExpectPrefChanged();
230  prefs_.Set(name_, *new_value);
231  EXPECT_EQ(value_, prefs_.GetString(name_));
232}
233
234TEST_F(PrefServiceSetValueTest, SetDictionaryValue) {
235  prefs_.RegisterDictionaryPref(name_);
236  PrefChangeRegistrar registrar;
237  registrar.Init(&prefs_);
238  registrar.Add(name_, &observer_);
239
240  // Dictionary values are special: setting one to NULL is the same as clearing
241  // the user value, allowing the NULL default to take (or keep) control.
242  SetExpectNoNotification();
243  prefs_.Set(name_, *null_value_);
244  Mock::VerifyAndClearExpectations(&observer_);
245
246  DictionaryValue new_value;
247  new_value.SetString(name_, value_);
248  SetExpectPrefChanged();
249  prefs_.Set(name_, new_value);
250  Mock::VerifyAndClearExpectations(&observer_);
251  DictionaryValue* dict = prefs_.GetMutableDictionary(name_);
252  EXPECT_EQ(1U, dict->size());
253  std::string out_value;
254  dict->GetString(name_, &out_value);
255  EXPECT_EQ(value_, out_value);
256
257  SetExpectNoNotification();
258  prefs_.Set(name_, new_value);
259  Mock::VerifyAndClearExpectations(&observer_);
260
261  SetExpectPrefChanged();
262  prefs_.Set(name_, *null_value_);
263  Mock::VerifyAndClearExpectations(&observer_);
264  dict = prefs_.GetMutableDictionary(name_);
265  EXPECT_EQ(0U, dict->size());
266}
267
268TEST_F(PrefServiceSetValueTest, SetListValue) {
269  prefs_.RegisterListPref(name_);
270  PrefChangeRegistrar registrar;
271  registrar.Init(&prefs_);
272  registrar.Add(name_, &observer_);
273
274  // List values are special: setting one to NULL is the same as clearing the
275  // user value, allowing the NULL default to take (or keep) control.
276  SetExpectNoNotification();
277  prefs_.Set(name_, *null_value_);
278  Mock::VerifyAndClearExpectations(&observer_);
279
280  ListValue new_value;
281  new_value.Append(Value::CreateStringValue(value_));
282  SetExpectPrefChanged();
283  prefs_.Set(name_, new_value);
284  Mock::VerifyAndClearExpectations(&observer_);
285  ListValue* list = prefs_.GetMutableList(name_);
286  ASSERT_EQ(1U, list->GetSize());
287  std::string out_value;
288  list->GetString(0, &out_value);
289  EXPECT_EQ(value_, out_value);
290
291  SetExpectNoNotification();
292  prefs_.Set(name_, new_value);
293  Mock::VerifyAndClearExpectations(&observer_);
294
295  SetExpectPrefChanged();
296  prefs_.Set(name_, *null_value_);
297  Mock::VerifyAndClearExpectations(&observer_);
298  list = prefs_.GetMutableList(name_);
299  EXPECT_EQ(0U, list->GetSize());
300}
301