Ensure tests have an active task runner
[chromium-blink-merge.git] / chrome / browser / content_settings / content_settings_pref_provider_unittest.cc
blob6386a7569cd19940ef86603ef822a6813a43dac2
1 // Copyright (c) 2012 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.
5 #include "components/content_settings/core/browser/content_settings_pref_provider.h"
7 #include "base/auto_reset.h"
8 #include "base/command_line.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/default_pref_store.h"
12 #include "base/prefs/overlay_user_pref_store.h"
13 #include "base/prefs/pref_change_registrar.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/prefs/scoped_user_pref_update.h"
16 #include "base/prefs/testing_pref_store.h"
17 #include "base/test/simple_test_clock.h"
18 #include "base/threading/platform_thread.h"
19 #include "base/values.h"
20 #include "chrome/browser/content_settings/content_settings_mock_observer.h"
21 #include "chrome/browser/prefs/browser_prefs.h"
22 #include "chrome/browser/prefs/pref_service_mock_factory.h"
23 #include "chrome/browser/prefs/pref_service_syncable.h"
24 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/common/url_constants.h"
27 #include "chrome/test/base/testing_pref_service_syncable.h"
28 #include "chrome/test/base/testing_profile.h"
29 #include "components/content_settings/core/browser/content_settings_pref.h"
30 #include "components/content_settings/core/browser/content_settings_rule.h"
31 #include "components/content_settings/core/browser/content_settings_utils.h"
32 #include "components/content_settings/core/test/content_settings_test_utils.h"
33 #include "components/pref_registry/pref_registry_syncable.h"
34 #include "content/public/test/test_browser_thread_bundle.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36 #include "url/gurl.h"
38 using ::testing::_;
40 namespace content_settings {
42 class DeadlockCheckerThread : public base::PlatformThread::Delegate {
43 public:
44 explicit DeadlockCheckerThread(PrefProvider* provider)
45 : provider_(provider) {}
47 void ThreadMain() override {
48 EXPECT_TRUE(provider_->TestAllLocks());
50 private:
51 PrefProvider* provider_;
52 DISALLOW_COPY_AND_ASSIGN(DeadlockCheckerThread);
55 // A helper for observing an preference changes and testing whether
56 // |PrefProvider| holds a lock when the preferences change.
57 class DeadlockCheckerObserver {
58 public:
59 // |DeadlockCheckerObserver| doesn't take the ownership of |prefs| or
60 // |provider|.
61 DeadlockCheckerObserver(PrefService* prefs, PrefProvider* provider)
62 : provider_(provider),
63 notification_received_(false) {
64 pref_change_registrar_.Init(prefs);
65 pref_change_registrar_.Add(
66 prefs::kContentSettingsPatternPairs,
67 base::Bind(
68 &DeadlockCheckerObserver::OnContentSettingsPatternPairsChanged,
69 base::Unretained(this)));
71 virtual ~DeadlockCheckerObserver() {}
73 bool notification_received() const {
74 return notification_received_;
77 private:
78 void OnContentSettingsPatternPairsChanged() {
79 // Check whether |provider_| holds its lock. For this, we need a
80 // separate thread.
81 DeadlockCheckerThread thread(provider_);
82 base::PlatformThreadHandle handle;
83 ASSERT_TRUE(base::PlatformThread::Create(0, &thread, &handle));
84 base::PlatformThread::Join(handle);
85 notification_received_ = true;
88 PrefProvider* provider_;
89 PrefChangeRegistrar pref_change_registrar_;
90 bool notification_received_;
91 DISALLOW_COPY_AND_ASSIGN(DeadlockCheckerObserver);
94 class PrefProviderTest : public testing::Test {
95 content::TestBrowserThreadBundle thread_bundle_;
98 TEST_F(PrefProviderTest, Observer) {
99 TestingProfile profile;
100 PrefProvider pref_content_settings_provider(profile.GetPrefs(), false);
102 ContentSettingsPattern pattern =
103 ContentSettingsPattern::FromString("[*.]example.com");
104 content_settings::MockObserver mock_observer;
105 EXPECT_CALL(mock_observer,
106 OnContentSettingChanged(pattern,
107 ContentSettingsPattern::Wildcard(),
108 CONTENT_SETTINGS_TYPE_IMAGES,
109 ""));
111 pref_content_settings_provider.AddObserver(&mock_observer);
113 pref_content_settings_provider.SetWebsiteSetting(
114 pattern,
115 ContentSettingsPattern::Wildcard(),
116 CONTENT_SETTINGS_TYPE_IMAGES,
117 std::string(),
118 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
120 pref_content_settings_provider.ShutdownOnUIThread();
123 // Test for regression in which the PrefProvider modified the user pref store
124 // of the OTR unintentionally: http://crbug.com/74466.
125 TEST_F(PrefProviderTest, Incognito) {
126 PersistentPrefStore* user_prefs = new TestingPrefStore();
127 OverlayUserPrefStore* otr_user_prefs =
128 new OverlayUserPrefStore(user_prefs);
130 PrefServiceMockFactory factory;
131 factory.set_user_prefs(make_scoped_refptr(user_prefs));
132 scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
133 new user_prefs::PrefRegistrySyncable);
134 PrefServiceSyncable* regular_prefs =
135 factory.CreateSyncable(registry.get()).release();
137 chrome::RegisterUserProfilePrefs(registry.get());
139 PrefServiceMockFactory otr_factory;
140 otr_factory.set_user_prefs(make_scoped_refptr(otr_user_prefs));
141 scoped_refptr<user_prefs::PrefRegistrySyncable> otr_registry(
142 new user_prefs::PrefRegistrySyncable);
143 PrefServiceSyncable* otr_prefs =
144 otr_factory.CreateSyncable(otr_registry.get()).release();
146 chrome::RegisterUserProfilePrefs(otr_registry.get());
148 TestingProfile::Builder profile_builder;
149 profile_builder.SetPrefService(make_scoped_ptr(regular_prefs));
150 scoped_ptr<TestingProfile> profile = profile_builder.Build();
152 TestingProfile::Builder otr_profile_builder;
153 otr_profile_builder.SetPrefService(make_scoped_ptr(otr_prefs));
154 otr_profile_builder.BuildIncognito(profile.get());
156 PrefProvider pref_content_settings_provider(regular_prefs, false);
157 PrefProvider pref_content_settings_provider_incognito(otr_prefs, true);
158 ContentSettingsPattern pattern =
159 ContentSettingsPattern::FromString("[*.]example.com");
160 pref_content_settings_provider.SetWebsiteSetting(
161 pattern,
162 pattern,
163 CONTENT_SETTINGS_TYPE_IMAGES,
164 std::string(),
165 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
167 GURL host("http://example.com/");
168 // The value should of course be visible in the regular PrefProvider.
169 EXPECT_EQ(CONTENT_SETTING_ALLOW,
170 GetContentSetting(&pref_content_settings_provider,
171 host,
172 host,
173 CONTENT_SETTINGS_TYPE_IMAGES,
174 std::string(),
175 false));
176 // And also in the OTR version.
177 EXPECT_EQ(CONTENT_SETTING_ALLOW,
178 GetContentSetting(&pref_content_settings_provider_incognito,
179 host,
180 host,
181 CONTENT_SETTINGS_TYPE_IMAGES,
182 std::string(),
183 false));
184 // But the value should not be overridden in the OTR user prefs accidentally.
185 EXPECT_FALSE(otr_user_prefs->IsSetInOverlay(
186 prefs::kContentSettingsPatternPairs));
188 pref_content_settings_provider.ShutdownOnUIThread();
189 pref_content_settings_provider_incognito.ShutdownOnUIThread();
192 TEST_F(PrefProviderTest, GetContentSettingsValue) {
193 TestingProfile testing_profile;
194 PrefProvider provider(testing_profile.GetPrefs(), false);
196 GURL primary_url("http://example.com/");
197 ContentSettingsPattern primary_pattern =
198 ContentSettingsPattern::FromString("[*.]example.com");
200 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
201 GetContentSetting(&provider,
202 primary_url,
203 primary_url,
204 CONTENT_SETTINGS_TYPE_IMAGES,
205 std::string(),
206 false));
208 EXPECT_EQ(NULL,
209 GetContentSettingValue(&provider,
210 primary_url,
211 primary_url,
212 CONTENT_SETTINGS_TYPE_IMAGES,
213 std::string(),
214 false));
216 provider.SetWebsiteSetting(primary_pattern,
217 primary_pattern,
218 CONTENT_SETTINGS_TYPE_IMAGES,
219 std::string(),
220 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
221 EXPECT_EQ(CONTENT_SETTING_BLOCK,
222 GetContentSetting(&provider,
223 primary_url,
224 primary_url,
225 CONTENT_SETTINGS_TYPE_IMAGES,
226 std::string(),
227 false));
228 scoped_ptr<base::Value> value_ptr(
229 GetContentSettingValue(&provider,
230 primary_url,
231 primary_url,
232 CONTENT_SETTINGS_TYPE_IMAGES,
233 std::string(),
234 false));
235 int int_value = -1;
236 value_ptr->GetAsInteger(&int_value);
237 EXPECT_EQ(CONTENT_SETTING_BLOCK, IntToContentSetting(int_value));
239 provider.SetWebsiteSetting(primary_pattern,
240 primary_pattern,
241 CONTENT_SETTINGS_TYPE_IMAGES,
242 std::string(),
243 NULL);
244 EXPECT_EQ(NULL,
245 GetContentSettingValue(&provider,
246 primary_url,
247 primary_url,
248 CONTENT_SETTINGS_TYPE_IMAGES,
249 std::string(),
250 false));
251 provider.ShutdownOnUIThread();
254 TEST_F(PrefProviderTest, Patterns) {
255 TestingProfile testing_profile;
256 PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
257 false);
259 GURL host1("http://example.com/");
260 GURL host2("http://www.example.com/");
261 GURL host3("http://example.org/");
262 GURL host4("file:///tmp/test.html");
263 ContentSettingsPattern pattern1 =
264 ContentSettingsPattern::FromString("[*.]example.com");
265 ContentSettingsPattern pattern2 =
266 ContentSettingsPattern::FromString("example.org");
267 ContentSettingsPattern pattern3 =
268 ContentSettingsPattern::FromString("file:///tmp/test.html");
270 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
271 GetContentSetting(&pref_content_settings_provider,
272 host1,
273 host1,
274 CONTENT_SETTINGS_TYPE_IMAGES,
275 std::string(),
276 false));
277 pref_content_settings_provider.SetWebsiteSetting(
278 pattern1,
279 pattern1,
280 CONTENT_SETTINGS_TYPE_IMAGES,
281 std::string(),
282 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
283 EXPECT_EQ(CONTENT_SETTING_BLOCK,
284 GetContentSetting(&pref_content_settings_provider,
285 host1,
286 host1,
287 CONTENT_SETTINGS_TYPE_IMAGES,
288 std::string(),
289 false));
290 EXPECT_EQ(CONTENT_SETTING_BLOCK,
291 GetContentSetting(&pref_content_settings_provider,
292 host2,
293 host2,
294 CONTENT_SETTINGS_TYPE_IMAGES,
295 std::string(),
296 false));
298 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
299 GetContentSetting(&pref_content_settings_provider,
300 host3,
301 host3,
302 CONTENT_SETTINGS_TYPE_IMAGES,
303 std::string(),
304 false));
305 pref_content_settings_provider.SetWebsiteSetting(
306 pattern2,
307 pattern2,
308 CONTENT_SETTINGS_TYPE_IMAGES,
309 std::string(),
310 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
311 EXPECT_EQ(CONTENT_SETTING_BLOCK,
312 GetContentSetting(&pref_content_settings_provider,
313 host3,
314 host3,
315 CONTENT_SETTINGS_TYPE_IMAGES,
316 std::string(),
317 false));
319 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
320 GetContentSetting(&pref_content_settings_provider,
321 host4,
322 host4,
323 CONTENT_SETTINGS_TYPE_IMAGES,
324 std::string(),
325 false));
326 pref_content_settings_provider.SetWebsiteSetting(
327 pattern3,
328 pattern3,
329 CONTENT_SETTINGS_TYPE_IMAGES,
330 std::string(),
331 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
332 EXPECT_EQ(CONTENT_SETTING_BLOCK,
333 GetContentSetting(&pref_content_settings_provider,
334 host4,
335 host4,
336 CONTENT_SETTINGS_TYPE_IMAGES,
337 std::string(),
338 false));
340 pref_content_settings_provider.ShutdownOnUIThread();
343 TEST_F(PrefProviderTest, ResourceIdentifier) {
344 TestingProfile testing_profile;
345 PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
346 false);
348 GURL host("http://example.com/");
349 ContentSettingsPattern pattern =
350 ContentSettingsPattern::FromString("[*.]example.com");
351 std::string resource1("someplugin");
352 std::string resource2("otherplugin");
354 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
355 GetContentSetting(
356 &pref_content_settings_provider,
357 host, host, CONTENT_SETTINGS_TYPE_PLUGINS,
358 resource1, false));
359 pref_content_settings_provider.SetWebsiteSetting(
360 pattern,
361 pattern,
362 CONTENT_SETTINGS_TYPE_PLUGINS,
363 resource1,
364 new base::FundamentalValue(CONTENT_SETTING_BLOCK));
365 EXPECT_EQ(CONTENT_SETTING_BLOCK,
366 GetContentSetting(
367 &pref_content_settings_provider,
368 host, host, CONTENT_SETTINGS_TYPE_PLUGINS,
369 resource1, false));
370 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
371 GetContentSetting(
372 &pref_content_settings_provider,
373 host, host, CONTENT_SETTINGS_TYPE_PLUGINS,
374 resource2, false));
376 pref_content_settings_provider.ShutdownOnUIThread();
379 TEST_F(PrefProviderTest, AutoSubmitCertificateContentSetting) {
380 TestingProfile profile;
381 TestingPrefServiceSyncable* prefs = profile.GetTestingPrefService();
382 GURL primary_url("https://www.example.com");
383 GURL secondary_url("https://www.sample.com");
385 PrefProvider provider(prefs, false);
387 EXPECT_EQ(CONTENT_SETTING_DEFAULT,
388 GetContentSetting(
389 &provider,
390 primary_url,
391 primary_url,
392 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
393 std::string(),
394 false));
396 provider.SetWebsiteSetting(ContentSettingsPattern::FromURL(primary_url),
397 ContentSettingsPattern::Wildcard(),
398 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
399 std::string(),
400 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
401 EXPECT_EQ(CONTENT_SETTING_ALLOW,
402 GetContentSetting(
403 &provider,
404 primary_url,
405 secondary_url,
406 CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE,
407 std::string(),
408 false));
409 provider.ShutdownOnUIThread();
412 // http://crosbug.com/17760
413 TEST_F(PrefProviderTest, Deadlock) {
414 TestingPrefServiceSyncable prefs;
415 PrefProvider::RegisterProfilePrefs(prefs.registry());
417 // Chain of events: a preference changes, |PrefProvider| notices it, and reads
418 // and writes the preference. When the preference is written, a notification
419 // is sent, and this used to happen when |PrefProvider| was still holding its
420 // lock.
422 PrefProvider provider(&prefs, false);
423 DeadlockCheckerObserver observer(&prefs, &provider);
425 DictionaryPrefUpdate update(&prefs,
426 prefs::kContentSettingsPatternPairs);
427 base::DictionaryValue* mutable_settings = update.Get();
428 mutable_settings->SetWithoutPathExpansion("www.example.com,*",
429 new base::DictionaryValue());
431 EXPECT_TRUE(observer.notification_received());
433 provider.ShutdownOnUIThread();
436 TEST_F(PrefProviderTest, LastUsage) {
437 TestingProfile testing_profile;
438 PrefProvider pref_content_settings_provider(testing_profile.GetPrefs(),
439 false);
440 base::SimpleTestClock* test_clock = new base::SimpleTestClock;
441 test_clock->SetNow(base::Time::Now());
443 pref_content_settings_provider.SetClockForTesting(
444 scoped_ptr<base::Clock>(test_clock));
445 GURL host("http://example.com/");
446 ContentSettingsPattern pattern =
447 ContentSettingsPattern::FromString("[*.]example.com");
449 base::Time no_usage = pref_content_settings_provider.GetLastUsage(
450 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
451 EXPECT_EQ(no_usage.ToDoubleT(), 0);
453 pref_content_settings_provider.UpdateLastUsage(
454 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
455 base::Time first = pref_content_settings_provider.GetLastUsage(
456 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
458 test_clock->Advance(base::TimeDelta::FromSeconds(10));
460 pref_content_settings_provider.UpdateLastUsage(
461 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
462 base::Time second = pref_content_settings_provider.GetLastUsage(
463 pattern, pattern, CONTENT_SETTINGS_TYPE_GEOLOCATION);
465 base::TimeDelta delta = second - first;
466 EXPECT_EQ(delta.InSeconds(), 10);
468 pref_content_settings_provider.ShutdownOnUIThread();
472 // TODO(msramek): This tests the correct migration behavior between the old
473 // aggregate dictionary preferences for all content settings types and the new
474 // dictionary preferences for individual types. Remove this when the migration
475 // period is over.
476 TEST_F(PrefProviderTest, SyncingOldToNew) {
477 TestingPrefServiceSyncable prefs;
478 PrefProvider::RegisterProfilePrefs(prefs.registry());
479 PrefProvider provider(&prefs, false);
481 const std::string pattern = "google.com,*";
482 const std::string resource_id = "abcde12345";
483 base::DictionaryValue* exceptions = new base::DictionaryValue();
484 base::DictionaryValue* plugin_resources = new base::DictionaryValue();
486 // Add exceptions for images and app banner.
487 exceptions->SetIntegerWithoutPathExpansion(
488 GetTypeName(CONTENT_SETTINGS_TYPE_IMAGES), CONTENT_SETTING_ALLOW);
489 exceptions->SetIntegerWithoutPathExpansion(
490 GetTypeName(CONTENT_SETTINGS_TYPE_APP_BANNER), CONTENT_SETTING_ALLOW);
492 // Add a regular exception for plugins, then one with a resource identifier.
493 exceptions->SetIntegerWithoutPathExpansion(
494 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS), CONTENT_SETTING_ALLOW);
495 plugin_resources->SetIntegerWithoutPathExpansion(
496 resource_id, CONTENT_SETTING_BLOCK);
497 exceptions->SetWithoutPathExpansion(
498 "per_plugin", plugin_resources);
500 // Change the old dictionary preference and observe changes
501 // in the new preferences.
503 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
504 base::DictionaryValue* old_dictionary = update.Get();
505 old_dictionary->SetWithoutPathExpansion(pattern, exceptions);
508 // The images exception was synced.
510 DictionaryPrefUpdate update(
511 &prefs, prefs::kContentSettingsImagesPatternPairs);
512 const base::DictionaryValue* images_dictionary = update.Get();
514 EXPECT_EQ(1u, images_dictionary->size());
515 const base::DictionaryValue* images_exception;
516 EXPECT_TRUE(images_dictionary->GetDictionaryWithoutPathExpansion(
517 pattern, &images_exception));
519 // And it has a correct value.
520 int images_exception_value = CONTENT_SETTING_DEFAULT;
521 EXPECT_TRUE(images_exception->GetIntegerWithoutPathExpansion(
522 "setting", &images_exception_value));
523 EXPECT_EQ(CONTENT_SETTING_ALLOW, images_exception_value);
526 // The app banner exception was not synced.
528 DictionaryPrefUpdate update(
529 &prefs, prefs::kContentSettingsAppBannerPatternPairs);
530 const base::DictionaryValue* app_banner_dictionary = update.Get();
531 EXPECT_TRUE(app_banner_dictionary->empty());
534 // The plugins exception was synced, together with the resource identifiers.
536 DictionaryPrefUpdate update(
537 &prefs, prefs::kContentSettingsPluginsPatternPairs);
538 const base::DictionaryValue* plugins_dictionary = update.Get();
539 EXPECT_EQ(1u, plugins_dictionary->size());
541 const base::DictionaryValue* plugins_exception;
542 EXPECT_TRUE(plugins_dictionary->GetDictionaryWithoutPathExpansion(
543 pattern, &plugins_exception));
545 int plugins_exception_value = CONTENT_SETTING_DEFAULT;
546 EXPECT_TRUE(plugins_exception->GetIntegerWithoutPathExpansion(
547 "setting", &plugins_exception_value));
548 EXPECT_EQ(CONTENT_SETTING_ALLOW, plugins_exception_value);
550 int resource_exception_value = CONTENT_SETTING_DEFAULT;
551 const base::DictionaryValue* resource_exception;
552 EXPECT_TRUE(plugins_exception->GetDictionaryWithoutPathExpansion(
553 "per_resource", &resource_exception));
554 EXPECT_TRUE(resource_exception->GetIntegerWithoutPathExpansion(
555 resource_id, &resource_exception_value));
556 EXPECT_EQ(CONTENT_SETTING_BLOCK, resource_exception_value);
559 provider.ShutdownOnUIThread();
562 TEST_F(PrefProviderTest, SyncingNewToOld) {
563 TestingPrefServiceSyncable prefs;
564 PrefProvider::RegisterProfilePrefs(prefs.registry());
565 PrefProvider provider(&prefs, false);
567 const std::string pattern = "google.com,*";
568 const std::string resource_id = "abcde12345";
569 base::DictionaryValue block_exception;
570 block_exception.SetIntegerWithoutPathExpansion(
571 "setting", CONTENT_SETTING_BLOCK);
573 // Add a mouselock exception.
575 DictionaryPrefUpdate update(
576 &prefs, prefs::kContentSettingsMouseLockPatternPairs);
577 base::DictionaryValue* mouselock_dictionary = update.Get();
579 mouselock_dictionary->SetWithoutPathExpansion(
580 pattern, block_exception.DeepCopy());
583 // Add a microphone exception.
585 DictionaryPrefUpdate update(
586 &prefs, prefs::kContentSettingsMediaStreamMicPatternPairs);
587 base::DictionaryValue* microphone_dictionary = update.Get();
589 microphone_dictionary->SetWithoutPathExpansion(
590 pattern, block_exception.DeepCopy());
593 // Add a plugin exception with resource identifiers.
595 DictionaryPrefUpdate update(
596 &prefs, prefs::kContentSettingsPluginsPatternPairs);
597 base::DictionaryValue* plugins_dictionary = update.Get();
599 base::DictionaryValue* plugin_exception = block_exception.DeepCopy();
600 plugins_dictionary->SetWithoutPathExpansion(
601 pattern, plugin_exception);
603 base::DictionaryValue* resource_exception = new base::DictionaryValue();
604 resource_exception->SetIntegerWithoutPathExpansion(
605 resource_id, CONTENT_SETTING_ALLOW);
607 plugin_exception->SetWithoutPathExpansion(
608 "per_resource", resource_exception);
611 // Only the notifications and plugin exceptions should appear in the
612 // old dictionary. We should also have a resource identifiers section
613 // for plugins.
615 DictionaryPrefUpdate update(
616 &prefs, prefs::kContentSettingsPatternPairs);
617 const base::DictionaryValue* old_dictionary = update.Get();
619 const base::DictionaryValue* exception;
620 EXPECT_TRUE(old_dictionary->GetDictionaryWithoutPathExpansion(
621 pattern, &exception));
622 EXPECT_EQ(3u, exception->size());
623 EXPECT_FALSE(exception->HasKey(
624 GetTypeName(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)));
626 int mouselock_exception_value = CONTENT_SETTING_DEFAULT;
627 exception->GetIntegerWithoutPathExpansion(
628 GetTypeName(CONTENT_SETTINGS_TYPE_MOUSELOCK),
629 &mouselock_exception_value);
630 DCHECK_EQ(CONTENT_SETTING_BLOCK, mouselock_exception_value);
632 int plugins_exception_value = CONTENT_SETTING_DEFAULT;
633 exception->GetIntegerWithoutPathExpansion(
634 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS),
635 &plugins_exception_value);
636 DCHECK_EQ(CONTENT_SETTING_BLOCK, plugins_exception_value);
638 int resource_exception_value = CONTENT_SETTING_DEFAULT;
639 const base::DictionaryValue* resource_values;
640 exception->GetDictionaryWithoutPathExpansion(
641 "per_plugin", &resource_values);
642 resource_values->GetIntegerWithoutPathExpansion(
643 resource_id, &resource_exception_value);
644 DCHECK_EQ(CONTENT_SETTING_ALLOW, resource_exception_value);
647 provider.ShutdownOnUIThread();
650 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
651 TEST_F(PrefProviderTest, PMIMigrateOnlyAllow) {
652 TestingPrefServiceSyncable prefs;
653 PrefProvider::RegisterProfilePrefs(prefs.registry());
655 const std::string pattern_1 = "google.com,*";
656 const std::string pattern_2 = "www.google.com,*";
657 base::DictionaryValue* exception_1 = new base::DictionaryValue();
658 base::DictionaryValue* exception_2 = new base::DictionaryValue();
660 // Add both an "allow" and "block" exception for PMI.
661 exception_1->SetIntegerWithoutPathExpansion(
662 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER),
663 CONTENT_SETTING_ALLOW);
664 exception_2->SetIntegerWithoutPathExpansion(
665 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER),
666 CONTENT_SETTING_BLOCK);
668 // Change the old dictionary preference.
670 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
671 base::DictionaryValue* old_dictionary = update.Get();
672 old_dictionary->SetWithoutPathExpansion(pattern_1, exception_1);
673 old_dictionary->SetWithoutPathExpansion(pattern_2, exception_2);
676 // Create the PrefProvider. It should migrate the settings.
677 PrefProvider provider(&prefs, false);
679 // The "block" exception for PMI was migrated, but "allow" was not.
681 DictionaryPrefUpdate update(
682 &prefs, prefs::kContentSettingsProtectedMediaIdentifierPatternPairs);
683 const base::DictionaryValue* pmi_dictionary = update.Get();
684 EXPECT_FALSE(pmi_dictionary->HasKey(pattern_1));
685 EXPECT_TRUE(pmi_dictionary->HasKey(pattern_2));
688 provider.ShutdownOnUIThread();
690 #endif
692 TEST_F(PrefProviderTest, PrefsMigrateVerbatim) {
693 TestingPrefServiceSyncable prefs;
694 PrefProvider::RegisterProfilePrefs(prefs.registry());
696 const std::string pattern_1 = "google.com,*";
697 const std::string pattern_2 = "www.google.com,*";
698 base::DictionaryValue* exception_1 = new base::DictionaryValue();
699 base::DictionaryValue* exception_2 = new base::DictionaryValue();
700 scoped_ptr<base::DictionaryValue> old_dictionary;
702 // Add two exceptions.
703 exception_1->SetIntegerWithoutPathExpansion(
704 GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES),
705 CONTENT_SETTING_ALLOW);
706 exception_2->SetIntegerWithoutPathExpansion(
707 GetTypeName(CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS),
708 CONTENT_SETTING_BLOCK);
710 // Change the old dictionary preference.
712 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
713 base::DictionaryValue* dictionary = update.Get();
714 dictionary->SetWithoutPathExpansion(pattern_1, exception_1);
715 dictionary->SetWithoutPathExpansion(pattern_2, exception_2);
716 old_dictionary.reset(dictionary->DeepCopy());
719 // Create the PrefProvider. It should copy the settings from the old
720 // preference to the new ones.
721 PrefProvider provider(&prefs, false);
723 // Force copying back from the new preferences to the old one.
725 DictionaryPrefUpdate update(
726 &prefs, prefs::kContentSettingsCookiesPatternPairs);
729 DictionaryPrefUpdate update(
730 &prefs, prefs::kContentSettingsAutomaticDownloadsPatternPairs);
733 // Test if the value after copying there and back is the same.
735 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
736 base::DictionaryValue* new_dictionary = update.Get();
737 EXPECT_TRUE(old_dictionary->Equals(new_dictionary));
740 provider.ShutdownOnUIThread();
743 TEST_F(PrefProviderTest, IncognitoInheritsValueMap) {
744 TestingPrefServiceSyncable prefs;
745 PrefProvider::RegisterProfilePrefs(prefs.registry());
747 ContentSettingsPattern pattern_1 =
748 ContentSettingsPattern::FromString("google.com");
749 ContentSettingsPattern pattern_2 =
750 ContentSettingsPattern::FromString("www.google.com");
751 ContentSettingsPattern wildcard =
752 ContentSettingsPattern::FromString("*");
753 scoped_ptr<base::Value> value(
754 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
756 // Create a normal provider and set a setting.
757 PrefProvider normal_provider(&prefs, false);
758 normal_provider.SetWebsiteSetting(pattern_1,
759 wildcard,
760 CONTENT_SETTINGS_TYPE_IMAGES,
761 std::string(),
762 value->DeepCopy());
764 // Non-OTR provider, Non-OTR iterator has one setting (pattern 1).
766 scoped_ptr<RuleIterator> it (normal_provider.GetRuleIterator(
767 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), false));
768 EXPECT_TRUE(it->HasNext());
769 EXPECT_EQ(pattern_1, it->Next().primary_pattern);
770 EXPECT_FALSE(it->HasNext());
773 // Non-OTR provider, OTR iterator has no settings.
775 scoped_ptr<RuleIterator> it(normal_provider.GetRuleIterator(
776 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), true));
777 EXPECT_FALSE(it->HasNext());
780 // Create an incognito provider and set a setting.
781 PrefProvider incognito_provider(&prefs, true);
782 incognito_provider.SetWebsiteSetting(pattern_2,
783 wildcard,
784 CONTENT_SETTINGS_TYPE_IMAGES,
785 std::string(),
786 value->DeepCopy());
788 // OTR provider, non-OTR iterator has one setting (pattern 1).
790 scoped_ptr<RuleIterator> it(incognito_provider.GetRuleIterator(
791 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), false));
792 EXPECT_TRUE(it->HasNext());
793 EXPECT_EQ(pattern_1, it->Next().primary_pattern);
794 EXPECT_FALSE(it->HasNext());
797 // OTR provider, OTR iterator has one setting (pattern 2).
799 scoped_ptr<RuleIterator> it(incognito_provider.GetRuleIterator(
800 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), true));
801 EXPECT_TRUE(it->HasNext());
802 EXPECT_EQ(pattern_2, it->Next().primary_pattern);
803 EXPECT_FALSE(it->HasNext());
806 incognito_provider.ShutdownOnUIThread();
807 normal_provider.ShutdownOnUIThread();
810 TEST_F(PrefProviderTest, ClearAllContentSettingsRules) {
811 TestingPrefServiceSyncable prefs;
812 PrefProvider::RegisterProfilePrefs(prefs.registry());
814 ContentSettingsPattern pattern =
815 ContentSettingsPattern::FromString("google.com");
816 ContentSettingsPattern wildcard =
817 ContentSettingsPattern::FromString("*");
818 scoped_ptr<base::Value> value(
819 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
820 ResourceIdentifier res_id("abcde");
822 PrefProvider provider(&prefs, false);
824 // Non-empty pattern, syncable, empty resource identifier.
825 provider.SetWebsiteSetting(pattern, wildcard, CONTENT_SETTINGS_TYPE_IMAGES,
826 ResourceIdentifier(), value->DeepCopy());
828 // Non-empty pattern, non-syncable, empty resource identifier.
829 provider.SetWebsiteSetting(pattern, wildcard,
830 CONTENT_SETTINGS_TYPE_GEOLOCATION,
831 ResourceIdentifier(), value->DeepCopy());
833 // Non-empty pattern, plugins, non-empty resource identifier.
834 provider.SetWebsiteSetting(pattern, wildcard, CONTENT_SETTINGS_TYPE_PLUGINS,
835 res_id, value->DeepCopy());
837 // Empty pattern, plugins, non-empty resource identifier.
838 provider.SetWebsiteSetting(wildcard, wildcard, CONTENT_SETTINGS_TYPE_PLUGINS,
839 res_id, value->DeepCopy());
841 // Non-empty pattern, syncable, empty resource identifier.
842 provider.SetWebsiteSetting(pattern, wildcard, CONTENT_SETTINGS_TYPE_COOKIES,
843 ResourceIdentifier(), value->DeepCopy());
845 // Non-empty pattern, non-syncable, empty resource identifier.
846 provider.SetWebsiteSetting(pattern, wildcard,
847 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
848 ResourceIdentifier(), value->DeepCopy());
850 provider.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_IMAGES);
851 provider.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_GEOLOCATION);
852 provider.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_PLUGINS);
854 // Test that the new preferences for images, geolocation and plugins
855 // are empty.
856 const char* empty_prefs[] = {
857 prefs::kContentSettingsImagesPatternPairs,
858 prefs::kContentSettingsGeolocationPatternPairs,
859 prefs::kContentSettingsPluginsPatternPairs
862 for (const char* pref : empty_prefs) {
863 DictionaryPrefUpdate update(&prefs, pref);
864 const base::DictionaryValue* dictionary = update.Get();
865 EXPECT_TRUE(dictionary->empty());
868 // Test that the preferences for cookies and notifications are not empty.
869 const char* nonempty_prefs[] = {
870 prefs::kContentSettingsCookiesPatternPairs,
871 prefs::kContentSettingsNotificationsPatternPairs
874 for (const char* pref : nonempty_prefs) {
875 DictionaryPrefUpdate update(&prefs, pref);
876 const base::DictionaryValue* dictionary = update.Get();
877 EXPECT_EQ(1u, dictionary->size());
880 // Test that the old preference only contains cookies and notifications.
882 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
883 const base::DictionaryValue* dictionary = update.Get();
884 const base::DictionaryValue* exception;
885 EXPECT_TRUE(dictionary->GetDictionaryWithoutPathExpansion(
886 CreatePatternString(pattern, wildcard), &exception));
887 EXPECT_EQ(1u, exception->size());
888 EXPECT_TRUE(exception->HasKey(GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES)));
890 // The notification setting was not cleared, but it was also never written
891 // to the old preference, as it is unsyncable.
894 provider.ShutdownOnUIThread();
897 } // namespace content_settings