1 // Copyright 2013 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.
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/prefs/mock_pref_change_callback.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/./extension_prefs_unittest.h"
12 #include "chrome/browser/extensions/api/content_settings/content_settings_service.h"
13 #include "chrome/browser/extensions/api/preference/preference_api.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "components/user_prefs/pref_registry_syncable.h"
16 #include "extensions/browser/extension_prefs.h"
17 #include "extensions/common/extension.h"
18 #include "testing/gtest/include/gtest/gtest.h"
22 namespace extensions {
26 const char kPref1[] = "path1.subpath";
27 const char kPref2[] = "path2";
28 const char kPref3[] = "path3";
29 const char kPref4[] = "path4";
31 // Default values in case an extension pref value is not overridden.
32 const char kDefaultPref1[] = "default pref 1";
33 const char kDefaultPref2[] = "default pref 2";
34 const char kDefaultPref3[] = "default pref 3";
35 const char kDefaultPref4[] = "default pref 4";
39 // An implementation of the PreferenceAPI which returns the ExtensionPrefs and
40 // ExtensionPrefValueMap from the TestExtensionPrefs, rather than from a
41 // profile (which we don't create in unittests).
42 class TestPreferenceAPI : public PreferenceAPIBase {
44 explicit TestPreferenceAPI(TestExtensionPrefs* test_extension_prefs,
45 ContentSettingsService* content_settings)
46 : test_extension_prefs_(test_extension_prefs),
47 content_settings_(content_settings) {}
48 ~TestPreferenceAPI() {}
51 // PreferenceAPIBase implementation.
52 virtual ExtensionPrefs* extension_prefs() OVERRIDE {
53 return test_extension_prefs_->prefs();
55 virtual ExtensionPrefValueMap* extension_pref_value_map() OVERRIDE {
56 return test_extension_prefs_->extension_pref_value_map();
58 virtual scoped_refptr<ContentSettingsStore> content_settings_store()
60 return content_settings_->content_settings_store();
63 TestExtensionPrefs* test_extension_prefs_;
64 ContentSettingsService* content_settings_;
66 DISALLOW_COPY_AND_ASSIGN(TestPreferenceAPI);
69 class ExtensionControlledPrefsTest : public PrefsPrepopulatedTestBase {
71 ExtensionControlledPrefsTest();
72 virtual ~ExtensionControlledPrefsTest();
74 virtual void RegisterPreferences(user_prefs::PrefRegistrySyncable* registry)
76 void InstallExtensionControlledPref(Extension* extension,
77 const std::string& key,
79 void InstallExtensionControlledPrefIncognito(Extension* extension,
80 const std::string& key,
82 void InstallExtensionControlledPrefIncognitoSessionOnly(
84 const std::string& key,
86 void InstallExtension(Extension* extension);
87 void UninstallExtension(const std::string& extension_id);
89 scoped_refptr<ContentSettingsStore> content_settings_store() {
90 return content_settings_->content_settings_store();
94 void EnsureExtensionInstalled(Extension* extension);
95 void EnsureExtensionUninstalled(const std::string& extension_id);
97 TestingProfile profile_;
98 ContentSettingsService* content_settings_;
99 TestPreferenceAPI test_preference_api_;
102 ExtensionControlledPrefsTest::ExtensionControlledPrefsTest()
103 : PrefsPrepopulatedTestBase(),
104 content_settings_(ContentSettingsService::Get(&profile_)),
105 test_preference_api_(&prefs_, content_settings_) {
106 prefs_.prefs()->AddObserver(content_settings_);
109 ExtensionControlledPrefsTest::~ExtensionControlledPrefsTest() {
112 void ExtensionControlledPrefsTest::RegisterPreferences(
113 user_prefs::PrefRegistrySyncable* registry) {
114 registry->RegisterStringPref(
115 kPref1, kDefaultPref1, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
116 registry->RegisterStringPref(
117 kPref2, kDefaultPref2, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
118 registry->RegisterStringPref(
119 kPref3, kDefaultPref3, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
120 registry->RegisterStringPref(
121 kPref4, kDefaultPref4, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
124 void ExtensionControlledPrefsTest::InstallExtensionControlledPref(
125 Extension* extension,
126 const std::string& key,
127 base::Value* value) {
128 EnsureExtensionInstalled(extension);
129 test_preference_api_.SetExtensionControlledPref(
130 extension->id(), key, kExtensionPrefsScopeRegular, value);
133 void ExtensionControlledPrefsTest::InstallExtensionControlledPrefIncognito(
134 Extension* extension,
135 const std::string& key,
136 base::Value* value) {
137 EnsureExtensionInstalled(extension);
138 test_preference_api_.SetExtensionControlledPref(
139 extension->id(), key, kExtensionPrefsScopeIncognitoPersistent, value);
142 void ExtensionControlledPrefsTest::
143 InstallExtensionControlledPrefIncognitoSessionOnly(Extension* extension,
144 const std::string& key,
145 base::Value* value) {
146 EnsureExtensionInstalled(extension);
147 test_preference_api_.SetExtensionControlledPref(
148 extension->id(), key, kExtensionPrefsScopeIncognitoSessionOnly, value);
151 void ExtensionControlledPrefsTest::InstallExtension(Extension* extension) {
152 EnsureExtensionInstalled(extension);
155 void ExtensionControlledPrefsTest::UninstallExtension(
156 const std::string& extension_id) {
157 EnsureExtensionUninstalled(extension_id);
160 void ExtensionControlledPrefsTest::EnsureExtensionInstalled(
161 Extension* extension) {
162 // Install extension the first time a preference is set for it.
163 Extension* extensions[] = { extension1(),
167 for (size_t i = 0; i < kNumInstalledExtensions; ++i) {
168 if (extension == extensions[i] && !installed_[i]) {
169 prefs()->OnExtensionInstalled(extension,
172 syncer::StringOrdinal(),
174 prefs()->SetIsIncognitoEnabled(extension->id(), true);
175 installed_[i] = true;
181 void ExtensionControlledPrefsTest::EnsureExtensionUninstalled(
182 const std::string& extension_id) {
183 Extension* extensions[] = { extension1(),
187 for (size_t i = 0; i < kNumInstalledExtensions; ++i) {
188 if (extensions[i]->id() == extension_id) {
189 installed_[i] = false;
193 prefs()->OnExtensionUninstalled(extension_id, Manifest::INTERNAL, false);
196 class ControlledPrefsInstallOneExtension
197 : public ExtensionControlledPrefsTest {
198 virtual void Initialize() OVERRIDE {
199 InstallExtensionControlledPref(extension1(),
201 new base::StringValue("val1"));
203 virtual void Verify() OVERRIDE {
204 std::string actual = prefs()->pref_service()->GetString(kPref1);
205 EXPECT_EQ("val1", actual);
208 TEST_F(ControlledPrefsInstallOneExtension,
209 ControlledPrefsInstallOneExtension) { }
211 // Check that we do not forget persistent incognito values after a reload.
212 class ControlledPrefsInstallIncognitoPersistent
213 : public ExtensionControlledPrefsTest {
215 virtual void Initialize() OVERRIDE {
216 InstallExtensionControlledPref(
217 extension1(), kPref1, new base::StringValue("val1"));
218 InstallExtensionControlledPrefIncognito(
219 extension1(), kPref1, new base::StringValue("val2"));
220 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
221 std::string actual = incog_prefs->GetString(kPref1);
222 EXPECT_EQ("val2", actual);
225 virtual void Verify() OVERRIDE {
226 // Main pref service shall see only non-incognito settings.
227 std::string actual = prefs()->pref_service()->GetString(kPref1);
228 EXPECT_EQ("val1", actual);
229 // Incognito pref service shall see incognito values.
230 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
231 actual = incog_prefs->GetString(kPref1);
232 EXPECT_EQ("val2", actual);
235 TEST_F(ControlledPrefsInstallIncognitoPersistent,
236 ControlledPrefsInstallIncognitoPersistent) { }
238 // Check that we forget 'session only' incognito values after a reload.
239 class ControlledPrefsInstallIncognitoSessionOnly
240 : public ExtensionControlledPrefsTest {
242 ControlledPrefsInstallIncognitoSessionOnly() : iteration_(0) {}
244 virtual void Initialize() OVERRIDE {
245 InstallExtensionControlledPref(
246 extension1(), kPref1, new base::StringValue("val1"));
247 InstallExtensionControlledPrefIncognitoSessionOnly(
248 extension1(), kPref1, new base::StringValue("val2"));
249 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
250 std::string actual = incog_prefs->GetString(kPref1);
251 EXPECT_EQ("val2", actual);
253 virtual void Verify() OVERRIDE {
254 // Main pref service shall see only non-incognito settings.
255 std::string actual = prefs()->pref_service()->GetString(kPref1);
256 EXPECT_EQ("val1", actual);
257 // Incognito pref service shall see session-only incognito values only
258 // during first run. Once the pref service was reloaded, all values shall be
260 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
261 actual = incog_prefs->GetString(kPref1);
262 if (iteration_ == 0) {
263 EXPECT_EQ("val2", actual);
265 EXPECT_EQ("val1", actual);
271 TEST_F(ControlledPrefsInstallIncognitoSessionOnly,
272 ControlledPrefsInstallIncognitoSessionOnly) { }
274 class ControlledPrefsUninstallExtension : public ExtensionControlledPrefsTest {
275 virtual void Initialize() OVERRIDE {
276 InstallExtensionControlledPref(
277 extension1(), kPref1, new base::StringValue("val1"));
278 InstallExtensionControlledPref(
279 extension1(), kPref2, new base::StringValue("val2"));
280 scoped_refptr<ContentSettingsStore> store = content_settings_store();
281 ContentSettingsPattern pattern =
282 ContentSettingsPattern::FromString("http://[*.]example.com");
283 store->SetExtensionContentSetting(extension1()->id(),
285 CONTENT_SETTINGS_TYPE_IMAGES,
287 CONTENT_SETTING_BLOCK,
288 kExtensionPrefsScopeRegular);
290 UninstallExtension(extension1()->id());
292 virtual void Verify() OVERRIDE {
293 EXPECT_FALSE(prefs()->HasPrefForExtension(extension1()->id()));
296 actual = prefs()->pref_service()->GetString(kPref1);
297 EXPECT_EQ(kDefaultPref1, actual);
298 actual = prefs()->pref_service()->GetString(kPref2);
299 EXPECT_EQ(kDefaultPref2, actual);
302 TEST_F(ControlledPrefsUninstallExtension,
303 ControlledPrefsUninstallExtension) { }
305 // Tests triggering of notifications to registered observers.
306 class ControlledPrefsNotifyWhenNeeded : public ExtensionControlledPrefsTest {
307 virtual void Initialize() OVERRIDE {
310 using testing::StrEq;
312 MockPrefChangeCallback observer(prefs()->pref_service());
313 PrefChangeRegistrar registrar;
314 registrar.Init(prefs()->pref_service());
315 registrar.Add(kPref1, observer.GetCallback());
317 MockPrefChangeCallback incognito_observer(prefs()->pref_service());
318 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
319 PrefChangeRegistrar incognito_registrar;
320 incognito_registrar.Init(incog_prefs.get());
321 incognito_registrar.Add(kPref1, incognito_observer.GetCallback());
323 // Write value and check notification.
324 EXPECT_CALL(observer, OnPreferenceChanged(_));
325 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
326 InstallExtensionControlledPref(extension1(), kPref1,
327 new base::StringValue("https://www.chromium.org"));
328 Mock::VerifyAndClearExpectations(&observer);
329 Mock::VerifyAndClearExpectations(&incognito_observer);
332 EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
333 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_)).Times(0);
334 InstallExtensionControlledPref(extension1(), kPref1,
335 new base::StringValue("https://www.chromium.org"));
336 Mock::VerifyAndClearExpectations(&observer);
337 Mock::VerifyAndClearExpectations(&incognito_observer);
340 EXPECT_CALL(observer, OnPreferenceChanged(_));
341 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
342 InstallExtensionControlledPref(extension1(), kPref1,
343 new base::StringValue("chrome://newtab"));
344 Mock::VerifyAndClearExpectations(&observer);
345 Mock::VerifyAndClearExpectations(&incognito_observer);
346 // Change only incognito persistent value.
347 EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
348 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
349 InstallExtensionControlledPrefIncognito(extension1(), kPref1,
350 new base::StringValue("chrome://newtab2"));
351 Mock::VerifyAndClearExpectations(&observer);
352 Mock::VerifyAndClearExpectations(&incognito_observer);
354 // Change only incognito session-only value.
355 EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
356 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
357 InstallExtensionControlledPrefIncognito(extension1(), kPref1,
358 new base::StringValue("chrome://newtab3"));
359 Mock::VerifyAndClearExpectations(&observer);
360 Mock::VerifyAndClearExpectations(&incognito_observer);
363 EXPECT_CALL(observer, OnPreferenceChanged(_));
364 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
365 UninstallExtension(extension1()->id());
366 Mock::VerifyAndClearExpectations(&observer);
367 Mock::VerifyAndClearExpectations(&incognito_observer);
369 registrar.Remove(kPref1);
370 incognito_registrar.Remove(kPref1);
372 virtual void Verify() OVERRIDE {
373 std::string actual = prefs()->pref_service()->GetString(kPref1);
374 EXPECT_EQ(kDefaultPref1, actual);
377 TEST_F(ControlledPrefsNotifyWhenNeeded,
378 ControlledPrefsNotifyWhenNeeded) { }
380 // Tests disabling an extension.
381 class ControlledPrefsDisableExtension : public ExtensionControlledPrefsTest {
382 virtual void Initialize() OVERRIDE {
383 InstallExtensionControlledPref(
384 extension1(), kPref1, new base::StringValue("val1"));
385 std::string actual = prefs()->pref_service()->GetString(kPref1);
386 EXPECT_EQ("val1", actual);
387 prefs()->SetExtensionState(extension1()->id(), Extension::DISABLED);
389 virtual void Verify() OVERRIDE {
390 std::string actual = prefs()->pref_service()->GetString(kPref1);
391 EXPECT_EQ(kDefaultPref1, actual);
394 TEST_F(ControlledPrefsDisableExtension, ControlledPrefsDisableExtension) { }
396 // Tests disabling and reenabling an extension.
397 class ControlledPrefsReenableExtension : public ExtensionControlledPrefsTest {
398 virtual void Initialize() OVERRIDE {
399 InstallExtensionControlledPref(
400 extension1(), kPref1, new base::StringValue("val1"));
401 prefs()->SetExtensionState(extension1()->id(), Extension::DISABLED);
402 prefs()->SetExtensionState(extension1()->id(), Extension::ENABLED);
404 virtual void Verify() OVERRIDE {
405 std::string actual = prefs()->pref_service()->GetString(kPref1);
406 EXPECT_EQ("val1", actual);
409 TEST_F(ControlledPrefsDisableExtension, ControlledPrefsReenableExtension) { }
411 // Mock class to test whether objects are deleted correctly.
412 class MockStringValue : public base::StringValue {
414 explicit MockStringValue(const std::string& in_value)
415 : base::StringValue(in_value) {
417 virtual ~MockStringValue() {
420 MOCK_METHOD0(Die, void());
423 class ControlledPrefsSetExtensionControlledPref
424 : public ExtensionControlledPrefsTest {
426 virtual void Initialize() OVERRIDE {
427 MockStringValue* v1 = new MockStringValue("https://www.chromium.org");
428 MockStringValue* v2 = new MockStringValue("https://www.chromium.org");
429 MockStringValue* v1i = new MockStringValue("https://www.chromium.org");
430 MockStringValue* v2i = new MockStringValue("https://www.chromium.org");
431 // Ownership is taken, value shall not be deleted.
432 EXPECT_CALL(*v1, Die()).Times(0);
433 EXPECT_CALL(*v1i, Die()).Times(0);
434 InstallExtensionControlledPref(extension1(), kPref1, v1);
435 InstallExtensionControlledPrefIncognito(extension1(), kPref1, v1i);
436 testing::Mock::VerifyAndClearExpectations(v1);
437 testing::Mock::VerifyAndClearExpectations(v1i);
438 // Make sure there is no memory leak and both values are deleted.
439 EXPECT_CALL(*v1, Die()).Times(1);
440 EXPECT_CALL(*v1i, Die()).Times(1);
441 EXPECT_CALL(*v2, Die()).Times(1);
442 EXPECT_CALL(*v2i, Die()).Times(1);
443 InstallExtensionControlledPref(extension1(), kPref1, v2);
444 InstallExtensionControlledPrefIncognito(extension1(), kPref1, v2i);
445 prefs_.RecreateExtensionPrefs();
446 testing::Mock::VerifyAndClearExpectations(v1);
447 testing::Mock::VerifyAndClearExpectations(v1i);
448 testing::Mock::VerifyAndClearExpectations(v2);
449 testing::Mock::VerifyAndClearExpectations(v2i);
452 virtual void Verify() OVERRIDE {
455 TEST_F(ControlledPrefsSetExtensionControlledPref,
456 ControlledPrefsSetExtensionControlledPref) { }
458 // Tests that the switches::kDisableExtensions command-line flag prevents
459 // extension controlled preferences from being enacted.
460 class ControlledPrefsDisableExtensions : public ExtensionControlledPrefsTest {
462 ControlledPrefsDisableExtensions()
464 virtual ~ControlledPrefsDisableExtensions() {}
465 virtual void Initialize() OVERRIDE {
466 InstallExtensionControlledPref(
467 extension1(), kPref1, new base::StringValue("val1"));
468 // This becomes only active in the second verification phase.
469 prefs_.set_extensions_disabled(true);
471 virtual void Verify() OVERRIDE {
472 std::string actual = prefs()->pref_service()->GetString(kPref1);
473 if (iteration_ == 0) {
474 EXPECT_EQ("val1", actual);
477 EXPECT_EQ(kDefaultPref1, actual);
484 TEST_F(ControlledPrefsDisableExtensions, ControlledPrefsDisableExtensions) { }
486 } // namespace extensions