blob: 4c5211e5758fe1559b378d1409d4f19777d0edea [file] [log] [blame]
[email protected]39f83892011-04-25 17:15:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]acd78969c2010-12-08 09:49:112// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]a6a7ced2012-11-01 17:24:185#include "base/bind.h"
6#include "base/callback.h"
7#include "base/prefs/public/pref_observer.h"
[email protected]acd78969c2010-12-08 09:49:118#include "chrome/browser/prefs/pref_notifier_impl.h"
9#include "chrome/browser/prefs/pref_observer_mock.h"
10#include "chrome/browser/prefs/pref_service.h"
11#include "chrome/browser/prefs/pref_value_store.h"
[email protected]432115822011-07-10 15:52:2712#include "chrome/common/chrome_notification_types.h"
[email protected]8ad3636e2011-08-01 22:31:4013#include "chrome/test/base/testing_pref_service.h"
[email protected]acd78969c2010-12-08 09:49:1114#include "testing/gmock/include/gmock/gmock.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17using testing::_;
18using testing::Field;
19using testing::Invoke;
20using testing::Mock;
21using testing::Truly;
22
23namespace {
24
25const char kChangedPref[] = "changed_pref";
26const char kUnchangedPref[] = "unchanged_pref";
27
[email protected]a6a7ced2012-11-01 17:24:1828class MockPrefInitObserver {
29 public:
30 MOCK_METHOD1(OnInitializationCompleted, void(bool));
31};
32
33// This is an unmodified PrefNotifierImpl, except we make
34// OnPreferenceChanged public for tests.
35class TestingPrefNotifierImpl : public PrefNotifierImpl {
36 public:
37 TestingPrefNotifierImpl(PrefService* service) : PrefNotifierImpl(service) {}
38
39 // Make public for tests.
40 using PrefNotifierImpl::OnPreferenceChanged;
41};
42
43// Mock PrefNotifier that allows tracking of observers and notifications.
[email protected]acd78969c2010-12-08 09:49:1144class MockPrefNotifier : public PrefNotifierImpl {
45 public:
46 explicit MockPrefNotifier(PrefService* pref_service)
47 : PrefNotifierImpl(pref_service) {}
48 virtual ~MockPrefNotifier() {}
49
50 MOCK_METHOD1(FireObservers, void(const std::string& path));
51
[email protected]a6a7ced2012-11-01 17:24:1852 size_t CountObserver(const char* path, PrefObserver* obs) {
[email protected]acd78969c2010-12-08 09:49:1153 PrefObserverMap::const_iterator observer_iterator =
54 pref_observers()->find(path);
55 if (observer_iterator == pref_observers()->end())
56 return false;
57
[email protected]a6a7ced2012-11-01 17:24:1858 PrefObserverList* observer_list = observer_iterator->second;
59 PrefObserverList::Iterator it(*observer_list);
60 PrefObserver* existing_obs;
[email protected]acd78969c2010-12-08 09:49:1161 size_t count = 0;
62 while ((existing_obs = it.GetNext()) != NULL) {
63 if (existing_obs == obs)
64 count++;
65 }
66
67 return count;
68 }
[email protected]a6a7ced2012-11-01 17:24:1869
70 // Make public for tests below.
71 using PrefNotifierImpl::OnPreferenceChanged;
72 using PrefNotifierImpl::OnInitializationCompleted;
[email protected]acd78969c2010-12-08 09:49:1173};
74
75// Test fixture class.
[email protected]583844c2011-08-27 00:38:3576class PrefNotifierTest : public testing::Test {
[email protected]acd78969c2010-12-08 09:49:1177 protected:
78 virtual void SetUp() {
[email protected]d36f941b2011-05-09 06:19:1679 pref_service_.RegisterBooleanPref(kChangedPref,
80 true,
81 PrefService::UNSYNCABLE_PREF);
82 pref_service_.RegisterBooleanPref(kUnchangedPref,
83 true,
84 PrefService::UNSYNCABLE_PREF);
[email protected]acd78969c2010-12-08 09:49:1185 }
86
87 TestingPrefService pref_service_;
88
89 PrefObserverMock obs1_;
90 PrefObserverMock obs2_;
91};
92
93TEST_F(PrefNotifierTest, OnPreferenceChanged) {
94 MockPrefNotifier notifier(&pref_service_);
95 EXPECT_CALL(notifier, FireObservers(kChangedPref)).Times(1);
96 notifier.OnPreferenceChanged(kChangedPref);
97}
98
99TEST_F(PrefNotifierTest, OnInitializationCompleted) {
100 MockPrefNotifier notifier(&pref_service_);
[email protected]a6a7ced2012-11-01 17:24:18101 MockPrefInitObserver observer;
102 notifier.AddInitObserver(
103 base::Bind(&MockPrefInitObserver::OnInitializationCompleted,
104 base::Unretained(&observer)));
105 EXPECT_CALL(observer, OnInitializationCompleted(true));
[email protected]845b43a82011-05-11 10:14:43106 notifier.OnInitializationCompleted(true);
[email protected]acd78969c2010-12-08 09:49:11107}
108
109TEST_F(PrefNotifierTest, AddAndRemovePrefObservers) {
110 const char pref_name[] = "homepage";
111 const char pref_name2[] = "proxy";
112
113 MockPrefNotifier notifier(&pref_service_);
114 notifier.AddPrefObserver(pref_name, &obs1_);
115 ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
116 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
117 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
118 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
119
120 // Re-adding the same observer for the same pref doesn't change anything.
121 // Skip this in debug mode, since it hits a DCHECK and death tests aren't
122 // thread-safe.
[email protected]20960e072011-09-20 20:59:01123#if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
[email protected]acd78969c2010-12-08 09:49:11124 notifier.AddPrefObserver(pref_name, &obs1_);
125 ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
126 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
127 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
128 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
[email protected]20960e072011-09-20 20:59:01129#endif
[email protected]acd78969c2010-12-08 09:49:11130
131 // Ensure that we can add the same observer to a different pref.
132 notifier.AddPrefObserver(pref_name2, &obs1_);
133 ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
134 ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
135 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
136 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
137
138 // Ensure that we can add another observer to the same pref.
139 notifier.AddPrefObserver(pref_name, &obs2_);
140 ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs1_));
141 ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
142 ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
143 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
144
145 // Ensure that we can remove all observers, and that removing a non-existent
146 // observer is harmless.
147 notifier.RemovePrefObserver(pref_name, &obs1_);
148 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
149 ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
150 ASSERT_EQ(1u, notifier.CountObserver(pref_name, &obs2_));
151 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
152
153 notifier.RemovePrefObserver(pref_name, &obs2_);
154 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
155 ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
156 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
157 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
158
159 notifier.RemovePrefObserver(pref_name, &obs1_);
160 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
161 ASSERT_EQ(1u, notifier.CountObserver(pref_name2, &obs1_));
162 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
163 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
164
165 notifier.RemovePrefObserver(pref_name2, &obs1_);
166 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs1_));
167 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs1_));
168 ASSERT_EQ(0u, notifier.CountObserver(pref_name, &obs2_));
169 ASSERT_EQ(0u, notifier.CountObserver(pref_name2, &obs2_));
170}
171
172TEST_F(PrefNotifierTest, FireObservers) {
[email protected]a6a7ced2012-11-01 17:24:18173 TestingPrefNotifierImpl notifier(&pref_service_);
[email protected]acd78969c2010-12-08 09:49:11174 notifier.AddPrefObserver(kChangedPref, &obs1_);
175 notifier.AddPrefObserver(kUnchangedPref, &obs1_);
176
[email protected]a6a7ced2012-11-01 17:24:18177 EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref));
178 EXPECT_CALL(obs2_, OnPreferenceChanged(_, _)).Times(0);
[email protected]acd78969c2010-12-08 09:49:11179 notifier.OnPreferenceChanged(kChangedPref);
180 Mock::VerifyAndClearExpectations(&obs1_);
181 Mock::VerifyAndClearExpectations(&obs2_);
182
183 notifier.AddPrefObserver(kChangedPref, &obs2_);
184 notifier.AddPrefObserver(kUnchangedPref, &obs2_);
185
[email protected]a6a7ced2012-11-01 17:24:18186 EXPECT_CALL(obs1_, OnPreferenceChanged(&pref_service_, kChangedPref));
187 EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
[email protected]acd78969c2010-12-08 09:49:11188 notifier.OnPreferenceChanged(kChangedPref);
189 Mock::VerifyAndClearExpectations(&obs1_);
190 Mock::VerifyAndClearExpectations(&obs2_);
191
192 // Make sure removing an observer from one pref doesn't affect anything else.
193 notifier.RemovePrefObserver(kChangedPref, &obs1_);
194
[email protected]a6a7ced2012-11-01 17:24:18195 EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0);
196 EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
[email protected]acd78969c2010-12-08 09:49:11197 notifier.OnPreferenceChanged(kChangedPref);
198 Mock::VerifyAndClearExpectations(&obs1_);
199 Mock::VerifyAndClearExpectations(&obs2_);
200
201 // Make sure removing an observer entirely doesn't affect anything else.
202 notifier.RemovePrefObserver(kUnchangedPref, &obs1_);
203
[email protected]a6a7ced2012-11-01 17:24:18204 EXPECT_CALL(obs1_, OnPreferenceChanged(_, _)).Times(0);
205 EXPECT_CALL(obs2_, OnPreferenceChanged(&pref_service_, kChangedPref));
[email protected]acd78969c2010-12-08 09:49:11206 notifier.OnPreferenceChanged(kChangedPref);
207 Mock::VerifyAndClearExpectations(&obs1_);
208 Mock::VerifyAndClearExpectations(&obs2_);
209
210 notifier.RemovePrefObserver(kChangedPref, &obs2_);
211 notifier.RemovePrefObserver(kUnchangedPref, &obs2_);
212}
213
214} // namespace