blob: 6b270afbf16bfdd80512181dbe30f25d1934cf72 [file] [log] [blame]
[email protected]eb75f7b2012-01-04 09:07:281// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]25ae0152011-11-18 14:40:022// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <string>
6
7#include "chrome/browser/extensions/component_loader.h"
8
9#include "base/file_util.h"
10#include "base/path_service.h"
11#include "chrome/browser/extensions/test_extension_service.h"
[email protected]b1de2c72013-02-06 02:45:4712#include "chrome/browser/prefs/pref_registry_simple.h"
[email protected]25ae0152011-11-18 14:40:0213#include "chrome/common/chrome_paths.h"
14#include "chrome/common/extensions/extension.h"
[email protected]84df8332011-12-06 18:22:4615#include "chrome/common/extensions/extension_set.h"
[email protected]25ae0152011-11-18 14:40:0216#include "chrome/common/pref_names.h"
17#include "chrome/test/base/testing_pref_service.h"
18#include "testing/gtest/include/gtest/gtest.h"
19
[email protected]1c321ee52012-05-21 03:02:3420using extensions::Extension;
21
[email protected]25ae0152011-11-18 14:40:0222namespace {
23
24class MockExtensionService : public TestExtensionService {
25 private:
26 bool ready_;
[email protected]43cbd7592011-12-08 08:52:1027 size_t unloaded_count_;
[email protected]84df8332011-12-06 18:22:4628 ExtensionSet extension_set_;
[email protected]25ae0152011-11-18 14:40:0229
30 public:
[email protected]43cbd7592011-12-08 08:52:1031 MockExtensionService() : ready_(false), unloaded_count_(0) {
[email protected]25ae0152011-11-18 14:40:0232 }
33
[email protected]8c484b742012-11-29 06:05:3634 virtual void AddComponentExtension(const Extension* extension) OVERRIDE {
[email protected]61f5fc82012-02-15 20:10:4535 EXPECT_FALSE(extension_set_.Contains(extension->id()));
[email protected]25ae0152011-11-18 14:40:0236 // ExtensionService must become the owner of the extension object.
[email protected]84df8332011-12-06 18:22:4637 extension_set_.Insert(extension);
[email protected]25ae0152011-11-18 14:40:0238 }
39
40 virtual void UnloadExtension(
41 const std::string& extension_id,
42 extension_misc::UnloadedExtensionReason reason) OVERRIDE {
[email protected]43cbd7592011-12-08 08:52:1043 ASSERT_TRUE(extension_set_.Contains(extension_id));
[email protected]25ae0152011-11-18 14:40:0244 // Remove the extension with the matching id.
[email protected]84df8332011-12-06 18:22:4645 extension_set_.Remove(extension_id);
[email protected]43cbd7592011-12-08 08:52:1046 unloaded_count_++;
[email protected]25ae0152011-11-18 14:40:0247 }
48
49 virtual bool is_ready() OVERRIDE {
50 return ready_;
51 }
52
[email protected]84df8332011-12-06 18:22:4653 virtual const ExtensionSet* extensions() const OVERRIDE {
54 return &extension_set_;
[email protected]25ae0152011-11-18 14:40:0255 }
56
57 void set_ready(bool ready) {
58 ready_ = ready;
59 }
60
[email protected]43cbd7592011-12-08 08:52:1061 size_t unloaded_count() const {
62 return unloaded_count_;
63 }
64
[email protected]84df8332011-12-06 18:22:4665 void clear_extensions() {
66 extension_set_.Clear();
[email protected]25ae0152011-11-18 14:40:0267 }
68};
69
70} // namespace
71
72namespace extensions {
73
74class ComponentLoaderTest : public testing::Test {
75 public:
76 ComponentLoaderTest() :
77 // Note: we pass the same pref service here, to stand in for both
78 // user prefs and local state.
[email protected]5b199522012-12-22 17:24:4479 component_loader_(&extension_service_, &prefs_, &local_state_) {
[email protected]25ae0152011-11-18 14:40:0280 }
81
[email protected]49aeab62013-02-07 02:53:1182 virtual void SetUp() {
[email protected]25ae0152011-11-18 14:40:0283 extension_path_ =
[email protected]43cbd7592011-12-08 08:52:1084 GetBasePath().AppendASCII("good")
[email protected]25ae0152011-11-18 14:40:0285 .AppendASCII("Extensions")
86 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
87 .AppendASCII("1.0.0.0");
88
89 // Read in the extension manifest.
90 ASSERT_TRUE(file_util::ReadFileToString(
91 extension_path_.Append(Extension::kManifestFilename),
92 &manifest_contents_));
93
94 // Register the user prefs that ComponentLoader will read.
[email protected]5b199522012-12-22 17:24:4495 prefs_.RegisterStringPref(prefs::kEnterpriseWebStoreURL,
96 std::string(),
97 PrefServiceSyncable::UNSYNCABLE_PREF);
98 prefs_.RegisterStringPref(prefs::kEnterpriseWebStoreName,
99 std::string(),
100 PrefServiceSyncable::UNSYNCABLE_PREF);
[email protected]25ae0152011-11-18 14:40:02101
102 // Register the local state prefs.
103#if defined(OS_CHROMEOS)
[email protected]b1de2c72013-02-06 02:45:47104 local_state_.registry()->RegisterBooleanPref(
105 prefs::kSpokenFeedbackEnabled, false);
[email protected]25ae0152011-11-18 14:40:02106#endif
107 }
108
109 protected:
110 MockExtensionService extension_service_;
[email protected]5b199522012-12-22 17:24:44111 TestingPrefServiceSyncable prefs_;
112 TestingPrefServiceSimple local_state_;
[email protected]25ae0152011-11-18 14:40:02113 ComponentLoader component_loader_;
114
115 // The root directory of the text extension.
[email protected]650b2d52013-02-10 03:41:45116 base::FilePath extension_path_;
[email protected]25ae0152011-11-18 14:40:02117
118 // The contents of the text extension's manifest file.
119 std::string manifest_contents_;
[email protected]43cbd7592011-12-08 08:52:10120
[email protected]650b2d52013-02-10 03:41:45121 base::FilePath GetBasePath() {
122 base::FilePath test_data_dir;
[email protected]43cbd7592011-12-08 08:52:10123 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
124 return test_data_dir.AppendASCII("extensions");
125 }
[email protected]25ae0152011-11-18 14:40:02126};
127
128TEST_F(ComponentLoaderTest, ParseManifest) {
129 scoped_ptr<DictionaryValue> manifest;
130
131 // Test invalid JSON.
132 manifest.reset(
133 component_loader_.ParseManifest("{ 'test': 3 } invalid"));
[email protected]ee837d32012-10-02 22:25:49134 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02135
136 // Test manifests that are valid JSON, but don't have an object literal
137 // at the root. ParseManifest() should always return NULL.
138
139 manifest.reset(component_loader_.ParseManifest(""));
[email protected]ee837d32012-10-02 22:25:49140 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02141
142 manifest.reset(component_loader_.ParseManifest("[{ \"foo\": 3 }]"));
[email protected]ee837d32012-10-02 22:25:49143 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02144
145 manifest.reset(component_loader_.ParseManifest("\"Test\""));
[email protected]ee837d32012-10-02 22:25:49146 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02147
148 manifest.reset(component_loader_.ParseManifest("42"));
[email protected]ee837d32012-10-02 22:25:49149 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02150
151 manifest.reset(component_loader_.ParseManifest("true"));
[email protected]ee837d32012-10-02 22:25:49152 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02153
154 manifest.reset(component_loader_.ParseManifest("false"));
[email protected]ee837d32012-10-02 22:25:49155 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02156
157 manifest.reset(component_loader_.ParseManifest("null"));
[email protected]ee837d32012-10-02 22:25:49158 EXPECT_FALSE(manifest.get());
[email protected]25ae0152011-11-18 14:40:02159
160 // Test parsing valid JSON.
161
[email protected]ee837d32012-10-02 22:25:49162 int value = 0;
[email protected]25ae0152011-11-18 14:40:02163 manifest.reset(component_loader_.ParseManifest(
164 "{ \"test\": { \"one\": 1 }, \"two\": 2 }"));
[email protected]ee837d32012-10-02 22:25:49165 ASSERT_TRUE(manifest.get());
166 EXPECT_TRUE(manifest->GetInteger("test.one", &value));
167 EXPECT_EQ(1, value);
[email protected]25ae0152011-11-18 14:40:02168 ASSERT_TRUE(manifest->GetInteger("two", &value));
[email protected]ee837d32012-10-02 22:25:49169 EXPECT_EQ(2, value);
[email protected]25ae0152011-11-18 14:40:02170
171 std::string string_value;
172 manifest.reset(component_loader_.ParseManifest(manifest_contents_));
[email protected]eb75f7b2012-01-04 09:07:28173 ASSERT_TRUE(manifest->GetString("background.page", &string_value));
[email protected]ee837d32012-10-02 22:25:49174 EXPECT_EQ("backgroundpage.html", string_value);
[email protected]25ae0152011-11-18 14:40:02175}
176
177// Test that the extension isn't loaded if the extension service isn't ready.
178TEST_F(ComponentLoaderTest, AddWhenNotReady) {
[email protected]25ae0152011-11-18 14:40:02179 extension_service_.set_ready(false);
[email protected]ee837d32012-10-02 22:25:49180 std::string extension_id =
181 component_loader_.Add(manifest_contents_, extension_path_);
182 EXPECT_NE("", extension_id);
183 EXPECT_EQ(0u, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02184}
185
186// Test that it *is* loaded when the extension service *is* ready.
187TEST_F(ComponentLoaderTest, AddWhenReady) {
[email protected]25ae0152011-11-18 14:40:02188 extension_service_.set_ready(true);
[email protected]ee837d32012-10-02 22:25:49189 std::string extension_id =
190 component_loader_.Add(manifest_contents_, extension_path_);
191 EXPECT_NE("", extension_id);
192 EXPECT_EQ(1u, extension_service_.extensions()->size());
193 EXPECT_TRUE(extension_service_.extensions()->GetByID(extension_id));
[email protected]25ae0152011-11-18 14:40:02194}
195
196TEST_F(ComponentLoaderTest, Remove) {
197 extension_service_.set_ready(false);
198
199 // Removing an extension that was never added should be ok.
200 component_loader_.Remove(extension_path_);
[email protected]ee837d32012-10-02 22:25:49201 EXPECT_EQ(0u, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02202
[email protected]eac88332012-12-26 17:57:45203 // Try adding and removing before LoadAll() is called.
[email protected]25ae0152011-11-18 14:40:02204 component_loader_.Add(manifest_contents_, extension_path_);
205 component_loader_.Remove(extension_path_);
[email protected]eac88332012-12-26 17:57:45206 component_loader_.LoadAll();
[email protected]ee837d32012-10-02 22:25:49207 EXPECT_EQ(0u, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02208
209 // Load an extension, and check that it's unloaded when Remove() is called.
[email protected]25ae0152011-11-18 14:40:02210 extension_service_.set_ready(true);
[email protected]ee837d32012-10-02 22:25:49211 std::string extension_id =
212 component_loader_.Add(manifest_contents_, extension_path_);
213 EXPECT_EQ(1u, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02214 component_loader_.Remove(extension_path_);
[email protected]ee837d32012-10-02 22:25:49215 EXPECT_EQ(0u, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02216
[email protected]eac88332012-12-26 17:57:45217 // And after calling LoadAll(), it shouldn't get loaded.
218 component_loader_.LoadAll();
[email protected]ee837d32012-10-02 22:25:49219 EXPECT_EQ(0u, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02220}
221
222TEST_F(ComponentLoaderTest, LoadAll) {
223 extension_service_.set_ready(false);
224
225 // No extensions should be loaded if none were added.
[email protected]eac88332012-12-26 17:57:45226 component_loader_.LoadAll();
[email protected]ee837d32012-10-02 22:25:49227 EXPECT_EQ(0u, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02228
[email protected]eac88332012-12-26 17:57:45229 // Use LoadAll() to load the default extensions.
[email protected]bb121482012-12-08 06:49:38230 component_loader_.AddDefaultComponentExtensions(false);
[email protected]eac88332012-12-26 17:57:45231 component_loader_.LoadAll();
[email protected]25ae0152011-11-18 14:40:02232 unsigned int default_count = extension_service_.extensions()->size();
233
234 // Clear the list of loaded extensions, and reload with one more.
[email protected]84df8332011-12-06 18:22:46235 extension_service_.clear_extensions();
[email protected]25ae0152011-11-18 14:40:02236 component_loader_.Add(manifest_contents_, extension_path_);
[email protected]eac88332012-12-26 17:57:45237 component_loader_.LoadAll();
[email protected]25ae0152011-11-18 14:40:02238
[email protected]ee837d32012-10-02 22:25:49239 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02240}
241
[email protected]3c1adb82012-12-11 04:36:48242TEST_F(ComponentLoaderTest, RemoveAll) {
243 extension_service_.set_ready(true);
244 EXPECT_EQ(0u, extension_service_.extensions()->size());
[email protected]ae4c37e2012-12-21 01:16:25245 // Add all the default extensions. Since the extension service is ready, they
246 // will be loaded immediately.
[email protected]3c1adb82012-12-11 04:36:48247 component_loader_.AddDefaultComponentExtensions(false);
248 unsigned int default_count = extension_service_.extensions()->size();
249
250 // And add one more just to make sure there is anything in there in case
251 // there are no defaults for this platform.
252 component_loader_.Add(manifest_contents_, extension_path_);
253 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
254
255 // Remove all default extensions.
256 component_loader_.RemoveAll();
257 EXPECT_EQ(0u, extension_service_.extensions()->size());
258}
259
[email protected]25ae0152011-11-18 14:40:02260TEST_F(ComponentLoaderTest, EnterpriseWebStore) {
[email protected]bb121482012-12-08 06:49:38261 component_loader_.AddDefaultComponentExtensions(false);
[email protected]eac88332012-12-26 17:57:45262 component_loader_.LoadAll();
[email protected]25ae0152011-11-18 14:40:02263 unsigned int default_count = extension_service_.extensions()->size();
264
265 // Set the pref, and it should get loaded automatically.
266 extension_service_.set_ready(true);
267 prefs_.SetUserPref(prefs::kEnterpriseWebStoreURL,
268 Value::CreateStringValue("http://www.google.com"));
[email protected]ee837d32012-10-02 22:25:49269 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02270
271 // Now that the pref is set, check if it's added by default.
272 extension_service_.set_ready(false);
[email protected]84df8332011-12-06 18:22:46273 extension_service_.clear_extensions();
[email protected]25ae0152011-11-18 14:40:02274 component_loader_.ClearAllRegistered();
[email protected]bb121482012-12-08 06:49:38275 component_loader_.AddDefaultComponentExtensions(false);
[email protected]eac88332012-12-26 17:57:45276 component_loader_.LoadAll();
[email protected]ee837d32012-10-02 22:25:49277 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02278
279 // Number of loaded extensions should be the same after changing the pref.
280 prefs_.SetUserPref(prefs::kEnterpriseWebStoreURL,
281 Value::CreateStringValue("http://www.google.de"));
[email protected]ee837d32012-10-02 22:25:49282 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
[email protected]25ae0152011-11-18 14:40:02283}
284
[email protected]43cbd7592011-12-08 08:52:10285TEST_F(ComponentLoaderTest, AddOrReplace) {
[email protected]ee837d32012-10-02 22:25:49286 EXPECT_EQ(0u, component_loader_.registered_extensions_count());
[email protected]bb121482012-12-08 06:49:38287 component_loader_.AddDefaultComponentExtensions(false);
[email protected]43cbd7592011-12-08 08:52:10288 size_t const default_count = component_loader_.registered_extensions_count();
[email protected]650b2d52013-02-10 03:41:45289 base::FilePath known_extension = GetBasePath()
[email protected]43cbd7592011-12-08 08:52:10290 .AppendASCII("override_component_extension");
[email protected]650b2d52013-02-10 03:41:45291 base::FilePath unknow_extension = extension_path_;
[email protected]43cbd7592011-12-08 08:52:10292
293 // Replace a default component extension.
294 component_loader_.AddOrReplace(known_extension);
[email protected]ee837d32012-10-02 22:25:49295 EXPECT_EQ(default_count,
[email protected]43cbd7592011-12-08 08:52:10296 component_loader_.registered_extensions_count());
297
298 // Add a new component extension.
299 component_loader_.AddOrReplace(unknow_extension);
[email protected]ee837d32012-10-02 22:25:49300 EXPECT_EQ(default_count + 1,
[email protected]43cbd7592011-12-08 08:52:10301 component_loader_.registered_extensions_count());
302
303 extension_service_.set_ready(true);
[email protected]eac88332012-12-26 17:57:45304 component_loader_.LoadAll();
[email protected]43cbd7592011-12-08 08:52:10305
[email protected]ee837d32012-10-02 22:25:49306 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
307 EXPECT_EQ(0u, extension_service_.unloaded_count());
[email protected]43cbd7592011-12-08 08:52:10308
309 // replace loaded component extension.
310 component_loader_.AddOrReplace(known_extension);
[email protected]ee837d32012-10-02 22:25:49311 EXPECT_EQ(default_count + 1, extension_service_.extensions()->size());
312 EXPECT_EQ(1u, extension_service_.unloaded_count());
[email protected]43cbd7592011-12-08 08:52:10313}
314
[email protected]25ae0152011-11-18 14:40:02315} // namespace extensions