blob: f29d6cc10a9b94a689146f877f27de5a1131d1d1 [file] [log] [blame]
[email protected]2edc32f2011-01-10 13:57:051// Copyright (c) 2011 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]eaa7dd182010-12-14 11:09:005#include "chrome/browser/extensions/extension_service_unittest.h"
[email protected]bf73f0b2010-02-10 19:26:596
[email protected]f0397fa2008-12-11 17:59:587#include <algorithm>
[email protected]7fa19f82010-12-21 19:40:088#include <set>
[email protected]6014d672008-12-05 00:38:259#include <vector>
10
[email protected]24b538a2010-02-27 01:22:4411#include "base/basictypes.h"
[email protected]36a784c2009-06-23 06:21:0812#include "base/command_line.h"
[email protected]6014d672008-12-05 00:38:2513#include "base/file_util.h"
[email protected]93d49d72009-10-23 20:00:2014#include "base/json/json_reader.h"
[email protected]3b63f8f42011-03-28 01:54:1515#include "base/memory/scoped_ptr.h"
[email protected]3a305db2011-04-12 13:40:5316#include "base/memory/scoped_temp_dir.h"
[email protected]6014d672008-12-05 00:38:2517#include "base/message_loop.h"
18#include "base/path_service.h"
[email protected]dbbad7a2010-08-13 18:18:3619#include "base/stl_util-inl.h"
[email protected]24b538a2010-02-27 01:22:4420#include "base/string16.h"
[email protected]e83326f2010-07-31 17:29:2521#include "base/string_number_conversions.h"
[email protected]6014d672008-12-05 00:38:2522#include "base/string_util.h"
[email protected]24b538a2010-02-27 01:22:4423#include "base/task.h"
[email protected]be1ce6a72010-08-03 14:35:2224#include "base/utf_string_conversions.h"
[email protected]aa142702010-03-26 01:26:3325#include "base/version.h"
[email protected]da0aa3b2009-12-06 21:41:0326#include "chrome/browser/extensions/crx_installer.h"
[email protected]a17f9462009-06-09 02:56:4127#include "chrome/browser/extensions/extension_creator.h"
[email protected]14a000d2010-04-29 21:44:2428#include "chrome/browser/extensions/extension_error_reporter.h"
[email protected]eaa7dd182010-12-14 11:09:0029#include "chrome/browser/extensions/extension_service.h"
[email protected]19eb80152011-02-26 00:28:4330#include "chrome/browser/extensions/extension_special_storage_policy.h"
[email protected]90310d92011-04-17 07:35:0431#include "chrome/browser/extensions/extension_sync_data.h"
32#include "chrome/browser/extensions/extension_updater.h"
[email protected]8e4560b62011-01-14 10:09:1433#include "chrome/browser/extensions/external_extension_provider_impl.h"
[email protected]b3841c502011-03-09 01:21:3134#include "chrome/browser/extensions/external_extension_provider_interface.h"
[email protected]8e4560b62011-01-14 10:09:1435#include "chrome/browser/extensions/external_pref_extension_loader.h"
[email protected]0349ab5d2010-08-11 21:41:5736#include "chrome/browser/extensions/pack_extension_job.cc"
[email protected]90310d92011-04-17 07:35:0437#include "chrome/browser/extensions/pending_extension_info.h"
38#include "chrome/browser/extensions/pending_extension_manager.h"
[email protected]37858e52010-08-26 00:22:0239#include "chrome/browser/prefs/browser_prefs.h"
[email protected]f2d1f612010-12-09 15:10:1740#include "chrome/browser/prefs/pref_service_mock_builder.h"
[email protected]f89ee342011-03-07 09:28:2741#include "chrome/browser/prefs/scoped_user_pref_update.h"
[email protected]37858e52010-08-26 00:22:0242#include "chrome/common/chrome_paths.h"
43#include "chrome/common/chrome_switches.h"
[email protected]5b1a0e22009-05-26 19:00:5844#include "chrome/common/extensions/extension.h"
[email protected]cb691e82009-07-13 14:59:0145#include "chrome/common/extensions/extension_constants.h"
[email protected]942690b132010-05-11 06:42:1446#include "chrome/common/extensions/extension_resource.h"
[email protected]7197f4992009-03-23 05:05:4947#include "chrome/common/extensions/url_pattern.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]1eaa4f72011-02-24 23:37:3551#include "content/browser/appcache/chrome_appcache_service.h"
[email protected]567812d2011-02-24 17:40:5052#include "content/browser/browser_thread.h"
[email protected]1eaa4f72011-02-24 23:37:3553#include "content/browser/file_system/browser_file_system_helper.h"
[email protected]567812d2011-02-24 17:40:5054#include "content/browser/in_process_webkit/dom_storage_context.h"
55#include "content/browser/in_process_webkit/webkit_context.h"
[email protected]c3113022011-04-16 03:26:3056#include "content/common/json_value_serializer.h"
[email protected]b3841c502011-03-09 01:21:3157#include "content/common/notification_registrar.h"
58#include "content/common/notification_service.h"
59#include "content/common/notification_type.h"
[email protected]24b538a2010-02-27 01:22:4460#include "googleurl/src/gurl.h"
[email protected]37858e52010-08-26 00:22:0261#include "net/base/cookie_monster.h"
62#include "net/base/cookie_options.h"
[email protected]dbbad7a2010-08-13 18:18:3663#include "net/url_request/url_request_context.h"
[email protected]abe2c032011-03-31 18:49:3464#include "net/url_request/url_request_context_getter.h"
[email protected]6014d672008-12-05 00:38:2565#include "testing/gtest/include/gtest/gtest.h"
[email protected]f66c110c2008-12-05 20:26:2966#include "testing/platform_test.h"
[email protected]24b538a2010-02-27 01:22:4467#include "webkit/database/database_tracker.h"
68#include "webkit/database/database_util.h"
[email protected]6014d672008-12-05 00:38:2569
[email protected]c6d474f82009-12-16 21:11:0670namespace keys = extension_manifest_keys;
71
[email protected]f0397fa2008-12-11 17:59:5872namespace {
73
[email protected]df4956e2009-06-10 16:53:4274// Extension ids used during testing.
[email protected]5a2721f62009-06-13 07:08:2075const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
76const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
77const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj";
78const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk";
79const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
80const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
[email protected]d7eaf572009-07-01 21:57:0081const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln";
[email protected]5a2721f62009-06-13 07:08:2082const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad";
83const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
[email protected]8d888c12010-11-30 00:00:2584const char* const permissions_crx = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
[email protected]df4956e2009-06-10 16:53:4285
[email protected]f0397fa2008-12-11 17:59:5886struct ExtensionsOrder {
87 bool operator()(const Extension* a, const Extension* b) {
88 return a->name() < b->name();
89 }
90};
91
[email protected]bb28e062009-02-27 17:19:1892static std::vector<std::string> GetErrors() {
93 const std::vector<std::string>* errors =
94 ExtensionErrorReporter::GetInstance()->GetErrors();
95 std::vector<std::string> ret_val;
96
97 for (std::vector<std::string>::const_iterator iter = errors->begin();
98 iter != errors->end(); ++iter) {
99 if (iter->find(".svn") == std::string::npos) {
100 ret_val.push_back(*iter);
101 }
102 }
103
104 // The tests rely on the errors being in a certain order, which can vary
105 // depending on how filesystem iteration works.
106 std::stable_sort(ret_val.begin(), ret_val.end());
107
108 return ret_val;
109}
110
[email protected]8d888c12010-11-30 00:00:25111static void AddPattern(ExtensionExtent* extent, const std::string& pattern) {
112 int schemes = URLPattern::SCHEME_ALL;
113 extent->AddPattern(URLPattern(schemes, pattern));
114}
115
116static void AssertEqualExtents(ExtensionExtent* extent1,
117 ExtensionExtent* extent2) {
118 std::vector<URLPattern> patterns1 = extent1->patterns();
119 std::vector<URLPattern> patterns2 = extent2->patterns();
120 std::set<std::string> strings1;
121 EXPECT_EQ(patterns1.size(), patterns2.size());
122
123 for (size_t i = 0; i < patterns1.size(); ++i)
124 strings1.insert(patterns1.at(i).GetAsString());
125
126 std::set<std::string> strings2;
127 for (size_t i = 0; i < patterns2.size(); ++i)
128 strings2.insert(patterns2.at(i).GetAsString());
129
130 EXPECT_EQ(strings1, strings2);
131}
132
[email protected]f0397fa2008-12-11 17:59:58133} // namespace
[email protected]6014d672008-12-05 00:38:25134
[email protected]8e4560b62011-01-14 10:09:14135class MockExtensionProvider : public ExternalExtensionProviderInterface {
[email protected]a1257b12009-06-12 02:51:34136 public:
[email protected]8e4560b62011-01-14 10:09:14137 explicit MockExtensionProvider(
138 VisitorInterface* visitor,
139 Extension::Location location)
140 : location_(location), visitor_(visitor), visit_count_(0) {
141 }
[email protected]a1257b12009-06-12 02:51:34142 virtual ~MockExtensionProvider() {}
143
144 void UpdateOrAddExtension(const std::string& id,
145 const std::string& version,
[email protected]f5ad7542009-07-24 17:38:59146 const FilePath& path) {
[email protected]a1257b12009-06-12 02:51:34147 extension_map_[id] = std::make_pair(version, path);
148 }
149
150 void RemoveExtension(const std::string& id) {
151 extension_map_.erase(id);
152 }
153
154 // ExternalExtensionProvider implementation:
[email protected]8e4560b62011-01-14 10:09:14155 virtual void VisitRegisteredExtension() const {
[email protected]0a60a2e2010-10-25 16:15:21156 visit_count_++;
[email protected]a1257b12009-06-12 02:51:34157 for (DataMap::const_iterator i = extension_map_.begin();
158 i != extension_map_.end(); ++i) {
[email protected]a1257b12009-06-12 02:51:34159 scoped_ptr<Version> version;
160 version.reset(Version::GetVersionFromString(i->second.first));
161
[email protected]8e4560b62011-01-14 10:09:14162 visitor_->OnExternalExtensionFileFound(
[email protected]7577a5c52009-07-30 06:21:58163 i->first, version.get(), i->second.second, location_);
[email protected]a1257b12009-06-12 02:51:34164 }
[email protected]8e4560b62011-01-14 10:09:14165 visitor_->OnExternalProviderReady();
[email protected]a1257b12009-06-12 02:51:34166 }
167
[email protected]0a60a2e2010-10-25 16:15:21168 virtual bool HasExtension(const std::string& id) const {
169 return extension_map_.find(id) != extension_map_.end();
170 }
171
172 virtual bool GetExtensionDetails(const std::string& id,
173 Extension::Location* location,
174 scoped_ptr<Version>* version) const {
[email protected]a1257b12009-06-12 02:51:34175 DataMap::const_iterator it = extension_map_.find(id);
176 if (it == extension_map_.end())
[email protected]0a60a2e2010-10-25 16:15:21177 return false;
178
179 if (version)
180 version->reset(Version::GetVersionFromString(it->second.first));
[email protected]a1257b12009-06-12 02:51:34181
182 if (location)
183 *location = location_;
[email protected]0a60a2e2010-10-25 16:15:21184
185 return true;
186 }
[email protected]8e4560b62011-01-14 10:09:14187
188 virtual bool IsReady() {
189 return true;
190 }
191
192 virtual void ServiceShutdown() {
193 }
194
[email protected]0a60a2e2010-10-25 16:15:21195 int visit_count() const { return visit_count_; }
196 void set_visit_count(int visit_count) {
197 visit_count_ = visit_count;
[email protected]a1257b12009-06-12 02:51:34198 }
199
200 private:
201 typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap;
202 DataMap extension_map_;
203 Extension::Location location_;
[email protected]8e4560b62011-01-14 10:09:14204 VisitorInterface* visitor_;
[email protected]27b985d2009-06-25 17:53:15205
[email protected]0a60a2e2010-10-25 16:15:21206 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
207 // Mutable because it must be incremented on each call to
208 // VisitRegisteredExtension(), which must be a const method to inherit
209 // from the class being mocked.
210 mutable int visit_count_;
211
[email protected]27b985d2009-06-25 17:53:15212 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
213};
214
[email protected]8e4560b62011-01-14 10:09:14215class MockProviderVisitor
216 : public ExternalExtensionProviderInterface::VisitorInterface {
[email protected]27b985d2009-06-25 17:53:15217 public:
[email protected]f0841cd2011-01-19 15:07:24218
219 // The provider will return |fake_base_path| from
220 // GetBaseCrxFilePath(). User can test the behavior with
221 // and without an empty path using this parameter.
222 explicit MockProviderVisitor(FilePath fake_base_path)
223 : ids_found_(0),
224 fake_base_path_(fake_base_path) {
[email protected]27b985d2009-06-25 17:53:15225 }
226
[email protected]683d0702010-12-06 16:25:57227 int Visit(const std::string& json_data) {
[email protected]27b985d2009-06-25 17:53:15228 // Give the test json file to the provider for parsing.
[email protected]8e4560b62011-01-14 10:09:14229 provider_.reset(new ExternalExtensionProviderImpl(
230 this,
[email protected]f0841cd2011-01-19 15:07:24231 new ExternalTestingExtensionLoader(json_data, fake_base_path_),
[email protected]8e4560b62011-01-14 10:09:14232 Extension::EXTERNAL_PREF,
233 Extension::EXTERNAL_PREF_DOWNLOAD));
[email protected]27b985d2009-06-25 17:53:15234
235 // We also parse the file into a dictionary to compare what we get back
236 // from the provider.
237 JSONStringValueSerializer serializer(json_data);
[email protected]ba399672010-04-06 15:42:39238 Value* json_value = serializer.Deserialize(NULL, NULL);
[email protected]27b985d2009-06-25 17:53:15239
[email protected]ba399672010-04-06 15:42:39240 if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
[email protected]e2194742010-08-12 05:54:34241 NOTREACHED() << "Unable to deserialize json data";
[email protected]27b985d2009-06-25 17:53:15242 return -1;
243 } else {
244 DictionaryValue* external_extensions =
245 static_cast<DictionaryValue*>(json_value);
246 prefs_.reset(external_extensions);
247 }
248
249 // Reset our counter.
250 ids_found_ = 0;
[email protected]683d0702010-12-06 16:25:57251 // Ask the provider to look up all extensions and return them.
[email protected]8e4560b62011-01-14 10:09:14252 provider_->VisitRegisteredExtension();
[email protected]27b985d2009-06-25 17:53:15253
254 return ids_found_;
255 }
256
[email protected]8ef78fd2010-08-19 17:14:32257 virtual void OnExternalExtensionFileFound(const std::string& id,
258 const Version* version,
259 const FilePath& path,
260 Extension::Location unused) {
[email protected]27b985d2009-06-25 17:53:15261 ++ids_found_;
262 DictionaryValue* pref;
263 // This tests is to make sure that the provider only notifies us of the
264 // values we gave it. So if the id we doesn't exist in our internal
265 // dictionary then something is wrong.
[email protected]e2194742010-08-12 05:54:34266 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
267 << "Got back ID (" << id.c_str() << ") we weren't expecting";
[email protected]27b985d2009-06-25 17:53:15268
[email protected]f0841cd2011-01-19 15:07:24269 EXPECT_TRUE(path.IsAbsolute());
270 if (!fake_base_path_.empty())
271 EXPECT_TRUE(fake_base_path_.IsParent(path));
272
[email protected]27b985d2009-06-25 17:53:15273 if (pref) {
[email protected]0a60a2e2010-10-25 16:15:21274 EXPECT_TRUE(provider_->HasExtension(id));
275
[email protected]27b985d2009-06-25 17:53:15276 // Ask provider if the extension we got back is registered.
277 Extension::Location location = Extension::INVALID;
[email protected]0a60a2e2010-10-25 16:15:21278 scoped_ptr<Version> v1;
279 FilePath crx_path;
280
281 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
282 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
283
284 scoped_ptr<Version> v2;
285 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
[email protected]27b985d2009-06-25 17:53:15286 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
287 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
288 EXPECT_EQ(Extension::EXTERNAL_PREF, location);
289
290 // Remove it so we won't count it ever again.
[email protected]e2194742010-08-12 05:54:34291 prefs_->Remove(id, NULL);
[email protected]27b985d2009-06-25 17:53:15292 }
293 }
294
[email protected]21a5a672010-11-04 10:47:42295 virtual void OnExternalExtensionUpdateUrlFound(
296 const std::string& id, const GURL& update_url,
297 Extension::Location location) {
[email protected]8ef78fd2010-08-19 17:14:32298 ++ids_found_;
299 DictionaryValue* pref;
300 // This tests is to make sure that the provider only notifies us of the
301 // values we gave it. So if the id we doesn't exist in our internal
302 // dictionary then something is wrong.
303 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
304 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
[email protected]21a5a672010-11-04 10:47:42305 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location);
[email protected]8ef78fd2010-08-19 17:14:32306
307 if (pref) {
[email protected]0a60a2e2010-10-25 16:15:21308 EXPECT_TRUE(provider_->HasExtension(id));
309
310 // External extensions with update URLs do not have versions.
311 scoped_ptr<Version> v1;
[email protected]21a5a672010-11-04 10:47:42312 Extension::Location location1 = Extension::INVALID;
313 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
[email protected]0a60a2e2010-10-25 16:15:21314 EXPECT_FALSE(v1.get());
[email protected]21a5a672010-11-04 10:47:42315 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location1);
[email protected]0a60a2e2010-10-25 16:15:21316
[email protected]8ef78fd2010-08-19 17:14:32317 // Remove it so we won't count it again.
318 prefs_->Remove(id, NULL);
319 }
320 }
321
[email protected]8e4560b62011-01-14 10:09:14322 virtual void OnExternalProviderReady() {
323 EXPECT_TRUE(provider_->IsReady());
324 }
325
[email protected]27b985d2009-06-25 17:53:15326 private:
327 int ids_found_;
[email protected]f0841cd2011-01-19 15:07:24328 FilePath fake_base_path_;
[email protected]8e4560b62011-01-14 10:09:14329 scoped_ptr<ExternalExtensionProviderImpl> provider_;
[email protected]27b985d2009-06-25 17:53:15330 scoped_ptr<DictionaryValue> prefs_;
331
332 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
[email protected]a1257b12009-06-12 02:51:34333};
334
[email protected]bf73f0b2010-02-10 19:26:59335class ExtensionTestingProfile : public TestingProfile {
[email protected]6014d672008-12-05 00:38:25336 public:
[email protected]9931fbfc2010-07-23 09:15:51337 ExtensionTestingProfile() : service_(NULL) {
[email protected]bf73f0b2010-02-10 19:26:59338 }
339
[email protected]eaa7dd182010-12-14 11:09:00340 void set_extensions_service(ExtensionService* service) {
[email protected]bf73f0b2010-02-10 19:26:59341 service_ = service;
342 }
[email protected]eaa7dd182010-12-14 11:09:00343 virtual ExtensionService* GetExtensionService() { return service_; }
[email protected]bf73f0b2010-02-10 19:26:59344
[email protected]c2c263c2010-08-13 21:59:48345 virtual ChromeAppCacheService* GetAppCacheService() {
346 if (!appcache_service_) {
347 appcache_service_ = new ChromeAppCacheService;
[email protected]14908b72011-04-20 06:54:36348 if (!BrowserThread::PostTask(
349 BrowserThread::IO, FROM_HERE,
350 NewRunnableMethod(
351 appcache_service_.get(),
352 &ChromeAppCacheService::InitializeOnIOThread,
353 IsOffTheRecord()
[email protected]39fc6472011-04-06 20:54:00354 ? FilePath() : GetPath().Append(chrome::kAppCacheDirname),
[email protected]14908b72011-04-20 06:54:36355 make_scoped_refptr(GetHostContentSettingsMap()),
356 make_scoped_refptr(GetExtensionSpecialStoragePolicy()),
357 false)))
358 NOTREACHED();
[email protected]c2c263c2010-08-13 21:59:48359 }
360 return appcache_service_;
361 }
362
[email protected]397281f2011-02-14 05:15:53363 virtual fileapi::FileSystemContext* GetFileSystemContext() {
[email protected]b7b82eb2010-12-14 01:12:12364 if (!file_system_context_)
365 file_system_context_ = CreateFileSystemContext(
[email protected]19eb80152011-02-26 00:28:43366 GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
[email protected]b7b82eb2010-12-14 01:12:12367 return file_system_context_;
[email protected]70c6c042010-10-08 09:52:07368 }
369
[email protected]bf73f0b2010-02-10 19:26:59370 private:
[email protected]eaa7dd182010-12-14 11:09:00371 ExtensionService* service_;
[email protected]c2c263c2010-08-13 21:59:48372 scoped_refptr<ChromeAppCacheService> appcache_service_;
[email protected]397281f2011-02-14 05:15:53373 scoped_refptr<fileapi::FileSystemContext> file_system_context_;
[email protected]bf73f0b2010-02-10 19:26:59374};
375
376// Our message loop may be used in tests which require it to be an IO loop.
[email protected]eaa7dd182010-12-14 11:09:00377ExtensionServiceTestBase::ExtensionServiceTestBase()
[email protected]14908b72011-04-20 06:54:36378 : service_(NULL),
379 total_successes_(0),
[email protected]9931fbfc2010-07-23 09:15:51380 loop_(MessageLoop::TYPE_IO),
[email protected]ca4b5fa32010-10-09 12:42:18381 ui_thread_(BrowserThread::UI, &loop_),
382 db_thread_(BrowserThread::DB, &loop_),
383 webkit_thread_(BrowserThread::WEBKIT, &loop_),
384 file_thread_(BrowserThread::FILE, &loop_),
385 io_thread_(BrowserThread::IO, &loop_) {
[email protected]e85e34c32011-04-13 18:38:35386 FilePath test_data_dir;
387 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
388 ADD_FAILURE();
389 return;
390 }
391 data_dir_ = test_data_dir.AppendASCII("extensions");
[email protected]bf73f0b2010-02-10 19:26:59392}
393
[email protected]eaa7dd182010-12-14 11:09:00394ExtensionServiceTestBase::~ExtensionServiceTestBase() {
395 // Drop our reference to ExtensionService and TestingProfile, so that they
[email protected]ca4b5fa32010-10-09 12:42:18396 // can be destroyed while BrowserThreads and MessageLoop are still around
397 // (they are used in the destruction process).
[email protected]bf73f0b2010-02-10 19:26:59398 service_ = NULL;
[email protected]c10da4b02010-03-25 14:38:32399 profile_.reset(NULL);
[email protected]bf73f0b2010-02-10 19:26:59400 MessageLoop::current()->RunAllPending();
401}
402
[email protected]eaa7dd182010-12-14 11:09:00403void ExtensionServiceTestBase::InitializeExtensionService(
[email protected]90310d92011-04-17 07:35:04404 const FilePath& pref_file, const FilePath& extensions_install_dir,
405 bool autoupdate_enabled) {
[email protected]bf73f0b2010-02-10 19:26:59406 ExtensionTestingProfile* profile = new ExtensionTestingProfile();
[email protected]f2d1f612010-12-09 15:10:17407 // Create a PrefService that only contains user defined preference values.
408 PrefService* prefs =
409 PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create();
[email protected]2fb7dc982010-09-29 12:24:28410 Profile::RegisterUserPrefs(prefs);
411 browser::RegisterUserPrefs(prefs);
412 profile->SetPrefService(prefs);
[email protected]ea587b02010-05-21 15:01:35413
[email protected]bf73f0b2010-02-10 19:26:59414 profile_.reset(profile);
415
[email protected]eaa7dd182010-12-14 11:09:00416 service_ = profile->CreateExtensionService(
[email protected]2fb7dc982010-09-29 12:24:28417 CommandLine::ForCurrentProcess(),
[email protected]90310d92011-04-17 07:35:04418 extensions_install_dir,
419 autoupdate_enabled);
[email protected]bf73f0b2010-02-10 19:26:59420 service_->set_extensions_enabled(true);
421 service_->set_show_extensions_prompts(false);
[email protected]14908b72011-04-20 06:54:36422 profile->set_extensions_service(service_);
[email protected]bf73f0b2010-02-10 19:26:59423
424 // When we start up, we want to make sure there is no external provider,
425 // since the ExtensionService on Windows will use the Registry as a default
426 // provider and if there is something already registered there then it will
427 // interfere with the tests. Those tests that need an external provider
428 // will register one specifically.
429 service_->ClearProvidersForTesting();
430
431 total_successes_ = 0;
432}
433
[email protected]eaa7dd182010-12-14 11:09:00434void ExtensionServiceTestBase::InitializeInstalledExtensionService(
[email protected]bf73f0b2010-02-10 19:26:59435 const FilePath& prefs_file, const FilePath& source_install_dir) {
436 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
437 FilePath path_ = temp_dir_.path();
438 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
439 file_util::Delete(path_, true);
440 file_util::CreateDirectory(path_);
441 FilePath temp_prefs = path_.Append(FILE_PATH_LITERAL("Preferences"));
442 file_util::CopyFile(prefs_file, temp_prefs);
443
444 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
445 file_util::Delete(extensions_install_dir_, true);
446 file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
447
[email protected]90310d92011-04-17 07:35:04448 InitializeExtensionService(temp_prefs, extensions_install_dir_, false);
[email protected]bf73f0b2010-02-10 19:26:59449}
450
[email protected]eaa7dd182010-12-14 11:09:00451void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
[email protected]90310d92011-04-17 07:35:04452 InitializeExtensionServiceHelper(false);
453}
454
455void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
456 InitializeExtensionServiceHelper(true);
457 service_->updater()->Start();
458}
459
460void ExtensionServiceTestBase::InitializeExtensionServiceHelper(
461 bool autoupdate_enabled) {
[email protected]bf73f0b2010-02-10 19:26:59462 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
463 FilePath path_ = temp_dir_.path();
464 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
465 file_util::Delete(path_, true);
466 file_util::CreateDirectory(path_);
467 FilePath prefs_filename = path_
468 .Append(FILE_PATH_LITERAL("TestPreferences"));
469 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
470 file_util::Delete(extensions_install_dir_, true);
471 file_util::CreateDirectory(extensions_install_dir_);
472
[email protected]90310d92011-04-17 07:35:04473 InitializeExtensionService(prefs_filename, extensions_install_dir_,
474 autoupdate_enabled);
[email protected]bf73f0b2010-02-10 19:26:59475}
476
477// static
[email protected]eaa7dd182010-12-14 11:09:00478void ExtensionServiceTestBase::SetUpTestCase() {
[email protected]bf73f0b2010-02-10 19:26:59479 ExtensionErrorReporter::Init(false); // no noisy errors
480}
481
[email protected]eaa7dd182010-12-14 11:09:00482void ExtensionServiceTestBase::SetUp() {
[email protected]bf73f0b2010-02-10 19:26:59483 ExtensionErrorReporter::GetInstance()->ClearErrors();
484}
485
[email protected]eaa7dd182010-12-14 11:09:00486class ExtensionServiceTest
487 : public ExtensionServiceTestBase, public NotificationObserver {
[email protected]bf73f0b2010-02-10 19:26:59488 public:
[email protected]eaa7dd182010-12-14 11:09:00489 ExtensionServiceTest() : installed_(NULL) {
[email protected]ae09ca62009-08-21 19:46:46490 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
[email protected]894bb502009-05-21 22:39:57491 NotificationService::AllSources());
492 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
493 NotificationService::AllSources());
494 registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
495 NotificationService::AllSources());
[email protected]a9b00ac2009-06-25 21:03:23496 }
[email protected]cc655912009-01-29 23:19:19497
[email protected]894bb502009-05-21 22:39:57498 virtual void Observe(NotificationType type,
499 const NotificationSource& source,
500 const NotificationDetails& details) {
501 switch (type.value) {
[email protected]ae09ca62009-08-21 19:46:46502 case NotificationType::EXTENSION_LOADED: {
[email protected]9adb9692010-10-29 23:14:02503 const Extension* extension = Details<const Extension>(details).ptr();
[email protected]00cd9c42010-11-02 20:15:57504 loaded_.push_back(make_scoped_refptr(extension));
[email protected]894bb502009-05-21 22:39:57505 // The tests rely on the errors being in a certain order, which can vary
506 // depending on how filesystem iteration works.
507 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
508 break;
509 }
510
[email protected]9f1087e2009-06-15 17:29:32511 case NotificationType::EXTENSION_UNLOADED: {
[email protected]a9f39a312010-12-23 22:14:27512 const Extension* e =
513 Details<UnloadedExtensionInfo>(details)->extension;
[email protected]9f1087e2009-06-15 17:29:32514 unloaded_id_ = e->id();
515 ExtensionList::iterator i =
516 std::find(loaded_.begin(), loaded_.end(), e);
517 // TODO(erikkay) fix so this can be an assert. Right now the tests
518 // are manually calling clear() on loaded_, so this isn't doable.
519 if (i == loaded_.end())
520 return;
521 loaded_.erase(i);
[email protected]894bb502009-05-21 22:39:57522 break;
[email protected]9f1087e2009-06-15 17:29:32523 }
[email protected]894bb502009-05-21 22:39:57524 case NotificationType::EXTENSION_INSTALLED:
[email protected]9adb9692010-10-29 23:14:02525 installed_ = Details<const Extension>(details).ptr();
[email protected]894bb502009-05-21 22:39:57526 break;
527
[email protected]894bb502009-05-21 22:39:57528 default:
529 DCHECK(false);
[email protected]3acbd422008-12-08 18:25:00530 }
531 }
532
[email protected]8e4560b62011-01-14 10:09:14533 void AddMockExternalProvider(ExternalExtensionProviderInterface* provider) {
[email protected]0a60a2e2010-10-25 16:15:21534 service_->AddProviderForTesting(provider);
[email protected]a1257b12009-06-12 02:51:34535 }
536
[email protected]9197f3b2009-06-02 00:49:27537 protected:
[email protected]d55e7602009-12-16 04:20:42538 void TestExternalProvider(MockExtensionProvider* provider,
539 Extension::Location location);
540
[email protected]145a317b2011-04-12 16:03:46541 void PackAndInstallCrx(const FilePath& dir_path,
542 const FilePath& pem_path,
543 bool should_succeed) {
[email protected]3ba0fd32010-06-19 05:39:10544 FilePath crx_path;
[email protected]3a305db2011-04-12 13:40:53545 ScopedTempDir temp_dir;
546 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
547 crx_path = temp_dir_.path().AppendASCII("temp.crx");
[email protected]8d888c12010-11-30 00:00:25548
549 // Use the existing pem key, if provided.
550 FilePath pem_output_path;
551 if (pem_path.value().empty()) {
552 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
553 ASSERT_TRUE(file_util::Delete(pem_output_path, false));
554 } else {
555 ASSERT_TRUE(file_util::PathExists(pem_path));
556 }
[email protected]3ba0fd32010-06-19 05:39:10557
558 ASSERT_TRUE(file_util::Delete(crx_path, false));
[email protected]8d888c12010-11-30 00:00:25559
[email protected]3ba0fd32010-06-19 05:39:10560 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
[email protected]8d888c12010-11-30 00:00:25561 ASSERT_TRUE(creator->Run(dir_path,
562 crx_path,
563 pem_path,
564 pem_output_path));
565
[email protected]3ba0fd32010-06-19 05:39:10566 ASSERT_TRUE(file_util::PathExists(crx_path));
567
[email protected]145a317b2011-04-12 16:03:46568 InstallCrx(crx_path, should_succeed);
[email protected]3ba0fd32010-06-19 05:39:10569 }
570
[email protected]145a317b2011-04-12 16:03:46571 void PackAndInstallCrx(const FilePath& dir_path,
572 bool should_succeed) {
573 PackAndInstallCrx(dir_path, FilePath(), should_succeed);
[email protected]8d888c12010-11-30 00:00:25574 }
575
[email protected]53da2c962011-03-03 17:08:05576 // Create a CrxInstaller and start installation. To allow the install
577 // to happen, use loop_.RunAllPending();. Most tests will not use this
[email protected]145a317b2011-04-12 16:03:46578 // method directly. Instead, use InstallCrx(), which waits for
[email protected]53da2c962011-03-03 17:08:05579 // the crx to be installed and does extra error checking.
580 void StartCrxInstall(const FilePath& crx_path) {
[email protected]b2907fd2011-03-25 16:43:37581 ASSERT_TRUE(file_util::PathExists(crx_path))
582 << "Path does not exist: "<< crx_path.value().c_str();
[email protected]14908b72011-04-20 06:54:36583 // no client (silent install)
584 scoped_refptr<CrxInstaller> installer(service_->MakeCrxInstaller(NULL));
[email protected]53da2c962011-03-03 17:08:05585 installer->InstallCrx(crx_path);
586 }
587
[email protected]145a317b2011-04-12 16:03:46588 void InstallCrx(const FilePath& path,
[email protected]d2d89d82009-06-08 21:01:53589 bool should_succeed) {
[email protected]53da2c962011-03-03 17:08:05590 StartCrxInstall(path);
[email protected]145a317b2011-04-12 16:03:46591 WaitForCrxInstall(path, should_succeed);
592 }
593
594 void InstallCrxWithLocation(const FilePath& crx_path,
595 Extension::Location install_location,
596 bool should_succeed) {
597 ASSERT_TRUE(file_util::PathExists(crx_path))
598 << "Path does not exist: "<< crx_path.value().c_str();
[email protected]14908b72011-04-20 06:54:36599 // no client (silent install)
600 scoped_refptr<CrxInstaller> installer(service_->MakeCrxInstaller(NULL));
[email protected]145a317b2011-04-12 16:03:46601
602 installer->set_install_source(install_location);
603 installer->InstallCrx(crx_path);
604
605 WaitForCrxInstall(crx_path, should_succeed);
606 }
607
608 // Wait for a CrxInstaller to finish. Used by InstallCrx.
609 void WaitForCrxInstall(const FilePath& path,
610 bool should_succeed) {
[email protected]894bb502009-05-21 22:39:57611 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:18612 std::vector<std::string> errors = GetErrors();
[email protected]cc655912009-01-29 23:19:19613 if (should_succeed) {
[email protected]902f7cd2009-05-22 19:02:19614 ++total_successes_;
615
[email protected]a57209872009-05-04 22:53:14616 EXPECT_TRUE(installed_) << path.value();
[email protected]9197f3b2009-06-02 00:49:27617
[email protected]a1257b12009-06-12 02:51:34618 ASSERT_EQ(1u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18619 EXPECT_EQ(0u, errors.size()) << path.value();
[email protected]902f7cd2009-05-22 19:02:19620 EXPECT_EQ(total_successes_, service_->extensions()->size()) <<
621 path.value();
[email protected]61b411612009-11-10 23:17:41622 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
[email protected]d2d89d82009-06-08 21:01:53623 path.value();
[email protected]bb28e062009-02-27 17:19:18624 for (std::vector<std::string>::iterator err = errors.begin();
625 err != errors.end(); ++err) {
[email protected]37eeb5a2009-02-26 23:36:17626 LOG(ERROR) << *err;
627 }
[email protected]cc655912009-01-29 23:19:19628 } else {
[email protected]a57209872009-05-04 22:53:14629 EXPECT_FALSE(installed_) << path.value();
[email protected]86a274072009-06-11 02:06:45630 EXPECT_EQ(0u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18631 EXPECT_EQ(1u, errors.size()) << path.value();
[email protected]cc655912009-01-29 23:19:19632 }
[email protected]bb28e062009-02-27 17:19:18633
[email protected]a57209872009-05-04 22:53:14634 installed_ = NULL;
[email protected]894bb502009-05-21 22:39:57635 loaded_.clear();
[email protected]bb28e062009-02-27 17:19:18636 ExtensionErrorReporter::GetInstance()->ClearErrors();
[email protected]cc655912009-01-29 23:19:19637 }
638
[email protected]4416c5a2010-06-26 01:28:57639 enum UpdateState {
640 FAILED_SILENTLY,
641 FAILED,
642 UPDATED,
643 INSTALLED,
644 ENABLED
645 };
646
[email protected]7577a5c52009-07-30 06:21:58647 void UpdateExtension(const std::string& id, const FilePath& in_path,
[email protected]4416c5a2010-06-26 01:28:57648 UpdateState expected_state) {
[email protected]7577a5c52009-07-30 06:21:58649 ASSERT_TRUE(file_util::PathExists(in_path));
[email protected]e957fe52009-06-23 16:51:05650
[email protected]7577a5c52009-07-30 06:21:58651 // We need to copy this to a temporary location because Update() will delete
652 // it.
[email protected]a1295ba22009-09-02 03:33:39653 FilePath path = temp_dir_.path();
654 path = path.Append(in_path.BaseName());
[email protected]7577a5c52009-07-30 06:21:58655 ASSERT_TRUE(file_util::CopyFile(in_path, path));
[email protected]e957fe52009-06-23 16:51:05656
[email protected]4416c5a2010-06-26 01:28:57657 int previous_enabled_extension_count =
658 service_->extensions()->size();
659 int previous_installed_extension_count =
660 previous_enabled_extension_count +
661 service_->disabled_extensions()->size();
662
[email protected]5c8516202010-03-18 21:43:34663 service_->UpdateExtension(id, path, GURL());
[email protected]e957fe52009-06-23 16:51:05664 loop_.RunAllPending();
[email protected]f3113e232010-06-25 01:36:40665
[email protected]4416c5a2010-06-26 01:28:57666 std::vector<std::string> errors = GetErrors();
667 int error_count = errors.size();
668 int enabled_extension_count =
669 service_->extensions()->size();
670 int installed_extension_count =
671 enabled_extension_count + service_->disabled_extensions()->size();
672
673 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
674 EXPECT_EQ(expected_error_count, error_count) << path.value();
675
676 if (expected_state <= FAILED) {
677 EXPECT_EQ(previous_enabled_extension_count,
678 enabled_extension_count);
679 EXPECT_EQ(previous_installed_extension_count,
680 installed_extension_count);
[email protected]e957fe52009-06-23 16:51:05681 } else {
[email protected]4416c5a2010-06-26 01:28:57682 int expected_installed_extension_count =
683 (expected_state >= INSTALLED) ? 1 : 0;
684 int expected_enabled_extension_count =
685 (expected_state >= ENABLED) ? 1 : 0;
686 EXPECT_EQ(expected_installed_extension_count,
687 installed_extension_count);
688 EXPECT_EQ(expected_enabled_extension_count,
689 enabled_extension_count);
[email protected]e957fe52009-06-23 16:51:05690 }
[email protected]7577a5c52009-07-30 06:21:58691
692 // Update() should delete the temporary input file.
693 EXPECT_FALSE(file_util::PathExists(path));
[email protected]e957fe52009-06-23 16:51:05694 }
695
[email protected]25b34332009-06-05 21:53:19696 void ValidatePrefKeyCount(size_t count) {
[email protected]43d3bf82011-04-11 07:46:58697 const DictionaryValue* dict =
698 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]25b34332009-06-05 21:53:19699 ASSERT_TRUE(dict != NULL);
[email protected]4dad9ad82009-11-25 20:47:52700 EXPECT_EQ(count, dict->size());
[email protected]25b34332009-06-05 21:53:19701 }
702
[email protected]6b75ec32009-08-14 06:37:18703 void ValidateBooleanPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34704 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06705 bool expected_val) {
[email protected]e2194742010-08-12 05:54:34706 std::string msg = " while checking: ";
707 msg += extension_id;
708 msg += " ";
[email protected]6b75ec32009-08-14 06:37:18709 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34710 msg += " == ";
711 msg += expected_val ? "true" : "false";
[email protected]6b75ec32009-08-14 06:37:18712
[email protected]2fb7dc982010-09-29 12:24:28713 PrefService* prefs = profile_->GetPrefs();
714 const DictionaryValue* dict =
715 prefs->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18716 ASSERT_TRUE(dict != NULL) << msg;
717 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34718 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]6b75ec32009-08-14 06:37:18719 EXPECT_TRUE(pref != NULL) << msg;
720 bool val;
[email protected]4c91487e2009-10-02 04:11:04721 ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06722 EXPECT_EQ(expected_val, val) << msg;
[email protected]6b75ec32009-08-14 06:37:18723 }
724
725 bool IsPrefExist(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34726 const std::string& pref_path) {
[email protected]2fb7dc982010-09-29 12:24:28727 const DictionaryValue* dict =
728 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18729 if (dict == NULL) return false;
730 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34731 if (!dict->GetDictionary(extension_id, &pref)) {
[email protected]6b75ec32009-08-14 06:37:18732 return false;
733 }
734 if (pref == NULL) {
735 return false;
736 }
737 bool val;
738 if (!pref->GetBoolean(pref_path, &val)) {
739 return false;
740 }
741 return true;
742 }
743
744 void ValidateIntegerPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34745 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06746 int expected_val) {
[email protected]e2194742010-08-12 05:54:34747 std::string msg = " while checking: ";
748 msg += extension_id;
749 msg += " ";
[email protected]25b34332009-06-05 21:53:19750 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34751 msg += " == ";
752 msg += base::IntToString(expected_val);
[email protected]25b34332009-06-05 21:53:19753
[email protected]2fb7dc982010-09-29 12:24:28754 PrefService* prefs = profile_->GetPrefs();
755 const DictionaryValue* dict =
756 prefs->GetDictionary("extensions.settings");
[email protected]25b34332009-06-05 21:53:19757 ASSERT_TRUE(dict != NULL) << msg;
758 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34759 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]25b34332009-06-05 21:53:19760 EXPECT_TRUE(pref != NULL) << msg;
761 int val;
[email protected]4c91487e2009-10-02 04:11:04762 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06763 EXPECT_EQ(expected_val, val) << msg;
764 }
765
766 void ValidateStringPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34767 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06768 const std::string& expected_val) {
[email protected]e2194742010-08-12 05:54:34769 std::string msg = " while checking: ";
770 msg += extension_id;
771 msg += ".manifest.";
[email protected]c6d474f82009-12-16 21:11:06772 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34773 msg += " == ";
774 msg += expected_val;
[email protected]c6d474f82009-12-16 21:11:06775
[email protected]2fb7dc982010-09-29 12:24:28776 const DictionaryValue* dict =
777 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]c6d474f82009-12-16 21:11:06778 ASSERT_TRUE(dict != NULL) << msg;
779 DictionaryValue* pref = NULL;
780 std::string manifest_path = extension_id + ".manifest";
[email protected]e2194742010-08-12 05:54:34781 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
[email protected]c6d474f82009-12-16 21:11:06782 EXPECT_TRUE(pref != NULL) << msg;
783 std::string val;
784 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
785 EXPECT_EQ(expected_val, val) << msg;
[email protected]25b34332009-06-05 21:53:19786 }
787
[email protected]8d888c12010-11-30 00:00:25788 void SetPref(const std::string& extension_id,
789 const std::string& pref_path,
790 Value* value,
791 const std::string& msg) {
[email protected]43d3bf82011-04-11 07:46:58792 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
793 DictionaryValue* dict = update.Get();
[email protected]8d888c12010-11-30 00:00:25794 ASSERT_TRUE(dict != NULL) << msg;
795 DictionaryValue* pref = NULL;
796 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
797 EXPECT_TRUE(pref != NULL) << msg;
798 pref->Set(pref_path, value);
799 }
800
[email protected]6b75ec32009-08-14 06:37:18801 void SetPrefInteg(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34802 const std::string& pref_path,
[email protected]6b75ec32009-08-14 06:37:18803 int value) {
[email protected]e2194742010-08-12 05:54:34804 std::string msg = " while setting: ";
805 msg += extension_id;
806 msg += " ";
[email protected]a1257b12009-06-12 02:51:34807 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34808 msg += " = ";
809 msg += base::IntToString(value);
[email protected]a1257b12009-06-12 02:51:34810
[email protected]8d888c12010-11-30 00:00:25811 SetPref(extension_id, pref_path, Value::CreateIntegerValue(value), msg);
812 }
813
814 void SetPrefBool(const std::string& extension_id,
815 const std::string& pref_path,
816 bool value) {
817 std::string msg = " while setting: ";
818 msg += extension_id + " " + pref_path;
819 msg += " = ";
820 msg += (value ? "true" : "false");
821
822 SetPref(extension_id, pref_path, Value::CreateBooleanValue(value), msg);
823 }
824
825 void ClearPref(const std::string& extension_id,
826 const std::string& pref_path) {
827 std::string msg = " while clearing: ";
828 msg += extension_id + " " + pref_path;
829
[email protected]43d3bf82011-04-11 07:46:58830 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
831 DictionaryValue* dict = update.Get();
[email protected]a1257b12009-06-12 02:51:34832 ASSERT_TRUE(dict != NULL) << msg;
833 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34834 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]a1257b12009-06-12 02:51:34835 EXPECT_TRUE(pref != NULL) << msg;
[email protected]8d888c12010-11-30 00:00:25836 pref->Remove(pref_path, NULL);
837 }
838
839 void SetPrefStringSet(const std::string& extension_id,
840 const std::string& pref_path,
841 const std::set<std::string>& value) {
842 std::string msg = " while setting: ";
843 msg += extension_id + " " + pref_path;
844
845 ListValue* list_value = new ListValue();
846 for (std::set<std::string>::const_iterator iter = value.begin();
847 iter != value.end(); ++iter)
848 list_value->Append(Value::CreateStringValue(*iter));
849
850 SetPref(extension_id, pref_path, list_value, msg);
[email protected]a1257b12009-06-12 02:51:34851 }
852
[email protected]25b34332009-06-05 21:53:19853 protected:
[email protected]9f1087e2009-06-15 17:29:32854 ExtensionList loaded_;
[email protected]894bb502009-05-21 22:39:57855 std::string unloaded_id_;
[email protected]9adb9692010-10-29 23:14:02856 const Extension* installed_;
[email protected]894bb502009-05-21 22:39:57857
[email protected]6014d672008-12-05 00:38:25858 private:
[email protected]894bb502009-05-21 22:39:57859 NotificationRegistrar registrar_;
[email protected]bb28e062009-02-27 17:19:18860};
[email protected]6014d672008-12-05 00:38:25861
[email protected]0349ab5d2010-08-11 21:41:57862FilePath NormalizeSeparators(const FilePath& path) {
[email protected]a9b00ac2009-06-25 21:03:23863#if defined(FILE_PATH_USES_WIN_SEPARATORS)
[email protected]0349ab5d2010-08-11 21:41:57864 return path.NormalizeWindowsPathSeparators();
865#else
[email protected]a9b00ac2009-06-25 21:03:23866 return path;
[email protected]0349ab5d2010-08-11 21:41:57867#endif // FILE_PATH_USES_WIN_SEPARATORS
[email protected]a9b00ac2009-06-25 21:03:23868}
[email protected]0349ab5d2010-08-11 21:41:57869
870// Receives notifications from a PackExtensionJob, indicating either that
871// packing succeeded or that there was some error.
872class PackExtensionTestClient : public PackExtensionJob::Client {
873 public:
874 PackExtensionTestClient(const FilePath& expected_crx_path,
875 const FilePath& expected_private_key_path);
876 virtual void OnPackSuccess(const FilePath& crx_path,
877 const FilePath& private_key_path);
878 virtual void OnPackFailure(const std::string& error_message);
879
880 private:
881 const FilePath expected_crx_path_;
882 const FilePath expected_private_key_path_;
883 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
884};
885
886PackExtensionTestClient::PackExtensionTestClient(
887 const FilePath& expected_crx_path,
888 const FilePath& expected_private_key_path)
889 : expected_crx_path_(expected_crx_path),
890 expected_private_key_path_(expected_private_key_path) {}
891
892// If packing succeeded, we make sure that the package names match our
893// expectations.
894void PackExtensionTestClient::OnPackSuccess(const FilePath& crx_path,
895 const FilePath& private_key_path) {
896 // We got the notification and processed it; we don't expect any further tasks
897 // to be posted to the current thread, so we should stop blocking and continue
898 // on with the rest of the test.
899 // This call to |Quit()| matches the call to |Run()| in the
900 // |PackPunctuatedExtension| test.
901 MessageLoop::current()->Quit();
902 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
903 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
904 ASSERT_TRUE(file_util::PathExists(private_key_path));
905}
906
907// The tests are designed so that we never expect to see a packing error.
908void PackExtensionTestClient::OnPackFailure(const std::string& error_message) {
909 FAIL() << "Packing should not fail.";
910}
911
[email protected]54cb3c92009-02-17 22:30:21912// Test loading good extensions from the profile directory.
[email protected]eaa7dd182010-12-14 11:09:00913TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
[email protected]a9b00ac2009-06-25 21:03:23914 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:35915 FilePath source_install_dir = data_dir_
[email protected]a9b00ac2009-06-25 21:03:23916 .AppendASCII("good")
917 .AppendASCII("Extensions");
918 FilePath pref_path = source_install_dir
919 .DirName()
920 .AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:00921 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]6014d672008-12-05 00:38:25922
[email protected]9f1087e2009-06-15 17:29:32923 service_->Init();
[email protected]6014d672008-12-05 00:38:25924
[email protected]e50013c32010-08-18 21:05:24925 // On Chrome OS, we disallow extensions with plugins. "good1" has plugins,
926 // so we need to edit it out here.
927 uint32 expected_num_extensions = 3u;
928#if defined(OS_CHROMEOS)
929 --expected_num_extensions;
930#endif
931 ASSERT_EQ(expected_num_extensions, loaded_.size());
[email protected]6014d672008-12-05 00:38:25932
[email protected]fbcc40302009-06-12 20:45:45933 EXPECT_EQ(std::string(good0), loaded_[0]->id());
[email protected]e1cec06c2008-12-18 01:22:23934 EXPECT_EQ(std::string("My extension 1"),
[email protected]894bb502009-05-21 22:39:57935 loaded_[0]->name());
[email protected]e1cec06c2008-12-18 01:22:23936 EXPECT_EQ(std::string("The first extension that I made."),
[email protected]894bb502009-05-21 22:39:57937 loaded_[0]->description());
938 EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location());
[email protected]61b411612009-11-10 23:17:41939 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
[email protected]e50013c32010-08-18 21:05:24940 EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
[email protected]eab9b452009-01-23 20:48:59941
[email protected]25b34332009-06-05 21:53:19942 ValidatePrefKeyCount(3);
[email protected]e2194742010-08-12 05:54:34943 ValidateIntegerPref(good0, "state", Extension::ENABLED);
944 ValidateIntegerPref(good0, "location", Extension::INTERNAL);
945 ValidateIntegerPref(good1, "state", Extension::ENABLED);
946 ValidateIntegerPref(good1, "location", Extension::INTERNAL);
947 ValidateIntegerPref(good2, "state", Extension::ENABLED);
948 ValidateIntegerPref(good2, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:19949
[email protected]9adb9692010-10-29 23:14:02950 const Extension* extension = loaded_[0];
[email protected]34aa8dc2009-02-19 07:03:05951 const UserScriptList& scripts = extension->content_scripts();
[email protected]e66de892009-03-20 20:38:43952 ASSERT_EQ(2u, scripts.size());
[email protected]f0488f2f2009-07-01 05:25:22953 EXPECT_EQ(3u, scripts[0].url_patterns().size());
[email protected]62771442009-11-22 02:25:04954 EXPECT_EQ("file://*",
[email protected]5f8681f2009-11-18 03:21:13955 scripts[0].url_patterns()[0].GetAsString());
[email protected]62771442009-11-22 02:25:04956 EXPECT_EQ("http://*.google.com/*",
[email protected]5f8681f2009-11-18 03:21:13957 scripts[0].url_patterns()[1].GetAsString());
[email protected]62771442009-11-22 02:25:04958 EXPECT_EQ("https://*.google.com/*",
[email protected]f0488f2f2009-07-01 05:25:22959 scripts[0].url_patterns()[2].GetAsString());
[email protected]e66de892009-03-20 20:38:43960 EXPECT_EQ(2u, scripts[0].js_scripts().size());
[email protected]052c92702010-06-25 07:25:52961 ExtensionResource resource00(extension->id(),
962 scripts[0].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:21963 scripts[0].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:29964 FilePath expected_path(extension->path().AppendASCII("script1.js"));
965 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
966 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
[email protected]052c92702010-06-25 07:25:52967 ExtensionResource resource01(extension->id(),
968 scripts[0].js_scripts()[1].extension_root(),
[email protected]9194b3f2009-10-20 15:27:21969 scripts[0].js_scripts()[1].relative_path());
[email protected]a14b16b2009-10-28 12:41:29970 expected_path = extension->path().AppendASCII("script2.js");
971 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
972 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
[email protected]c533bb22009-06-03 19:06:11973 EXPECT_TRUE(extension->plugins().empty());
[email protected]e66de892009-03-20 20:38:43974 EXPECT_EQ(1u, scripts[1].url_patterns().size());
975 EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString());
[email protected]052c92702010-06-25 07:25:52976 ExtensionResource resource10(extension->id(),
977 scripts[1].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:21978 scripts[1].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:29979 expected_path =
980 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
981 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
982 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
[email protected]35506352009-08-07 18:58:19983 const std::vector<URLPattern> permissions = extension->host_permissions();
[email protected]7197f4992009-03-23 05:05:49984 ASSERT_EQ(2u, permissions.size());
985 EXPECT_EQ("http://*.google.com/*", permissions[0].GetAsString());
986 EXPECT_EQ("https://*.google.com/*", permissions[1].GetAsString());
[email protected]6014d672008-12-05 00:38:25987
[email protected]e50013c32010-08-18 21:05:24988#if !defined(OS_CHROMEOS)
[email protected]25b34332009-06-05 21:53:19989 EXPECT_EQ(std::string(good1), loaded_[1]->id());
[email protected]894bb502009-05-21 22:39:57990 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
991 EXPECT_EQ(std::string(""), loaded_[1]->description());
[email protected]81067e02009-07-27 15:12:09992 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
993 loaded_[1]->background_url());
[email protected]894bb502009-05-21 22:39:57994 EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
[email protected]c533bb22009-06-03 19:06:11995 EXPECT_EQ(2u, loaded_[1]->plugins().size());
996 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
997 loaded_[1]->plugins()[0].path.value());
998 EXPECT_TRUE(loaded_[1]->plugins()[0].is_public);
999 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1000 loaded_[1]->plugins()[1].path.value());
1001 EXPECT_FALSE(loaded_[1]->plugins()[1].is_public);
[email protected]894bb502009-05-21 22:39:571002 EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location());
[email protected]e50013c32010-08-18 21:05:241003#endif
[email protected]18a12352009-01-31 01:33:281004
[email protected]e50013c32010-08-18 21:05:241005 int index = expected_num_extensions - 1;
1006 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1007 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1008 EXPECT_EQ(std::string(""), loaded_[index]->description());
1009 EXPECT_EQ(0u, loaded_[index]->content_scripts().size());
1010 EXPECT_EQ(Extension::INTERNAL, loaded_[index]->location());
[email protected]6014d672008-12-05 00:38:251011};
[email protected]cc655912009-01-29 23:19:191012
[email protected]54cb3c92009-02-17 22:30:211013// Test loading bad extensions from the profile directory.
[email protected]eaa7dd182010-12-14 11:09:001014TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
[email protected]c6d474f82009-12-16 21:11:061015 // Initialize the test dir with a bad Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:351016 FilePath source_install_dir = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231017 .AppendASCII("bad")
1018 .AppendASCII("Extensions");
1019 FilePath pref_path = source_install_dir
1020 .DirName()
1021 .AppendASCII("Preferences");
[email protected]54cb3c92009-02-17 22:30:211022
[email protected]eaa7dd182010-12-14 11:09:001023 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]54cb3c92009-02-17 22:30:211024
[email protected]9f1087e2009-06-15 17:29:321025 service_->Init();
[email protected]894bb502009-05-21 22:39:571026 loop_.RunAllPending();
[email protected]54cb3c92009-02-17 22:30:211027
[email protected]a9b00ac2009-06-25 21:03:231028 ASSERT_EQ(4u, GetErrors().size());
1029 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:191030
[email protected]44935742010-09-10 08:18:461031 EXPECT_TRUE(MatchPattern(GetErrors()[0],
[email protected]d7b36dc2009-10-29 21:47:401032 std::string("Could not load extension from '*'. ") +
1033 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[0];
[email protected]8d6d9ff2009-02-20 08:14:391034
[email protected]44935742010-09-10 08:18:461035 EXPECT_TRUE(MatchPattern(GetErrors()[1],
[email protected]8d6d9ff2009-02-20 08:14:391036 std::string("Could not load extension from '*'. ") +
[email protected]f6f5b8b2009-10-09 21:28:191037 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[1];
[email protected]8d6d9ff2009-02-20 08:14:391038
[email protected]44935742010-09-10 08:18:461039 EXPECT_TRUE(MatchPattern(GetErrors()[2],
[email protected]8d6d9ff2009-02-20 08:14:391040 std::string("Could not load extension from '*'. ") +
[email protected]cb691e82009-07-13 14:59:011041 extension_manifest_errors::kMissingFile)) << GetErrors()[2];
[email protected]a9b00ac2009-06-25 21:03:231042
[email protected]44935742010-09-10 08:18:461043 EXPECT_TRUE(MatchPattern(GetErrors()[3],
[email protected]a9b00ac2009-06-25 21:03:231044 std::string("Could not load extension from '*'. ") +
[email protected]f6f5b8b2009-10-09 21:28:191045 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[3];
[email protected]54cb3c92009-02-17 22:30:211046};
1047
[email protected]894bb502009-05-21 22:39:571048// Test that partially deleted extensions are cleaned up during startup
1049// Test loading bad extensions from the profile directory.
[email protected]eaa7dd182010-12-14 11:09:001050TEST_F(ExtensionServiceTest, CleanupOnStartup) {
[email protected]e85e34c32011-04-13 18:38:351051 FilePath source_install_dir = data_dir_
[email protected]b6ab96d2009-08-20 18:58:191052 .AppendASCII("good")
1053 .AppendASCII("Extensions");
1054 FilePath pref_path = source_install_dir
1055 .DirName()
1056 .AppendASCII("Preferences");
[email protected]a9b00ac2009-06-25 21:03:231057
[email protected]eaa7dd182010-12-14 11:09:001058 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]894bb502009-05-21 22:39:571059
[email protected]b6ab96d2009-08-20 18:58:191060 // Simulate that one of them got partially deleted by clearing its pref.
[email protected]43d3bf82011-04-11 07:46:581061 {
1062 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1063 DictionaryValue* dict = update.Get();
1064 ASSERT_TRUE(dict != NULL);
1065 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1066 }
[email protected]894bb502009-05-21 22:39:571067
1068 service_->Init();
1069 loop_.RunAllPending();
1070
[email protected]a9b00ac2009-06-25 21:03:231071 file_util::FileEnumerator dirs(extensions_install_dir_, false,
[email protected]9f1087e2009-06-15 17:29:321072 file_util::FileEnumerator::DIRECTORIES);
1073 size_t count = 0;
1074 while (!dirs.Next().empty())
1075 count++;
1076
[email protected]894bb502009-05-21 22:39:571077 // We should have only gotten two extensions now.
[email protected]9f1087e2009-06-15 17:29:321078 EXPECT_EQ(2u, count);
[email protected]e2eb43112009-05-29 21:19:541079
[email protected]894bb502009-05-21 22:39:571080 // And extension1 dir should now be toast.
[email protected]b6ab96d2009-08-20 18:58:191081 FilePath extension_dir = extensions_install_dir_
1082 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1083 ASSERT_FALSE(file_util::PathExists(extension_dir));
[email protected]894bb502009-05-21 22:39:571084}
1085
[email protected]d7eaf572009-07-01 21:57:001086// Test installing extensions. This test tries to install few extensions using
1087// crx files. If you need to change those crx files, feel free to repackage
1088// them, throw away the key used and change the id's above.
[email protected]eaa7dd182010-12-14 11:09:001089TEST_F(ExtensionServiceTest, InstallExtension) {
1090 InitializeEmptyExtensionService();
[email protected]a9b00ac2009-06-25 21:03:231091
[email protected]e2eb43112009-05-29 21:19:541092 // Extensions not enabled.
[email protected]7577a5c52009-07-30 06:21:581093 set_extensions_enabled(false);
[email protected]e85e34c32011-04-13 18:38:351094 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:461095 InstallCrx(path, false);
[email protected]7577a5c52009-07-30 06:21:581096 set_extensions_enabled(true);
[email protected]e2eb43112009-05-29 21:19:541097
[email protected]25b34332009-06-05 21:53:191098 ValidatePrefKeyCount(0);
1099
[email protected]e2eb43112009-05-29 21:19:541100 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:351101 path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:461102 InstallCrx(path, true);
[email protected]cc655912009-01-29 23:19:191103 // TODO(erikkay): verify the contents of the installed extension.
1104
[email protected]25b34332009-06-05 21:53:191105 int pref_count = 0;
1106 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341107 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1108 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:191109
[email protected]902f7cd2009-05-22 19:02:191110 // An extension with page actions.
[email protected]e85e34c32011-04-13 18:38:351111 path = data_dir_.AppendASCII("page_action.crx");
[email protected]145a317b2011-04-12 16:03:461112 InstallCrx(path, true);
[email protected]25b34332009-06-05 21:53:191113 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341114 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1115 ValidateIntegerPref(page_action, "location", Extension::INTERNAL);
[email protected]902f7cd2009-05-22 19:02:191116
[email protected]9f1087e2009-06-15 17:29:321117 // Bad signature.
[email protected]e85e34c32011-04-13 18:38:351118 path = data_dir_.AppendASCII("bad_signature.crx");
[email protected]145a317b2011-04-12 16:03:461119 InstallCrx(path, false);
[email protected]d7eaf572009-07-01 21:57:001120 ValidatePrefKeyCount(pref_count);
[email protected]fbcc40302009-06-12 20:45:451121
[email protected]cc655912009-01-29 23:19:191122 // 0-length extension file.
[email protected]e85e34c32011-04-13 18:38:351123 path = data_dir_.AppendASCII("not_an_extension.crx");
[email protected]145a317b2011-04-12 16:03:461124 InstallCrx(path, false);
[email protected]25b34332009-06-05 21:53:191125 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191126
1127 // Bad magic number.
[email protected]e85e34c32011-04-13 18:38:351128 path = data_dir_.AppendASCII("bad_magic.crx");
[email protected]145a317b2011-04-12 16:03:461129 InstallCrx(path, false);
[email protected]25b34332009-06-05 21:53:191130 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191131
[email protected]8ef78fd2010-08-19 17:14:321132 // Extensions cannot have folders or files that have underscores except in
[email protected]99872e32009-09-25 22:02:491133 // certain whitelisted cases (eg _locales). This is an example of a broader
1134 // class of validation that we do to the directory structure of the extension.
1135 // We did not used to handle this correctly for installation.
[email protected]e85e34c32011-04-13 18:38:351136 path = data_dir_.AppendASCII("bad_underscore.crx");
[email protected]145a317b2011-04-12 16:03:461137 InstallCrx(path, false);
[email protected]99872e32009-09-25 22:02:491138 ValidatePrefKeyCount(pref_count);
1139
[email protected]cc655912009-01-29 23:19:191140 // TODO(erikkay): add more tests for many of the failure cases.
1141 // TODO(erikkay): add tests for upgrade cases.
1142}
1143
[email protected]79c833b52011-04-05 18:31:011144// Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1145TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
[email protected]eaa7dd182010-12-14 11:09:001146 InitializeEmptyExtensionService();
[email protected]683d0702010-12-06 16:25:571147
[email protected]e85e34c32011-04-13 18:38:351148 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]683d0702010-12-06 16:25:571149 set_extensions_enabled(true);
1150
[email protected]8e4560b62011-01-14 10:09:141151 scoped_ptr<Version> version;
1152 version.reset(Version::GetVersionFromString("1.0.0.0"));
[email protected]683d0702010-12-06 16:25:571153 // Install an external extension.
[email protected]8e4560b62011-01-14 10:09:141154 service_->OnExternalExtensionFileFound(good_crx, version.get(),
[email protected]683d0702010-12-06 16:25:571155 path, Extension::EXTERNAL_PREF);
1156 loop_.RunAllPending();
[email protected]604322d2011-03-22 16:51:561157 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]683d0702010-12-06 16:25:571158
1159 // Uninstall it and check that its killbit gets set.
[email protected]d6ebc9792011-04-07 18:18:331160 service_->UninstallExtension(good_crx, false, NULL);
[email protected]683d0702010-12-06 16:25:571161 loop_.RunAllPending();
[email protected]79c833b52011-04-05 18:31:011162 ValidateIntegerPref(good_crx, "location",
1163 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571164
1165 // Try to re-install it externally. This should fail because of the killbit.
[email protected]8e4560b62011-01-14 10:09:141166 service_->OnExternalExtensionFileFound(good_crx, version.get(),
[email protected]683d0702010-12-06 16:25:571167 path, Extension::EXTERNAL_PREF);
1168 loop_.RunAllPending();
1169 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
[email protected]79c833b52011-04-05 18:31:011170 ValidateIntegerPref(good_crx, "location",
1171 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571172
[email protected]8e4560b62011-01-14 10:09:141173 version.reset(Version::GetVersionFromString("1.0.0.1"));
[email protected]683d0702010-12-06 16:25:571174 // Repeat the same thing with a newer version of the extension.
[email protected]e85e34c32011-04-13 18:38:351175 path = data_dir_.AppendASCII("good2.crx");
[email protected]8e4560b62011-01-14 10:09:141176 service_->OnExternalExtensionFileFound(good_crx, version.get(),
[email protected]683d0702010-12-06 16:25:571177 path, Extension::EXTERNAL_PREF);
1178 loop_.RunAllPending();
1179 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
[email protected]79c833b52011-04-05 18:31:011180 ValidateIntegerPref(good_crx, "location",
1181 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571182
1183 // Try adding the same extension from an external update URL.
[email protected]b2907fd2011-03-25 16:43:371184 service_->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]683d0702010-12-06 16:25:571185 good_crx,
1186 GURL("http:://fake.update/url"),
1187 Extension::EXTERNAL_PREF_DOWNLOAD);
[email protected]b2907fd2011-03-25 16:43:371188
1189 ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
[email protected]683d0702010-12-06 16:25:571190}
1191
[email protected]604322d2011-03-22 16:51:561192// Test that external extensions with incorrect IDs are not installed.
1193TEST_F(ExtensionServiceTest, FailOnWrongId) {
1194 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351195 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]604322d2011-03-22 16:51:561196 set_extensions_enabled(true);
1197
1198 scoped_ptr<Version> version;
1199 version.reset(Version::GetVersionFromString("1.0.0.0"));
1200
1201 const std::string wrong_id = all_zero;
1202 const std::string correct_id = good_crx;
1203 ASSERT_NE(correct_id, wrong_id);
1204
1205 // Install an external extension with an ID from the external
1206 // source that is not equal to the ID in the extension manifest.
1207 service_->OnExternalExtensionFileFound(
1208 wrong_id, version.get(), path, Extension::EXTERNAL_PREF);
1209
1210 loop_.RunAllPending();
1211 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1212
1213 // Try again with the right ID. Expect success.
1214 service_->OnExternalExtensionFileFound(
1215 correct_id, version.get(), path, Extension::EXTERNAL_PREF);
1216 loop_.RunAllPending();
1217 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1218}
1219
1220// Test that external extensions with incorrect versions are not installed.
1221TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1222 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351223 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]604322d2011-03-22 16:51:561224 set_extensions_enabled(true);
1225
1226 // Install an external extension with a version from the external
1227 // source that is not equal to the version in the extension manifest.
1228 scoped_ptr<Version> wrong_version;
1229 wrong_version.reset(Version::GetVersionFromString("1.2.3.4"));
1230 service_->OnExternalExtensionFileFound(
1231 good_crx, wrong_version.get(), path, Extension::EXTERNAL_PREF);
1232
1233 loop_.RunAllPending();
1234 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1235
1236 // Try again with the right version. Expect success.
1237 scoped_ptr<Version> correct_version;
1238 correct_version.reset(Version::GetVersionFromString("1.0.0.0"));
1239 service_->OnExternalExtensionFileFound(
1240 good_crx, correct_version.get(), path, Extension::EXTERNAL_PREF);
1241 loop_.RunAllPending();
1242 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1243}
1244
[email protected]da0aa3b2009-12-06 21:41:031245// Install a user script (they get converted automatically to an extension)
[email protected]eaa7dd182010-12-14 11:09:001246TEST_F(ExtensionServiceTest, InstallUserScript) {
[email protected]da0aa3b2009-12-06 21:41:031247 // The details of script conversion are tested elsewhere, this just tests
[email protected]eaa7dd182010-12-14 11:09:001248 // integration with ExtensionService.
1249 InitializeEmptyExtensionService();
[email protected]da0aa3b2009-12-06 21:41:031250
[email protected]e85e34c32011-04-13 18:38:351251 FilePath path = data_dir_
[email protected]da0aa3b2009-12-06 21:41:031252 .AppendASCII("user_script_basic.user.js");
1253
1254 ASSERT_TRUE(file_util::PathExists(path));
[email protected]14908b72011-04-20 06:54:361255 // Pass NULL to install silently.
1256 scoped_refptr<CrxInstaller> installer(service_->MakeCrxInstaller(NULL));
[email protected]6dfbbf82010-03-12 23:09:161257 installer->InstallUserScript(
[email protected]da0aa3b2009-12-06 21:41:031258 path,
[email protected]6dfbbf82010-03-12 23:09:161259 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
[email protected]da0aa3b2009-12-06 21:41:031260
1261 loop_.RunAllPending();
1262 std::vector<std::string> errors = GetErrors();
1263 EXPECT_TRUE(installed_) << "Nothing was installed.";
1264 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1265 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1266 << JoinString(errors, ',');
1267 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
1268 path.value();
1269
1270 installed_ = NULL;
1271 loaded_.clear();
1272 ExtensionErrorReporter::GetInstance()->ClearErrors();
1273}
1274
[email protected]8d888c12010-11-30 00:00:251275// This tests that the granted permissions preferences are correctly set when
1276// installing an extension.
[email protected]eaa7dd182010-12-14 11:09:001277TEST_F(ExtensionServiceTest, GrantedPermissions) {
1278 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351279 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251280 .AppendASCII("permissions");
1281
[email protected]e85e34c32011-04-13 18:38:351282 FilePath pem_path = path.AppendASCII("unknown.pem");
[email protected]8d888c12010-11-30 00:00:251283 path = path.AppendASCII("unknown");
1284
1285 ASSERT_TRUE(file_util::PathExists(pem_path));
1286 ASSERT_TRUE(file_util::PathExists(path));
1287
1288 ExtensionPrefs* prefs = service_->extension_prefs();
1289
1290 std::set<std::string> expected_api_perms;
1291 std::set<std::string> known_api_perms;
1292 bool full_access;
1293 ExtensionExtent expected_host_perms;
1294 ExtensionExtent known_host_perms;
1295
1296 // Make sure there aren't any granted permissions before the
1297 // extension is installed.
1298 EXPECT_FALSE(prefs->GetGrantedPermissions(
1299 permissions_crx, &full_access, &known_api_perms, &known_host_perms));
1300 EXPECT_TRUE(known_api_perms.empty());
1301 EXPECT_TRUE(known_host_perms.is_empty());
1302
[email protected]145a317b2011-04-12 16:03:461303 PackAndInstallCrx(path, pem_path, true);
[email protected]8d888c12010-11-30 00:00:251304
1305 EXPECT_EQ(0u, GetErrors().size());
1306 ASSERT_EQ(1u, service_->extensions()->size());
1307 std::string extension_id = service_->extensions()->at(0)->id();
1308 EXPECT_EQ(permissions_crx, extension_id);
1309
1310
1311 // Verify that the valid API permissions have been recognized.
1312 expected_api_perms.insert("tabs");
1313
1314 AddPattern(&expected_host_perms, "http://*.google.com/*");
1315 AddPattern(&expected_host_perms, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151316 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251317 AddPattern(&expected_host_perms, "http://www.example.com/*");
1318
1319 EXPECT_TRUE(prefs->GetGrantedPermissions(extension_id,
1320 &full_access,
1321 &known_api_perms,
1322 &known_host_perms));
1323
1324 EXPECT_EQ(expected_api_perms, known_api_perms);
1325 EXPECT_FALSE(full_access);
1326 AssertEqualExtents(&expected_host_perms, &known_host_perms);
1327}
1328
1329#if !defined(OS_CHROMEOS)
1330// Tests that the granted permissions full_access bit gets set correctly when
1331// an extension contains an NPAPI plugin. Don't run this test on Chrome OS
1332// since they don't support plugins.
[email protected]eaa7dd182010-12-14 11:09:001333TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1334 InitializeEmptyExtensionService();
[email protected]8d888c12010-11-30 00:00:251335
[email protected]e85e34c32011-04-13 18:38:351336 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251337 .AppendASCII("good")
1338 .AppendASCII("Extensions")
1339 .AppendASCII(good1)
1340 .AppendASCII("2");
1341
1342 ASSERT_TRUE(file_util::PathExists(path));
1343
[email protected]145a317b2011-04-12 16:03:461344 PackAndInstallCrx(path, true);
[email protected]8d888c12010-11-30 00:00:251345
1346 EXPECT_EQ(0u, GetErrors().size());
1347 EXPECT_EQ(1u, service_->extensions()->size());
1348 const Extension* extension = service_->extensions()->at(0);
1349 std::string extension_id = extension->id();
1350 ExtensionPrefs* prefs = service_->extension_prefs();
1351
1352 bool full_access;
1353 std::set<std::string> api_permissions;
1354 ExtensionExtent host_permissions;
1355 EXPECT_TRUE(prefs->GetGrantedPermissions(
1356 extension_id, &full_access, &api_permissions, &host_permissions));
1357
1358 EXPECT_TRUE(full_access);
1359 EXPECT_TRUE(api_permissions.empty());
1360 EXPECT_TRUE(host_permissions.is_empty());
1361}
1362#endif
1363
1364// Tests that the extension is disabled when permissions are missing from
1365// the extension's granted permissions preferences. (This simulates updating
1366// the browser to a version which recognizes more permissions).
[email protected]eaa7dd182010-12-14 11:09:001367TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1368 InitializeEmptyExtensionService();
[email protected]8d888c12010-11-30 00:00:251369
[email protected]e85e34c32011-04-13 18:38:351370 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251371 .AppendASCII("permissions")
1372 .AppendASCII("unknown");
1373
1374 ASSERT_TRUE(file_util::PathExists(path));
1375
[email protected]145a317b2011-04-12 16:03:461376 PackAndInstallCrx(path, true);
[email protected]8d888c12010-11-30 00:00:251377
1378 EXPECT_EQ(0u, GetErrors().size());
1379 EXPECT_EQ(1u, service_->extensions()->size());
1380 const Extension* extension = service_->extensions()->at(0);
1381 std::string extension_id = extension->id();
1382
1383 ExtensionPrefs* prefs = service_->extension_prefs();
1384
1385 std::set<std::string> expected_api_permissions;
1386 ExtensionExtent expected_host_permissions;
1387
1388 expected_api_permissions.insert("tabs");
1389 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1390 AddPattern(&expected_host_permissions, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151391 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251392 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1393
1394 std::set<std::string> api_permissions;
1395 std::set<std::string> host_permissions;
1396
1397 // Test that the extension is disabled when an API permission is missing from
1398 // the extension's granted api permissions preference. (This simulates
1399 // updating the browser to a version which recognizes a new API permission).
1400 SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions);
1401
1402 service_->ReloadExtensions();
1403
1404 EXPECT_EQ(1u, service_->disabled_extensions()->size());
1405 extension = service_->disabled_extensions()->at(0);
1406
1407 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED);
1408 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1409
1410 // Now grant and re-enable the extension, making sure the prefs are updated.
1411 service_->GrantPermissionsAndEnableExtension(extension);
1412
1413 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1414 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1415
1416 std::set<std::string> current_api_permissions;
1417 ExtensionExtent current_host_permissions;
1418 bool current_full_access;
1419
1420 ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1421 &current_full_access,
1422 &current_api_permissions,
1423 &current_host_permissions));
1424
1425 ASSERT_FALSE(current_full_access);
1426 ASSERT_EQ(expected_api_permissions, current_api_permissions);
1427 AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1428
1429 // Tests that the extension is disabled when a host permission is missing from
1430 // the extension's granted host permissions preference. (This simulates
1431 // updating the browser to a version which recognizes additional host
1432 // permissions).
1433 api_permissions.clear();
1434 host_permissions.clear();
1435 current_api_permissions.clear();
1436 current_host_permissions.ClearPaths();
1437
1438 api_permissions.insert("tabs");
1439 host_permissions.insert("http://*.google.com/*");
1440 host_permissions.insert("https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151441 host_permissions.insert("http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251442
1443 SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions);
1444 SetPrefStringSet(extension_id, "granted_permissions.host", host_permissions);
1445
1446 service_->ReloadExtensions();
1447
1448 EXPECT_EQ(1u, service_->disabled_extensions()->size());
1449 extension = service_->disabled_extensions()->at(0);
1450
1451 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED);
1452 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1453
1454 // Now grant and re-enable the extension, making sure the prefs are updated.
1455 service_->GrantPermissionsAndEnableExtension(extension);
1456
1457 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1458 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1459
1460 ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1461 &current_full_access,
1462 &current_api_permissions,
1463 &current_host_permissions));
1464
1465 ASSERT_FALSE(current_full_access);
1466 ASSERT_EQ(expected_api_permissions, current_api_permissions);
1467 AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1468
1469 // Tests that the granted permissions preferences are initialized when
1470 // migrating from the old pref schema.
1471 current_api_permissions.clear();
1472 current_host_permissions.ClearPaths();
1473
1474 ClearPref(extension_id, "granted_permissions");
1475
1476 service_->ReloadExtensions();
1477
1478 EXPECT_EQ(1u, service_->extensions()->size());
1479 extension = service_->extensions()->at(0);
1480
1481 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1482 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1483
1484 ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1485 &current_full_access,
1486 &current_api_permissions,
1487 &current_host_permissions));
1488
1489 ASSERT_FALSE(current_full_access);
1490 ASSERT_EQ(expected_api_permissions, current_api_permissions);
1491 AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1492}
1493
[email protected]a17f9462009-06-09 02:56:411494// Test Packaging and installing an extension.
[email protected]eaa7dd182010-12-14 11:09:001495TEST_F(ExtensionServiceTest, PackExtension) {
1496 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351497 FilePath input_directory = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231498 .AppendASCII("good")
1499 .AppendASCII("Extensions")
1500 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1501 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:411502
[email protected]aca3e9b2009-11-03 01:14:211503 ScopedTempDir temp_dir;
1504 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1505 FilePath output_directory = temp_dir.path();
1506
[email protected]a17f9462009-06-09 02:56:411507 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1508 FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
1509
1510 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1511 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
1512 privkey_path));
1513
[email protected]a17f9462009-06-09 02:56:411514 ASSERT_TRUE(file_util::PathExists(privkey_path));
[email protected]145a317b2011-04-12 16:03:461515 InstallCrx(crx_path, true);
[email protected]0dc2ca82009-11-17 07:06:161516
1517 // Try packing with invalid paths.
1518 creator.reset(new ExtensionCreator());
1519 ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath()));
1520
1521 // Try packing an empty directory. Should fail because an empty directory is
1522 // not a valid extension.
1523 ScopedTempDir temp_dir2;
1524 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
1525 creator.reset(new ExtensionCreator());
1526 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
1527 FilePath()));
1528
1529 // Try packing with an invalid manifest.
1530 std::string invalid_manifest_content = "I am not a manifest.";
1531 ASSERT_TRUE(file_util::WriteFile(
[email protected]99efb7b12009-12-18 02:39:161532 temp_dir2.path().Append(Extension::kManifestFilename),
[email protected]0dc2ca82009-11-17 07:06:161533 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
1534 creator.reset(new ExtensionCreator());
1535 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
1536 FilePath()));
[email protected]a17f9462009-06-09 02:56:411537}
1538
[email protected]0349ab5d2010-08-11 21:41:571539// Test Packaging and installing an extension whose name contains punctuation.
[email protected]eaa7dd182010-12-14 11:09:001540TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
1541 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351542 FilePath input_directory = data_dir_
[email protected]0349ab5d2010-08-11 21:41:571543 .AppendASCII("good")
1544 .AppendASCII("Extensions")
1545 .AppendASCII(good0)
1546 .AppendASCII("1.0.0.0");
1547
1548 ScopedTempDir temp_dir;
1549 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1550
1551 // Extension names containing punctuation, and the expected names for the
1552 // packed extensions.
1553 const FilePath punctuated_names[] = {
1554 FilePath(FilePath::StringType(
1555 FILE_PATH_LITERAL("this.extensions.name.has.periods"))),
1556 FilePath(FilePath::StringType(
1557 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod"))),
1558 NormalizeSeparators(FilePath(FilePath::StringType(
1559 FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")))),
1560 };
1561 const FilePath expected_crx_names[] = {
1562 FilePath(FilePath::StringType(
1563 FILE_PATH_LITERAL("this.extensions.name.has.periods.crx"))),
1564 FilePath(FilePath::StringType(
1565 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx"))),
1566 FilePath(FilePath::StringType(
1567 FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx"))),
1568 };
1569 const FilePath expected_private_key_names[] = {
1570 FilePath(FilePath::StringType(
1571 FILE_PATH_LITERAL("this.extensions.name.has.periods.pem"))),
1572 FilePath(FilePath::StringType(
1573 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem"))),
1574 FilePath(FilePath::StringType(
1575 FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem"))),
1576 };
1577
1578 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
1579 SCOPED_TRACE(punctuated_names[i].value().c_str());
1580 FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
1581
1582 // Copy the extension into the output directory, as PackExtensionJob doesn't
1583 // let us choose where to output the packed extension.
1584 ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true));
1585
1586 FilePath expected_crx_path = temp_dir.path().Append(expected_crx_names[i]);
1587 FilePath expected_private_key_path =
1588 temp_dir.path().Append(expected_private_key_names[i]);
1589 PackExtensionTestClient pack_client(expected_crx_path,
1590 expected_private_key_path);
1591 scoped_refptr<PackExtensionJob> packer(new PackExtensionJob(&pack_client,
1592 output_dir,
1593 FilePath()));
1594 packer->Start();
1595
1596 // The packer will post a notification task to the current thread's message
1597 // loop when it is finished. We manually run the loop here so that we
1598 // block and catch the notification; otherwise, the process would exit.
1599 // This call to |Run()| is matched by a call to |Quit()| in the
1600 // |PackExtensionTestClient|'s notification handling code.
1601 MessageLoop::current()->Run();
1602
1603 if (HasFatalFailure())
1604 return;
1605
[email protected]145a317b2011-04-12 16:03:461606 InstallCrx(expected_crx_path, true);
[email protected]0349ab5d2010-08-11 21:41:571607 }
1608}
1609
[email protected]a17f9462009-06-09 02:56:411610// Test Packaging and installing an extension using an openssl generated key.
1611// The openssl is generated with the following:
[email protected]a1257b12009-06-12 02:51:341612// > openssl genrsa -out privkey.pem 1024
[email protected]df4956e2009-06-10 16:53:421613// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
[email protected]a1257b12009-06-12 02:51:341614// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
[email protected]a17f9462009-06-09 02:56:411615// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
[email protected]eaa7dd182010-12-14 11:09:001616TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
1617 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351618 FilePath input_directory = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231619 .AppendASCII("good")
1620 .AppendASCII("Extensions")
1621 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1622 .AppendASCII("1.0.0.0");
[email protected]e85e34c32011-04-13 18:38:351623 FilePath privkey_path(data_dir_.AppendASCII(
[email protected]a17f9462009-06-09 02:56:411624 "openssl_privkey_asn1.pem"));
1625 ASSERT_TRUE(file_util::PathExists(privkey_path));
1626
[email protected]aca3e9b2009-11-03 01:14:211627 ScopedTempDir temp_dir;
1628 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1629 FilePath output_directory = temp_dir.path();
1630
[email protected]a17f9462009-06-09 02:56:411631 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1632
1633 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1634 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
1635 FilePath()));
1636
[email protected]145a317b2011-04-12 16:03:461637 InstallCrx(crx_path, true);
[email protected]a17f9462009-06-09 02:56:411638}
[email protected]a17f9462009-06-09 02:56:411639
[email protected]eaa7dd182010-12-14 11:09:001640TEST_F(ExtensionServiceTest, InstallTheme) {
1641 InitializeEmptyExtensionService();
[email protected]e2eb43112009-05-29 21:19:541642
1643 // A theme.
[email protected]e85e34c32011-04-13 18:38:351644 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]145a317b2011-04-12 16:03:461645 InstallCrx(path, true);
[email protected]25b34332009-06-05 21:53:191646 int pref_count = 0;
1647 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341648 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
1649 ValidateIntegerPref(theme_crx, "location", Extension::INTERNAL);
[email protected]e2eb43112009-05-29 21:19:541650
[email protected]6ef635e42009-07-26 06:16:121651 // A theme when extensions are disabled. Themes can be installed, even when
1652 // extensions are disabled.
[email protected]7577a5c52009-07-30 06:21:581653 set_extensions_enabled(false);
[email protected]e85e34c32011-04-13 18:38:351654 path = data_dir_.AppendASCII("theme2.crx");
[email protected]145a317b2011-04-12 16:03:461655 InstallCrx(path, true);
[email protected]25b34332009-06-05 21:53:191656 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341657 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
1658 ValidateIntegerPref(theme2_crx, "location", Extension::INTERNAL);
[email protected]494c06e2009-07-25 01:06:421659
[email protected]25b34332009-06-05 21:53:191660 // A theme with extension elements. Themes cannot have extension elements so
1661 // this test should fail.
[email protected]7577a5c52009-07-30 06:21:581662 set_extensions_enabled(true);
[email protected]e85e34c32011-04-13 18:38:351663 path = data_dir_.AppendASCII("theme_with_extension.crx");
[email protected]145a317b2011-04-12 16:03:461664 InstallCrx(path, false);
[email protected]25b34332009-06-05 21:53:191665 ValidatePrefKeyCount(pref_count);
[email protected]12198912009-06-05 03:41:221666
1667 // A theme with image resources missing (misspelt path).
[email protected]e85e34c32011-04-13 18:38:351668 path = data_dir_.AppendASCII("theme_missing_image.crx");
[email protected]145a317b2011-04-12 16:03:461669 InstallCrx(path, false);
[email protected]25b34332009-06-05 21:53:191670 ValidatePrefKeyCount(pref_count);
[email protected]e2eb43112009-05-29 21:19:541671}
1672
[email protected]eaa7dd182010-12-14 11:09:001673TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
[email protected]584245e52010-06-17 01:08:131674 // Load.
[email protected]eaa7dd182010-12-14 11:09:001675 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351676 FilePath extension_path = data_dir_
[email protected]584245e52010-06-17 01:08:131677 .AppendASCII("theme_i18n");
1678
1679 service_->LoadExtension(extension_path);
1680 loop_.RunAllPending();
1681 EXPECT_EQ(0u, GetErrors().size());
1682 ASSERT_EQ(1u, loaded_.size());
1683 EXPECT_EQ(1u, service_->extensions()->size());
1684 EXPECT_EQ("name", service_->extensions()->at(0)->name());
1685 EXPECT_EQ("description", service_->extensions()->at(0)->description());
1686}
1687
[email protected]eaa7dd182010-12-14 11:09:001688TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
1689 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351690 FilePath theme_path = data_dir_
[email protected]584245e52010-06-17 01:08:131691 .AppendASCII("theme_i18n");
1692
[email protected]145a317b2011-04-12 16:03:461693 PackAndInstallCrx(theme_path, true);
[email protected]584245e52010-06-17 01:08:131694
[email protected]584245e52010-06-17 01:08:131695 EXPECT_EQ(0u, GetErrors().size());
1696 EXPECT_EQ(1u, service_->extensions()->size());
1697 EXPECT_EQ("name", service_->extensions()->at(0)->name());
1698 EXPECT_EQ("description", service_->extensions()->at(0)->description());
1699}
1700
[email protected]eaa7dd182010-12-14 11:09:001701TEST_F(ExtensionServiceTest, InstallApps) {
1702 InitializeEmptyExtensionService();
[email protected]6d2e60bd2010-06-03 22:37:391703
1704 // An empty app.
[email protected]e85e34c32011-04-13 18:38:351705 PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
[email protected]6d2e60bd2010-06-03 22:37:391706 int pref_count = 0;
1707 ValidatePrefKeyCount(++pref_count);
[email protected]3ba0fd32010-06-19 05:39:101708 ASSERT_EQ(1u, service_->extensions()->size());
1709 std::string id = service_->extensions()->at(0)->id();
[email protected]e2194742010-08-12 05:54:341710 ValidateIntegerPref(id, "state", Extension::ENABLED);
1711 ValidateIntegerPref(id, "location", Extension::INTERNAL);
[email protected]6d2e60bd2010-06-03 22:37:391712
1713 // Another app with non-overlapping extent. Should succeed.
[email protected]e85e34c32011-04-13 18:38:351714 PackAndInstallCrx(data_dir_.AppendASCII("app2"), true);
[email protected]6d2e60bd2010-06-03 22:37:391715 ValidatePrefKeyCount(++pref_count);
1716
1717 // A third app whose extent overlaps the first. Should fail.
[email protected]e85e34c32011-04-13 18:38:351718 PackAndInstallCrx(data_dir_.AppendASCII("app3"), false);
[email protected]cd10e282010-10-26 21:04:511719 ValidatePrefKeyCount(pref_count);
[email protected]6d2e60bd2010-06-03 22:37:391720}
1721
[email protected]15300d92011-01-19 18:44:301722TEST_F(ExtensionServiceTest, UpdateApps) {
1723 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351724 FilePath extensions_path = data_dir_.AppendASCII("app_update");
[email protected]15300d92011-01-19 18:44:301725
1726 // First install v1 of a hosted app.
[email protected]145a317b2011-04-12 16:03:461727 InstallCrx(extensions_path.AppendASCII("v1.crx"), true);
[email protected]15300d92011-01-19 18:44:301728 ASSERT_EQ(1u, service_->extensions()->size());
1729 std::string id = service_->extensions()->at(0)->id();
1730 ASSERT_EQ(std::string("1"),
1731 service_->extensions()->at(0)->version()->GetString());
1732
1733 // Now try updating to v2.
1734 UpdateExtension(id,
1735 extensions_path.AppendASCII("v2.crx"),
1736 ENABLED);
1737 ASSERT_EQ(std::string("2"),
1738 service_->extensions()->at(0)->version()->GetString());
1739}
1740
[email protected]eaa7dd182010-12-14 11:09:001741TEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) {
1742 InitializeEmptyExtensionService();
[email protected]c2c263c2010-08-13 21:59:481743 EXPECT_TRUE(service_->extensions()->empty());
[email protected]c2c263c2010-08-13 21:59:481744
[email protected]c2c263c2010-08-13 21:59:481745 int pref_count = 0;
[email protected]c2c263c2010-08-13 21:59:481746
1747 // Install app1 with unlimited storage.
[email protected]e85e34c32011-04-13 18:38:351748 PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
[email protected]c2c263c2010-08-13 21:59:481749 ValidatePrefKeyCount(++pref_count);
1750 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]9adb9692010-10-29 23:14:021751 const Extension* extension = service_->extensions()->at(0);
[email protected]c2c263c2010-08-13 21:59:481752 const std::string id1 = extension->id();
1753 EXPECT_TRUE(extension->HasApiPermission(
1754 Extension::kUnlimitedStoragePermission));
1755 EXPECT_TRUE(extension->web_extent().ContainsURL(
1756 extension->GetFullLaunchURL()));
1757 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
[email protected]19eb80152011-02-26 00:28:431758 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1759 IsStorageUnlimited(origin1));
[email protected]c2c263c2010-08-13 21:59:481760
1761 // Install app2 from the same origin with unlimited storage.
[email protected]e85e34c32011-04-13 18:38:351762 PackAndInstallCrx(data_dir_.AppendASCII("app2"), true);
[email protected]c2c263c2010-08-13 21:59:481763 ValidatePrefKeyCount(++pref_count);
1764 ASSERT_EQ(2u, service_->extensions()->size());
1765 extension = service_->extensions()->at(1);
1766 const std::string id2 = extension->id();
1767 EXPECT_TRUE(extension->HasApiPermission(
1768 Extension::kUnlimitedStoragePermission));
1769 EXPECT_TRUE(extension->web_extent().ContainsURL(
1770 extension->GetFullLaunchURL()));
1771 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
1772 EXPECT_EQ(origin1, origin2);
[email protected]19eb80152011-02-26 00:28:431773 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1774 IsStorageUnlimited(origin2));
1775
[email protected]c2c263c2010-08-13 21:59:481776
1777 // Uninstall one of them, unlimited storage should still be granted
1778 // to the origin.
[email protected]d6ebc9792011-04-07 18:18:331779 service_->UninstallExtension(id1, false, NULL);
[email protected]c2c263c2010-08-13 21:59:481780 loop_.RunAllPending();
1781 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]19eb80152011-02-26 00:28:431782 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1783 IsStorageUnlimited(origin1));
1784
[email protected]c2c263c2010-08-13 21:59:481785
1786 // Uninstall the other, unlimited storage should be revoked.
[email protected]d6ebc9792011-04-07 18:18:331787 service_->UninstallExtension(id2, false, NULL);
[email protected]c2c263c2010-08-13 21:59:481788 loop_.RunAllPending();
1789 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]19eb80152011-02-26 00:28:431790 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1791 IsStorageUnlimited(origin2));
[email protected]c2c263c2010-08-13 21:59:481792}
1793
[email protected]eaa7dd182010-12-14 11:09:001794TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
1795 InitializeEmptyExtensionService();
[email protected]654512b2010-09-01 02:09:421796 EXPECT_TRUE(service_->extensions()->empty());
[email protected]654512b2010-09-01 02:09:421797
[email protected]654512b2010-09-01 02:09:421798 int pref_count = 0;
1799
[email protected]e85e34c32011-04-13 18:38:351800 PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
[email protected]654512b2010-09-01 02:09:421801 ValidatePrefKeyCount(++pref_count);
1802 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]9adb9692010-10-29 23:14:021803 const Extension* extension = service_->extensions()->at(0);
[email protected]654512b2010-09-01 02:09:421804 EXPECT_TRUE(extension->is_app());
1805 const std::string id1 = extension->id();
[email protected]654512b2010-09-01 02:09:421806 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
[email protected]19eb80152011-02-26 00:28:431807 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1808 IsStorageProtected(origin1));
[email protected]654512b2010-09-01 02:09:421809
1810 // App 4 has a different origin (maps.google.com).
[email protected]e85e34c32011-04-13 18:38:351811 PackAndInstallCrx(data_dir_.AppendASCII("app4"), true);
[email protected]654512b2010-09-01 02:09:421812 ValidatePrefKeyCount(++pref_count);
1813 ASSERT_EQ(2u, service_->extensions()->size());
1814 extension = service_->extensions()->at(1);
1815 const std::string id2 = extension->id();
[email protected]654512b2010-09-01 02:09:421816 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
1817 ASSERT_NE(origin1, origin2);
[email protected]19eb80152011-02-26 00:28:431818 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1819 IsStorageProtected(origin2));
[email protected]654512b2010-09-01 02:09:421820
[email protected]d6ebc9792011-04-07 18:18:331821 service_->UninstallExtension(id1, false, NULL);
[email protected]654512b2010-09-01 02:09:421822 loop_.RunAllPending();
1823 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]654512b2010-09-01 02:09:421824
[email protected]d6ebc9792011-04-07 18:18:331825 service_->UninstallExtension(id2, false, NULL);
[email protected]654512b2010-09-01 02:09:421826 loop_.RunAllPending();
1827
1828 EXPECT_TRUE(service_->extensions()->empty());
[email protected]19eb80152011-02-26 00:28:431829 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1830 IsStorageProtected(origin1));
1831 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1832 IsStorageProtected(origin2));
[email protected]654512b2010-09-01 02:09:421833}
1834
[email protected]894bb502009-05-21 22:39:571835// Test that when an extension version is reinstalled, nothing happens.
[email protected]eaa7dd182010-12-14 11:09:001836TEST_F(ExtensionServiceTest, Reinstall) {
1837 InitializeEmptyExtensionService();
[email protected]894bb502009-05-21 22:39:571838
1839 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:351840 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]53da2c962011-03-03 17:08:051841 StartCrxInstall(path);
[email protected]894bb502009-05-21 22:39:571842 loop_.RunAllPending();
1843
1844 ASSERT_TRUE(installed_);
1845 ASSERT_EQ(1u, loaded_.size());
1846 ASSERT_EQ(0u, GetErrors().size());
[email protected]25b34332009-06-05 21:53:191847 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:341848 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1849 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:571850
1851 installed_ = NULL;
1852 loaded_.clear();
1853 ExtensionErrorReporter::GetInstance()->ClearErrors();
1854
[email protected]ca3dbf52010-05-19 22:27:061855 // Reinstall the same version, it should overwrite the previous one.
[email protected]53da2c962011-03-03 17:08:051856 StartCrxInstall(path);
[email protected]894bb502009-05-21 22:39:571857 loop_.RunAllPending();
1858
[email protected]ca3dbf52010-05-19 22:27:061859 ASSERT_TRUE(installed_);
1860 ASSERT_EQ(1u, loaded_.size());
[email protected]894bb502009-05-21 22:39:571861 ASSERT_EQ(0u, GetErrors().size());
[email protected]25b34332009-06-05 21:53:191862 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:341863 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1864 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:571865}
1866
[email protected]fbcc40302009-06-12 20:45:451867// Test upgrading a signed extension.
[email protected]eaa7dd182010-12-14 11:09:001868TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
1869 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:451870
[email protected]e85e34c32011-04-13 18:38:351871 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]53da2c962011-03-03 17:08:051872 StartCrxInstall(path);
[email protected]fbcc40302009-06-12 20:45:451873 loop_.RunAllPending();
1874
1875 ASSERT_TRUE(installed_);
1876 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:321877 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:451878 ASSERT_EQ(0u, GetErrors().size());
1879
1880 // Upgrade to version 2.0
[email protected]e85e34c32011-04-13 18:38:351881 path = data_dir_.AppendASCII("good2.crx");
[email protected]53da2c962011-03-03 17:08:051882 StartCrxInstall(path);
[email protected]fbcc40302009-06-12 20:45:451883 loop_.RunAllPending();
1884
1885 ASSERT_TRUE(installed_);
[email protected]9f1087e2009-06-15 17:29:321886 ASSERT_EQ(1u, loaded_.size());
1887 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:451888 ASSERT_EQ(0u, GetErrors().size());
1889}
1890
1891// Test upgrading a signed extension with a bad signature.
[email protected]eaa7dd182010-12-14 11:09:001892TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
1893 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:451894
[email protected]e85e34c32011-04-13 18:38:351895 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]53da2c962011-03-03 17:08:051896 StartCrxInstall(path);
[email protected]fbcc40302009-06-12 20:45:451897 loop_.RunAllPending();
1898
1899 ASSERT_TRUE(installed_);
1900 ASSERT_EQ(1u, loaded_.size());
1901 ASSERT_EQ(0u, GetErrors().size());
1902 installed_ = NULL;
1903
1904 // Try upgrading with a bad signature. This should fail during the unpack,
1905 // because the key will not match the signature.
[email protected]e85e34c32011-04-13 18:38:351906 path = data_dir_.AppendASCII("bad_signature.crx");
[email protected]53da2c962011-03-03 17:08:051907 StartCrxInstall(path);
[email protected]fbcc40302009-06-12 20:45:451908 loop_.RunAllPending();
1909
1910 ASSERT_FALSE(installed_);
1911 ASSERT_EQ(1u, loaded_.size());
1912 ASSERT_EQ(1u, GetErrors().size());
1913}
1914
[email protected]e957fe52009-06-23 16:51:051915// Test a normal update via the UpdateExtension API
[email protected]eaa7dd182010-12-14 11:09:001916TEST_F(ExtensionServiceTest, UpdateExtension) {
1917 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:051918
[email protected]e85e34c32011-04-13 18:38:351919 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:051920
[email protected]145a317b2011-04-12 16:03:461921 InstallCrx(path, true);
[email protected]9adb9692010-10-29 23:14:021922 const Extension* good = service_->extensions()->at(0);
[email protected]e957fe52009-06-23 16:51:051923 ASSERT_EQ("1.0.0.0", good->VersionString());
1924 ASSERT_EQ(good_crx, good->id());
1925
[email protected]e85e34c32011-04-13 18:38:351926 path = data_dir_.AppendASCII("good2.crx");
[email protected]4416c5a2010-06-26 01:28:571927 UpdateExtension(good_crx, path, ENABLED);
[email protected]e957fe52009-06-23 16:51:051928 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
1929}
1930
1931// Test updating a not-already-installed extension - this should fail
[email protected]eaa7dd182010-12-14 11:09:001932TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
1933 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:051934
[email protected]e85e34c32011-04-13 18:38:351935 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:571936 UpdateExtension(good_crx, path, UPDATED);
[email protected]e957fe52009-06-23 16:51:051937 loop_.RunAllPending();
1938
1939 ASSERT_EQ(0u, service_->extensions()->size());
1940 ASSERT_FALSE(installed_);
1941 ASSERT_EQ(0u, loaded_.size());
1942}
1943
1944// Makes sure you can't downgrade an extension via UpdateExtension
[email protected]eaa7dd182010-12-14 11:09:001945TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
1946 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:051947
[email protected]e85e34c32011-04-13 18:38:351948 FilePath path = data_dir_.AppendASCII("good2.crx");
[email protected]e957fe52009-06-23 16:51:051949
[email protected]145a317b2011-04-12 16:03:461950 InstallCrx(path, true);
[email protected]9adb9692010-10-29 23:14:021951 const Extension* good = service_->extensions()->at(0);
[email protected]e957fe52009-06-23 16:51:051952 ASSERT_EQ("1.0.0.1", good->VersionString());
1953 ASSERT_EQ(good_crx, good->id());
1954
1955 // Change path from good2.crx -> good.crx
[email protected]e85e34c32011-04-13 18:38:351956 path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:571957 UpdateExtension(good_crx, path, FAILED);
[email protected]e957fe52009-06-23 16:51:051958 ASSERT_EQ("1.0.0.1", service_->extensions()->at(0)->VersionString());
1959}
1960
1961// Make sure calling update with an identical version does nothing
[email protected]eaa7dd182010-12-14 11:09:001962TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
1963 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:051964
[email protected]e85e34c32011-04-13 18:38:351965 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:051966
[email protected]145a317b2011-04-12 16:03:461967 InstallCrx(path, true);
[email protected]9adb9692010-10-29 23:14:021968 const Extension* good = service_->extensions()->at(0);
[email protected]e957fe52009-06-23 16:51:051969 ASSERT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:571970 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]aa142702010-03-26 01:26:331971}
1972
[email protected]dbec3792010-08-10 00:08:451973// Tests that updating an extension does not clobber old state.
[email protected]eaa7dd182010-12-14 11:09:001974TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
1975 InitializeEmptyExtensionService();
[email protected]dbec3792010-08-10 00:08:451976
[email protected]e85e34c32011-04-13 18:38:351977 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]dbec3792010-08-10 00:08:451978
[email protected]145a317b2011-04-12 16:03:461979 InstallCrx(path, true);
[email protected]9adb9692010-10-29 23:14:021980 const Extension* good = service_->extensions()->at(0);
[email protected]dbec3792010-08-10 00:08:451981 ASSERT_EQ("1.0.0.0", good->VersionString());
1982 ASSERT_EQ(good_crx, good->id());
1983
1984 // Disable it and allow it to run in incognito. These settings should carry
1985 // over to the updated version.
1986 service_->DisableExtension(good->id());
[email protected]c3cfb012011-04-06 22:07:351987 service_->SetIsIncognitoEnabled(good->id(), true);
[email protected]dbec3792010-08-10 00:08:451988
[email protected]e85e34c32011-04-13 18:38:351989 path = data_dir_.AppendASCII("good2.crx");
[email protected]dbec3792010-08-10 00:08:451990 UpdateExtension(good_crx, path, INSTALLED);
1991 ASSERT_EQ(1u, service_->disabled_extensions()->size());
[email protected]9adb9692010-10-29 23:14:021992 const Extension* good2 = service_->disabled_extensions()->at(0);
[email protected]dbec3792010-08-10 00:08:451993 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
[email protected]c3cfb012011-04-06 22:07:351994 EXPECT_TRUE(service_->IsIncognitoEnabled(good2->id()));
[email protected]dbec3792010-08-10 00:08:451995}
1996
[email protected]5eb375e92010-11-26 07:50:411997// Tests that updating preserves extension location.
[email protected]eaa7dd182010-12-14 11:09:001998TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
1999 InitializeEmptyExtensionService();
[email protected]5eb375e92010-11-26 07:50:412000
[email protected]e85e34c32011-04-13 18:38:352001 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]5eb375e92010-11-26 07:50:412002
[email protected]145a317b2011-04-12 16:03:462003 InstallCrx(path, true);
[email protected]5eb375e92010-11-26 07:50:412004 const Extension* good = service_->extensions()->at(0);
2005
2006 ASSERT_EQ("1.0.0.0", good->VersionString());
2007 ASSERT_EQ(good_crx, good->id());
2008
2009 // Simulate non-internal location.
2010 const_cast<Extension*>(good)->location_ = Extension::EXTERNAL_PREF;
2011
[email protected]e85e34c32011-04-13 18:38:352012 path = data_dir_.AppendASCII("good2.crx");
[email protected]5eb375e92010-11-26 07:50:412013 UpdateExtension(good_crx, path, ENABLED);
2014 const Extension* good2 = service_->extensions()->at(0);
2015 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2016 EXPECT_EQ(good2->location(), Extension::EXTERNAL_PREF);
2017}
2018
[email protected]66e26872010-12-03 20:07:252019// Makes sure that LOAD extension types can downgrade.
[email protected]eaa7dd182010-12-14 11:09:002020TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2021 InitializeEmptyExtensionService();
[email protected]66e26872010-12-03 20:07:252022
2023 ScopedTempDir temp;
2024 ASSERT_TRUE(temp.CreateUniqueTempDir());
2025
2026 // We'll write the extension manifest dynamically to a temporary path
2027 // to make it easier to change the version number.
2028 FilePath extension_path = temp.path();
2029 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
2030 ASSERT_FALSE(file_util::PathExists(manifest_path));
2031
2032 // Start with version 2.0.
2033 DictionaryValue manifest;
2034 manifest.SetString("version", "2.0");
2035 manifest.SetString("name", "LOAD Downgrade Test");
2036
2037 JSONFileValueSerializer serializer(manifest_path);
2038 ASSERT_TRUE(serializer.Serialize(manifest));
2039
2040 service_->LoadExtension(extension_path);
2041 loop_.RunAllPending();
2042
2043 EXPECT_EQ(0u, GetErrors().size());
2044 ASSERT_EQ(1u, loaded_.size());
2045 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2046 EXPECT_EQ(1u, service_->extensions()->size());
2047 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2048
2049 // Now set the version number to 1.0, reload the extensions and verify that
2050 // the downgrade was accepted.
2051 manifest.SetString("version", "1.0");
2052 ASSERT_TRUE(serializer.Serialize(manifest));
2053
2054 service_->LoadExtension(extension_path);
2055 loop_.RunAllPending();
2056
2057 EXPECT_EQ(0u, GetErrors().size());
2058 ASSERT_EQ(1u, loaded_.size());
2059 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2060 EXPECT_EQ(1u, service_->extensions()->size());
2061 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2062}
2063
[email protected]7fa19f82010-12-21 19:40:082064namespace {
2065
2066bool IsExtension(const Extension& extension) {
2067 return extension.GetType() == Extension::TYPE_EXTENSION;
2068}
2069
2070} // namespace
2071
[email protected]aa142702010-03-26 01:26:332072// Test adding a pending extension.
[email protected]7fa19f82010-12-21 19:40:082073TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
[email protected]eaa7dd182010-12-14 11:09:002074 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332075
[email protected]145a317b2011-04-12 16:03:462076 const std::string kFakeId(all_zero);
[email protected]aa142702010-03-26 01:26:332077 const GURL kFakeUpdateURL("http:://fake.update/url");
[email protected]aa142702010-03-26 01:26:332078 const bool kFakeInstallSilently(true);
[email protected]4416c5a2010-06-26 01:28:572079 const Extension::State kFakeInitialState(Extension::ENABLED);
2080 const bool kFakeInitialIncognitoEnabled(false);
[email protected]aa142702010-03-26 01:26:332081
[email protected]b2907fd2011-03-25 16:43:372082 service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082083 kFakeId, kFakeUpdateURL, &IsExtension,
2084 kFakeInstallSilently, kFakeInitialState, kFakeInitialIncognitoEnabled);
[email protected]b2907fd2011-03-25 16:43:372085
2086 PendingExtensionInfo pending_extension_info;
2087 ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2088 kFakeId, &pending_extension_info));
2089 EXPECT_EQ(kFakeUpdateURL, pending_extension_info.update_url());
2090 EXPECT_EQ(&IsExtension, pending_extension_info.should_allow_install_);
2091 EXPECT_EQ(kFakeInstallSilently, pending_extension_info.install_silently());
[email protected]aa142702010-03-26 01:26:332092}
2093
[email protected]aa142702010-03-26 01:26:332094namespace {
2095const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2096const char kGoodUpdateURL[] = "http://good.update/url";
[email protected]8ef78fd2010-08-19 17:14:322097const bool kGoodIsFromSync = true;
[email protected]aa142702010-03-26 01:26:332098const bool kGoodInstallSilently = true;
[email protected]4416c5a2010-06-26 01:28:572099const Extension::State kGoodInitialState = Extension::DISABLED;
2100const bool kGoodInitialIncognitoEnabled = true;
[email protected]aa142702010-03-26 01:26:332101} // namespace
2102
2103// Test updating a pending extension.
[email protected]eaa7dd182010-12-14 11:09:002104TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2105 InitializeEmptyExtensionService();
[email protected]b2907fd2011-03-25 16:43:372106 service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082107 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]4416c5a2010-06-26 01:28:572108 kGoodInstallSilently, kGoodInitialState,
2109 kGoodInitialIncognitoEnabled);
[email protected]b2907fd2011-03-25 16:43:372110 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332111
[email protected]e85e34c32011-04-13 18:38:352112 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572113 UpdateExtension(kGoodId, path, INSTALLED);
[email protected]aa142702010-03-26 01:26:332114
[email protected]b2907fd2011-03-25 16:43:372115 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]4416c5a2010-06-26 01:28:572116
[email protected]9adb9692010-10-29 23:14:022117 const Extension* extension = service_->GetExtensionById(kGoodId, true);
[email protected]4416c5a2010-06-26 01:28:572118 ASSERT_TRUE(extension);
2119
2120 bool enabled = service_->GetExtensionById(kGoodId, false);
[email protected]1c51cf72011-02-25 13:39:412121 EXPECT_EQ(enabled, kGoodInitialState == Extension::ENABLED);
[email protected]4416c5a2010-06-26 01:28:572122 EXPECT_EQ(kGoodInitialState,
2123 service_->extension_prefs()->GetExtensionState(extension->id()));
2124 EXPECT_EQ(kGoodInitialIncognitoEnabled,
[email protected]c3cfb012011-04-06 22:07:352125 service_->IsIncognitoEnabled(extension->id()));
[email protected]aa142702010-03-26 01:26:332126}
2127
[email protected]7fa19f82010-12-21 19:40:082128namespace {
2129
2130bool IsTheme(const Extension& extension) {
2131 return extension.is_theme();
2132}
2133
2134} // namespace
2135
[email protected]11edd1e2010-07-21 00:14:502136// Test updating a pending theme.
[email protected]eaa7dd182010-12-14 11:09:002137TEST_F(ExtensionServiceTest, UpdatePendingTheme) {
2138 InitializeEmptyExtensionService();
[email protected]b2907fd2011-03-25 16:43:372139 service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082140 theme_crx, GURL(), &IsTheme,
[email protected]8ef78fd2010-08-19 17:14:322141 false, Extension::ENABLED, false);
[email protected]b2907fd2011-03-25 16:43:372142 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502143
[email protected]e85e34c32011-04-13 18:38:352144 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]11edd1e2010-07-21 00:14:502145 UpdateExtension(theme_crx, path, ENABLED);
2146
[email protected]b2907fd2011-03-25 16:43:372147 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502148
[email protected]9adb9692010-10-29 23:14:022149 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]11edd1e2010-07-21 00:14:502150 ASSERT_TRUE(extension);
2151
2152 EXPECT_EQ(Extension::ENABLED,
2153 service_->extension_prefs()->GetExtensionState(extension->id()));
[email protected]c3cfb012011-04-06 22:07:352154 EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
[email protected]11edd1e2010-07-21 00:14:502155}
2156
[email protected]d74f92e2011-04-18 15:39:232157#if defined(OS_CHROMEOS)
2158// Always fails on ChromeOS: http://crbug.com/79737
2159#define MAYBE_UpdatePendingExternalCrx FAILS_UpdatePendingExternalCrx
2160#else
2161#define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
2162#endif
[email protected]8ef78fd2010-08-19 17:14:322163// Test updating a pending CRX as if the source is an external extension
2164// with an update URL. In this case we don't know if the CRX is a theme
2165// or not.
[email protected]d74f92e2011-04-18 15:39:232166TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
[email protected]eaa7dd182010-12-14 11:09:002167 InitializeEmptyExtensionService();
[email protected]b2907fd2011-03-25 16:43:372168 service_->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]21a5a672010-11-04 10:47:422169 theme_crx, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
[email protected]8ef78fd2010-08-19 17:14:322170
[email protected]b2907fd2011-03-25 16:43:372171 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322172
[email protected]e85e34c32011-04-13 18:38:352173 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:322174 UpdateExtension(theme_crx, path, ENABLED);
2175
[email protected]b2907fd2011-03-25 16:43:372176 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322177
[email protected]9adb9692010-10-29 23:14:022178 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]8ef78fd2010-08-19 17:14:322179 ASSERT_TRUE(extension);
2180
2181 EXPECT_EQ(Extension::ENABLED,
2182 service_->extension_prefs()->GetExtensionState(extension->id()));
[email protected]c3cfb012011-04-06 22:07:352183 EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
[email protected]8ef78fd2010-08-19 17:14:322184}
2185
[email protected]1afaf2a52010-11-02 19:29:172186// Test updating a pending CRX as if the source is an external extension
2187// with an update URL. The external update should overwrite a sync update,
2188// but a sync update should not overwrite a non-sync update.
[email protected]eaa7dd182010-12-14 11:09:002189TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
2190 InitializeEmptyExtensionService();
[email protected]1afaf2a52010-11-02 19:29:172191
2192 // Add a crx to be installed from the update mechanism.
[email protected]b2907fd2011-03-25 16:43:372193 service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082194 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]1afaf2a52010-11-02 19:29:172195 kGoodInstallSilently, kGoodInitialState,
2196 kGoodInitialIncognitoEnabled);
2197
2198 // Check that there is a pending crx, with is_from_sync set to true.
[email protected]b2907fd2011-03-25 16:43:372199 PendingExtensionInfo pending_extension_info;
2200 ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2201 kGoodId, &pending_extension_info));
2202 EXPECT_TRUE(pending_extension_info.is_from_sync());
[email protected]1afaf2a52010-11-02 19:29:172203
2204 // Add a crx to be updated, with the same ID, from a non-sync source.
[email protected]b2907fd2011-03-25 16:43:372205 service_->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]21a5a672010-11-04 10:47:422206 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD);
[email protected]1afaf2a52010-11-02 19:29:172207
2208 // Check that there is a pending crx, with is_from_sync set to false.
[email protected]b2907fd2011-03-25 16:43:372209 ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2210 kGoodId, &pending_extension_info));
2211 EXPECT_FALSE(pending_extension_info.is_from_sync());
2212 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
2213 pending_extension_info.install_source());
[email protected]1afaf2a52010-11-02 19:29:172214
2215 // Add a crx to be installed from the update mechanism.
[email protected]b2907fd2011-03-25 16:43:372216 service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082217 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]1afaf2a52010-11-02 19:29:172218 kGoodInstallSilently, kGoodInitialState,
2219 kGoodInitialIncognitoEnabled);
2220
2221 // Check that the external, non-sync update was not overridden.
[email protected]b2907fd2011-03-25 16:43:372222 ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2223 kGoodId, &pending_extension_info));
2224 EXPECT_FALSE(pending_extension_info.is_from_sync());
2225 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
2226 pending_extension_info.install_source());
[email protected]1afaf2a52010-11-02 19:29:172227}
2228
[email protected]8ef78fd2010-08-19 17:14:322229// Updating a theme should fail if the updater is explicitly told that
2230// the CRX is not a theme.
[email protected]eaa7dd182010-12-14 11:09:002231TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
2232 InitializeEmptyExtensionService();
[email protected]b2907fd2011-03-25 16:43:372233 service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082234 theme_crx, GURL(), &IsExtension,
[email protected]8ef78fd2010-08-19 17:14:322235 true, Extension::ENABLED, false);
2236
[email protected]b2907fd2011-03-25 16:43:372237 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322238
[email protected]e85e34c32011-04-13 18:38:352239 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:322240 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
2241
[email protected]b2907fd2011-03-25 16:43:372242 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322243
[email protected]9adb9692010-10-29 23:14:022244 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]8ef78fd2010-08-19 17:14:322245 ASSERT_FALSE(extension);
2246}
2247
[email protected]aa142702010-03-26 01:26:332248// TODO(akalin): Test updating a pending extension non-silently once
2249// we can mock out ExtensionInstallUI and inject our version into
2250// UpdateExtension().
2251
[email protected]7fa19f82010-12-21 19:40:082252// Test updating a pending extension which fails the should-install test.
2253TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
[email protected]eaa7dd182010-12-14 11:09:002254 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332255 // Add pending extension with a flipped is_theme.
[email protected]b2907fd2011-03-25 16:43:372256 service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082257 kGoodId, GURL(kGoodUpdateURL), &IsTheme,
2258 kGoodInstallSilently, kGoodInitialState,
[email protected]4416c5a2010-06-26 01:28:572259 kGoodInitialIncognitoEnabled);
[email protected]b2907fd2011-03-25 16:43:372260 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332261
[email protected]e85e34c32011-04-13 18:38:352262 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572263 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:332264
2265 // TODO(akalin): Figure out how to check that the extensions
2266 // directory is cleaned up properly in OnExtensionInstalled().
2267
[email protected]b2907fd2011-03-25 16:43:372268 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332269}
2270
[email protected]11edd1e2010-07-21 00:14:502271// TODO(akalin): Figure out how to test that installs of pending
2272// unsyncable extensions are blocked.
2273
[email protected]aa142702010-03-26 01:26:332274// Test updating a pending extension for one that is not pending.
[email protected]eaa7dd182010-12-14 11:09:002275TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
2276 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332277
[email protected]e85e34c32011-04-13 18:38:352278 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572279 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:332280
[email protected]b2907fd2011-03-25 16:43:372281 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332282}
2283
2284// Test updating a pending extension for one that is already
2285// installed.
[email protected]eaa7dd182010-12-14 11:09:002286TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
2287 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332288
[email protected]e85e34c32011-04-13 18:38:352289 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:462290 InstallCrx(path, true);
[email protected]aa142702010-03-26 01:26:332291 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]9adb9692010-10-29 23:14:022292 const Extension* good = service_->extensions()->at(0);
[email protected]aa142702010-03-26 01:26:332293
[email protected]8ef78fd2010-08-19 17:14:322294 EXPECT_FALSE(good->is_theme());
2295
[email protected]b2907fd2011-03-25 16:43:372296 // Use AddExtensionImpl() as AddFrom*() would balk.
2297 service_->pending_extension_manager()->AddExtensionImpl(
[email protected]7fa19f82010-12-21 19:40:082298 good->id(), good->update_url(), &IsExtension,
[email protected]8ef78fd2010-08-19 17:14:322299 kGoodIsFromSync, kGoodInstallSilently, kGoodInitialState,
[email protected]ec5b50d2010-10-09 16:35:182300 kGoodInitialIncognitoEnabled, Extension::INTERNAL);
[email protected]4416c5a2010-06-26 01:28:572301 UpdateExtension(good->id(), path, INSTALLED);
[email protected]aa142702010-03-26 01:26:332302
[email protected]b2907fd2011-03-25 16:43:372303 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]e957fe52009-06-23 16:51:052304}
2305
[email protected]6b75ec32009-08-14 06:37:182306// Test pref settings for blacklist and unblacklist extensions.
[email protected]eaa7dd182010-12-14 11:09:002307TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
2308 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182309 std::vector<std::string> blacklist;
2310 blacklist.push_back(good0);
2311 blacklist.push_back("invalid_id"); // an invalid id
2312 blacklist.push_back(good1);
2313 service_->UpdateExtensionBlacklist(blacklist);
2314 // Make sure pref is updated
2315 loop_.RunAllPending();
2316
2317 // blacklist is set for good0,1,2
[email protected]e2194742010-08-12 05:54:342318 ValidateBooleanPref(good0, "blacklist", true);
2319 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182320 // invalid_id should not be inserted to pref.
[email protected]e2194742010-08-12 05:54:342321 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182322
2323 // remove good1, add good2
2324 blacklist.pop_back();
2325 blacklist.push_back(good2);
2326
2327 service_->UpdateExtensionBlacklist(blacklist);
2328 // only good0 and good1 should be set
[email protected]e2194742010-08-12 05:54:342329 ValidateBooleanPref(good0, "blacklist", true);
2330 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
2331 ValidateBooleanPref(good2, "blacklist", true);
2332 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182333}
2334
2335// Unload installed extension from blacklist.
[email protected]eaa7dd182010-12-14 11:09:002336TEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) {
2337 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182338
[email protected]e85e34c32011-04-13 18:38:352339 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]6b75ec32009-08-14 06:37:182340
[email protected]145a317b2011-04-12 16:03:462341 InstallCrx(path, true);
[email protected]9adb9692010-10-29 23:14:022342 const Extension* good = service_->extensions()->at(0);
[email protected]6b75ec32009-08-14 06:37:182343 EXPECT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:572344 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]6b75ec32009-08-14 06:37:182345
2346 std::vector<std::string> blacklist;
2347 blacklist.push_back(good_crx);
2348 service_->UpdateExtensionBlacklist(blacklist);
2349 // Make sure pref is updated
2350 loop_.RunAllPending();
2351
2352 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:342353 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182354 EXPECT_EQ(0u, service_->extensions()->size());
2355
2356 // Remove good_crx from blacklist
2357 blacklist.pop_back();
2358 service_->UpdateExtensionBlacklist(blacklist);
2359 // Make sure pref is updated
2360 loop_.RunAllPending();
2361 // blacklist value should not be set for good_crx
[email protected]e2194742010-08-12 05:54:342362 EXPECT_FALSE(IsPrefExist(good_crx, "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182363}
2364
2365// Unload installed extension from blacklist.
[email protected]eaa7dd182010-12-14 11:09:002366TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
2367 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182368 std::vector<std::string> blacklist;
2369 blacklist.push_back(good_crx);
2370 service_->UpdateExtensionBlacklist(blacklist);
2371 // Make sure pref is updated
2372 loop_.RunAllPending();
2373
2374 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:342375 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182376
2377 // We can not install good_crx.
[email protected]e85e34c32011-04-13 18:38:352378 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]53da2c962011-03-03 17:08:052379 StartCrxInstall(path);
[email protected]6b75ec32009-08-14 06:37:182380 loop_.RunAllPending();
2381 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]e2194742010-08-12 05:54:342382 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182383}
2384
2385// Test loading extensions from the profile directory, except
2386// blacklisted ones.
[email protected]eaa7dd182010-12-14 11:09:002387TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
[email protected]6b75ec32009-08-14 06:37:182388 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:352389 FilePath source_install_dir = data_dir_
[email protected]6b75ec32009-08-14 06:37:182390 .AppendASCII("good")
2391 .AppendASCII("Extensions");
2392 FilePath pref_path = source_install_dir
2393 .DirName()
2394 .AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:002395 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]6b75ec32009-08-14 06:37:182396
[email protected]e50013c32010-08-18 21:05:242397 // Blacklist good1.
[email protected]6b75ec32009-08-14 06:37:182398 std::vector<std::string> blacklist;
[email protected]e50013c32010-08-18 21:05:242399 blacklist.push_back(good1);
[email protected]6b75ec32009-08-14 06:37:182400 service_->UpdateExtensionBlacklist(blacklist);
2401 // Make sure pref is updated
2402 loop_.RunAllPending();
2403
[email protected]e50013c32010-08-18 21:05:242404 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182405
2406 // Load extensions.
2407 service_->Init();
2408 loop_.RunAllPending();
2409
2410 std::vector<std::string> errors = GetErrors();
2411 for (std::vector<std::string>::iterator err = errors.begin();
2412 err != errors.end(); ++err) {
2413 LOG(ERROR) << *err;
2414 }
[email protected]d7b36dc2009-10-29 21:47:402415 ASSERT_EQ(2u, loaded_.size());
[email protected]6b75ec32009-08-14 06:37:182416
[email protected]e50013c32010-08-18 21:05:242417 EXPECT_NE(std::string(good1), loaded_[0]->id());
2418 EXPECT_NE(std::string(good1), loaded_[1]->id());
[email protected]6b75ec32009-08-14 06:37:182419}
2420
[email protected]e50013c32010-08-18 21:05:242421#if defined(OS_CHROMEOS)
2422// Test loading extensions from the profile directory, except
2423// ones with a plugin.
[email protected]eaa7dd182010-12-14 11:09:002424TEST_F(ExtensionServiceTest, WillNotLoadPluginExtensionsFromDirectory) {
[email protected]e50013c32010-08-18 21:05:242425 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:352426 FilePath source_install_dir = data_dir_
[email protected]e50013c32010-08-18 21:05:242427 .AppendASCII("good")
2428 .AppendASCII("Extensions");
2429 FilePath pref_path = source_install_dir
2430 .DirName()
2431 .AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:002432 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]e50013c32010-08-18 21:05:242433
2434 // good1 contains a plugin.
2435 // Load extensions.
2436 service_->Init();
2437 loop_.RunAllPending();
2438
2439 std::vector<std::string> errors = GetErrors();
2440 for (std::vector<std::string>::iterator err = errors.begin();
2441 err != errors.end(); ++err) {
2442 LOG(ERROR) << *err;
2443 }
2444 ASSERT_EQ(2u, loaded_.size());
2445
2446 EXPECT_NE(std::string(good1), loaded_[0]->id());
2447 EXPECT_NE(std::string(good1), loaded_[1]->id());
2448}
2449#endif
2450
[email protected]306a2bd2010-08-11 14:56:362451// Will not install extension blacklisted by policy.
[email protected]eaa7dd182010-12-14 11:09:002452TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
2453 InitializeEmptyExtensionService();
[email protected]306a2bd2010-08-11 14:56:362454
[email protected]306a2bd2010-08-11 14:56:362455 // Blacklist everything.
[email protected]43d3bf82011-04-11 07:46:582456 {
2457 ListPrefUpdate update(profile_->GetPrefs(),
2458 prefs::kExtensionInstallDenyList);
2459 ListValue* blacklist = update.Get();
2460 blacklist->Append(Value::CreateStringValue("*"));
2461 }
[email protected]306a2bd2010-08-11 14:56:362462
2463 // Blacklist prevents us from installing good_crx.
[email protected]e85e34c32011-04-13 18:38:352464 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]53da2c962011-03-03 17:08:052465 StartCrxInstall(path);
[email protected]306a2bd2010-08-11 14:56:362466 loop_.RunAllPending();
2467 EXPECT_EQ(0u, service_->extensions()->size());
2468
2469 // Now whitelist this particular extension.
[email protected]43d3bf82011-04-11 07:46:582470 {
2471 ListPrefUpdate update(profile_->GetPrefs(),
2472 prefs::kExtensionInstallAllowList);
2473 ListValue* whitelist = update.Get();
2474 whitelist->Append(Value::CreateStringValue(good_crx));
2475 }
2476
[email protected]306a2bd2010-08-11 14:56:362477
2478 // Ensure we can now install good_crx.
[email protected]53da2c962011-03-03 17:08:052479 StartCrxInstall(path);
[email protected]306a2bd2010-08-11 14:56:362480 loop_.RunAllPending();
2481 EXPECT_EQ(1u, service_->extensions()->size());
2482}
2483
[email protected]aa96d3a2010-08-21 08:45:252484// Extension blacklisted by policy get unloaded after installing.
[email protected]eaa7dd182010-12-14 11:09:002485TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
2486 InitializeEmptyExtensionService();
[email protected]aa96d3a2010-08-21 08:45:252487
2488 // Install good_crx.
[email protected]e85e34c32011-04-13 18:38:352489 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]53da2c962011-03-03 17:08:052490 StartCrxInstall(path);
[email protected]aa96d3a2010-08-21 08:45:252491 loop_.RunAllPending();
2492 EXPECT_EQ(1u, service_->extensions()->size());
2493
[email protected]acd78969c2010-12-08 09:49:112494 { // Scope for pref update notification.
2495 PrefService* prefs = profile_->GetPrefs();
[email protected]43d3bf82011-04-11 07:46:582496 ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList);
2497 ListValue* blacklist = update.Get();
[email protected]acd78969c2010-12-08 09:49:112498 ASSERT_TRUE(blacklist != NULL);
[email protected]aa96d3a2010-08-21 08:45:252499
[email protected]acd78969c2010-12-08 09:49:112500 // Blacklist this extension.
2501 blacklist->Append(Value::CreateStringValue(good_crx));
2502 prefs->ScheduleSavePersistentPrefs();
2503 }
[email protected]aa96d3a2010-08-21 08:45:252504
2505 // Extension should not be running now.
2506 loop_.RunAllPending();
2507 EXPECT_EQ(0u, service_->extensions()->size());
2508}
2509
[email protected]cd500f72010-06-25 23:44:322510// Tests disabling extensions
[email protected]eaa7dd182010-12-14 11:09:002511TEST_F(ExtensionServiceTest, DisableExtension) {
2512 InitializeEmptyExtensionService();
[email protected]cd500f72010-06-25 23:44:322513
2514 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:352515 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:462516 InstallCrx(path, true);
[email protected]cd500f72010-06-25 23:44:322517
2518 const char* extension_id = good_crx;
2519 EXPECT_FALSE(service_->extensions()->empty());
2520 EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
2521 EXPECT_TRUE(service_->GetExtensionById(extension_id, false) != NULL);
2522 EXPECT_TRUE(service_->disabled_extensions()->empty());
2523
2524 // Disable it.
2525 service_->DisableExtension(extension_id);
2526
2527 EXPECT_TRUE(service_->extensions()->empty());
2528 EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
2529 EXPECT_FALSE(service_->GetExtensionById(extension_id, false) != NULL);
2530 EXPECT_FALSE(service_->disabled_extensions()->empty());
2531}
2532
[email protected]d728e002010-12-08 04:46:232533// Tests disabling all extensions (simulating --disable-extensions flag).
[email protected]eaa7dd182010-12-14 11:09:002534TEST_F(ExtensionServiceTest, DisableAllExtensions) {
2535 InitializeEmptyExtensionService();
[email protected]d728e002010-12-08 04:46:232536
[email protected]d728e002010-12-08 04:46:232537
[email protected]e85e34c32011-04-13 18:38:352538 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:462539 InstallCrx(path, true);
[email protected]d728e002010-12-08 04:46:232540
2541 EXPECT_EQ(1u, service_->extensions()->size());
2542 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2543
2544 // Disable extensions.
2545 service_->set_extensions_enabled(false);
2546 service_->ReloadExtensions();
2547
2548 // There shouldn't be extensions in either list.
2549 EXPECT_EQ(0u, service_->extensions()->size());
2550 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2551
2552 // This shouldn't do anything when all extensions are disabled.
2553 service_->EnableExtension(good_crx);
2554 service_->ReloadExtensions();
2555
2556 // There still shouldn't be extensions in either list.
2557 EXPECT_EQ(0u, service_->extensions()->size());
2558 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2559
2560 // And then re-enable the extensions.
2561 service_->set_extensions_enabled(true);
2562 service_->ReloadExtensions();
2563
2564 EXPECT_EQ(1u, service_->extensions()->size());
2565 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2566}
2567
[email protected]cd500f72010-06-25 23:44:322568// Tests reloading extensions
[email protected]eaa7dd182010-12-14 11:09:002569TEST_F(ExtensionServiceTest, ReloadExtensions) {
2570 InitializeEmptyExtensionService();
[email protected]cd500f72010-06-25 23:44:322571
2572 // Simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:352573 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:462574 InstallCrx(path, true);
[email protected]cd500f72010-06-25 23:44:322575 const char* extension_id = good_crx;
2576 service_->DisableExtension(extension_id);
2577
2578 EXPECT_EQ(0u, service_->extensions()->size());
2579 EXPECT_EQ(1u, service_->disabled_extensions()->size());
2580
2581 service_->ReloadExtensions();
2582
2583 // Extension counts shouldn't change.
2584 EXPECT_EQ(0u, service_->extensions()->size());
2585 EXPECT_EQ(1u, service_->disabled_extensions()->size());
2586
2587 service_->EnableExtension(extension_id);
2588
2589 EXPECT_EQ(1u, service_->extensions()->size());
2590 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2591
[email protected]5a73f902010-06-30 02:29:412592 // Need to clear |loaded_| manually before reloading as the
2593 // EnableExtension() call above inserted into it and
2594 // UnloadAllExtensions() doesn't send out notifications.
2595 loaded_.clear();
[email protected]cd500f72010-06-25 23:44:322596 service_->ReloadExtensions();
2597
2598 // Extension counts shouldn't change.
2599 EXPECT_EQ(1u, service_->extensions()->size());
2600 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2601}
2602
[email protected]894bb502009-05-21 22:39:572603// Tests uninstalling normal extensions
[email protected]eaa7dd182010-12-14 11:09:002604TEST_F(ExtensionServiceTest, UninstallExtension) {
2605 InitializeEmptyExtensionService();
[email protected]631cf822009-05-15 07:01:252606
[email protected]4f313d52009-05-21 00:42:292607 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:352608 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:462609 InstallCrx(path, true);
[email protected]631cf822009-05-15 07:01:252610
2611 // The directory should be there now.
[email protected]25b34332009-06-05 21:53:192612 const char* extension_id = good_crx;
[email protected]a9b00ac2009-06-25 21:03:232613 FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
[email protected]631cf822009-05-15 07:01:252614 EXPECT_TRUE(file_util::PathExists(extension_path));
2615
[email protected]25b34332009-06-05 21:53:192616 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342617 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2618 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:192619
[email protected]894bb502009-05-21 22:39:572620 // Uninstall it.
[email protected]d6ebc9792011-04-07 18:18:332621 service_->UninstallExtension(extension_id, false, NULL);
[email protected]902f7cd2009-05-22 19:02:192622 total_successes_ = 0;
[email protected]894bb502009-05-21 22:39:572623
2624 // We should get an unload notification.
2625 ASSERT_TRUE(unloaded_id_.length());
2626 EXPECT_EQ(extension_id, unloaded_id_);
2627
[email protected]9f1087e2009-06-15 17:29:322628 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:192629
[email protected]894bb502009-05-21 22:39:572630 // The extension should not be in the service anymore.
[email protected]61b411612009-11-10 23:17:412631 ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
[email protected]894bb502009-05-21 22:39:572632 loop_.RunAllPending();
2633
2634 // The directory should be gone.
[email protected]631cf822009-05-15 07:01:252635 EXPECT_FALSE(file_util::PathExists(extension_path));
[email protected]631cf822009-05-15 07:01:252636}
2637
[email protected]6aeac8342010-10-01 20:21:182638// Tests the uninstaller helper.
[email protected]eaa7dd182010-12-14 11:09:002639TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
2640 InitializeEmptyExtensionService();
[email protected]6aeac8342010-10-01 20:21:182641
2642 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:352643 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:462644 InstallCrx(path, true);
[email protected]6aeac8342010-10-01 20:21:182645
2646 // The directory should be there now.
2647 const char* extension_id = good_crx;
2648 FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
2649 EXPECT_TRUE(file_util::PathExists(extension_path));
2650
[email protected]eaa7dd182010-12-14 11:09:002651 bool result = ExtensionService::UninstallExtensionHelper(service_,
[email protected]604322d2011-03-22 16:51:562652 extension_id);
[email protected]6aeac8342010-10-01 20:21:182653 total_successes_ = 0;
2654
2655 EXPECT_TRUE(result);
2656
2657 // We should get an unload notification.
2658 ASSERT_TRUE(unloaded_id_.length());
2659 EXPECT_EQ(extension_id, unloaded_id_);
2660
2661 ValidatePrefKeyCount(0);
2662
2663 // The extension should not be in the service anymore.
2664 ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
2665 loop_.RunAllPending();
2666
2667 // The directory should be gone.
2668 EXPECT_FALSE(file_util::PathExists(extension_path));
2669
2670 // Attempt to uninstall again. This should fail as we just removed the
2671 // extension.
[email protected]eaa7dd182010-12-14 11:09:002672 result = ExtensionService::UninstallExtensionHelper(service_, extension_id);
[email protected]6aeac8342010-10-01 20:21:182673 EXPECT_FALSE(result);
2674}
2675
[email protected]c10da4b02010-03-25 14:38:322676// Verifies extension state is removed upon uninstall
[email protected]eaa7dd182010-12-14 11:09:002677TEST_F(ExtensionServiceTest, ClearExtensionData) {
2678 InitializeEmptyExtensionService();
[email protected]c10da4b02010-03-25 14:38:322679
2680 // Load a test extension.
[email protected]e85e34c32011-04-13 18:38:352681 FilePath path = data_dir_;
[email protected]c10da4b02010-03-25 14:38:322682 path = path.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:462683 InstallCrx(path, true);
[email protected]9adb9692010-10-29 23:14:022684 const Extension* extension = service_->GetExtensionById(good_crx, false);
[email protected]c10da4b02010-03-25 14:38:322685 ASSERT_TRUE(extension);
2686 GURL ext_url(extension->url());
2687 string16 origin_id =
2688 webkit_database::DatabaseUtil::GetOriginIdentifier(ext_url);
2689
2690 // Set a cookie for the extension.
[email protected]277ec262011-03-30 21:09:402691 net::CookieMonster* cookie_monster =
2692 profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
2693 cookie_store()->GetCookieMonster();
[email protected]c10da4b02010-03-25 14:38:322694 ASSERT_TRUE(cookie_monster);
2695 net::CookieOptions options;
2696 cookie_monster->SetCookieWithOptions(ext_url, "dummy=value", options);
[email protected]7d80c542010-12-03 15:30:362697 net::CookieList list = cookie_monster->GetAllCookiesForURL(ext_url);
[email protected]c10da4b02010-03-25 14:38:322698 EXPECT_EQ(1U, list.size());
2699
2700 // Open a database.
2701 webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
2702 string16 db_name = UTF8ToUTF16("db");
2703 string16 description = UTF8ToUTF16("db_description");
2704 int64 size;
2705 int64 available;
2706 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size,
2707 &available);
2708 db_tracker->DatabaseClosed(origin_id, db_name);
2709 std::vector<webkit_database::OriginInfo> origins;
2710 db_tracker->GetAllOriginsInfo(&origins);
2711 EXPECT_EQ(1U, origins.size());
2712 EXPECT_EQ(origin_id, origins[0].GetOrigin());
2713
2714 // Create local storage. We only simulate this by creating the backing file
2715 // since webkit is not initialized.
2716 DOMStorageContext* context =
2717 profile_->GetWebKitContext()->dom_storage_context();
2718 FilePath lso_path = context->GetLocalStorageFilePath(origin_id);
2719 EXPECT_TRUE(file_util::CreateDirectory(lso_path.DirName()));
2720 EXPECT_EQ(0, file_util::WriteFile(lso_path, NULL, 0));
2721 EXPECT_TRUE(file_util::PathExists(lso_path));
2722
[email protected]e1dcf922010-11-22 19:12:122723 // Create indexed db. Again, it is enough to only simulate this by creating
2724 // the file on the disk.
2725 IndexedDBContext* idb_context =
2726 profile_->GetWebKitContext()->indexed_db_context();
2727 FilePath idb_path = idb_context->GetIndexedDBFilePath(origin_id);
2728 EXPECT_TRUE(file_util::CreateDirectory(idb_path.DirName()));
2729 EXPECT_EQ(0, file_util::WriteFile(idb_path, NULL, 0));
2730 EXPECT_TRUE(file_util::PathExists(idb_path));
2731
[email protected]c10da4b02010-03-25 14:38:322732 // Uninstall the extension.
[email protected]d6ebc9792011-04-07 18:18:332733 service_->UninstallExtension(good_crx, false, NULL);
[email protected]c10da4b02010-03-25 14:38:322734 loop_.RunAllPending();
2735
2736 // Check that the cookie is gone.
2737 list = cookie_monster->GetAllCookiesForURL(ext_url);
2738 EXPECT_EQ(0U, list.size());
2739
2740 // The database should have vanished as well.
2741 origins.clear();
2742 db_tracker->GetAllOriginsInfo(&origins);
2743 EXPECT_EQ(0U, origins.size());
2744
2745 // Check that the LSO file has been removed.
2746 EXPECT_FALSE(file_util::PathExists(lso_path));
[email protected]e1dcf922010-11-22 19:12:122747
2748 // Check if the indexed db has disappeared too.
2749 EXPECT_FALSE(file_util::PathExists(idb_path));
[email protected]c10da4b02010-03-25 14:38:322750}
2751
[email protected]894bb502009-05-21 22:39:572752// Tests loading single extensions (like --load-extension)
[email protected]eaa7dd182010-12-14 11:09:002753TEST_F(ExtensionServiceTest, LoadExtension) {
2754 InitializeEmptyExtensionService();
[email protected]3cf4f0992009-02-03 23:00:302755
[email protected]e85e34c32011-04-13 18:38:352756 FilePath ext1 = data_dir_
[email protected]a9b00ac2009-06-25 21:03:232757 .AppendASCII("good")
2758 .AppendASCII("Extensions")
[email protected]5a2721f62009-06-13 07:08:202759 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2760 .AppendASCII("1.0.0.0");
[email protected]894bb502009-05-21 22:39:572761 service_->LoadExtension(ext1);
2762 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:182763 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:572764 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:322765 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2766 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:302767
[email protected]e8c729a2010-03-09 19:55:192768 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:192769
[email protected]e85e34c32011-04-13 18:38:352770 FilePath no_manifest = data_dir_
[email protected]a9b00ac2009-06-25 21:03:232771 .AppendASCII("bad")
[email protected]93fd78f42009-07-10 16:43:172772 // .AppendASCII("Extensions")
[email protected]a9b00ac2009-06-25 21:03:232773 .AppendASCII("cccccccccccccccccccccccccccccccc")
2774 .AppendASCII("1");
[email protected]894bb502009-05-21 22:39:572775 service_->LoadExtension(no_manifest);
2776 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:182777 EXPECT_EQ(1u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:572778 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:322779 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]25b34332009-06-05 21:53:192780
2781 // Test uninstall.
[email protected]894bb502009-05-21 22:39:572782 std::string id = loaded_[0]->id();
2783 EXPECT_FALSE(unloaded_id_.length());
[email protected]d6ebc9792011-04-07 18:18:332784 service_->UninstallExtension(id, false, NULL);
[email protected]894bb502009-05-21 22:39:572785 loop_.RunAllPending();
2786 EXPECT_EQ(id, unloaded_id_);
[email protected]9f1087e2009-06-15 17:29:322787 ASSERT_EQ(0u, loaded_.size());
2788 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:302789}
[email protected]0b344962009-03-31 04:21:452790
[email protected]894bb502009-05-21 22:39:572791// Tests that we generate IDs when they are not specified in the manifest for
2792// --load-extension.
[email protected]eaa7dd182010-12-14 11:09:002793TEST_F(ExtensionServiceTest, GenerateID) {
2794 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:452795
[email protected]0b344962009-03-31 04:21:452796
[email protected]e85e34c32011-04-13 18:38:352797 FilePath no_id_ext = data_dir_.AppendASCII("no_id");
[email protected]894bb502009-05-21 22:39:572798 service_->LoadExtension(no_id_ext);
2799 loop_.RunAllPending();
[email protected]0b344962009-03-31 04:21:452800 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:572801 ASSERT_EQ(1u, loaded_.size());
[email protected]84ac7f32009-10-06 06:17:542802 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
[email protected]9f1087e2009-06-15 17:29:322803 EXPECT_EQ(loaded_[0]->location(), Extension::LOAD);
[email protected]0b344962009-03-31 04:21:452804
[email protected]e8c729a2010-03-09 19:55:192805 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:192806
[email protected]84ac7f32009-10-06 06:17:542807 std::string previous_id = loaded_[0]->id();
2808
2809 // If we reload the same path, we should get the same extension ID.
[email protected]894bb502009-05-21 22:39:572810 service_->LoadExtension(no_id_ext);
2811 loop_.RunAllPending();
[email protected]84ac7f32009-10-06 06:17:542812 ASSERT_EQ(1u, loaded_.size());
2813 ASSERT_EQ(previous_id, loaded_[0]->id());
[email protected]0b344962009-03-31 04:21:452814}
[email protected]894bb502009-05-21 22:39:572815
[email protected]eaa7dd182010-12-14 11:09:002816void ExtensionServiceTest::TestExternalProvider(
[email protected]d55e7602009-12-16 04:20:422817 MockExtensionProvider* provider, Extension::Location location) {
[email protected]a1257b12009-06-12 02:51:342818 // Verify that starting with no providers loads no extensions.
2819 service_->Init();
2820 loop_.RunAllPending();
2821 ASSERT_EQ(0u, loaded_.size());
2822
[email protected]0a60a2e2010-10-25 16:15:212823 provider->set_visit_count(0);
2824
[email protected]a1257b12009-06-12 02:51:342825 // Register a test extension externally using the mock registry provider.
[email protected]e85e34c32011-04-13 18:38:352826 FilePath source_path = data_dir_.AppendASCII("good.crx");
[email protected]894bb502009-05-21 22:39:572827
[email protected]a1257b12009-06-12 02:51:342828 // Add the extension.
[email protected]d55e7602009-12-16 04:20:422829 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
[email protected]894bb502009-05-21 22:39:572830
[email protected]9f1087e2009-06-15 17:29:322831 // Reloading extensions should find our externally registered extension
[email protected]894bb502009-05-21 22:39:572832 // and install it.
[email protected]93fd78f42009-07-10 16:43:172833 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:572834 loop_.RunAllPending();
2835
2836 ASSERT_EQ(0u, GetErrors().size());
2837 ASSERT_EQ(1u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:422838 ASSERT_EQ(location, loaded_[0]->location());
[email protected]894bb502009-05-21 22:39:572839 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:192840 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342841 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2842 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:572843
[email protected]9f1087e2009-06-15 17:29:322844 // Reload extensions without changing anything. The extension should be
[email protected]894bb502009-05-21 22:39:572845 // loaded again.
2846 loaded_.clear();
[email protected]9f1087e2009-06-15 17:29:322847 service_->ReloadExtensions();
[email protected]894bb502009-05-21 22:39:572848 loop_.RunAllPending();
2849 ASSERT_EQ(0u, GetErrors().size());
2850 ASSERT_EQ(1u, loaded_.size());
[email protected]25b34332009-06-05 21:53:192851 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342852 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2853 ValidateIntegerPref(good_crx, "location", location);
[email protected]e2eb43112009-05-29 21:19:542854
[email protected]894bb502009-05-21 22:39:572855 // Now update the extension with a new version. We should get upgraded.
2856 source_path = source_path.DirName().AppendASCII("good2.crx");
[email protected]d55e7602009-12-16 04:20:422857 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]894bb502009-05-21 22:39:572858
2859 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:172860 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:572861 loop_.RunAllPending();
2862 ASSERT_EQ(0u, GetErrors().size());
2863 ASSERT_EQ(1u, loaded_.size());
2864 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:192865 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342866 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2867 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:572868
[email protected]27b985d2009-06-25 17:53:152869 // Uninstall the extension and reload. Nothing should happen because the
[email protected]894bb502009-05-21 22:39:572870 // preference should prevent us from reinstalling.
2871 std::string id = loaded_[0]->id();
[email protected]d6ebc9792011-04-07 18:18:332872 service_->UninstallExtension(id, false, NULL);
[email protected]894bb502009-05-21 22:39:572873 loop_.RunAllPending();
2874
[email protected]a9b00ac2009-06-25 21:03:232875 FilePath install_path = extensions_install_dir_.AppendASCII(id);
[email protected]95da88c42011-03-31 10:07:332876 // It should not be possible to uninstall a policy controlled extension.
2877 if (Extension::UserMayDisable(location)) {
2878 // The extension should also be gone from the install directory.
2879 ASSERT_FALSE(file_util::PathExists(install_path));
2880 loaded_.clear();
2881 service_->CheckForExternalUpdates();
2882 loop_.RunAllPending();
2883 ASSERT_EQ(0u, loaded_.size());
2884 ValidatePrefKeyCount(1);
[email protected]79c833b52011-04-05 18:31:012885 ValidateIntegerPref(good_crx, "state",
2886 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]95da88c42011-03-31 10:07:332887 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:572888
[email protected]95da88c42011-03-31 10:07:332889 // Now clear the preference and reinstall.
2890 SetPrefInteg(good_crx, "state", Extension::ENABLED);
2891 profile_->GetPrefs()->ScheduleSavePersistentPrefs();
[email protected]25b34332009-06-05 21:53:192892
[email protected]95da88c42011-03-31 10:07:332893 loaded_.clear();
2894 service_->CheckForExternalUpdates();
2895 loop_.RunAllPending();
2896 ASSERT_EQ(1u, loaded_.size());
2897 } else {
2898 // Policy controlled extesions should not have been touched by uninstall.
2899 ASSERT_TRUE(file_util::PathExists(install_path));
2900 }
[email protected]25b34332009-06-05 21:53:192901 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342902 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2903 ValidateIntegerPref(good_crx, "location", location);
[email protected]25b34332009-06-05 21:53:192904
[email protected]95da88c42011-03-31 10:07:332905 if (Extension::UserMayDisable(location)) {
2906 // Now test an externally triggered uninstall (deleting the registry key or
2907 // the pref entry).
2908 provider->RemoveExtension(good_crx);
[email protected]25b34332009-06-05 21:53:192909
[email protected]95da88c42011-03-31 10:07:332910 loaded_.clear();
2911 service_->OnExternalProviderReady();
2912 loop_.RunAllPending();
2913 ASSERT_EQ(0u, loaded_.size());
2914 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:192915
[email protected]95da88c42011-03-31 10:07:332916 // The extension should also be gone from the install directory.
2917 ASSERT_FALSE(file_util::PathExists(install_path));
[email protected]abe7a8942009-06-23 05:14:292918
[email protected]95da88c42011-03-31 10:07:332919 // Now test the case where user uninstalls and then the extension is removed
2920 // from the external provider.
[email protected]abe7a8942009-06-23 05:14:292921
[email protected]604322d2011-03-22 16:51:562922 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]95da88c42011-03-31 10:07:332923 service_->CheckForExternalUpdates();
2924 loop_.RunAllPending();
[email protected]abe7a8942009-06-23 05:14:292925
[email protected]95da88c42011-03-31 10:07:332926 ASSERT_EQ(1u, loaded_.size());
2927 ASSERT_EQ(0u, GetErrors().size());
[email protected]d55e7602009-12-16 04:20:422928
[email protected]95da88c42011-03-31 10:07:332929 // User uninstalls.
2930 loaded_.clear();
[email protected]d6ebc9792011-04-07 18:18:332931 service_->UninstallExtension(id, false, NULL);
[email protected]95da88c42011-03-31 10:07:332932 loop_.RunAllPending();
2933 ASSERT_EQ(0u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:422934
[email protected]95da88c42011-03-31 10:07:332935 // Then remove the extension from the extension provider.
2936 provider->RemoveExtension(good_crx);
[email protected]d55e7602009-12-16 04:20:422937
[email protected]95da88c42011-03-31 10:07:332938 // Should still be at 0.
2939 loaded_.clear();
2940 service_->LoadAllExtensions();
2941 loop_.RunAllPending();
2942 ASSERT_EQ(0u, loaded_.size());
2943 ValidatePrefKeyCount(1);
[email protected]0a60a2e2010-10-25 16:15:212944
[email protected]95da88c42011-03-31 10:07:332945 EXPECT_EQ(5, provider->visit_count());
2946 } else {
2947 EXPECT_EQ(2, provider->visit_count());
2948 }
[email protected]d55e7602009-12-16 04:20:422949}
2950
2951// Tests the external installation feature
2952#if defined(OS_WIN)
[email protected]eaa7dd182010-12-14 11:09:002953TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
[email protected]aebe23a32010-12-10 22:15:482954 // This should all work, even when normal extension installation is disabled.
[email protected]eaa7dd182010-12-14 11:09:002955 InitializeEmptyExtensionService();
[email protected]aebe23a32010-12-10 22:15:482956 set_extensions_enabled(false);
[email protected]d55e7602009-12-16 04:20:422957
2958 // Now add providers. Extension system takes ownership of the objects.
2959 MockExtensionProvider* reg_provider =
[email protected]14908b72011-04-20 06:54:362960 new MockExtensionProvider(service_, Extension::EXTERNAL_REGISTRY);
[email protected]0a60a2e2010-10-25 16:15:212961 AddMockExternalProvider(reg_provider);
[email protected]d55e7602009-12-16 04:20:422962 TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
2963}
2964#endif
2965
[email protected]eaa7dd182010-12-14 11:09:002966TEST_F(ExtensionServiceTest, ExternalInstallPref) {
2967 InitializeEmptyExtensionService();
[email protected]d55e7602009-12-16 04:20:422968
2969 // Now add providers. Extension system takes ownership of the objects.
2970 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:362971 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]0a60a2e2010-10-25 16:15:212972
2973 AddMockExternalProvider(pref_provider);
[email protected]d55e7602009-12-16 04:20:422974 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
[email protected]27b985d2009-06-25 17:53:152975}
2976
[email protected]eaa7dd182010-12-14 11:09:002977TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
[email protected]aebe23a32010-12-10 22:15:482978 // This should all work, even when normal extension installation is disabled.
[email protected]eaa7dd182010-12-14 11:09:002979 InitializeEmptyExtensionService();
[email protected]aebe23a32010-12-10 22:15:482980 set_extensions_enabled(false);
[email protected]55196e92010-09-29 15:04:462981
[email protected]0a60a2e2010-10-25 16:15:212982 // TODO(skerner): The mock provider is not a good model of a provider
2983 // that works with update URLs, because it adds file and version info.
2984 // Extend the mock to work with update URLs. This test checks the
2985 // behavior that is common to all external extension visitors. The
2986 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
2987 // what the visitor does results in an extension being downloaded and
2988 // installed.
[email protected]55196e92010-09-29 15:04:462989 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:362990 new MockExtensionProvider(service_,
[email protected]8e4560b62011-01-14 10:09:142991 Extension::EXTERNAL_PREF_DOWNLOAD);
[email protected]0a60a2e2010-10-25 16:15:212992 AddMockExternalProvider(pref_provider);
[email protected]55196e92010-09-29 15:04:462993 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF_DOWNLOAD);
2994}
2995
[email protected]95da88c42011-03-31 10:07:332996TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
2997 // This should all work, even when normal extension installation is disabled.
2998 InitializeEmptyExtensionService();
2999 set_extensions_enabled(false);
3000
3001 // TODO(skerner): The mock provider is not a good model of a provider
3002 // that works with update URLs, because it adds file and version info.
3003 // Extend the mock to work with update URLs. This test checks the
3004 // behavior that is common to all external extension visitors. The
3005 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
3006 // what the visitor does results in an extension being downloaded and
3007 // installed.
3008 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:363009 new MockExtensionProvider(service_,
[email protected]95da88c42011-03-31 10:07:333010 Extension::EXTERNAL_POLICY_DOWNLOAD);
3011 AddMockExternalProvider(pref_provider);
3012 TestExternalProvider(pref_provider, Extension::EXTERNAL_POLICY_DOWNLOAD);
3013}
3014
[email protected]aebe23a32010-12-10 22:15:483015// Tests that external extensions get uninstalled when the external extension
3016// providers can't account for them.
[email protected]eaa7dd182010-12-14 11:09:003017TEST_F(ExtensionServiceTest, ExternalUninstall) {
[email protected]aebe23a32010-12-10 22:15:483018 // Start the extensions service with one external extension already installed.
[email protected]e85e34c32011-04-13 18:38:353019 FilePath source_install_dir = data_dir_
[email protected]aebe23a32010-12-10 22:15:483020 .AppendASCII("good")
3021 .AppendASCII("Extensions");
3022 FilePath pref_path = source_install_dir
3023 .DirName()
3024 .AppendASCII("PreferencesExternal");
3025
3026 // This initializes the extensions service with no ExternalExtensionProviders.
[email protected]eaa7dd182010-12-14 11:09:003027 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]aebe23a32010-12-10 22:15:483028 set_extensions_enabled(false);
3029
3030 service_->Init();
3031 loop_.RunAllPending();
3032
3033 ASSERT_EQ(0u, GetErrors().size());
3034 ASSERT_EQ(0u, loaded_.size());
3035
3036 // Verify that it's not the disabled extensions flag causing it not to load.
3037 set_extensions_enabled(true);
3038 service_->ReloadExtensions();
3039 loop_.RunAllPending();
3040
3041 ASSERT_EQ(0u, GetErrors().size());
3042 ASSERT_EQ(0u, loaded_.size());
3043}
3044
[email protected]a29a517a2011-01-21 21:11:123045// Test that running multiple update checks simultaneously does not
3046// keep the update from succeeding.
3047TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
3048 InitializeEmptyExtensionService();
3049
3050 MockExtensionProvider* provider =
[email protected]14908b72011-04-20 06:54:363051 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]a29a517a2011-01-21 21:11:123052 AddMockExternalProvider(provider);
3053
3054 // Verify that starting with no providers loads no extensions.
3055 service_->Init();
3056 loop_.RunAllPending();
3057 ASSERT_EQ(0u, loaded_.size());
3058
3059 // Start two checks for updates.
3060 provider->set_visit_count(0);
3061 service_->CheckForExternalUpdates();
3062 service_->CheckForExternalUpdates();
3063 loop_.RunAllPending();
3064
3065 // Two calls should cause two checks for external extensions.
3066 EXPECT_EQ(2, provider->visit_count());
3067 EXPECT_EQ(0u, GetErrors().size());
3068 EXPECT_EQ(0u, loaded_.size());
3069
3070 // Register a test extension externally using the mock registry provider.
[email protected]e85e34c32011-04-13 18:38:353071 FilePath source_path = data_dir_.AppendASCII("good.crx");
[email protected]a29a517a2011-01-21 21:11:123072 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
3073
3074 // Two checks for external updates should find the extension, and install it
3075 // once.
3076 provider->set_visit_count(0);
3077 service_->CheckForExternalUpdates();
3078 service_->CheckForExternalUpdates();
3079 loop_.RunAllPending();
3080 EXPECT_EQ(2, provider->visit_count());
3081 ASSERT_EQ(0u, GetErrors().size());
3082 ASSERT_EQ(1u, loaded_.size());
3083 ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location());
3084 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
3085 ValidatePrefKeyCount(1);
3086 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
3087 ValidateIntegerPref(good_crx, "location", Extension::EXTERNAL_PREF);
3088
3089 provider->RemoveExtension(good_crx);
3090 provider->set_visit_count(0);
3091 service_->CheckForExternalUpdates();
3092 service_->CheckForExternalUpdates();
3093 loop_.RunAllPending();
3094
3095 // Two calls should cause two checks for external extensions.
3096 // Because the external source no longer includes good_crx,
3097 // good_crx will be uninstalled. So, expect that no extensions
3098 // are loaded.
3099 EXPECT_EQ(2, provider->visit_count());
3100 EXPECT_EQ(0u, GetErrors().size());
3101 EXPECT_EQ(0u, loaded_.size());
3102}
3103
[email protected]eaa7dd182010-12-14 11:09:003104TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
3105 InitializeEmptyExtensionService();
[email protected]f0841cd2011-01-19 15:07:243106
3107 // Test some valid extension records.
3108 // Set a base path to avoid erroring out on relative paths.
3109 // Paths starting with // are absolute on every platform we support.
3110 FilePath base_path(FILE_PATH_LITERAL("//base/path"));
3111 ASSERT_TRUE(base_path.IsAbsolute());
3112 MockProviderVisitor visitor(base_path);
[email protected]27b985d2009-06-25 17:53:153113 std::string json_data =
3114 "{"
[email protected]f0841cd2011-01-19 15:07:243115 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
[email protected]9e54cb572010-09-03 20:08:063116 " \"external_crx\": \"RandomExtension.crx\","
3117 " \"external_version\": \"1.0\""
3118 " },"
3119 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
3120 " \"external_crx\": \"RandomExtension2.crx\","
3121 " \"external_version\": \"2.0\""
3122 " },"
3123 " \"cccccccccccccccccccccccccccccccc\": {"
[email protected]a424d84c2010-09-24 09:31:153124 " \"external_update_url\": \"http:\\\\foo.com/update\""
[email protected]9e54cb572010-09-03 20:08:063125 " }"
[email protected]27b985d2009-06-25 17:53:153126 "}";
[email protected]f0841cd2011-01-19 15:07:243127 EXPECT_EQ(3, visitor.Visit(json_data));
[email protected]27b985d2009-06-25 17:53:153128
[email protected]9e54cb572010-09-03 20:08:063129 // Simulate an external_extensions.json file that contains seven invalid
[email protected]f0841cd2011-01-19 15:07:243130 // records:
[email protected]27b985d2009-06-25 17:53:153131 // - One that is missing the 'external_crx' key.
3132 // - One that is missing the 'external_version' key.
3133 // - One that is specifying .. in the path.
[email protected]8ef78fd2010-08-19 17:14:323134 // - One that specifies both a file and update URL.
3135 // - One that specifies no file or update URL.
3136 // - One that has an update URL that is not well formed.
[email protected]9e54cb572010-09-03 20:08:063137 // - One that contains a malformed version.
[email protected]ab22ba42011-01-14 16:36:383138 // - One that has an invalid id.
3139 // - One that has a non-dictionary value.
[email protected]9e54cb572010-09-03 20:08:063140 // The final extension is valid, and we check that it is read to make sure
3141 // failures don't stop valid records from being read.
[email protected]27b985d2009-06-25 17:53:153142 json_data =
3143 "{"
[email protected]9e54cb572010-09-03 20:08:063144 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
3145 " \"external_version\": \"1.0\""
3146 " },"
3147 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
3148 " \"external_crx\": \"RandomExtension.crx\""
3149 " },"
3150 " \"cccccccccccccccccccccccccccccccc\": {"
3151 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
3152 " \"external_version\": \"2.0\""
3153 " },"
3154 " \"dddddddddddddddddddddddddddddddd\": {"
3155 " \"external_crx\": \"RandomExtension2.crx\","
3156 " \"external_version\": \"2.0\","
3157 " \"external_update_url\": \"http:\\\\foo.com/update\""
3158 " },"
3159 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
3160 " },"
3161 " \"ffffffffffffffffffffffffffffffff\": {"
3162 " \"external_update_url\": \"This string is not a valid URL\""
3163 " },"
3164 " \"gggggggggggggggggggggggggggggggg\": {"
3165 " \"external_crx\": \"RandomExtension3.crx\","
3166 " \"external_version\": \"This is not a valid version!\""
3167 " },"
[email protected]ab22ba42011-01-14 16:36:383168 " \"This is not a valid id!\": {},"
3169 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
3170 " \"pppppppppppppppppppppppppppppppp\": {"
[email protected]9e54cb572010-09-03 20:08:063171 " \"external_crx\": \"RandomValidExtension.crx\","
3172 " \"external_version\": \"1.0\""
3173 " }"
[email protected]27b985d2009-06-25 17:53:153174 "}";
[email protected]683d0702010-12-06 16:25:573175 EXPECT_EQ(1, visitor.Visit(json_data));
[email protected]f0841cd2011-01-19 15:07:243176
3177 // Check that if a base path is not provided, use of a relative
3178 // path fails.
3179 FilePath empty;
3180 MockProviderVisitor visitor_no_relative_paths(empty);
3181
3182 // Use absolute paths. Expect success.
3183 json_data =
3184 "{"
3185 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
3186 " \"external_crx\": \"//RandomExtension1.crx\","
3187 " \"external_version\": \"3.0\""
3188 " },"
3189 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
3190 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
3191 " \"external_version\": \"3.0\""
3192 " }"
3193 "}";
3194 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
3195
3196 // Use a relative path. Expect that it will error out.
3197 json_data =
3198 "{"
3199 " \"cccccccccccccccccccccccccccccccc\": {"
3200 " \"external_crx\": \"RandomExtension2.crx\","
3201 " \"external_version\": \"3.0\""
3202 " }"
3203 "}";
3204 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
[email protected]e18236b2009-06-22 21:32:103205}
[email protected]36a784c2009-06-23 06:21:083206
[email protected]c6d474f82009-12-16 21:11:063207// Test loading good extensions from the profile directory.
[email protected]eaa7dd182010-12-14 11:09:003208TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
[email protected]c6d474f82009-12-16 21:11:063209 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:353210 FilePath source_install_dir = data_dir_
[email protected]c6d474f82009-12-16 21:11:063211 .AppendASCII("l10n");
3212 FilePath pref_path = source_install_dir.AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:003213 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]c6d474f82009-12-16 21:11:063214
3215 service_->Init();
3216 loop_.RunAllPending();
3217
3218 ASSERT_EQ(3u, loaded_.size());
3219
3220 // This was equal to "sr" on load.
3221 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
3222
3223 // These are untouched by re-localization.
3224 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
3225 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
3226
3227 // This one starts with Serbian name, and gets re-localized into English.
3228 EXPECT_EQ("My name is simple.", loaded_[0]->name());
3229
3230 // These are untouched by re-localization.
3231 EXPECT_EQ("My name is simple.", loaded_[1]->name());
3232 EXPECT_EQ("no l10n", loaded_[2]->name());
3233}
3234
[email protected]f0488f2f2009-07-01 05:25:223235class ExtensionsReadyRecorder : public NotificationObserver {
3236 public:
3237 ExtensionsReadyRecorder() : ready_(false) {
3238 registrar_.Add(this, NotificationType::EXTENSIONS_READY,
3239 NotificationService::AllSources());
3240 }
3241
3242 void set_ready(bool value) { ready_ = value; }
3243 bool ready() { return ready_; }
3244
3245 private:
3246 virtual void Observe(NotificationType type,
3247 const NotificationSource& source,
3248 const NotificationDetails& details) {
3249 switch (type.value) {
3250 case NotificationType::EXTENSIONS_READY:
3251 ready_ = true;
3252 break;
3253 default:
3254 NOTREACHED();
3255 }
3256 }
3257
3258 NotificationRegistrar registrar_;
3259 bool ready_;
3260};
3261
[email protected]36a784c2009-06-23 06:21:083262// Test that we get enabled/disabled correctly for all the pref/command-line
[email protected]eaa7dd182010-12-14 11:09:003263// combinations. We don't want to derive from the ExtensionServiceTest class
3264// for this test, so we use ExtensionServiceTestSimple.
[email protected]f0488f2f2009-07-01 05:25:223265//
3266// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
3267// enabled or not.
[email protected]eaa7dd182010-12-14 11:09:003268TEST(ExtensionServiceTestSimple, Enabledness) {
[email protected]ed8ee722011-04-22 06:49:443269 ExtensionErrorReporter::Init(false); // no noisy errors
[email protected]f0488f2f2009-07-01 05:25:223270 ExtensionsReadyRecorder recorder;
[email protected]aa96d3a2010-08-21 08:45:253271 scoped_ptr<TestingProfile> profile(new TestingProfile());
[email protected]36a784c2009-06-23 06:21:083272 MessageLoop loop;
[email protected]ca4b5fa32010-10-09 12:42:183273 BrowserThread ui_thread(BrowserThread::UI, &loop);
3274 BrowserThread file_thread(BrowserThread::FILE, &loop);
[email protected]36a784c2009-06-23 06:21:083275 scoped_ptr<CommandLine> command_line;
[email protected]aa96d3a2010-08-21 08:45:253276 FilePath install_dir = profile->GetPath()
[email protected]eaa7dd182010-12-14 11:09:003277 .AppendASCII(ExtensionService::kInstallDirectoryName);
[email protected]36a784c2009-06-23 06:21:083278
[email protected]6d60703b2009-08-29 01:29:233279 // By default, we are enabled.
[email protected]947446b2010-10-21 03:36:313280 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
[email protected]14908b72011-04-20 06:54:363281 // Owned by |profile|.
3282 ExtensionService* service =
3283 profile->CreateExtensionService(command_line.get(),
3284 install_dir,
3285 false);
[email protected]6d60703b2009-08-29 01:29:233286 EXPECT_TRUE(service->extensions_enabled());
3287 service->Init();
3288 loop.RunAllPending();
3289 EXPECT_TRUE(recorder.ready());
3290
3291 // If either the command line or pref is set, we are disabled.
3292 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:253293 profile.reset(new TestingProfile());
[email protected]6d60703b2009-08-29 01:29:233294 command_line->AppendSwitch(switches::kDisableExtensions);
[email protected]eaa7dd182010-12-14 11:09:003295 service = profile->CreateExtensionService(command_line.get(),
[email protected]90310d92011-04-17 07:35:043296 install_dir,
3297 false);
[email protected]36a784c2009-06-23 06:21:083298 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:223299 service->Init();
3300 loop.RunAllPending();
3301 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:083302
[email protected]f0488f2f2009-07-01 05:25:223303 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:253304 profile.reset(new TestingProfile());
3305 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]eaa7dd182010-12-14 11:09:003306 service = profile->CreateExtensionService(command_line.get(),
[email protected]90310d92011-04-17 07:35:043307 install_dir,
3308 false);
[email protected]6d60703b2009-08-29 01:29:233309 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:223310 service->Init();
3311 loop.RunAllPending();
3312 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:083313
[email protected]f0488f2f2009-07-01 05:25:223314 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:253315 profile.reset(new TestingProfile());
3316 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]947446b2010-10-21 03:36:313317 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
[email protected]eaa7dd182010-12-14 11:09:003318 service = profile->CreateExtensionService(command_line.get(),
[email protected]90310d92011-04-17 07:35:043319 install_dir,
3320 false);
[email protected]6d60703b2009-08-29 01:29:233321 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:223322 service->Init();
3323 loop.RunAllPending();
3324 EXPECT_TRUE(recorder.ready());
[email protected]7e1951a2010-09-30 10:22:203325
3326 // Explicitly delete all the resources used in this test.
3327 profile.reset();
3328 service = NULL;
[email protected]36a784c2009-06-23 06:21:083329}
[email protected]24b538a2010-02-27 01:22:443330
3331// Test loading extensions that require limited and unlimited storage quotas.
[email protected]eaa7dd182010-12-14 11:09:003332TEST_F(ExtensionServiceTest, StorageQuota) {
3333 InitializeEmptyExtensionService();
[email protected]24b538a2010-02-27 01:22:443334
[email protected]e85e34c32011-04-13 18:38:353335 FilePath extensions_path = data_dir_
[email protected]24b538a2010-02-27 01:22:443336 .AppendASCII("storage_quota");
3337
[email protected]e85e34c32011-04-13 18:38:353338 FilePath limited_quota_ext =
3339 extensions_path.AppendASCII("limited_quota")
[email protected]24b538a2010-02-27 01:22:443340 .AppendASCII("1.0");
[email protected]03b612f2010-08-13 21:09:213341
3342 // The old permission name for unlimited quota was "unlimited_storage", but
3343 // we changed it to "unlimitedStorage". This tests both versions.
[email protected]e85e34c32011-04-13 18:38:353344 FilePath unlimited_quota_ext =
3345 extensions_path.AppendASCII("unlimited_quota")
[email protected]24b538a2010-02-27 01:22:443346 .AppendASCII("1.0");
[email protected]e85e34c32011-04-13 18:38:353347 FilePath unlimited_quota_ext2 =
3348 extensions_path.AppendASCII("unlimited_quota")
[email protected]03b612f2010-08-13 21:09:213349 .AppendASCII("2.0");
[email protected]24b538a2010-02-27 01:22:443350 service_->LoadExtension(limited_quota_ext);
3351 service_->LoadExtension(unlimited_quota_ext);
[email protected]03b612f2010-08-13 21:09:213352 service_->LoadExtension(unlimited_quota_ext2);
[email protected]24b538a2010-02-27 01:22:443353 loop_.RunAllPending();
3354
[email protected]03b612f2010-08-13 21:09:213355 ASSERT_EQ(3u, loaded_.size());
[email protected]24b538a2010-02-27 01:22:443356 EXPECT_TRUE(profile_.get());
3357 EXPECT_FALSE(profile_->IsOffTheRecord());
3358
[email protected]03b612f2010-08-13 21:09:213359 // Open the database from each origin to make the tracker aware
[email protected]7798871882010-09-14 17:18:563360 // of the existence of these origins and to get their quotas.
[email protected]24b538a2010-02-27 01:22:443361 int64 limited_quota = -1;
3362 int64 unlimited_quota = -1;
3363 string16 limited_quota_identifier =
3364 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[0]->url());
3365 string16 unlimited_quota_identifier =
3366 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[1]->url());
[email protected]03b612f2010-08-13 21:09:213367 string16 unlimited_quota_identifier2 =
3368 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[2]->url());
[email protected]24b538a2010-02-27 01:22:443369 string16 db_name = UTF8ToUTF16("db");
3370 string16 description = UTF8ToUTF16("db_description");
3371 int64 database_size;
3372 webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
[email protected]03b612f2010-08-13 21:09:213373
3374 // First check the normal limited quota extension.
[email protected]24b538a2010-02-27 01:22:443375 db_tracker->DatabaseOpened(limited_quota_identifier, db_name, description,
3376 1, &database_size, &limited_quota);
3377 db_tracker->DatabaseClosed(limited_quota_identifier, db_name);
[email protected]03b612f2010-08-13 21:09:213378 EXPECT_EQ(profile_->GetDatabaseTracker()->GetDefaultQuota(), limited_quota);
3379
3380 // Now check the two unlimited quota ones.
[email protected]24b538a2010-02-27 01:22:443381 db_tracker->DatabaseOpened(unlimited_quota_identifier, db_name, description,
3382 1, &database_size, &unlimited_quota);
3383 db_tracker->DatabaseClosed(unlimited_quota_identifier, db_name);
[email protected]03b612f2010-08-13 21:09:213384 EXPECT_EQ(kint64max, unlimited_quota);
3385 db_tracker->DatabaseOpened(unlimited_quota_identifier2, db_name, description,
3386 1, &database_size, &unlimited_quota);
3387 db_tracker->DatabaseClosed(unlimited_quota_identifier2, db_name);
[email protected]24b538a2010-02-27 01:22:443388
[email protected]24b538a2010-02-27 01:22:443389 EXPECT_EQ(kint64max, unlimited_quota);
3390}
[email protected]1952c7d2010-03-04 23:48:343391
[email protected]eaa7dd182010-12-14 11:09:003392// Tests ExtensionService::register_component_extension().
3393TEST_F(ExtensionServiceTest, ComponentExtensions) {
3394 InitializeEmptyExtensionService();
[email protected]1952c7d2010-03-04 23:48:343395
[email protected]f0b97f12010-10-11 21:44:353396 // Component extensions should work even when extensions are disabled.
3397 set_extensions_enabled(false);
3398
[email protected]e85e34c32011-04-13 18:38:353399 FilePath path = data_dir_
[email protected]1952c7d2010-03-04 23:48:343400 .AppendASCII("good")
3401 .AppendASCII("Extensions")
3402 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
3403 .AppendASCII("1.0.0.0");
3404
3405 std::string manifest;
3406 ASSERT_TRUE(file_util::ReadFileToString(
3407 path.Append(Extension::kManifestFilename), &manifest));
3408
3409 service_->register_component_extension(
[email protected]eaa7dd182010-12-14 11:09:003410 ExtensionService::ComponentExtensionInfo(manifest, path));
[email protected]1952c7d2010-03-04 23:48:343411 service_->Init();
3412
3413 // Note that we do not pump messages -- the extension should be loaded
3414 // immediately.
3415
3416 EXPECT_EQ(0u, GetErrors().size());
3417 ASSERT_EQ(1u, loaded_.size());
3418 EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location());
3419 EXPECT_EQ(1u, service_->extensions()->size());
3420
3421 // Component extensions shouldn't get recourded in the prefs.
3422 ValidatePrefKeyCount(0);
3423
3424 // Reload all extensions, and make sure it comes back.
3425 std::string extension_id = service_->extensions()->at(0)->id();
3426 loaded_.clear();
3427 service_->ReloadExtensions();
3428 ASSERT_EQ(1u, service_->extensions()->size());
3429 EXPECT_EQ(extension_id, service_->extensions()->at(0)->id());
3430}
[email protected]145a317b2011-04-12 16:03:463431
[email protected]90310d92011-04-17 07:35:043432namespace {
3433
3434bool AlwaysInstall(const Extension& extension) {
3435 return true;
3436}
3437
3438} // namespace
3439
3440TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
3441 InitializeEmptyExtensionService();
3442
3443 ExtensionSyncData extension_sync_data;
3444 extension_sync_data.id = good_crx;
3445 extension_sync_data.uninstalled = true;
3446
3447 // Should do nothing.
3448 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3449
3450 // Install the extension.
3451 FilePath extension_path = data_dir_.AppendASCII("good.crx");
3452 InstallCrx(extension_path, true);
3453 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3454
3455 // Should uninstall the extension.
3456 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3457 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
3458
3459 // Should again do nothing.
3460 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3461}
3462
3463
3464TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
3465 InitializeEmptyExtensionService();
3466
3467 FilePath extension_path = data_dir_.AppendASCII("good.crx");
3468 InstallCrx(extension_path, true);
3469 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3470 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3471
3472 ExtensionSyncData extension_sync_data;
3473 extension_sync_data.id = good_crx;
3474 extension_sync_data.version =
3475 *(service_->GetExtensionById(good_crx, true)->version());
3476
3477 extension_sync_data.enabled = false;
3478 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3479 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
3480 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3481
3482 extension_sync_data.enabled = true;
3483 extension_sync_data.incognito_enabled = true;
3484 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3485 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3486 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
3487
3488 extension_sync_data.enabled = false;
3489 extension_sync_data.incognito_enabled = true;
3490 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3491 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
3492 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
3493
3494 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
3495}
3496
3497TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
3498 InitializeExtensionServiceWithUpdater();
3499
3500 // Install the extension.
3501 FilePath extension_path = data_dir_.AppendASCII("good.crx");
3502 InstallCrx(extension_path, true);
3503 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3504 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3505
3506 ExtensionSyncData extension_sync_data;
3507 extension_sync_data.id = good_crx;
3508 extension_sync_data.enabled = true;
3509 extension_sync_data.version =
3510 *(service_->GetExtensionById(good_crx, true)->version());
3511
3512 // Should do nothing if extension version == sync version.
3513 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3514 EXPECT_FALSE(service_->updater()->WillCheckSoon());
3515
3516 // Should do nothing if extension version > sync version (but see
3517 // the TODO in ProcessSyncData).
3518 {
3519 scoped_ptr<Version> version(Version::GetVersionFromString("0.0.0.0"));
3520 extension_sync_data.version = *version;
3521 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3522 EXPECT_FALSE(service_->updater()->WillCheckSoon());
3523 }
3524
3525 // Should kick off an update if extension version < sync version.
3526 {
3527 scoped_ptr<Version> version(Version::GetVersionFromString("9.9.9.9"));
3528 extension_sync_data.version = *version;
3529 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3530 EXPECT_TRUE(service_->updater()->WillCheckSoon());
3531 }
3532
3533 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
3534}
3535
3536TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
3537 InitializeExtensionServiceWithUpdater();
3538
3539 ExtensionSyncData extension_sync_data;
3540 extension_sync_data.id = good_crx;
3541 extension_sync_data.update_url = GURL("http://www.google.com");
3542 extension_sync_data.enabled = true;
3543 {
3544 scoped_ptr<Version> version(Version::GetVersionFromString("1.2.3.4"));
3545 extension_sync_data.version = *version;
3546 }
3547
3548 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3549 EXPECT_TRUE(service_->updater()->WillCheckSoon());
3550
3551 PendingExtensionInfo info;
3552 EXPECT_TRUE(
3553 service_->pending_extension_manager()->GetById(good_crx, &info));
3554 EXPECT_EQ(extension_sync_data.update_url, info.update_url());
3555 EXPECT_TRUE(info.is_from_sync());
3556 EXPECT_TRUE(info.install_silently());
3557 EXPECT_EQ(extension_sync_data.enabled, info.enable_on_install());
3558 EXPECT_EQ(extension_sync_data.incognito_enabled,
3559 info.enable_incognito_on_install());
3560 EXPECT_EQ(Extension::INTERNAL, info.install_source());
3561 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
3562}
3563
[email protected]145a317b2011-04-12 16:03:463564// Test that when multiple sources try to install an extension,
3565// we consistently choose the right one. To make tests easy to read,
3566// methods that fake requests to install crx files in several ways
3567// are provided.
3568class ExtensionSourcePriorityTest : public ExtensionServiceTest {
3569 public:
3570 void SetUp() {
[email protected]ed8ee722011-04-22 06:49:443571 ExtensionServiceTest::SetUp();
3572
[email protected]145a317b2011-04-12 16:03:463573 // All tests use a single extension. Put the id and path in member vars
3574 // that all methods can read.
3575 crx_id_ = kGoodId;
[email protected]e85e34c32011-04-13 18:38:353576 crx_path_ = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:463577 }
3578
3579 // Fake an external source adding a URL to fetch an extension from.
3580 void AddPendingExternalPrefUrl() {
3581 service_->pending_extension_manager()->AddFromExternalUpdateUrl(
3582 crx_id_, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
3583 }
3584
3585 // Fake an external file from external_extensions.json.
3586 void AddPendingExternalPrefFileInstall() {
3587 scoped_ptr<Version> version;
3588 version.reset(Version::GetVersionFromString("1.0.0.0"));
3589
3590 service_->OnExternalExtensionFileFound(
3591 crx_id_, version.get(), crx_path_, Extension::EXTERNAL_PREF);
3592 }
3593
3594 // Fake a request from sync to install an extension.
3595 bool AddPendingSyncInstall() {
3596 return service_->pending_extension_manager()->AddFromSync(
3597 crx_id_, GURL(kGoodUpdateURL), &IsExtension,
3598 kGoodInstallSilently, kGoodInitialState,
3599 kGoodInitialIncognitoEnabled);
3600 }
3601
3602 // Fake a request to install a default app.
3603 void AddPendingDefaultAppInstall() {
3604 service_->pending_extension_manager()->AddFromDefaultAppList(crx_id_);
3605 }
3606
3607 // Fake a policy install.
3608 void AddPendingPolicyInstall() {
3609 scoped_ptr<Version> version;
3610 version.reset(Version::GetVersionFromString("1.0.0.0"));
3611
3612 // Get path to the CRX with id |kGoodId|.
3613 service_->OnExternalExtensionUpdateUrlFound(
3614 crx_id_, GURL(), Extension::EXTERNAL_POLICY_DOWNLOAD);
3615 }
3616
3617 // Get the install source of a pending extension.
3618 Extension::Location GetPendingLocation() {
3619 PendingExtensionInfo info;
3620 EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info));
3621 return info.install_source();
3622 }
3623
3624 // Is an extension pending from a sync request?
3625 bool GetPendingIsFromSync() {
3626 PendingExtensionInfo info;
3627 EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info));
3628 return info.is_from_sync();
3629 }
3630
3631 // Is the CRX id these tests use pending?
3632 bool IsCrxPending() {
3633 return service_->pending_extension_manager()->IsIdPending(crx_id_);
3634 }
3635
3636 // Is an extension installed?
3637 bool IsCrxInstalled() {
3638 return (service_->GetExtensionById(crx_id_, true) != NULL);
3639 }
3640
3641 protected:
3642 // All tests use a single extension. Making the id and path member
3643 // vars avoids pasing the same argument to every method.
3644 std::string crx_id_;
3645 FilePath crx_path_;
3646};
3647
[email protected]3634ebd2011-04-20 00:34:123648// Test that a pending request for installation of an external CRX from
3649// an update URL overrides a pending request to install the same extension
3650// from sync.
[email protected]ed8ee722011-04-22 06:49:443651TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
[email protected]145a317b2011-04-12 16:03:463652 InitializeEmptyExtensionService();
3653
3654 ASSERT_FALSE(IsCrxInstalled());
3655
3656 // Install pending extension from sync.
3657 AddPendingSyncInstall();
3658 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3659 EXPECT_TRUE(GetPendingIsFromSync());
3660 ASSERT_FALSE(IsCrxInstalled());
3661
3662 // Install pending as external prefs json would.
3663 AddPendingExternalPrefFileInstall();
3664 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3665 ASSERT_FALSE(IsCrxInstalled());
3666
3667 // Another request from sync should be ignorred.
3668 AddPendingSyncInstall();
3669 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3670 ASSERT_FALSE(IsCrxInstalled());
3671
3672 WaitForCrxInstall(crx_path_, true);
3673 ASSERT_TRUE(IsCrxInstalled());
3674}
3675
3676// Test that an install of an external CRX from an update overrides
3677// an install of the same extension from sync.
[email protected]ed8ee722011-04-22 06:49:443678TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
[email protected]145a317b2011-04-12 16:03:463679 InitializeEmptyExtensionService();
3680 ASSERT_FALSE(IsCrxInstalled());
3681
3682 AddPendingSyncInstall();
3683 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3684 EXPECT_TRUE(GetPendingIsFromSync());
3685 ASSERT_FALSE(IsCrxInstalled());
3686
3687 AddPendingExternalPrefUrl();
3688 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
3689 EXPECT_FALSE(GetPendingIsFromSync());
3690 ASSERT_FALSE(IsCrxInstalled());
3691
3692 AddPendingSyncInstall();
3693 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
3694 EXPECT_FALSE(GetPendingIsFromSync());
3695 ASSERT_FALSE(IsCrxInstalled());
3696}
3697
3698// Test that an install of an external CRX overrides a request for a default
3699// app.
[email protected]ed8ee722011-04-22 06:49:443700TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverDefaultApp) {
[email protected]145a317b2011-04-12 16:03:463701 InitializeEmptyExtensionService();
3702 ASSERT_FALSE(IsCrxInstalled());
3703
3704 AddPendingDefaultAppInstall();
3705 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3706 ASSERT_FALSE(IsCrxInstalled());
3707
3708 AddPendingExternalPrefFileInstall();
3709 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3710 ASSERT_FALSE(IsCrxInstalled());
3711
3712 AddPendingDefaultAppInstall();
3713 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3714 ASSERT_FALSE(IsCrxInstalled());
3715
3716 WaitForCrxInstall(crx_path_, true);
3717 ASSERT_TRUE(IsCrxInstalled());
3718}
3719
3720// Test that an external install request stops sync from installing
3721// the same extension.
[email protected]ed8ee722011-04-22 06:49:443722TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
[email protected]145a317b2011-04-12 16:03:463723 InitializeEmptyExtensionService();
3724 ASSERT_FALSE(IsCrxInstalled());
3725
3726 // External prefs starts an install.
3727 AddPendingExternalPrefFileInstall();
3728
3729 // Crx installer was made, but has not yet run.
3730 ASSERT_FALSE(IsCrxInstalled());
3731
3732 // Before the CRX installer runs, Sync requests that the same extension
3733 // be installed. Should fail, because an external source is pending.
3734 ASSERT_FALSE(AddPendingSyncInstall());
3735
3736 // Wait for the external source to install.
3737 WaitForCrxInstall(crx_path_, true);
3738 ASSERT_TRUE(IsCrxInstalled());
3739
3740 // Now that the extension is installed, sync request should fail
3741 // because the extension is already installed.
3742 ASSERT_FALSE(AddPendingSyncInstall());
3743}