blob: e5cf7b408167ac52200f5bdd4c9f3ba7d7810c0b [file] [log] [blame]
[email protected]4dad9ad82009-11-25 20:47:521// Copyright (c) 2009 The Chromium Authors. All rights reserved.
[email protected]6014d672008-12-05 00:38:252// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]bf73f0b2010-02-10 19:26:595#include "chrome/browser/extensions/extensions_service_unittest.h"
6
[email protected]f0397fa2008-12-11 17:59:587#include <algorithm>
[email protected]6014d672008-12-05 00:38:258#include <vector>
9
[email protected]24b538a2010-02-27 01:22:4410#include "base/basictypes.h"
[email protected]36a784c2009-06-23 06:21:0811#include "base/command_line.h"
[email protected]6014d672008-12-05 00:38:2512#include "base/file_util.h"
[email protected]93d49d72009-10-23 20:00:2013#include "base/json/json_reader.h"
[email protected]6014d672008-12-05 00:38:2514#include "base/message_loop.h"
15#include "base/path_service.h"
[email protected]24b538a2010-02-27 01:22:4416#include "base/string16.h"
[email protected]6014d672008-12-05 00:38:2517#include "base/string_util.h"
[email protected]24b538a2010-02-27 01:22:4418#include "base/task.h"
[email protected]da0aa3b2009-12-06 21:41:0319#include "chrome/browser/extensions/crx_installer.h"
[email protected]a17f9462009-06-09 02:56:4120#include "chrome/browser/extensions/extension_creator.h"
[email protected]6014d672008-12-05 00:38:2521#include "chrome/browser/extensions/extensions_service.h"
[email protected]a1257b12009-06-12 02:51:3422#include "chrome/browser/extensions/external_extension_provider.h"
[email protected]27b985d2009-06-25 17:53:1523#include "chrome/browser/extensions/external_pref_extension_provider.h"
[email protected]5b1a0e22009-05-26 19:00:5824#include "chrome/common/extensions/extension.h"
[email protected]cb691e82009-07-13 14:59:0125#include "chrome/common/extensions/extension_constants.h"
[email protected]7197f4992009-03-23 05:05:4926#include "chrome/common/extensions/url_pattern.h"
[email protected]6014d672008-12-05 00:38:2527#include "chrome/common/chrome_paths.h"
[email protected]e2eb43112009-05-29 21:19:5428#include "chrome/common/chrome_switches.h"
[email protected]5b1a0e22009-05-26 19:00:5829#include "chrome/common/extensions/extension_error_reporter.h"
[email protected]6014d672008-12-05 00:38:2530#include "chrome/common/json_value_serializer.h"
[email protected]894bb502009-05-21 22:39:5731#include "chrome/common/notification_registrar.h"
32#include "chrome/common/notification_service.h"
33#include "chrome/common/notification_type.h"
[email protected]36a784c2009-06-23 06:21:0834#include "chrome/common/pref_names.h"
[email protected]24b538a2010-02-27 01:22:4435#include "chrome/common/url_constants.h"
[email protected]894bb502009-05-21 22:39:5736#include "chrome/test/testing_profile.h"
[email protected]24b538a2010-02-27 01:22:4437#include "googleurl/src/gurl.h"
[email protected]6014d672008-12-05 00:38:2538#include "testing/gtest/include/gtest/gtest.h"
[email protected]f66c110c2008-12-05 20:26:2939#include "testing/platform_test.h"
[email protected]24b538a2010-02-27 01:22:4440#include "webkit/database/database_tracker.h"
41#include "webkit/database/database_util.h"
[email protected]6014d672008-12-05 00:38:2542
[email protected]c6d474f82009-12-16 21:11:0643namespace keys = extension_manifest_keys;
44
[email protected]f0397fa2008-12-11 17:59:5845namespace {
46
[email protected]df4956e2009-06-10 16:53:4247// Extension ids used during testing.
[email protected]5a2721f62009-06-13 07:08:2048const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
49const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
50const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj";
51const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk";
52const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
53const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
[email protected]d7eaf572009-07-01 21:57:0054const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln";
[email protected]5a2721f62009-06-13 07:08:2055const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad";
56const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
[email protected]df4956e2009-06-10 16:53:4257
[email protected]f0397fa2008-12-11 17:59:5858struct ExtensionsOrder {
59 bool operator()(const Extension* a, const Extension* b) {
60 return a->name() < b->name();
61 }
62};
63
[email protected]bb28e062009-02-27 17:19:1864static std::vector<std::string> GetErrors() {
65 const std::vector<std::string>* errors =
66 ExtensionErrorReporter::GetInstance()->GetErrors();
67 std::vector<std::string> ret_val;
68
69 for (std::vector<std::string>::const_iterator iter = errors->begin();
70 iter != errors->end(); ++iter) {
71 if (iter->find(".svn") == std::string::npos) {
72 ret_val.push_back(*iter);
73 }
74 }
75
76 // The tests rely on the errors being in a certain order, which can vary
77 // depending on how filesystem iteration works.
78 std::stable_sort(ret_val.begin(), ret_val.end());
79
80 return ret_val;
81}
82
[email protected]f0397fa2008-12-11 17:59:5883} // namespace
[email protected]6014d672008-12-05 00:38:2584
[email protected]a1257b12009-06-12 02:51:3485class MockExtensionProvider : public ExternalExtensionProvider {
86 public:
87 explicit MockExtensionProvider(Extension::Location location)
88 : location_(location) {}
89 virtual ~MockExtensionProvider() {}
90
91 void UpdateOrAddExtension(const std::string& id,
92 const std::string& version,
[email protected]f5ad7542009-07-24 17:38:5993 const FilePath& path) {
[email protected]a1257b12009-06-12 02:51:3494 extension_map_[id] = std::make_pair(version, path);
95 }
96
97 void RemoveExtension(const std::string& id) {
98 extension_map_.erase(id);
99 }
100
101 // ExternalExtensionProvider implementation:
102 virtual void VisitRegisteredExtension(
103 Visitor* visitor, const std::set<std::string>& ids_to_ignore) const {
104 for (DataMap::const_iterator i = extension_map_.begin();
105 i != extension_map_.end(); ++i) {
106 if (ids_to_ignore.find(i->first) != ids_to_ignore.end())
107 continue;
108 scoped_ptr<Version> version;
109 version.reset(Version::GetVersionFromString(i->second.first));
110
111 visitor->OnExternalExtensionFound(
[email protected]7577a5c52009-07-30 06:21:58112 i->first, version.get(), i->second.second, location_);
[email protected]a1257b12009-06-12 02:51:34113 }
114 }
115
[email protected]f5ad7542009-07-24 17:38:59116 virtual Version* RegisteredVersion(const std::string& id,
[email protected]a1257b12009-06-12 02:51:34117 Extension::Location* location) const {
118 DataMap::const_iterator it = extension_map_.find(id);
119 if (it == extension_map_.end())
120 return NULL;
121
122 if (location)
123 *location = location_;
124 return Version::GetVersionFromString(it->second.first);
125 }
126
127 private:
128 typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap;
129 DataMap extension_map_;
130 Extension::Location location_;
[email protected]27b985d2009-06-25 17:53:15131
132 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
133};
134
135class MockProviderVisitor : public ExternalExtensionProvider::Visitor {
136 public:
[email protected]eb752082009-09-28 21:18:32137 MockProviderVisitor() : ids_found_(0) {
[email protected]27b985d2009-06-25 17:53:15138 }
139
[email protected]f5ad7542009-07-24 17:38:59140 int Visit(const std::string& json_data,
141 const std::set<std::string>& ignore_list) {
[email protected]27b985d2009-06-25 17:53:15142 // Give the test json file to the provider for parsing.
143 provider_.reset(new ExternalPrefExtensionProvider());
144 provider_->SetPreferencesForTesting(json_data);
145
146 // We also parse the file into a dictionary to compare what we get back
147 // from the provider.
148 JSONStringValueSerializer serializer(json_data);
149 std::string error_msg;
150 Value* json_value = serializer.Deserialize(&error_msg);
151
152 if (!error_msg.empty() || !json_value ||
153 !json_value->IsType(Value::TYPE_DICTIONARY)) {
154 NOTREACHED() << L"Unable to deserialize json data";
155 return -1;
156 } else {
157 DictionaryValue* external_extensions =
158 static_cast<DictionaryValue*>(json_value);
159 prefs_.reset(external_extensions);
160 }
161
162 // Reset our counter.
163 ids_found_ = 0;
164 // Ask the provider to look up all extensions (and return the ones
165 // found (that are not on the ignore list).
166 provider_->VisitRegisteredExtension(this, ignore_list);
167
168 return ids_found_;
169 }
170
171 virtual void OnExternalExtensionFound(const std::string& id,
172 const Version* version,
[email protected]7577a5c52009-07-30 06:21:58173 const FilePath& path,
174 Extension::Location unused) {
[email protected]27b985d2009-06-25 17:53:15175 ++ids_found_;
176 DictionaryValue* pref;
177 // This tests is to make sure that the provider only notifies us of the
178 // values we gave it. So if the id we doesn't exist in our internal
179 // dictionary then something is wrong.
180 EXPECT_TRUE(prefs_->GetDictionary(ASCIIToWide(id), &pref))
181 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
182
183 if (pref) {
184 // Ask provider if the extension we got back is registered.
185 Extension::Location location = Extension::INVALID;
186 scoped_ptr<Version> v1(provider_->RegisteredVersion(id, NULL));
187 scoped_ptr<Version> v2(provider_->RegisteredVersion(id, &location));
188 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
189 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
190 EXPECT_EQ(Extension::EXTERNAL_PREF, location);
191
192 // Remove it so we won't count it ever again.
193 prefs_->Remove(ASCIIToWide(id), NULL);
194 }
195 }
196
197 private:
198 int ids_found_;
199
200 scoped_ptr<ExternalPrefExtensionProvider> provider_;
201 scoped_ptr<DictionaryValue> prefs_;
202
203 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
[email protected]a1257b12009-06-12 02:51:34204};
205
[email protected]bf73f0b2010-02-10 19:26:59206class ExtensionTestingProfile : public TestingProfile {
[email protected]6014d672008-12-05 00:38:25207 public:
[email protected]bf73f0b2010-02-10 19:26:59208 ExtensionTestingProfile() {
209 }
210
211 void set_extensions_service(ExtensionsService* service) {
212 service_ = service;
213 }
214 virtual ExtensionsService* GetExtensionsService() { return service_; }
215
216 private:
217 ExtensionsService* service_;
218};
219
220// Our message loop may be used in tests which require it to be an IO loop.
221ExtensionsServiceTestBase::ExtensionsServiceTestBase()
222 : loop_(MessageLoop::TYPE_IO),
223 ui_thread_(ChromeThread::UI, &loop_),
224 file_thread_(ChromeThread::FILE, &loop_) {
225}
226
227ExtensionsServiceTestBase::~ExtensionsServiceTestBase() {
228 // Drop our reference to ExtensionsService now, so that it can be destroyed
229 // while ChromeThreads and MessageLoop are still around (they are used
230 // in the ExtensionsService destruction process).
231 service_ = NULL;
232 MessageLoop::current()->RunAllPending();
233}
234
235void ExtensionsServiceTestBase::InitializeExtensionsService(
236 const FilePath& pref_file, const FilePath& extensions_install_dir) {
237 ExtensionTestingProfile* profile = new ExtensionTestingProfile();
238 prefs_.reset(new PrefService(pref_file));
239 profile_.reset(profile);
240
241 CommandLine::ForCurrentProcess()->AppendSwitch(
242 switches::kEnableExtensionToolstrips);
243 service_ = new ExtensionsService(profile_.get(),
244 CommandLine::ForCurrentProcess(),
245 prefs_.get(),
246 extensions_install_dir,
247 false);
248 service_->set_extensions_enabled(true);
249 service_->set_show_extensions_prompts(false);
250 profile->set_extensions_service(service_.get());
251
252 // When we start up, we want to make sure there is no external provider,
253 // since the ExtensionService on Windows will use the Registry as a default
254 // provider and if there is something already registered there then it will
255 // interfere with the tests. Those tests that need an external provider
256 // will register one specifically.
257 service_->ClearProvidersForTesting();
258
259 total_successes_ = 0;
260}
261
262void ExtensionsServiceTestBase::InitializeInstalledExtensionsService(
263 const FilePath& prefs_file, const FilePath& source_install_dir) {
264 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
265 FilePath path_ = temp_dir_.path();
266 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
267 file_util::Delete(path_, true);
268 file_util::CreateDirectory(path_);
269 FilePath temp_prefs = path_.Append(FILE_PATH_LITERAL("Preferences"));
270 file_util::CopyFile(prefs_file, temp_prefs);
271
272 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
273 file_util::Delete(extensions_install_dir_, true);
274 file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
275
276 InitializeExtensionsService(temp_prefs, extensions_install_dir_);
277}
278
279void ExtensionsServiceTestBase::InitializeEmptyExtensionsService() {
280 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
281 FilePath path_ = temp_dir_.path();
282 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
283 file_util::Delete(path_, true);
284 file_util::CreateDirectory(path_);
285 FilePath prefs_filename = path_
286 .Append(FILE_PATH_LITERAL("TestPreferences"));
287 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
288 file_util::Delete(extensions_install_dir_, true);
289 file_util::CreateDirectory(extensions_install_dir_);
290
291 InitializeExtensionsService(prefs_filename, extensions_install_dir_);
292}
293
294// static
295void ExtensionsServiceTestBase::SetUpTestCase() {
296 ExtensionErrorReporter::Init(false); // no noisy errors
297}
298
299void ExtensionsServiceTestBase::SetUp() {
300 ExtensionErrorReporter::GetInstance()->ClearErrors();
301}
302
303class ExtensionsServiceTest
304 : public ExtensionsServiceTestBase, public NotificationObserver {
305 public:
306 ExtensionsServiceTest() : installed_(NULL) {
[email protected]ae09ca62009-08-21 19:46:46307 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
[email protected]894bb502009-05-21 22:39:57308 NotificationService::AllSources());
309 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
310 NotificationService::AllSources());
311 registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
312 NotificationService::AllSources());
[email protected]e2eb43112009-05-29 21:19:54313 registrar_.Add(this, NotificationType::THEME_INSTALLED,
314 NotificationService::AllSources());
[email protected]a9b00ac2009-06-25 21:03:23315 }
[email protected]cc655912009-01-29 23:19:19316
[email protected]894bb502009-05-21 22:39:57317 virtual void Observe(NotificationType type,
318 const NotificationSource& source,
319 const NotificationDetails& details) {
320 switch (type.value) {
[email protected]ae09ca62009-08-21 19:46:46321 case NotificationType::EXTENSION_LOADED: {
322 Extension* extension = Details<Extension>(details).ptr();
323 loaded_.push_back(extension);
[email protected]894bb502009-05-21 22:39:57324 // The tests rely on the errors being in a certain order, which can vary
325 // depending on how filesystem iteration works.
326 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
327 break;
328 }
329
[email protected]9f1087e2009-06-15 17:29:32330 case NotificationType::EXTENSION_UNLOADED: {
331 Extension* e = Details<Extension>(details).ptr();
332 unloaded_id_ = e->id();
333 ExtensionList::iterator i =
334 std::find(loaded_.begin(), loaded_.end(), e);
335 // TODO(erikkay) fix so this can be an assert. Right now the tests
336 // are manually calling clear() on loaded_, so this isn't doable.
337 if (i == loaded_.end())
338 return;
339 loaded_.erase(i);
[email protected]894bb502009-05-21 22:39:57340 break;
[email protected]9f1087e2009-06-15 17:29:32341 }
[email protected]894bb502009-05-21 22:39:57342 case NotificationType::EXTENSION_INSTALLED:
[email protected]e2eb43112009-05-29 21:19:54343 case NotificationType::THEME_INSTALLED:
[email protected]894bb502009-05-21 22:39:57344 installed_ = Details<Extension>(details).ptr();
345 break;
346
[email protected]894bb502009-05-21 22:39:57347 default:
348 DCHECK(false);
[email protected]3acbd422008-12-08 18:25:00349 }
350 }
351
[email protected]a1257b12009-06-12 02:51:34352 void SetMockExternalProvider(Extension::Location location,
353 ExternalExtensionProvider* provider) {
354 service_->SetProviderForTesting(location, provider);
355 }
356
[email protected]9197f3b2009-06-02 00:49:27357 protected:
[email protected]d55e7602009-12-16 04:20:42358 void TestExternalProvider(MockExtensionProvider* provider,
359 Extension::Location location);
360
[email protected]9197f3b2009-06-02 00:49:27361 void InstallExtension(const FilePath& path,
[email protected]d2d89d82009-06-08 21:01:53362 bool should_succeed) {
[email protected]cc655912009-01-29 23:19:19363 ASSERT_TRUE(file_util::PathExists(path));
[email protected]6ef635e42009-07-26 06:16:12364 service_->InstallExtension(path);
[email protected]894bb502009-05-21 22:39:57365 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:18366 std::vector<std::string> errors = GetErrors();
[email protected]cc655912009-01-29 23:19:19367 if (should_succeed) {
[email protected]902f7cd2009-05-22 19:02:19368 ++total_successes_;
369
[email protected]a57209872009-05-04 22:53:14370 EXPECT_TRUE(installed_) << path.value();
[email protected]9197f3b2009-06-02 00:49:27371
[email protected]a1257b12009-06-12 02:51:34372 ASSERT_EQ(1u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18373 EXPECT_EQ(0u, errors.size()) << path.value();
[email protected]902f7cd2009-05-22 19:02:19374 EXPECT_EQ(total_successes_, service_->extensions()->size()) <<
375 path.value();
[email protected]61b411612009-11-10 23:17:41376 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
[email protected]d2d89d82009-06-08 21:01:53377 path.value();
[email protected]bb28e062009-02-27 17:19:18378 for (std::vector<std::string>::iterator err = errors.begin();
379 err != errors.end(); ++err) {
[email protected]37eeb5a2009-02-26 23:36:17380 LOG(ERROR) << *err;
381 }
[email protected]cc655912009-01-29 23:19:19382 } else {
[email protected]a57209872009-05-04 22:53:14383 EXPECT_FALSE(installed_) << path.value();
[email protected]86a274072009-06-11 02:06:45384 EXPECT_EQ(0u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18385 EXPECT_EQ(1u, errors.size()) << path.value();
[email protected]cc655912009-01-29 23:19:19386 }
[email protected]bb28e062009-02-27 17:19:18387
[email protected]a57209872009-05-04 22:53:14388 installed_ = NULL;
[email protected]894bb502009-05-21 22:39:57389 loaded_.clear();
[email protected]bb28e062009-02-27 17:19:18390 ExtensionErrorReporter::GetInstance()->ClearErrors();
[email protected]cc655912009-01-29 23:19:19391 }
392
[email protected]7577a5c52009-07-30 06:21:58393 void UpdateExtension(const std::string& id, const FilePath& in_path,
394 bool should_succeed, bool expect_report_on_failure) {
395 ASSERT_TRUE(file_util::PathExists(in_path));
[email protected]e957fe52009-06-23 16:51:05396
[email protected]7577a5c52009-07-30 06:21:58397 // We need to copy this to a temporary location because Update() will delete
398 // it.
[email protected]a1295ba22009-09-02 03:33:39399 FilePath path = temp_dir_.path();
400 path = path.Append(in_path.BaseName());
[email protected]7577a5c52009-07-30 06:21:58401 ASSERT_TRUE(file_util::CopyFile(in_path, path));
[email protected]e957fe52009-06-23 16:51:05402
[email protected]7577a5c52009-07-30 06:21:58403 service_->UpdateExtension(id, path);
[email protected]e957fe52009-06-23 16:51:05404 loop_.RunAllPending();
405 std::vector<std::string> errors = GetErrors();
406
[email protected]e957fe52009-06-23 16:51:05407 if (should_succeed) {
408 EXPECT_EQ(0u, errors.size()) << path.value();
409 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]e957fe52009-06-23 16:51:05410 } else {
411 if (expect_report_on_failure) {
412 EXPECT_EQ(1u, errors.size()) << path.value();
413 }
[email protected]e957fe52009-06-23 16:51:05414 }
[email protected]7577a5c52009-07-30 06:21:58415
416 // Update() should delete the temporary input file.
417 EXPECT_FALSE(file_util::PathExists(path));
[email protected]e957fe52009-06-23 16:51:05418 }
419
[email protected]25b34332009-06-05 21:53:19420 void ValidatePrefKeyCount(size_t count) {
421 DictionaryValue* dict =
[email protected]a9b00ac2009-06-25 21:03:23422 prefs_->GetMutableDictionary(L"extensions.settings");
[email protected]25b34332009-06-05 21:53:19423 ASSERT_TRUE(dict != NULL);
[email protected]4dad9ad82009-11-25 20:47:52424 EXPECT_EQ(count, dict->size());
[email protected]25b34332009-06-05 21:53:19425 }
426
[email protected]6b75ec32009-08-14 06:37:18427 void ValidateBooleanPref(const std::string& extension_id,
428 const std::wstring& pref_path,
[email protected]c6d474f82009-12-16 21:11:06429 bool expected_val) {
[email protected]6b75ec32009-08-14 06:37:18430 std::wstring msg = L" while checking: ";
431 msg += ASCIIToWide(extension_id);
432 msg += L" ";
433 msg += pref_path;
434 msg += L" == ";
[email protected]c6d474f82009-12-16 21:11:06435 msg += expected_val ? L"true" : L"false";
[email protected]6b75ec32009-08-14 06:37:18436
437 const DictionaryValue* dict =
438 prefs_->GetDictionary(L"extensions.settings");
439 ASSERT_TRUE(dict != NULL) << msg;
440 DictionaryValue* pref = NULL;
441 ASSERT_TRUE(dict->GetDictionary(ASCIIToWide(extension_id), &pref)) << msg;
442 EXPECT_TRUE(pref != NULL) << msg;
443 bool val;
[email protected]4c91487e2009-10-02 04:11:04444 ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06445 EXPECT_EQ(expected_val, val) << msg;
[email protected]6b75ec32009-08-14 06:37:18446 }
447
448 bool IsPrefExist(const std::string& extension_id,
449 const std::wstring& pref_path) {
450 const DictionaryValue* dict =
451 prefs_->GetDictionary(L"extensions.settings");
452 if (dict == NULL) return false;
453 DictionaryValue* pref = NULL;
454 if (!dict->GetDictionary(ASCIIToWide(extension_id), &pref)) {
455 return false;
456 }
457 if (pref == NULL) {
458 return false;
459 }
460 bool val;
461 if (!pref->GetBoolean(pref_path, &val)) {
462 return false;
463 }
464 return true;
465 }
466
467 void ValidateIntegerPref(const std::string& extension_id,
468 const std::wstring& pref_path,
[email protected]c6d474f82009-12-16 21:11:06469 int expected_val) {
[email protected]25b34332009-06-05 21:53:19470 std::wstring msg = L" while checking: ";
471 msg += ASCIIToWide(extension_id);
472 msg += L" ";
473 msg += pref_path;
474 msg += L" == ";
[email protected]c6d474f82009-12-16 21:11:06475 msg += IntToWString(expected_val);
[email protected]25b34332009-06-05 21:53:19476
477 const DictionaryValue* dict =
[email protected]a9b00ac2009-06-25 21:03:23478 prefs_->GetDictionary(L"extensions.settings");
[email protected]25b34332009-06-05 21:53:19479 ASSERT_TRUE(dict != NULL) << msg;
480 DictionaryValue* pref = NULL;
481 ASSERT_TRUE(dict->GetDictionary(ASCIIToWide(extension_id), &pref)) << msg;
482 EXPECT_TRUE(pref != NULL) << msg;
483 int val;
[email protected]4c91487e2009-10-02 04:11:04484 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06485 EXPECT_EQ(expected_val, val) << msg;
486 }
487
488 void ValidateStringPref(const std::string& extension_id,
489 const std::wstring& pref_path,
490 const std::string& expected_val) {
491 std::wstring msg = L" while checking: ";
492 msg += ASCIIToWide(extension_id);
493 msg += L".manifest.";
494 msg += pref_path;
495 msg += L" == ";
496 msg += ASCIIToWide(expected_val);
497
498 const DictionaryValue* dict =
499 prefs_->GetDictionary(L"extensions.settings");
500 ASSERT_TRUE(dict != NULL) << msg;
501 DictionaryValue* pref = NULL;
502 std::string manifest_path = extension_id + ".manifest";
503 ASSERT_TRUE(dict->GetDictionary(ASCIIToWide(manifest_path), &pref)) << msg;
504 EXPECT_TRUE(pref != NULL) << msg;
505 std::string val;
506 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
507 EXPECT_EQ(expected_val, val) << msg;
[email protected]25b34332009-06-05 21:53:19508 }
509
[email protected]6b75ec32009-08-14 06:37:18510 void SetPrefInteg(const std::string& extension_id,
511 const std::wstring& pref_path,
512 int value) {
[email protected]a1257b12009-06-12 02:51:34513 std::wstring msg = L" while setting: ";
514 msg += ASCIIToWide(extension_id);
515 msg += L" ";
516 msg += pref_path;
517 msg += L" = ";
518 msg += IntToWString(value);
519
520 const DictionaryValue* dict =
[email protected]a9b00ac2009-06-25 21:03:23521 prefs_->GetMutableDictionary(L"extensions.settings");
[email protected]a1257b12009-06-12 02:51:34522 ASSERT_TRUE(dict != NULL) << msg;
523 DictionaryValue* pref = NULL;
524 ASSERT_TRUE(dict->GetDictionary(ASCIIToWide(extension_id), &pref)) << msg;
525 EXPECT_TRUE(pref != NULL) << msg;
526 pref->SetInteger(pref_path, value);
527 }
528
[email protected]25b34332009-06-05 21:53:19529 protected:
[email protected]9f1087e2009-06-15 17:29:32530 ExtensionList loaded_;
[email protected]894bb502009-05-21 22:39:57531 std::string unloaded_id_;
532 Extension* installed_;
[email protected]894bb502009-05-21 22:39:57533
[email protected]6014d672008-12-05 00:38:25534 private:
[email protected]894bb502009-05-21 22:39:57535 NotificationRegistrar registrar_;
[email protected]bb28e062009-02-27 17:19:18536};
[email protected]6014d672008-12-05 00:38:25537
[email protected]a3278802009-07-24 17:50:20538FilePath::StringType NormalizeSeperators(FilePath::StringType path) {
[email protected]a9b00ac2009-06-25 21:03:23539#if defined(FILE_PATH_USES_WIN_SEPARATORS)
540 FilePath::StringType ret_val;
541 for (size_t i = 0; i < path.length(); i++) {
542 if (FilePath::IsSeparator(path[i]))
543 path[i] = FilePath::kSeparators[0];
544 }
545#endif // FILE_PATH_USES_WIN_SEPARATORS
546 return path;
547}
[email protected]54cb3c92009-02-17 22:30:21548// Test loading good extensions from the profile directory.
[email protected]a9b00ac2009-06-25 21:03:23549TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
550 // Initialize the test dir with a good Preferences/extensions.
551 FilePath source_install_dir;
552 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
553 source_install_dir = source_install_dir
554 .AppendASCII("extensions")
555 .AppendASCII("good")
556 .AppendASCII("Extensions");
557 FilePath pref_path = source_install_dir
558 .DirName()
559 .AppendASCII("Preferences");
560 InitializeInstalledExtensionsService(pref_path, source_install_dir);
[email protected]6014d672008-12-05 00:38:25561
[email protected]9f1087e2009-06-15 17:29:32562 service_->Init();
[email protected]894bb502009-05-21 22:39:57563 loop_.RunAllPending();
[email protected]6014d672008-12-05 00:38:25564
[email protected]894bb502009-05-21 22:39:57565 ASSERT_EQ(3u, loaded_.size());
[email protected]6014d672008-12-05 00:38:25566
[email protected]fbcc40302009-06-12 20:45:45567 EXPECT_EQ(std::string(good0), loaded_[0]->id());
[email protected]e1cec06c2008-12-18 01:22:23568 EXPECT_EQ(std::string("My extension 1"),
[email protected]894bb502009-05-21 22:39:57569 loaded_[0]->name());
[email protected]e1cec06c2008-12-18 01:22:23570 EXPECT_EQ(std::string("The first extension that I made."),
[email protected]894bb502009-05-21 22:39:57571 loaded_[0]->description());
572 EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location());
[email protected]61b411612009-11-10 23:17:41573 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
[email protected]894bb502009-05-21 22:39:57574 EXPECT_EQ(3u, service_->extensions()->size());
[email protected]eab9b452009-01-23 20:48:59575
[email protected]25b34332009-06-05 21:53:19576 ValidatePrefKeyCount(3);
[email protected]6b75ec32009-08-14 06:37:18577 ValidateIntegerPref(good0, L"state", Extension::ENABLED);
578 ValidateIntegerPref(good0, L"location", Extension::INTERNAL);
579 ValidateIntegerPref(good1, L"state", Extension::ENABLED);
580 ValidateIntegerPref(good1, L"location", Extension::INTERNAL);
581 ValidateIntegerPref(good2, L"state", Extension::ENABLED);
582 ValidateIntegerPref(good2, L"location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:19583
[email protected]894bb502009-05-21 22:39:57584 Extension* extension = loaded_[0];
[email protected]34aa8dc2009-02-19 07:03:05585 const UserScriptList& scripts = extension->content_scripts();
[email protected]bbc945542009-07-26 00:11:42586 const std::vector<Extension::ToolstripInfo>& toolstrips =
587 extension->toolstrips();
[email protected]e66de892009-03-20 20:38:43588 ASSERT_EQ(2u, scripts.size());
[email protected]f0488f2f2009-07-01 05:25:22589 EXPECT_EQ(3u, scripts[0].url_patterns().size());
[email protected]62771442009-11-22 02:25:04590 EXPECT_EQ("file://*",
[email protected]5f8681f2009-11-18 03:21:13591 scripts[0].url_patterns()[0].GetAsString());
[email protected]62771442009-11-22 02:25:04592 EXPECT_EQ("http://*.google.com/*",
[email protected]5f8681f2009-11-18 03:21:13593 scripts[0].url_patterns()[1].GetAsString());
[email protected]62771442009-11-22 02:25:04594 EXPECT_EQ("https://*.google.com/*",
[email protected]f0488f2f2009-07-01 05:25:22595 scripts[0].url_patterns()[2].GetAsString());
[email protected]e66de892009-03-20 20:38:43596 EXPECT_EQ(2u, scripts[0].js_scripts().size());
[email protected]9194b3f2009-10-20 15:27:21597 ExtensionResource resource00(scripts[0].js_scripts()[0].extension_root(),
598 scripts[0].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:29599 FilePath expected_path(extension->path().AppendASCII("script1.js"));
600 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
601 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
[email protected]9194b3f2009-10-20 15:27:21602 ExtensionResource resource01(scripts[0].js_scripts()[1].extension_root(),
603 scripts[0].js_scripts()[1].relative_path());
[email protected]a14b16b2009-10-28 12:41:29604 expected_path = extension->path().AppendASCII("script2.js");
605 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
606 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
[email protected]c533bb22009-06-03 19:06:11607 EXPECT_TRUE(extension->plugins().empty());
[email protected]e66de892009-03-20 20:38:43608 EXPECT_EQ(1u, scripts[1].url_patterns().size());
609 EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString());
[email protected]9194b3f2009-10-20 15:27:21610 ExtensionResource resource10(scripts[1].js_scripts()[0].extension_root(),
611 scripts[1].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:29612 expected_path =
613 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
614 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
615 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
[email protected]35506352009-08-07 18:58:19616 const std::vector<URLPattern> permissions = extension->host_permissions();
[email protected]7197f4992009-03-23 05:05:49617 ASSERT_EQ(2u, permissions.size());
618 EXPECT_EQ("http://*.google.com/*", permissions[0].GetAsString());
619 EXPECT_EQ("https://*.google.com/*", permissions[1].GetAsString());
[email protected]d5cef1b2009-03-21 05:36:49620 ASSERT_EQ(2u, toolstrips.size());
[email protected]bbc945542009-07-26 00:11:42621 EXPECT_EQ(extension->GetResourceURL("toolstrip1.html"),
622 toolstrips[0].toolstrip);
[email protected]e7a89e12009-07-26 23:29:47623 EXPECT_EQ(extension->GetResourceURL("lorem_ipsum.html"),
624 toolstrips[0].mole);
625 EXPECT_EQ(200, toolstrips[0].mole_height);
[email protected]bbc945542009-07-26 00:11:42626 EXPECT_EQ(extension->GetResourceURL("toolstrip2.html"),
627 toolstrips[1].toolstrip);
[email protected]6014d672008-12-05 00:38:25628
[email protected]25b34332009-06-05 21:53:19629 EXPECT_EQ(std::string(good1), loaded_[1]->id());
[email protected]894bb502009-05-21 22:39:57630 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
631 EXPECT_EQ(std::string(""), loaded_[1]->description());
[email protected]81067e02009-07-27 15:12:09632 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
633 loaded_[1]->background_url());
[email protected]894bb502009-05-21 22:39:57634 EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
[email protected]c533bb22009-06-03 19:06:11635 EXPECT_EQ(2u, loaded_[1]->plugins().size());
636 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
637 loaded_[1]->plugins()[0].path.value());
638 EXPECT_TRUE(loaded_[1]->plugins()[0].is_public);
639 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
640 loaded_[1]->plugins()[1].path.value());
641 EXPECT_FALSE(loaded_[1]->plugins()[1].is_public);
[email protected]894bb502009-05-21 22:39:57642 EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location());
[email protected]18a12352009-01-31 01:33:28643
[email protected]25b34332009-06-05 21:53:19644 EXPECT_EQ(std::string(good2), loaded_[2]->id());
[email protected]894bb502009-05-21 22:39:57645 EXPECT_EQ(std::string("My extension 3"), loaded_[2]->name());
646 EXPECT_EQ(std::string(""), loaded_[2]->description());
[email protected]7a379f02010-01-08 23:14:12647 EXPECT_EQ(0u, loaded_[2]->content_scripts().size());
[email protected]894bb502009-05-21 22:39:57648 EXPECT_EQ(Extension::INTERNAL, loaded_[2]->location());
[email protected]6014d672008-12-05 00:38:25649};
[email protected]cc655912009-01-29 23:19:19650
[email protected]54cb3c92009-02-17 22:30:21651// Test loading bad extensions from the profile directory.
[email protected]a9b00ac2009-06-25 21:03:23652TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) {
[email protected]c6d474f82009-12-16 21:11:06653 // Initialize the test dir with a bad Preferences/extensions.
[email protected]a9b00ac2009-06-25 21:03:23654 FilePath source_install_dir;
655 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
656 source_install_dir = source_install_dir
657 .AppendASCII("extensions")
658 .AppendASCII("bad")
659 .AppendASCII("Extensions");
660 FilePath pref_path = source_install_dir
661 .DirName()
662 .AppendASCII("Preferences");
[email protected]54cb3c92009-02-17 22:30:21663
[email protected]a9b00ac2009-06-25 21:03:23664 InitializeInstalledExtensionsService(pref_path, source_install_dir);
[email protected]54cb3c92009-02-17 22:30:21665
[email protected]9f1087e2009-06-15 17:29:32666 service_->Init();
[email protected]894bb502009-05-21 22:39:57667 loop_.RunAllPending();
[email protected]54cb3c92009-02-17 22:30:21668
[email protected]a9b00ac2009-06-25 21:03:23669 ASSERT_EQ(4u, GetErrors().size());
670 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:19671
[email protected]c5a72482009-12-03 23:32:57672 EXPECT_TRUE(MatchPatternASCII(GetErrors()[0],
[email protected]d7b36dc2009-10-29 21:47:40673 std::string("Could not load extension from '*'. ") +
674 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[0];
[email protected]8d6d9ff2009-02-20 08:14:39675
[email protected]c5a72482009-12-03 23:32:57676 EXPECT_TRUE(MatchPatternASCII(GetErrors()[1],
[email protected]8d6d9ff2009-02-20 08:14:39677 std::string("Could not load extension from '*'. ") +
[email protected]f6f5b8b2009-10-09 21:28:19678 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[1];
[email protected]8d6d9ff2009-02-20 08:14:39679
[email protected]c5a72482009-12-03 23:32:57680 EXPECT_TRUE(MatchPatternASCII(GetErrors()[2],
[email protected]8d6d9ff2009-02-20 08:14:39681 std::string("Could not load extension from '*'. ") +
[email protected]cb691e82009-07-13 14:59:01682 extension_manifest_errors::kMissingFile)) << GetErrors()[2];
[email protected]a9b00ac2009-06-25 21:03:23683
[email protected]c5a72482009-12-03 23:32:57684 EXPECT_TRUE(MatchPatternASCII(GetErrors()[3],
[email protected]a9b00ac2009-06-25 21:03:23685 std::string("Could not load extension from '*'. ") +
[email protected]f6f5b8b2009-10-09 21:28:19686 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[3];
[email protected]54cb3c92009-02-17 22:30:21687};
688
[email protected]894bb502009-05-21 22:39:57689// Test that partially deleted extensions are cleaned up during startup
690// Test loading bad extensions from the profile directory.
691TEST_F(ExtensionsServiceTest, CleanupOnStartup) {
[email protected]b6ab96d2009-08-20 18:58:19692 FilePath source_install_dir;
693 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
694 source_install_dir = source_install_dir
695 .AppendASCII("extensions")
696 .AppendASCII("good")
697 .AppendASCII("Extensions");
698 FilePath pref_path = source_install_dir
699 .DirName()
700 .AppendASCII("Preferences");
[email protected]a9b00ac2009-06-25 21:03:23701
[email protected]b6ab96d2009-08-20 18:58:19702 InitializeInstalledExtensionsService(pref_path, source_install_dir);
[email protected]894bb502009-05-21 22:39:57703
[email protected]b6ab96d2009-08-20 18:58:19704 // Simulate that one of them got partially deleted by clearing its pref.
[email protected]9b410dee2009-10-08 21:12:35705 DictionaryValue* dict = prefs_->GetMutableDictionary(L"extensions.settings");
[email protected]932342a2009-10-08 21:27:17706 ASSERT_TRUE(dict != NULL);
[email protected]9b410dee2009-10-08 21:12:35707 dict->Remove(L"behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
[email protected]894bb502009-05-21 22:39:57708
709 service_->Init();
710 loop_.RunAllPending();
711
[email protected]a9b00ac2009-06-25 21:03:23712 file_util::FileEnumerator dirs(extensions_install_dir_, false,
[email protected]9f1087e2009-06-15 17:29:32713 file_util::FileEnumerator::DIRECTORIES);
714 size_t count = 0;
715 while (!dirs.Next().empty())
716 count++;
717
[email protected]894bb502009-05-21 22:39:57718 // We should have only gotten two extensions now.
[email protected]9f1087e2009-06-15 17:29:32719 EXPECT_EQ(2u, count);
[email protected]e2eb43112009-05-29 21:19:54720
[email protected]894bb502009-05-21 22:39:57721 // And extension1 dir should now be toast.
[email protected]b6ab96d2009-08-20 18:58:19722 FilePath extension_dir = extensions_install_dir_
723 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
724 ASSERT_FALSE(file_util::PathExists(extension_dir));
[email protected]894bb502009-05-21 22:39:57725}
726
[email protected]d7eaf572009-07-01 21:57:00727// Test installing extensions. This test tries to install few extensions using
728// crx files. If you need to change those crx files, feel free to repackage
729// them, throw away the key used and change the id's above.
[email protected]da0aa3b2009-12-06 21:41:03730TEST_F(ExtensionsServiceTest, InstallExtension) {
[email protected]a9b00ac2009-06-25 21:03:23731 InitializeEmptyExtensionsService();
732
[email protected]cc655912009-01-29 23:19:19733 FilePath extensions_path;
734 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
735 extensions_path = extensions_path.AppendASCII("extensions");
736
[email protected]e2eb43112009-05-29 21:19:54737 // Extensions not enabled.
[email protected]7577a5c52009-07-30 06:21:58738 set_extensions_enabled(false);
[email protected]894bb502009-05-21 22:39:57739 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]d2d89d82009-06-08 21:01:53740 InstallExtension(path, false);
[email protected]7577a5c52009-07-30 06:21:58741 set_extensions_enabled(true);
[email protected]e2eb43112009-05-29 21:19:54742
[email protected]25b34332009-06-05 21:53:19743 ValidatePrefKeyCount(0);
744
[email protected]e2eb43112009-05-29 21:19:54745 // A simple extension that should install without error.
746 path = extensions_path.AppendASCII("good.crx");
[email protected]d2d89d82009-06-08 21:01:53747 InstallExtension(path, true);
[email protected]cc655912009-01-29 23:19:19748 // TODO(erikkay): verify the contents of the installed extension.
749
[email protected]25b34332009-06-05 21:53:19750 int pref_count = 0;
751 ValidatePrefKeyCount(++pref_count);
[email protected]6b75ec32009-08-14 06:37:18752 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
753 ValidateIntegerPref(good_crx, L"location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:19754
[email protected]902f7cd2009-05-22 19:02:19755 // An extension with page actions.
756 path = extensions_path.AppendASCII("page_action.crx");
[email protected]d2d89d82009-06-08 21:01:53757 InstallExtension(path, true);
[email protected]25b34332009-06-05 21:53:19758 ValidatePrefKeyCount(++pref_count);
[email protected]6b75ec32009-08-14 06:37:18759 ValidateIntegerPref(page_action, L"state", Extension::ENABLED);
760 ValidateIntegerPref(page_action, L"location", Extension::INTERNAL);
[email protected]902f7cd2009-05-22 19:02:19761
[email protected]9f1087e2009-06-15 17:29:32762 // Bad signature.
[email protected]fbcc40302009-06-12 20:45:45763 path = extensions_path.AppendASCII("bad_signature.crx");
764 InstallExtension(path, false);
[email protected]d7eaf572009-07-01 21:57:00765 ValidatePrefKeyCount(pref_count);
[email protected]fbcc40302009-06-12 20:45:45766
[email protected]cc655912009-01-29 23:19:19767 // 0-length extension file.
768 path = extensions_path.AppendASCII("not_an_extension.crx");
[email protected]d2d89d82009-06-08 21:01:53769 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:19770 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:19771
772 // Bad magic number.
773 path = extensions_path.AppendASCII("bad_magic.crx");
[email protected]d2d89d82009-06-08 21:01:53774 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:19775 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:19776
[email protected]99872e32009-09-25 22:02:49777 // Extensions cannot have folders or files that have underscores except ofr in
778 // certain whitelisted cases (eg _locales). This is an example of a broader
779 // class of validation that we do to the directory structure of the extension.
780 // We did not used to handle this correctly for installation.
781 path = extensions_path.AppendASCII("bad_underscore.crx");
782 InstallExtension(path, false);
783 ValidatePrefKeyCount(pref_count);
784
[email protected]cc655912009-01-29 23:19:19785 // TODO(erikkay): add more tests for many of the failure cases.
786 // TODO(erikkay): add tests for upgrade cases.
787}
788
[email protected]da0aa3b2009-12-06 21:41:03789// Install a user script (they get converted automatically to an extension)
790TEST_F(ExtensionsServiceTest, InstallUserScript) {
791 // The details of script conversion are tested elsewhere, this just tests
792 // integration with ExtensionsService.
793 InitializeEmptyExtensionsService();
794
795 FilePath path;
796 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
797 path = path.AppendASCII("extensions")
798 .AppendASCII("user_script_basic.user.js");
799
800 ASSERT_TRUE(file_util::PathExists(path));
[email protected]6dfbbf82010-03-12 23:09:16801 scoped_refptr<CrxInstaller> installer(
802 new CrxInstaller(service_->install_directory(),
803 service_,
804 NULL)); // silent install
805 installer->InstallUserScript(
[email protected]da0aa3b2009-12-06 21:41:03806 path,
[email protected]6dfbbf82010-03-12 23:09:16807 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
[email protected]da0aa3b2009-12-06 21:41:03808
809 loop_.RunAllPending();
810 std::vector<std::string> errors = GetErrors();
811 EXPECT_TRUE(installed_) << "Nothing was installed.";
812 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
813 EXPECT_EQ(0u, errors.size()) << "There were errors: "
814 << JoinString(errors, ',');
815 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
816 path.value();
817
818 installed_ = NULL;
819 loaded_.clear();
820 ExtensionErrorReporter::GetInstance()->ClearErrors();
821}
822
[email protected]a17f9462009-06-09 02:56:41823// Test Packaging and installing an extension.
[email protected]a17f9462009-06-09 02:56:41824TEST_F(ExtensionsServiceTest, PackExtension) {
[email protected]a9b00ac2009-06-25 21:03:23825 InitializeEmptyExtensionsService();
[email protected]a17f9462009-06-09 02:56:41826 FilePath extensions_path;
827 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
828 extensions_path = extensions_path.AppendASCII("extensions");
[email protected]a9b00ac2009-06-25 21:03:23829 FilePath input_directory = extensions_path
830 .AppendASCII("good")
831 .AppendASCII("Extensions")
832 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
833 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:41834
[email protected]aca3e9b2009-11-03 01:14:21835 ScopedTempDir temp_dir;
836 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
837 FilePath output_directory = temp_dir.path();
838
[email protected]a17f9462009-06-09 02:56:41839 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
840 FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
841
842 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
843 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
844 privkey_path));
845
[email protected]a17f9462009-06-09 02:56:41846 ASSERT_TRUE(file_util::PathExists(privkey_path));
[email protected]5a2721f62009-06-13 07:08:20847 InstallExtension(crx_path, true);
[email protected]0dc2ca82009-11-17 07:06:16848
849 // Try packing with invalid paths.
850 creator.reset(new ExtensionCreator());
851 ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath()));
852
853 // Try packing an empty directory. Should fail because an empty directory is
854 // not a valid extension.
855 ScopedTempDir temp_dir2;
856 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
857 creator.reset(new ExtensionCreator());
858 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
859 FilePath()));
860
861 // Try packing with an invalid manifest.
862 std::string invalid_manifest_content = "I am not a manifest.";
863 ASSERT_TRUE(file_util::WriteFile(
[email protected]99efb7b12009-12-18 02:39:16864 temp_dir2.path().Append(Extension::kManifestFilename),
[email protected]0dc2ca82009-11-17 07:06:16865 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
866 creator.reset(new ExtensionCreator());
867 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
868 FilePath()));
[email protected]a17f9462009-06-09 02:56:41869}
870
871// Test Packaging and installing an extension using an openssl generated key.
872// The openssl is generated with the following:
[email protected]a1257b12009-06-12 02:51:34873// > openssl genrsa -out privkey.pem 1024
[email protected]df4956e2009-06-10 16:53:42874// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
[email protected]a1257b12009-06-12 02:51:34875// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
[email protected]a17f9462009-06-09 02:56:41876// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
877TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) {
[email protected]a9b00ac2009-06-25 21:03:23878 InitializeEmptyExtensionsService();
[email protected]a17f9462009-06-09 02:56:41879 FilePath extensions_path;
880 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
881 extensions_path = extensions_path.AppendASCII("extensions");
[email protected]a9b00ac2009-06-25 21:03:23882 FilePath input_directory = extensions_path
883 .AppendASCII("good")
884 .AppendASCII("Extensions")
885 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
886 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:41887 FilePath privkey_path(extensions_path.AppendASCII(
888 "openssl_privkey_asn1.pem"));
889 ASSERT_TRUE(file_util::PathExists(privkey_path));
890
[email protected]aca3e9b2009-11-03 01:14:21891 ScopedTempDir temp_dir;
892 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
893 FilePath output_directory = temp_dir.path();
894
[email protected]a17f9462009-06-09 02:56:41895 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
896
897 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
898 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
899 FilePath()));
900
[email protected]5a2721f62009-06-13 07:08:20901 InstallExtension(crx_path, true);
[email protected]a17f9462009-06-09 02:56:41902}
[email protected]a17f9462009-06-09 02:56:41903
[email protected]e2eb43112009-05-29 21:19:54904TEST_F(ExtensionsServiceTest, InstallTheme) {
[email protected]a9b00ac2009-06-25 21:03:23905 InitializeEmptyExtensionsService();
[email protected]e2eb43112009-05-29 21:19:54906 FilePath extensions_path;
907 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
908 extensions_path = extensions_path.AppendASCII("extensions");
909
910 // A theme.
911 FilePath path = extensions_path.AppendASCII("theme.crx");
[email protected]d2d89d82009-06-08 21:01:53912 InstallExtension(path, true);
[email protected]25b34332009-06-05 21:53:19913 int pref_count = 0;
914 ValidatePrefKeyCount(++pref_count);
[email protected]6b75ec32009-08-14 06:37:18915 ValidateIntegerPref(theme_crx, L"state", Extension::ENABLED);
916 ValidateIntegerPref(theme_crx, L"location", Extension::INTERNAL);
[email protected]e2eb43112009-05-29 21:19:54917
[email protected]6ef635e42009-07-26 06:16:12918 // A theme when extensions are disabled. Themes can be installed, even when
919 // extensions are disabled.
[email protected]7577a5c52009-07-30 06:21:58920 set_extensions_enabled(false);
[email protected]e2eb43112009-05-29 21:19:54921 path = extensions_path.AppendASCII("theme2.crx");
[email protected]6ef635e42009-07-26 06:16:12922 InstallExtension(path, true);
[email protected]25b34332009-06-05 21:53:19923 ValidatePrefKeyCount(++pref_count);
[email protected]6b75ec32009-08-14 06:37:18924 ValidateIntegerPref(theme2_crx, L"state", Extension::ENABLED);
925 ValidateIntegerPref(theme2_crx, L"location", Extension::INTERNAL);
[email protected]494c06e2009-07-25 01:06:42926
[email protected]25b34332009-06-05 21:53:19927 // A theme with extension elements. Themes cannot have extension elements so
928 // this test should fail.
[email protected]7577a5c52009-07-30 06:21:58929 set_extensions_enabled(true);
[email protected]e2eb43112009-05-29 21:19:54930 path = extensions_path.AppendASCII("theme_with_extension.crx");
[email protected]d2d89d82009-06-08 21:01:53931 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:19932 ValidatePrefKeyCount(pref_count);
[email protected]12198912009-06-05 03:41:22933
934 // A theme with image resources missing (misspelt path).
935 path = extensions_path.AppendASCII("theme_missing_image.crx");
[email protected]d2d89d82009-06-08 21:01:53936 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:19937 ValidatePrefKeyCount(pref_count);
[email protected]e2eb43112009-05-29 21:19:54938}
939
[email protected]894bb502009-05-21 22:39:57940// Test that when an extension version is reinstalled, nothing happens.
941TEST_F(ExtensionsServiceTest, Reinstall) {
[email protected]a9b00ac2009-06-25 21:03:23942 InitializeEmptyExtensionsService();
[email protected]894bb502009-05-21 22:39:57943 FilePath extensions_path;
944 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
945 extensions_path = extensions_path.AppendASCII("extensions");
946
947 // A simple extension that should install without error.
948 FilePath path = extensions_path.AppendASCII("good.crx");
949 service_->InstallExtension(path);
950 loop_.RunAllPending();
951
952 ASSERT_TRUE(installed_);
953 ASSERT_EQ(1u, loaded_.size());
954 ASSERT_EQ(0u, GetErrors().size());
[email protected]25b34332009-06-05 21:53:19955 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:18956 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
957 ValidateIntegerPref(good_crx, L"location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:57958
959 installed_ = NULL;
960 loaded_.clear();
961 ExtensionErrorReporter::GetInstance()->ClearErrors();
962
963 // Reinstall the same version, nothing should happen.
964 service_->InstallExtension(path);
965 loop_.RunAllPending();
966
967 ASSERT_FALSE(installed_);
968 ASSERT_EQ(0u, loaded_.size());
969 ASSERT_EQ(0u, GetErrors().size());
[email protected]25b34332009-06-05 21:53:19970 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:18971 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
972 ValidateIntegerPref(good_crx, L"location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:57973}
974
[email protected]fbcc40302009-06-12 20:45:45975// Test upgrading a signed extension.
976TEST_F(ExtensionsServiceTest, UpgradeSignedGood) {
[email protected]a9b00ac2009-06-25 21:03:23977 InitializeEmptyExtensionsService();
[email protected]fbcc40302009-06-12 20:45:45978 FilePath extensions_path;
979 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
980 extensions_path = extensions_path.AppendASCII("extensions");
981
982 FilePath path = extensions_path.AppendASCII("good.crx");
983 service_->InstallExtension(path);
984 loop_.RunAllPending();
985
986 ASSERT_TRUE(installed_);
987 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:32988 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:45989 ASSERT_EQ(0u, GetErrors().size());
990
991 // Upgrade to version 2.0
992 path = extensions_path.AppendASCII("good2.crx");
993 service_->InstallExtension(path);
994 loop_.RunAllPending();
995
996 ASSERT_TRUE(installed_);
[email protected]9f1087e2009-06-15 17:29:32997 ASSERT_EQ(1u, loaded_.size());
998 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:45999 ASSERT_EQ(0u, GetErrors().size());
1000}
1001
1002// Test upgrading a signed extension with a bad signature.
1003TEST_F(ExtensionsServiceTest, UpgradeSignedBad) {
[email protected]a9b00ac2009-06-25 21:03:231004 InitializeEmptyExtensionsService();
[email protected]fbcc40302009-06-12 20:45:451005 FilePath extensions_path;
1006 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1007 extensions_path = extensions_path.AppendASCII("extensions");
1008
1009 FilePath path = extensions_path.AppendASCII("good.crx");
1010 service_->InstallExtension(path);
1011 loop_.RunAllPending();
1012
1013 ASSERT_TRUE(installed_);
1014 ASSERT_EQ(1u, loaded_.size());
1015 ASSERT_EQ(0u, GetErrors().size());
1016 installed_ = NULL;
1017
1018 // Try upgrading with a bad signature. This should fail during the unpack,
1019 // because the key will not match the signature.
1020 path = extensions_path.AppendASCII("good2_bad_signature.crx");
1021 service_->InstallExtension(path);
1022 loop_.RunAllPending();
1023
1024 ASSERT_FALSE(installed_);
1025 ASSERT_EQ(1u, loaded_.size());
1026 ASSERT_EQ(1u, GetErrors().size());
1027}
1028
[email protected]e957fe52009-06-23 16:51:051029// Test a normal update via the UpdateExtension API
1030TEST_F(ExtensionsServiceTest, UpdateExtension) {
[email protected]a9b00ac2009-06-25 21:03:231031 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051032 FilePath extensions_path;
1033 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1034 extensions_path = extensions_path.AppendASCII("extensions");
1035
1036 FilePath path = extensions_path.AppendASCII("good.crx");
1037
1038 InstallExtension(path, true);
1039 Extension* good = service_->extensions()->at(0);
1040 ASSERT_EQ("1.0.0.0", good->VersionString());
1041 ASSERT_EQ(good_crx, good->id());
1042
1043 path = extensions_path.AppendASCII("good2.crx");
[email protected]7577a5c52009-07-30 06:21:581044 UpdateExtension(good_crx, path, true, true);
[email protected]e957fe52009-06-23 16:51:051045 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
1046}
1047
1048// Test updating a not-already-installed extension - this should fail
1049TEST_F(ExtensionsServiceTest, UpdateNotInstalledExtension) {
[email protected]a9b00ac2009-06-25 21:03:231050 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051051 FilePath extensions_path;
1052 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1053 extensions_path = extensions_path.AppendASCII("extensions");
1054
1055 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]7577a5c52009-07-30 06:21:581056 service_->UpdateExtension(good_crx, path);
[email protected]e957fe52009-06-23 16:51:051057 loop_.RunAllPending();
1058
1059 ASSERT_EQ(0u, service_->extensions()->size());
1060 ASSERT_FALSE(installed_);
1061 ASSERT_EQ(0u, loaded_.size());
1062}
1063
1064// Makes sure you can't downgrade an extension via UpdateExtension
1065TEST_F(ExtensionsServiceTest, UpdateWillNotDowngrade) {
[email protected]a9b00ac2009-06-25 21:03:231066 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051067 FilePath extensions_path;
1068 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1069 extensions_path = extensions_path.AppendASCII("extensions");
1070
1071 FilePath path = extensions_path.AppendASCII("good2.crx");
1072
1073 InstallExtension(path, true);
1074 Extension* good = service_->extensions()->at(0);
1075 ASSERT_EQ("1.0.0.1", good->VersionString());
1076 ASSERT_EQ(good_crx, good->id());
1077
1078 // Change path from good2.crx -> good.crx
1079 path = extensions_path.AppendASCII("good.crx");
[email protected]7577a5c52009-07-30 06:21:581080 UpdateExtension(good_crx, path, false, true);
[email protected]e957fe52009-06-23 16:51:051081 ASSERT_EQ("1.0.0.1", service_->extensions()->at(0)->VersionString());
1082}
1083
1084// Make sure calling update with an identical version does nothing
1085TEST_F(ExtensionsServiceTest, UpdateToSameVersionIsNoop) {
[email protected]a9b00ac2009-06-25 21:03:231086 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051087 FilePath extensions_path;
1088 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1089 extensions_path = extensions_path.AppendASCII("extensions");
1090
1091 FilePath path = extensions_path.AppendASCII("good.crx");
1092
1093 InstallExtension(path, true);
1094 Extension* good = service_->extensions()->at(0);
1095 ASSERT_EQ(good_crx, good->id());
[email protected]7577a5c52009-07-30 06:21:581096 UpdateExtension(good_crx, path, false, false);
[email protected]e957fe52009-06-23 16:51:051097}
1098
[email protected]6b75ec32009-08-14 06:37:181099// Test pref settings for blacklist and unblacklist extensions.
1100TEST_F(ExtensionsServiceTest, SetUnsetBlacklistInPrefs) {
1101 InitializeEmptyExtensionsService();
1102 std::vector<std::string> blacklist;
1103 blacklist.push_back(good0);
1104 blacklist.push_back("invalid_id"); // an invalid id
1105 blacklist.push_back(good1);
1106 service_->UpdateExtensionBlacklist(blacklist);
1107 // Make sure pref is updated
1108 loop_.RunAllPending();
1109
1110 // blacklist is set for good0,1,2
1111 ValidateBooleanPref(good0, L"blacklist", true);
1112 ValidateBooleanPref(good1, L"blacklist", true);
1113 // invalid_id should not be inserted to pref.
1114 EXPECT_FALSE(IsPrefExist("invalid_id", L"blacklist"));
1115
1116 // remove good1, add good2
1117 blacklist.pop_back();
1118 blacklist.push_back(good2);
1119
1120 service_->UpdateExtensionBlacklist(blacklist);
1121 // only good0 and good1 should be set
1122 ValidateBooleanPref(good0, L"blacklist", true);
1123 EXPECT_FALSE(IsPrefExist(good1, L"blacklist"));
1124 ValidateBooleanPref(good2, L"blacklist", true);
1125 EXPECT_FALSE(IsPrefExist("invalid_id", L"blacklist"));
1126}
1127
1128// Unload installed extension from blacklist.
1129TEST_F(ExtensionsServiceTest, UnloadBlacklistedExtension) {
1130 InitializeEmptyExtensionsService();
1131 FilePath extensions_path;
1132 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1133 extensions_path = extensions_path.AppendASCII("extensions");
1134
1135 FilePath path = extensions_path.AppendASCII("good.crx");
1136
1137 InstallExtension(path, true);
1138 Extension* good = service_->extensions()->at(0);
1139 EXPECT_EQ(good_crx, good->id());
1140 UpdateExtension(good_crx, path, false, false);
1141
1142 std::vector<std::string> blacklist;
1143 blacklist.push_back(good_crx);
1144 service_->UpdateExtensionBlacklist(blacklist);
1145 // Make sure pref is updated
1146 loop_.RunAllPending();
1147
1148 // Now, the good_crx is blacklisted.
1149 ValidateBooleanPref(good_crx, L"blacklist", true);
1150 EXPECT_EQ(0u, service_->extensions()->size());
1151
1152 // Remove good_crx from blacklist
1153 blacklist.pop_back();
1154 service_->UpdateExtensionBlacklist(blacklist);
1155 // Make sure pref is updated
1156 loop_.RunAllPending();
1157 // blacklist value should not be set for good_crx
1158 EXPECT_FALSE(IsPrefExist(good_crx, L"blacklist"));
1159}
1160
1161// Unload installed extension from blacklist.
1162TEST_F(ExtensionsServiceTest, BlacklistedExtensionWillNotInstall) {
1163 InitializeEmptyExtensionsService();
1164 std::vector<std::string> blacklist;
1165 blacklist.push_back(good_crx);
1166 service_->UpdateExtensionBlacklist(blacklist);
1167 // Make sure pref is updated
1168 loop_.RunAllPending();
1169
1170 // Now, the good_crx is blacklisted.
1171 ValidateBooleanPref(good_crx, L"blacklist", true);
1172
1173 // We can not install good_crx.
1174 FilePath extensions_path;
1175 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1176 extensions_path = extensions_path.AppendASCII("extensions");
1177 FilePath path = extensions_path.AppendASCII("good.crx");
1178 service_->InstallExtension(path);
1179 loop_.RunAllPending();
1180 EXPECT_EQ(0u, service_->extensions()->size());
1181 ValidateBooleanPref(good_crx, L"blacklist", true);
1182}
1183
1184// Test loading extensions from the profile directory, except
1185// blacklisted ones.
1186TEST_F(ExtensionsServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
1187 // Initialize the test dir with a good Preferences/extensions.
1188 FilePath source_install_dir;
1189 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
1190 source_install_dir = source_install_dir
1191 .AppendASCII("extensions")
1192 .AppendASCII("good")
1193 .AppendASCII("Extensions");
1194 FilePath pref_path = source_install_dir
1195 .DirName()
1196 .AppendASCII("Preferences");
1197 InitializeInstalledExtensionsService(pref_path, source_install_dir);
1198
1199 // Blacklist good0.
1200 std::vector<std::string> blacklist;
1201 blacklist.push_back(good0);
1202 service_->UpdateExtensionBlacklist(blacklist);
1203 // Make sure pref is updated
1204 loop_.RunAllPending();
1205
1206 ValidateBooleanPref(good0, L"blacklist", true);
1207
1208 // Load extensions.
1209 service_->Init();
1210 loop_.RunAllPending();
1211
1212 std::vector<std::string> errors = GetErrors();
1213 for (std::vector<std::string>::iterator err = errors.begin();
1214 err != errors.end(); ++err) {
1215 LOG(ERROR) << *err;
1216 }
[email protected]d7b36dc2009-10-29 21:47:401217 ASSERT_EQ(2u, loaded_.size());
[email protected]6b75ec32009-08-14 06:37:181218
1219 EXPECT_NE(std::string(good0), loaded_[0]->id());
1220 EXPECT_NE(std::string(good0), loaded_[1]->id());
1221}
1222
[email protected]894bb502009-05-21 22:39:571223// Tests uninstalling normal extensions
[email protected]631cf822009-05-15 07:01:251224TEST_F(ExtensionsServiceTest, UninstallExtension) {
[email protected]a9b00ac2009-06-25 21:03:231225 InitializeEmptyExtensionsService();
[email protected]631cf822009-05-15 07:01:251226 FilePath extensions_path;
1227 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1228 extensions_path = extensions_path.AppendASCII("extensions");
1229
[email protected]4f313d52009-05-21 00:42:291230 // A simple extension that should install without error.
[email protected]894bb502009-05-21 22:39:571231 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]d2d89d82009-06-08 21:01:531232 InstallExtension(path, true);
[email protected]631cf822009-05-15 07:01:251233
1234 // The directory should be there now.
[email protected]25b34332009-06-05 21:53:191235 const char* extension_id = good_crx;
[email protected]a9b00ac2009-06-25 21:03:231236 FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
[email protected]631cf822009-05-15 07:01:251237 EXPECT_TRUE(file_util::PathExists(extension_path));
1238
[email protected]25b34332009-06-05 21:53:191239 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:181240 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
1241 ValidateIntegerPref(good_crx, L"location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:191242
[email protected]894bb502009-05-21 22:39:571243 // Uninstall it.
[email protected]27b985d2009-06-25 17:53:151244 service_->UninstallExtension(extension_id, false);
[email protected]902f7cd2009-05-22 19:02:191245 total_successes_ = 0;
[email protected]894bb502009-05-21 22:39:571246
1247 // We should get an unload notification.
1248 ASSERT_TRUE(unloaded_id_.length());
1249 EXPECT_EQ(extension_id, unloaded_id_);
1250
[email protected]9f1087e2009-06-15 17:29:321251 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:191252
[email protected]894bb502009-05-21 22:39:571253 // The extension should not be in the service anymore.
[email protected]61b411612009-11-10 23:17:411254 ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
[email protected]894bb502009-05-21 22:39:571255 loop_.RunAllPending();
1256
1257 // The directory should be gone.
[email protected]631cf822009-05-15 07:01:251258 EXPECT_FALSE(file_util::PathExists(extension_path));
[email protected]631cf822009-05-15 07:01:251259}
1260
[email protected]894bb502009-05-21 22:39:571261// Tests loading single extensions (like --load-extension)
[email protected]3cf4f0992009-02-03 23:00:301262TEST_F(ExtensionsServiceTest, LoadExtension) {
[email protected]a9b00ac2009-06-25 21:03:231263 InitializeEmptyExtensionsService();
[email protected]3cf4f0992009-02-03 23:00:301264 FilePath extensions_path;
1265 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1266 extensions_path = extensions_path.AppendASCII("extensions");
1267
[email protected]a9b00ac2009-06-25 21:03:231268 FilePath ext1 = extensions_path
1269 .AppendASCII("good")
1270 .AppendASCII("Extensions")
[email protected]5a2721f62009-06-13 07:08:201271 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1272 .AppendASCII("1.0.0.0");
[email protected]894bb502009-05-21 22:39:571273 service_->LoadExtension(ext1);
1274 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:181275 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:571276 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:321277 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
1278 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:301279
[email protected]e8c729a2010-03-09 19:55:191280 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:191281
[email protected]a9b00ac2009-06-25 21:03:231282 FilePath no_manifest = extensions_path
1283 .AppendASCII("bad")
[email protected]93fd78f42009-07-10 16:43:171284 // .AppendASCII("Extensions")
[email protected]a9b00ac2009-06-25 21:03:231285 .AppendASCII("cccccccccccccccccccccccccccccccc")
1286 .AppendASCII("1");
[email protected]894bb502009-05-21 22:39:571287 service_->LoadExtension(no_manifest);
1288 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:181289 EXPECT_EQ(1u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:571290 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:321291 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]25b34332009-06-05 21:53:191292
1293 // Test uninstall.
[email protected]894bb502009-05-21 22:39:571294 std::string id = loaded_[0]->id();
1295 EXPECT_FALSE(unloaded_id_.length());
[email protected]27b985d2009-06-25 17:53:151296 service_->UninstallExtension(id, false);
[email protected]894bb502009-05-21 22:39:571297 loop_.RunAllPending();
1298 EXPECT_EQ(id, unloaded_id_);
[email protected]9f1087e2009-06-15 17:29:321299 ASSERT_EQ(0u, loaded_.size());
1300 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:301301}
[email protected]0b344962009-03-31 04:21:451302
[email protected]894bb502009-05-21 22:39:571303// Tests that we generate IDs when they are not specified in the manifest for
1304// --load-extension.
[email protected]0b344962009-03-31 04:21:451305TEST_F(ExtensionsServiceTest, GenerateID) {
[email protected]a9b00ac2009-06-25 21:03:231306 InitializeEmptyExtensionsService();
[email protected]fbcc40302009-06-12 20:45:451307
[email protected]0b344962009-03-31 04:21:451308 FilePath extensions_path;
1309 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1310 extensions_path = extensions_path.AppendASCII("extensions");
1311
[email protected]0b344962009-03-31 04:21:451312 FilePath no_id_ext = extensions_path.AppendASCII("no_id");
[email protected]894bb502009-05-21 22:39:571313 service_->LoadExtension(no_id_ext);
1314 loop_.RunAllPending();
[email protected]0b344962009-03-31 04:21:451315 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:571316 ASSERT_EQ(1u, loaded_.size());
[email protected]84ac7f32009-10-06 06:17:541317 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
[email protected]9f1087e2009-06-15 17:29:321318 EXPECT_EQ(loaded_[0]->location(), Extension::LOAD);
[email protected]0b344962009-03-31 04:21:451319
[email protected]e8c729a2010-03-09 19:55:191320 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:191321
[email protected]84ac7f32009-10-06 06:17:541322 std::string previous_id = loaded_[0]->id();
1323
1324 // If we reload the same path, we should get the same extension ID.
[email protected]894bb502009-05-21 22:39:571325 service_->LoadExtension(no_id_ext);
1326 loop_.RunAllPending();
[email protected]84ac7f32009-10-06 06:17:541327 ASSERT_EQ(1u, loaded_.size());
1328 ASSERT_EQ(previous_id, loaded_[0]->id());
[email protected]0b344962009-03-31 04:21:451329}
[email protected]894bb502009-05-21 22:39:571330
[email protected]d55e7602009-12-16 04:20:421331void ExtensionsServiceTest::TestExternalProvider(
1332 MockExtensionProvider* provider, Extension::Location location) {
[email protected]a1257b12009-06-12 02:51:341333 // Verify that starting with no providers loads no extensions.
1334 service_->Init();
1335 loop_.RunAllPending();
1336 ASSERT_EQ(0u, loaded_.size());
1337
[email protected]a1257b12009-06-12 02:51:341338 // Register a test extension externally using the mock registry provider.
[email protected]894bb502009-05-21 22:39:571339 FilePath source_path;
1340 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path));
1341 source_path = source_path.AppendASCII("extensions").AppendASCII("good.crx");
1342
[email protected]a1257b12009-06-12 02:51:341343 // Add the extension.
[email protected]d55e7602009-12-16 04:20:421344 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
[email protected]894bb502009-05-21 22:39:571345
[email protected]9f1087e2009-06-15 17:29:321346 // Reloading extensions should find our externally registered extension
[email protected]894bb502009-05-21 22:39:571347 // and install it.
[email protected]93fd78f42009-07-10 16:43:171348 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:571349 loop_.RunAllPending();
1350
1351 ASSERT_EQ(0u, GetErrors().size());
1352 ASSERT_EQ(1u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:421353 ASSERT_EQ(location, loaded_[0]->location());
[email protected]894bb502009-05-21 22:39:571354 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:191355 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:181356 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
[email protected]d55e7602009-12-16 04:20:421357 ValidateIntegerPref(good_crx, L"location", location);
[email protected]894bb502009-05-21 22:39:571358
[email protected]9f1087e2009-06-15 17:29:321359 // Reload extensions without changing anything. The extension should be
[email protected]894bb502009-05-21 22:39:571360 // loaded again.
1361 loaded_.clear();
[email protected]9f1087e2009-06-15 17:29:321362 service_->ReloadExtensions();
[email protected]894bb502009-05-21 22:39:571363 loop_.RunAllPending();
1364 ASSERT_EQ(0u, GetErrors().size());
1365 ASSERT_EQ(1u, loaded_.size());
[email protected]25b34332009-06-05 21:53:191366 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:181367 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
[email protected]d55e7602009-12-16 04:20:421368 ValidateIntegerPref(good_crx, L"location", location);
[email protected]e2eb43112009-05-29 21:19:541369
[email protected]894bb502009-05-21 22:39:571370 // Now update the extension with a new version. We should get upgraded.
1371 source_path = source_path.DirName().AppendASCII("good2.crx");
[email protected]d55e7602009-12-16 04:20:421372 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]894bb502009-05-21 22:39:571373
1374 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:171375 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:571376 loop_.RunAllPending();
1377 ASSERT_EQ(0u, GetErrors().size());
1378 ASSERT_EQ(1u, loaded_.size());
1379 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:191380 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:181381 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
[email protected]d55e7602009-12-16 04:20:421382 ValidateIntegerPref(good_crx, L"location", location);
[email protected]894bb502009-05-21 22:39:571383
[email protected]27b985d2009-06-25 17:53:151384 // Uninstall the extension and reload. Nothing should happen because the
[email protected]894bb502009-05-21 22:39:571385 // preference should prevent us from reinstalling.
1386 std::string id = loaded_[0]->id();
[email protected]27b985d2009-06-25 17:53:151387 service_->UninstallExtension(id, false);
[email protected]894bb502009-05-21 22:39:571388 loop_.RunAllPending();
1389
1390 // The extension should also be gone from the install directory.
[email protected]a9b00ac2009-06-25 21:03:231391 FilePath install_path = extensions_install_dir_.AppendASCII(id);
[email protected]894bb502009-05-21 22:39:571392 ASSERT_FALSE(file_util::PathExists(install_path));
1393
1394 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:171395 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:571396 loop_.RunAllPending();
1397 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:191398 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:181399 ValidateIntegerPref(good_crx, L"state", Extension::KILLBIT);
[email protected]d55e7602009-12-16 04:20:421400 ValidateIntegerPref(good_crx, L"location", location);
[email protected]25b34332009-06-05 21:53:191401
1402 // Now clear the preference and reinstall.
[email protected]6b75ec32009-08-14 06:37:181403 SetPrefInteg(good_crx, L"state", Extension::ENABLED);
[email protected]a9b00ac2009-06-25 21:03:231404 prefs_->ScheduleSavePersistentPrefs();
[email protected]25b34332009-06-05 21:53:191405
1406 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:171407 service_->CheckForExternalUpdates();
[email protected]25b34332009-06-05 21:53:191408 loop_.RunAllPending();
1409 ASSERT_EQ(1u, loaded_.size());
[email protected]25b34332009-06-05 21:53:191410 ValidatePrefKeyCount(1);
[email protected]6b75ec32009-08-14 06:37:181411 ValidateIntegerPref(good_crx, L"state", Extension::ENABLED);
[email protected]d55e7602009-12-16 04:20:421412 ValidateIntegerPref(good_crx, L"location", location);
[email protected]25b34332009-06-05 21:53:191413
[email protected]d55e7602009-12-16 04:20:421414 // Now test an externally triggered uninstall (deleting the registry key or
1415 // the pref entry).
1416 provider->RemoveExtension(good_crx);
[email protected]25b34332009-06-05 21:53:191417
1418 loaded_.clear();
[email protected]27b985d2009-06-25 17:53:151419 service_->LoadAllExtensions();
[email protected]25b34332009-06-05 21:53:191420 loop_.RunAllPending();
1421 ASSERT_EQ(0u, loaded_.size());
[email protected]27b985d2009-06-25 17:53:151422 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:191423
[email protected]27b985d2009-06-25 17:53:151424 // The extension should also be gone from the install directory.
1425 ASSERT_FALSE(file_util::PathExists(install_path));
[email protected]abe7a8942009-06-23 05:14:291426
[email protected]d55e7602009-12-16 04:20:421427 // Now test the case where user uninstalls and then the extension is removed
1428 // from the external provider.
[email protected]abe7a8942009-06-23 05:14:291429
[email protected]d55e7602009-12-16 04:20:421430 provider->UpdateOrAddExtension(good_crx, "1.0", source_path);
[email protected]93fd78f42009-07-10 16:43:171431 service_->CheckForExternalUpdates();
[email protected]abe7a8942009-06-23 05:14:291432 loop_.RunAllPending();
1433
[email protected]c1e432a2009-07-22 21:21:481434 ASSERT_EQ(1u, loaded_.size());
[email protected]d11c8e92009-10-20 23:26:401435 ASSERT_EQ(1u, GetErrors().size());
[email protected]d55e7602009-12-16 04:20:421436
1437 // User uninstalls.
1438 loaded_.clear();
1439 service_->UninstallExtension(id, false);
1440 loop_.RunAllPending();
1441 ASSERT_EQ(0u, loaded_.size());
1442
1443 // Then remove the extension from the extension provider.
1444 provider->RemoveExtension(good_crx);
1445
1446 // Should still be at 0.
1447 loaded_.clear();
1448 service_->LoadAllExtensions();
1449 loop_.RunAllPending();
1450 ASSERT_EQ(0u, loaded_.size());
1451 ValidatePrefKeyCount(1);
1452}
1453
1454// Tests the external installation feature
1455#if defined(OS_WIN)
1456TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
1457 // This should all work, even when normal extension installation is disabled.
1458 InitializeEmptyExtensionsService();
1459 set_extensions_enabled(false);
1460
1461 // Now add providers. Extension system takes ownership of the objects.
1462 MockExtensionProvider* reg_provider =
1463 new MockExtensionProvider(Extension::EXTERNAL_REGISTRY);
1464 SetMockExternalProvider(Extension::EXTERNAL_REGISTRY, reg_provider);
1465 TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
1466}
1467#endif
1468
1469TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
1470 // This should all work, even when normal extension installation is disabled.
1471 InitializeEmptyExtensionsService();
1472 set_extensions_enabled(false);
1473
1474 // Now add providers. Extension system takes ownership of the objects.
1475 MockExtensionProvider* pref_provider =
1476 new MockExtensionProvider(Extension::EXTERNAL_PREF);
1477 SetMockExternalProvider(Extension::EXTERNAL_PREF, pref_provider);
1478 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
[email protected]27b985d2009-06-25 17:53:151479}
1480
1481TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {
[email protected]a9b00ac2009-06-25 21:03:231482 InitializeEmptyExtensionsService();
[email protected]27b985d2009-06-25 17:53:151483 std::string json_data =
1484 "{"
1485 "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
1486 "\"external_crx\": \"RandomExtension.crx\","
1487 "\"external_version\": \"1.0\""
1488 "},"
1489 "\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
1490 "\"external_crx\": \"RandomExtension2.crx\","
1491 "\"external_version\": \"2.0\""
1492 "}"
1493 "}";
1494
1495 MockProviderVisitor visitor;
1496 std::set<std::string> ignore_list;
1497 EXPECT_EQ(2, visitor.Visit(json_data, ignore_list));
1498 ignore_list.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
1499 EXPECT_EQ(1, visitor.Visit(json_data, ignore_list));
1500 ignore_list.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
1501 EXPECT_EQ(0, visitor.Visit(json_data, ignore_list));
1502
1503 // Use a json that contains three invalid extensions:
1504 // - One that is missing the 'external_crx' key.
1505 // - One that is missing the 'external_version' key.
1506 // - One that is specifying .. in the path.
1507 // - Plus one valid extension to make sure the json file is parsed properly.
1508 json_data =
1509 "{"
1510 "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
1511 "\"external_version\": \"1.0\""
1512 "},"
1513 "\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
1514 "\"external_crx\": \"RandomExtension.crx\""
1515 "},"
1516 "\"cccccccccccccccccccccccccccccccc\": {"
1517 "\"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
1518 "\"external_version\": \"2.0\""
1519 "},"
1520 "\"dddddddddddddddddddddddddddddddddd\": {"
1521 "\"external_crx\": \"RandomValidExtension.crx\","
1522 "\"external_version\": \"1.0\""
1523 "}"
1524 "}";
1525 ignore_list.clear();
1526 EXPECT_EQ(1, visitor.Visit(json_data, ignore_list));
[email protected]e18236b2009-06-22 21:32:101527}
[email protected]36a784c2009-06-23 06:21:081528
[email protected]c6d474f82009-12-16 21:11:061529// Test loading good extensions from the profile directory.
1530TEST_F(ExtensionsServiceTest, LoadAndRelocalizeExtensions) {
1531 // Initialize the test dir with a good Preferences/extensions.
1532 FilePath source_install_dir;
1533 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
1534 source_install_dir = source_install_dir
1535 .AppendASCII("extensions")
1536 .AppendASCII("l10n");
1537 FilePath pref_path = source_install_dir.AppendASCII("Preferences");
1538 InitializeInstalledExtensionsService(pref_path, source_install_dir);
1539
1540 service_->Init();
1541 loop_.RunAllPending();
1542
1543 ASSERT_EQ(3u, loaded_.size());
1544
1545 // This was equal to "sr" on load.
1546 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
1547
1548 // These are untouched by re-localization.
1549 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
1550 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
1551
1552 // This one starts with Serbian name, and gets re-localized into English.
1553 EXPECT_EQ("My name is simple.", loaded_[0]->name());
1554
1555 // These are untouched by re-localization.
1556 EXPECT_EQ("My name is simple.", loaded_[1]->name());
1557 EXPECT_EQ("no l10n", loaded_[2]->name());
1558}
1559
[email protected]f0488f2f2009-07-01 05:25:221560class ExtensionsReadyRecorder : public NotificationObserver {
1561 public:
1562 ExtensionsReadyRecorder() : ready_(false) {
1563 registrar_.Add(this, NotificationType::EXTENSIONS_READY,
1564 NotificationService::AllSources());
1565 }
1566
1567 void set_ready(bool value) { ready_ = value; }
1568 bool ready() { return ready_; }
1569
1570 private:
1571 virtual void Observe(NotificationType type,
1572 const NotificationSource& source,
1573 const NotificationDetails& details) {
1574 switch (type.value) {
1575 case NotificationType::EXTENSIONS_READY:
1576 ready_ = true;
1577 break;
1578 default:
1579 NOTREACHED();
1580 }
1581 }
1582
1583 NotificationRegistrar registrar_;
1584 bool ready_;
1585};
1586
[email protected]36a784c2009-06-23 06:21:081587// Test that we get enabled/disabled correctly for all the pref/command-line
[email protected]27b985d2009-06-25 17:53:151588// combinations. We don't want to derive from the ExtensionsServiceTest class
1589// for this test, so we use ExtensionsServiceTestSimple.
[email protected]f0488f2f2009-07-01 05:25:221590//
1591// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
1592// enabled or not.
[email protected]27b985d2009-06-25 17:53:151593TEST(ExtensionsServiceTestSimple, Enabledness) {
[email protected]f0488f2f2009-07-01 05:25:221594 ExtensionsReadyRecorder recorder;
[email protected]36a784c2009-06-23 06:21:081595 TestingProfile profile;
1596 MessageLoop loop;
[email protected]95d29192009-10-30 01:49:061597 ChromeThread ui_thread(ChromeThread::UI, &loop);
1598 ChromeThread file_thread(ChromeThread::FILE, &loop);
[email protected]36a784c2009-06-23 06:21:081599 scoped_ptr<CommandLine> command_line;
1600 scoped_refptr<ExtensionsService> service;
[email protected]a9b00ac2009-06-25 21:03:231601 FilePath install_dir = profile.GetPath()
1602 .AppendASCII(ExtensionsService::kInstallDirectoryName);
[email protected]36a784c2009-06-23 06:21:081603
[email protected]6d60703b2009-08-29 01:29:231604 // By default, we are enabled.
[email protected]51343d5a2009-10-26 22:39:331605 command_line.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY));
[email protected]a9b00ac2009-06-25 21:03:231606 service = new ExtensionsService(&profile, command_line.get(),
[email protected]95d29192009-10-30 01:49:061607 profile.GetPrefs(), install_dir, false);
[email protected]6d60703b2009-08-29 01:29:231608 EXPECT_TRUE(service->extensions_enabled());
1609 service->Init();
1610 loop.RunAllPending();
1611 EXPECT_TRUE(recorder.ready());
1612
1613 // If either the command line or pref is set, we are disabled.
1614 recorder.set_ready(false);
1615 command_line->AppendSwitch(switches::kDisableExtensions);
1616 service = new ExtensionsService(&profile, command_line.get(),
[email protected]95d29192009-10-30 01:49:061617 profile.GetPrefs(), install_dir, false);
[email protected]36a784c2009-06-23 06:21:081618 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:221619 service->Init();
1620 loop.RunAllPending();
1621 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:081622
[email protected]f0488f2f2009-07-01 05:25:221623 recorder.set_ready(false);
[email protected]6d60703b2009-08-29 01:29:231624 profile.GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]a9b00ac2009-06-25 21:03:231625 service = new ExtensionsService(&profile, command_line.get(),
[email protected]95d29192009-10-30 01:49:061626 profile.GetPrefs(), install_dir, false);
[email protected]6d60703b2009-08-29 01:29:231627 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:221628 service->Init();
1629 loop.RunAllPending();
1630 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:081631
[email protected]f0488f2f2009-07-01 05:25:221632 recorder.set_ready(false);
[email protected]51343d5a2009-10-26 22:39:331633 command_line.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY));
[email protected]a9b00ac2009-06-25 21:03:231634 service = new ExtensionsService(&profile, command_line.get(),
[email protected]95d29192009-10-30 01:49:061635 profile.GetPrefs(), install_dir, false);
[email protected]6d60703b2009-08-29 01:29:231636 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:221637 service->Init();
1638 loop.RunAllPending();
1639 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:081640}
[email protected]24b538a2010-02-27 01:22:441641
1642// Test loading extensions that require limited and unlimited storage quotas.
1643TEST_F(ExtensionsServiceTest, StorageQuota) {
1644 InitializeEmptyExtensionsService();
1645
1646 FilePath extensions_path;
1647 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1648 extensions_path = extensions_path.AppendASCII("extensions")
1649 .AppendASCII("storage_quota");
1650
1651 FilePath limited_quota_ext = extensions_path.AppendASCII("limited_quota")
1652 .AppendASCII("1.0");
1653 FilePath unlimited_quota_ext = extensions_path.AppendASCII("unlimited_quota")
1654 .AppendASCII("1.0");
1655 service_->LoadExtension(limited_quota_ext);
1656 service_->LoadExtension(unlimited_quota_ext);
1657 loop_.RunAllPending();
1658
1659 EXPECT_EQ(2u, loaded_.size());
1660 EXPECT_TRUE(profile_.get());
1661 EXPECT_FALSE(profile_->IsOffTheRecord());
1662
1663 // Open a database in each origin to make the tracker aware
1664 // of the existance of these origins and to get their quotas.
1665 int64 limited_quota = -1;
1666 int64 unlimited_quota = -1;
1667 string16 limited_quota_identifier =
1668 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[0]->url());
1669 string16 unlimited_quota_identifier =
1670 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[1]->url());
1671 string16 db_name = UTF8ToUTF16("db");
1672 string16 description = UTF8ToUTF16("db_description");
1673 int64 database_size;
1674 webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
1675 db_tracker->DatabaseOpened(limited_quota_identifier, db_name, description,
1676 1, &database_size, &limited_quota);
1677 db_tracker->DatabaseClosed(limited_quota_identifier, db_name);
1678 db_tracker->DatabaseOpened(unlimited_quota_identifier, db_name, description,
1679 1, &database_size, &unlimited_quota);
1680 db_tracker->DatabaseClosed(unlimited_quota_identifier, db_name);
1681
1682 EXPECT_EQ(profile_->GetDatabaseTracker()->GetDefaultQuota(), limited_quota);
1683 EXPECT_EQ(kint64max, unlimited_quota);
1684}
[email protected]1952c7d2010-03-04 23:48:341685
1686// Tests ExtensionsService::register_component_extension().
1687TEST_F(ExtensionsServiceTest, ComponentExtensions) {
1688 InitializeEmptyExtensionsService();
1689
1690 FilePath path;
1691 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
1692 path = path.AppendASCII("extensions")
1693 .AppendASCII("good")
1694 .AppendASCII("Extensions")
1695 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1696 .AppendASCII("1.0.0.0");
1697
1698 std::string manifest;
1699 ASSERT_TRUE(file_util::ReadFileToString(
1700 path.Append(Extension::kManifestFilename), &manifest));
1701
1702 service_->register_component_extension(
1703 ExtensionsService::ComponentExtensionInfo(manifest, path));
1704 service_->Init();
1705
1706 // Note that we do not pump messages -- the extension should be loaded
1707 // immediately.
1708
1709 EXPECT_EQ(0u, GetErrors().size());
1710 ASSERT_EQ(1u, loaded_.size());
1711 EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location());
1712 EXPECT_EQ(1u, service_->extensions()->size());
1713
1714 // Component extensions shouldn't get recourded in the prefs.
1715 ValidatePrefKeyCount(0);
1716
1717 // Reload all extensions, and make sure it comes back.
1718 std::string extension_id = service_->extensions()->at(0)->id();
1719 loaded_.clear();
1720 service_->ReloadExtensions();
1721 ASSERT_EQ(1u, service_->extensions()->size());
1722 EXPECT_EQ(extension_id, service_->extensions()->at(0)->id());
1723}