extension_registry_unittest.cc 12 KB

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