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/api/content_settings/content_settings_service.h"
12 #include "chrome/browser/extensions/api/preference/preference_api.h"
13 #include "chrome/browser/extensions/extension_prefs_unittest.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(kPref1
, kDefaultPref1
);
113 registry
->RegisterStringPref(kPref2
, kDefaultPref2
);
114 registry
->RegisterStringPref(kPref3
, kDefaultPref3
);
115 registry
->RegisterStringPref(kPref4
, kDefaultPref4
);
118 void ExtensionControlledPrefsTest::InstallExtensionControlledPref(
119 Extension
* extension
,
120 const std::string
& key
,
121 base::Value
* value
) {
122 EnsureExtensionInstalled(extension
);
123 test_preference_api_
.SetExtensionControlledPref(
124 extension
->id(), key
, kExtensionPrefsScopeRegular
, value
);
127 void ExtensionControlledPrefsTest::InstallExtensionControlledPrefIncognito(
128 Extension
* extension
,
129 const std::string
& key
,
130 base::Value
* value
) {
131 EnsureExtensionInstalled(extension
);
132 test_preference_api_
.SetExtensionControlledPref(
133 extension
->id(), key
, kExtensionPrefsScopeIncognitoPersistent
, value
);
136 void ExtensionControlledPrefsTest::
137 InstallExtensionControlledPrefIncognitoSessionOnly(Extension
* extension
,
138 const std::string
& key
,
139 base::Value
* value
) {
140 EnsureExtensionInstalled(extension
);
141 test_preference_api_
.SetExtensionControlledPref(
142 extension
->id(), key
, kExtensionPrefsScopeIncognitoSessionOnly
, value
);
145 void ExtensionControlledPrefsTest::InstallExtension(Extension
* extension
) {
146 EnsureExtensionInstalled(extension
);
149 void ExtensionControlledPrefsTest::UninstallExtension(
150 const std::string
& extension_id
) {
151 EnsureExtensionUninstalled(extension_id
);
154 void ExtensionControlledPrefsTest::EnsureExtensionInstalled(
155 Extension
* extension
) {
156 // Install extension the first time a preference is set for it.
157 Extension
* extensions
[] = { extension1(),
161 for (size_t i
= 0; i
< kNumInstalledExtensions
; ++i
) {
162 if (extension
== extensions
[i
] && !installed_
[i
]) {
163 prefs()->OnExtensionInstalled(extension
,
165 syncer::StringOrdinal(),
167 prefs()->SetIsIncognitoEnabled(extension
->id(), true);
168 installed_
[i
] = true;
174 void ExtensionControlledPrefsTest::EnsureExtensionUninstalled(
175 const std::string
& extension_id
) {
176 Extension
* extensions
[] = { extension1(),
180 for (size_t i
= 0; i
< kNumInstalledExtensions
; ++i
) {
181 if (extensions
[i
]->id() == extension_id
) {
182 installed_
[i
] = false;
186 prefs()->OnExtensionUninstalled(extension_id
, Manifest::INTERNAL
, false);
189 class ControlledPrefsInstallOneExtension
190 : public ExtensionControlledPrefsTest
{
191 void Initialize() override
{
192 InstallExtensionControlledPref(extension1(),
194 new base::StringValue("val1"));
196 void Verify() override
{
197 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
198 EXPECT_EQ("val1", actual
);
201 TEST_F(ControlledPrefsInstallOneExtension
,
202 ControlledPrefsInstallOneExtension
) { }
204 // Check that we do not forget persistent incognito values after a reload.
205 class ControlledPrefsInstallIncognitoPersistent
206 : public ExtensionControlledPrefsTest
{
208 void Initialize() override
{
209 InstallExtensionControlledPref(
210 extension1(), kPref1
, new base::StringValue("val1"));
211 InstallExtensionControlledPrefIncognito(
212 extension1(), kPref1
, new base::StringValue("val2"));
213 scoped_ptr
<PrefService
> incog_prefs(prefs_
.CreateIncognitoPrefService());
214 std::string actual
= incog_prefs
->GetString(kPref1
);
215 EXPECT_EQ("val2", actual
);
218 void Verify() override
{
219 // Main pref service shall see only non-incognito settings.
220 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
221 EXPECT_EQ("val1", actual
);
222 // Incognito pref service shall see incognito values.
223 scoped_ptr
<PrefService
> incog_prefs(prefs_
.CreateIncognitoPrefService());
224 actual
= incog_prefs
->GetString(kPref1
);
225 EXPECT_EQ("val2", actual
);
228 TEST_F(ControlledPrefsInstallIncognitoPersistent
,
229 ControlledPrefsInstallIncognitoPersistent
) { }
231 // Check that we forget 'session only' incognito values after a reload.
232 class ControlledPrefsInstallIncognitoSessionOnly
233 : public ExtensionControlledPrefsTest
{
235 ControlledPrefsInstallIncognitoSessionOnly() : iteration_(0) {}
237 void Initialize() override
{
238 InstallExtensionControlledPref(
239 extension1(), kPref1
, new base::StringValue("val1"));
240 InstallExtensionControlledPrefIncognitoSessionOnly(
241 extension1(), kPref1
, new base::StringValue("val2"));
242 scoped_ptr
<PrefService
> incog_prefs(prefs_
.CreateIncognitoPrefService());
243 std::string actual
= incog_prefs
->GetString(kPref1
);
244 EXPECT_EQ("val2", actual
);
246 void Verify() override
{
247 // Main pref service shall see only non-incognito settings.
248 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
249 EXPECT_EQ("val1", actual
);
250 // Incognito pref service shall see session-only incognito values only
251 // during first run. Once the pref service was reloaded, all values shall be
253 scoped_ptr
<PrefService
> incog_prefs(prefs_
.CreateIncognitoPrefService());
254 actual
= incog_prefs
->GetString(kPref1
);
255 if (iteration_
== 0) {
256 EXPECT_EQ("val2", actual
);
258 EXPECT_EQ("val1", actual
);
264 TEST_F(ControlledPrefsInstallIncognitoSessionOnly
,
265 ControlledPrefsInstallIncognitoSessionOnly
) { }
267 class ControlledPrefsUninstallExtension
: public ExtensionControlledPrefsTest
{
268 void Initialize() override
{
269 InstallExtensionControlledPref(
270 extension1(), kPref1
, new base::StringValue("val1"));
271 InstallExtensionControlledPref(
272 extension1(), kPref2
, new base::StringValue("val2"));
273 scoped_refptr
<ContentSettingsStore
> store
= content_settings_store();
274 ContentSettingsPattern pattern
=
275 ContentSettingsPattern::FromString("http://[*.]example.com");
276 store
->SetExtensionContentSetting(extension1()->id(),
278 CONTENT_SETTINGS_TYPE_IMAGES
,
280 CONTENT_SETTING_BLOCK
,
281 kExtensionPrefsScopeRegular
);
283 UninstallExtension(extension1()->id());
285 void Verify() override
{
286 EXPECT_FALSE(prefs()->HasPrefForExtension(extension1()->id()));
289 actual
= prefs()->pref_service()->GetString(kPref1
);
290 EXPECT_EQ(kDefaultPref1
, actual
);
291 actual
= prefs()->pref_service()->GetString(kPref2
);
292 EXPECT_EQ(kDefaultPref2
, actual
);
295 TEST_F(ControlledPrefsUninstallExtension
,
296 ControlledPrefsUninstallExtension
) { }
298 // Tests triggering of notifications to registered observers.
299 class ControlledPrefsNotifyWhenNeeded
: public ExtensionControlledPrefsTest
{
300 void Initialize() override
{
303 using testing::StrEq
;
305 MockPrefChangeCallback
observer(prefs()->pref_service());
306 PrefChangeRegistrar registrar
;
307 registrar
.Init(prefs()->pref_service());
308 registrar
.Add(kPref1
, observer
.GetCallback());
310 MockPrefChangeCallback
incognito_observer(prefs()->pref_service());
311 scoped_ptr
<PrefService
> incog_prefs(prefs_
.CreateIncognitoPrefService());
312 PrefChangeRegistrar incognito_registrar
;
313 incognito_registrar
.Init(incog_prefs
.get());
314 incognito_registrar
.Add(kPref1
, incognito_observer
.GetCallback());
316 // Write value and check notification.
317 EXPECT_CALL(observer
, OnPreferenceChanged(_
));
318 EXPECT_CALL(incognito_observer
, OnPreferenceChanged(_
));
319 InstallExtensionControlledPref(extension1(), kPref1
,
320 new base::StringValue("https://www.chromium.org"));
321 Mock::VerifyAndClearExpectations(&observer
);
322 Mock::VerifyAndClearExpectations(&incognito_observer
);
325 EXPECT_CALL(observer
, OnPreferenceChanged(_
)).Times(0);
326 EXPECT_CALL(incognito_observer
, OnPreferenceChanged(_
)).Times(0);
327 InstallExtensionControlledPref(extension1(), kPref1
,
328 new base::StringValue("https://www.chromium.org"));
329 Mock::VerifyAndClearExpectations(&observer
);
330 Mock::VerifyAndClearExpectations(&incognito_observer
);
333 EXPECT_CALL(observer
, OnPreferenceChanged(_
));
334 EXPECT_CALL(incognito_observer
, OnPreferenceChanged(_
));
335 InstallExtensionControlledPref(extension1(), kPref1
,
336 new base::StringValue("chrome://newtab"));
337 Mock::VerifyAndClearExpectations(&observer
);
338 Mock::VerifyAndClearExpectations(&incognito_observer
);
339 // Change only incognito persistent value.
340 EXPECT_CALL(observer
, OnPreferenceChanged(_
)).Times(0);
341 EXPECT_CALL(incognito_observer
, OnPreferenceChanged(_
));
342 InstallExtensionControlledPrefIncognito(extension1(), kPref1
,
343 new base::StringValue("chrome://newtab2"));
344 Mock::VerifyAndClearExpectations(&observer
);
345 Mock::VerifyAndClearExpectations(&incognito_observer
);
347 // Change only incognito session-only value.
348 EXPECT_CALL(observer
, OnPreferenceChanged(_
)).Times(0);
349 EXPECT_CALL(incognito_observer
, OnPreferenceChanged(_
));
350 InstallExtensionControlledPrefIncognito(extension1(), kPref1
,
351 new base::StringValue("chrome://newtab3"));
352 Mock::VerifyAndClearExpectations(&observer
);
353 Mock::VerifyAndClearExpectations(&incognito_observer
);
356 EXPECT_CALL(observer
, OnPreferenceChanged(_
));
357 EXPECT_CALL(incognito_observer
, OnPreferenceChanged(_
));
358 UninstallExtension(extension1()->id());
359 Mock::VerifyAndClearExpectations(&observer
);
360 Mock::VerifyAndClearExpectations(&incognito_observer
);
362 registrar
.Remove(kPref1
);
363 incognito_registrar
.Remove(kPref1
);
365 void Verify() override
{
366 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
367 EXPECT_EQ(kDefaultPref1
, actual
);
370 TEST_F(ControlledPrefsNotifyWhenNeeded
,
371 ControlledPrefsNotifyWhenNeeded
) { }
373 // Tests disabling an extension.
374 class ControlledPrefsDisableExtension
: public ExtensionControlledPrefsTest
{
375 void Initialize() override
{
376 InstallExtensionControlledPref(
377 extension1(), kPref1
, new base::StringValue("val1"));
378 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
379 EXPECT_EQ("val1", actual
);
380 prefs()->SetExtensionDisabled(extension1()->id(),
381 Extension::DISABLE_USER_ACTION
);
383 void Verify() override
{
384 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
385 EXPECT_EQ(kDefaultPref1
, actual
);
388 TEST_F(ControlledPrefsDisableExtension
, ControlledPrefsDisableExtension
) { }
390 // Tests disabling and reenabling an extension.
391 class ControlledPrefsReenableExtension
: public ExtensionControlledPrefsTest
{
392 void Initialize() override
{
393 InstallExtensionControlledPref(
394 extension1(), kPref1
, new base::StringValue("val1"));
395 prefs()->SetExtensionDisabled(extension1()->id(),
396 Extension::DISABLE_USER_ACTION
);
397 prefs()->SetExtensionEnabled(extension1()->id());
399 void Verify() override
{
400 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
401 EXPECT_EQ("val1", actual
);
404 TEST_F(ControlledPrefsDisableExtension
, ControlledPrefsReenableExtension
) { }
406 // Mock class to test whether objects are deleted correctly.
407 class MockStringValue
: public base::StringValue
{
409 explicit MockStringValue(const std::string
& in_value
)
410 : base::StringValue(in_value
) {
412 virtual ~MockStringValue() {
415 MOCK_METHOD0(Die
, void());
418 class ControlledPrefsSetExtensionControlledPref
419 : public ExtensionControlledPrefsTest
{
421 void Initialize() override
{
422 MockStringValue
* v1
= new MockStringValue("https://www.chromium.org");
423 MockStringValue
* v2
= new MockStringValue("https://www.chromium.org");
424 MockStringValue
* v1i
= new MockStringValue("https://www.chromium.org");
425 MockStringValue
* v2i
= new MockStringValue("https://www.chromium.org");
426 // Ownership is taken, value shall not be deleted.
427 EXPECT_CALL(*v1
, Die()).Times(0);
428 EXPECT_CALL(*v1i
, Die()).Times(0);
429 InstallExtensionControlledPref(extension1(), kPref1
, v1
);
430 InstallExtensionControlledPrefIncognito(extension1(), kPref1
, v1i
);
431 testing::Mock::VerifyAndClearExpectations(v1
);
432 testing::Mock::VerifyAndClearExpectations(v1i
);
433 // Make sure there is no memory leak and both values are deleted.
434 EXPECT_CALL(*v1
, Die()).Times(1);
435 EXPECT_CALL(*v1i
, Die()).Times(1);
436 EXPECT_CALL(*v2
, Die()).Times(1);
437 EXPECT_CALL(*v2i
, Die()).Times(1);
438 InstallExtensionControlledPref(extension1(), kPref1
, v2
);
439 InstallExtensionControlledPrefIncognito(extension1(), kPref1
, v2i
);
440 prefs_
.RecreateExtensionPrefs();
441 testing::Mock::VerifyAndClearExpectations(v1
);
442 testing::Mock::VerifyAndClearExpectations(v1i
);
443 testing::Mock::VerifyAndClearExpectations(v2
);
444 testing::Mock::VerifyAndClearExpectations(v2i
);
447 void Verify() override
{}
449 TEST_F(ControlledPrefsSetExtensionControlledPref
,
450 ControlledPrefsSetExtensionControlledPref
) { }
452 // Tests that the switches::kDisableExtensions command-line flag prevents
453 // extension controlled preferences from being enacted.
454 class ControlledPrefsDisableExtensions
: public ExtensionControlledPrefsTest
{
456 ControlledPrefsDisableExtensions()
458 ~ControlledPrefsDisableExtensions() override
{}
459 void Initialize() override
{
460 InstallExtensionControlledPref(
461 extension1(), kPref1
, new base::StringValue("val1"));
462 // This becomes only active in the second verification phase.
463 prefs_
.set_extensions_disabled(true);
465 void Verify() override
{
466 std::string actual
= prefs()->pref_service()->GetString(kPref1
);
467 if (iteration_
== 0) {
468 EXPECT_EQ("val1", actual
);
471 EXPECT_EQ(kDefaultPref1
, actual
);
478 TEST_F(ControlledPrefsDisableExtensions
, ControlledPrefsDisableExtensions
) { }
480 } // namespace extensions