No dual_mode on Win10+ shortcuts.
[chromium-blink-merge.git] / chrome / browser / content_settings / content_settings_pref_provider_unittest.cc
blobde9b1a7ea5774c5127210eeabc30fe25b5f83ceb
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 which did not need to be migrated.
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 exceptions for new content settings types added after the migration.
493 exceptions->SetIntegerWithoutPathExpansion(
494 GetTypeName(CONTENT_SETTINGS_TYPE_SITE_ENGAGEMENT),
495 CONTENT_SETTING_ALLOW);
497 // Add a regular exception for plugins, then one with a resource identifier.
498 exceptions->SetIntegerWithoutPathExpansion(
499 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS), CONTENT_SETTING_ALLOW);
500 plugin_resources->SetIntegerWithoutPathExpansion(
501 resource_id, CONTENT_SETTING_BLOCK);
502 exceptions->SetWithoutPathExpansion(
503 "per_plugin", plugin_resources);
505 // Change the old dictionary preference and observe changes
506 // in the new preferences.
508 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
509 base::DictionaryValue* old_dictionary = update.Get();
510 old_dictionary->SetWithoutPathExpansion(pattern, exceptions);
513 // The images exception was synced.
515 DictionaryPrefUpdate update(
516 &prefs, prefs::kContentSettingsImagesPatternPairs);
517 const base::DictionaryValue* images_dictionary = update.Get();
519 EXPECT_EQ(1u, images_dictionary->size());
520 const base::DictionaryValue* images_exception;
521 EXPECT_TRUE(images_dictionary->GetDictionaryWithoutPathExpansion(
522 pattern, &images_exception));
524 // And it has a correct value.
525 int images_exception_value = CONTENT_SETTING_DEFAULT;
526 EXPECT_TRUE(images_exception->GetIntegerWithoutPathExpansion(
527 "setting", &images_exception_value));
528 EXPECT_EQ(CONTENT_SETTING_ALLOW, images_exception_value);
531 // The app banner exception was not synced.
533 DictionaryPrefUpdate update(
534 &prefs, prefs::kContentSettingsAppBannerPatternPairs);
535 const base::DictionaryValue* app_banner_dictionary = update.Get();
536 EXPECT_TRUE(app_banner_dictionary->empty());
539 // The plugins exception was synced, together with the resource identifiers.
541 DictionaryPrefUpdate update(
542 &prefs, prefs::kContentSettingsPluginsPatternPairs);
543 const base::DictionaryValue* plugins_dictionary = update.Get();
544 EXPECT_EQ(1u, plugins_dictionary->size());
546 const base::DictionaryValue* plugins_exception;
547 EXPECT_TRUE(plugins_dictionary->GetDictionaryWithoutPathExpansion(
548 pattern, &plugins_exception));
550 int plugins_exception_value = CONTENT_SETTING_DEFAULT;
551 EXPECT_TRUE(plugins_exception->GetIntegerWithoutPathExpansion(
552 "setting", &plugins_exception_value));
553 EXPECT_EQ(CONTENT_SETTING_ALLOW, plugins_exception_value);
555 int resource_exception_value = CONTENT_SETTING_DEFAULT;
556 const base::DictionaryValue* resource_exception;
557 EXPECT_TRUE(plugins_exception->GetDictionaryWithoutPathExpansion(
558 "per_resource", &resource_exception));
559 EXPECT_TRUE(resource_exception->GetIntegerWithoutPathExpansion(
560 resource_id, &resource_exception_value));
561 EXPECT_EQ(CONTENT_SETTING_BLOCK, resource_exception_value);
564 provider.ShutdownOnUIThread();
567 TEST_F(PrefProviderTest, SyncingNewToOld) {
568 TestingPrefServiceSyncable prefs;
569 PrefProvider::RegisterProfilePrefs(prefs.registry());
570 PrefProvider provider(&prefs, false);
572 const std::string pattern = "google.com,*";
573 const std::string resource_id = "abcde12345";
574 base::DictionaryValue block_exception;
575 block_exception.SetIntegerWithoutPathExpansion(
576 "setting", CONTENT_SETTING_BLOCK);
578 // Add a mouselock exception.
580 DictionaryPrefUpdate update(
581 &prefs, prefs::kContentSettingsMouseLockPatternPairs);
582 base::DictionaryValue* mouselock_dictionary = update.Get();
584 mouselock_dictionary->SetWithoutPathExpansion(
585 pattern, block_exception.DeepCopy());
588 // Add a microphone exception.
590 DictionaryPrefUpdate update(
591 &prefs, prefs::kContentSettingsMediaStreamMicPatternPairs);
592 base::DictionaryValue* microphone_dictionary = update.Get();
594 microphone_dictionary->SetWithoutPathExpansion(
595 pattern, block_exception.DeepCopy());
598 // Add a plugin exception with resource identifiers.
600 DictionaryPrefUpdate update(
601 &prefs, prefs::kContentSettingsPluginsPatternPairs);
602 base::DictionaryValue* plugins_dictionary = update.Get();
604 base::DictionaryValue* plugin_exception = block_exception.DeepCopy();
605 plugins_dictionary->SetWithoutPathExpansion(
606 pattern, plugin_exception);
608 base::DictionaryValue* resource_exception = new base::DictionaryValue();
609 resource_exception->SetIntegerWithoutPathExpansion(
610 resource_id, CONTENT_SETTING_ALLOW);
612 plugin_exception->SetWithoutPathExpansion(
613 "per_resource", resource_exception);
616 // Only the notifications and plugin exceptions should appear in the
617 // old dictionary. We should also have a resource identifiers section
618 // for plugins.
620 DictionaryPrefUpdate update(
621 &prefs, prefs::kContentSettingsPatternPairs);
622 const base::DictionaryValue* old_dictionary = update.Get();
624 const base::DictionaryValue* exception;
625 EXPECT_TRUE(old_dictionary->GetDictionaryWithoutPathExpansion(
626 pattern, &exception));
627 EXPECT_EQ(3u, exception->size());
628 EXPECT_FALSE(exception->HasKey(
629 GetTypeName(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)));
631 int mouselock_exception_value = CONTENT_SETTING_DEFAULT;
632 exception->GetIntegerWithoutPathExpansion(
633 GetTypeName(CONTENT_SETTINGS_TYPE_MOUSELOCK),
634 &mouselock_exception_value);
635 DCHECK_EQ(CONTENT_SETTING_BLOCK, mouselock_exception_value);
637 int plugins_exception_value = CONTENT_SETTING_DEFAULT;
638 exception->GetIntegerWithoutPathExpansion(
639 GetTypeName(CONTENT_SETTINGS_TYPE_PLUGINS),
640 &plugins_exception_value);
641 DCHECK_EQ(CONTENT_SETTING_BLOCK, plugins_exception_value);
643 int resource_exception_value = CONTENT_SETTING_DEFAULT;
644 const base::DictionaryValue* resource_values;
645 exception->GetDictionaryWithoutPathExpansion(
646 "per_plugin", &resource_values);
647 resource_values->GetIntegerWithoutPathExpansion(
648 resource_id, &resource_exception_value);
649 DCHECK_EQ(CONTENT_SETTING_ALLOW, resource_exception_value);
652 provider.ShutdownOnUIThread();
655 #if defined(OS_CHROMEOS) || defined(OS_ANDROID)
656 TEST_F(PrefProviderTest, PMIMigrateOnlyAllow) {
657 TestingPrefServiceSyncable prefs;
658 PrefProvider::RegisterProfilePrefs(prefs.registry());
660 const std::string pattern_1 = "google.com,*";
661 const std::string pattern_2 = "www.google.com,*";
662 base::DictionaryValue* exception_1 = new base::DictionaryValue();
663 base::DictionaryValue* exception_2 = new base::DictionaryValue();
665 // Add both an "allow" and "block" exception for PMI.
666 exception_1->SetIntegerWithoutPathExpansion(
667 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER),
668 CONTENT_SETTING_ALLOW);
669 exception_2->SetIntegerWithoutPathExpansion(
670 GetTypeName(CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER),
671 CONTENT_SETTING_BLOCK);
673 // Change the old dictionary preference.
675 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
676 base::DictionaryValue* old_dictionary = update.Get();
677 old_dictionary->SetWithoutPathExpansion(pattern_1, exception_1);
678 old_dictionary->SetWithoutPathExpansion(pattern_2, exception_2);
681 // Create the PrefProvider. It should migrate the settings.
682 PrefProvider provider(&prefs, false);
684 // The "block" exception for PMI was migrated, but "allow" was not.
686 DictionaryPrefUpdate update(
687 &prefs, prefs::kContentSettingsProtectedMediaIdentifierPatternPairs);
688 const base::DictionaryValue* pmi_dictionary = update.Get();
689 EXPECT_FALSE(pmi_dictionary->HasKey(pattern_1));
690 EXPECT_TRUE(pmi_dictionary->HasKey(pattern_2));
693 provider.ShutdownOnUIThread();
695 #endif
697 TEST_F(PrefProviderTest, PrefsMigrateVerbatim) {
698 TestingPrefServiceSyncable prefs;
699 PrefProvider::RegisterProfilePrefs(prefs.registry());
701 const std::string pattern_1 = "google.com,*";
702 const std::string pattern_2 = "www.google.com,*";
703 base::DictionaryValue* exception_1 = new base::DictionaryValue();
704 base::DictionaryValue* exception_2 = new base::DictionaryValue();
705 scoped_ptr<base::DictionaryValue> old_dictionary;
707 // Add two exceptions.
708 exception_1->SetIntegerWithoutPathExpansion(
709 GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES),
710 CONTENT_SETTING_ALLOW);
711 exception_2->SetIntegerWithoutPathExpansion(
712 GetTypeName(CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS),
713 CONTENT_SETTING_BLOCK);
715 // Change the old dictionary preference.
717 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
718 base::DictionaryValue* dictionary = update.Get();
719 dictionary->SetWithoutPathExpansion(pattern_1, exception_1);
720 dictionary->SetWithoutPathExpansion(pattern_2, exception_2);
721 old_dictionary.reset(dictionary->DeepCopy());
724 // Create the PrefProvider. It should copy the settings from the old
725 // preference to the new ones.
726 PrefProvider provider(&prefs, false);
728 // Force copying back from the new preferences to the old one.
730 DictionaryPrefUpdate update(
731 &prefs, prefs::kContentSettingsCookiesPatternPairs);
734 DictionaryPrefUpdate update(
735 &prefs, prefs::kContentSettingsAutomaticDownloadsPatternPairs);
738 // Test if the value after copying there and back is the same.
740 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
741 base::DictionaryValue* new_dictionary = update.Get();
742 EXPECT_TRUE(old_dictionary->Equals(new_dictionary));
745 provider.ShutdownOnUIThread();
748 TEST_F(PrefProviderTest, IncognitoInheritsValueMap) {
749 TestingPrefServiceSyncable prefs;
750 PrefProvider::RegisterProfilePrefs(prefs.registry());
752 ContentSettingsPattern pattern_1 =
753 ContentSettingsPattern::FromString("google.com");
754 ContentSettingsPattern pattern_2 =
755 ContentSettingsPattern::FromString("www.google.com");
756 ContentSettingsPattern wildcard =
757 ContentSettingsPattern::FromString("*");
758 scoped_ptr<base::Value> value(
759 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
761 // Create a normal provider and set a setting.
762 PrefProvider normal_provider(&prefs, false);
763 normal_provider.SetWebsiteSetting(pattern_1,
764 wildcard,
765 CONTENT_SETTINGS_TYPE_IMAGES,
766 std::string(),
767 value->DeepCopy());
769 // Non-OTR provider, Non-OTR iterator has one setting (pattern 1).
771 scoped_ptr<RuleIterator> it(normal_provider.GetRuleIterator(
772 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), false));
773 EXPECT_TRUE(it->HasNext());
774 EXPECT_EQ(pattern_1, it->Next().primary_pattern);
775 EXPECT_FALSE(it->HasNext());
778 // Non-OTR provider, OTR iterator has no settings.
780 scoped_ptr<RuleIterator> it(normal_provider.GetRuleIterator(
781 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), true));
782 EXPECT_FALSE(it->HasNext());
785 // Create an incognito provider and set a setting.
786 PrefProvider incognito_provider(&prefs, true);
787 incognito_provider.SetWebsiteSetting(pattern_2,
788 wildcard,
789 CONTENT_SETTINGS_TYPE_IMAGES,
790 std::string(),
791 value->DeepCopy());
793 // OTR provider, non-OTR iterator has one setting (pattern 1).
795 scoped_ptr<RuleIterator> it(incognito_provider.GetRuleIterator(
796 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), false));
797 EXPECT_TRUE(it->HasNext());
798 EXPECT_EQ(pattern_1, it->Next().primary_pattern);
799 EXPECT_FALSE(it->HasNext());
802 // OTR provider, OTR iterator has one setting (pattern 2).
804 scoped_ptr<RuleIterator> it(incognito_provider.GetRuleIterator(
805 CONTENT_SETTINGS_TYPE_IMAGES, std::string(), true));
806 EXPECT_TRUE(it->HasNext());
807 EXPECT_EQ(pattern_2, it->Next().primary_pattern);
808 EXPECT_FALSE(it->HasNext());
811 incognito_provider.ShutdownOnUIThread();
812 normal_provider.ShutdownOnUIThread();
815 TEST_F(PrefProviderTest, ClearAllContentSettingsRules) {
816 TestingPrefServiceSyncable prefs;
817 PrefProvider::RegisterProfilePrefs(prefs.registry());
819 ContentSettingsPattern pattern =
820 ContentSettingsPattern::FromString("google.com");
821 ContentSettingsPattern wildcard =
822 ContentSettingsPattern::FromString("*");
823 scoped_ptr<base::Value> value(
824 new base::FundamentalValue(CONTENT_SETTING_ALLOW));
825 ResourceIdentifier res_id("abcde");
827 PrefProvider provider(&prefs, false);
829 // Non-empty pattern, syncable, empty resource identifier.
830 provider.SetWebsiteSetting(pattern, wildcard, CONTENT_SETTINGS_TYPE_IMAGES,
831 ResourceIdentifier(), value->DeepCopy());
833 // Non-empty pattern, non-syncable, empty resource identifier.
834 provider.SetWebsiteSetting(pattern, wildcard,
835 CONTENT_SETTINGS_TYPE_GEOLOCATION,
836 ResourceIdentifier(), value->DeepCopy());
838 // Non-empty pattern, plugins, non-empty resource identifier.
839 provider.SetWebsiteSetting(pattern, wildcard, CONTENT_SETTINGS_TYPE_PLUGINS,
840 res_id, value->DeepCopy());
842 // Empty pattern, plugins, non-empty resource identifier.
843 provider.SetWebsiteSetting(wildcard, wildcard, CONTENT_SETTINGS_TYPE_PLUGINS,
844 res_id, value->DeepCopy());
846 // Non-empty pattern, syncable, empty resource identifier.
847 provider.SetWebsiteSetting(pattern, wildcard, CONTENT_SETTINGS_TYPE_COOKIES,
848 ResourceIdentifier(), value->DeepCopy());
850 // Non-empty pattern, non-syncable, empty resource identifier.
851 provider.SetWebsiteSetting(pattern, wildcard,
852 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
853 ResourceIdentifier(), value->DeepCopy());
855 provider.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_IMAGES);
856 provider.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_GEOLOCATION);
857 provider.ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_PLUGINS);
859 // Test that the new preferences for images, geolocation and plugins
860 // are empty.
861 const char* empty_prefs[] = {
862 prefs::kContentSettingsImagesPatternPairs,
863 prefs::kContentSettingsGeolocationPatternPairs,
864 prefs::kContentSettingsPluginsPatternPairs
867 for (const char* pref : empty_prefs) {
868 DictionaryPrefUpdate update(&prefs, pref);
869 const base::DictionaryValue* dictionary = update.Get();
870 EXPECT_TRUE(dictionary->empty());
873 // Test that the preferences for cookies and notifications are not empty.
874 const char* nonempty_prefs[] = {
875 prefs::kContentSettingsCookiesPatternPairs,
876 prefs::kContentSettingsNotificationsPatternPairs
879 for (const char* pref : nonempty_prefs) {
880 DictionaryPrefUpdate update(&prefs, pref);
881 const base::DictionaryValue* dictionary = update.Get();
882 EXPECT_EQ(1u, dictionary->size());
885 // Test that the old preference only contains cookies and notifications.
887 DictionaryPrefUpdate update(&prefs, prefs::kContentSettingsPatternPairs);
888 const base::DictionaryValue* dictionary = update.Get();
889 const base::DictionaryValue* exception;
890 EXPECT_TRUE(dictionary->GetDictionaryWithoutPathExpansion(
891 CreatePatternString(pattern, wildcard), &exception));
892 EXPECT_EQ(1u, exception->size());
893 EXPECT_TRUE(exception->HasKey(GetTypeName(CONTENT_SETTINGS_TYPE_COOKIES)));
895 // The notification setting was not cleared, but it was also never written
896 // to the old preference, as it is unsyncable.
899 provider.ShutdownOnUIThread();
902 } // namespace content_settings