Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / component_loader_unittest.cc
blobcfce964792a8a9c59f621f5e530cb6fd6b26bf90
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.
5 #include "chrome/browser/extensions/component_loader.h"
7 #include <string>
9 #include "base/command_line.h"
10 #include "base/files/file_util.h"
11 #include "base/path_service.h"
12 #include "base/prefs/pref_registry_simple.h"
13 #include "chrome/browser/extensions/test_extension_service.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/testing_pref_service_syncable.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/pref_registry/pref_registry_syncable.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "extensions/browser/extension_registry.h"
22 #include "extensions/common/constants.h"
23 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_set.h"
25 #include "extensions/common/manifest_handlers/background_info.h"
26 #include "testing/gtest/include/gtest/gtest.h"
28 namespace extensions {
30 namespace {
32 class MockExtensionService : public TestExtensionService {
33 private:
34 bool ready_;
35 size_t unloaded_count_;
36 ExtensionRegistry* registry_;
38 public:
39 explicit MockExtensionService(Profile* profile)
40 : ready_(false),
41 unloaded_count_(0),
42 registry_(ExtensionRegistry::Get(profile)) {}
44 void AddComponentExtension(const Extension* extension) override {
45 EXPECT_FALSE(registry_->enabled_extensions().Contains(extension->id()));
46 // ExtensionService must become the owner of the extension object.
47 registry_->AddEnabled(extension);
50 void UnloadExtension(const std::string& extension_id,
51 UnloadedExtensionInfo::Reason reason) override {
52 ASSERT_TRUE(registry_->enabled_extensions().Contains(extension_id));
53 // Remove the extension with the matching id.
54 registry_->RemoveEnabled(extension_id);
55 unloaded_count_++;
58 void RemoveComponentExtension(const std::string& extension_id) override {
59 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_DISABLE);
62 bool is_ready() override { return ready_; }
64 void set_ready(bool ready) {
65 ready_ = ready;
68 size_t unloaded_count() const {
69 return unloaded_count_;
72 void clear_extensions() { registry_->ClearAll(); }
75 } // namespace
77 class ComponentLoaderTest : public testing::Test {
78 public:
79 ComponentLoaderTest()
80 // Note: we pass the same pref service here, to stand in for both
81 // user prefs and local state.
82 : extension_service_(&profile_),
83 component_loader_(&extension_service_,
84 &prefs_,
85 &local_state_,
86 &profile_) {
87 component_loader_.set_ignore_whitelist_for_testing(true);
90 void SetUp() override {
91 extension_path_ =
92 GetBasePath().AppendASCII("good")
93 .AppendASCII("Extensions")
94 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
95 .AppendASCII("1.0.0.0");
97 // Read in the extension manifest.
98 ASSERT_TRUE(base::ReadFileToString(
99 extension_path_.Append(kManifestFilename),
100 &manifest_contents_));
102 // Register the local state prefs.
103 #if defined(OS_CHROMEOS)
104 local_state_.registry()->RegisterBooleanPref(
105 prefs::kAccessibilitySpokenFeedbackEnabled, false);
106 #endif
109 protected:
110 content::TestBrowserThreadBundle thread_bundle_;
111 TestingProfile profile_;
112 MockExtensionService extension_service_;
113 TestingPrefServiceSyncable prefs_;
114 TestingPrefServiceSimple local_state_;
115 ComponentLoader component_loader_;
117 // The root directory of the text extension.
118 base::FilePath extension_path_;
120 // The contents of the text extension's manifest file.
121 std::string manifest_contents_;
123 base::FilePath GetBasePath() {
124 base::FilePath test_data_dir;
125 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
126 return test_data_dir.AppendASCII("extensions");
130 TEST_F(ComponentLoaderTest, ParseManifest) {
131 scoped_ptr<base::DictionaryValue> manifest;
133 // Test invalid JSON.
134 manifest.reset(
135 component_loader_.ParseManifest("{ 'test': 3 } invalid"));
136 EXPECT_FALSE(manifest.get());
138 // Test manifests that are valid JSON, but don't have an object literal
139 // at the root. ParseManifest() should always return NULL.
141 manifest.reset(component_loader_.ParseManifest(std::string()));
142 EXPECT_FALSE(manifest.get());
144 manifest.reset(component_loader_.ParseManifest("[{ \"foo\": 3 }]"));
145 EXPECT_FALSE(manifest.get());
147 manifest.reset(component_loader_.ParseManifest("\"Test\""));
148 EXPECT_FALSE(manifest.get());
150 manifest.reset(component_loader_.ParseManifest("42"));
151 EXPECT_FALSE(manifest.get());
153 manifest.reset(component_loader_.ParseManifest("true"));
154 EXPECT_FALSE(manifest.get());
156 manifest.reset(component_loader_.ParseManifest("false"));
157 EXPECT_FALSE(manifest.get());
159 manifest.reset(component_loader_.ParseManifest("null"));
160 EXPECT_FALSE(manifest.get());
162 // Test parsing valid JSON.
164 int value = 0;
165 manifest.reset(component_loader_.ParseManifest(
166 "{ \"test\": { \"one\": 1 }, \"two\": 2 }"));
167 ASSERT_TRUE(manifest.get());
168 EXPECT_TRUE(manifest->GetInteger("test.one", &value));
169 EXPECT_EQ(1, value);
170 ASSERT_TRUE(manifest->GetInteger("two", &value));
171 EXPECT_EQ(2, value);
173 std::string string_value;
174 manifest.reset(component_loader_.ParseManifest(manifest_contents_));
175 ASSERT_TRUE(manifest->GetString("background.page", &string_value));
176 EXPECT_EQ("backgroundpage.html", string_value);
179 // Test that the extension isn't loaded if the extension service isn't ready.
180 TEST_F(ComponentLoaderTest, AddWhenNotReady) {
181 extension_service_.set_ready(false);
182 std::string extension_id =
183 component_loader_.Add(manifest_contents_, extension_path_);
184 EXPECT_NE("", extension_id);
185 ExtensionRegistry* registry = ExtensionRegistry::Get(&profile_);
186 EXPECT_EQ(0u, registry->enabled_extensions().size());
189 // Test that it *is* loaded when the extension service *is* ready.
190 TEST_F(ComponentLoaderTest, AddWhenReady) {
191 extension_service_.set_ready(true);
192 std::string extension_id =
193 component_loader_.Add(manifest_contents_, extension_path_);
194 EXPECT_NE("", extension_id);
195 ExtensionRegistry* registry = ExtensionRegistry::Get(&profile_);
196 EXPECT_EQ(1u, registry->enabled_extensions().size());
197 EXPECT_TRUE(registry->enabled_extensions().GetByID(extension_id));
200 TEST_F(ComponentLoaderTest, Remove) {
201 extension_service_.set_ready(false);
202 ExtensionRegistry* registry = ExtensionRegistry::Get(&profile_);
204 // Removing an extension that was never added should be ok.
205 component_loader_.Remove(extension_path_);
206 EXPECT_EQ(0u, registry->enabled_extensions().size());
208 // Try adding and removing before LoadAll() is called.
209 component_loader_.Add(manifest_contents_, extension_path_);
210 component_loader_.Remove(extension_path_);
211 component_loader_.LoadAll();
212 EXPECT_EQ(0u, registry->enabled_extensions().size());
214 // Load an extension, and check that it's unloaded when Remove() is called.
215 extension_service_.set_ready(true);
216 std::string extension_id =
217 component_loader_.Add(manifest_contents_, extension_path_);
218 EXPECT_EQ(1u, registry->enabled_extensions().size());
219 component_loader_.Remove(extension_path_);
220 EXPECT_EQ(0u, registry->enabled_extensions().size());
222 // And after calling LoadAll(), it shouldn't get loaded.
223 component_loader_.LoadAll();
224 EXPECT_EQ(0u, registry->enabled_extensions().size());
227 TEST_F(ComponentLoaderTest, LoadAll) {
228 extension_service_.set_ready(false);
229 ExtensionRegistry* registry = ExtensionRegistry::Get(&profile_);
231 // No extensions should be loaded if none were added.
232 component_loader_.LoadAll();
233 EXPECT_EQ(0u, registry->enabled_extensions().size());
235 // Use LoadAll() to load the default extensions.
236 component_loader_.AddDefaultComponentExtensions(false);
237 component_loader_.LoadAll();
238 unsigned int default_count = registry->enabled_extensions().size();
240 // Clear the list of loaded extensions, and reload with one more.
241 extension_service_.clear_extensions();
242 component_loader_.Add(manifest_contents_, extension_path_);
243 component_loader_.LoadAll();
245 EXPECT_EQ(default_count + 1, registry->enabled_extensions().size());
248 TEST_F(ComponentLoaderTest, AddOrReplace) {
249 EXPECT_EQ(0u, component_loader_.registered_extensions_count());
250 component_loader_.AddDefaultComponentExtensions(false);
251 size_t const default_count = component_loader_.registered_extensions_count();
252 base::FilePath known_extension = GetBasePath()
253 .AppendASCII("override_component_extension");
254 base::FilePath unknow_extension = extension_path_;
255 base::FilePath invalid_extension = GetBasePath()
256 .AppendASCII("this_path_does_not_exist");
258 // Replace a default component extension.
259 component_loader_.AddOrReplace(known_extension);
260 EXPECT_EQ(default_count,
261 component_loader_.registered_extensions_count());
263 // Add a new component extension.
264 component_loader_.AddOrReplace(unknow_extension);
265 EXPECT_EQ(default_count + 1,
266 component_loader_.registered_extensions_count());
268 extension_service_.set_ready(true);
269 component_loader_.LoadAll();
270 ExtensionRegistry* registry = ExtensionRegistry::Get(&profile_);
272 EXPECT_EQ(default_count + 1, registry->enabled_extensions().size());
273 EXPECT_EQ(0u, extension_service_.unloaded_count());
275 // replace loaded component extension.
276 component_loader_.AddOrReplace(known_extension);
277 EXPECT_EQ(default_count + 1, registry->enabled_extensions().size());
278 EXPECT_EQ(1u, extension_service_.unloaded_count());
280 // Add an invalid component extension.
281 std::string extension_id = component_loader_.AddOrReplace(invalid_extension);
282 EXPECT_TRUE(extension_id.empty());
285 } // namespace extensions