1 // Copyright 2010 The Chromium Authors
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 "components/prefs/pref_change_registrar.h"
6
7 #include <memory>
8
9 #include "base/functional/bind.h"
10 #include "base/functional/callback_helpers.h"
11 #include "components/prefs/pref_observer.h"
12 #include "components/prefs/pref_registry_simple.h"
13 #include "components/prefs/testing_pref_service.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 using testing::Mock;
18 using testing::Eq;
19
20 namespace base {
21 namespace {
22
23 const char kHomePage[] = "homepage";
24 const char kHomePageIsNewTabPage[] = "homepage_is_newtabpage";
25 const char kApplicationLocale[] = "intl.app_locale";
26
27 // A mock provider that allows us to capture pref observer changes.
28 class MockPrefService : public TestingPrefServiceSimple {
29 public:
MockPrefService()30 MockPrefService() {}
~MockPrefService()31 ~MockPrefService() override {}
32
33 MOCK_METHOD2(AddPrefObserver, void(const std::string&, PrefObserver*));
34 MOCK_METHOD2(RemovePrefObserver, void(const std::string&, PrefObserver*));
35 };
36
37 // Due to overloads, base::DoNothing() cannot be passed directly to
38 // PrefChangeRegistrar::Add() as it is convertible to all callbacks.
DoNothingClosure()39 base::RepeatingClosure DoNothingClosure() {
40 return base::DoNothing();
41 }
42
43 } // namespace
44
45 class PrefChangeRegistrarTest : public testing::Test {
46 public:
PrefChangeRegistrarTest()47 PrefChangeRegistrarTest() {}
~PrefChangeRegistrarTest()48 ~PrefChangeRegistrarTest() override {}
49
50 protected:
51 void SetUp() override;
52
service() const53 MockPrefService* service() const { return service_.get(); }
54
55 private:
56 std::unique_ptr<MockPrefService> service_;
57 };
58
SetUp()59 void PrefChangeRegistrarTest::SetUp() {
60 service_ = std::make_unique<MockPrefService>();
61 }
62
TEST_F(PrefChangeRegistrarTest,AddAndRemove)63 TEST_F(PrefChangeRegistrarTest, AddAndRemove) {
64 PrefChangeRegistrar registrar;
65 registrar.Init(service());
66
67 // Test adding.
68 EXPECT_CALL(*service(),
69 AddPrefObserver(Eq(std::string("test.pref.1")), ®istrar));
70 EXPECT_CALL(*service(),
71 AddPrefObserver(Eq(std::string("test.pref.2")), ®istrar));
72 registrar.Add("test.pref.1", DoNothingClosure());
73 registrar.Add("test.pref.2", DoNothingClosure());
74 EXPECT_FALSE(registrar.IsEmpty());
75
76 // Test removing.
77 Mock::VerifyAndClearExpectations(service());
78 EXPECT_CALL(*service(),
79 RemovePrefObserver(Eq(std::string("test.pref.1")), ®istrar));
80 EXPECT_CALL(*service(),
81 RemovePrefObserver(Eq(std::string("test.pref.2")), ®istrar));
82 registrar.Remove("test.pref.1");
83 registrar.Remove("test.pref.2");
84 EXPECT_TRUE(registrar.IsEmpty());
85
86 // Explicitly check the expectations now to make sure that the Removes
87 // worked (rather than the registrar destructor doing the work).
88 Mock::VerifyAndClearExpectations(service());
89 }
90
TEST_F(PrefChangeRegistrarTest,AutoRemove)91 TEST_F(PrefChangeRegistrarTest, AutoRemove) {
92 PrefChangeRegistrar registrar;
93 registrar.Init(service());
94
95 // Setup of auto-remove.
96 EXPECT_CALL(*service(),
97 AddPrefObserver(Eq(std::string("test.pref.1")), ®istrar));
98 registrar.Add("test.pref.1", DoNothingClosure());
99 Mock::VerifyAndClearExpectations(service());
100 EXPECT_FALSE(registrar.IsEmpty());
101
102 // Test auto-removing.
103 EXPECT_CALL(*service(),
104 RemovePrefObserver(Eq(std::string("test.pref.1")), ®istrar));
105 }
106
TEST_F(PrefChangeRegistrarTest,RemoveAll)107 TEST_F(PrefChangeRegistrarTest, RemoveAll) {
108 PrefChangeRegistrar registrar;
109 registrar.Init(service());
110
111 EXPECT_CALL(*service(),
112 AddPrefObserver(Eq(std::string("test.pref.1")), ®istrar));
113 EXPECT_CALL(*service(),
114 AddPrefObserver(Eq(std::string("test.pref.2")), ®istrar));
115 registrar.Add("test.pref.1", DoNothingClosure());
116 registrar.Add("test.pref.2", DoNothingClosure());
117 Mock::VerifyAndClearExpectations(service());
118
119 EXPECT_CALL(*service(),
120 RemovePrefObserver(Eq(std::string("test.pref.1")), ®istrar));
121 EXPECT_CALL(*service(),
122 RemovePrefObserver(Eq(std::string("test.pref.2")), ®istrar));
123 registrar.RemoveAll();
124 EXPECT_TRUE(registrar.IsEmpty());
125
126 // Explicitly check the expectations now to make sure that the RemoveAll
127 // worked (rather than the registrar destructor doing the work).
128 Mock::VerifyAndClearExpectations(service());
129 }
130
131 class ObserveSetOfPreferencesTest : public testing::Test {
132 public:
SetUp()133 void SetUp() override {
134 pref_service_ = std::make_unique<TestingPrefServiceSimple>();
135 PrefRegistrySimple* registry = pref_service_->registry();
136 registry->RegisterStringPref(kHomePage, "http://google.com");
137 registry->RegisterBooleanPref(kHomePageIsNewTabPage, false);
138 registry->RegisterStringPref(kApplicationLocale, std::string());
139 }
140
CreatePrefChangeRegistrar()141 PrefChangeRegistrar* CreatePrefChangeRegistrar() {
142 PrefChangeRegistrar* pref_set = new PrefChangeRegistrar();
143 pref_set->Init(pref_service_.get());
144 pref_set->Add(kHomePage, DoNothingClosure());
145 pref_set->Add(kHomePageIsNewTabPage, DoNothingClosure());
146 return pref_set;
147 }
148
149 MOCK_METHOD1(OnPreferenceChanged, void(const std::string&));
150
151 std::unique_ptr<TestingPrefServiceSimple> pref_service_;
152 };
153
TEST_F(ObserveSetOfPreferencesTest,IsObserved)154 TEST_F(ObserveSetOfPreferencesTest, IsObserved) {
155 std::unique_ptr<PrefChangeRegistrar> pref_set(CreatePrefChangeRegistrar());
156 EXPECT_TRUE(pref_set->IsObserved(kHomePage));
157 EXPECT_TRUE(pref_set->IsObserved(kHomePageIsNewTabPage));
158 EXPECT_FALSE(pref_set->IsObserved(kApplicationLocale));
159 }
160
TEST_F(ObserveSetOfPreferencesTest,Observe)161 TEST_F(ObserveSetOfPreferencesTest, Observe) {
162 using testing::_;
163 using testing::Mock;
164
165 PrefChangeRegistrar pref_set;
166 PrefChangeRegistrar::NamedChangeCallback callback =
167 base::BindRepeating(&ObserveSetOfPreferencesTest::OnPreferenceChanged,
168 base::Unretained(this));
169 pref_set.Init(pref_service_.get());
170 pref_set.Add(kHomePage, callback);
171 pref_set.Add(kHomePageIsNewTabPage, callback);
172
173 EXPECT_CALL(*this, OnPreferenceChanged(kHomePage));
174 pref_service_->SetUserPref(kHomePage,
175 std::make_unique<Value>("http://crbug.com"));
176 Mock::VerifyAndClearExpectations(this);
177
178 EXPECT_CALL(*this, OnPreferenceChanged(kHomePageIsNewTabPage));
179 pref_service_->SetUserPref(kHomePageIsNewTabPage,
180 std::make_unique<Value>(true));
181 Mock::VerifyAndClearExpectations(this);
182
183 EXPECT_CALL(*this, OnPreferenceChanged(_)).Times(0);
184 pref_service_->SetUserPref(kApplicationLocale,
185 std::make_unique<Value>("en_US.utf8"));
186 Mock::VerifyAndClearExpectations(this);
187 }
188
189 } // namespace base
190