1// Copyright 2013 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/extension_registry.h" 6 7#include <string> 8 9#include "base/memory/ref_counted.h" 10#include "base/strings/string_util.h" 11#include "extensions/browser/extension_registry_observer.h" 12#include "extensions/browser/uninstall_reason.h" 13#include "extensions/common/test_util.h" 14#include "testing/gtest/include/gtest/gtest.h" 15 16namespace extensions { 17namespace { 18 19typedef testing::Test ExtensionRegistryTest; 20 21testing::AssertionResult HasSingleExtension( 22 const ExtensionList& list, 23 const scoped_refptr<const Extension>& extension) { 24 if (list.empty()) 25 return testing::AssertionFailure() << "No extensions in list"; 26 if (list.size() > 1) 27 return testing::AssertionFailure() << list.size() 28 << " extensions, expected 1"; 29 const Extension* did_load = list[0].get(); 30 if (did_load != extension.get()) 31 return testing::AssertionFailure() << "Expected " << extension->id() 32 << " found " << did_load->id(); 33 return testing::AssertionSuccess(); 34} 35 36class TestObserver : public ExtensionRegistryObserver { 37 public: 38 void Reset() { 39 loaded_.clear(); 40 unloaded_.clear(); 41 installed_.clear(); 42 uninstalled_.clear(); 43 } 44 45 const ExtensionList& loaded() { return loaded_; } 46 const ExtensionList& unloaded() { return unloaded_; } 47 const ExtensionList& installed() { return installed_; } 48 const ExtensionList& uninstalled() { return uninstalled_; } 49 50 private: 51 virtual void OnExtensionLoaded(content::BrowserContext* browser_context, 52 const Extension* extension) OVERRIDE { 53 loaded_.push_back(extension); 54 } 55 56 virtual void OnExtensionUnloaded(content::BrowserContext* browser_context, 57 const Extension* extension, 58 UnloadedExtensionInfo::Reason reason) 59 OVERRIDE { 60 unloaded_.push_back(extension); 61 } 62 63 virtual void OnExtensionWillBeInstalled( 64 content::BrowserContext* browser_context, 65 const Extension* extension, 66 bool is_update, 67 bool from_ephemeral, 68 const std::string& old_name) OVERRIDE { 69 installed_.push_back(extension); 70 } 71 72 virtual void OnExtensionUninstalled( 73 content::BrowserContext* browser_context, 74 const Extension* extension, 75 extensions::UninstallReason reason) OVERRIDE { 76 uninstalled_.push_back(extension); 77 } 78 79 virtual void OnShutdown(extensions::ExtensionRegistry* registry) OVERRIDE { 80 Reset(); 81 } 82 83 ExtensionList loaded_; 84 ExtensionList unloaded_; 85 ExtensionList installed_; 86 ExtensionList uninstalled_; 87}; 88 89TEST_F(ExtensionRegistryTest, FillAndClearRegistry) { 90 ExtensionRegistry registry(NULL); 91 scoped_refptr<Extension> extension1 = test_util::CreateEmptyExtension("id1"); 92 scoped_refptr<Extension> extension2 = test_util::CreateEmptyExtension("id2"); 93 scoped_refptr<Extension> extension3 = test_util::CreateEmptyExtension("id3"); 94 scoped_refptr<Extension> extension4 = test_util::CreateEmptyExtension("id4"); 95 96 // All the sets start empty. 97 EXPECT_EQ(0u, registry.enabled_extensions().size()); 98 EXPECT_EQ(0u, registry.disabled_extensions().size()); 99 EXPECT_EQ(0u, registry.terminated_extensions().size()); 100 EXPECT_EQ(0u, registry.blacklisted_extensions().size()); 101 102 // Extensions can be added to each set. 103 registry.AddEnabled(extension1); 104 registry.AddDisabled(extension2); 105 registry.AddTerminated(extension3); 106 registry.AddBlacklisted(extension4); 107 108 EXPECT_EQ(1u, registry.enabled_extensions().size()); 109 EXPECT_EQ(1u, registry.disabled_extensions().size()); 110 EXPECT_EQ(1u, registry.terminated_extensions().size()); 111 EXPECT_EQ(1u, registry.blacklisted_extensions().size()); 112 113 // Clearing the registry clears all sets. 114 registry.ClearAll(); 115 116 EXPECT_EQ(0u, registry.enabled_extensions().size()); 117 EXPECT_EQ(0u, registry.disabled_extensions().size()); 118 EXPECT_EQ(0u, registry.terminated_extensions().size()); 119 EXPECT_EQ(0u, registry.blacklisted_extensions().size()); 120} 121 122// A simple test of adding and removing things from sets. 123TEST_F(ExtensionRegistryTest, AddAndRemoveExtensionFromRegistry) { 124 ExtensionRegistry registry(NULL); 125 126 // Adding an extension works. 127 scoped_refptr<Extension> extension = test_util::CreateEmptyExtension("id"); 128 EXPECT_TRUE(registry.AddEnabled(extension)); 129 EXPECT_EQ(1u, registry.enabled_extensions().size()); 130 131 // The extension was only added to one set. 132 EXPECT_EQ(0u, registry.disabled_extensions().size()); 133 EXPECT_EQ(0u, registry.terminated_extensions().size()); 134 EXPECT_EQ(0u, registry.blacklisted_extensions().size()); 135 136 // Removing an extension works. 137 EXPECT_TRUE(registry.RemoveEnabled(extension->id())); 138 EXPECT_EQ(0u, registry.enabled_extensions().size()); 139 140 // Trying to remove an extension that isn't in the set fails cleanly. 141 EXPECT_FALSE(registry.RemoveEnabled(extension->id())); 142} 143 144TEST_F(ExtensionRegistryTest, AddExtensionToRegistryTwice) { 145 ExtensionRegistry registry(NULL); 146 scoped_refptr<Extension> extension = test_util::CreateEmptyExtension("id"); 147 148 // An extension can exist in two sets at once. It would be nice to eliminate 149 // this functionality, but some users of ExtensionRegistry need it. 150 EXPECT_TRUE(registry.AddEnabled(extension)); 151 EXPECT_TRUE(registry.AddDisabled(extension)); 152 153 EXPECT_EQ(1u, registry.enabled_extensions().size()); 154 EXPECT_EQ(1u, registry.disabled_extensions().size()); 155 EXPECT_EQ(0u, registry.terminated_extensions().size()); 156 EXPECT_EQ(0u, registry.blacklisted_extensions().size()); 157} 158 159TEST_F(ExtensionRegistryTest, GetExtensionById) { 160 ExtensionRegistry registry(NULL); 161 162 // Trying to get an extension fails cleanly when the sets are empty. 163 EXPECT_FALSE( 164 registry.GetExtensionById("id", ExtensionRegistry::EVERYTHING)); 165 166 scoped_refptr<Extension> enabled = test_util::CreateEmptyExtension("enabled"); 167 scoped_refptr<Extension> disabled = 168 test_util::CreateEmptyExtension("disabled"); 169 scoped_refptr<Extension> terminated = 170 test_util::CreateEmptyExtension("terminated"); 171 scoped_refptr<Extension> blacklisted = 172 test_util::CreateEmptyExtension("blacklisted"); 173 174 // Add an extension to each set. 175 registry.AddEnabled(enabled); 176 registry.AddDisabled(disabled); 177 registry.AddTerminated(terminated); 178 registry.AddBlacklisted(blacklisted); 179 180 // Enabled is part of everything and the enabled list. 181 EXPECT_TRUE( 182 registry.GetExtensionById("enabled", ExtensionRegistry::EVERYTHING)); 183 EXPECT_TRUE( 184 registry.GetExtensionById("enabled", ExtensionRegistry::ENABLED)); 185 EXPECT_FALSE( 186 registry.GetExtensionById("enabled", ExtensionRegistry::DISABLED)); 187 EXPECT_FALSE( 188 registry.GetExtensionById("enabled", ExtensionRegistry::TERMINATED)); 189 EXPECT_FALSE( 190 registry.GetExtensionById("enabled", ExtensionRegistry::BLACKLISTED)); 191 192 // Disabled is part of everything and the disabled list. 193 EXPECT_TRUE( 194 registry.GetExtensionById("disabled", ExtensionRegistry::EVERYTHING)); 195 EXPECT_FALSE( 196 registry.GetExtensionById("disabled", ExtensionRegistry::ENABLED)); 197 EXPECT_TRUE( 198 registry.GetExtensionById("disabled", ExtensionRegistry::DISABLED)); 199 EXPECT_FALSE( 200 registry.GetExtensionById("disabled", ExtensionRegistry::TERMINATED)); 201 EXPECT_FALSE( 202 registry.GetExtensionById("disabled", ExtensionRegistry::BLACKLISTED)); 203 204 // Terminated is part of everything and the terminated list. 205 EXPECT_TRUE( 206 registry.GetExtensionById("terminated", ExtensionRegistry::EVERYTHING)); 207 EXPECT_FALSE( 208 registry.GetExtensionById("terminated", ExtensionRegistry::ENABLED)); 209 EXPECT_FALSE( 210 registry.GetExtensionById("terminated", ExtensionRegistry::DISABLED)); 211 EXPECT_TRUE( 212 registry.GetExtensionById("terminated", ExtensionRegistry::TERMINATED)); 213 EXPECT_FALSE( 214 registry.GetExtensionById("terminated", ExtensionRegistry::BLACKLISTED)); 215 216 // Blacklisted is part of everything and the blacklisted list. 217 EXPECT_TRUE( 218 registry.GetExtensionById("blacklisted", ExtensionRegistry::EVERYTHING)); 219 EXPECT_FALSE( 220 registry.GetExtensionById("blacklisted", ExtensionRegistry::ENABLED)); 221 EXPECT_FALSE( 222 registry.GetExtensionById("blacklisted", ExtensionRegistry::DISABLED)); 223 EXPECT_FALSE( 224 registry.GetExtensionById("blacklisted", ExtensionRegistry::TERMINATED)); 225 EXPECT_TRUE( 226 registry.GetExtensionById("blacklisted", ExtensionRegistry::BLACKLISTED)); 227 228 // Enabled can be found with multiple flags set. 229 EXPECT_TRUE(registry.GetExtensionById( 230 "enabled", ExtensionRegistry::ENABLED | ExtensionRegistry::TERMINATED)); 231 232 // Enabled isn't found if the wrong flags are set. 233 EXPECT_FALSE(registry.GetExtensionById( 234 "enabled", ExtensionRegistry::DISABLED | ExtensionRegistry::BLACKLISTED)); 235} 236 237TEST_F(ExtensionRegistryTest, Observer) { 238 ExtensionRegistry registry(NULL); 239 TestObserver observer; 240 registry.AddObserver(&observer); 241 242 EXPECT_TRUE(observer.loaded().empty()); 243 EXPECT_TRUE(observer.unloaded().empty()); 244 EXPECT_TRUE(observer.installed().empty()); 245 246 scoped_refptr<const Extension> extension = 247 test_util::CreateEmptyExtension("id"); 248 249 registry.TriggerOnWillBeInstalled( 250 extension.get(), false, false, base::EmptyString()); 251 EXPECT_TRUE(HasSingleExtension(observer.installed(), extension.get())); 252 253 registry.AddEnabled(extension); 254 registry.TriggerOnLoaded(extension.get()); 255 256 registry.TriggerOnWillBeInstalled(extension.get(), true, false, "foo"); 257 258 EXPECT_TRUE(HasSingleExtension(observer.loaded(), extension.get())); 259 EXPECT_TRUE(observer.unloaded().empty()); 260 registry.Shutdown(); 261 262 registry.RemoveEnabled(extension->id()); 263 registry.TriggerOnUnloaded(extension.get(), 264 UnloadedExtensionInfo::REASON_DISABLE); 265 266 EXPECT_TRUE(observer.loaded().empty()); 267 EXPECT_TRUE(HasSingleExtension(observer.unloaded(), extension.get())); 268 registry.Shutdown(); 269 270 registry.TriggerOnUninstalled(extension.get(), 271 extensions::UNINSTALL_REASON_FOR_TESTING); 272 EXPECT_TRUE(observer.installed().empty()); 273 EXPECT_TRUE(HasSingleExtension(observer.uninstalled(), extension.get())); 274 275 registry.RemoveObserver(&observer); 276} 277 278} // namespace 279} // namespace extensions 280