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