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/pref_registry/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 ExtensionPrefs* extension_prefs() override {
53 return test_extension_prefs_->prefs();
55 ExtensionPrefValueMap* extension_pref_value_map() override {
56 return test_extension_prefs_->extension_pref_value_map();
58 scoped_refptr<ContentSettingsStore> content_settings_store() override {
59 return content_settings_->content_settings_store();
62 TestExtensionPrefs* test_extension_prefs_;
63 ContentSettingsService* content_settings_;
65 DISALLOW_COPY_AND_ASSIGN(TestPreferenceAPI);
68 class ExtensionControlledPrefsTest : public PrefsPrepopulatedTestBase {
70 ExtensionControlledPrefsTest();
71 ~ExtensionControlledPrefsTest() override;
73 void RegisterPreferences(user_prefs::PrefRegistrySyncable* registry) override;
74 void InstallExtensionControlledPref(Extension* extension,
75 const std::string& key,
77 void InstallExtensionControlledPrefIncognito(Extension* extension,
78 const std::string& key,
80 void InstallExtensionControlledPrefIncognitoSessionOnly(
82 const std::string& key,
84 void InstallExtension(Extension* extension);
85 void UninstallExtension(const std::string& extension_id);
87 scoped_refptr<ContentSettingsStore> content_settings_store() {
88 return content_settings_->content_settings_store();
92 void EnsureExtensionInstalled(Extension* extension);
93 void EnsureExtensionUninstalled(const std::string& extension_id);
95 TestingProfile profile_;
96 ContentSettingsService* content_settings_;
97 TestPreferenceAPI test_preference_api_;
100 ExtensionControlledPrefsTest::ExtensionControlledPrefsTest()
101 : PrefsPrepopulatedTestBase(),
102 content_settings_(ContentSettingsService::Get(&profile_)),
103 test_preference_api_(&prefs_, content_settings_) {
104 prefs_.prefs()->AddObserver(content_settings_);
107 ExtensionControlledPrefsTest::~ExtensionControlledPrefsTest() {
110 void ExtensionControlledPrefsTest::RegisterPreferences(
111 user_prefs::PrefRegistrySyncable* registry) {
112 registry->RegisterStringPref(
113 kPref1, kDefaultPref1, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
114 registry->RegisterStringPref(
115 kPref2, kDefaultPref2, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
116 registry->RegisterStringPref(
117 kPref3, kDefaultPref3, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
118 registry->RegisterStringPref(
119 kPref4, kDefaultPref4, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
122 void ExtensionControlledPrefsTest::InstallExtensionControlledPref(
123 Extension* extension,
124 const std::string& key,
125 base::Value* value) {
126 EnsureExtensionInstalled(extension);
127 test_preference_api_.SetExtensionControlledPref(
128 extension->id(), key, kExtensionPrefsScopeRegular, value);
131 void ExtensionControlledPrefsTest::InstallExtensionControlledPrefIncognito(
132 Extension* extension,
133 const std::string& key,
134 base::Value* value) {
135 EnsureExtensionInstalled(extension);
136 test_preference_api_.SetExtensionControlledPref(
137 extension->id(), key, kExtensionPrefsScopeIncognitoPersistent, value);
140 void ExtensionControlledPrefsTest::
141 InstallExtensionControlledPrefIncognitoSessionOnly(Extension* extension,
142 const std::string& key,
143 base::Value* value) {
144 EnsureExtensionInstalled(extension);
145 test_preference_api_.SetExtensionControlledPref(
146 extension->id(), key, kExtensionPrefsScopeIncognitoSessionOnly, value);
149 void ExtensionControlledPrefsTest::InstallExtension(Extension* extension) {
150 EnsureExtensionInstalled(extension);
153 void ExtensionControlledPrefsTest::UninstallExtension(
154 const std::string& extension_id) {
155 EnsureExtensionUninstalled(extension_id);
158 void ExtensionControlledPrefsTest::EnsureExtensionInstalled(
159 Extension* extension) {
160 // Install extension the first time a preference is set for it.
161 Extension* extensions[] = { extension1(),
165 for (size_t i = 0; i < kNumInstalledExtensions; ++i) {
166 if (extension == extensions[i] && !installed_[i]) {
167 prefs()->OnExtensionInstalled(extension,
169 syncer::StringOrdinal(),
171 prefs()->SetIsIncognitoEnabled(extension->id(), true);
172 installed_[i] = true;
178 void ExtensionControlledPrefsTest::EnsureExtensionUninstalled(
179 const std::string& extension_id) {
180 Extension* extensions[] = { extension1(),
184 for (size_t i = 0; i < kNumInstalledExtensions; ++i) {
185 if (extensions[i]->id() == extension_id) {
186 installed_[i] = false;
190 prefs()->OnExtensionUninstalled(extension_id, Manifest::INTERNAL, false);
193 class ControlledPrefsInstallOneExtension
194 : public ExtensionControlledPrefsTest {
195 void Initialize() override {
196 InstallExtensionControlledPref(extension1(),
198 new base::StringValue("val1"));
200 void Verify() override {
201 std::string actual = prefs()->pref_service()->GetString(kPref1);
202 EXPECT_EQ("val1", actual);
205 TEST_F(ControlledPrefsInstallOneExtension,
206 ControlledPrefsInstallOneExtension) { }
208 // Check that we do not forget persistent incognito values after a reload.
209 class ControlledPrefsInstallIncognitoPersistent
210 : public ExtensionControlledPrefsTest {
212 void Initialize() override {
213 InstallExtensionControlledPref(
214 extension1(), kPref1, new base::StringValue("val1"));
215 InstallExtensionControlledPrefIncognito(
216 extension1(), kPref1, new base::StringValue("val2"));
217 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
218 std::string actual = incog_prefs->GetString(kPref1);
219 EXPECT_EQ("val2", actual);
222 void Verify() override {
223 // Main pref service shall see only non-incognito settings.
224 std::string actual = prefs()->pref_service()->GetString(kPref1);
225 EXPECT_EQ("val1", actual);
226 // Incognito pref service shall see incognito values.
227 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
228 actual = incog_prefs->GetString(kPref1);
229 EXPECT_EQ("val2", actual);
232 TEST_F(ControlledPrefsInstallIncognitoPersistent,
233 ControlledPrefsInstallIncognitoPersistent) { }
235 // Check that we forget 'session only' incognito values after a reload.
236 class ControlledPrefsInstallIncognitoSessionOnly
237 : public ExtensionControlledPrefsTest {
239 ControlledPrefsInstallIncognitoSessionOnly() : iteration_(0) {}
241 void Initialize() override {
242 InstallExtensionControlledPref(
243 extension1(), kPref1, new base::StringValue("val1"));
244 InstallExtensionControlledPrefIncognitoSessionOnly(
245 extension1(), kPref1, new base::StringValue("val2"));
246 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
247 std::string actual = incog_prefs->GetString(kPref1);
248 EXPECT_EQ("val2", actual);
250 void Verify() override {
251 // Main pref service shall see only non-incognito settings.
252 std::string actual = prefs()->pref_service()->GetString(kPref1);
253 EXPECT_EQ("val1", actual);
254 // Incognito pref service shall see session-only incognito values only
255 // during first run. Once the pref service was reloaded, all values shall be
257 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
258 actual = incog_prefs->GetString(kPref1);
259 if (iteration_ == 0) {
260 EXPECT_EQ("val2", actual);
262 EXPECT_EQ("val1", actual);
268 TEST_F(ControlledPrefsInstallIncognitoSessionOnly,
269 ControlledPrefsInstallIncognitoSessionOnly) { }
271 class ControlledPrefsUninstallExtension : public ExtensionControlledPrefsTest {
272 void Initialize() override {
273 InstallExtensionControlledPref(
274 extension1(), kPref1, new base::StringValue("val1"));
275 InstallExtensionControlledPref(
276 extension1(), kPref2, new base::StringValue("val2"));
277 scoped_refptr<ContentSettingsStore> store = content_settings_store();
278 ContentSettingsPattern pattern =
279 ContentSettingsPattern::FromString("http://[*.]example.com");
280 store->SetExtensionContentSetting(extension1()->id(),
282 CONTENT_SETTINGS_TYPE_IMAGES,
284 CONTENT_SETTING_BLOCK,
285 kExtensionPrefsScopeRegular);
287 UninstallExtension(extension1()->id());
289 void Verify() override {
290 EXPECT_FALSE(prefs()->HasPrefForExtension(extension1()->id()));
293 actual = prefs()->pref_service()->GetString(kPref1);
294 EXPECT_EQ(kDefaultPref1, actual);
295 actual = prefs()->pref_service()->GetString(kPref2);
296 EXPECT_EQ(kDefaultPref2, actual);
299 TEST_F(ControlledPrefsUninstallExtension,
300 ControlledPrefsUninstallExtension) { }
302 // Tests triggering of notifications to registered observers.
303 class ControlledPrefsNotifyWhenNeeded : public ExtensionControlledPrefsTest {
304 void Initialize() override {
307 using testing::StrEq;
309 MockPrefChangeCallback observer(prefs()->pref_service());
310 PrefChangeRegistrar registrar;
311 registrar.Init(prefs()->pref_service());
312 registrar.Add(kPref1, observer.GetCallback());
314 MockPrefChangeCallback incognito_observer(prefs()->pref_service());
315 scoped_ptr<PrefService> incog_prefs(prefs_.CreateIncognitoPrefService());
316 PrefChangeRegistrar incognito_registrar;
317 incognito_registrar.Init(incog_prefs.get());
318 incognito_registrar.Add(kPref1, incognito_observer.GetCallback());
320 // Write value and check notification.
321 EXPECT_CALL(observer, OnPreferenceChanged(_));
322 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
323 InstallExtensionControlledPref(extension1(), kPref1,
324 new base::StringValue("https://www.chromium.org"));
325 Mock::VerifyAndClearExpectations(&observer);
326 Mock::VerifyAndClearExpectations(&incognito_observer);
329 EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
330 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_)).Times(0);
331 InstallExtensionControlledPref(extension1(), kPref1,
332 new base::StringValue("https://www.chromium.org"));
333 Mock::VerifyAndClearExpectations(&observer);
334 Mock::VerifyAndClearExpectations(&incognito_observer);
337 EXPECT_CALL(observer, OnPreferenceChanged(_));
338 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
339 InstallExtensionControlledPref(extension1(), kPref1,
340 new base::StringValue("chrome://newtab"));
341 Mock::VerifyAndClearExpectations(&observer);
342 Mock::VerifyAndClearExpectations(&incognito_observer);
343 // Change only incognito persistent value.
344 EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
345 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
346 InstallExtensionControlledPrefIncognito(extension1(), kPref1,
347 new base::StringValue("chrome://newtab2"));
348 Mock::VerifyAndClearExpectations(&observer);
349 Mock::VerifyAndClearExpectations(&incognito_observer);
351 // Change only incognito session-only value.
352 EXPECT_CALL(observer, OnPreferenceChanged(_)).Times(0);
353 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
354 InstallExtensionControlledPrefIncognito(extension1(), kPref1,
355 new base::StringValue("chrome://newtab3"));
356 Mock::VerifyAndClearExpectations(&observer);
357 Mock::VerifyAndClearExpectations(&incognito_observer);
360 EXPECT_CALL(observer, OnPreferenceChanged(_));
361 EXPECT_CALL(incognito_observer, OnPreferenceChanged(_));
362 UninstallExtension(extension1()->id());
363 Mock::VerifyAndClearExpectations(&observer);
364 Mock::VerifyAndClearExpectations(&incognito_observer);
366 registrar.Remove(kPref1);
367 incognito_registrar.Remove(kPref1);
369 void Verify() override {
370 std::string actual = prefs()->pref_service()->GetString(kPref1);
371 EXPECT_EQ(kDefaultPref1, actual);
374 TEST_F(ControlledPrefsNotifyWhenNeeded,
375 ControlledPrefsNotifyWhenNeeded) { }
377 // Tests disabling an extension.
378 class ControlledPrefsDisableExtension : public ExtensionControlledPrefsTest {
379 void Initialize() override {
380 InstallExtensionControlledPref(
381 extension1(), kPref1, new base::StringValue("val1"));
382 std::string actual = prefs()->pref_service()->GetString(kPref1);
383 EXPECT_EQ("val1", actual);
384 prefs()->SetExtensionState(extension1()->id(), Extension::DISABLED);
386 void Verify() override {
387 std::string actual = prefs()->pref_service()->GetString(kPref1);
388 EXPECT_EQ(kDefaultPref1, actual);
391 TEST_F(ControlledPrefsDisableExtension, ControlledPrefsDisableExtension) { }
393 // Tests disabling and reenabling an extension.
394 class ControlledPrefsReenableExtension : public ExtensionControlledPrefsTest {
395 void Initialize() override {
396 InstallExtensionControlledPref(
397 extension1(), kPref1, new base::StringValue("val1"));
398 prefs()->SetExtensionState(extension1()->id(), Extension::DISABLED);
399 prefs()->SetExtensionState(extension1()->id(), Extension::ENABLED);
401 void Verify() override {
402 std::string actual = prefs()->pref_service()->GetString(kPref1);
403 EXPECT_EQ("val1", actual);
406 TEST_F(ControlledPrefsDisableExtension, ControlledPrefsReenableExtension) { }
408 // Mock class to test whether objects are deleted correctly.
409 class MockStringValue : public base::StringValue {
411 explicit MockStringValue(const std::string& in_value)
412 : base::StringValue(in_value) {
414 virtual ~MockStringValue() {
417 MOCK_METHOD0(Die, void());
420 class ControlledPrefsSetExtensionControlledPref
421 : public ExtensionControlledPrefsTest {
423 void Initialize() override {
424 MockStringValue* v1 = new MockStringValue("https://www.chromium.org");
425 MockStringValue* v2 = new MockStringValue("https://www.chromium.org");
426 MockStringValue* v1i = new MockStringValue("https://www.chromium.org");
427 MockStringValue* v2i = new MockStringValue("https://www.chromium.org");
428 // Ownership is taken, value shall not be deleted.
429 EXPECT_CALL(*v1, Die()).Times(0);
430 EXPECT_CALL(*v1i, Die()).Times(0);
431 InstallExtensionControlledPref(extension1(), kPref1, v1);
432 InstallExtensionControlledPrefIncognito(extension1(), kPref1, v1i);
433 testing::Mock::VerifyAndClearExpectations(v1);
434 testing::Mock::VerifyAndClearExpectations(v1i);
435 // Make sure there is no memory leak and both values are deleted.
436 EXPECT_CALL(*v1, Die()).Times(1);
437 EXPECT_CALL(*v1i, Die()).Times(1);
438 EXPECT_CALL(*v2, Die()).Times(1);
439 EXPECT_CALL(*v2i, Die()).Times(1);
440 InstallExtensionControlledPref(extension1(), kPref1, v2);
441 InstallExtensionControlledPrefIncognito(extension1(), kPref1, v2i);
442 prefs_.RecreateExtensionPrefs();
443 testing::Mock::VerifyAndClearExpectations(v1);
444 testing::Mock::VerifyAndClearExpectations(v1i);
445 testing::Mock::VerifyAndClearExpectations(v2);
446 testing::Mock::VerifyAndClearExpectations(v2i);
449 void Verify() override {}
451 TEST_F(ControlledPrefsSetExtensionControlledPref,
452 ControlledPrefsSetExtensionControlledPref) { }
454 // Tests that the switches::kDisableExtensions command-line flag prevents
455 // extension controlled preferences from being enacted.
456 class ControlledPrefsDisableExtensions : public ExtensionControlledPrefsTest {
458 ControlledPrefsDisableExtensions()
460 ~ControlledPrefsDisableExtensions() override {}
461 void Initialize() override {
462 InstallExtensionControlledPref(
463 extension1(), kPref1, new base::StringValue("val1"));
464 // This becomes only active in the second verification phase.
465 prefs_.set_extensions_disabled(true);
467 void Verify() override {
468 std::string actual = prefs()->pref_service()->GetString(kPref1);
469 if (iteration_ == 0) {
470 EXPECT_EQ("val1", actual);
473 EXPECT_EQ(kDefaultPref1, actual);
480 TEST_F(ControlledPrefsDisableExtensions, ControlledPrefsDisableExtensions) { }
482 } // namespace extensions