blob: 272e840425b47ac583291c104f58638b43ad0493 [file] [log] [blame]
[email protected]9931fbfc2010-07-23 09:15:511// Copyright (c) 2010 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]aa142702010-03-26 01:26:3316#include "base/scoped_ptr.h"
[email protected]dbbad7a2010-08-13 18:18:3617#include "base/stl_util-inl.h"
[email protected]24b538a2010-02-27 01:22:4418#include "base/string16.h"
[email protected]e83326f2010-07-31 17:29:2519#include "base/string_number_conversions.h"
[email protected]6014d672008-12-05 00:38:2520#include "base/string_util.h"
[email protected]24b538a2010-02-27 01:22:4421#include "base/task.h"
[email protected]be1ce6a72010-08-03 14:35:2222#include "base/utf_string_conversions.h"
[email protected]aa142702010-03-26 01:26:3323#include "base/version.h"
[email protected]dbbad7a2010-08-13 18:18:3624#include "chrome/browser/browser_prefs.h"
[email protected]ea587b02010-05-21 15:01:3525#include "chrome/browser/chrome_thread.h"
[email protected]c2c263c2010-08-13 21:59:4826#include "chrome/browser/appcache/chrome_appcache_service.h"
[email protected]da0aa3b2009-12-06 21:41:0327#include "chrome/browser/extensions/crx_installer.h"
[email protected]a17f9462009-06-09 02:56:4128#include "chrome/browser/extensions/extension_creator.h"
[email protected]14a000d2010-04-29 21:44:2429#include "chrome/browser/extensions/extension_error_reporter.h"
[email protected]6014d672008-12-05 00:38:2530#include "chrome/browser/extensions/extensions_service.h"
[email protected]a1257b12009-06-12 02:51:3431#include "chrome/browser/extensions/external_extension_provider.h"
[email protected]27b985d2009-06-25 17:53:1532#include "chrome/browser/extensions/external_pref_extension_provider.h"
[email protected]0349ab5d2010-08-11 21:41:5733#include "chrome/browser/extensions/pack_extension_job.cc"
[email protected]dbbad7a2010-08-13 18:18:3634#include "chrome/browser/in_process_webkit/webkit_context.h"
35#include "chrome/browser/in_process_webkit/dom_storage_context.h"
[email protected]d8b08c92010-06-07 13:13:2836#include "chrome/browser/pref_value_store.h"
[email protected]5b1a0e22009-05-26 19:00:5837#include "chrome/common/extensions/extension.h"
[email protected]cb691e82009-07-13 14:59:0138#include "chrome/common/extensions/extension_constants.h"
[email protected]942690b132010-05-11 06:42:1439#include "chrome/common/extensions/extension_resource.h"
[email protected]7197f4992009-03-23 05:05:4940#include "chrome/common/extensions/url_pattern.h"
[email protected]6014d672008-12-05 00:38:2541#include "chrome/common/chrome_paths.h"
[email protected]e2eb43112009-05-29 21:19:5442#include "chrome/common/chrome_switches.h"
[email protected]6014d672008-12-05 00:38:2543#include "chrome/common/json_value_serializer.h"
[email protected]dbbad7a2010-08-13 18:18:3644#include "chrome/common/net/url_request_context_getter.h"
[email protected]894bb502009-05-21 22:39:5745#include "chrome/common/notification_registrar.h"
46#include "chrome/common/notification_service.h"
47#include "chrome/common/notification_type.h"
[email protected]36a784c2009-06-23 06:21:0848#include "chrome/common/pref_names.h"
[email protected]24b538a2010-02-27 01:22:4449#include "chrome/common/url_constants.h"
[email protected]894bb502009-05-21 22:39:5750#include "chrome/test/testing_profile.h"
[email protected]24b538a2010-02-27 01:22:4451#include "googleurl/src/gurl.h"
[email protected]dbbad7a2010-08-13 18:18:3652#include "net/url_request/url_request_context.h"
[email protected]6014d672008-12-05 00:38:2553#include "testing/gtest/include/gtest/gtest.h"
[email protected]f66c110c2008-12-05 20:26:2954#include "testing/platform_test.h"
[email protected]24b538a2010-02-27 01:22:4455#include "webkit/database/database_tracker.h"
56#include "webkit/database/database_util.h"
[email protected]c10da4b02010-03-25 14:38:3257#include "net/base/cookie_monster.h"
58#include "net/base/cookie_options.h"
[email protected]6014d672008-12-05 00:38:2559
[email protected]c6d474f82009-12-16 21:11:0660namespace keys = extension_manifest_keys;
61
[email protected]f0397fa2008-12-11 17:59:5862namespace {
63
[email protected]df4956e2009-06-10 16:53:4264// Extension ids used during testing.
[email protected]5a2721f62009-06-13 07:08:2065const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
66const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
67const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj";
68const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk";
69const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
70const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
[email protected]d7eaf572009-07-01 21:57:0071const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln";
[email protected]5a2721f62009-06-13 07:08:2072const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad";
73const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
[email protected]df4956e2009-06-10 16:53:4274
[email protected]f0397fa2008-12-11 17:59:5875struct ExtensionsOrder {
76 bool operator()(const Extension* a, const Extension* b) {
77 return a->name() < b->name();
78 }
79};
80
[email protected]bb28e062009-02-27 17:19:1881static std::vector<std::string> GetErrors() {
82 const std::vector<std::string>* errors =
83 ExtensionErrorReporter::GetInstance()->GetErrors();
84 std::vector<std::string> ret_val;
85
86 for (std::vector<std::string>::const_iterator iter = errors->begin();
87 iter != errors->end(); ++iter) {
88 if (iter->find(".svn") == std::string::npos) {
89 ret_val.push_back(*iter);
90 }
91 }
92
93 // The tests rely on the errors being in a certain order, which can vary
94 // depending on how filesystem iteration works.
95 std::stable_sort(ret_val.begin(), ret_val.end());
96
97 return ret_val;
98}
99
[email protected]f0397fa2008-12-11 17:59:58100} // namespace
[email protected]6014d672008-12-05 00:38:25101
[email protected]a1257b12009-06-12 02:51:34102class MockExtensionProvider : public ExternalExtensionProvider {
103 public:
104 explicit MockExtensionProvider(Extension::Location location)
105 : location_(location) {}
106 virtual ~MockExtensionProvider() {}
107
108 void UpdateOrAddExtension(const std::string& id,
109 const std::string& version,
[email protected]f5ad7542009-07-24 17:38:59110 const FilePath& path) {
[email protected]a1257b12009-06-12 02:51:34111 extension_map_[id] = std::make_pair(version, path);
112 }
113
114 void RemoveExtension(const std::string& id) {
115 extension_map_.erase(id);
116 }
117
118 // ExternalExtensionProvider implementation:
119 virtual void VisitRegisteredExtension(
120 Visitor* visitor, const std::set<std::string>& ids_to_ignore) const {
121 for (DataMap::const_iterator i = extension_map_.begin();
122 i != extension_map_.end(); ++i) {
123 if (ids_to_ignore.find(i->first) != ids_to_ignore.end())
124 continue;
125 scoped_ptr<Version> version;
126 version.reset(Version::GetVersionFromString(i->second.first));
127
[email protected]8ef78fd2010-08-19 17:14:32128 visitor->OnExternalExtensionFileFound(
[email protected]7577a5c52009-07-30 06:21:58129 i->first, version.get(), i->second.second, location_);
[email protected]a1257b12009-06-12 02:51:34130 }
131 }
132
[email protected]f5ad7542009-07-24 17:38:59133 virtual Version* RegisteredVersion(const std::string& id,
[email protected]a1257b12009-06-12 02:51:34134 Extension::Location* location) const {
135 DataMap::const_iterator it = extension_map_.find(id);
136 if (it == extension_map_.end())
137 return NULL;
138
139 if (location)
140 *location = location_;
141 return Version::GetVersionFromString(it->second.first);
142 }
143
144 private:
145 typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap;
146 DataMap extension_map_;
147 Extension::Location location_;
[email protected]27b985d2009-06-25 17:53:15148
149 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
150};
151
152class MockProviderVisitor : public ExternalExtensionProvider::Visitor {
153 public:
[email protected]eb752082009-09-28 21:18:32154 MockProviderVisitor() : ids_found_(0) {
[email protected]27b985d2009-06-25 17:53:15155 }
156
[email protected]f5ad7542009-07-24 17:38:59157 int Visit(const std::string& json_data,
158 const std::set<std::string>& ignore_list) {
[email protected]27b985d2009-06-25 17:53:15159 // Give the test json file to the provider for parsing.
160 provider_.reset(new ExternalPrefExtensionProvider());
161 provider_->SetPreferencesForTesting(json_data);
162
163 // We also parse the file into a dictionary to compare what we get back
164 // from the provider.
165 JSONStringValueSerializer serializer(json_data);
[email protected]ba399672010-04-06 15:42:39166 Value* json_value = serializer.Deserialize(NULL, NULL);
[email protected]27b985d2009-06-25 17:53:15167
[email protected]ba399672010-04-06 15:42:39168 if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
[email protected]e2194742010-08-12 05:54:34169 NOTREACHED() << "Unable to deserialize json data";
[email protected]27b985d2009-06-25 17:53:15170 return -1;
171 } else {
172 DictionaryValue* external_extensions =
173 static_cast<DictionaryValue*>(json_value);
174 prefs_.reset(external_extensions);
175 }
176
177 // Reset our counter.
178 ids_found_ = 0;
179 // Ask the provider to look up all extensions (and return the ones
180 // found (that are not on the ignore list).
181 provider_->VisitRegisteredExtension(this, ignore_list);
182
183 return ids_found_;
184 }
185
[email protected]8ef78fd2010-08-19 17:14:32186 virtual void OnExternalExtensionFileFound(const std::string& id,
187 const Version* version,
188 const FilePath& path,
189 Extension::Location unused) {
[email protected]27b985d2009-06-25 17:53:15190 ++ids_found_;
191 DictionaryValue* pref;
192 // This tests is to make sure that the provider only notifies us of the
193 // values we gave it. So if the id we doesn't exist in our internal
194 // dictionary then something is wrong.
[email protected]e2194742010-08-12 05:54:34195 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
196 << "Got back ID (" << id.c_str() << ") we weren't expecting";
[email protected]27b985d2009-06-25 17:53:15197
198 if (pref) {
199 // Ask provider if the extension we got back is registered.
200 Extension::Location location = Extension::INVALID;
201 scoped_ptr<Version> v1(provider_->RegisteredVersion(id, NULL));
202 scoped_ptr<Version> v2(provider_->RegisteredVersion(id, &location));
203 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
204 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
205 EXPECT_EQ(Extension::EXTERNAL_PREF, location);
206
207 // Remove it so we won't count it ever again.
[email protected]e2194742010-08-12 05:54:34208 prefs_->Remove(id, NULL);
[email protected]27b985d2009-06-25 17:53:15209 }
210 }
211
[email protected]8ef78fd2010-08-19 17:14:32212 virtual void OnExternalExtensionUpdateUrlFound(const std::string& id,
213 const GURL& update_url) {
214 ++ids_found_;
215 DictionaryValue* pref;
216 // This tests is to make sure that the provider only notifies us of the
217 // values we gave it. So if the id we doesn't exist in our internal
218 // dictionary then something is wrong.
219 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
220 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
221
222 if (pref) {
223 // Remove it so we won't count it again.
224 prefs_->Remove(id, NULL);
225 }
226 }
227
[email protected]27b985d2009-06-25 17:53:15228 private:
229 int ids_found_;
230
231 scoped_ptr<ExternalPrefExtensionProvider> provider_;
232 scoped_ptr<DictionaryValue> prefs_;
233
234 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
[email protected]a1257b12009-06-12 02:51:34235};
236
[email protected]bf73f0b2010-02-10 19:26:59237class ExtensionTestingProfile : public TestingProfile {
[email protected]6014d672008-12-05 00:38:25238 public:
[email protected]9931fbfc2010-07-23 09:15:51239 ExtensionTestingProfile() : service_(NULL) {
[email protected]bf73f0b2010-02-10 19:26:59240 }
241
242 void set_extensions_service(ExtensionsService* service) {
243 service_ = service;
244 }
245 virtual ExtensionsService* GetExtensionsService() { return service_; }
246
[email protected]c2c263c2010-08-13 21:59:48247 virtual ChromeAppCacheService* GetAppCacheService() {
248 if (!appcache_service_) {
249 appcache_service_ = new ChromeAppCacheService;
250 ChromeThread::PostTask(
251 ChromeThread::IO, FROM_HERE,
252 NewRunnableMethod(appcache_service_.get(),
253 &ChromeAppCacheService::InitializeOnIOThread,
254 GetPath(), IsOffTheRecord(),
255 make_scoped_refptr(GetHostContentSettingsMap())));
256 }
257 return appcache_service_;
258 }
259
[email protected]bf73f0b2010-02-10 19:26:59260 private:
261 ExtensionsService* service_;
[email protected]c2c263c2010-08-13 21:59:48262 scoped_refptr<ChromeAppCacheService> appcache_service_;
[email protected]bf73f0b2010-02-10 19:26:59263};
264
265// Our message loop may be used in tests which require it to be an IO loop.
266ExtensionsServiceTestBase::ExtensionsServiceTestBase()
[email protected]9931fbfc2010-07-23 09:15:51267 : total_successes_(0),
268 loop_(MessageLoop::TYPE_IO),
[email protected]bf73f0b2010-02-10 19:26:59269 ui_thread_(ChromeThread::UI, &loop_),
[email protected]c2c263c2010-08-13 21:59:48270 db_thread_(ChromeThread::DB, &loop_),
[email protected]c10da4b02010-03-25 14:38:32271 webkit_thread_(ChromeThread::WEBKIT, &loop_),
272 file_thread_(ChromeThread::FILE, &loop_),
273 io_thread_(ChromeThread::IO, &loop_) {
[email protected]bf73f0b2010-02-10 19:26:59274}
275
276ExtensionsServiceTestBase::~ExtensionsServiceTestBase() {
[email protected]c10da4b02010-03-25 14:38:32277 // Drop our reference to ExtensionsService and TestingProfile, so that they
278 // can be destroyed while ChromeThreads and MessageLoop are still around (they
279 // are used in the destruction process).
[email protected]bf73f0b2010-02-10 19:26:59280 service_ = NULL;
[email protected]c10da4b02010-03-25 14:38:32281 profile_.reset(NULL);
[email protected]bf73f0b2010-02-10 19:26:59282 MessageLoop::current()->RunAllPending();
283}
284
285void ExtensionsServiceTestBase::InitializeExtensionsService(
286 const FilePath& pref_file, const FilePath& extensions_install_dir) {
[email protected]bf73f0b2010-02-10 19:26:59287 ExtensionTestingProfile* profile = new ExtensionTestingProfile();
[email protected]d8b08c92010-06-07 13:13:28288 // Create a preference service that only contains user defined
289 // preference values.
[email protected]db198b22010-07-12 16:48:49290 prefs_.reset(PrefService::CreateUserPrefService(pref_file));
[email protected]ea587b02010-05-21 15:01:35291
[email protected]fee8f0222010-03-17 01:13:37292 Profile::RegisterUserPrefs(prefs_.get());
293 browser::RegisterUserPrefs(prefs_.get());
[email protected]bf73f0b2010-02-10 19:26:59294 profile_.reset(profile);
295
[email protected]bf73f0b2010-02-10 19:26:59296 service_ = new ExtensionsService(profile_.get(),
297 CommandLine::ForCurrentProcess(),
298 prefs_.get(),
299 extensions_install_dir,
300 false);
301 service_->set_extensions_enabled(true);
302 service_->set_show_extensions_prompts(false);
303 profile->set_extensions_service(service_.get());
304
305 // When we start up, we want to make sure there is no external provider,
306 // since the ExtensionService on Windows will use the Registry as a default
307 // provider and if there is something already registered there then it will
308 // interfere with the tests. Those tests that need an external provider
309 // will register one specifically.
310 service_->ClearProvidersForTesting();
311
312 total_successes_ = 0;
313}
314
315void ExtensionsServiceTestBase::InitializeInstalledExtensionsService(
316 const FilePath& prefs_file, const FilePath& source_install_dir) {
317 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
318 FilePath path_ = temp_dir_.path();
319 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
320 file_util::Delete(path_, true);
321 file_util::CreateDirectory(path_);
322 FilePath temp_prefs = path_.Append(FILE_PATH_LITERAL("Preferences"));
323 file_util::CopyFile(prefs_file, temp_prefs);
324
325 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
326 file_util::Delete(extensions_install_dir_, true);
327 file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
328
329 InitializeExtensionsService(temp_prefs, extensions_install_dir_);
330}
331
332void ExtensionsServiceTestBase::InitializeEmptyExtensionsService() {
333 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
334 FilePath path_ = temp_dir_.path();
335 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
336 file_util::Delete(path_, true);
337 file_util::CreateDirectory(path_);
338 FilePath prefs_filename = path_
339 .Append(FILE_PATH_LITERAL("TestPreferences"));
340 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
341 file_util::Delete(extensions_install_dir_, true);
342 file_util::CreateDirectory(extensions_install_dir_);
343
344 InitializeExtensionsService(prefs_filename, extensions_install_dir_);
345}
346
347// static
348void ExtensionsServiceTestBase::SetUpTestCase() {
349 ExtensionErrorReporter::Init(false); // no noisy errors
350}
351
352void ExtensionsServiceTestBase::SetUp() {
353 ExtensionErrorReporter::GetInstance()->ClearErrors();
354}
355
356class ExtensionsServiceTest
357 : public ExtensionsServiceTestBase, public NotificationObserver {
358 public:
359 ExtensionsServiceTest() : installed_(NULL) {
[email protected]ae09ca62009-08-21 19:46:46360 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
[email protected]894bb502009-05-21 22:39:57361 NotificationService::AllSources());
362 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
363 NotificationService::AllSources());
364 registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
365 NotificationService::AllSources());
[email protected]e2eb43112009-05-29 21:19:54366 registrar_.Add(this, NotificationType::THEME_INSTALLED,
367 NotificationService::AllSources());
[email protected]a9b00ac2009-06-25 21:03:23368 }
[email protected]cc655912009-01-29 23:19:19369
[email protected]894bb502009-05-21 22:39:57370 virtual void Observe(NotificationType type,
371 const NotificationSource& source,
372 const NotificationDetails& details) {
373 switch (type.value) {
[email protected]ae09ca62009-08-21 19:46:46374 case NotificationType::EXTENSION_LOADED: {
375 Extension* extension = Details<Extension>(details).ptr();
376 loaded_.push_back(extension);
[email protected]894bb502009-05-21 22:39:57377 // The tests rely on the errors being in a certain order, which can vary
378 // depending on how filesystem iteration works.
379 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
380 break;
381 }
382
[email protected]9f1087e2009-06-15 17:29:32383 case NotificationType::EXTENSION_UNLOADED: {
384 Extension* e = Details<Extension>(details).ptr();
385 unloaded_id_ = e->id();
386 ExtensionList::iterator i =
387 std::find(loaded_.begin(), loaded_.end(), e);
388 // TODO(erikkay) fix so this can be an assert. Right now the tests
389 // are manually calling clear() on loaded_, so this isn't doable.
390 if (i == loaded_.end())
391 return;
392 loaded_.erase(i);
[email protected]894bb502009-05-21 22:39:57393 break;
[email protected]9f1087e2009-06-15 17:29:32394 }
[email protected]894bb502009-05-21 22:39:57395 case NotificationType::EXTENSION_INSTALLED:
[email protected]e2eb43112009-05-29 21:19:54396 case NotificationType::THEME_INSTALLED:
[email protected]894bb502009-05-21 22:39:57397 installed_ = Details<Extension>(details).ptr();
398 break;
399
[email protected]894bb502009-05-21 22:39:57400 default:
401 DCHECK(false);
[email protected]3acbd422008-12-08 18:25:00402 }
403 }
404
[email protected]a1257b12009-06-12 02:51:34405 void SetMockExternalProvider(Extension::Location location,
406 ExternalExtensionProvider* provider) {
407 service_->SetProviderForTesting(location, provider);
408 }
409
[email protected]9197f3b2009-06-02 00:49:27410 protected:
[email protected]d55e7602009-12-16 04:20:42411 void TestExternalProvider(MockExtensionProvider* provider,
412 Extension::Location location);
413
[email protected]3ba0fd32010-06-19 05:39:10414 void PackAndInstallExtension(const FilePath& dir_path,
415 bool should_succeed) {
416 FilePath crx_path;
417 ASSERT_TRUE(PathService::Get(base::DIR_TEMP, &crx_path));
418 crx_path = crx_path.AppendASCII("temp.crx");
419 FilePath pem_path = crx_path.DirName().AppendASCII("temp.pem");
420
421 ASSERT_TRUE(file_util::Delete(crx_path, false));
422 ASSERT_TRUE(file_util::Delete(pem_path, false));
423 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
424 ASSERT_TRUE(creator->Run(dir_path, crx_path, FilePath(), pem_path));
425 ASSERT_TRUE(file_util::PathExists(crx_path));
426
427 InstallExtension(crx_path, should_succeed);
428 }
429
[email protected]9197f3b2009-06-02 00:49:27430 void InstallExtension(const FilePath& path,
[email protected]d2d89d82009-06-08 21:01:53431 bool should_succeed) {
[email protected]cc655912009-01-29 23:19:19432 ASSERT_TRUE(file_util::PathExists(path));
[email protected]6ef635e42009-07-26 06:16:12433 service_->InstallExtension(path);
[email protected]894bb502009-05-21 22:39:57434 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:18435 std::vector<std::string> errors = GetErrors();
[email protected]cc655912009-01-29 23:19:19436 if (should_succeed) {
[email protected]902f7cd2009-05-22 19:02:19437 ++total_successes_;
438
[email protected]a57209872009-05-04 22:53:14439 EXPECT_TRUE(installed_) << path.value();
[email protected]9197f3b2009-06-02 00:49:27440
[email protected]a1257b12009-06-12 02:51:34441 ASSERT_EQ(1u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18442 EXPECT_EQ(0u, errors.size()) << path.value();
[email protected]902f7cd2009-05-22 19:02:19443 EXPECT_EQ(total_successes_, service_->extensions()->size()) <<
444 path.value();
[email protected]61b411612009-11-10 23:17:41445 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
[email protected]d2d89d82009-06-08 21:01:53446 path.value();
[email protected]bb28e062009-02-27 17:19:18447 for (std::vector<std::string>::iterator err = errors.begin();
448 err != errors.end(); ++err) {
[email protected]37eeb5a2009-02-26 23:36:17449 LOG(ERROR) << *err;
450 }
[email protected]cc655912009-01-29 23:19:19451 } else {
[email protected]a57209872009-05-04 22:53:14452 EXPECT_FALSE(installed_) << path.value();
[email protected]86a274072009-06-11 02:06:45453 EXPECT_EQ(0u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18454 EXPECT_EQ(1u, errors.size()) << path.value();
[email protected]cc655912009-01-29 23:19:19455 }
[email protected]bb28e062009-02-27 17:19:18456
[email protected]a57209872009-05-04 22:53:14457 installed_ = NULL;
[email protected]894bb502009-05-21 22:39:57458 loaded_.clear();
[email protected]bb28e062009-02-27 17:19:18459 ExtensionErrorReporter::GetInstance()->ClearErrors();
[email protected]cc655912009-01-29 23:19:19460 }
461
[email protected]4416c5a2010-06-26 01:28:57462 enum UpdateState {
463 FAILED_SILENTLY,
464 FAILED,
465 UPDATED,
466 INSTALLED,
467 ENABLED
468 };
469
[email protected]7577a5c52009-07-30 06:21:58470 void UpdateExtension(const std::string& id, const FilePath& in_path,
[email protected]4416c5a2010-06-26 01:28:57471 UpdateState expected_state) {
[email protected]7577a5c52009-07-30 06:21:58472 ASSERT_TRUE(file_util::PathExists(in_path));
[email protected]e957fe52009-06-23 16:51:05473
[email protected]7577a5c52009-07-30 06:21:58474 // We need to copy this to a temporary location because Update() will delete
475 // it.
[email protected]a1295ba22009-09-02 03:33:39476 FilePath path = temp_dir_.path();
477 path = path.Append(in_path.BaseName());
[email protected]7577a5c52009-07-30 06:21:58478 ASSERT_TRUE(file_util::CopyFile(in_path, path));
[email protected]e957fe52009-06-23 16:51:05479
[email protected]4416c5a2010-06-26 01:28:57480 int previous_enabled_extension_count =
481 service_->extensions()->size();
482 int previous_installed_extension_count =
483 previous_enabled_extension_count +
484 service_->disabled_extensions()->size();
485
[email protected]5c8516202010-03-18 21:43:34486 service_->UpdateExtension(id, path, GURL());
[email protected]e957fe52009-06-23 16:51:05487 loop_.RunAllPending();
[email protected]f3113e232010-06-25 01:36:40488
[email protected]4416c5a2010-06-26 01:28:57489 std::vector<std::string> errors = GetErrors();
490 int error_count = errors.size();
491 int enabled_extension_count =
492 service_->extensions()->size();
493 int installed_extension_count =
494 enabled_extension_count + service_->disabled_extensions()->size();
495
496 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
497 EXPECT_EQ(expected_error_count, error_count) << path.value();
498
499 if (expected_state <= FAILED) {
500 EXPECT_EQ(previous_enabled_extension_count,
501 enabled_extension_count);
502 EXPECT_EQ(previous_installed_extension_count,
503 installed_extension_count);
[email protected]e957fe52009-06-23 16:51:05504 } else {
[email protected]4416c5a2010-06-26 01:28:57505 int expected_installed_extension_count =
506 (expected_state >= INSTALLED) ? 1 : 0;
507 int expected_enabled_extension_count =
508 (expected_state >= ENABLED) ? 1 : 0;
509 EXPECT_EQ(expected_installed_extension_count,
510 installed_extension_count);
511 EXPECT_EQ(expected_enabled_extension_count,
512 enabled_extension_count);
[email protected]e957fe52009-06-23 16:51:05513 }
[email protected]7577a5c52009-07-30 06:21:58514
515 // Update() should delete the temporary input file.
516 EXPECT_FALSE(file_util::PathExists(path));
[email protected]e957fe52009-06-23 16:51:05517 }
518
[email protected]25b34332009-06-05 21:53:19519 void ValidatePrefKeyCount(size_t count) {
520 DictionaryValue* dict =
[email protected]e2194742010-08-12 05:54:34521 prefs_->GetMutableDictionary("extensions.settings");
[email protected]25b34332009-06-05 21:53:19522 ASSERT_TRUE(dict != NULL);
[email protected]4dad9ad82009-11-25 20:47:52523 EXPECT_EQ(count, dict->size());
[email protected]25b34332009-06-05 21:53:19524 }
525
[email protected]6b75ec32009-08-14 06:37:18526 void ValidateBooleanPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34527 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06528 bool expected_val) {
[email protected]e2194742010-08-12 05:54:34529 std::string msg = " while checking: ";
530 msg += extension_id;
531 msg += " ";
[email protected]6b75ec32009-08-14 06:37:18532 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34533 msg += " == ";
534 msg += expected_val ? "true" : "false";
[email protected]6b75ec32009-08-14 06:37:18535
[email protected]e2194742010-08-12 05:54:34536 const DictionaryValue* dict = prefs_->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18537 ASSERT_TRUE(dict != NULL) << msg;
538 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34539 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]6b75ec32009-08-14 06:37:18540 EXPECT_TRUE(pref != NULL) << msg;
541 bool val;
[email protected]4c91487e2009-10-02 04:11:04542 ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06543 EXPECT_EQ(expected_val, val) << msg;
[email protected]6b75ec32009-08-14 06:37:18544 }
545
546 bool IsPrefExist(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34547 const std::string& pref_path) {
548 const DictionaryValue* dict = prefs_->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18549 if (dict == NULL) return false;
550 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34551 if (!dict->GetDictionary(extension_id, &pref)) {
[email protected]6b75ec32009-08-14 06:37:18552 return false;
553 }
554 if (pref == NULL) {
555 return false;
556 }
557 bool val;
558 if (!pref->GetBoolean(pref_path, &val)) {
559 return false;
560 }
561 return true;
562 }
563
564 void ValidateIntegerPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34565 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06566 int expected_val) {
[email protected]e2194742010-08-12 05:54:34567 std::string msg = " while checking: ";
568 msg += extension_id;
569 msg += " ";
[email protected]25b34332009-06-05 21:53:19570 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34571 msg += " == ";
572 msg += base::IntToString(expected_val);
[email protected]25b34332009-06-05 21:53:19573
[email protected]e2194742010-08-12 05:54:34574 const DictionaryValue* dict = prefs_->GetDictionary("extensions.settings");
[email protected]25b34332009-06-05 21:53:19575 ASSERT_TRUE(dict != NULL) << msg;
576 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34577 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]25b34332009-06-05 21:53:19578 EXPECT_TRUE(pref != NULL) << msg;
579 int val;
[email protected]4c91487e2009-10-02 04:11:04580 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06581 EXPECT_EQ(expected_val, val) << msg;
582 }
583
584 void ValidateStringPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34585 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06586 const std::string& expected_val) {
[email protected]e2194742010-08-12 05:54:34587 std::string msg = " while checking: ";
588 msg += extension_id;
589 msg += ".manifest.";
[email protected]c6d474f82009-12-16 21:11:06590 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34591 msg += " == ";
592 msg += expected_val;
[email protected]c6d474f82009-12-16 21:11:06593
[email protected]e2194742010-08-12 05:54:34594 const DictionaryValue* dict = prefs_->GetDictionary("extensions.settings");
[email protected]c6d474f82009-12-16 21:11:06595 ASSERT_TRUE(dict != NULL) << msg;
596 DictionaryValue* pref = NULL;
597 std::string manifest_path = extension_id + ".manifest";
[email protected]e2194742010-08-12 05:54:34598 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
[email protected]c6d474f82009-12-16 21:11:06599 EXPECT_TRUE(pref != NULL) << msg;
600 std::string val;
601 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
602 EXPECT_EQ(expected_val, val) << msg;
[email protected]25b34332009-06-05 21:53:19603 }
604
[email protected]6b75ec32009-08-14 06:37:18605 void SetPrefInteg(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34606 const std::string& pref_path,
[email protected]6b75ec32009-08-14 06:37:18607 int value) {
[email protected]e2194742010-08-12 05:54:34608 std::string msg = " while setting: ";
609 msg += extension_id;
610 msg += " ";
[email protected]a1257b12009-06-12 02:51:34611 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34612 msg += " = ";
613 msg += base::IntToString(value);
[email protected]a1257b12009-06-12 02:51:34614
615 const DictionaryValue* dict =
[email protected]e2194742010-08-12 05:54:34616 prefs_->GetMutableDictionary("extensions.settings");
[email protected]a1257b12009-06-12 02:51:34617 ASSERT_TRUE(dict != NULL) << msg;
618 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34619 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]a1257b12009-06-12 02:51:34620 EXPECT_TRUE(pref != NULL) << msg;
621 pref->SetInteger(pref_path, value);
622 }
623
[email protected]25b34332009-06-05 21:53:19624 protected:
[email protected]9f1087e2009-06-15 17:29:32625 ExtensionList loaded_;
[email protected]894bb502009-05-21 22:39:57626 std::string unloaded_id_;
627 Extension* installed_;
[email protected]894bb502009-05-21 22:39:57628
[email protected]6014d672008-12-05 00:38:25629 private:
[email protected]894bb502009-05-21 22:39:57630 NotificationRegistrar registrar_;
[email protected]bb28e062009-02-27 17:19:18631};
[email protected]6014d672008-12-05 00:38:25632
[email protected]0349ab5d2010-08-11 21:41:57633FilePath NormalizeSeparators(const FilePath& path) {
[email protected]a9b00ac2009-06-25 21:03:23634#if defined(FILE_PATH_USES_WIN_SEPARATORS)
[email protected]0349ab5d2010-08-11 21:41:57635 return path.NormalizeWindowsPathSeparators();
636#else
[email protected]a9b00ac2009-06-25 21:03:23637 return path;
[email protected]0349ab5d2010-08-11 21:41:57638#endif // FILE_PATH_USES_WIN_SEPARATORS
[email protected]a9b00ac2009-06-25 21:03:23639}
[email protected]0349ab5d2010-08-11 21:41:57640
641// Receives notifications from a PackExtensionJob, indicating either that
642// packing succeeded or that there was some error.
643class PackExtensionTestClient : public PackExtensionJob::Client {
644 public:
645 PackExtensionTestClient(const FilePath& expected_crx_path,
646 const FilePath& expected_private_key_path);
647 virtual void OnPackSuccess(const FilePath& crx_path,
648 const FilePath& private_key_path);
649 virtual void OnPackFailure(const std::string& error_message);
650
651 private:
652 const FilePath expected_crx_path_;
653 const FilePath expected_private_key_path_;
654 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
655};
656
657PackExtensionTestClient::PackExtensionTestClient(
658 const FilePath& expected_crx_path,
659 const FilePath& expected_private_key_path)
660 : expected_crx_path_(expected_crx_path),
661 expected_private_key_path_(expected_private_key_path) {}
662
663// If packing succeeded, we make sure that the package names match our
664// expectations.
665void PackExtensionTestClient::OnPackSuccess(const FilePath& crx_path,
666 const FilePath& private_key_path) {
667 // We got the notification and processed it; we don't expect any further tasks
668 // to be posted to the current thread, so we should stop blocking and continue
669 // on with the rest of the test.
670 // This call to |Quit()| matches the call to |Run()| in the
671 // |PackPunctuatedExtension| test.
672 MessageLoop::current()->Quit();
673 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
674 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
675 ASSERT_TRUE(file_util::PathExists(private_key_path));
676}
677
678// The tests are designed so that we never expect to see a packing error.
679void PackExtensionTestClient::OnPackFailure(const std::string& error_message) {
680 FAIL() << "Packing should not fail.";
681}
682
[email protected]54cb3c92009-02-17 22:30:21683// Test loading good extensions from the profile directory.
[email protected]a9b00ac2009-06-25 21:03:23684TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
685 // Initialize the test dir with a good Preferences/extensions.
686 FilePath source_install_dir;
687 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
688 source_install_dir = source_install_dir
689 .AppendASCII("extensions")
690 .AppendASCII("good")
691 .AppendASCII("Extensions");
692 FilePath pref_path = source_install_dir
693 .DirName()
694 .AppendASCII("Preferences");
695 InitializeInstalledExtensionsService(pref_path, source_install_dir);
[email protected]6014d672008-12-05 00:38:25696
[email protected]9f1087e2009-06-15 17:29:32697 service_->Init();
[email protected]894bb502009-05-21 22:39:57698 loop_.RunAllPending();
[email protected]6014d672008-12-05 00:38:25699
[email protected]e50013c32010-08-18 21:05:24700 // On Chrome OS, we disallow extensions with plugins. "good1" has plugins,
701 // so we need to edit it out here.
702 uint32 expected_num_extensions = 3u;
703#if defined(OS_CHROMEOS)
704 --expected_num_extensions;
705#endif
706 ASSERT_EQ(expected_num_extensions, loaded_.size());
[email protected]6014d672008-12-05 00:38:25707
[email protected]fbcc40302009-06-12 20:45:45708 EXPECT_EQ(std::string(good0), loaded_[0]->id());
[email protected]e1cec06c2008-12-18 01:22:23709 EXPECT_EQ(std::string("My extension 1"),
[email protected]894bb502009-05-21 22:39:57710 loaded_[0]->name());
[email protected]e1cec06c2008-12-18 01:22:23711 EXPECT_EQ(std::string("The first extension that I made."),
[email protected]894bb502009-05-21 22:39:57712 loaded_[0]->description());
713 EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location());
[email protected]61b411612009-11-10 23:17:41714 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
[email protected]e50013c32010-08-18 21:05:24715 EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
[email protected]eab9b452009-01-23 20:48:59716
[email protected]25b34332009-06-05 21:53:19717 ValidatePrefKeyCount(3);
[email protected]e2194742010-08-12 05:54:34718 ValidateIntegerPref(good0, "state", Extension::ENABLED);
719 ValidateIntegerPref(good0, "location", Extension::INTERNAL);
720 ValidateIntegerPref(good1, "state", Extension::ENABLED);
721 ValidateIntegerPref(good1, "location", Extension::INTERNAL);
722 ValidateIntegerPref(good2, "state", Extension::ENABLED);
723 ValidateIntegerPref(good2, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:19724
[email protected]894bb502009-05-21 22:39:57725 Extension* extension = loaded_[0];
[email protected]34aa8dc2009-02-19 07:03:05726 const UserScriptList& scripts = extension->content_scripts();
[email protected]e66de892009-03-20 20:38:43727 ASSERT_EQ(2u, scripts.size());
[email protected]f0488f2f2009-07-01 05:25:22728 EXPECT_EQ(3u, scripts[0].url_patterns().size());
[email protected]62771442009-11-22 02:25:04729 EXPECT_EQ("file://*",
[email protected]5f8681f2009-11-18 03:21:13730 scripts[0].url_patterns()[0].GetAsString());
[email protected]62771442009-11-22 02:25:04731 EXPECT_EQ("http://*.google.com/*",
[email protected]5f8681f2009-11-18 03:21:13732 scripts[0].url_patterns()[1].GetAsString());
[email protected]62771442009-11-22 02:25:04733 EXPECT_EQ("https://*.google.com/*",
[email protected]f0488f2f2009-07-01 05:25:22734 scripts[0].url_patterns()[2].GetAsString());
[email protected]e66de892009-03-20 20:38:43735 EXPECT_EQ(2u, scripts[0].js_scripts().size());
[email protected]052c92702010-06-25 07:25:52736 ExtensionResource resource00(extension->id(),
737 scripts[0].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:21738 scripts[0].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:29739 FilePath expected_path(extension->path().AppendASCII("script1.js"));
740 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
741 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
[email protected]052c92702010-06-25 07:25:52742 ExtensionResource resource01(extension->id(),
743 scripts[0].js_scripts()[1].extension_root(),
[email protected]9194b3f2009-10-20 15:27:21744 scripts[0].js_scripts()[1].relative_path());
[email protected]a14b16b2009-10-28 12:41:29745 expected_path = extension->path().AppendASCII("script2.js");
746 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
747 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
[email protected]c533bb22009-06-03 19:06:11748 EXPECT_TRUE(extension->plugins().empty());
[email protected]e66de892009-03-20 20:38:43749 EXPECT_EQ(1u, scripts[1].url_patterns().size());
750 EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString());
[email protected]052c92702010-06-25 07:25:52751 ExtensionResource resource10(extension->id(),
752 scripts[1].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:21753 scripts[1].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:29754 expected_path =
755 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
756 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
757 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
[email protected]35506352009-08-07 18:58:19758 const std::vector<URLPattern> permissions = extension->host_permissions();
[email protected]7197f4992009-03-23 05:05:49759 ASSERT_EQ(2u, permissions.size());
760 EXPECT_EQ("http://*.google.com/*", permissions[0].GetAsString());
761 EXPECT_EQ("https://*.google.com/*", permissions[1].GetAsString());
[email protected]6014d672008-12-05 00:38:25762
[email protected]e50013c32010-08-18 21:05:24763#if !defined(OS_CHROMEOS)
[email protected]25b34332009-06-05 21:53:19764 EXPECT_EQ(std::string(good1), loaded_[1]->id());
[email protected]894bb502009-05-21 22:39:57765 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
766 EXPECT_EQ(std::string(""), loaded_[1]->description());
[email protected]81067e02009-07-27 15:12:09767 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
768 loaded_[1]->background_url());
[email protected]894bb502009-05-21 22:39:57769 EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
[email protected]c533bb22009-06-03 19:06:11770 EXPECT_EQ(2u, loaded_[1]->plugins().size());
771 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
772 loaded_[1]->plugins()[0].path.value());
773 EXPECT_TRUE(loaded_[1]->plugins()[0].is_public);
774 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
775 loaded_[1]->plugins()[1].path.value());
776 EXPECT_FALSE(loaded_[1]->plugins()[1].is_public);
[email protected]894bb502009-05-21 22:39:57777 EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location());
[email protected]e50013c32010-08-18 21:05:24778#endif
[email protected]18a12352009-01-31 01:33:28779
[email protected]e50013c32010-08-18 21:05:24780 int index = expected_num_extensions - 1;
781 EXPECT_EQ(std::string(good2), loaded_[index]->id());
782 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
783 EXPECT_EQ(std::string(""), loaded_[index]->description());
784 EXPECT_EQ(0u, loaded_[index]->content_scripts().size());
785 EXPECT_EQ(Extension::INTERNAL, loaded_[index]->location());
[email protected]6014d672008-12-05 00:38:25786};
[email protected]cc655912009-01-29 23:19:19787
[email protected]54cb3c92009-02-17 22:30:21788// Test loading bad extensions from the profile directory.
[email protected]a9b00ac2009-06-25 21:03:23789TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) {
[email protected]c6d474f82009-12-16 21:11:06790 // Initialize the test dir with a bad Preferences/extensions.
[email protected]a9b00ac2009-06-25 21:03:23791 FilePath source_install_dir;
792 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
793 source_install_dir = source_install_dir
794 .AppendASCII("extensions")
795 .AppendASCII("bad")
796 .AppendASCII("Extensions");
797 FilePath pref_path = source_install_dir
798 .DirName()
799 .AppendASCII("Preferences");
[email protected]54cb3c92009-02-17 22:30:21800
[email protected]a9b00ac2009-06-25 21:03:23801 InitializeInstalledExtensionsService(pref_path, source_install_dir);
[email protected]54cb3c92009-02-17 22:30:21802
[email protected]9f1087e2009-06-15 17:29:32803 service_->Init();
[email protected]894bb502009-05-21 22:39:57804 loop_.RunAllPending();
[email protected]54cb3c92009-02-17 22:30:21805
[email protected]a9b00ac2009-06-25 21:03:23806 ASSERT_EQ(4u, GetErrors().size());
807 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:19808
[email protected]c5a72482009-12-03 23:32:57809 EXPECT_TRUE(MatchPatternASCII(GetErrors()[0],
[email protected]d7b36dc2009-10-29 21:47:40810 std::string("Could not load extension from '*'. ") +
811 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[0];
[email protected]8d6d9ff2009-02-20 08:14:39812
[email protected]c5a72482009-12-03 23:32:57813 EXPECT_TRUE(MatchPatternASCII(GetErrors()[1],
[email protected]8d6d9ff2009-02-20 08:14:39814 std::string("Could not load extension from '*'. ") +
[email protected]f6f5b8b2009-10-09 21:28:19815 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[1];
[email protected]8d6d9ff2009-02-20 08:14:39816
[email protected]c5a72482009-12-03 23:32:57817 EXPECT_TRUE(MatchPatternASCII(GetErrors()[2],
[email protected]8d6d9ff2009-02-20 08:14:39818 std::string("Could not load extension from '*'. ") +
[email protected]cb691e82009-07-13 14:59:01819 extension_manifest_errors::kMissingFile)) << GetErrors()[2];
[email protected]a9b00ac2009-06-25 21:03:23820
[email protected]c5a72482009-12-03 23:32:57821 EXPECT_TRUE(MatchPatternASCII(GetErrors()[3],
[email protected]a9b00ac2009-06-25 21:03:23822 std::string("Could not load extension from '*'. ") +
[email protected]f6f5b8b2009-10-09 21:28:19823 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[3];
[email protected]54cb3c92009-02-17 22:30:21824};
825
[email protected]894bb502009-05-21 22:39:57826// Test that partially deleted extensions are cleaned up during startup
827// Test loading bad extensions from the profile directory.
828TEST_F(ExtensionsServiceTest, CleanupOnStartup) {
[email protected]b6ab96d2009-08-20 18:58:19829 FilePath source_install_dir;
830 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
831 source_install_dir = source_install_dir
832 .AppendASCII("extensions")
833 .AppendASCII("good")
834 .AppendASCII("Extensions");
835 FilePath pref_path = source_install_dir
836 .DirName()
837 .AppendASCII("Preferences");
[email protected]a9b00ac2009-06-25 21:03:23838
[email protected]b6ab96d2009-08-20 18:58:19839 InitializeInstalledExtensionsService(pref_path, source_install_dir);
[email protected]894bb502009-05-21 22:39:57840
[email protected]b6ab96d2009-08-20 18:58:19841 // Simulate that one of them got partially deleted by clearing its pref.
[email protected]e2194742010-08-12 05:54:34842 DictionaryValue* dict = prefs_->GetMutableDictionary("extensions.settings");
[email protected]932342a2009-10-08 21:27:17843 ASSERT_TRUE(dict != NULL);
[email protected]e2194742010-08-12 05:54:34844 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
[email protected]894bb502009-05-21 22:39:57845
846 service_->Init();
847 loop_.RunAllPending();
848
[email protected]a9b00ac2009-06-25 21:03:23849 file_util::FileEnumerator dirs(extensions_install_dir_, false,
[email protected]9f1087e2009-06-15 17:29:32850 file_util::FileEnumerator::DIRECTORIES);
851 size_t count = 0;
852 while (!dirs.Next().empty())
853 count++;
854
[email protected]894bb502009-05-21 22:39:57855 // We should have only gotten two extensions now.
[email protected]9f1087e2009-06-15 17:29:32856 EXPECT_EQ(2u, count);
[email protected]e2eb43112009-05-29 21:19:54857
[email protected]894bb502009-05-21 22:39:57858 // And extension1 dir should now be toast.
[email protected]b6ab96d2009-08-20 18:58:19859 FilePath extension_dir = extensions_install_dir_
860 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
861 ASSERT_FALSE(file_util::PathExists(extension_dir));
[email protected]894bb502009-05-21 22:39:57862}
863
[email protected]d7eaf572009-07-01 21:57:00864// Test installing extensions. This test tries to install few extensions using
865// crx files. If you need to change those crx files, feel free to repackage
866// them, throw away the key used and change the id's above.
[email protected]da0aa3b2009-12-06 21:41:03867TEST_F(ExtensionsServiceTest, InstallExtension) {
[email protected]a9b00ac2009-06-25 21:03:23868 InitializeEmptyExtensionsService();
869
[email protected]cc655912009-01-29 23:19:19870 FilePath extensions_path;
871 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
872 extensions_path = extensions_path.AppendASCII("extensions");
873
[email protected]e2eb43112009-05-29 21:19:54874 // Extensions not enabled.
[email protected]7577a5c52009-07-30 06:21:58875 set_extensions_enabled(false);
[email protected]894bb502009-05-21 22:39:57876 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]d2d89d82009-06-08 21:01:53877 InstallExtension(path, false);
[email protected]7577a5c52009-07-30 06:21:58878 set_extensions_enabled(true);
[email protected]e2eb43112009-05-29 21:19:54879
[email protected]25b34332009-06-05 21:53:19880 ValidatePrefKeyCount(0);
881
[email protected]e2eb43112009-05-29 21:19:54882 // A simple extension that should install without error.
883 path = extensions_path.AppendASCII("good.crx");
[email protected]d2d89d82009-06-08 21:01:53884 InstallExtension(path, true);
[email protected]cc655912009-01-29 23:19:19885 // TODO(erikkay): verify the contents of the installed extension.
886
[email protected]25b34332009-06-05 21:53:19887 int pref_count = 0;
888 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:34889 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
890 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:19891
[email protected]902f7cd2009-05-22 19:02:19892 // An extension with page actions.
893 path = extensions_path.AppendASCII("page_action.crx");
[email protected]d2d89d82009-06-08 21:01:53894 InstallExtension(path, true);
[email protected]25b34332009-06-05 21:53:19895 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:34896 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
897 ValidateIntegerPref(page_action, "location", Extension::INTERNAL);
[email protected]902f7cd2009-05-22 19:02:19898
[email protected]9f1087e2009-06-15 17:29:32899 // Bad signature.
[email protected]fbcc40302009-06-12 20:45:45900 path = extensions_path.AppendASCII("bad_signature.crx");
901 InstallExtension(path, false);
[email protected]d7eaf572009-07-01 21:57:00902 ValidatePrefKeyCount(pref_count);
[email protected]fbcc40302009-06-12 20:45:45903
[email protected]cc655912009-01-29 23:19:19904 // 0-length extension file.
905 path = extensions_path.AppendASCII("not_an_extension.crx");
[email protected]d2d89d82009-06-08 21:01:53906 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:19907 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:19908
909 // Bad magic number.
910 path = extensions_path.AppendASCII("bad_magic.crx");
[email protected]d2d89d82009-06-08 21:01:53911 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:19912 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:19913
[email protected]8ef78fd2010-08-19 17:14:32914 // Extensions cannot have folders or files that have underscores except in
[email protected]99872e32009-09-25 22:02:49915 // certain whitelisted cases (eg _locales). This is an example of a broader
916 // class of validation that we do to the directory structure of the extension.
917 // We did not used to handle this correctly for installation.
918 path = extensions_path.AppendASCII("bad_underscore.crx");
919 InstallExtension(path, false);
920 ValidatePrefKeyCount(pref_count);
921
[email protected]cc655912009-01-29 23:19:19922 // TODO(erikkay): add more tests for many of the failure cases.
923 // TODO(erikkay): add tests for upgrade cases.
924}
925
[email protected]da0aa3b2009-12-06 21:41:03926// Install a user script (they get converted automatically to an extension)
927TEST_F(ExtensionsServiceTest, InstallUserScript) {
928 // The details of script conversion are tested elsewhere, this just tests
929 // integration with ExtensionsService.
930 InitializeEmptyExtensionsService();
931
932 FilePath path;
933 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
934 path = path.AppendASCII("extensions")
935 .AppendASCII("user_script_basic.user.js");
936
937 ASSERT_TRUE(file_util::PathExists(path));
[email protected]6dfbbf82010-03-12 23:09:16938 scoped_refptr<CrxInstaller> installer(
939 new CrxInstaller(service_->install_directory(),
940 service_,
941 NULL)); // silent install
942 installer->InstallUserScript(
[email protected]da0aa3b2009-12-06 21:41:03943 path,
[email protected]6dfbbf82010-03-12 23:09:16944 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
[email protected]da0aa3b2009-12-06 21:41:03945
946 loop_.RunAllPending();
947 std::vector<std::string> errors = GetErrors();
948 EXPECT_TRUE(installed_) << "Nothing was installed.";
949 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
950 EXPECT_EQ(0u, errors.size()) << "There were errors: "
951 << JoinString(errors, ',');
952 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
953 path.value();
954
955 installed_ = NULL;
956 loaded_.clear();
957 ExtensionErrorReporter::GetInstance()->ClearErrors();
958}
959
[email protected]a17f9462009-06-09 02:56:41960// Test Packaging and installing an extension.
[email protected]a17f9462009-06-09 02:56:41961TEST_F(ExtensionsServiceTest, PackExtension) {
[email protected]a9b00ac2009-06-25 21:03:23962 InitializeEmptyExtensionsService();
[email protected]a17f9462009-06-09 02:56:41963 FilePath extensions_path;
964 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
965 extensions_path = extensions_path.AppendASCII("extensions");
[email protected]a9b00ac2009-06-25 21:03:23966 FilePath input_directory = extensions_path
967 .AppendASCII("good")
968 .AppendASCII("Extensions")
969 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
970 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:41971
[email protected]aca3e9b2009-11-03 01:14:21972 ScopedTempDir temp_dir;
973 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
974 FilePath output_directory = temp_dir.path();
975
[email protected]a17f9462009-06-09 02:56:41976 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
977 FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
978
979 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
980 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
981 privkey_path));
982
[email protected]a17f9462009-06-09 02:56:41983 ASSERT_TRUE(file_util::PathExists(privkey_path));
[email protected]5a2721f62009-06-13 07:08:20984 InstallExtension(crx_path, true);
[email protected]0dc2ca82009-11-17 07:06:16985
986 // Try packing with invalid paths.
987 creator.reset(new ExtensionCreator());
988 ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath()));
989
990 // Try packing an empty directory. Should fail because an empty directory is
991 // not a valid extension.
992 ScopedTempDir temp_dir2;
993 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
994 creator.reset(new ExtensionCreator());
995 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
996 FilePath()));
997
998 // Try packing with an invalid manifest.
999 std::string invalid_manifest_content = "I am not a manifest.";
1000 ASSERT_TRUE(file_util::WriteFile(
[email protected]99efb7b12009-12-18 02:39:161001 temp_dir2.path().Append(Extension::kManifestFilename),
[email protected]0dc2ca82009-11-17 07:06:161002 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
1003 creator.reset(new ExtensionCreator());
1004 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
1005 FilePath()));
[email protected]a17f9462009-06-09 02:56:411006}
1007
[email protected]0349ab5d2010-08-11 21:41:571008// Test Packaging and installing an extension whose name contains punctuation.
1009TEST_F(ExtensionsServiceTest, PackPunctuatedExtension) {
1010 InitializeEmptyExtensionsService();
1011 FilePath extensions_path;
1012 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1013 extensions_path = extensions_path.AppendASCII("extensions");
1014 FilePath input_directory = extensions_path
1015 .AppendASCII("good")
1016 .AppendASCII("Extensions")
1017 .AppendASCII(good0)
1018 .AppendASCII("1.0.0.0");
1019
1020 ScopedTempDir temp_dir;
1021 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1022
1023 // Extension names containing punctuation, and the expected names for the
1024 // packed extensions.
1025 const FilePath punctuated_names[] = {
1026 FilePath(FilePath::StringType(
1027 FILE_PATH_LITERAL("this.extensions.name.has.periods"))),
1028 FilePath(FilePath::StringType(
1029 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod"))),
1030 NormalizeSeparators(FilePath(FilePath::StringType(
1031 FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")))),
1032 };
1033 const FilePath expected_crx_names[] = {
1034 FilePath(FilePath::StringType(
1035 FILE_PATH_LITERAL("this.extensions.name.has.periods.crx"))),
1036 FilePath(FilePath::StringType(
1037 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx"))),
1038 FilePath(FilePath::StringType(
1039 FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx"))),
1040 };
1041 const FilePath expected_private_key_names[] = {
1042 FilePath(FilePath::StringType(
1043 FILE_PATH_LITERAL("this.extensions.name.has.periods.pem"))),
1044 FilePath(FilePath::StringType(
1045 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem"))),
1046 FilePath(FilePath::StringType(
1047 FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem"))),
1048 };
1049
1050 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
1051 SCOPED_TRACE(punctuated_names[i].value().c_str());
1052 FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
1053
1054 // Copy the extension into the output directory, as PackExtensionJob doesn't
1055 // let us choose where to output the packed extension.
1056 ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true));
1057
1058 FilePath expected_crx_path = temp_dir.path().Append(expected_crx_names[i]);
1059 FilePath expected_private_key_path =
1060 temp_dir.path().Append(expected_private_key_names[i]);
1061 PackExtensionTestClient pack_client(expected_crx_path,
1062 expected_private_key_path);
1063 scoped_refptr<PackExtensionJob> packer(new PackExtensionJob(&pack_client,
1064 output_dir,
1065 FilePath()));
1066 packer->Start();
1067
1068 // The packer will post a notification task to the current thread's message
1069 // loop when it is finished. We manually run the loop here so that we
1070 // block and catch the notification; otherwise, the process would exit.
1071 // This call to |Run()| is matched by a call to |Quit()| in the
1072 // |PackExtensionTestClient|'s notification handling code.
1073 MessageLoop::current()->Run();
1074
1075 if (HasFatalFailure())
1076 return;
1077
1078 InstallExtension(expected_crx_path, true);
1079 }
1080}
1081
[email protected]a17f9462009-06-09 02:56:411082// Test Packaging and installing an extension using an openssl generated key.
1083// The openssl is generated with the following:
[email protected]a1257b12009-06-12 02:51:341084// > openssl genrsa -out privkey.pem 1024
[email protected]df4956e2009-06-10 16:53:421085// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
[email protected]a1257b12009-06-12 02:51:341086// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
[email protected]a17f9462009-06-09 02:56:411087// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
1088TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) {
[email protected]a9b00ac2009-06-25 21:03:231089 InitializeEmptyExtensionsService();
[email protected]a17f9462009-06-09 02:56:411090 FilePath extensions_path;
1091 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1092 extensions_path = extensions_path.AppendASCII("extensions");
[email protected]a9b00ac2009-06-25 21:03:231093 FilePath input_directory = extensions_path
1094 .AppendASCII("good")
1095 .AppendASCII("Extensions")
1096 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1097 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:411098 FilePath privkey_path(extensions_path.AppendASCII(
1099 "openssl_privkey_asn1.pem"));
1100 ASSERT_TRUE(file_util::PathExists(privkey_path));
1101
[email protected]aca3e9b2009-11-03 01:14:211102 ScopedTempDir temp_dir;
1103 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1104 FilePath output_directory = temp_dir.path();
1105
[email protected]a17f9462009-06-09 02:56:411106 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1107
1108 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1109 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
1110 FilePath()));
1111
[email protected]5a2721f62009-06-13 07:08:201112 InstallExtension(crx_path, true);
[email protected]a17f9462009-06-09 02:56:411113}
[email protected]a17f9462009-06-09 02:56:411114
[email protected]e2eb43112009-05-29 21:19:541115TEST_F(ExtensionsServiceTest, InstallTheme) {
[email protected]a9b00ac2009-06-25 21:03:231116 InitializeEmptyExtensionsService();
[email protected]e2eb43112009-05-29 21:19:541117 FilePath extensions_path;
1118 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1119 extensions_path = extensions_path.AppendASCII("extensions");
1120
1121 // A theme.
1122 FilePath path = extensions_path.AppendASCII("theme.crx");
[email protected]d2d89d82009-06-08 21:01:531123 InstallExtension(path, true);
[email protected]25b34332009-06-05 21:53:191124 int pref_count = 0;
1125 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341126 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
1127 ValidateIntegerPref(theme_crx, "location", Extension::INTERNAL);
[email protected]e2eb43112009-05-29 21:19:541128
[email protected]6ef635e42009-07-26 06:16:121129 // A theme when extensions are disabled. Themes can be installed, even when
1130 // extensions are disabled.
[email protected]7577a5c52009-07-30 06:21:581131 set_extensions_enabled(false);
[email protected]e2eb43112009-05-29 21:19:541132 path = extensions_path.AppendASCII("theme2.crx");
[email protected]6ef635e42009-07-26 06:16:121133 InstallExtension(path, true);
[email protected]25b34332009-06-05 21:53:191134 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341135 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
1136 ValidateIntegerPref(theme2_crx, "location", Extension::INTERNAL);
[email protected]494c06e2009-07-25 01:06:421137
[email protected]25b34332009-06-05 21:53:191138 // A theme with extension elements. Themes cannot have extension elements so
1139 // this test should fail.
[email protected]7577a5c52009-07-30 06:21:581140 set_extensions_enabled(true);
[email protected]e2eb43112009-05-29 21:19:541141 path = extensions_path.AppendASCII("theme_with_extension.crx");
[email protected]d2d89d82009-06-08 21:01:531142 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:191143 ValidatePrefKeyCount(pref_count);
[email protected]12198912009-06-05 03:41:221144
1145 // A theme with image resources missing (misspelt path).
1146 path = extensions_path.AppendASCII("theme_missing_image.crx");
[email protected]d2d89d82009-06-08 21:01:531147 InstallExtension(path, false);
[email protected]25b34332009-06-05 21:53:191148 ValidatePrefKeyCount(pref_count);
[email protected]e2eb43112009-05-29 21:19:541149}
1150
[email protected]584245e52010-06-17 01:08:131151TEST_F(ExtensionsServiceTest, LoadLocalizedTheme) {
1152 // Load.
1153 InitializeEmptyExtensionsService();
1154 FilePath extension_path;
1155 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extension_path));
1156 extension_path = extension_path
1157 .AppendASCII("extensions")
1158 .AppendASCII("theme_i18n");
1159
1160 service_->LoadExtension(extension_path);
1161 loop_.RunAllPending();
1162 EXPECT_EQ(0u, GetErrors().size());
1163 ASSERT_EQ(1u, loaded_.size());
1164 EXPECT_EQ(1u, service_->extensions()->size());
1165 EXPECT_EQ("name", service_->extensions()->at(0)->name());
1166 EXPECT_EQ("description", service_->extensions()->at(0)->description());
1167}
1168
1169TEST_F(ExtensionsServiceTest, InstallLocalizedTheme) {
[email protected]584245e52010-06-17 01:08:131170 InitializeEmptyExtensionsService();
[email protected]3ba0fd32010-06-19 05:39:101171 FilePath theme_path;
1172 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &theme_path));
1173 theme_path = theme_path
[email protected]584245e52010-06-17 01:08:131174 .AppendASCII("extensions")
1175 .AppendASCII("theme_i18n");
1176
[email protected]3ba0fd32010-06-19 05:39:101177 PackAndInstallExtension(theme_path, true);
[email protected]584245e52010-06-17 01:08:131178
[email protected]584245e52010-06-17 01:08:131179 EXPECT_EQ(0u, GetErrors().size());
1180 EXPECT_EQ(1u, service_->extensions()->size());
1181 EXPECT_EQ("name", service_->extensions()->at(0)->name());
1182 EXPECT_EQ("description", service_->extensions()->at(0)->description());
1183}
1184
[email protected]669ee492010-06-15 17:36:571185TEST_F(ExtensionsServiceTest, InstallApps) {
[email protected]6d2e60bd2010-06-03 22:37:391186 InitializeEmptyExtensionsService();
1187 FilePath extensions_path;
1188 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1189 extensions_path = extensions_path.AppendASCII("extensions");
1190
1191 // An empty app.
[email protected]3ba0fd32010-06-19 05:39:101192 PackAndInstallExtension(extensions_path.AppendASCII("app1"), true);
[email protected]6d2e60bd2010-06-03 22:37:391193 int pref_count = 0;
1194 ValidatePrefKeyCount(++pref_count);
[email protected]3ba0fd32010-06-19 05:39:101195 ASSERT_EQ(1u, service_->extensions()->size());
1196 std::string id = service_->extensions()->at(0)->id();
[email protected]e2194742010-08-12 05:54:341197 ValidateIntegerPref(id, "state", Extension::ENABLED);
1198 ValidateIntegerPref(id, "location", Extension::INTERNAL);
[email protected]6d2e60bd2010-06-03 22:37:391199
1200 // Another app with non-overlapping extent. Should succeed.
[email protected]3ba0fd32010-06-19 05:39:101201 PackAndInstallExtension(extensions_path.AppendASCII("app2"), true);
[email protected]6d2e60bd2010-06-03 22:37:391202 ValidatePrefKeyCount(++pref_count);
1203
1204 // A third app whose extent overlaps the first. Should fail.
[email protected]9f72aa02010-06-25 10:01:051205 // TODO(aa): bring this back when overlap is fixed. http://crbug.com/47445.
1206 // PackAndInstallExtension(extensions_path.AppendASCII("app3"), false);
1207 // ValidatePrefKeyCount(pref_count);
[email protected]6d2e60bd2010-06-03 22:37:391208}
1209
[email protected]c2c263c2010-08-13 21:59:481210TEST_F(ExtensionsServiceTest, InstallAppsWithUnlimtedStorage) {
1211 InitializeEmptyExtensionsService();
1212 EXPECT_TRUE(service_->extensions()->empty());
1213 EXPECT_TRUE(service_->unlimited_storage_map_.empty());
1214
1215 FilePath extensions_path;
1216 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1217 extensions_path = extensions_path.AppendASCII("extensions");
1218 int pref_count = 0;
1219 ChromeAppCacheService* appcache_service = profile_->GetAppCacheService();
1220
1221 // Install app1 with unlimited storage.
1222 PackAndInstallExtension(extensions_path.AppendASCII("app1"), true);
1223 ValidatePrefKeyCount(++pref_count);
1224 ASSERT_EQ(1u, service_->extensions()->size());
1225 Extension* extension = service_->extensions()->at(0);
1226 const std::string id1 = extension->id();
1227 EXPECT_TRUE(extension->HasApiPermission(
1228 Extension::kUnlimitedStoragePermission));
1229 EXPECT_TRUE(extension->web_extent().ContainsURL(
1230 extension->GetFullLaunchURL()));
1231 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
1232 EXPECT_EQ(kint64max,
1233 appcache_service->storage()->GetOriginQuotaInMemory(origin1));
1234 EXPECT_FALSE(service_->unlimited_storage_map_.empty());
1235
1236 // Install app2 from the same origin with unlimited storage.
1237 PackAndInstallExtension(extensions_path.AppendASCII("app2"), true);
1238 ValidatePrefKeyCount(++pref_count);
1239 ASSERT_EQ(2u, service_->extensions()->size());
1240 extension = service_->extensions()->at(1);
1241 const std::string id2 = extension->id();
1242 EXPECT_TRUE(extension->HasApiPermission(
1243 Extension::kUnlimitedStoragePermission));
1244 EXPECT_TRUE(extension->web_extent().ContainsURL(
1245 extension->GetFullLaunchURL()));
1246 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
1247 EXPECT_EQ(origin1, origin2);
1248 EXPECT_EQ(kint64max,
1249 appcache_service->storage()->GetOriginQuotaInMemory(origin2));
1250 EXPECT_FALSE(service_->unlimited_storage_map_.empty());
1251
1252 // Uninstall one of them, unlimited storage should still be granted
1253 // to the origin.
1254 service_->UninstallExtension(id1, false);
1255 loop_.RunAllPending();
1256 EXPECT_EQ(1u, service_->extensions()->size());
1257 EXPECT_EQ(kint64max,
1258 appcache_service->storage()->GetOriginQuotaInMemory(origin1));
1259 EXPECT_FALSE(service_->unlimited_storage_map_.empty());
1260
1261 // Uninstall the other, unlimited storage should be revoked.
1262 service_->UninstallExtension(id2, false);
1263 loop_.RunAllPending();
1264 EXPECT_EQ(0u, service_->extensions()->size());
1265 EXPECT_EQ(-1L,
1266 appcache_service->storage()->GetOriginQuotaInMemory(origin2));
1267 EXPECT_TRUE(service_->unlimited_storage_map_.empty());
1268}
1269
[email protected]894bb502009-05-21 22:39:571270// Test that when an extension version is reinstalled, nothing happens.
1271TEST_F(ExtensionsServiceTest, Reinstall) {
[email protected]a9b00ac2009-06-25 21:03:231272 InitializeEmptyExtensionsService();
[email protected]894bb502009-05-21 22:39:571273 FilePath extensions_path;
1274 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1275 extensions_path = extensions_path.AppendASCII("extensions");
1276
1277 // A simple extension that should install without error.
1278 FilePath path = extensions_path.AppendASCII("good.crx");
1279 service_->InstallExtension(path);
1280 loop_.RunAllPending();
1281
1282 ASSERT_TRUE(installed_);
1283 ASSERT_EQ(1u, loaded_.size());
1284 ASSERT_EQ(0u, GetErrors().size());
[email protected]25b34332009-06-05 21:53:191285 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:341286 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1287 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:571288
1289 installed_ = NULL;
1290 loaded_.clear();
1291 ExtensionErrorReporter::GetInstance()->ClearErrors();
1292
[email protected]ca3dbf52010-05-19 22:27:061293 // Reinstall the same version, it should overwrite the previous one.
[email protected]894bb502009-05-21 22:39:571294 service_->InstallExtension(path);
1295 loop_.RunAllPending();
1296
[email protected]ca3dbf52010-05-19 22:27:061297 ASSERT_TRUE(installed_);
1298 ASSERT_EQ(1u, loaded_.size());
[email protected]894bb502009-05-21 22:39:571299 ASSERT_EQ(0u, GetErrors().size());
[email protected]25b34332009-06-05 21:53:191300 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:341301 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1302 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:571303}
1304
[email protected]fbcc40302009-06-12 20:45:451305// Test upgrading a signed extension.
1306TEST_F(ExtensionsServiceTest, UpgradeSignedGood) {
[email protected]a9b00ac2009-06-25 21:03:231307 InitializeEmptyExtensionsService();
[email protected]fbcc40302009-06-12 20:45:451308 FilePath extensions_path;
1309 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1310 extensions_path = extensions_path.AppendASCII("extensions");
1311
1312 FilePath path = extensions_path.AppendASCII("good.crx");
1313 service_->InstallExtension(path);
1314 loop_.RunAllPending();
1315
1316 ASSERT_TRUE(installed_);
1317 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:321318 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:451319 ASSERT_EQ(0u, GetErrors().size());
1320
1321 // Upgrade to version 2.0
1322 path = extensions_path.AppendASCII("good2.crx");
1323 service_->InstallExtension(path);
1324 loop_.RunAllPending();
1325
1326 ASSERT_TRUE(installed_);
[email protected]9f1087e2009-06-15 17:29:321327 ASSERT_EQ(1u, loaded_.size());
1328 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:451329 ASSERT_EQ(0u, GetErrors().size());
1330}
1331
1332// Test upgrading a signed extension with a bad signature.
1333TEST_F(ExtensionsServiceTest, UpgradeSignedBad) {
[email protected]a9b00ac2009-06-25 21:03:231334 InitializeEmptyExtensionsService();
[email protected]fbcc40302009-06-12 20:45:451335 FilePath extensions_path;
1336 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1337 extensions_path = extensions_path.AppendASCII("extensions");
1338
1339 FilePath path = extensions_path.AppendASCII("good.crx");
1340 service_->InstallExtension(path);
1341 loop_.RunAllPending();
1342
1343 ASSERT_TRUE(installed_);
1344 ASSERT_EQ(1u, loaded_.size());
1345 ASSERT_EQ(0u, GetErrors().size());
1346 installed_ = NULL;
1347
1348 // Try upgrading with a bad signature. This should fail during the unpack,
1349 // because the key will not match the signature.
1350 path = extensions_path.AppendASCII("good2_bad_signature.crx");
1351 service_->InstallExtension(path);
1352 loop_.RunAllPending();
1353
1354 ASSERT_FALSE(installed_);
1355 ASSERT_EQ(1u, loaded_.size());
1356 ASSERT_EQ(1u, GetErrors().size());
1357}
1358
[email protected]e957fe52009-06-23 16:51:051359// Test a normal update via the UpdateExtension API
1360TEST_F(ExtensionsServiceTest, UpdateExtension) {
[email protected]a9b00ac2009-06-25 21:03:231361 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051362 FilePath extensions_path;
1363 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1364 extensions_path = extensions_path.AppendASCII("extensions");
1365
1366 FilePath path = extensions_path.AppendASCII("good.crx");
1367
1368 InstallExtension(path, true);
1369 Extension* good = service_->extensions()->at(0);
1370 ASSERT_EQ("1.0.0.0", good->VersionString());
1371 ASSERT_EQ(good_crx, good->id());
1372
1373 path = extensions_path.AppendASCII("good2.crx");
[email protected]4416c5a2010-06-26 01:28:571374 UpdateExtension(good_crx, path, ENABLED);
[email protected]e957fe52009-06-23 16:51:051375 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
1376}
1377
1378// Test updating a not-already-installed extension - this should fail
1379TEST_F(ExtensionsServiceTest, UpdateNotInstalledExtension) {
[email protected]a9b00ac2009-06-25 21:03:231380 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051381 FilePath extensions_path;
1382 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1383 extensions_path = extensions_path.AppendASCII("extensions");
1384
1385 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:571386 UpdateExtension(good_crx, path, UPDATED);
[email protected]e957fe52009-06-23 16:51:051387 loop_.RunAllPending();
1388
1389 ASSERT_EQ(0u, service_->extensions()->size());
1390 ASSERT_FALSE(installed_);
1391 ASSERT_EQ(0u, loaded_.size());
1392}
1393
1394// Makes sure you can't downgrade an extension via UpdateExtension
1395TEST_F(ExtensionsServiceTest, UpdateWillNotDowngrade) {
[email protected]a9b00ac2009-06-25 21:03:231396 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051397 FilePath extensions_path;
1398 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1399 extensions_path = extensions_path.AppendASCII("extensions");
1400
1401 FilePath path = extensions_path.AppendASCII("good2.crx");
1402
1403 InstallExtension(path, true);
1404 Extension* good = service_->extensions()->at(0);
1405 ASSERT_EQ("1.0.0.1", good->VersionString());
1406 ASSERT_EQ(good_crx, good->id());
1407
1408 // Change path from good2.crx -> good.crx
1409 path = extensions_path.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:571410 UpdateExtension(good_crx, path, FAILED);
[email protected]e957fe52009-06-23 16:51:051411 ASSERT_EQ("1.0.0.1", service_->extensions()->at(0)->VersionString());
1412}
1413
1414// Make sure calling update with an identical version does nothing
1415TEST_F(ExtensionsServiceTest, UpdateToSameVersionIsNoop) {
[email protected]a9b00ac2009-06-25 21:03:231416 InitializeEmptyExtensionsService();
[email protected]e957fe52009-06-23 16:51:051417 FilePath extensions_path;
1418 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1419 extensions_path = extensions_path.AppendASCII("extensions");
1420
1421 FilePath path = extensions_path.AppendASCII("good.crx");
1422
1423 InstallExtension(path, true);
1424 Extension* good = service_->extensions()->at(0);
1425 ASSERT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:571426 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]aa142702010-03-26 01:26:331427}
1428
[email protected]dbec3792010-08-10 00:08:451429// Tests that updating an extension does not clobber old state.
1430TEST_F(ExtensionsServiceTest, UpdateExtensionPreservesState) {
1431 InitializeEmptyExtensionsService();
1432 FilePath extensions_path;
1433 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1434 extensions_path = extensions_path.AppendASCII("extensions");
1435
1436 FilePath path = extensions_path.AppendASCII("good.crx");
1437
1438 InstallExtension(path, true);
1439 Extension* good = service_->extensions()->at(0);
1440 ASSERT_EQ("1.0.0.0", good->VersionString());
1441 ASSERT_EQ(good_crx, good->id());
1442
1443 // Disable it and allow it to run in incognito. These settings should carry
1444 // over to the updated version.
1445 service_->DisableExtension(good->id());
1446 service_->SetIsIncognitoEnabled(good, true);
1447
1448 path = extensions_path.AppendASCII("good2.crx");
1449 UpdateExtension(good_crx, path, INSTALLED);
1450 ASSERT_EQ(1u, service_->disabled_extensions()->size());
1451 Extension* good2 = service_->disabled_extensions()->at(0);
1452 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
1453 EXPECT_TRUE(service_->IsIncognitoEnabled(good2));
1454}
1455
[email protected]aa142702010-03-26 01:26:331456// Test adding a pending extension.
1457TEST_F(ExtensionsServiceTest, AddPendingExtension) {
1458 InitializeEmptyExtensionsService();
1459
1460 const std::string kFakeId("fake-id");
1461 const GURL kFakeUpdateURL("http:://fake.update/url");
[email protected]8ef78fd2010-08-19 17:14:321462 const PendingExtensionInfo::ExpectedCrxType kFakeExpectedCrxType =
1463 PendingExtensionInfo::EXTENSION;
[email protected]aa142702010-03-26 01:26:331464 const bool kFakeInstallSilently(true);
[email protected]4416c5a2010-06-26 01:28:571465 const Extension::State kFakeInitialState(Extension::ENABLED);
1466 const bool kFakeInitialIncognitoEnabled(false);
[email protected]aa142702010-03-26 01:26:331467
[email protected]8ef78fd2010-08-19 17:14:321468 service_->AddPendingExtensionFromSync(
1469 kFakeId, kFakeUpdateURL, kFakeExpectedCrxType, kFakeInstallSilently,
[email protected]4416c5a2010-06-26 01:28:571470 kFakeInitialState, kFakeInitialIncognitoEnabled);
[email protected]aa142702010-03-26 01:26:331471 PendingExtensionMap::const_iterator it =
1472 service_->pending_extensions().find(kFakeId);
1473 ASSERT_TRUE(it != service_->pending_extensions().end());
1474 EXPECT_EQ(kFakeUpdateURL, it->second.update_url);
[email protected]8ef78fd2010-08-19 17:14:321475 EXPECT_EQ(kFakeExpectedCrxType, it->second.expected_crx_type);
[email protected]aa142702010-03-26 01:26:331476 EXPECT_EQ(kFakeInstallSilently, it->second.install_silently);
[email protected]aa142702010-03-26 01:26:331477}
1478
[email protected]aa142702010-03-26 01:26:331479namespace {
1480const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
1481const char kGoodUpdateURL[] = "http://good.update/url";
[email protected]8ef78fd2010-08-19 17:14:321482const PendingExtensionInfo::ExpectedCrxType kCrxTypeTheme =
1483 PendingExtensionInfo::THEME;
1484const PendingExtensionInfo::ExpectedCrxType kCrxTypeExtension =
1485 PendingExtensionInfo::EXTENSION;
1486const bool kGoodIsFromSync = true;
[email protected]aa142702010-03-26 01:26:331487const bool kGoodInstallSilently = true;
[email protected]4416c5a2010-06-26 01:28:571488const Extension::State kGoodInitialState = Extension::DISABLED;
1489const bool kGoodInitialIncognitoEnabled = true;
[email protected]aa142702010-03-26 01:26:331490} // namespace
1491
1492// Test updating a pending extension.
1493TEST_F(ExtensionsServiceTest, UpdatePendingExtension) {
1494 InitializeEmptyExtensionsService();
[email protected]8ef78fd2010-08-19 17:14:321495 service_->AddPendingExtensionFromSync(
1496 kGoodId, GURL(kGoodUpdateURL), kCrxTypeExtension,
[email protected]4416c5a2010-06-26 01:28:571497 kGoodInstallSilently, kGoodInitialState,
1498 kGoodInitialIncognitoEnabled);
[email protected]aa142702010-03-26 01:26:331499 EXPECT_TRUE(ContainsKey(service_->pending_extensions(), kGoodId));
1500
1501 FilePath extensions_path;
1502 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1503 extensions_path = extensions_path.AppendASCII("extensions");
1504 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:571505 UpdateExtension(kGoodId, path, INSTALLED);
[email protected]aa142702010-03-26 01:26:331506
1507 EXPECT_FALSE(ContainsKey(service_->pending_extensions(), kGoodId));
[email protected]4416c5a2010-06-26 01:28:571508
1509 Extension* extension = service_->GetExtensionById(kGoodId, true);
1510 ASSERT_TRUE(extension);
1511
1512 bool enabled = service_->GetExtensionById(kGoodId, false);
1513 EXPECT_EQ(kGoodInitialState == Extension::ENABLED, enabled);
1514 EXPECT_EQ(kGoodInitialState,
1515 service_->extension_prefs()->GetExtensionState(extension->id()));
1516 EXPECT_EQ(kGoodInitialIncognitoEnabled,
1517 service_->IsIncognitoEnabled(extension));
[email protected]aa142702010-03-26 01:26:331518}
1519
[email protected]11edd1e2010-07-21 00:14:501520// Test updating a pending theme.
1521TEST_F(ExtensionsServiceTest, UpdatePendingTheme) {
1522 InitializeEmptyExtensionsService();
[email protected]8ef78fd2010-08-19 17:14:321523 service_->AddPendingExtensionFromSync(
1524 theme_crx, GURL(), PendingExtensionInfo::THEME,
1525 false, Extension::ENABLED, false);
[email protected]11edd1e2010-07-21 00:14:501526 EXPECT_TRUE(ContainsKey(service_->pending_extensions(), theme_crx));
1527
1528 FilePath extensions_path;
1529 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1530 extensions_path = extensions_path.AppendASCII("extensions");
1531 FilePath path = extensions_path.AppendASCII("theme.crx");
1532 UpdateExtension(theme_crx, path, ENABLED);
1533
1534 EXPECT_FALSE(ContainsKey(service_->pending_extensions(), theme_crx));
1535
1536 Extension* extension = service_->GetExtensionById(theme_crx, true);
1537 ASSERT_TRUE(extension);
1538
1539 EXPECT_EQ(Extension::ENABLED,
1540 service_->extension_prefs()->GetExtensionState(extension->id()));
1541 EXPECT_FALSE(service_->IsIncognitoEnabled(extension));
1542}
1543
[email protected]8ef78fd2010-08-19 17:14:321544// Test updating a pending CRX as if the source is an external extension
1545// with an update URL. In this case we don't know if the CRX is a theme
1546// or not.
1547TEST_F(ExtensionsServiceTest, UpdatePendingExternalCrx) {
1548 InitializeEmptyExtensionsService();
1549 service_->AddPendingExtensionFromExternalUpdateUrl(theme_crx, GURL());
1550
1551 EXPECT_TRUE(ContainsKey(service_->pending_extensions(), theme_crx));
1552
1553 FilePath extensions_path;
1554 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1555 extensions_path = extensions_path.AppendASCII("extensions");
1556 FilePath path = extensions_path.AppendASCII("theme.crx");
1557 UpdateExtension(theme_crx, path, ENABLED);
1558
1559 EXPECT_FALSE(ContainsKey(service_->pending_extensions(), theme_crx));
1560
1561 Extension* extension = service_->GetExtensionById(theme_crx, true);
1562 ASSERT_TRUE(extension);
1563
1564 EXPECT_EQ(Extension::ENABLED,
1565 service_->extension_prefs()->GetExtensionState(extension->id()));
1566 EXPECT_FALSE(service_->IsIncognitoEnabled(extension));
1567}
1568
1569// Updating a theme should fail if the updater is explicitly told that
1570// the CRX is not a theme.
1571TEST_F(ExtensionsServiceTest, UpdatePendingCrxThemeMismatch) {
1572 InitializeEmptyExtensionsService();
1573 service_->AddPendingExtensionFromSync(
1574 theme_crx, GURL(),
1575 PendingExtensionInfo::EXTENSION,
1576 true, Extension::ENABLED, false);
1577
1578 EXPECT_TRUE(ContainsKey(service_->pending_extensions(), theme_crx));
1579
1580 FilePath extensions_path;
1581 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1582 extensions_path = extensions_path.AppendASCII("extensions");
1583 FilePath path = extensions_path.AppendASCII("theme.crx");
1584 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
1585
1586 EXPECT_FALSE(ContainsKey(service_->pending_extensions(), theme_crx));
1587
1588 Extension* extension = service_->GetExtensionById(theme_crx, true);
1589 ASSERT_FALSE(extension);
1590}
1591
[email protected]aa142702010-03-26 01:26:331592// TODO(akalin): Test updating a pending extension non-silently once
1593// we can mock out ExtensionInstallUI and inject our version into
1594// UpdateExtension().
1595
1596// Test updating a pending extension with wrong is_theme.
1597TEST_F(ExtensionsServiceTest, UpdatePendingExtensionWrongIsTheme) {
1598 InitializeEmptyExtensionsService();
[email protected]aa142702010-03-26 01:26:331599 // Add pending extension with a flipped is_theme.
[email protected]8ef78fd2010-08-19 17:14:321600 service_->AddPendingExtensionFromSync(
1601 kGoodId, GURL(kGoodUpdateURL),
1602 kCrxTypeTheme, kGoodInstallSilently, kGoodInitialState,
[email protected]4416c5a2010-06-26 01:28:571603 kGoodInitialIncognitoEnabled);
[email protected]aa142702010-03-26 01:26:331604 EXPECT_TRUE(ContainsKey(service_->pending_extensions(), kGoodId));
1605
1606 FilePath extensions_path;
1607 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1608 extensions_path = extensions_path.AppendASCII("extensions");
1609 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:571610 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:331611
1612 // TODO(akalin): Figure out how to check that the extensions
1613 // directory is cleaned up properly in OnExtensionInstalled().
1614
[email protected]11edd1e2010-07-21 00:14:501615 EXPECT_FALSE(ContainsKey(service_->pending_extensions(), kGoodId));
[email protected]aa142702010-03-26 01:26:331616}
1617
[email protected]11edd1e2010-07-21 00:14:501618// TODO(akalin): Figure out how to test that installs of pending
1619// unsyncable extensions are blocked.
1620
[email protected]aa142702010-03-26 01:26:331621// Test updating a pending extension for one that is not pending.
1622TEST_F(ExtensionsServiceTest, UpdatePendingExtensionNotPending) {
1623 InitializeEmptyExtensionsService();
1624
1625 FilePath extensions_path;
1626 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1627 extensions_path = extensions_path.AppendASCII("extensions");
1628 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:571629 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:331630
1631 EXPECT_FALSE(ContainsKey(service_->pending_extensions(), kGoodId));
1632}
1633
1634// Test updating a pending extension for one that is already
1635// installed.
1636TEST_F(ExtensionsServiceTest, UpdatePendingExtensionAlreadyInstalled) {
1637 InitializeEmptyExtensionsService();
1638
1639 FilePath extensions_path;
1640 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1641 extensions_path = extensions_path.AppendASCII("extensions");
1642 FilePath path = extensions_path.AppendASCII("good.crx");
1643 InstallExtension(path, true);
1644 ASSERT_EQ(1u, service_->extensions()->size());
1645 Extension* good = service_->extensions()->at(0);
1646
[email protected]8ef78fd2010-08-19 17:14:321647 EXPECT_FALSE(good->is_theme());
1648
[email protected]aa142702010-03-26 01:26:331649 // Use AddPendingExtensionInternal() as AddPendingExtension() would
1650 // balk.
1651 service_->AddPendingExtensionInternal(
[email protected]8ef78fd2010-08-19 17:14:321652 good->id(), good->update_url(),
1653 PendingExtensionInfo::EXTENSION,
1654 kGoodIsFromSync, kGoodInstallSilently, kGoodInitialState,
[email protected]4416c5a2010-06-26 01:28:571655 kGoodInitialIncognitoEnabled);
[email protected]4416c5a2010-06-26 01:28:571656 UpdateExtension(good->id(), path, INSTALLED);
[email protected]aa142702010-03-26 01:26:331657
[email protected]ca3dbf52010-05-19 22:27:061658 EXPECT_FALSE(ContainsKey(service_->pending_extensions(), kGoodId));
[email protected]e957fe52009-06-23 16:51:051659}
1660
[email protected]6b75ec32009-08-14 06:37:181661// Test pref settings for blacklist and unblacklist extensions.
1662TEST_F(ExtensionsServiceTest, SetUnsetBlacklistInPrefs) {
1663 InitializeEmptyExtensionsService();
1664 std::vector<std::string> blacklist;
1665 blacklist.push_back(good0);
1666 blacklist.push_back("invalid_id"); // an invalid id
1667 blacklist.push_back(good1);
1668 service_->UpdateExtensionBlacklist(blacklist);
1669 // Make sure pref is updated
1670 loop_.RunAllPending();
1671
1672 // blacklist is set for good0,1,2
[email protected]e2194742010-08-12 05:54:341673 ValidateBooleanPref(good0, "blacklist", true);
1674 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:181675 // invalid_id should not be inserted to pref.
[email protected]e2194742010-08-12 05:54:341676 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:181677
1678 // remove good1, add good2
1679 blacklist.pop_back();
1680 blacklist.push_back(good2);
1681
1682 service_->UpdateExtensionBlacklist(blacklist);
1683 // only good0 and good1 should be set
[email protected]e2194742010-08-12 05:54:341684 ValidateBooleanPref(good0, "blacklist", true);
1685 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
1686 ValidateBooleanPref(good2, "blacklist", true);
1687 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:181688}
1689
1690// Unload installed extension from blacklist.
1691TEST_F(ExtensionsServiceTest, UnloadBlacklistedExtension) {
1692 InitializeEmptyExtensionsService();
1693 FilePath extensions_path;
1694 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1695 extensions_path = extensions_path.AppendASCII("extensions");
1696
1697 FilePath path = extensions_path.AppendASCII("good.crx");
1698
1699 InstallExtension(path, true);
1700 Extension* good = service_->extensions()->at(0);
1701 EXPECT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:571702 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]6b75ec32009-08-14 06:37:181703
1704 std::vector<std::string> blacklist;
1705 blacklist.push_back(good_crx);
1706 service_->UpdateExtensionBlacklist(blacklist);
1707 // Make sure pref is updated
1708 loop_.RunAllPending();
1709
1710 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:341711 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:181712 EXPECT_EQ(0u, service_->extensions()->size());
1713
1714 // Remove good_crx from blacklist
1715 blacklist.pop_back();
1716 service_->UpdateExtensionBlacklist(blacklist);
1717 // Make sure pref is updated
1718 loop_.RunAllPending();
1719 // blacklist value should not be set for good_crx
[email protected]e2194742010-08-12 05:54:341720 EXPECT_FALSE(IsPrefExist(good_crx, "blacklist"));
[email protected]6b75ec32009-08-14 06:37:181721}
1722
1723// Unload installed extension from blacklist.
1724TEST_F(ExtensionsServiceTest, BlacklistedExtensionWillNotInstall) {
1725 InitializeEmptyExtensionsService();
1726 std::vector<std::string> blacklist;
1727 blacklist.push_back(good_crx);
1728 service_->UpdateExtensionBlacklist(blacklist);
1729 // Make sure pref is updated
1730 loop_.RunAllPending();
1731
1732 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:341733 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:181734
1735 // We can not install good_crx.
1736 FilePath extensions_path;
1737 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1738 extensions_path = extensions_path.AppendASCII("extensions");
1739 FilePath path = extensions_path.AppendASCII("good.crx");
1740 service_->InstallExtension(path);
1741 loop_.RunAllPending();
1742 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]e2194742010-08-12 05:54:341743 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:181744}
1745
1746// Test loading extensions from the profile directory, except
1747// blacklisted ones.
1748TEST_F(ExtensionsServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
1749 // Initialize the test dir with a good Preferences/extensions.
1750 FilePath source_install_dir;
1751 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
1752 source_install_dir = source_install_dir
1753 .AppendASCII("extensions")
1754 .AppendASCII("good")
1755 .AppendASCII("Extensions");
1756 FilePath pref_path = source_install_dir
1757 .DirName()
1758 .AppendASCII("Preferences");
1759 InitializeInstalledExtensionsService(pref_path, source_install_dir);
1760
[email protected]e50013c32010-08-18 21:05:241761 // Blacklist good1.
[email protected]6b75ec32009-08-14 06:37:181762 std::vector<std::string> blacklist;
[email protected]e50013c32010-08-18 21:05:241763 blacklist.push_back(good1);
[email protected]6b75ec32009-08-14 06:37:181764 service_->UpdateExtensionBlacklist(blacklist);
1765 // Make sure pref is updated
1766 loop_.RunAllPending();
1767
[email protected]e50013c32010-08-18 21:05:241768 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:181769
1770 // Load extensions.
1771 service_->Init();
1772 loop_.RunAllPending();
1773
1774 std::vector<std::string> errors = GetErrors();
1775 for (std::vector<std::string>::iterator err = errors.begin();
1776 err != errors.end(); ++err) {
1777 LOG(ERROR) << *err;
1778 }
[email protected]d7b36dc2009-10-29 21:47:401779 ASSERT_EQ(2u, loaded_.size());
[email protected]6b75ec32009-08-14 06:37:181780
[email protected]e50013c32010-08-18 21:05:241781 EXPECT_NE(std::string(good1), loaded_[0]->id());
1782 EXPECT_NE(std::string(good1), loaded_[1]->id());
[email protected]6b75ec32009-08-14 06:37:181783}
1784
[email protected]e50013c32010-08-18 21:05:241785#if defined(OS_CHROMEOS)
1786// Test loading extensions from the profile directory, except
1787// ones with a plugin.
1788TEST_F(ExtensionsServiceTest, WillNotLoadPluginExtensionsFromDirectory) {
1789 // Initialize the test dir with a good Preferences/extensions.
1790 FilePath source_install_dir;
1791 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
1792 source_install_dir = source_install_dir
1793 .AppendASCII("extensions")
1794 .AppendASCII("good")
1795 .AppendASCII("Extensions");
1796 FilePath pref_path = source_install_dir
1797 .DirName()
1798 .AppendASCII("Preferences");
1799 InitializeInstalledExtensionsService(pref_path, source_install_dir);
1800
1801 // good1 contains a plugin.
1802 // Load extensions.
1803 service_->Init();
1804 loop_.RunAllPending();
1805
1806 std::vector<std::string> errors = GetErrors();
1807 for (std::vector<std::string>::iterator err = errors.begin();
1808 err != errors.end(); ++err) {
1809 LOG(ERROR) << *err;
1810 }
1811 ASSERT_EQ(2u, loaded_.size());
1812
1813 EXPECT_NE(std::string(good1), loaded_[0]->id());
1814 EXPECT_NE(std::string(good1), loaded_[1]->id());
1815}
1816#endif
1817
[email protected]306a2bd2010-08-11 14:56:361818// Will not install extension blacklisted by policy.
1819TEST_F(ExtensionsServiceTest, BlacklistedByPolicyWillNotInstall) {
1820 InitializeEmptyExtensionsService();
1821
[email protected]e2194742010-08-12 05:54:341822 ListValue* whitelist = prefs_->GetMutableList("extensions.install.allowlist");
1823 ListValue* blacklist = prefs_->GetMutableList("extensions.install.denylist");
[email protected]306a2bd2010-08-11 14:56:361824 ASSERT_TRUE(whitelist != NULL && blacklist != NULL);
1825
1826 // Blacklist everything.
1827 blacklist->Append(Value::CreateStringValue("*"));
1828
1829 // Blacklist prevents us from installing good_crx.
1830 FilePath extensions_path;
1831 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1832 extensions_path = extensions_path.AppendASCII("extensions");
1833 FilePath path = extensions_path.AppendASCII("good.crx");
1834 service_->InstallExtension(path);
1835 loop_.RunAllPending();
1836 EXPECT_EQ(0u, service_->extensions()->size());
1837
1838 // Now whitelist this particular extension.
1839 whitelist->Append(Value::CreateStringValue(good_crx));
1840
1841 // Ensure we can now install good_crx.
1842 service_->InstallExtension(path);
1843 loop_.RunAllPending();
1844 EXPECT_EQ(1u, service_->extensions()->size());
1845}
1846
[email protected]aa96d3a2010-08-21 08:45:251847// Extension blacklisted by policy get unloaded after installing.
1848TEST_F(ExtensionsServiceTest, BlacklistedByPolicyRemovedIfRunning) {
1849 InitializeEmptyExtensionsService();
1850
1851 // Install good_crx.
1852 FilePath extensions_path;
1853 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1854 extensions_path = extensions_path.AppendASCII("extensions");
1855 FilePath path = extensions_path.AppendASCII("good.crx");
1856 service_->InstallExtension(path);
1857 loop_.RunAllPending();
1858 EXPECT_EQ(1u, service_->extensions()->size());
1859
1860 ListValue* blacklist = prefs_->GetMutableList("extensions.install.denylist");
1861 ASSERT_TRUE(blacklist != NULL);
1862
1863 // Blacklist this extension.
1864 blacklist->Append(Value::CreateStringValue(good_crx));
1865 prefs_->ScheduleSavePersistentPrefs();
1866
1867 // Programmatically appending to the prefs doesn't seem to notify the
1868 // observers... :/
1869 prefs_->pref_notifier()->FireObservers("extensions.install.denylist");
1870
1871 // Extension should not be running now.
1872 loop_.RunAllPending();
1873 EXPECT_EQ(0u, service_->extensions()->size());
1874}
1875
[email protected]cd500f72010-06-25 23:44:321876// Tests disabling extensions
1877TEST_F(ExtensionsServiceTest, DisableExtension) {
1878 InitializeEmptyExtensionsService();
1879 FilePath extensions_path;
1880 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1881 extensions_path = extensions_path.AppendASCII("extensions");
1882
1883 // A simple extension that should install without error.
1884 FilePath path = extensions_path.AppendASCII("good.crx");
1885 InstallExtension(path, true);
1886
1887 const char* extension_id = good_crx;
1888 EXPECT_FALSE(service_->extensions()->empty());
1889 EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
1890 EXPECT_TRUE(service_->GetExtensionById(extension_id, false) != NULL);
1891 EXPECT_TRUE(service_->disabled_extensions()->empty());
1892
1893 // Disable it.
1894 service_->DisableExtension(extension_id);
1895
1896 EXPECT_TRUE(service_->extensions()->empty());
1897 EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
1898 EXPECT_FALSE(service_->GetExtensionById(extension_id, false) != NULL);
1899 EXPECT_FALSE(service_->disabled_extensions()->empty());
1900}
1901
1902// Tests reloading extensions
1903TEST_F(ExtensionsServiceTest, ReloadExtensions) {
1904 InitializeEmptyExtensionsService();
1905 FilePath extensions_path;
1906 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1907 extensions_path = extensions_path.AppendASCII("extensions");
1908
1909 // Simple extension that should install without error.
1910 FilePath path = extensions_path.AppendASCII("good.crx");
1911 InstallExtension(path, true);
1912 const char* extension_id = good_crx;
1913 service_->DisableExtension(extension_id);
1914
1915 EXPECT_EQ(0u, service_->extensions()->size());
1916 EXPECT_EQ(1u, service_->disabled_extensions()->size());
1917
1918 service_->ReloadExtensions();
1919
1920 // Extension counts shouldn't change.
1921 EXPECT_EQ(0u, service_->extensions()->size());
1922 EXPECT_EQ(1u, service_->disabled_extensions()->size());
1923
1924 service_->EnableExtension(extension_id);
1925
1926 EXPECT_EQ(1u, service_->extensions()->size());
1927 EXPECT_EQ(0u, service_->disabled_extensions()->size());
1928
[email protected]5a73f902010-06-30 02:29:411929 // Need to clear |loaded_| manually before reloading as the
1930 // EnableExtension() call above inserted into it and
1931 // UnloadAllExtensions() doesn't send out notifications.
1932 loaded_.clear();
[email protected]cd500f72010-06-25 23:44:321933 service_->ReloadExtensions();
1934
1935 // Extension counts shouldn't change.
1936 EXPECT_EQ(1u, service_->extensions()->size());
1937 EXPECT_EQ(0u, service_->disabled_extensions()->size());
1938}
1939
[email protected]894bb502009-05-21 22:39:571940// Tests uninstalling normal extensions
[email protected]631cf822009-05-15 07:01:251941TEST_F(ExtensionsServiceTest, UninstallExtension) {
[email protected]a9b00ac2009-06-25 21:03:231942 InitializeEmptyExtensionsService();
[email protected]631cf822009-05-15 07:01:251943 FilePath extensions_path;
1944 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
1945 extensions_path = extensions_path.AppendASCII("extensions");
1946
[email protected]4f313d52009-05-21 00:42:291947 // A simple extension that should install without error.
[email protected]894bb502009-05-21 22:39:571948 FilePath path = extensions_path.AppendASCII("good.crx");
[email protected]d2d89d82009-06-08 21:01:531949 InstallExtension(path, true);
[email protected]631cf822009-05-15 07:01:251950
1951 // The directory should be there now.
[email protected]25b34332009-06-05 21:53:191952 const char* extension_id = good_crx;
[email protected]a9b00ac2009-06-25 21:03:231953 FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
[email protected]631cf822009-05-15 07:01:251954 EXPECT_TRUE(file_util::PathExists(extension_path));
1955
[email protected]25b34332009-06-05 21:53:191956 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:341957 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1958 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:191959
[email protected]894bb502009-05-21 22:39:571960 // Uninstall it.
[email protected]27b985d2009-06-25 17:53:151961 service_->UninstallExtension(extension_id, false);
[email protected]902f7cd2009-05-22 19:02:191962 total_successes_ = 0;
[email protected]894bb502009-05-21 22:39:571963
1964 // We should get an unload notification.
1965 ASSERT_TRUE(unloaded_id_.length());
1966 EXPECT_EQ(extension_id, unloaded_id_);
1967
[email protected]9f1087e2009-06-15 17:29:321968 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:191969
[email protected]894bb502009-05-21 22:39:571970 // The extension should not be in the service anymore.
[email protected]61b411612009-11-10 23:17:411971 ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
[email protected]894bb502009-05-21 22:39:571972 loop_.RunAllPending();
1973
1974 // The directory should be gone.
[email protected]631cf822009-05-15 07:01:251975 EXPECT_FALSE(file_util::PathExists(extension_path));
[email protected]631cf822009-05-15 07:01:251976}
1977
[email protected]c10da4b02010-03-25 14:38:321978// Verifies extension state is removed upon uninstall
1979TEST_F(ExtensionsServiceTest, ClearExtensionData) {
1980 InitializeEmptyExtensionsService();
1981
1982 // Load a test extension.
1983 FilePath path;
1984 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
1985 path = path.AppendASCII("extensions");
1986 path = path.AppendASCII("good.crx");
1987 InstallExtension(path, true);
1988 Extension* extension = service_->GetExtensionById(good_crx, false);
1989 ASSERT_TRUE(extension);
1990 GURL ext_url(extension->url());
1991 string16 origin_id =
1992 webkit_database::DatabaseUtil::GetOriginIdentifier(ext_url);
1993
1994 // Set a cookie for the extension.
1995 net::CookieMonster* cookie_monster = profile_
1996 ->GetRequestContextForExtensions()->GetCookieStore()->GetCookieMonster();
1997 ASSERT_TRUE(cookie_monster);
1998 net::CookieOptions options;
1999 cookie_monster->SetCookieWithOptions(ext_url, "dummy=value", options);
2000 net::CookieMonster::CookieList list =
2001 cookie_monster->GetAllCookiesForURL(ext_url);
2002 EXPECT_EQ(1U, list.size());
2003
2004 // Open a database.
2005 webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
2006 string16 db_name = UTF8ToUTF16("db");
2007 string16 description = UTF8ToUTF16("db_description");
2008 int64 size;
2009 int64 available;
2010 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size,
2011 &available);
2012 db_tracker->DatabaseClosed(origin_id, db_name);
2013 std::vector<webkit_database::OriginInfo> origins;
2014 db_tracker->GetAllOriginsInfo(&origins);
2015 EXPECT_EQ(1U, origins.size());
2016 EXPECT_EQ(origin_id, origins[0].GetOrigin());
2017
2018 // Create local storage. We only simulate this by creating the backing file
2019 // since webkit is not initialized.
2020 DOMStorageContext* context =
2021 profile_->GetWebKitContext()->dom_storage_context();
2022 FilePath lso_path = context->GetLocalStorageFilePath(origin_id);
2023 EXPECT_TRUE(file_util::CreateDirectory(lso_path.DirName()));
2024 EXPECT_EQ(0, file_util::WriteFile(lso_path, NULL, 0));
2025 EXPECT_TRUE(file_util::PathExists(lso_path));
2026
2027 // Uninstall the extension.
2028 service_->UninstallExtension(good_crx, false);
2029 loop_.RunAllPending();
2030
2031 // Check that the cookie is gone.
2032 list = cookie_monster->GetAllCookiesForURL(ext_url);
2033 EXPECT_EQ(0U, list.size());
2034
2035 // The database should have vanished as well.
2036 origins.clear();
2037 db_tracker->GetAllOriginsInfo(&origins);
2038 EXPECT_EQ(0U, origins.size());
2039
2040 // Check that the LSO file has been removed.
2041 EXPECT_FALSE(file_util::PathExists(lso_path));
2042}
2043
[email protected]894bb502009-05-21 22:39:572044// Tests loading single extensions (like --load-extension)
[email protected]3cf4f0992009-02-03 23:00:302045TEST_F(ExtensionsServiceTest, LoadExtension) {
[email protected]a9b00ac2009-06-25 21:03:232046 InitializeEmptyExtensionsService();
[email protected]3cf4f0992009-02-03 23:00:302047 FilePath extensions_path;
2048 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
2049 extensions_path = extensions_path.AppendASCII("extensions");
2050
[email protected]a9b00ac2009-06-25 21:03:232051 FilePath ext1 = extensions_path
2052 .AppendASCII("good")
2053 .AppendASCII("Extensions")
[email protected]5a2721f62009-06-13 07:08:202054 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2055 .AppendASCII("1.0.0.0");
[email protected]894bb502009-05-21 22:39:572056 service_->LoadExtension(ext1);
2057 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:182058 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:572059 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:322060 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2061 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:302062
[email protected]e8c729a2010-03-09 19:55:192063 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:192064
[email protected]a9b00ac2009-06-25 21:03:232065 FilePath no_manifest = extensions_path
2066 .AppendASCII("bad")
[email protected]93fd78f42009-07-10 16:43:172067 // .AppendASCII("Extensions")
[email protected]a9b00ac2009-06-25 21:03:232068 .AppendASCII("cccccccccccccccccccccccccccccccc")
2069 .AppendASCII("1");
[email protected]894bb502009-05-21 22:39:572070 service_->LoadExtension(no_manifest);
2071 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:182072 EXPECT_EQ(1u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:572073 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:322074 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]25b34332009-06-05 21:53:192075
2076 // Test uninstall.
[email protected]894bb502009-05-21 22:39:572077 std::string id = loaded_[0]->id();
2078 EXPECT_FALSE(unloaded_id_.length());
[email protected]27b985d2009-06-25 17:53:152079 service_->UninstallExtension(id, false);
[email protected]894bb502009-05-21 22:39:572080 loop_.RunAllPending();
2081 EXPECT_EQ(id, unloaded_id_);
[email protected]9f1087e2009-06-15 17:29:322082 ASSERT_EQ(0u, loaded_.size());
2083 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:302084}
[email protected]0b344962009-03-31 04:21:452085
[email protected]894bb502009-05-21 22:39:572086// Tests that we generate IDs when they are not specified in the manifest for
2087// --load-extension.
[email protected]0b344962009-03-31 04:21:452088TEST_F(ExtensionsServiceTest, GenerateID) {
[email protected]a9b00ac2009-06-25 21:03:232089 InitializeEmptyExtensionsService();
[email protected]fbcc40302009-06-12 20:45:452090
[email protected]0b344962009-03-31 04:21:452091 FilePath extensions_path;
2092 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
2093 extensions_path = extensions_path.AppendASCII("extensions");
2094
[email protected]0b344962009-03-31 04:21:452095 FilePath no_id_ext = extensions_path.AppendASCII("no_id");
[email protected]894bb502009-05-21 22:39:572096 service_->LoadExtension(no_id_ext);
2097 loop_.RunAllPending();
[email protected]0b344962009-03-31 04:21:452098 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:572099 ASSERT_EQ(1u, loaded_.size());
[email protected]84ac7f32009-10-06 06:17:542100 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
[email protected]9f1087e2009-06-15 17:29:322101 EXPECT_EQ(loaded_[0]->location(), Extension::LOAD);
[email protected]0b344962009-03-31 04:21:452102
[email protected]e8c729a2010-03-09 19:55:192103 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:192104
[email protected]84ac7f32009-10-06 06:17:542105 std::string previous_id = loaded_[0]->id();
2106
2107 // If we reload the same path, we should get the same extension ID.
[email protected]894bb502009-05-21 22:39:572108 service_->LoadExtension(no_id_ext);
2109 loop_.RunAllPending();
[email protected]84ac7f32009-10-06 06:17:542110 ASSERT_EQ(1u, loaded_.size());
2111 ASSERT_EQ(previous_id, loaded_[0]->id());
[email protected]0b344962009-03-31 04:21:452112}
[email protected]894bb502009-05-21 22:39:572113
[email protected]d55e7602009-12-16 04:20:422114void ExtensionsServiceTest::TestExternalProvider(
2115 MockExtensionProvider* provider, Extension::Location location) {
[email protected]a1257b12009-06-12 02:51:342116 // Verify that starting with no providers loads no extensions.
2117 service_->Init();
2118 loop_.RunAllPending();
2119 ASSERT_EQ(0u, loaded_.size());
2120
[email protected]a1257b12009-06-12 02:51:342121 // Register a test extension externally using the mock registry provider.
[email protected]894bb502009-05-21 22:39:572122 FilePath source_path;
2123 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path));
2124 source_path = source_path.AppendASCII("extensions").AppendASCII("good.crx");
2125
[email protected]a1257b12009-06-12 02:51:342126 // Add the extension.
[email protected]d55e7602009-12-16 04:20:422127 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
[email protected]894bb502009-05-21 22:39:572128
[email protected]9f1087e2009-06-15 17:29:322129 // Reloading extensions should find our externally registered extension
[email protected]894bb502009-05-21 22:39:572130 // and install it.
[email protected]93fd78f42009-07-10 16:43:172131 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:572132 loop_.RunAllPending();
2133
2134 ASSERT_EQ(0u, GetErrors().size());
2135 ASSERT_EQ(1u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:422136 ASSERT_EQ(location, loaded_[0]->location());
[email protected]894bb502009-05-21 22:39:572137 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:192138 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342139 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2140 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:572141
[email protected]9f1087e2009-06-15 17:29:322142 // Reload extensions without changing anything. The extension should be
[email protected]894bb502009-05-21 22:39:572143 // loaded again.
2144 loaded_.clear();
[email protected]9f1087e2009-06-15 17:29:322145 service_->ReloadExtensions();
[email protected]894bb502009-05-21 22:39:572146 loop_.RunAllPending();
2147 ASSERT_EQ(0u, GetErrors().size());
2148 ASSERT_EQ(1u, loaded_.size());
[email protected]25b34332009-06-05 21:53:192149 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342150 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2151 ValidateIntegerPref(good_crx, "location", location);
[email protected]e2eb43112009-05-29 21:19:542152
[email protected]894bb502009-05-21 22:39:572153 // Now update the extension with a new version. We should get upgraded.
2154 source_path = source_path.DirName().AppendASCII("good2.crx");
[email protected]d55e7602009-12-16 04:20:422155 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]894bb502009-05-21 22:39:572156
2157 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:172158 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:572159 loop_.RunAllPending();
2160 ASSERT_EQ(0u, GetErrors().size());
2161 ASSERT_EQ(1u, loaded_.size());
2162 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:192163 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342164 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2165 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:572166
[email protected]27b985d2009-06-25 17:53:152167 // Uninstall the extension and reload. Nothing should happen because the
[email protected]894bb502009-05-21 22:39:572168 // preference should prevent us from reinstalling.
2169 std::string id = loaded_[0]->id();
[email protected]27b985d2009-06-25 17:53:152170 service_->UninstallExtension(id, false);
[email protected]894bb502009-05-21 22:39:572171 loop_.RunAllPending();
2172
2173 // The extension should also be gone from the install directory.
[email protected]a9b00ac2009-06-25 21:03:232174 FilePath install_path = extensions_install_dir_.AppendASCII(id);
[email protected]894bb502009-05-21 22:39:572175 ASSERT_FALSE(file_util::PathExists(install_path));
2176
2177 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:172178 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:572179 loop_.RunAllPending();
2180 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:192181 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342182 ValidateIntegerPref(good_crx, "state", Extension::KILLBIT);
2183 ValidateIntegerPref(good_crx, "location", location);
[email protected]25b34332009-06-05 21:53:192184
2185 // Now clear the preference and reinstall.
[email protected]e2194742010-08-12 05:54:342186 SetPrefInteg(good_crx, "state", Extension::ENABLED);
[email protected]a9b00ac2009-06-25 21:03:232187 prefs_->ScheduleSavePersistentPrefs();
[email protected]25b34332009-06-05 21:53:192188
2189 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:172190 service_->CheckForExternalUpdates();
[email protected]25b34332009-06-05 21:53:192191 loop_.RunAllPending();
2192 ASSERT_EQ(1u, loaded_.size());
[email protected]25b34332009-06-05 21:53:192193 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342194 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2195 ValidateIntegerPref(good_crx, "location", location);
[email protected]25b34332009-06-05 21:53:192196
[email protected]d55e7602009-12-16 04:20:422197 // Now test an externally triggered uninstall (deleting the registry key or
2198 // the pref entry).
2199 provider->RemoveExtension(good_crx);
[email protected]25b34332009-06-05 21:53:192200
2201 loaded_.clear();
[email protected]c6d82c72010-05-19 18:27:052202 service_->UnloadAllExtensions();
[email protected]27b985d2009-06-25 17:53:152203 service_->LoadAllExtensions();
[email protected]25b34332009-06-05 21:53:192204 loop_.RunAllPending();
2205 ASSERT_EQ(0u, loaded_.size());
[email protected]27b985d2009-06-25 17:53:152206 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:192207
[email protected]27b985d2009-06-25 17:53:152208 // The extension should also be gone from the install directory.
2209 ASSERT_FALSE(file_util::PathExists(install_path));
[email protected]abe7a8942009-06-23 05:14:292210
[email protected]d55e7602009-12-16 04:20:422211 // Now test the case where user uninstalls and then the extension is removed
2212 // from the external provider.
[email protected]abe7a8942009-06-23 05:14:292213
[email protected]d55e7602009-12-16 04:20:422214 provider->UpdateOrAddExtension(good_crx, "1.0", source_path);
[email protected]93fd78f42009-07-10 16:43:172215 service_->CheckForExternalUpdates();
[email protected]abe7a8942009-06-23 05:14:292216 loop_.RunAllPending();
2217
[email protected]c1e432a2009-07-22 21:21:482218 ASSERT_EQ(1u, loaded_.size());
[email protected]c6d82c72010-05-19 18:27:052219 ASSERT_EQ(0u, GetErrors().size());
[email protected]d55e7602009-12-16 04:20:422220
2221 // User uninstalls.
2222 loaded_.clear();
2223 service_->UninstallExtension(id, false);
2224 loop_.RunAllPending();
2225 ASSERT_EQ(0u, loaded_.size());
2226
2227 // Then remove the extension from the extension provider.
2228 provider->RemoveExtension(good_crx);
2229
2230 // Should still be at 0.
2231 loaded_.clear();
2232 service_->LoadAllExtensions();
2233 loop_.RunAllPending();
2234 ASSERT_EQ(0u, loaded_.size());
2235 ValidatePrefKeyCount(1);
2236}
2237
2238// Tests the external installation feature
2239#if defined(OS_WIN)
2240TEST_F(ExtensionsServiceTest, ExternalInstallRegistry) {
2241 // This should all work, even when normal extension installation is disabled.
2242 InitializeEmptyExtensionsService();
2243 set_extensions_enabled(false);
2244
2245 // Now add providers. Extension system takes ownership of the objects.
2246 MockExtensionProvider* reg_provider =
2247 new MockExtensionProvider(Extension::EXTERNAL_REGISTRY);
2248 SetMockExternalProvider(Extension::EXTERNAL_REGISTRY, reg_provider);
2249 TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
2250}
2251#endif
2252
2253TEST_F(ExtensionsServiceTest, ExternalInstallPref) {
2254 // This should all work, even when normal extension installation is disabled.
2255 InitializeEmptyExtensionsService();
2256 set_extensions_enabled(false);
2257
2258 // Now add providers. Extension system takes ownership of the objects.
2259 MockExtensionProvider* pref_provider =
2260 new MockExtensionProvider(Extension::EXTERNAL_PREF);
2261 SetMockExternalProvider(Extension::EXTERNAL_PREF, pref_provider);
2262 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
[email protected]27b985d2009-06-25 17:53:152263}
2264
2265TEST_F(ExtensionsServiceTest, ExternalPrefProvider) {
[email protected]a9b00ac2009-06-25 21:03:232266 InitializeEmptyExtensionsService();
[email protected]27b985d2009-06-25 17:53:152267 std::string json_data =
2268 "{"
2269 "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
2270 "\"external_crx\": \"RandomExtension.crx\","
2271 "\"external_version\": \"1.0\""
2272 "},"
2273 "\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
2274 "\"external_crx\": \"RandomExtension2.crx\","
2275 "\"external_version\": \"2.0\""
[email protected]8ef78fd2010-08-19 17:14:322276 "},"
2277 "\"cccccccccccccccccccccccccccccccc\": {"
2278 "\"external_update_url\": \"http:\\\\foo.com/update\""
[email protected]27b985d2009-06-25 17:53:152279 "}"
2280 "}";
2281
2282 MockProviderVisitor visitor;
2283 std::set<std::string> ignore_list;
[email protected]8ef78fd2010-08-19 17:14:322284 EXPECT_EQ(3, visitor.Visit(json_data, ignore_list));
[email protected]27b985d2009-06-25 17:53:152285 ignore_list.insert("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
[email protected]8ef78fd2010-08-19 17:14:322286 EXPECT_EQ(2, visitor.Visit(json_data, ignore_list));
[email protected]27b985d2009-06-25 17:53:152287 ignore_list.insert("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
[email protected]8ef78fd2010-08-19 17:14:322288 EXPECT_EQ(1, visitor.Visit(json_data, ignore_list));
2289 ignore_list.insert("cccccccccccccccccccccccccccccccc");
[email protected]27b985d2009-06-25 17:53:152290 EXPECT_EQ(0, visitor.Visit(json_data, ignore_list));
2291
[email protected]8ef78fd2010-08-19 17:14:322292 // Use a json that contains six invalid extensions:
[email protected]27b985d2009-06-25 17:53:152293 // - One that is missing the 'external_crx' key.
2294 // - One that is missing the 'external_version' key.
2295 // - One that is specifying .. in the path.
[email protected]8ef78fd2010-08-19 17:14:322296 // - One that specifies both a file and update URL.
2297 // - One that specifies no file or update URL.
2298 // - One that has an update URL that is not well formed.
[email protected]27b985d2009-06-25 17:53:152299 // - Plus one valid extension to make sure the json file is parsed properly.
2300 json_data =
2301 "{"
[email protected]8ef78fd2010-08-19 17:14:322302 "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
[email protected]27b985d2009-06-25 17:53:152303 "\"external_version\": \"1.0\""
2304 "},"
2305 "\"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
2306 "\"external_crx\": \"RandomExtension.crx\""
2307 "},"
2308 "\"cccccccccccccccccccccccccccccccc\": {"
2309 "\"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
2310 "\"external_version\": \"2.0\""
2311 "},"
[email protected]8ef78fd2010-08-19 17:14:322312 "\"dddddddddddddddddddddddddddddddd\": {"
2313 "\"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
2314 "\"external_version\": \"2.0\","
2315 "\"external_update_url\": \"http:\\\\foo.com/update\""
2316 "},"
2317 "\"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
2318 "},"
2319 "\"ffffffffffffffffffffffffffffffff\": {"
2320 "\"external_update_url\": \"This string is not avalid URL\""
2321 "},"
2322 "\"gggggggggggggggggggggggggggggggg\": {"
[email protected]27b985d2009-06-25 17:53:152323 "\"external_crx\": \"RandomValidExtension.crx\","
2324 "\"external_version\": \"1.0\""
2325 "}"
2326 "}";
2327 ignore_list.clear();
2328 EXPECT_EQ(1, visitor.Visit(json_data, ignore_list));
[email protected]e18236b2009-06-22 21:32:102329}
[email protected]36a784c2009-06-23 06:21:082330
[email protected]c6d474f82009-12-16 21:11:062331// Test loading good extensions from the profile directory.
2332TEST_F(ExtensionsServiceTest, LoadAndRelocalizeExtensions) {
2333 // Initialize the test dir with a good Preferences/extensions.
2334 FilePath source_install_dir;
2335 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_install_dir));
2336 source_install_dir = source_install_dir
2337 .AppendASCII("extensions")
2338 .AppendASCII("l10n");
2339 FilePath pref_path = source_install_dir.AppendASCII("Preferences");
2340 InitializeInstalledExtensionsService(pref_path, source_install_dir);
2341
2342 service_->Init();
2343 loop_.RunAllPending();
2344
2345 ASSERT_EQ(3u, loaded_.size());
2346
2347 // This was equal to "sr" on load.
2348 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
2349
2350 // These are untouched by re-localization.
2351 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
2352 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
2353
2354 // This one starts with Serbian name, and gets re-localized into English.
2355 EXPECT_EQ("My name is simple.", loaded_[0]->name());
2356
2357 // These are untouched by re-localization.
2358 EXPECT_EQ("My name is simple.", loaded_[1]->name());
2359 EXPECT_EQ("no l10n", loaded_[2]->name());
2360}
2361
[email protected]f0488f2f2009-07-01 05:25:222362class ExtensionsReadyRecorder : public NotificationObserver {
2363 public:
2364 ExtensionsReadyRecorder() : ready_(false) {
2365 registrar_.Add(this, NotificationType::EXTENSIONS_READY,
2366 NotificationService::AllSources());
2367 }
2368
2369 void set_ready(bool value) { ready_ = value; }
2370 bool ready() { return ready_; }
2371
2372 private:
2373 virtual void Observe(NotificationType type,
2374 const NotificationSource& source,
2375 const NotificationDetails& details) {
2376 switch (type.value) {
2377 case NotificationType::EXTENSIONS_READY:
2378 ready_ = true;
2379 break;
2380 default:
2381 NOTREACHED();
2382 }
2383 }
2384
2385 NotificationRegistrar registrar_;
2386 bool ready_;
2387};
2388
[email protected]36a784c2009-06-23 06:21:082389// Test that we get enabled/disabled correctly for all the pref/command-line
[email protected]27b985d2009-06-25 17:53:152390// combinations. We don't want to derive from the ExtensionsServiceTest class
2391// for this test, so we use ExtensionsServiceTestSimple.
[email protected]f0488f2f2009-07-01 05:25:222392//
2393// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
2394// enabled or not.
[email protected]27b985d2009-06-25 17:53:152395TEST(ExtensionsServiceTestSimple, Enabledness) {
[email protected]f0488f2f2009-07-01 05:25:222396 ExtensionsReadyRecorder recorder;
[email protected]aa96d3a2010-08-21 08:45:252397 scoped_ptr<TestingProfile> profile(new TestingProfile());
[email protected]36a784c2009-06-23 06:21:082398 MessageLoop loop;
[email protected]95d29192009-10-30 01:49:062399 ChromeThread ui_thread(ChromeThread::UI, &loop);
2400 ChromeThread file_thread(ChromeThread::FILE, &loop);
[email protected]36a784c2009-06-23 06:21:082401 scoped_ptr<CommandLine> command_line;
2402 scoped_refptr<ExtensionsService> service;
[email protected]aa96d3a2010-08-21 08:45:252403 FilePath install_dir = profile->GetPath()
[email protected]a9b00ac2009-06-25 21:03:232404 .AppendASCII(ExtensionsService::kInstallDirectoryName);
[email protected]36a784c2009-06-23 06:21:082405
[email protected]6d60703b2009-08-29 01:29:232406 // By default, we are enabled.
[email protected]51343d5a2009-10-26 22:39:332407 command_line.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY));
[email protected]aa96d3a2010-08-21 08:45:252408 service = new ExtensionsService(profile.get(), command_line.get(),
2409 profile->GetPrefs(), install_dir, false);
[email protected]6d60703b2009-08-29 01:29:232410 EXPECT_TRUE(service->extensions_enabled());
2411 service->Init();
2412 loop.RunAllPending();
2413 EXPECT_TRUE(recorder.ready());
2414
2415 // If either the command line or pref is set, we are disabled.
2416 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:252417 profile.reset(new TestingProfile());
[email protected]6d60703b2009-08-29 01:29:232418 command_line->AppendSwitch(switches::kDisableExtensions);
[email protected]aa96d3a2010-08-21 08:45:252419 service = new ExtensionsService(profile.get(), command_line.get(),
2420 profile->GetPrefs(), install_dir, false);
[email protected]36a784c2009-06-23 06:21:082421 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:222422 service->Init();
2423 loop.RunAllPending();
2424 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:082425
[email protected]f0488f2f2009-07-01 05:25:222426 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:252427 profile.reset(new TestingProfile());
2428 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
2429 service = new ExtensionsService(profile.get(), command_line.get(),
2430 profile->GetPrefs(), install_dir, false);
[email protected]6d60703b2009-08-29 01:29:232431 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:222432 service->Init();
2433 loop.RunAllPending();
2434 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:082435
[email protected]f0488f2f2009-07-01 05:25:222436 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:252437 profile.reset(new TestingProfile());
2438 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]51343d5a2009-10-26 22:39:332439 command_line.reset(new CommandLine(CommandLine::ARGUMENTS_ONLY));
[email protected]aa96d3a2010-08-21 08:45:252440 service = new ExtensionsService(profile.get(), command_line.get(),
2441 profile->GetPrefs(), install_dir, false);
[email protected]6d60703b2009-08-29 01:29:232442 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:222443 service->Init();
2444 loop.RunAllPending();
2445 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:082446}
[email protected]24b538a2010-02-27 01:22:442447
2448// Test loading extensions that require limited and unlimited storage quotas.
2449TEST_F(ExtensionsServiceTest, StorageQuota) {
2450 InitializeEmptyExtensionsService();
2451
2452 FilePath extensions_path;
2453 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
2454 extensions_path = extensions_path.AppendASCII("extensions")
2455 .AppendASCII("storage_quota");
2456
2457 FilePath limited_quota_ext = extensions_path.AppendASCII("limited_quota")
2458 .AppendASCII("1.0");
[email protected]03b612f2010-08-13 21:09:212459
2460 // The old permission name for unlimited quota was "unlimited_storage", but
2461 // we changed it to "unlimitedStorage". This tests both versions.
[email protected]24b538a2010-02-27 01:22:442462 FilePath unlimited_quota_ext = extensions_path.AppendASCII("unlimited_quota")
2463 .AppendASCII("1.0");
[email protected]03b612f2010-08-13 21:09:212464 FilePath unlimited_quota_ext2 = extensions_path.AppendASCII("unlimited_quota")
2465 .AppendASCII("2.0");
[email protected]24b538a2010-02-27 01:22:442466 service_->LoadExtension(limited_quota_ext);
2467 service_->LoadExtension(unlimited_quota_ext);
[email protected]03b612f2010-08-13 21:09:212468 service_->LoadExtension(unlimited_quota_ext2);
[email protected]24b538a2010-02-27 01:22:442469 loop_.RunAllPending();
2470
[email protected]03b612f2010-08-13 21:09:212471 ASSERT_EQ(3u, loaded_.size());
[email protected]24b538a2010-02-27 01:22:442472 EXPECT_TRUE(profile_.get());
2473 EXPECT_FALSE(profile_->IsOffTheRecord());
2474
[email protected]03b612f2010-08-13 21:09:212475 // Open the database from each origin to make the tracker aware
[email protected]24b538a2010-02-27 01:22:442476 // of the existance of these origins and to get their quotas.
2477 int64 limited_quota = -1;
2478 int64 unlimited_quota = -1;
2479 string16 limited_quota_identifier =
2480 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[0]->url());
2481 string16 unlimited_quota_identifier =
2482 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[1]->url());
[email protected]03b612f2010-08-13 21:09:212483 string16 unlimited_quota_identifier2 =
2484 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[2]->url());
[email protected]24b538a2010-02-27 01:22:442485 string16 db_name = UTF8ToUTF16("db");
2486 string16 description = UTF8ToUTF16("db_description");
2487 int64 database_size;
2488 webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
[email protected]03b612f2010-08-13 21:09:212489
2490 // First check the normal limited quota extension.
[email protected]24b538a2010-02-27 01:22:442491 db_tracker->DatabaseOpened(limited_quota_identifier, db_name, description,
2492 1, &database_size, &limited_quota);
2493 db_tracker->DatabaseClosed(limited_quota_identifier, db_name);
[email protected]03b612f2010-08-13 21:09:212494 EXPECT_EQ(profile_->GetDatabaseTracker()->GetDefaultQuota(), limited_quota);
2495
2496 // Now check the two unlimited quota ones.
[email protected]24b538a2010-02-27 01:22:442497 db_tracker->DatabaseOpened(unlimited_quota_identifier, db_name, description,
2498 1, &database_size, &unlimited_quota);
2499 db_tracker->DatabaseClosed(unlimited_quota_identifier, db_name);
[email protected]03b612f2010-08-13 21:09:212500 EXPECT_EQ(kint64max, unlimited_quota);
2501 db_tracker->DatabaseOpened(unlimited_quota_identifier2, db_name, description,
2502 1, &database_size, &unlimited_quota);
2503 db_tracker->DatabaseClosed(unlimited_quota_identifier2, db_name);
[email protected]24b538a2010-02-27 01:22:442504
[email protected]24b538a2010-02-27 01:22:442505 EXPECT_EQ(kint64max, unlimited_quota);
2506}
[email protected]1952c7d2010-03-04 23:48:342507
2508// Tests ExtensionsService::register_component_extension().
2509TEST_F(ExtensionsServiceTest, ComponentExtensions) {
2510 InitializeEmptyExtensionsService();
2511
2512 FilePath path;
2513 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
2514 path = path.AppendASCII("extensions")
2515 .AppendASCII("good")
2516 .AppendASCII("Extensions")
2517 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2518 .AppendASCII("1.0.0.0");
2519
2520 std::string manifest;
2521 ASSERT_TRUE(file_util::ReadFileToString(
2522 path.Append(Extension::kManifestFilename), &manifest));
2523
2524 service_->register_component_extension(
2525 ExtensionsService::ComponentExtensionInfo(manifest, path));
2526 service_->Init();
2527
2528 // Note that we do not pump messages -- the extension should be loaded
2529 // immediately.
2530
2531 EXPECT_EQ(0u, GetErrors().size());
2532 ASSERT_EQ(1u, loaded_.size());
2533 EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location());
2534 EXPECT_EQ(1u, service_->extensions()->size());
2535
2536 // Component extensions shouldn't get recourded in the prefs.
2537 ValidatePrefKeyCount(0);
2538
2539 // Reload all extensions, and make sure it comes back.
2540 std::string extension_id = service_->extensions()->at(0)->id();
2541 loaded_.clear();
2542 service_->ReloadExtensions();
2543 ASSERT_EQ(1u, service_->extensions()->size());
2544 EXPECT_EQ(extension_id, service_->extensions()->at(0)->id());
2545}