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_with_cache.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/test_rules_registry.h" 14 #include "chrome/browser/extensions/extension_prefs.h" 15 #include "chrome/browser/extensions/test_extension_system.h" 16 #include "chrome/browser/value_store/testing_value_store.h" 17 #include "chrome/test/base/testing_profile.h" 18 #include "content/public/test/test_browser_thread.h" 19 #include "testing/gtest/include/gtest/gtest.h" 20 21 #if defined(OS_CHROMEOS) 22 #include "chrome/browser/chromeos/login/user_manager.h" 23 #include "chrome/browser/chromeos/settings/cros_settings.h" 24 #include "chrome/browser/chromeos/settings/device_settings_service.h" 25 #endif 26 27 namespace { 28 // The |extension_id| needs to pass the Extension::IdIsValid test. 29 const char extension_id[] = "abcdefghijklmnopabcdefghijklmnop"; 30 const char extension2_id[] = "ponmlkjihgfedcbaponmlkjihgfedcba"; 31 const char rule_id[] = "rule"; 32 const char rule2_id[] = "rule2"; 33 } 34 35 namespace extensions { 36 37 class RulesRegistryWithCacheTest : public testing::Test { 38 public: 39 RulesRegistryWithCacheTest() 40 : ui_thread_(content::BrowserThread::UI, &message_loop_), 41 file_thread_(content::BrowserThread::FILE, &message_loop_), 42 registry_(new TestRulesRegistry(content::BrowserThread::UI, 43 "" /*event_name*/)) {} 44 45 virtual ~RulesRegistryWithCacheTest() {} 46 47 virtual void TearDown() OVERRIDE { 48 // Make sure that deletion traits of all registries are executed. 49 registry_ = NULL; 50 message_loop_.RunUntilIdle(); 51 } 52 53 std::string AddRule(const std::string& extension_id, 54 const std::string rule_id) { 55 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > add_rules; 56 add_rules.push_back(make_linked_ptr(new extensions::RulesRegistry::Rule)); 57 add_rules[0]->id.reset(new std::string(rule_id)); 58 return registry_->AddRules(extension_id, add_rules); 59 } 60 61 std::string RemoveRule(const std::string& extension_id, 62 const std::string rule_id) { 63 std::vector<std::string> remove_rules; 64 remove_rules.push_back(rule_id); 65 return registry_->RemoveRules(extension_id, remove_rules); 66 } 67 68 int GetNumberOfRules(const std::string& extension_id) { 69 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > get_rules; 70 std::string error = registry_->GetAllRules(extension_id, &get_rules); 71 EXPECT_EQ("", error); 72 return get_rules.size(); 73 } 74 75 protected: 76 base::MessageLoop message_loop_; 77 content::TestBrowserThread ui_thread_; 78 content::TestBrowserThread file_thread_; 79 scoped_refptr<TestRulesRegistry> registry_; 80 #if defined OS_CHROMEOS 81 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 82 chromeos::ScopedTestCrosSettings test_cros_settings_; 83 chromeos::ScopedTestUserManager test_user_manager_; 84 #endif 85 }; 86 87 TEST_F(RulesRegistryWithCacheTest, AddRules) { 88 // Check that nothing happens if the concrete RulesRegistry refuses to insert 89 // the rules. 90 registry_->SetResult("Error"); 91 EXPECT_EQ("Error", AddRule(extension_id, rule_id)); 92 EXPECT_EQ(0, GetNumberOfRules(extension_id)); 93 registry_->SetResult(std::string()); 94 95 // Check that rules can be inserted. 96 EXPECT_EQ("", AddRule(extension_id, rule_id)); 97 EXPECT_EQ(1, GetNumberOfRules(extension_id)); 98 99 // Check that rules cannot be inserted twice with the same rule_id. 100 EXPECT_NE("", AddRule(extension_id, rule_id)); 101 EXPECT_EQ(1, GetNumberOfRules(extension_id)); 102 103 // Check that different extensions may use the same rule_id. 104 EXPECT_EQ("", AddRule(extension2_id, rule_id)); 105 EXPECT_EQ(1, GetNumberOfRules(extension_id)); 106 EXPECT_EQ(1, GetNumberOfRules(extension2_id)); 107 } 108 109 TEST_F(RulesRegistryWithCacheTest, RemoveRules) { 110 // Prime registry. 111 EXPECT_EQ("", AddRule(extension_id, rule_id)); 112 EXPECT_EQ("", AddRule(extension2_id, rule_id)); 113 EXPECT_EQ(1, GetNumberOfRules(extension_id)); 114 EXPECT_EQ(1, GetNumberOfRules(extension2_id)); 115 116 // Check that nothing happens if the concrete RuleRegistry refuses to remove 117 // the rules. 118 registry_->SetResult("Error"); 119 EXPECT_EQ("Error", RemoveRule(extension_id, rule_id)); 120 EXPECT_EQ(1, GetNumberOfRules(extension_id)); 121 registry_->SetResult(std::string()); 122 123 // Check that nothing happens if a rule does not exist. 124 EXPECT_EQ("", RemoveRule(extension_id, "unknown_rule")); 125 EXPECT_EQ(1, GetNumberOfRules(extension_id)); 126 127 // Check that rules may be removed and only for the correct extension. 128 EXPECT_EQ("", RemoveRule(extension_id, rule_id)); 129 EXPECT_EQ(0, GetNumberOfRules(extension_id)); 130 EXPECT_EQ(1, GetNumberOfRules(extension2_id)); 131 } 132 133 TEST_F(RulesRegistryWithCacheTest, RemoveAllRules) { 134 // Prime registry. 135 EXPECT_EQ("", AddRule(extension_id, rule_id)); 136 EXPECT_EQ("", AddRule(extension_id, rule2_id)); 137 EXPECT_EQ("", AddRule(extension2_id, rule_id)); 138 EXPECT_EQ(2, GetNumberOfRules(extension_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", registry_->RemoveAllRules(extension_id)); 145 EXPECT_EQ(2, GetNumberOfRules(extension_id)); 146 registry_->SetResult(std::string()); 147 148 // Check that rules may be removed and only for the correct extension. 149 EXPECT_EQ("", registry_->RemoveAllRules(extension_id)); 150 EXPECT_EQ(0, GetNumberOfRules(extension_id)); 151 EXPECT_EQ(1, GetNumberOfRules(extension2_id)); 152 } 153 154 TEST_F(RulesRegistryWithCacheTest, GetRules) { 155 // Prime registry. 156 EXPECT_EQ("", AddRule(extension_id, rule_id)); 157 EXPECT_EQ("", AddRule(extension_id, rule2_id)); 158 EXPECT_EQ("", AddRule(extension2_id, rule_id)); 159 160 // Check that we get the correct rule and unknown rules are ignored. 161 std::vector<std::string> rules_to_get; 162 rules_to_get.push_back(rule_id); 163 rules_to_get.push_back("unknown_rule"); 164 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > gotten_rules; 165 EXPECT_EQ("", registry_->GetRules(extension_id, rules_to_get, &gotten_rules)); 166 ASSERT_EQ(1u, gotten_rules.size()); 167 ASSERT_TRUE(gotten_rules[0]->id.get()); 168 EXPECT_EQ(rule_id, *(gotten_rules[0]->id)); 169 } 170 171 TEST_F(RulesRegistryWithCacheTest, GetAllRules) { 172 // Prime registry. 173 EXPECT_EQ("", AddRule(extension_id, rule_id)); 174 EXPECT_EQ("", AddRule(extension_id, rule2_id)); 175 EXPECT_EQ("", AddRule(extension2_id, rule_id)); 176 177 // Check that we get the correct rules. 178 std::vector<linked_ptr<extensions::RulesRegistry::Rule> > gotten_rules; 179 EXPECT_EQ("", registry_->GetAllRules(extension_id, &gotten_rules)); 180 EXPECT_EQ(2u, gotten_rules.size()); 181 ASSERT_TRUE(gotten_rules[0]->id.get()); 182 ASSERT_TRUE(gotten_rules[1]->id.get()); 183 EXPECT_TRUE( (rule_id == *(gotten_rules[0]->id) && 184 rule2_id == *(gotten_rules[1]->id)) || 185 (rule_id == *(gotten_rules[1]->id) && 186 rule2_id == *(gotten_rules[0]->id)) ); 187 } 188 189 TEST_F(RulesRegistryWithCacheTest, OnExtensionUnloaded) { 190 // Prime registry. 191 EXPECT_EQ("", AddRule(extension_id, rule_id)); 192 EXPECT_EQ("", AddRule(extension2_id, rule_id)); 193 194 // Check that the correct rules are removed. 195 registry_->OnExtensionUnloaded(extension_id); 196 EXPECT_EQ(0, GetNumberOfRules(extension_id)); 197 EXPECT_EQ(1, GetNumberOfRules(extension2_id)); 198 } 199 200 TEST_F(RulesRegistryWithCacheTest, DeclarativeRulesStored) { 201 TestingProfile profile; 202 // TestingProfile::Init makes sure that the factory method for a corresponding 203 // extension system creates a TestExtensionSystem. 204 extensions::TestExtensionSystem* system = 205 static_cast<extensions::TestExtensionSystem*>( 206 extensions::ExtensionSystem::Get(&profile)); 207 ExtensionPrefs* extension_prefs = system->CreateExtensionPrefs( 208 CommandLine::ForCurrentProcess(), base::FilePath()); 209 system->CreateExtensionService( 210 CommandLine::ForCurrentProcess(), base::FilePath(), false); 211 // The value store is first created during CreateExtensionService. 212 TestingValueStore* store = system->value_store(); 213 214 scoped_ptr<RulesRegistryWithCache::RuleStorageOnUI> ui_part; 215 scoped_refptr<RulesRegistryWithCache> registry(new TestRulesRegistry( 216 &profile, "testEvent", content::BrowserThread::UI, &ui_part)); 217 218 // 1. Test the handling of preferences. 219 // Default value is always true. 220 EXPECT_TRUE(ui_part->GetDeclarativeRulesStored(extension_id)); 221 222 extension_prefs->UpdateExtensionPref( 223 extension_id, 224 RulesRegistryWithCache::RuleStorageOnUI::kRulesStoredKey, 225 new base::FundamentalValue(false)); 226 EXPECT_FALSE(ui_part->GetDeclarativeRulesStored(extension_id)); 227 228 extension_prefs->UpdateExtensionPref( 229 extension_id, 230 RulesRegistryWithCache::RuleStorageOnUI::kRulesStoredKey, 231 new base::FundamentalValue(true)); 232 EXPECT_TRUE(ui_part->GetDeclarativeRulesStored(extension_id)); 233 234 // 2. Test writing behavior. 235 int write_count = store->write_count(); 236 237 scoped_ptr<base::ListValue> value(new base::ListValue); 238 value->AppendBoolean(true); 239 ui_part->WriteToStorage(extension_id, value.PassAs<base::Value>()); 240 EXPECT_TRUE(ui_part->GetDeclarativeRulesStored(extension_id)); 241 message_loop_.RunUntilIdle(); 242 EXPECT_EQ(write_count + 1, store->write_count()); 243 write_count = store->write_count(); 244 245 value.reset(new base::ListValue); 246 ui_part->WriteToStorage(extension_id, value.PassAs<base::Value>()); 247 EXPECT_FALSE(ui_part->GetDeclarativeRulesStored(extension_id)); 248 message_loop_.RunUntilIdle(); 249 // No rules currently, but previously there were, so we expect a write. 250 EXPECT_EQ(write_count + 1, store->write_count()); 251 write_count = store->write_count(); 252 253 value.reset(new base::ListValue); 254 ui_part->WriteToStorage(extension_id, value.PassAs<base::Value>()); 255 EXPECT_FALSE(ui_part->GetDeclarativeRulesStored(extension_id)); 256 message_loop_.RunUntilIdle(); 257 EXPECT_EQ(write_count, store->write_count()); 258 259 // 3. Test reading behavior. 260 int read_count = store->read_count(); 261 262 ui_part->SetDeclarativeRulesStored(extension_id, false); 263 ui_part->ReadFromStorage(extension_id); 264 message_loop_.RunUntilIdle(); 265 EXPECT_EQ(read_count, store->read_count()); 266 read_count = store->read_count(); 267 268 ui_part->SetDeclarativeRulesStored(extension_id, true); 269 ui_part->ReadFromStorage(extension_id); 270 message_loop_.RunUntilIdle(); 271 EXPECT_EQ(read_count + 1, store->read_count()); 272 } 273 274 } // namespace extensions 275