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 "chrome/browser/extensions/api/content_settings/content_settings_store.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "components/content_settings/core/browser/content_settings_rule.h"
9 #include "components/content_settings/core/browser/content_settings_utils.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
14 using ::testing::Mock
;
16 namespace extensions
{
20 void CheckRule(const content_settings::Rule
& rule
,
21 const ContentSettingsPattern
& primary_pattern
,
22 const ContentSettingsPattern
& secondary_pattern
,
23 ContentSetting setting
) {
24 EXPECT_EQ(primary_pattern
.ToString(), rule
.primary_pattern
.ToString());
25 EXPECT_EQ(secondary_pattern
.ToString(), rule
.secondary_pattern
.ToString());
26 EXPECT_EQ(setting
, content_settings::ValueToContentSetting(rule
.value
.get()));
29 // Helper class which returns monotonically-increasing base::Time objects.
32 FakeTimer() : internal_(0) {}
34 base::Time
GetNext() {
35 return base::Time::FromInternalValue(++internal_
);
42 class MockContentSettingsStoreObserver
43 : public ContentSettingsStore::Observer
{
45 MOCK_METHOD2(OnContentSettingChanged
,
46 void(const std::string
& extension_id
, bool incognito
));
49 ContentSetting
GetContentSettingFromStore(
50 const ContentSettingsStore
* store
,
51 const GURL
& primary_url
, const GURL
& secondary_url
,
52 ContentSettingsType content_type
,
53 const std::string
& resource_identifier
,
55 scoped_ptr
<content_settings::RuleIterator
> rule_iterator(
56 store
->GetRuleIterator(content_type
, resource_identifier
, incognito
));
57 scoped_ptr
<base::Value
> setting(
58 content_settings::GetContentSettingValueAndPatterns(
59 rule_iterator
.get(), primary_url
, secondary_url
, NULL
, NULL
));
60 return content_settings::ValueToContentSetting(setting
.get());
63 void GetSettingsForOneTypeFromStore(
64 const ContentSettingsStore
* store
,
65 ContentSettingsType content_type
,
66 const std::string
& resource_identifier
,
68 std::vector
<content_settings::Rule
>* rules
) {
70 scoped_ptr
<content_settings::RuleIterator
> rule_iterator(
71 store
->GetRuleIterator(content_type
, resource_identifier
, incognito
));
72 while (rule_iterator
->HasNext())
73 rules
->push_back(rule_iterator
->Next());
78 class ContentSettingsStoreTest
: public ::testing::Test
{
80 ContentSettingsStoreTest() :
81 store_(new ContentSettingsStore()) {
85 void RegisterExtension(const std::string
& ext_id
) {
86 store_
->RegisterExtension(ext_id
, timer_
.GetNext(), true);
89 ContentSettingsStore
* store() {
95 scoped_refptr
<ContentSettingsStore
> store_
;
98 TEST_F(ContentSettingsStoreTest
, RegisterUnregister
) {
99 ::testing::StrictMock
<MockContentSettingsStoreObserver
> observer
;
100 store()->AddObserver(&observer
);
102 GURL
url("http://www.youtube.com");
104 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
105 GetContentSettingFromStore(store(),
108 CONTENT_SETTINGS_TYPE_COOKIES
,
112 // Register first extension
113 std::string
ext_id("my_extension");
114 RegisterExtension(ext_id
);
116 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
117 GetContentSettingFromStore(store(),
120 CONTENT_SETTINGS_TYPE_COOKIES
,
125 ContentSettingsPattern pattern
=
126 ContentSettingsPattern::FromURL(GURL("http://www.youtube.com"));
127 EXPECT_CALL(observer
, OnContentSettingChanged(ext_id
, false));
128 store()->SetExtensionContentSetting(ext_id
,
131 CONTENT_SETTINGS_TYPE_COOKIES
,
133 CONTENT_SETTING_ALLOW
,
134 kExtensionPrefsScopeRegular
);
135 Mock::VerifyAndClear(&observer
);
137 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
138 GetContentSettingFromStore(store(),
141 CONTENT_SETTINGS_TYPE_COOKIES
,
145 // Register second extension.
146 std::string
ext_id_2("my_second_extension");
147 RegisterExtension(ext_id_2
);
148 EXPECT_CALL(observer
, OnContentSettingChanged(ext_id_2
, false));
149 store()->SetExtensionContentSetting(ext_id_2
,
152 CONTENT_SETTINGS_TYPE_COOKIES
,
154 CONTENT_SETTING_BLOCK
,
155 kExtensionPrefsScopeRegular
);
157 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
158 GetContentSettingFromStore(store(),
161 CONTENT_SETTINGS_TYPE_COOKIES
,
165 // Unregister first extension. This shouldn't change the setting.
166 EXPECT_CALL(observer
, OnContentSettingChanged(ext_id
, false));
167 store()->UnregisterExtension(ext_id
);
168 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
169 GetContentSettingFromStore(store(),
172 CONTENT_SETTINGS_TYPE_COOKIES
,
175 Mock::VerifyAndClear(&observer
);
177 // Unregister second extension. This should reset the setting to its default
179 EXPECT_CALL(observer
, OnContentSettingChanged(ext_id_2
, false));
180 store()->UnregisterExtension(ext_id_2
);
181 EXPECT_EQ(CONTENT_SETTING_DEFAULT
,
182 GetContentSettingFromStore(store(),
185 CONTENT_SETTINGS_TYPE_COOKIES
,
189 store()->RemoveObserver(&observer
);
192 TEST_F(ContentSettingsStoreTest
, GetAllSettings
) {
193 bool incognito
= false;
194 std::vector
<content_settings::Rule
> rules
;
195 GetSettingsForOneTypeFromStore(
196 store(), CONTENT_SETTINGS_TYPE_COOKIES
, std::string(), incognito
, &rules
);
197 ASSERT_EQ(0u, rules
.size());
199 // Register first extension.
200 std::string
ext_id("my_extension");
201 RegisterExtension(ext_id
);
202 ContentSettingsPattern pattern
=
203 ContentSettingsPattern::FromURL(GURL("http://www.youtube.com"));
204 store()->SetExtensionContentSetting(ext_id
,
207 CONTENT_SETTINGS_TYPE_COOKIES
,
209 CONTENT_SETTING_ALLOW
,
210 kExtensionPrefsScopeRegular
);
212 GetSettingsForOneTypeFromStore(
213 store(), CONTENT_SETTINGS_TYPE_COOKIES
, std::string(), incognito
, &rules
);
214 ASSERT_EQ(1u, rules
.size());
215 CheckRule(rules
[0], pattern
, pattern
, CONTENT_SETTING_ALLOW
);
217 // Register second extension.
218 std::string
ext_id_2("my_second_extension");
219 RegisterExtension(ext_id_2
);
220 ContentSettingsPattern pattern_2
=
221 ContentSettingsPattern::FromURL(GURL("http://www.example.com"));
222 store()->SetExtensionContentSetting(ext_id_2
,
225 CONTENT_SETTINGS_TYPE_COOKIES
,
227 CONTENT_SETTING_BLOCK
,
228 kExtensionPrefsScopeRegular
);
230 GetSettingsForOneTypeFromStore(
231 store(), CONTENT_SETTINGS_TYPE_COOKIES
, std::string(), incognito
, &rules
);
232 ASSERT_EQ(2u, rules
.size());
233 // Rules appear in the reverse installation order of the extensions.
234 CheckRule(rules
[0], pattern_2
, pattern_2
, CONTENT_SETTING_BLOCK
);
235 CheckRule(rules
[1], pattern
, pattern
, CONTENT_SETTING_ALLOW
);
237 // Disable first extension.
238 store()->SetExtensionState(ext_id
, false);
240 GetSettingsForOneTypeFromStore(
241 store(), CONTENT_SETTINGS_TYPE_COOKIES
, std::string(), incognito
, &rules
);
242 ASSERT_EQ(1u, rules
.size());
243 CheckRule(rules
[0], pattern_2
, pattern_2
, CONTENT_SETTING_BLOCK
);
245 // Uninstall second extension.
246 store()->UnregisterExtension(ext_id_2
);
248 GetSettingsForOneTypeFromStore(
249 store(), CONTENT_SETTINGS_TYPE_COOKIES
, std::string(), incognito
, &rules
);
250 ASSERT_EQ(0u, rules
.size());
253 } // namespace extensions