Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / declarative / rules_registry_with_cache_unittest.cc
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.
4
5 #include "extensions/browser/api/declarative/rules_registry.h"
6
7 // Here we test the TestRulesRegistry which is the simplest possible
8 // implementation of RulesRegistryWithCache as a proxy for
9 // RulesRegistryWithCache.
10
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/test_rules_registry.h"
22 #include "extensions/browser/extension_prefs.h"
23 #include "extensions/browser/value_store/testing_value_store.h"
24 #include "extensions/common/extension.h"
25 #include "extensions/common/manifest_constants.h"
26 #include "extensions/common/permissions/permissions_data.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 using extension_test_util::LoadManifestUnchecked;
30
31 namespace {
32 const char kRuleId[] = "rule";
33 const char kRule2Id[] = "rule2";
34 }
35
36 namespace extensions {
37
38 class RulesRegistryWithCacheTest : public testing::Test {
39  public:
40   RulesRegistryWithCacheTest()
41       : cache_delegate_(/*log_storage_init_delay=*/false),
42         registry_(new TestRulesRegistry(profile(),
43                                         /*event_name=*/"",
44                                         content::BrowserThread::UI,
45                                         &cache_delegate_,
46                                         RulesRegistry::WebViewKey(0, 0))) {}
47
48   virtual void SetUp() {
49     env_.GetExtensionPrefs();  // Force creation before adding extensions.
50     // Note that env_.MakeExtension below also forces the creation of
51     // ExtensionService.
52
53     base::DictionaryValue manifest_extra;
54     std::string key;
55     CHECK(Extension::ProducePEM("test extension 1", &key));
56     manifest_extra.SetString(manifest_keys::kPublicKey, key);
57     extension1_ = env_.MakeExtension(manifest_extra);
58     CHECK(extension1_.get());
59
60     // Different "key" values for the two extensions ensure a different ID.
61     CHECK(Extension::ProducePEM("test extension 2", &key));
62     manifest_extra.SetString(manifest_keys::kPublicKey, key);
63     extension2_ = env_.MakeExtension(manifest_extra);
64     CHECK(extension2_.get());
65     CHECK_NE(extension2_->id(), extension1_->id());
66   }
67
68   virtual ~RulesRegistryWithCacheTest() {}
69
70   std::string AddRule(const std::string& extension_id,
71                       const std::string& rule_id,
72                       TestRulesRegistry* registry) {
73     std::vector<linked_ptr<RulesRegistry::Rule> > add_rules;
74     add_rules.push_back(make_linked_ptr(new RulesRegistry::Rule));
75     add_rules[0]->id.reset(new std::string(rule_id));
76     return registry->AddRules(extension_id, add_rules);
77   }
78
79   std::string AddRule(const std::string& extension_id,
80                       const std::string& rule_id) {
81     return AddRule(extension_id, rule_id, registry_.get());
82   }
83
84   std::string RemoveRule(const std::string& extension_id,
85                          const std::string& rule_id) {
86     std::vector<std::string> remove_rules;
87     remove_rules.push_back(rule_id);
88     return registry_->RemoveRules(extension_id, remove_rules);
89   }
90
91   int GetNumberOfRules(const std::string& extension_id,
92                        TestRulesRegistry* registry) {
93     std::vector<linked_ptr<RulesRegistry::Rule> > get_rules;
94     registry->GetAllRules(extension_id, &get_rules);
95     return get_rules.size();
96   }
97
98   int GetNumberOfRules(const std::string& extension_id) {
99     return GetNumberOfRules(extension_id, registry_.get());
100   }
101
102   TestingProfile* profile() const { return env_.profile(); }
103
104  protected:
105   TestExtensionEnvironment env_;
106   RulesCacheDelegate cache_delegate_;
107   scoped_refptr<TestRulesRegistry> registry_;
108   scoped_refptr<const Extension> extension1_;
109   scoped_refptr<const Extension> extension2_;
110 };
111
112 TEST_F(RulesRegistryWithCacheTest, AddRules) {
113   // Check that nothing happens if the concrete RulesRegistry refuses to insert
114   // the rules.
115   registry_->SetResult("Error");
116   EXPECT_EQ("Error", AddRule(extension1_->id(), kRuleId));
117   EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
118   registry_->SetResult(std::string());
119
120   // Check that rules can be inserted.
121   EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
122   EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
123
124   // Check that rules cannot be inserted twice with the same kRuleId.
125   EXPECT_NE("", AddRule(extension1_->id(), kRuleId));
126   EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
127
128   // Check that different extensions may use the same kRuleId.
129   EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
130   EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
131   EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
132 }
133
134 TEST_F(RulesRegistryWithCacheTest, RemoveRules) {
135   // Prime registry.
136   EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
137   EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
138   EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
139   EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
140
141   // Check that nothing happens if the concrete RuleRegistry refuses to remove
142   // the rules.
143   registry_->SetResult("Error");
144   EXPECT_EQ("Error", RemoveRule(extension1_->id(), kRuleId));
145   EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
146   registry_->SetResult(std::string());
147
148   // Check that nothing happens if a rule does not exist.
149   EXPECT_EQ("", RemoveRule(extension1_->id(), "unknown_rule"));
150   EXPECT_EQ(1, GetNumberOfRules(extension1_->id()));
151
152   // Check that rules may be removed and only for the correct extension.
153   EXPECT_EQ("", RemoveRule(extension1_->id(), kRuleId));
154   EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
155   EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
156 }
157
158 TEST_F(RulesRegistryWithCacheTest, RemoveAllRules) {
159   // Prime registry.
160   EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
161   EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
162   EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
163   EXPECT_EQ(2, GetNumberOfRules(extension1_->id()));
164   EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
165
166   // Check that nothing happens if the concrete RuleRegistry refuses to remove
167   // the rules.
168   registry_->SetResult("Error");
169   EXPECT_EQ("Error", registry_->RemoveAllRules(extension1_->id()));
170   EXPECT_EQ(2, GetNumberOfRules(extension1_->id()));
171   registry_->SetResult(std::string());
172
173   // Check that rules may be removed and only for the correct extension.
174   EXPECT_EQ("", registry_->RemoveAllRules(extension1_->id()));
175   EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
176   EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
177 }
178
179 TEST_F(RulesRegistryWithCacheTest, GetRules) {
180   // Prime registry.
181   EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
182   EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
183   EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
184
185   // Check that we get the correct rule and unknown rules are ignored.
186   std::vector<std::string> rules_to_get;
187   rules_to_get.push_back(kRuleId);
188   rules_to_get.push_back("unknown_rule");
189   std::vector<linked_ptr<RulesRegistry::Rule> > gotten_rules;
190   registry_->GetRules(extension1_->id(), rules_to_get, &gotten_rules);
191   ASSERT_EQ(1u, gotten_rules.size());
192   ASSERT_TRUE(gotten_rules[0]->id.get());
193   EXPECT_EQ(kRuleId, *(gotten_rules[0]->id));
194 }
195
196 TEST_F(RulesRegistryWithCacheTest, GetAllRules) {
197   // Prime registry.
198   EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
199   EXPECT_EQ("", AddRule(extension1_->id(), kRule2Id));
200   EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
201
202   // Check that we get the correct rules.
203   std::vector<linked_ptr<RulesRegistry::Rule> > gotten_rules;
204   registry_->GetAllRules(extension1_->id(), &gotten_rules);
205   EXPECT_EQ(2u, gotten_rules.size());
206   ASSERT_TRUE(gotten_rules[0]->id.get());
207   ASSERT_TRUE(gotten_rules[1]->id.get());
208   EXPECT_TRUE( (kRuleId == *(gotten_rules[0]->id) &&
209                 kRule2Id == *(gotten_rules[1]->id)) ||
210                (kRuleId == *(gotten_rules[1]->id) &&
211                 kRule2Id == *(gotten_rules[0]->id)) );
212 }
213
214 TEST_F(RulesRegistryWithCacheTest, OnExtensionUninstalled) {
215   // Prime registry.
216   EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
217   EXPECT_EQ("", AddRule(extension2_->id(), kRuleId));
218
219   // Check that the correct rules are removed.
220   registry_->OnExtensionUninstalled(extension1_->id());
221   EXPECT_EQ(0, GetNumberOfRules(extension1_->id()));
222   EXPECT_EQ(1, GetNumberOfRules(extension2_->id()));
223 }
224
225 TEST_F(RulesRegistryWithCacheTest, DeclarativeRulesStored) {
226   ExtensionPrefs* extension_prefs = env_.GetExtensionPrefs();
227   // The value store is first created during GetExtensionService.
228   TestingValueStore* store = env_.GetExtensionSystem()->value_store();
229
230   const std::string event_name("testEvent");
231   const std::string rules_stored_key(
232       RulesCacheDelegate::GetRulesStoredKey(
233           event_name, profile()->IsOffTheRecord()));
234   scoped_ptr<RulesCacheDelegate> cache_delegate(new RulesCacheDelegate(false));
235   scoped_refptr<RulesRegistry> registry(new TestRulesRegistry(
236       profile(), event_name, content::BrowserThread::UI,
237       cache_delegate.get(),
238       RulesRegistry::WebViewKey(0, 0)));
239
240   // 1. Test the handling of preferences.
241   // Default value is always true.
242   EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
243
244   extension_prefs->UpdateExtensionPref(
245       extension1_->id(), rules_stored_key, new base::FundamentalValue(false));
246   EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
247
248   extension_prefs->UpdateExtensionPref(
249       extension1_->id(), rules_stored_key, new base::FundamentalValue(true));
250   EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
251
252   // 2. Test writing behavior.
253   int write_count = store->write_count();
254
255   scoped_ptr<base::ListValue> value(new base::ListValue);
256   value->AppendBoolean(true);
257   cache_delegate->WriteToStorage(extension1_->id(),
258                                  value.PassAs<base::Value>());
259   EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
260   base::RunLoop().RunUntilIdle();
261   EXPECT_EQ(write_count + 1, store->write_count());
262   write_count = store->write_count();
263
264   value.reset(new base::ListValue);
265   cache_delegate->WriteToStorage(extension1_->id(),
266                                  value.PassAs<base::Value>());
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();
272
273   value.reset(new base::ListValue);
274   cache_delegate->WriteToStorage(extension1_->id(),
275                                  value.PassAs<base::Value>());
276   EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(extension1_->id()));
277   base::RunLoop().RunUntilIdle();
278   EXPECT_EQ(write_count, store->write_count());
279
280   // 3. Test reading behavior.
281   int read_count = store->read_count();
282
283   cache_delegate->SetDeclarativeRulesStored(extension1_->id(), false);
284   cache_delegate->ReadFromStorage(extension1_->id());
285   base::RunLoop().RunUntilIdle();
286   EXPECT_EQ(read_count, store->read_count());
287   read_count = store->read_count();
288
289   cache_delegate->SetDeclarativeRulesStored(extension1_->id(), true);
290   cache_delegate->ReadFromStorage(extension1_->id());
291   base::RunLoop().RunUntilIdle();
292   EXPECT_EQ(read_count + 1, store->read_count());
293 }
294
295 // Test that each registry has its own "are some rules stored" flag.
296 TEST_F(RulesRegistryWithCacheTest, RulesStoredFlagMultipleRegistries) {
297   ExtensionPrefs* extension_prefs = env_.GetExtensionPrefs();
298
299   const std::string event_name1("testEvent1");
300   const std::string event_name2("testEvent2");
301   const std::string rules_stored_key1(
302       RulesCacheDelegate::GetRulesStoredKey(
303           event_name1, profile()->IsOffTheRecord()));
304   const std::string rules_stored_key2(
305       RulesCacheDelegate::GetRulesStoredKey(
306           event_name2, profile()->IsOffTheRecord()));
307   scoped_ptr<RulesCacheDelegate> cache_delegate1(new RulesCacheDelegate(false));
308   scoped_refptr<RulesRegistry> registry1(new TestRulesRegistry(
309       profile(), event_name1, content::BrowserThread::UI,
310       cache_delegate1.get(),
311       RulesRegistry::WebViewKey(0, 0)));
312
313   scoped_ptr<RulesCacheDelegate> cache_delegate2(new RulesCacheDelegate(false));
314   scoped_refptr<RulesRegistry> registry2(new TestRulesRegistry(
315       profile(), event_name2, content::BrowserThread::UI,
316       cache_delegate2.get(),
317       RulesRegistry::WebViewKey(0, 0)));
318
319   // Checkt the correct default values.
320   EXPECT_TRUE(cache_delegate1->GetDeclarativeRulesStored(extension1_->id()));
321   EXPECT_TRUE(cache_delegate2->GetDeclarativeRulesStored(extension1_->id()));
322
323   // Update the flag for the first registry.
324   extension_prefs->UpdateExtensionPref(
325       extension1_->id(), rules_stored_key1, new base::FundamentalValue(false));
326   EXPECT_FALSE(cache_delegate1->GetDeclarativeRulesStored(extension1_->id()));
327   EXPECT_TRUE(cache_delegate2->GetDeclarativeRulesStored(extension1_->id()));
328 }
329
330 TEST_F(RulesRegistryWithCacheTest, RulesPreservedAcrossRestart) {
331   // This test makes sure that rules are restored from the rule store
332   // on registry (in particular, browser) restart.
333
334   // TODO(vabr): Once some API using declarative rules enters the stable
335   // channel, make sure to use that API here, and remove |channel|.
336   ScopedCurrentChannel channel(chrome::VersionInfo::CHANNEL_UNKNOWN);
337
338   ExtensionService* extension_service = env_.GetExtensionService();
339
340   // 1. Add an extension, before rules registry gets created.
341   std::string error;
342   scoped_refptr<Extension> extension(
343       LoadManifestUnchecked("permissions",
344                             "web_request_all_host_permissions.json",
345                             Manifest::INVALID_LOCATION,
346                             Extension::NO_FLAGS,
347                             extension1_->id(),
348                             &error));
349   ASSERT_TRUE(error.empty());
350   extension_service->AddExtension(extension.get());
351   EXPECT_TRUE(extension_service->extensions()->Contains(extension->id()));
352   EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
353       APIPermission::kDeclarativeWebRequest));
354   env_.GetExtensionSystem()->SetReady();
355
356   // 2. First run, adding a rule for the extension.
357   scoped_ptr<RulesCacheDelegate> cache_delegate(new RulesCacheDelegate(false));
358   scoped_refptr<TestRulesRegistry> registry(new TestRulesRegistry(
359       profile(),
360       "testEvent",
361       content::BrowserThread::UI,
362       cache_delegate.get(),
363       RulesRegistry::WebViewKey(0, 0)));
364
365   AddRule(extension1_->id(), kRuleId, registry.get());
366   base::RunLoop().RunUntilIdle();  // Posted tasks store the added rule.
367   EXPECT_EQ(1, GetNumberOfRules(extension1_->id(), registry.get()));
368
369   // 3. Restart the TestRulesRegistry and see the rule still there.
370   cache_delegate.reset(new RulesCacheDelegate(false));
371   registry = new TestRulesRegistry(
372       profile(),
373       "testEvent",
374       content::BrowserThread::UI,
375       cache_delegate.get(),
376       RulesRegistry::WebViewKey(0, 0));
377
378   base::RunLoop().RunUntilIdle();  // Posted tasks retrieve the stored rule.
379   EXPECT_EQ(1, GetNumberOfRules(extension1_->id(), registry.get()));
380 }
381
382 TEST_F(RulesRegistryWithCacheTest, ConcurrentStoringOfRules) {
383   // When an extension updates its rules, the new set of rules is stored to disk
384   // with some delay. While it is acceptable for a quick series of updates for a
385   // single extension to only write the last one, we should never forget to
386   // write a rules update for extension A, just because it is immediately
387   // followed by a rules update for extension B.
388   extensions::TestExtensionSystem* system = env_.GetExtensionSystem();
389   TestingValueStore* store = system->value_store();
390
391   int write_count = store->write_count();
392   EXPECT_EQ("", AddRule(extension1_->id(), kRuleId));
393   EXPECT_EQ("", AddRule(extension2_->id(), kRule2Id));
394   env_.GetExtensionSystem()->SetReady();
395   base::RunLoop().RunUntilIdle();
396   EXPECT_EQ(write_count + 2, store->write_count());
397 }
398
399 }  //  namespace extensions