1 // Copyright (c) 2011 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 "base/basictypes.h"
6 #include "base/memory/ref_counted.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/values.h"
9 #include "chrome/browser/extensions/extension_pref_value_map.h"
10 #include "chrome/common/pref_store_observer_mock.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace {
15 const char kExt1[] = "ext1";
16 const char kExt2[] = "ext2";
17 const char kExt3[] = "ext3";
18
19 const char kPref1[] = "path1.subpath";
20 const char kPref2[] = "path2";
21 const char kPref3[] = "path3";
22 const char kPref4[] = "path4";
23 } // namespace
24
CreateVal(const char * str)25 static Value* CreateVal(const char* str) {
26 return Value::CreateStringValue(str);
27 }
28
CreateTime(int64 t)29 static base::Time CreateTime(int64 t) {
30 return base::Time::FromInternalValue(t);
31 }
32
33 template <typename BASECLASS>
34 class ExtensionPrefValueMapTestBase : public BASECLASS {
35 public:
36 // Returns an empty string if the key is not set.
GetValue(const char * key,bool incognito) const37 std::string GetValue(const char * key, bool incognito) const {
38 const Value *value = epvm_.GetEffectivePrefValue(key, incognito, NULL);
39 std::string string_value = "";
40 if (value)
41 value->GetAsString(&string_value);
42 return string_value;
43 }
44
45 protected:
46 ExtensionPrefValueMap epvm_;
47 };
48
49 class ExtensionPrefValueMapTest
50 : public ExtensionPrefValueMapTestBase<testing::Test> {
51 };
52
53 // A gmock-ified implementation of PrefStore::Observer.
54 class ExtensionPrefValueMapObserverMock
55 : public ExtensionPrefValueMap::Observer {
56 public:
ExtensionPrefValueMapObserverMock()57 ExtensionPrefValueMapObserverMock() {}
~ExtensionPrefValueMapObserverMock()58 virtual ~ExtensionPrefValueMapObserverMock() {}
59
60 MOCK_METHOD1(OnPrefValueChanged, void(const std::string&));
61 MOCK_METHOD0(OnInitializationCompleted, void());
62 MOCK_METHOD0(OnExtensionPrefValueMapDestruction, void());
63
64 private:
65 DISALLOW_COPY_AND_ASSIGN(ExtensionPrefValueMapObserverMock);
66 };
67
TEST_F(ExtensionPrefValueMapTest,SetAndGetPrefValue)68 TEST_F(ExtensionPrefValueMapTest, SetAndGetPrefValue) {
69 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
70 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
71 EXPECT_EQ("val1", GetValue(kPref1, false));
72 };
73
TEST_F(ExtensionPrefValueMapTest,GetNotSetPrefValue)74 TEST_F(ExtensionPrefValueMapTest, GetNotSetPrefValue) {
75 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
76 EXPECT_EQ("", GetValue(kPref1, false));
77 };
78
79 // Make sure the last-installed extension wins for each preference.
TEST_F(ExtensionPrefValueMapTest,Override)80 TEST_F(ExtensionPrefValueMapTest, Override) {
81 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
82 epvm_.RegisterExtension(kExt2, CreateTime(20), true);
83 epvm_.RegisterExtension(kExt3, CreateTime(30), true);
84
85 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
86 epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2"));
87 epvm_.SetExtensionPref(kExt3, kPref1, false, CreateVal("val3"));
88
89 epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val4"));
90 epvm_.SetExtensionPref(kExt2, kPref2, false, CreateVal("val5"));
91
92 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val6"));
93 epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val7"));
94 epvm_.SetExtensionPref(kExt1, kPref3, false, CreateVal("val8"));
95
96 EXPECT_EQ("val3", GetValue(kPref1, false));
97 EXPECT_EQ("val5", GetValue(kPref2, false));
98 EXPECT_EQ("val8", GetValue(kPref3, false));
99 }
100
TEST_F(ExtensionPrefValueMapTest,OverrideChecks)101 TEST_F(ExtensionPrefValueMapTest, OverrideChecks) {
102 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
103 epvm_.RegisterExtension(kExt2, CreateTime(20), true);
104 epvm_.RegisterExtension(kExt3, CreateTime(30), true);
105
106 EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt1, kPref1, false));
107 EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt2, kPref1, false));
108 EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt3, kPref1, false));
109 EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt1, kPref1, false));
110 EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt2, kPref1, false));
111 EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt3, kPref1, false));
112
113 epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val1"));
114
115 EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt1, kPref1, false));
116 EXPECT_TRUE(epvm_.DoesExtensionControlPref(kExt2, kPref1, false));
117 EXPECT_FALSE(epvm_.DoesExtensionControlPref(kExt3, kPref1, false));
118 EXPECT_FALSE(epvm_.CanExtensionControlPref(kExt1, kPref1, false));
119 EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt2, kPref1, false));
120 EXPECT_TRUE(epvm_.CanExtensionControlPref(kExt3, kPref1, false));
121 }
122
TEST_F(ExtensionPrefValueMapTest,SetAndGetPrefValueIncognito)123 TEST_F(ExtensionPrefValueMapTest, SetAndGetPrefValueIncognito) {
124 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
125 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
126 EXPECT_EQ("val1", GetValue(kPref1, true));
127 }
128
TEST_F(ExtensionPrefValueMapTest,UninstallOnlyExtension)129 TEST_F(ExtensionPrefValueMapTest, UninstallOnlyExtension) {
130 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
131 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
132 epvm_.UnregisterExtension(kExt1);
133
134 EXPECT_EQ("", GetValue(kPref1, false));
135 }
136
137 // Tests uninstalling an extension that wasn't winning for any preferences.
TEST_F(ExtensionPrefValueMapTest,UninstallIrrelevantExtension)138 TEST_F(ExtensionPrefValueMapTest, UninstallIrrelevantExtension) {
139 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
140 epvm_.RegisterExtension(kExt2, CreateTime(10), true);
141
142 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
143 epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2"));
144
145 epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val3"));
146 epvm_.SetExtensionPref(kExt2, kPref2, false, CreateVal("val4"));
147
148 epvm_.UnregisterExtension(kExt1);
149
150 EXPECT_EQ("val2", GetValue(kPref1, false));
151 EXPECT_EQ("val4", GetValue(kPref2, false));
152 }
153
154 // Tests uninstalling an extension that was winning for all preferences.
TEST_F(ExtensionPrefValueMapTest,UninstallExtensionFromTop)155 TEST_F(ExtensionPrefValueMapTest, UninstallExtensionFromTop) {
156 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
157 epvm_.RegisterExtension(kExt2, CreateTime(20), true);
158 epvm_.RegisterExtension(kExt3, CreateTime(30), true);
159
160 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
161 epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2"));
162 epvm_.SetExtensionPref(kExt3, kPref1, false, CreateVal("val3"));
163
164 epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val4"));
165 epvm_.SetExtensionPref(kExt3, kPref2, false, CreateVal("val5"));
166
167 epvm_.UnregisterExtension(kExt3);
168
169 EXPECT_EQ("val2", GetValue(kPref1, false));
170 EXPECT_EQ("val4", GetValue(kPref2, false));
171 }
172
173 // Tests uninstalling an extension that was winning for only some preferences.
TEST_F(ExtensionPrefValueMapTest,UninstallExtensionFromMiddle)174 TEST_F(ExtensionPrefValueMapTest, UninstallExtensionFromMiddle) {
175 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
176 epvm_.RegisterExtension(kExt2, CreateTime(20), true);
177 epvm_.RegisterExtension(kExt3, CreateTime(30), true);
178
179 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
180 epvm_.SetExtensionPref(kExt2, kPref1, false, CreateVal("val2"));
181 epvm_.SetExtensionPref(kExt3, kPref1, false, CreateVal("val3"));
182
183 epvm_.SetExtensionPref(kExt1, kPref2, false, CreateVal("val4"));
184 epvm_.SetExtensionPref(kExt2, kPref2, false, CreateVal("val5"));
185
186 epvm_.SetExtensionPref(kExt1, kPref3, false, CreateVal("val6"));
187
188 epvm_.SetExtensionPref(kExt2, kPref4, false, CreateVal("val7"));
189
190 epvm_.UnregisterExtension(kExt2);
191
192 EXPECT_EQ("val3", GetValue(kPref1, false));
193 EXPECT_EQ("val4", GetValue(kPref2, false));
194 EXPECT_EQ("val6", GetValue(kPref3, false));
195 EXPECT_EQ("", GetValue(kPref4, false));
196 }
197
198 // Tests triggering of notifications to registered observers.
TEST_F(ExtensionPrefValueMapTest,NotifyWhenNeeded)199 TEST_F(ExtensionPrefValueMapTest, NotifyWhenNeeded) {
200 using testing::_;
201 using testing::Mock;
202 using testing::StrEq;
203
204 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
205
206 ExtensionPrefValueMapObserverMock observer;
207 epvm_.AddObserver(&observer);
208
209 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
210 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
211 Mock::VerifyAndClearExpectations(&observer);
212
213 // Write the same value again.
214 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))).Times(0);
215 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
216 Mock::VerifyAndClearExpectations(&observer);
217
218 // Override incognito value.
219 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
220 epvm_.SetExtensionPref(kExt1, kPref1, true, CreateVal("val2"));
221 Mock::VerifyAndClearExpectations(&observer);
222
223 // Override non-incognito value.
224 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
225 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val3"));
226 Mock::VerifyAndClearExpectations(&observer);
227
228 // Disable.
229 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
230 epvm_.SetExtensionState(kExt1, false);
231 Mock::VerifyAndClearExpectations(&observer);
232
233 // Enable.
234 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
235 epvm_.SetExtensionState(kExt1, true);
236 Mock::VerifyAndClearExpectations(&observer);
237
238 // Uninstall
239 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1)));
240 epvm_.UnregisterExtension(kExt1);
241 Mock::VerifyAndClearExpectations(&observer);
242
243 epvm_.RemoveObserver(&observer);
244
245 // Write new value --> no notification after removing observer.
246 EXPECT_CALL(observer, OnPrefValueChanged(std::string(kPref1))).Times(0);
247 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
248 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val4"));
249 Mock::VerifyAndClearExpectations(&observer);
250 }
251
252 // Tests disabling an extension.
TEST_F(ExtensionPrefValueMapTest,DisableExt)253 TEST_F(ExtensionPrefValueMapTest, DisableExt) {
254 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
255
256 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
257 epvm_.SetExtensionState(kExt1, false);
258 EXPECT_EQ("", GetValue(kPref1, false));
259 }
260
261 // Tests disabling and reenabling an extension.
TEST_F(ExtensionPrefValueMapTest,ReenableExt)262 TEST_F(ExtensionPrefValueMapTest, ReenableExt) {
263 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
264
265 epvm_.SetExtensionPref(kExt1, kPref1, false, CreateVal("val1"));
266 epvm_.SetExtensionState(kExt1, false);
267 epvm_.SetExtensionState(kExt1, true);
268 EXPECT_EQ("val1", GetValue(kPref1, false));
269 }
270
271 struct OverrideIncognitoTestCase {
OverrideIncognitoTestCaseOverrideIncognitoTestCase272 OverrideIncognitoTestCase(int val_ext1_regular,
273 int val_ext1_incognito,
274 int val_ext2_regular,
275 int val_ext2_incognito,
276 int effective_value_regular,
277 int effective_value_incognito)
278 : val_ext1_regular_(val_ext1_regular),
279 val_ext1_incognito_(val_ext1_incognito),
280 val_ext2_regular_(val_ext2_regular),
281 val_ext2_incognito_(val_ext2_incognito),
282 effective_value_regular_(effective_value_regular),
283 effective_value_incognito_(effective_value_incognito) {}
284
285 int val_ext1_regular_; // pref value of extension 1
286 int val_ext1_incognito_; // pref value of extension 1 incognito
287 int val_ext2_regular_; // pref value of extension 2
288 int val_ext2_incognito_; // pref value of extension 2 incognito
289 int effective_value_regular_; // desired winner regular
290 int effective_value_incognito_; // desired winner incognito
291 };
292
293 class ExtensionPrefValueMapTestIncognitoTests
294 : public ExtensionPrefValueMapTestBase<
295 testing::TestWithParam<OverrideIncognitoTestCase> > {
296 };
297
TEST_P(ExtensionPrefValueMapTestIncognitoTests,OverrideIncognito)298 TEST_P(ExtensionPrefValueMapTestIncognitoTests, OverrideIncognito) {
299 OverrideIncognitoTestCase test = GetParam();
300 const char* strings[] = {
301 "undefined",
302 "val1",
303 "val2",
304 "val3",
305 "val4"
306 };
307
308 epvm_.RegisterExtension(kExt1, CreateTime(10), true);
309 epvm_.RegisterExtension(kExt2, CreateTime(20), true);
310 if (test.val_ext1_regular_) {
311 epvm_.SetExtensionPref(kExt1, kPref1, false,
312 CreateVal(strings[test.val_ext1_regular_]));
313 }
314 if (test.val_ext1_incognito_) {
315 epvm_.SetExtensionPref(kExt1, kPref1, true,
316 CreateVal(strings[test.val_ext1_incognito_]));
317 }
318 if (test.val_ext2_regular_) {
319 epvm_.SetExtensionPref(kExt2, kPref1, false,
320 CreateVal(strings[test.val_ext2_regular_]));
321 }
322 if (test.val_ext2_incognito_) {
323 epvm_.SetExtensionPref(kExt2, kPref1, true,
324 CreateVal(strings[test.val_ext2_incognito_]));
325 }
326 std::string actual;
327 EXPECT_EQ(strings[test.effective_value_regular_], GetValue(kPref1, false));
328 EXPECT_EQ(strings[test.effective_value_incognito_], GetValue(kPref1, true));
329 epvm_.UnregisterExtension(kExt1);
330 epvm_.UnregisterExtension(kExt2);
331 }
332
333 INSTANTIATE_TEST_CASE_P(
334 ExtensionPrefValueMapTestIncognitoTestsInstance,
335 ExtensionPrefValueMapTestIncognitoTests,
336 testing::Values(
337 // e.g. (1, 0, 0, 4, 1, 4), means:
338 // ext1 regular is set to "val1", ext2 incognito is set to "val4"
339 // --> the winning regular value is "val1", the winning incognito
340 // value is "val4".
341 OverrideIncognitoTestCase(1, 0, 0, 0, 1, 1),
342 OverrideIncognitoTestCase(1, 2, 0, 0, 1, 2),
343 OverrideIncognitoTestCase(1, 0, 3, 0, 3, 3),
344 OverrideIncognitoTestCase(1, 0, 0, 4, 1, 4),
345 // The last 3 in the following line is intentional!
346 OverrideIncognitoTestCase(1, 2, 3, 0, 3, 3),
347 OverrideIncognitoTestCase(1, 2, 0, 4, 1, 4),
348 OverrideIncognitoTestCase(1, 2, 3, 4, 3, 4)));
349