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/declarative/rules_registry.h"
7 // Here we test the TestRulesRegistry which is the simplest possible
8 // implementation of RulesRegistryWithCache as a proxy for
9 // RulesRegistryWithCache.
11 #include "base/command_line.h"
12 #include "base/message_loop/message_loop.h"
13 #include "chrome/browser/extensions/api/declarative/rules_cache_delegate.h"
14 #include "chrome/browser/extensions/api/declarative/test_rules_registry.h"
15 #include "chrome/browser/extensions/extension_prefs.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/test_extension_system.h"
18 #include "chrome/browser/value_store/testing_value_store.h"
19 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/extensions/extension_test_util.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "content/public/test/test_browser_thread.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 #if defined(OS_CHROMEOS)
26 #include "chrome/browser/chromeos/login/user_manager.h"
27 #include "chrome/browser/chromeos/settings/cros_settings.h"
28 #include "chrome/browser/chromeos/settings/device_settings_service.h"
31 using extension_test_util::LoadManifestUnchecked;
34 // The |kExtensionId| needs to pass the Extension::IdIsValid test.
35 const char kExtensionId[] = "abcdefghijklmnopabcdefghijklmnop";
36 const char kExtension2Id[] = "ponmlkjihgfedcbaponmlkjihgfedcba";
37 const char kRuleId[] = "rule";
38 const char kRule2Id[] = "rule2";
41 namespace extensions {
43 class RulesRegistryWithCacheTest : public testing::Test {
45 RulesRegistryWithCacheTest()
46 : ui_thread_(content::BrowserThread::UI, &message_loop_),
47 file_thread_(content::BrowserThread::FILE, &message_loop_),
48 registry_(new TestRulesRegistry(content::BrowserThread::UI,
49 "" /*event_name*/)) {}
51 virtual ~RulesRegistryWithCacheTest() {}
53 virtual void TearDown() OVERRIDE {
54 // Make sure that deletion traits of all registries are executed.
56 message_loop_.RunUntilIdle();
59 std::string AddRule(const std::string& extension_id,
60 const std::string& rule_id,
61 TestRulesRegistry* registry) {
62 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > add_rules;
63 add_rules.push_back(make_linked_ptr(new extensions::RulesRegistry::Rule));
64 add_rules[0]->id.reset(new std::string(rule_id));
65 return registry->AddRules(extension_id, add_rules);
68 std::string AddRule(const std::string& extension_id,
69 const std::string& rule_id) {
70 return AddRule(extension_id, rule_id, registry_.get());
73 std::string RemoveRule(const std::string& extension_id,
74 const std::string& rule_id) {
75 std::vector<std::string> remove_rules;
76 remove_rules.push_back(rule_id);
77 return registry_->RemoveRules(extension_id, remove_rules);
80 int GetNumberOfRules(const std::string& extension_id,
81 TestRulesRegistry* registry) {
82 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > get_rules;
83 std::string error = registry->GetAllRules(extension_id, &get_rules);
85 return get_rules.size();
88 int GetNumberOfRules(const std::string& extension_id) {
89 return GetNumberOfRules(extension_id, registry_.get());
93 base::MessageLoop message_loop_;
94 content::TestBrowserThread ui_thread_;
95 content::TestBrowserThread file_thread_;
96 scoped_refptr<TestRulesRegistry> registry_;
97 #if defined OS_CHROMEOS
98 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
99 chromeos::ScopedTestCrosSettings test_cros_settings_;
100 chromeos::ScopedTestUserManager test_user_manager_;
104 TEST_F(RulesRegistryWithCacheTest, AddRules) {
105 // Check that nothing happens if the concrete RulesRegistry refuses to insert
107 registry_->SetResult("Error");
108 EXPECT_EQ("Error", AddRule(kExtensionId, kRuleId));
109 EXPECT_EQ(0, GetNumberOfRules(kExtensionId));
110 registry_->SetResult(std::string());
112 // Check that rules can be inserted.
113 EXPECT_EQ("", AddRule(kExtensionId, kRule2Id));
114 EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
116 // Check that rules cannot be inserted twice with the same kRuleId.
117 EXPECT_NE("", AddRule(kExtensionId, kRuleId));
118 EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
120 // Check that different extensions may use the same kRuleId.
121 EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
122 EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
123 EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
126 TEST_F(RulesRegistryWithCacheTest, RemoveRules) {
128 EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
129 EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
130 EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
131 EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
133 // Check that nothing happens if the concrete RuleRegistry refuses to remove
135 registry_->SetResult("Error");
136 EXPECT_EQ("Error", RemoveRule(kExtensionId, kRuleId));
137 EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
138 registry_->SetResult(std::string());
140 // Check that nothing happens if a rule does not exist.
141 EXPECT_EQ("", RemoveRule(kExtensionId, "unknown_rule"));
142 EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
144 // Check that rules may be removed and only for the correct extension.
145 EXPECT_EQ("", RemoveRule(kExtensionId, kRuleId));
146 EXPECT_EQ(0, GetNumberOfRules(kExtensionId));
147 EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
150 TEST_F(RulesRegistryWithCacheTest, RemoveAllRules) {
152 EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
153 EXPECT_EQ("", AddRule(kExtensionId, kRule2Id));
154 EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
155 EXPECT_EQ(2, GetNumberOfRules(kExtensionId));
156 EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
158 // Check that nothing happens if the concrete RuleRegistry refuses to remove
160 registry_->SetResult("Error");
161 EXPECT_EQ("Error", registry_->RemoveAllRules(kExtensionId));
162 EXPECT_EQ(2, GetNumberOfRules(kExtensionId));
163 registry_->SetResult(std::string());
165 // Check that rules may be removed and only for the correct extension.
166 EXPECT_EQ("", registry_->RemoveAllRules(kExtensionId));
167 EXPECT_EQ(0, GetNumberOfRules(kExtensionId));
168 EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
171 TEST_F(RulesRegistryWithCacheTest, GetRules) {
173 EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
174 EXPECT_EQ("", AddRule(kExtensionId, kRule2Id));
175 EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
177 // Check that we get the correct rule and unknown rules are ignored.
178 std::vector<std::string> rules_to_get;
179 rules_to_get.push_back(kRuleId);
180 rules_to_get.push_back("unknown_rule");
181 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > gotten_rules;
182 EXPECT_EQ("", registry_->GetRules(kExtensionId, rules_to_get, &gotten_rules));
183 ASSERT_EQ(1u, gotten_rules.size());
184 ASSERT_TRUE(gotten_rules[0]->id.get());
185 EXPECT_EQ(kRuleId, *(gotten_rules[0]->id));
188 TEST_F(RulesRegistryWithCacheTest, GetAllRules) {
190 EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
191 EXPECT_EQ("", AddRule(kExtensionId, kRule2Id));
192 EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
194 // Check that we get the correct rules.
195 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > gotten_rules;
196 EXPECT_EQ("", registry_->GetAllRules(kExtensionId, &gotten_rules));
197 EXPECT_EQ(2u, gotten_rules.size());
198 ASSERT_TRUE(gotten_rules[0]->id.get());
199 ASSERT_TRUE(gotten_rules[1]->id.get());
200 EXPECT_TRUE( (kRuleId == *(gotten_rules[0]->id) &&
201 kRule2Id == *(gotten_rules[1]->id)) ||
202 (kRuleId == *(gotten_rules[1]->id) &&
203 kRule2Id == *(gotten_rules[0]->id)) );
206 TEST_F(RulesRegistryWithCacheTest, OnExtensionUnloaded) {
208 EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
209 EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
211 // Check that the correct rules are removed.
212 registry_->OnExtensionUnloaded(kExtensionId);
213 EXPECT_EQ(0, GetNumberOfRules(kExtensionId));
214 EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
217 TEST_F(RulesRegistryWithCacheTest, DeclarativeRulesStored) {
218 TestingProfile profile;
219 // TestingProfile::Init makes sure that the factory method for a corresponding
220 // extension system creates a TestExtensionSystem.
221 extensions::TestExtensionSystem* system =
222 static_cast<extensions::TestExtensionSystem*>(
223 extensions::ExtensionSystem::Get(&profile));
224 ExtensionPrefs* extension_prefs = system->CreateExtensionPrefs(
225 CommandLine::ForCurrentProcess(), base::FilePath());
226 system->CreateExtensionService(
227 CommandLine::ForCurrentProcess(), base::FilePath(), false);
228 // The value store is first created during CreateExtensionService.
229 TestingValueStore* store = system->value_store();
231 const std::string event_name("testEvent");
232 const std::string rules_stored_key(
233 RulesCacheDelegate::GetRulesStoredKey(
234 event_name, profile.IsOffTheRecord()));
235 scoped_ptr<RulesCacheDelegate> cache_delegate(new RulesCacheDelegate(false));
236 scoped_refptr<RulesRegistry> registry(new TestRulesRegistry(
237 &profile, event_name, content::BrowserThread::UI, cache_delegate.get()));
239 // 1. Test the handling of preferences.
240 // Default value is always true.
241 EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
243 extension_prefs->UpdateExtensionPref(
244 kExtensionId, rules_stored_key, new base::FundamentalValue(false));
245 EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
247 extension_prefs->UpdateExtensionPref(
248 kExtensionId, rules_stored_key, new base::FundamentalValue(true));
249 EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
251 // 2. Test writing behavior.
252 int write_count = store->write_count();
254 scoped_ptr<base::ListValue> value(new base::ListValue);
255 value->AppendBoolean(true);
256 cache_delegate->WriteToStorage(kExtensionId, value.PassAs<base::Value>());
257 EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
258 message_loop_.RunUntilIdle();
259 EXPECT_EQ(write_count + 1, store->write_count());
260 write_count = store->write_count();
262 value.reset(new base::ListValue);
263 cache_delegate->WriteToStorage(kExtensionId, value.PassAs<base::Value>());
264 EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
265 message_loop_.RunUntilIdle();
266 // No rules currently, but previously there were, so we expect a write.
267 EXPECT_EQ(write_count + 1, store->write_count());
268 write_count = store->write_count();
270 value.reset(new base::ListValue);
271 cache_delegate->WriteToStorage(kExtensionId, value.PassAs<base::Value>());
272 EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
273 message_loop_.RunUntilIdle();
274 EXPECT_EQ(write_count, store->write_count());
276 // 3. Test reading behavior.
277 int read_count = store->read_count();
279 cache_delegate->SetDeclarativeRulesStored(kExtensionId, false);
280 cache_delegate->ReadFromStorage(kExtensionId);
281 message_loop_.RunUntilIdle();
282 EXPECT_EQ(read_count, store->read_count());
283 read_count = store->read_count();
285 cache_delegate->SetDeclarativeRulesStored(kExtensionId, true);
286 cache_delegate->ReadFromStorage(kExtensionId);
287 message_loop_.RunUntilIdle();
288 EXPECT_EQ(read_count + 1, store->read_count());
291 // Test that each registry has its own "are some rules stored" flag.
292 TEST_F(RulesRegistryWithCacheTest, RulesStoredFlagMultipleRegistries) {
293 TestingProfile profile;
294 // TestingProfile::Init makes sure that the factory method for a corresponding
295 // extension system creates a TestExtensionSystem.
296 extensions::TestExtensionSystem* system =
297 static_cast<extensions::TestExtensionSystem*>(
298 extensions::ExtensionSystem::Get(&profile));
299 ExtensionPrefs* extension_prefs = system->CreateExtensionPrefs(
300 CommandLine::ForCurrentProcess(), base::FilePath());
302 const std::string event_name1("testEvent1");
303 const std::string event_name2("testEvent2");
304 const std::string rules_stored_key1(
305 RulesCacheDelegate::GetRulesStoredKey(
306 event_name1, profile.IsOffTheRecord()));
307 const std::string rules_stored_key2(
308 RulesCacheDelegate::GetRulesStoredKey(
309 event_name2, profile.IsOffTheRecord()));
310 scoped_ptr<RulesCacheDelegate> cache_delegate1(new RulesCacheDelegate(false));
311 scoped_refptr<RulesRegistry> registry1(new TestRulesRegistry(
312 &profile, event_name1, content::BrowserThread::UI,
313 cache_delegate1.get()));
315 scoped_ptr<RulesCacheDelegate> cache_delegate2(new RulesCacheDelegate(false));
316 scoped_refptr<RulesRegistry> registry2(new TestRulesRegistry(
317 &profile, event_name2, content::BrowserThread::UI,
318 cache_delegate2.get()));
320 // Checkt the correct default values.
321 EXPECT_TRUE(cache_delegate1->GetDeclarativeRulesStored(kExtensionId));
322 EXPECT_TRUE(cache_delegate2->GetDeclarativeRulesStored(kExtensionId));
324 // Update the flag for the first registry.
325 extension_prefs->UpdateExtensionPref(
326 kExtensionId, rules_stored_key1, new base::FundamentalValue(false));
327 EXPECT_FALSE(cache_delegate1->GetDeclarativeRulesStored(kExtensionId));
328 EXPECT_TRUE(cache_delegate2->GetDeclarativeRulesStored(kExtensionId));
331 TEST_F(RulesRegistryWithCacheTest, RulesPreservedAcrossRestart) {
332 // This test makes sure that rules are restored from the rule store
333 // on registry (in particular, browser) restart.
335 TestingProfile profile;
336 extensions::TestExtensionSystem* system =
337 static_cast<extensions::TestExtensionSystem*>(
338 extensions::ExtensionSystem::Get(&profile));
339 ExtensionService* extension_service = system->CreateExtensionService(
340 CommandLine::ForCurrentProcess(), base::FilePath(), false);
342 // 1. Add an extension, before rules registry gets created.
344 scoped_refptr<Extension> extension(
345 LoadManifestUnchecked("permissions",
346 "web_request_all_host_permissions.json",
347 Manifest::INVALID_LOCATION,
351 ASSERT_TRUE(error.empty());
352 extension_service->AddExtension(extension.get());
355 // 2. First run, adding a rule for the extension.
356 scoped_ptr<RulesCacheDelegate> cache_delegate(new RulesCacheDelegate(false));
357 scoped_refptr<TestRulesRegistry> registry(new TestRulesRegistry(
358 &profile, "testEvent", content::BrowserThread::UI, cache_delegate.get()));
360 AddRule(kExtensionId, kRuleId, registry.get());
361 message_loop_.RunUntilIdle(); // Posted tasks store the added rule.
362 EXPECT_EQ(1, GetNumberOfRules(kExtensionId, registry.get()));
364 // 3. Restart the TestRulesRegistry and see the rule still there.
365 cache_delegate.reset(
366 new RulesCacheDelegate(false));
367 registry = new TestRulesRegistry(
368 &profile, "testEvent", content::BrowserThread::UI, cache_delegate.get());
370 message_loop_.RunUntilIdle(); // Posted tasks retrieve the stored rule.
371 EXPECT_EQ(1, GetNumberOfRules(kExtensionId, registry.get()));
374 } // namespace extensions