Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / extensions / api / declarative / rules_registry_with_cache_unittest.cc
blobe0cb6cc640dc7b12a5a54dad167a6e02694da7bc
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 "extensions/browser/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/run_loop.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/test_extension_environment.h"
15 #include "chrome/browser/extensions/test_extension_system.h"
16 #include "chrome/common/extensions/extension_test_util.h"
17 #include "chrome/common/extensions/features/feature_channel.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "extensions/browser/api/declarative/rules_cache_delegate.h"
21 #include "extensions/browser/api/declarative/rules_registry_service.h"
22 #include "extensions/browser/api/declarative/test_rules_registry.h"
23 #include "extensions/browser/extension_prefs.h"
24 #include "extensions/browser/extension_registry.h"
25 #include "extensions/browser/value_store/testing_value_store.h"
26 #include "extensions/common/extension.h"
27 #include "extensions/common/manifest_constants.h"
28 #include "extensions/common/permissions/permissions_data.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 using extension_test_util::LoadManifestUnchecked;
33 namespace {
34 const char kRuleId[] = "rule";
35 const char kRule2Id[] = "rule2";
38 namespace extensions {
39 const int kRulesRegistryID = RulesRegistryService::kDefaultRulesRegistryID;
41 class RulesRegistryWithCacheTest : public testing::Test {
42 public:
43 RulesRegistryWithCacheTest()
44 : cache_delegate_(/*log_storage_init_delay=*/false),
45 registry_(new TestRulesRegistry(profile(),
46 /*event_name=*/"",
47 content::BrowserThread::UI,
48 &cache_delegate_,
49 kRulesRegistryID)) {}
51 void SetUp() override {
52 env_.GetExtensionPrefs(); // Force creation before adding extensions.
53 // Note that env_.MakeExtension below also forces the creation of
54 // ExtensionService.
56 base::DictionaryValue manifest_extra;
57 std::string key;
58 CHECK(Extension::ProducePEM("test extension 1", &key));
59 manifest_extra.SetString(manifest_keys::kPublicKey, key);
60 extension1_ = env_.MakeExtension(manifest_extra);
61 CHECK(extension1_.get());
63 // Different "key" values for the two extensions ensure a different ID.
64 CHECK(Extension::ProducePEM("test extension 2", &key));
65 manifest_extra.SetString(manifest_keys::kPublicKey, key);
66 extension2_ = env_.MakeExtension(manifest_extra);
67 CHECK(extension2_.get());
68 CHECK_NE(extension2_->id(), extension1_->id());
71 ~RulesRegistryWithCacheTest() override {}
73 std::string AddRule(const std::string& extension_id,
74 const std::string& rule_id,
75 TestRulesRegistry* registry) {
76 std::vector<linked_ptr<RulesRegistry::Rule> > add_rules;
77 add_rules.push_back(make_linked_ptr(new RulesRegistry::Rule));
78 add_rules[0]->id.reset(new std::string(rule_id));
79 return registry->AddRules(extension_id, add_rules);
82 std::string AddRule(const std::string& extension_id,
83 const std::string& rule_id) {
84 return AddRule(extension_id, rule_id, registry_.get());
87 std::string RemoveRule(const std::string& extension_id,
88 const std::string& rule_id) {
89 std::vector<std::string> remove_rules;
90 remove_rules.push_back(rule_id);
91 return registry_->RemoveRules(extension_id, remove_rules);
94 int GetNumberOfRules(const std::string& extension_id,
95 TestRulesRegistry* registry) {
96 std::vector<linked_ptr<RulesRegistry::Rule> > get_rules;
97 registry->GetAllRules(extension_id, &get_rules);
98 return get_rules.size();
101 int GetNumberOfRules(const std::string& extension_id) {
102 return GetNumberOfRules(extension_id, registry_.get());
105 TestingProfile* profile() const { return env_.profile(); }
107 protected:
108 TestExtensionEnvironment env_;
109 RulesCacheDelegate cache_delegate_;
110 scoped_refptr<TestRulesRegistry> registry_;
111 scoped_refptr<const Extension> extension1_;
112 scoped_refptr<const Extension> extension2_;
115 TEST_F(RulesRegistryWithCacheTest, AddRules) {
116 // Check that nothing happens if the concrete RulesRegistry refuses to insert
117 // the rules.
118 registry_->SetResult("Error");
119 EXPECT_EQ("Error", AddRule(extension1_->id(), kRuleId));
120 EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
121 registry_->SetResult(std::string());
123 // Check that rules can be inserted.
124 EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
125 EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
127 // Check that rules cannot be inserted twice with the same kRuleId.
128 EXPECT_NE("", AddRule(extension1_->id(), kRuleId));
129 EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
131 // Check that different extensions may use the same kRuleId.
132 EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
133 EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
134 EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
137 TEST_F(RulesRegistryWithCacheTest, RemoveRules) {
138 // Prime registry.
139 EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
140 EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
141 EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
142 EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
144 // Check that nothing happens if the concrete RuleRegistry refuses to remove
145 // the rules.
146 registry_->SetResult("Error");
147 EXPECT_EQ("Error", RemoveRule(extension1_->id(), kRuleId));
148 EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
149 registry_->SetResult(std::string());
151 // Check that nothing happens if a rule does not exist.
152 EXPECT_EQ("", RemoveRule(extension1_->id(), "unknown_rule"));
153 EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
155 // Check that rules may be removed and only for the correct extension.
156 EXPECT_EQ("", RemoveRule(extension1_->id(), kRuleId));
157 EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
158 EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
161 TEST_F(RulesRegistryWithCacheTest, RemoveAllRules) {
162 // Prime registry.
163 EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
164 EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
165 EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
166 EXPECT_EQ(2, GetNumberOfRules(extension1_->id()));
167 EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
169 // Check that nothing happens if the concrete RuleRegistry refuses to remove
170 // the rules.
171 registry_->SetResult("Error");
172 EXPECT_EQ("Error", registry_->RemoveAllRules(extension1_->id()));
173 EXPECT_EQ(2, GetNumberOfRules(extension1_->id()));
174 registry_->SetResult(std::string());
176 // Check that rules may be removed and only for the correct extension.
177 EXPECT_EQ("", registry_->RemoveAllRules(extension1_->id()));
178 EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
179 EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
182 TEST_F(RulesRegistryWithCacheTest, GetRules) {
183 // Prime registry.
184 EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
185 EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
186 EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
188 // Check that we get the correct rule and unknown rules are ignored.
189 std::vector<std::string> rules_to_get;
190 rules_to_get.push_back(kRuleId);
191 rules_to_get.push_back("unknown_rule");
192 std::vector<linked_ptr<RulesRegistry::Rule> > gotten_rules;
193 registry_->GetRules(extension1_->id(), rules_to_get, &gotten_rules);
194 ASSERT_EQ(1u, gotten_rules.size());
195 ASSERT_TRUE(gotten_rules[0]->id.get());
196 EXPECT_EQ(kRuleId, *(gotten_rules[0]->id));
199 TEST_F(RulesRegistryWithCacheTest, GetAllRules) {
200 // Prime registry.
201 EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
202 EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
203 EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
205 // Check that we get the correct rules.
206 std::vector<linked_ptr<RulesRegistry::Rule> > gotten_rules;
207 registry_->GetAllRules(extension1_->id(), &gotten_rules);
208 EXPECT_EQ(2u, gotten_rules.size());
209 ASSERT_TRUE(gotten_rules[0]->id.get());
210 ASSERT_TRUE(gotten_rules[1]->id.get());
211 EXPECT_TRUE( (kRuleId == *(gotten_rules[0]->id) &&
212 kRule2Id == *(gotten_rules[1]->id)) ||
213 (kRuleId == *(gotten_rules[1]->id) &&
214 kRule2Id == *(gotten_rules[0]->id)) );
217 TEST_F(RulesRegistryWithCacheTest, OnExtensionUninstalled) {
218 // Prime registry.
219 EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
220 EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
222 // Check that the correct rules are removed.
223 registry_->OnExtensionUninstalled(extension1_->id());
224 EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
225 EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
228 TEST_F(RulesRegistryWithCacheTest, DeclarativeRulesStored) {
229 ExtensionPrefs* extension_prefs = env_.GetExtensionPrefs();
230 // The value store is first created during GetExtensionService.
231 TestingValueStore* store = env_.GetExtensionSystem()->value_store();
233 const std::string event_name("testEvent");
234 const std::string rules_stored_key(
235 RulesCacheDelegate::GetRulesStoredKey(
236 event_name, profile()->IsOffTheRecord()));
237 scoped_ptr<RulesCacheDelegate> cache_delegate(new RulesCacheDelegate(false));
238 scoped_refptr<RulesRegistry> registry(
239 new TestRulesRegistry(profile(), event_name, content::BrowserThread::UI,
240 cache_delegate.get(), kRulesRegistryID));
242 // 1. Test the handling of preferences.
243 // Default value is always true.
244 EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
246 extension_prefs->UpdateExtensionPref(
247 extension1_->id(), rules_stored_key, new base::FundamentalValue(false));
248 EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
250 extension_prefs->UpdateExtensionPref(
251 extension1_->id(), rules_stored_key, new base::FundamentalValue(true));
252 EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
254 // 2. Test writing behavior.
255 int write_count = store->write_count();
257 scoped_ptr<base::ListValue> value(new base::ListValue);
258 value->AppendBoolean(true);
259 cache_delegate->WriteToStorage(extension1_->id(), value.Pass());
260 EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
261 base::RunLoop().RunUntilIdle();
262 EXPECT_EQ(write_count + 1, store->write_count());
263 write_count = store->write_count();
265 value.reset(new base::ListValue);
266 cache_delegate->WriteToStorage(extension1_->id(), value.Pass());
267 EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
268 base::RunLoop().RunUntilIdle();
269 // No rules currently, but previously there were, so we expect a write.
270 EXPECT_EQ(write_count + 1, store->write_count());
271 write_count = store->write_count();
273 value.reset(new base::ListValue);
274 cache_delegate->WriteToStorage(extension1_->id(), value.Pass());
275 EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
276 base::RunLoop().RunUntilIdle();
277 EXPECT_EQ(write_count, store->write_count());
279 // 3. Test reading behavior.
280 int read_count = store->read_count();
282 cache_delegate->SetDeclarativeRulesStored(extension1_->id(), false);
283 cache_delegate->ReadFromStorage(extension1_->id());
284 base::RunLoop().RunUntilIdle();
285 EXPECT_EQ(read_count, store->read_count());
286 read_count = store->read_count();
288 cache_delegate->SetDeclarativeRulesStored(extension1_->id(), true);
289 cache_delegate->ReadFromStorage(extension1_->id());
290 base::RunLoop().RunUntilIdle();
291 EXPECT_EQ(read_count + 1, store->read_count());
294 // Test that each registry has its own "are some rules stored" flag.
295 TEST_F(RulesRegistryWithCacheTest, RulesStoredFlagMultipleRegistries) {
296 ExtensionPrefs* extension_prefs = env_.GetExtensionPrefs();
298 const std::string event_name1("testEvent1");
299 const std::string event_name2("testEvent2");
300 const std::string rules_stored_key1(
301 RulesCacheDelegate::GetRulesStoredKey(
302 event_name1, profile()->IsOffTheRecord()));
303 const std::string rules_stored_key2(
304 RulesCacheDelegate::GetRulesStoredKey(
305 event_name2, profile()->IsOffTheRecord()));
306 scoped_ptr<RulesCacheDelegate> cache_delegate1(new RulesCacheDelegate(false));
307 scoped_refptr<RulesRegistry> registry1(
308 new TestRulesRegistry(profile(), event_name1, content::BrowserThread::UI,
309 cache_delegate1.get(), kRulesRegistryID));
311 scoped_ptr<RulesCacheDelegate> cache_delegate2(new RulesCacheDelegate(false));
312 scoped_refptr<RulesRegistry> registry2(
313 new TestRulesRegistry(profile(), event_name2, content::BrowserThread::UI,
314 cache_delegate2.get(), kRulesRegistryID));
316 // Checkt the correct default values.
317 EXPECT_TRUE(cache_delegate1->GetDeclarativeRulesStored(extension1_->id()));
318 EXPECT_TRUE(cache_delegate2->GetDeclarativeRulesStored(extension1_->id()));
320 // Update the flag for the first registry.
321 extension_prefs->UpdateExtensionPref(
322 extension1_->id(), rules_stored_key1, new base::FundamentalValue(false));
323 EXPECT_FALSE(cache_delegate1->GetDeclarativeRulesStored(extension1_->id()));
324 EXPECT_TRUE(cache_delegate2->GetDeclarativeRulesStored(extension1_->id()));
327 TEST_F(RulesRegistryWithCacheTest, RulesPreservedAcrossRestart) {
328 // This test makes sure that rules are restored from the rule store
329 // on registry (in particular, browser) restart.
331 // TODO(vabr): Once some API using declarative rules enters the stable
332 // channel, make sure to use that API here, and remove |channel|.
333 ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_UNKNOWN);
335 ExtensionService* extension_service = env_.GetExtensionService();
337 // 1. Add an extension, before rules registry gets created.
338 std::string error;
339 scoped_refptr<Extension> extension(
340 LoadManifestUnchecked("permissions",
341 "web_request_all_host_permissions.json",
342 Manifest::INVALID_LOCATION,
343 Extension::NO_FLAGS,
344 extension1_->id(),
345 &error));
346 ASSERT_TRUE(error.empty());
347 extension_service->AddExtension(extension.get());
348 EXPECT_TRUE(extensions::ExtensionRegistry::Get(env_.profile())
349 ->enabled_extensions()
350 .Contains(extension->id()));
351 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
352 APIPermission::kDeclarativeWebRequest));
353 env_.GetExtensionSystem()->SetReady();
355 // 2. First run, adding a rule for the extension.
356 scoped_ptr<RulesCacheDelegate> cache_delegate(new RulesCacheDelegate(false));
357 scoped_refptr<TestRulesRegistry> registry(
358 new TestRulesRegistry(profile(), "testEvent", content::BrowserThread::UI,
359 cache_delegate.get(), kRulesRegistryID));
361 AddRule(extension1_->id(), kRuleId, registry.get());
362 base::RunLoop().RunUntilIdle(); // Posted tasks store the added rule.
363 EXPECT_EQ(1, GetNumberOfRules(extension1_->id(), registry.get()));
365 // 3. Restart the TestRulesRegistry and see the rule still there.
366 cache_delegate.reset(new RulesCacheDelegate(false));
367 registry =
368 new TestRulesRegistry(profile(), "testEvent", content::BrowserThread::UI,
369 cache_delegate.get(), kRulesRegistryID);
371 base::RunLoop().RunUntilIdle(); // Posted tasks retrieve the stored rule.
372 EXPECT_EQ(1, GetNumberOfRules(extension1_->id(), registry.get()));
375 TEST_F(RulesRegistryWithCacheTest, ConcurrentStoringOfRules) {
376 // When an extension updates its rules, the new set of rules is stored to disk
377 // with some delay. While it is acceptable for a quick series of updates for a
378 // single extension to only write the last one, we should never forget to
379 // write a rules update for extension A, just because it is immediately
380 // followed by a rules update for extension B.
381 extensions::TestExtensionSystem* system = env_.GetExtensionSystem();
382 TestingValueStore* store = system->value_store();
384 int write_count = store->write_count();
385 EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
386 EXPECT_EQ("", AddRule(extension2_->id(), kRule2Id));
387 env_.GetExtensionSystem()->SetReady();
388 base::RunLoop().RunUntilIdle();
389 EXPECT_EQ(write_count + 2, store->write_count());
392 } // namespace extensions