- add sources.
[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 "chrome/browser/extensions/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/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"
24
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"
29 #endif
30
31 using extension_test_util::LoadManifestUnchecked;
32
33 namespace {
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";
39 }
40
41 namespace extensions {
42
43 class RulesRegistryWithCacheTest : public testing::Test {
44  public:
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*/)) {}
50
51   virtual ~RulesRegistryWithCacheTest() {}
52
53   virtual void TearDown() OVERRIDE {
54     // Make sure that deletion traits of all registries are executed.
55     registry_ = NULL;
56     message_loop_.RunUntilIdle();
57   }
58
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);
66   }
67
68   std::string AddRule(const std::string& extension_id,
69                       const std::string& rule_id) {
70     return AddRule(extension_id, rule_id, registry_.get());
71   }
72
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);
78   }
79
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);
84     EXPECT_EQ("", error);
85     return get_rules.size();
86   }
87
88   int GetNumberOfRules(const std::string& extension_id) {
89     return GetNumberOfRules(extension_id, registry_.get());
90   }
91
92  protected:
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_;
101 #endif
102 };
103
104 TEST_F(RulesRegistryWithCacheTest, AddRules) {
105   // Check that nothing happens if the concrete RulesRegistry refuses to insert
106   // the rules.
107   registry_->SetResult("Error");
108   EXPECT_EQ("Error", AddRule(kExtensionId, kRuleId));
109   EXPECT_EQ(0, GetNumberOfRules(kExtensionId));
110   registry_->SetResult(std::string());
111
112   // Check that rules can be inserted.
113   EXPECT_EQ("", AddRule(kExtensionId, kRule2Id));
114   EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
115
116   // Check that rules cannot be inserted twice with the same kRuleId.
117   EXPECT_NE("", AddRule(kExtensionId, kRuleId));
118   EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
119
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));
124 }
125
126 TEST_F(RulesRegistryWithCacheTest, RemoveRules) {
127   // Prime registry.
128   EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
129   EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
130   EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
131   EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
132
133   // Check that nothing happens if the concrete RuleRegistry refuses to remove
134   // the rules.
135   registry_->SetResult("Error");
136   EXPECT_EQ("Error", RemoveRule(kExtensionId, kRuleId));
137   EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
138   registry_->SetResult(std::string());
139
140   // Check that nothing happens if a rule does not exist.
141   EXPECT_EQ("", RemoveRule(kExtensionId, "unknown_rule"));
142   EXPECT_EQ(1, GetNumberOfRules(kExtensionId));
143
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));
148 }
149
150 TEST_F(RulesRegistryWithCacheTest, RemoveAllRules) {
151   // Prime registry.
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));
157
158   // Check that nothing happens if the concrete RuleRegistry refuses to remove
159   // the rules.
160   registry_->SetResult("Error");
161   EXPECT_EQ("Error", registry_->RemoveAllRules(kExtensionId));
162   EXPECT_EQ(2, GetNumberOfRules(kExtensionId));
163   registry_->SetResult(std::string());
164
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));
169 }
170
171 TEST_F(RulesRegistryWithCacheTest, GetRules) {
172   // Prime registry.
173   EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
174   EXPECT_EQ("", AddRule(kExtensionId, kRule2Id));
175   EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
176
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));
186 }
187
188 TEST_F(RulesRegistryWithCacheTest, GetAllRules) {
189   // Prime registry.
190   EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
191   EXPECT_EQ("", AddRule(kExtensionId, kRule2Id));
192   EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
193
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)) );
204 }
205
206 TEST_F(RulesRegistryWithCacheTest, OnExtensionUnloaded) {
207   // Prime registry.
208   EXPECT_EQ("", AddRule(kExtensionId, kRuleId));
209   EXPECT_EQ("", AddRule(kExtension2Id, kRuleId));
210
211   // Check that the correct rules are removed.
212   registry_->OnExtensionUnloaded(kExtensionId);
213   EXPECT_EQ(0, GetNumberOfRules(kExtensionId));
214   EXPECT_EQ(1, GetNumberOfRules(kExtension2Id));
215 }
216
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();
230
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()));
238
239   // 1. Test the handling of preferences.
240   // Default value is always true.
241   EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
242
243   extension_prefs->UpdateExtensionPref(
244       kExtensionId, rules_stored_key, new base::FundamentalValue(false));
245   EXPECT_FALSE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
246
247   extension_prefs->UpdateExtensionPref(
248       kExtensionId, rules_stored_key, new base::FundamentalValue(true));
249   EXPECT_TRUE(cache_delegate->GetDeclarativeRulesStored(kExtensionId));
250
251   // 2. Test writing behavior.
252   int write_count = store->write_count();
253
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();
261
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();
269
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());
275
276   // 3. Test reading behavior.
277   int read_count = store->read_count();
278
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();
284
285   cache_delegate->SetDeclarativeRulesStored(kExtensionId, true);
286   cache_delegate->ReadFromStorage(kExtensionId);
287   message_loop_.RunUntilIdle();
288   EXPECT_EQ(read_count + 1, store->read_count());
289 }
290
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());
301
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()));
314
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()));
319
320   // Checkt the correct default values.
321   EXPECT_TRUE(cache_delegate1->GetDeclarativeRulesStored(kExtensionId));
322   EXPECT_TRUE(cache_delegate2->GetDeclarativeRulesStored(kExtensionId));
323
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));
329 }
330
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.
334
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);
341
342   // 1. Add an extension, before rules registry gets created.
343   std::string error;
344   scoped_refptr<Extension> extension(
345       LoadManifestUnchecked("permissions",
346                             "web_request_all_host_permissions.json",
347                             Manifest::INVALID_LOCATION,
348                             Extension::NO_FLAGS,
349                             kExtensionId,
350                             &error));
351   ASSERT_TRUE(error.empty());
352   extension_service->AddExtension(extension.get());
353   system->SetReady();
354
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()));
359
360   AddRule(kExtensionId, kRuleId, registry.get());
361   message_loop_.RunUntilIdle();  // Posted tasks store the added rule.
362   EXPECT_EQ(1, GetNumberOfRules(kExtensionId, registry.get()));
363
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());
369
370   message_loop_.RunUntilIdle();  // Posted tasks retrieve the stored rule.
371   EXPECT_EQ(1, GetNumberOfRules(kExtensionId, registry.get()));
372 }
373
374 }  //  namespace extensions