Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / extensions / component_loader_unittest.cc
blob670b7c65b8e9c52a34268503b5da41579e463e2c
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/file_util.h"
10 #include "base/path_service.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "chrome/browser/extensions/test_extension_service.h"
13 #include "chrome/common/chrome_paths.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/testing_pref_service_syncable.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "components/user_prefs/pref_registry_syncable.h"
18 #include "extensions/common/constants.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_set.h"
21 #include "extensions/common/manifest_handlers/background_info.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace extensions {
26 namespace {
28 class MockExtensionService : public TestExtensionService {
29 private:
30 bool ready_;
31 size_t unloaded_count_;
32 ExtensionSet extension_set_;
34 public:
35 MockExtensionService() : ready_(false), unloaded_count_(0) {
38 virtual void AddComponentExtension(const Extension* extension) OVERRIDE {
39 EXPECT_FALSE(extension_set_.Contains(extension->id()));
40 // ExtensionService must become the owner of the extension object.
41 extension_set_.Insert(extension);
44 virtual void UnloadExtension(
45 const std::string& extension_id,
46 UnloadedExtensionInfo::Reason reason) OVERRIDE {
47 ASSERT_TRUE(extension_set_.Contains(extension_id));
48 // Remove the extension with the matching id.
49 extension_set_.Remove(extension_id);
50 unloaded_count_++;
53 virtual void RemoveComponentExtension(const std::string & extension_id)
54 OVERRIDE {
55 UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_DISABLE);
58 virtual bool is_ready() OVERRIDE {
59 return ready_;
62 virtual const ExtensionSet* extensions() const OVERRIDE {
63 return &extension_set_;
66 void set_ready(bool ready) {
67 ready_ = ready;
70 size_t unloaded_count() const {
71 return unloaded_count_;
74 void clear_extensions() {
75 extension_set_.Clear();
79 } // namespace
81 class ComponentLoaderTest : public testing::Test {
82 public:
83 ComponentLoaderTest()
84 // Note: we pass the same pref service here, to stand in for both
85 // user prefs and local state.
86 : component_loader_(&extension_service_,
87 &prefs_,
88 &local_state_,
89 &profile_) {
92 virtual void SetUp() OVERRIDE {
93 extension_path_ =
94 GetBasePath().AppendASCII("good")
95 .AppendASCII("Extensions")
96 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
97 .AppendASCII("1.0.0.0");
99 // Read in the extension manifest.
100 ASSERT_TRUE(base::ReadFileToString(
101 extension_path_.Append(kManifestFilename),
102 &manifest_contents_));
104 // Register the local state prefs.
105 #if defined(OS_CHROMEOS)
106 local_state_.registry()->RegisterBooleanPref(
107 prefs::kSpokenFeedbackEnabled, false);
108 #endif
111 protected:
112 MockExtensionService extension_service_;
113 TestingPrefServiceSyncable prefs_;
114 TestingPrefServiceSimple local_state_;
115 TestingProfile profile_;
116 ComponentLoader component_loader_;
118 // The root directory of the text extension.
119 base::FilePath extension_path_;
121 // The contents of the text extension's manifest file.
122 std::string manifest_contents_;
124 base::FilePath GetBasePath() {
125 base::FilePath test_data_dir;
126 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
127 return test_data_dir.AppendASCII("extensions");
131 TEST_F(ComponentLoaderTest, ParseManifest) {
132 scoped_ptr<base::DictionaryValue> manifest;
134 // Test invalid JSON.
135 manifest.reset(
136 component_loader_.ParseManifest("{ 'test': 3 } invalid"));
137 EXPECT_FALSE(manifest.get());
139 // Test manifests that are valid JSON, but don't have an object literal
140 // at the root. ParseManifest() should always return NULL.
142 manifest.reset(component_loader_.ParseManifest(std::string()));
143 EXPECT_FALSE(manifest.get());
145 manifest.reset(component_loader_.ParseManifest("[{ \"foo\": 3 }]"));
146 EXPECT_FALSE(manifest.get());
148 manifest.reset(component_loader_.ParseManifest("\"Test\""));
149 EXPECT_FALSE(manifest.get());
151 manifest.reset(component_loader_.ParseManifest("42"));
152 EXPECT_FALSE(manifest.get());
154 manifest.reset(component_loader_.ParseManifest("true"));
155 EXPECT_FALSE(manifest.get());
157 manifest.reset(component_loader_.ParseManifest("false"));
158 EXPECT_FALSE(manifest.get());
160 manifest.reset(component_loader_.ParseManifest("null"));
161 EXPECT_FALSE(manifest.get());
163 // Test parsing valid JSON.
165 int value = 0;
166 manifest.reset(component_loader_.ParseManifest(
167 "{ \"test\": { \"one\": 1 }, \"two\": 2 }"));
168 ASSERT_TRUE(manifest.get());
169 EXPECT_TRUE(manifest->GetInteger("test.one", &value));
170 EXPECT_EQ(1, value);
171 ASSERT_TRUE(manifest->GetInteger("two", &value));
172 EXPECT_EQ(2, value);
174 std::string string_value;
175 manifest.reset(component_loader_.ParseManifest(manifest_contents_));
176 ASSERT_TRUE(manifest->GetString("background.page", &string_value));
177 EXPECT_EQ("backgroundpage.html", string_value);
180 // Test that the extension isn't loaded if the extension service isn't ready.
181 TEST_F(ComponentLoaderTest, AddWhenNotReady) {
182 extension_service_.set_ready(false);
183 std::string extension_id =
184 component_loader_.Add(manifest_contents_, extension_path_);
185 EXPECT_NE("", extension_id);
186 EXPECT_EQ(0u, extension_service_.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 EXPECT_EQ(1u, extension_service_.extensions()->size());
196 EXPECT_TRUE(extension_service_.extensions()->GetByID(extension_id));
199 TEST_F(ComponentLoaderTest, Remove) {
200 extension_service_.set_ready(false);
202 // Removing an extension that was never added should be ok.
203 component_loader_.Remove(extension_path_);
204 EXPECT_EQ(0u, extension_service_.extensions()->size());
206 // Try adding and removing before LoadAll() is called.
207 component_loader_.Add(manifest_contents_, extension_path_);
208 component_loader_.Remove(extension_path_);
209 component_loader_.LoadAll();
210 EXPECT_EQ(0u, extension_service_.extensions()->size());
212 // Load an extension, and check that it's unloaded when Remove() is called.
213 extension_service_.set_ready(true);
214 std::string extension_id =
215 component_loader_.Add(manifest_contents_, extension_path_);
216 EXPECT_EQ(1u, extension_service_.extensions()->size());
217 component_loader_.Remove(extension_path_);
218 EXPECT_EQ(0u, extension_service_.extensions()->size());
220 // And after calling LoadAll(), it shouldn't get loaded.
221 component_loader_.LoadAll();
222 EXPECT_EQ(0u, extension_service_.extensions()->size());
225 TEST_F(ComponentLoaderTest, LoadAll) {
226 extension_service_.set_ready(false);
228 // No extensions should be loaded if none were added.
229 component_loader_.LoadAll();
230 EXPECT_EQ(0u, extension_service_.extensions()->size());
232 // Use LoadAll() to load the default extensions.
233 component_loader_.AddDefaultComponentExtensions(false);
234 component_loader_.LoadAll();
235 unsigned int default_count = extension_service_.extensions()->size();
237 // Clear the list of loaded extensions, and reload with one more.
238 extension_service_.clear_extensions();
239 component_loader_.Add(manifest_contents_, extension_path_);
240 component_loader_.LoadAll();
242 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
245 TEST_F(ComponentLoaderTest, AddOrReplace) {
246 EXPECT_EQ(0u, component_loader_.registered_extensions_count());
247 component_loader_.AddDefaultComponentExtensions(false);
248 size_t const default_count = component_loader_.registered_extensions_count();
249 base::FilePath known_extension = GetBasePath()
250 .AppendASCII("override_component_extension");
251 base::FilePath unknow_extension = extension_path_;
252 base::FilePath invalid_extension = GetBasePath().AppendASCII("bad");
254 // Replace a default component extension.
255 component_loader_.AddOrReplace(known_extension);
256 EXPECT_EQ(default_count,
257 component_loader_.registered_extensions_count());
259 // Add a new component extension.
260 component_loader_.AddOrReplace(unknow_extension);
261 EXPECT_EQ(default_count + 1,
262 component_loader_.registered_extensions_count());
264 extension_service_.set_ready(true);
265 component_loader_.LoadAll();
267 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
268 EXPECT_EQ(0u, extension_service_.unloaded_count());
270 // replace loaded component extension.
271 component_loader_.AddOrReplace(known_extension);
272 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
273 EXPECT_EQ(1u, extension_service_.unloaded_count());
275 // Add an invalid component extension.
276 std::string extension_id = component_loader_.AddOrReplace(invalid_extension);
277 EXPECT_TRUE(extension_id.empty());
280 } // namespace extensions