blob: 78d2efd3575d1d8f445c753da3779f982db2c010 [file] [log] [blame]
[email protected]a03d4448f2012-01-10 23:25:281// Copyright (c) 2012 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]be5a6db2012-11-13 14:39:1111#include "base/at_exit.h"
[email protected]24b538a2010-02-27 01:22:4412#include "base/basictypes.h"
[email protected]c4148a72011-08-09 23:04:2013#include "base/bind.h"
[email protected]36a784c2009-06-23 06:21:0814#include "base/command_line.h"
[email protected]6014d672008-12-05 00:38:2515#include "base/file_util.h"
[email protected]ea1a3f62012-11-16 20:34:2316#include "base/files/scoped_temp_dir.h"
[email protected]ffbec692012-02-26 20:26:4217#include "base/json/json_file_value_serializer.h"
[email protected]93d49d72009-10-23 20:00:2018#include "base/json/json_reader.h"
[email protected]ffbec692012-02-26 20:26:4219#include "base/json/json_string_value_serializer.h"
[email protected]3b63f8f42011-03-28 01:54:1520#include "base/memory/scoped_ptr.h"
[email protected]71cb8aa2011-12-29 19:14:0021#include "base/memory/weak_ptr.h"
[email protected]6014d672008-12-05 00:38:2522#include "base/message_loop.h"
23#include "base/path_service.h"
[email protected]7286e3fc2011-07-19 22:13:2424#include "base/stl_util.h"
[email protected]24b538a2010-02-27 01:22:4425#include "base/string16.h"
[email protected]e83326f2010-07-31 17:29:2526#include "base/string_number_conversions.h"
[email protected]6014d672008-12-05 00:38:2527#include "base/string_util.h"
[email protected]be1ce6a72010-08-03 14:35:2228#include "base/utf_string_conversions.h"
[email protected]aa142702010-03-26 01:26:3329#include "base/version.h"
[email protected]9d32ded072011-10-11 16:31:0530#include "chrome/browser/browser_process.h"
[email protected]5db9ada2012-04-11 13:48:2031#include "chrome/browser/extensions/app_sync_data.h"
[email protected]d8c8f25f2011-11-02 18:18:0132#include "chrome/browser/extensions/component_loader.h"
[email protected]eb6c7ef2011-12-12 23:12:2033#include "chrome/browser/extensions/crx_installer.h"
[email protected]a7cd28e2012-10-05 21:03:3634#include "chrome/browser/extensions/default_apps.h"
[email protected]a17f9462009-06-09 02:56:4135#include "chrome/browser/extensions/extension_creator.h"
[email protected]14a000d2010-04-29 21:44:2436#include "chrome/browser/extensions/extension_error_reporter.h"
[email protected]89226982012-07-16 20:09:1837#include "chrome/browser/extensions/extension_error_ui.h"
[email protected]eaa7dd182010-12-14 11:09:0038#include "chrome/browser/extensions/extension_service.h"
[email protected]1bcf30e2012-03-10 01:06:4139#include "chrome/browser/extensions/extension_sorting.h"
[email protected]19eb80152011-02-26 00:28:4340#include "chrome/browser/extensions/extension_special_storage_policy.h"
[email protected]90310d92011-04-17 07:35:0441#include "chrome/browser/extensions/extension_sync_data.h"
[email protected]31d8f5f22012-04-02 15:22:0842#include "chrome/browser/extensions/extension_system.h"
[email protected]612a1cb12012-10-17 13:18:0343#include "chrome/browser/extensions/external_install_ui.h"
[email protected]e410b5f2012-12-14 14:02:2444#include "chrome/browser/extensions/external_policy_loader.h"
[email protected]5df038b2012-07-16 19:03:2745#include "chrome/browser/extensions/external_pref_loader.h"
46#include "chrome/browser/extensions/external_provider_impl.h"
47#include "chrome/browser/extensions/external_provider_interface.h"
[email protected]d8c8f25f2011-11-02 18:18:0148#include "chrome/browser/extensions/installed_loader.h"
[email protected]fdd679b2012-11-15 20:49:3949#include "chrome/browser/extensions/management_policy.h"
[email protected]f0bfe622012-06-22 01:01:4450#include "chrome/browser/extensions/pack_extension_job.h"
[email protected]90310d92011-04-17 07:35:0451#include "chrome/browser/extensions/pending_extension_info.h"
52#include "chrome/browser/extensions/pending_extension_manager.h"
[email protected]31d8f5f22012-04-02 15:22:0853#include "chrome/browser/extensions/test_extension_system.h"
[email protected]65187152012-06-02 13:14:1454#include "chrome/browser/extensions/test_management_policy.h"
[email protected]d8c8f25f2011-11-02 18:18:0155#include "chrome/browser/extensions/unpacked_installer.h"
[email protected]42a08162012-03-16 18:09:1156#include "chrome/browser/extensions/updater/extension_updater.h"
[email protected]0f5e57f52012-09-20 20:53:1857#include "chrome/browser/plugins/plugin_prefs_factory.h"
[email protected]37858e52010-08-26 00:22:0258#include "chrome/browser/prefs/browser_prefs.h"
[email protected]f2d1f612010-12-09 15:10:1759#include "chrome/browser/prefs/pref_service_mock_builder.h"
[email protected]f89ee342011-03-07 09:28:2760#include "chrome/browser/prefs/scoped_user_pref_update.h"
[email protected]31d8f5f22012-04-02 15:22:0861#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:2762#include "chrome/common/chrome_notification_types.h"
[email protected]37858e52010-08-26 00:22:0263#include "chrome/common/chrome_paths.h"
64#include "chrome/common/chrome_switches.h"
[email protected]5b1a0e22009-05-26 19:00:5865#include "chrome/common/extensions/extension.h"
[email protected]6884a802012-08-07 03:55:2266#include "chrome/common/extensions/extension_l10n_util.h"
[email protected]a52c0e92012-03-23 06:02:2467#include "chrome/common/extensions/extension_manifest_constants.h"
[email protected]942690b132010-05-11 06:42:1468#include "chrome/common/extensions/extension_resource.h"
[email protected]bebe1d02012-08-02 20:17:0969#include "chrome/common/extensions/permissions/permission_set.h"
[email protected]36a784c2009-06-23 06:21:0870#include "chrome/common/pref_names.h"
[email protected]24b538a2010-02-27 01:22:4471#include "chrome/common/url_constants.h"
[email protected]a4ff9eae2011-08-01 19:58:1672#include "chrome/test/base/testing_profile.h"
[email protected]35cc399e2012-02-23 18:19:2873#include "content/public/browser/dom_storage_context.h"
[email protected]98270432012-09-11 20:51:2474#include "content/public/browser/gpu_data_manager.h"
[email protected]35cc399e2012-02-23 18:19:2875#include "content/public/browser/indexed_db_context.h"
[email protected]6c2381d2011-10-19 02:52:5376#include "content/public/browser/notification_registrar.h"
[email protected]ad50def52011-10-19 23:17:0777#include "content/public/browser/notification_service.h"
[email protected]e67385f2011-12-21 06:00:5678#include "content/public/browser/plugin_service.h"
[email protected]5c8e67c2012-08-29 00:48:5279#include "content/public/browser/storage_partition.h"
[email protected]55eb70e762012-02-20 17:38:3980#include "content/public/common/content_constants.h"
[email protected]7e343152012-09-20 21:49:5381#include "content/public/common/gpu_info.h"
[email protected]e97882f2012-06-04 02:23:1782#include "content/public/test/test_browser_thread.h"
[email protected]885c0e92012-11-13 20:27:4283#include "extensions/common/url_pattern.h"
[email protected]24b538a2010-02-27 01:22:4484#include "googleurl/src/gurl.h"
[email protected]b873cd92012-02-09 21:51:4885#include "grit/browser_resources.h"
[email protected]5b9bc352012-07-18 13:13:3486#include "net/cookies/canonical_cookie.h"
[email protected]aa84a7e2012-03-15 21:29:0687#include "net/cookies/cookie_monster.h"
88#include "net/cookies/cookie_options.h"
[email protected]dbbad7a2010-08-13 18:18:3689#include "net/url_request/url_request_context.h"
[email protected]abe2c032011-03-31 18:49:3490#include "net/url_request/url_request_context_getter.h"
[email protected]36b643212012-09-07 12:53:0091#include "sync/api/string_ordinal.h"
[email protected]895a1e52012-05-15 02:50:1292#include "sync/api/sync_error_factory.h"
93#include "sync/api/sync_error_factory_mock.h"
[email protected]1bcf30e2012-03-10 01:06:4194#include "sync/protocol/app_specifics.pb.h"
95#include "sync/protocol/extension_specifics.pb.h"
96#include "sync/protocol/sync.pb.h"
[email protected]6014d672008-12-05 00:38:2597#include "testing/gtest/include/gtest/gtest.h"
[email protected]f66c110c2008-12-05 20:26:2998#include "testing/platform_test.h"
[email protected]24b538a2010-02-27 01:22:4499#include "webkit/database/database_tracker.h"
100#include "webkit/database/database_util.h"
[email protected]eb6c7ef2011-12-12 23:12:20101#include "webkit/plugins/npapi/mock_plugin_list.h"
[email protected]c62983a72011-05-09 06:29:59102#include "webkit/quota/quota_manager.h"
[email protected]6014d672008-12-05 00:38:25103
[email protected]55eb70e762012-02-20 17:38:39104using content::BrowserContext;
[email protected]631bb742011-11-02 11:29:39105using content::BrowserThread;
[email protected]35cc399e2012-02-23 18:19:28106using content::DOMStorageContext;
107using content::IndexedDBContext;
[email protected]e67385f2011-12-21 06:00:56108using content::PluginService;
[email protected]c2e66e12012-06-27 06:27:06109using extensions::APIPermission;
110using extensions::APIPermissionSet;
[email protected]bf3d9df2012-07-24 23:20:27111using extensions::CrxInstaller;
[email protected]1c321ee52012-05-21 03:02:34112using extensions::Extension;
[email protected]6d777492012-07-11 17:33:43113using extensions::ExtensionCreator;
[email protected]45759612012-07-10 17:21:23114using extensions::ExtensionPrefs;
[email protected]bd306722012-07-11 20:43:59115using extensions::ExtensionSystem;
[email protected]00b5d0a52012-10-30 13:13:53116using extensions::FeatureSwitch;
[email protected]c2e66e12012-06-27 06:27:06117using extensions::PermissionSet;
[email protected]e9f541a2012-11-19 21:52:31118using extensions::URLPatternSet;
[email protected]631bb742011-11-02 11:29:39119
[email protected]c6d474f82009-12-16 21:11:06120namespace keys = extension_manifest_keys;
121
[email protected]f0397fa2008-12-11 17:59:58122namespace {
123
[email protected]df4956e2009-06-10 16:53:42124// Extension ids used during testing.
[email protected]5a2721f62009-06-13 07:08:20125const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
126const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
127const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj";
128const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk";
129const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
130const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
[email protected]07c9f2f42012-02-29 18:45:22131const char* const hosted_app = "kbmnembihfiondgfjekmnmcbddelicoi";
[email protected]d7eaf572009-07-01 21:57:00132const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln";
[email protected]5a2721f62009-06-13 07:08:20133const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad";
134const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
[email protected]8d888c12010-11-30 00:00:25135const char* const permissions_crx = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
[email protected]c24fb292012-02-01 22:52:11136const char* const unpacked = "cbcdidchbppangcjoddlpdjlenngjldk";
[email protected]df4956e2009-06-10 16:53:42137
[email protected]f0397fa2008-12-11 17:59:58138struct ExtensionsOrder {
139 bool operator()(const Extension* a, const Extension* b) {
140 return a->name() < b->name();
141 }
142};
143
[email protected]fc670822011-12-17 09:33:49144static std::vector<string16> GetErrors() {
145 const std::vector<string16>* errors =
[email protected]bb28e062009-02-27 17:19:18146 ExtensionErrorReporter::GetInstance()->GetErrors();
[email protected]fc670822011-12-17 09:33:49147 std::vector<string16> ret_val;
[email protected]bb28e062009-02-27 17:19:18148
[email protected]fc670822011-12-17 09:33:49149 for (std::vector<string16>::const_iterator iter = errors->begin();
[email protected]bb28e062009-02-27 17:19:18150 iter != errors->end(); ++iter) {
[email protected]fc670822011-12-17 09:33:49151 std::string utf8_error = UTF16ToUTF8(*iter);
152 if (utf8_error.find(".svn") == std::string::npos) {
[email protected]bb28e062009-02-27 17:19:18153 ret_val.push_back(*iter);
154 }
155 }
156
157 // The tests rely on the errors being in a certain order, which can vary
158 // depending on how filesystem iteration works.
159 std::stable_sort(ret_val.begin(), ret_val.end());
160
161 return ret_val;
162}
163
[email protected]cced75a2011-05-20 08:31:12164static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
[email protected]8d888c12010-11-30 00:00:25165 int schemes = URLPattern::SCHEME_ALL;
166 extent->AddPattern(URLPattern(schemes, pattern));
167}
168
[email protected]f0397fa2008-12-11 17:59:58169} // namespace
[email protected]6014d672008-12-05 00:38:25170
[email protected]5df038b2012-07-16 19:03:27171class MockExtensionProvider : public extensions::ExternalProviderInterface {
[email protected]a1257b12009-06-12 02:51:34172 public:
[email protected]a12ce8b22012-01-17 18:40:53173 MockExtensionProvider(
[email protected]8e4560b62011-01-14 10:09:14174 VisitorInterface* visitor,
175 Extension::Location location)
[email protected]f121003b2012-05-04 21:57:47176 : location_(location), visitor_(visitor), visit_count_(0) {
[email protected]a12ce8b22012-01-17 18:40:53177 }
178
[email protected]a1257b12009-06-12 02:51:34179 virtual ~MockExtensionProvider() {}
180
181 void UpdateOrAddExtension(const std::string& id,
182 const std::string& version,
[email protected]f5ad7542009-07-24 17:38:59183 const FilePath& path) {
[email protected]a1257b12009-06-12 02:51:34184 extension_map_[id] = std::make_pair(version, path);
185 }
186
187 void RemoveExtension(const std::string& id) {
188 extension_map_.erase(id);
189 }
190
[email protected]5df038b2012-07-16 19:03:27191 // ExternalProvider implementation:
[email protected]a12ce8b22012-01-17 18:40:53192 virtual void VisitRegisteredExtension() OVERRIDE {
[email protected]0a60a2e2010-10-25 16:15:21193 visit_count_++;
[email protected]a1257b12009-06-12 02:51:34194 for (DataMap::const_iterator i = extension_map_.begin();
195 i != extension_map_.end(); ++i) {
[email protected]12126d372012-07-11 18:40:53196 Version version(i->second.first);
[email protected]a1257b12009-06-12 02:51:34197
[email protected]8e4560b62011-01-14 10:09:14198 visitor_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:53199 i->first, &version, i->second.second, location_,
[email protected]f121003b2012-05-04 21:57:47200 Extension::NO_FLAGS, false);
[email protected]a1257b12009-06-12 02:51:34201 }
[email protected]50067e52011-10-20 23:17:07202 visitor_->OnExternalProviderReady(this);
[email protected]a1257b12009-06-12 02:51:34203 }
204
[email protected]a12ce8b22012-01-17 18:40:53205 virtual bool HasExtension(const std::string& id) const OVERRIDE {
[email protected]0a60a2e2010-10-25 16:15:21206 return extension_map_.find(id) != extension_map_.end();
207 }
208
[email protected]a12ce8b22012-01-17 18:40:53209 virtual bool GetExtensionDetails(
210 const std::string& id,
211 Extension::Location* location,
212 scoped_ptr<Version>* version) const OVERRIDE {
[email protected]a1257b12009-06-12 02:51:34213 DataMap::const_iterator it = extension_map_.find(id);
214 if (it == extension_map_.end())
[email protected]0a60a2e2010-10-25 16:15:21215 return false;
216
217 if (version)
[email protected]12126d372012-07-11 18:40:53218 version->reset(new Version(it->second.first));
[email protected]a1257b12009-06-12 02:51:34219
220 if (location)
221 *location = location_;
[email protected]0a60a2e2010-10-25 16:15:21222
223 return true;
224 }
[email protected]8e4560b62011-01-14 10:09:14225
[email protected]a12ce8b22012-01-17 18:40:53226 virtual bool IsReady() const OVERRIDE {
[email protected]8e4560b62011-01-14 10:09:14227 return true;
228 }
229
[email protected]a12ce8b22012-01-17 18:40:53230 virtual void ServiceShutdown() OVERRIDE {
[email protected]8e4560b62011-01-14 10:09:14231 }
232
[email protected]0a60a2e2010-10-25 16:15:21233 int visit_count() const { return visit_count_; }
234 void set_visit_count(int visit_count) {
235 visit_count_ = visit_count;
[email protected]a1257b12009-06-12 02:51:34236 }
237
238 private:
239 typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap;
240 DataMap extension_map_;
241 Extension::Location location_;
[email protected]8e4560b62011-01-14 10:09:14242 VisitorInterface* visitor_;
[email protected]27b985d2009-06-25 17:53:15243
[email protected]0a60a2e2010-10-25 16:15:21244 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
245 // Mutable because it must be incremented on each call to
246 // VisitRegisteredExtension(), which must be a const method to inherit
247 // from the class being mocked.
248 mutable int visit_count_;
249
[email protected]27b985d2009-06-25 17:53:15250 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
251};
252
[email protected]8e4560b62011-01-14 10:09:14253class MockProviderVisitor
[email protected]5df038b2012-07-16 19:03:27254 : public extensions::ExternalProviderInterface::VisitorInterface {
[email protected]27b985d2009-06-25 17:53:15255 public:
[email protected]f0841cd2011-01-19 15:07:24256 // The provider will return |fake_base_path| from
257 // GetBaseCrxFilePath(). User can test the behavior with
258 // and without an empty path using this parameter.
259 explicit MockProviderVisitor(FilePath fake_base_path)
260 : ids_found_(0),
[email protected]f121003b2012-05-04 21:57:47261 fake_base_path_(fake_base_path),
262 expected_creation_flags_(Extension::NO_FLAGS) {
263 }
264
265 MockProviderVisitor(FilePath fake_base_path, int expected_creation_flags)
266 : ids_found_(0),
267 fake_base_path_(fake_base_path),
268 expected_creation_flags_(expected_creation_flags) {
[email protected]27b985d2009-06-25 17:53:15269 }
270
[email protected]683d0702010-12-06 16:25:57271 int Visit(const std::string& json_data) {
[email protected]27b985d2009-06-25 17:53:15272 // Give the test json file to the provider for parsing.
[email protected]5df038b2012-07-16 19:03:27273 provider_.reset(new extensions::ExternalProviderImpl(
[email protected]8e4560b62011-01-14 10:09:14274 this,
[email protected]5df038b2012-07-16 19:03:27275 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
[email protected]8e4560b62011-01-14 10:09:14276 Extension::EXTERNAL_PREF,
[email protected]1bf73cc32011-10-26 22:38:31277 Extension::EXTERNAL_PREF_DOWNLOAD,
278 Extension::NO_FLAGS));
[email protected]27b985d2009-06-25 17:53:15279
280 // We also parse the file into a dictionary to compare what we get back
281 // from the provider.
282 JSONStringValueSerializer serializer(json_data);
[email protected]ba399672010-04-06 15:42:39283 Value* json_value = serializer.Deserialize(NULL, NULL);
[email protected]27b985d2009-06-25 17:53:15284
[email protected]ba399672010-04-06 15:42:39285 if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
[email protected]e2194742010-08-12 05:54:34286 NOTREACHED() << "Unable to deserialize json data";
[email protected]27b985d2009-06-25 17:53:15287 return -1;
288 } else {
289 DictionaryValue* external_extensions =
290 static_cast<DictionaryValue*>(json_value);
291 prefs_.reset(external_extensions);
292 }
293
294 // Reset our counter.
295 ids_found_ = 0;
[email protected]683d0702010-12-06 16:25:57296 // Ask the provider to look up all extensions and return them.
[email protected]8e4560b62011-01-14 10:09:14297 provider_->VisitRegisteredExtension();
[email protected]27b985d2009-06-25 17:53:15298
299 return ids_found_;
300 }
301
[email protected]9060d8b02012-01-13 02:14:30302 virtual bool OnExternalExtensionFileFound(const std::string& id,
[email protected]8ef78fd2010-08-19 17:14:32303 const Version* version,
304 const FilePath& path,
[email protected]1bf73cc32011-10-26 22:38:31305 Extension::Location unused,
[email protected]47fc70c2011-12-06 07:29:51306 int creation_flags,
307 bool mark_acknowledged) {
[email protected]f121003b2012-05-04 21:57:47308 EXPECT_EQ(expected_creation_flags_, creation_flags);
[email protected]1bf73cc32011-10-26 22:38:31309
[email protected]27b985d2009-06-25 17:53:15310 ++ids_found_;
311 DictionaryValue* pref;
312 // This tests is to make sure that the provider only notifies us of the
313 // values we gave it. So if the id we doesn't exist in our internal
314 // dictionary then something is wrong.
[email protected]e2194742010-08-12 05:54:34315 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
316 << "Got back ID (" << id.c_str() << ") we weren't expecting";
[email protected]27b985d2009-06-25 17:53:15317
[email protected]f0841cd2011-01-19 15:07:24318 EXPECT_TRUE(path.IsAbsolute());
319 if (!fake_base_path_.empty())
320 EXPECT_TRUE(fake_base_path_.IsParent(path));
321
[email protected]27b985d2009-06-25 17:53:15322 if (pref) {
[email protected]0a60a2e2010-10-25 16:15:21323 EXPECT_TRUE(provider_->HasExtension(id));
324
[email protected]27b985d2009-06-25 17:53:15325 // Ask provider if the extension we got back is registered.
326 Extension::Location location = Extension::INVALID;
[email protected]0a60a2e2010-10-25 16:15:21327 scoped_ptr<Version> v1;
328 FilePath crx_path;
329
330 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
331 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
332
333 scoped_ptr<Version> v2;
334 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
[email protected]27b985d2009-06-25 17:53:15335 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
336 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
337 EXPECT_EQ(Extension::EXTERNAL_PREF, location);
338
339 // Remove it so we won't count it ever again.
[email protected]e2194742010-08-12 05:54:34340 prefs_->Remove(id, NULL);
[email protected]27b985d2009-06-25 17:53:15341 }
[email protected]9060d8b02012-01-13 02:14:30342 return true;
[email protected]27b985d2009-06-25 17:53:15343 }
344
[email protected]9060d8b02012-01-13 02:14:30345 virtual bool OnExternalExtensionUpdateUrlFound(
[email protected]21a5a672010-11-04 10:47:42346 const std::string& id, const GURL& update_url,
347 Extension::Location location) {
[email protected]8ef78fd2010-08-19 17:14:32348 ++ids_found_;
349 DictionaryValue* pref;
350 // This tests is to make sure that the provider only notifies us of the
351 // values we gave it. So if the id we doesn't exist in our internal
352 // dictionary then something is wrong.
353 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
354 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
[email protected]21a5a672010-11-04 10:47:42355 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location);
[email protected]8ef78fd2010-08-19 17:14:32356
357 if (pref) {
[email protected]0a60a2e2010-10-25 16:15:21358 EXPECT_TRUE(provider_->HasExtension(id));
359
360 // External extensions with update URLs do not have versions.
361 scoped_ptr<Version> v1;
[email protected]21a5a672010-11-04 10:47:42362 Extension::Location location1 = Extension::INVALID;
363 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
[email protected]0a60a2e2010-10-25 16:15:21364 EXPECT_FALSE(v1.get());
[email protected]21a5a672010-11-04 10:47:42365 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location1);
[email protected]0a60a2e2010-10-25 16:15:21366
[email protected]8ef78fd2010-08-19 17:14:32367 // Remove it so we won't count it again.
368 prefs_->Remove(id, NULL);
369 }
[email protected]9060d8b02012-01-13 02:14:30370 return true;
[email protected]8ef78fd2010-08-19 17:14:32371 }
372
[email protected]50067e52011-10-20 23:17:07373 virtual void OnExternalProviderReady(
[email protected]5df038b2012-07-16 19:03:27374 const extensions::ExternalProviderInterface* provider) {
[email protected]50067e52011-10-20 23:17:07375 EXPECT_EQ(provider, provider_.get());
376 EXPECT_TRUE(provider->IsReady());
[email protected]8e4560b62011-01-14 10:09:14377 }
378
[email protected]27b985d2009-06-25 17:53:15379 private:
380 int ids_found_;
[email protected]f0841cd2011-01-19 15:07:24381 FilePath fake_base_path_;
[email protected]f121003b2012-05-04 21:57:47382 int expected_creation_flags_;
[email protected]5df038b2012-07-16 19:03:27383 scoped_ptr<extensions::ExternalProviderImpl> provider_;
[email protected]27b985d2009-06-25 17:53:15384 scoped_ptr<DictionaryValue> prefs_;
385
386 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
[email protected]a1257b12009-06-12 02:51:34387};
388
[email protected]bf73f0b2010-02-10 19:26:59389// Our message loop may be used in tests which require it to be an IO loop.
[email protected]eaa7dd182010-12-14 11:09:00390ExtensionServiceTestBase::ExtensionServiceTestBase()
[email protected]32e2e9b2011-11-18 18:56:45391 : loop_(MessageLoop::TYPE_IO),
392 service_(NULL),
[email protected]65187152012-06-02 13:14:14393 management_policy_(NULL),
[email protected]8f512c72011-11-22 21:02:50394 expected_extensions_count_(0),
[email protected]ca4b5fa32010-10-09 12:42:18395 ui_thread_(BrowserThread::UI, &loop_),
396 db_thread_(BrowserThread::DB, &loop_),
[email protected]e1dd5622011-12-20 12:28:58397 webkit_thread_(BrowserThread::WEBKIT_DEPRECATED, &loop_),
[email protected]ca4b5fa32010-10-09 12:42:18398 file_thread_(BrowserThread::FILE, &loop_),
[email protected]31dbf9d2011-12-07 01:25:30399 file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING, &loop_),
[email protected]00b5d0a52012-10-30 13:13:53400 io_thread_(BrowserThread::IO, &loop_),
401 override_sideload_wipeout_(
402 FeatureSwitch::sideload_wipeout(), false) {
[email protected]e85e34c32011-04-13 18:38:35403 FilePath test_data_dir;
404 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
405 ADD_FAILURE();
406 return;
407 }
408 data_dir_ = test_data_dir.AppendASCII("extensions");
[email protected]bf73f0b2010-02-10 19:26:59409}
410
[email protected]eaa7dd182010-12-14 11:09:00411ExtensionServiceTestBase::~ExtensionServiceTestBase() {
412 // Drop our reference to ExtensionService and TestingProfile, so that they
[email protected]ca4b5fa32010-10-09 12:42:18413 // can be destroyed while BrowserThreads and MessageLoop are still around
414 // (they are used in the destruction process).
[email protected]bf73f0b2010-02-10 19:26:59415 service_ = NULL;
[email protected]b8f50ce2012-11-17 12:37:57416 MessageLoop::current()->RunUntilIdle();
[email protected]c10da4b02010-03-25 14:38:32417 profile_.reset(NULL);
[email protected]b8f50ce2012-11-17 12:37:57418 MessageLoop::current()->RunUntilIdle();
[email protected]bf73f0b2010-02-10 19:26:59419}
420
[email protected]eaa7dd182010-12-14 11:09:00421void ExtensionServiceTestBase::InitializeExtensionService(
[email protected]bb05cae12012-09-06 00:37:52422 const FilePath& profile_path,
423 const FilePath& pref_file,
424 const FilePath& extensions_install_dir,
[email protected]90310d92011-04-17 07:35:04425 bool autoupdate_enabled) {
[email protected]bb05cae12012-09-06 00:37:52426 TestingProfile::Builder profile_builder;
[email protected]f2d1f612010-12-09 15:10:17427 // Create a PrefService that only contains user defined preference values.
[email protected]bb05cae12012-09-06 00:37:52428 scoped_ptr<PrefService> prefs(
[email protected]0de615a2012-11-08 04:40:59429 PrefServiceMockBuilder().WithUserFilePrefs(
430 pref_file, loop_.message_loop_proxy()).Create());
[email protected]bb05cae12012-09-06 00:37:52431 Profile::RegisterUserPrefs(prefs.get());
432 chrome::RegisterUserPrefs(prefs.get());
433 profile_builder.SetPrefService(prefs.Pass());
434 profile_builder.SetPath(profile_path);
435 profile_ = profile_builder.Build();
[email protected]bf73f0b2010-02-10 19:26:59436
[email protected]bd306722012-07-11 20:43:59437 service_ = static_cast<extensions::TestExtensionSystem*>(
[email protected]bb05cae12012-09-06 00:37:52438 ExtensionSystem::Get(profile_.get()))->CreateExtensionService(
[email protected]31d8f5f22012-04-02 15:22:08439 CommandLine::ForCurrentProcess(),
440 extensions_install_dir,
441 autoupdate_enabled);
[email protected]7f8f24f2012-11-15 19:40:14442 service_->SetFileTaskRunnerForTesting(loop_.message_loop_proxy());
[email protected]bf73f0b2010-02-10 19:26:59443 service_->set_extensions_enabled(true);
444 service_->set_show_extensions_prompts(false);
[email protected]fc332ae2012-11-14 20:17:33445 service_->set_install_updates_when_idle_for_test(false);
[email protected]bf73f0b2010-02-10 19:26:59446
[email protected]fdd679b2012-11-15 20:49:39447 management_policy_ =
448 ExtensionSystem::Get(profile_.get())->management_policy();
[email protected]65187152012-06-02 13:14:14449
[email protected]bf73f0b2010-02-10 19:26:59450 // When we start up, we want to make sure there is no external provider,
451 // since the ExtensionService on Windows will use the Registry as a default
452 // provider and if there is something already registered there then it will
453 // interfere with the tests. Those tests that need an external provider
454 // will register one specifically.
455 service_->ClearProvidersForTesting();
456
[email protected]8f512c72011-11-22 21:02:50457 expected_extensions_count_ = 0;
[email protected]bf73f0b2010-02-10 19:26:59458}
459
[email protected]eaa7dd182010-12-14 11:09:00460void ExtensionServiceTestBase::InitializeInstalledExtensionService(
[email protected]bf73f0b2010-02-10 19:26:59461 const FilePath& prefs_file, const FilePath& source_install_dir) {
462 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]bb05cae12012-09-06 00:37:52463 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 temp_prefs = path.Append(FILE_PATH_LITERAL("Preferences"));
[email protected]bf73f0b2010-02-10 19:26:59468 file_util::CopyFile(prefs_file, temp_prefs);
469
[email protected]bb05cae12012-09-06 00:37:52470 extensions_install_dir_ = path.Append(FILE_PATH_LITERAL("Extensions"));
[email protected]bf73f0b2010-02-10 19:26:59471 file_util::Delete(extensions_install_dir_, true);
472 file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
473
[email protected]bb05cae12012-09-06 00:37:52474 InitializeExtensionService(path, temp_prefs, extensions_install_dir_, false);
[email protected]bf73f0b2010-02-10 19:26:59475}
476
[email protected]eaa7dd182010-12-14 11:09:00477void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
[email protected]90310d92011-04-17 07:35:04478 InitializeExtensionServiceHelper(false);
479}
480
[email protected]406b5a92011-11-08 11:58:26481void ExtensionServiceTestBase::InitializeExtensionProcessManager() {
[email protected]bd306722012-07-11 20:43:59482 static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:24483 ExtensionSystem::Get(profile_.get()))->
[email protected]31d8f5f22012-04-02 15:22:08484 CreateExtensionProcessManager();
[email protected]406b5a92011-11-08 11:58:26485}
486
[email protected]90310d92011-04-17 07:35:04487void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
488 InitializeExtensionServiceHelper(true);
489 service_->updater()->Start();
490}
491
492void ExtensionServiceTestBase::InitializeExtensionServiceHelper(
493 bool autoupdate_enabled) {
[email protected]bf73f0b2010-02-10 19:26:59494 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]bb05cae12012-09-06 00:37:52495 FilePath path = temp_dir_.path();
496 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
497 file_util::Delete(path, true);
498 file_util::CreateDirectory(path);
499 FilePath prefs_filename = path.Append(FILE_PATH_LITERAL("TestPreferences"));
500 extensions_install_dir_ = path.Append(FILE_PATH_LITERAL("Extensions"));
[email protected]bf73f0b2010-02-10 19:26:59501 file_util::Delete(extensions_install_dir_, true);
502 file_util::CreateDirectory(extensions_install_dir_);
503
[email protected]bb05cae12012-09-06 00:37:52504 InitializeExtensionService(path, prefs_filename, extensions_install_dir_,
[email protected]90310d92011-04-17 07:35:04505 autoupdate_enabled);
[email protected]bf73f0b2010-02-10 19:26:59506}
507
[email protected]0d6ec3a72011-09-02 02:09:43508void ExtensionServiceTestBase::InitializeRequestContext() {
509 ASSERT_TRUE(profile_.get());
[email protected]31d8f5f22012-04-02 15:22:08510 TestingProfile* profile =
511 static_cast<TestingProfile*>(profile_.get());
[email protected]0d6ec3a72011-09-02 02:09:43512 profile->CreateRequestContext();
513}
514
[email protected]bf73f0b2010-02-10 19:26:59515// static
[email protected]eaa7dd182010-12-14 11:09:00516void ExtensionServiceTestBase::SetUpTestCase() {
[email protected]bf73f0b2010-02-10 19:26:59517 ExtensionErrorReporter::Init(false); // no noisy errors
518}
519
[email protected]eaa7dd182010-12-14 11:09:00520void ExtensionServiceTestBase::SetUp() {
[email protected]bf73f0b2010-02-10 19:26:59521 ExtensionErrorReporter::GetInstance()->ClearErrors();
522}
523
[email protected]eaa7dd182010-12-14 11:09:00524class ExtensionServiceTest
[email protected]6c2381d2011-10-19 02:52:53525 : public ExtensionServiceTestBase, public content::NotificationObserver {
[email protected]bf73f0b2010-02-10 19:26:59526 public:
[email protected]612a1cb12012-10-17 13:18:03527 ExtensionServiceTest()
528 : installed_(NULL),
529 override_external_install_prompt_(
[email protected]00b5d0a52012-10-30 13:13:53530 FeatureSwitch::prompt_for_external_extensions(), false) {
[email protected]432115822011-07-10 15:52:27531 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
[email protected]ad50def52011-10-19 23:17:07532 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27533 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]ad50def52011-10-19 23:17:07534 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27535 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
[email protected]ad50def52011-10-19 23:17:07536 content::NotificationService::AllSources());
[email protected]a9b00ac2009-06-25 21:03:23537 }
[email protected]cc655912009-01-29 23:19:19538
[email protected]432115822011-07-10 15:52:27539 virtual void Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53540 const content::NotificationSource& source,
541 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27542 switch (type) {
543 case chrome::NOTIFICATION_EXTENSION_LOADED: {
[email protected]6c2381d2011-10-19 02:52:53544 const Extension* extension =
545 content::Details<const Extension>(details).ptr();
[email protected]00cd9c42010-11-02 20:15:57546 loaded_.push_back(make_scoped_refptr(extension));
[email protected]894bb502009-05-21 22:39:57547 // The tests rely on the errors being in a certain order, which can vary
548 // depending on how filesystem iteration works.
549 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
550 break;
551 }
552
[email protected]432115822011-07-10 15:52:27553 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
[email protected]a9f39a312010-12-23 22:14:27554 const Extension* e =
[email protected]1c321ee52012-05-21 03:02:34555 content::Details<extensions::UnloadedExtensionInfo>(
556 details)->extension;
[email protected]9f1087e2009-06-15 17:29:32557 unloaded_id_ = e->id();
[email protected]1c321ee52012-05-21 03:02:34558 extensions::ExtensionList::iterator i =
[email protected]9f1087e2009-06-15 17:29:32559 std::find(loaded_.begin(), loaded_.end(), e);
560 // TODO(erikkay) fix so this can be an assert. Right now the tests
561 // are manually calling clear() on loaded_, so this isn't doable.
562 if (i == loaded_.end())
563 return;
564 loaded_.erase(i);
[email protected]894bb502009-05-21 22:39:57565 break;
[email protected]9f1087e2009-06-15 17:29:32566 }
[email protected]432115822011-07-10 15:52:27567 case chrome::NOTIFICATION_EXTENSION_INSTALLED:
[email protected]6c2381d2011-10-19 02:52:53568 installed_ = content::Details<const Extension>(details).ptr();
[email protected]894bb502009-05-21 22:39:57569 break;
570
[email protected]894bb502009-05-21 22:39:57571 default:
572 DCHECK(false);
[email protected]3acbd422008-12-08 18:25:00573 }
574 }
575
[email protected]5df038b2012-07-16 19:03:27576 void AddMockExternalProvider(
577 extensions::ExternalProviderInterface* provider) {
[email protected]0a60a2e2010-10-25 16:15:21578 service_->AddProviderForTesting(provider);
[email protected]a1257b12009-06-12 02:51:34579 }
580
[email protected]9197f3b2009-06-02 00:49:27581 protected:
[email protected]d55e7602009-12-16 04:20:42582 void TestExternalProvider(MockExtensionProvider* provider,
583 Extension::Location location);
584
[email protected]8f512c72011-11-22 21:02:50585 void PackCRX(const FilePath& dir_path,
586 const FilePath& pem_path,
587 const FilePath& crx_path) {
[email protected]8d888c12010-11-30 00:00:25588 // Use the existing pem key, if provided.
589 FilePath pem_output_path;
590 if (pem_path.value().empty()) {
591 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
[email protected]8d888c12010-11-30 00:00:25592 } else {
593 ASSERT_TRUE(file_util::PathExists(pem_path));
594 }
[email protected]3ba0fd32010-06-19 05:39:10595
596 ASSERT_TRUE(file_util::Delete(crx_path, false));
[email protected]8d888c12010-11-30 00:00:25597
[email protected]3ba0fd32010-06-19 05:39:10598 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
[email protected]8d888c12010-11-30 00:00:25599 ASSERT_TRUE(creator->Run(dir_path,
600 crx_path,
601 pem_path,
[email protected]93d973a2012-01-08 07:38:26602 pem_output_path,
603 ExtensionCreator::kOverwriteCRX));
[email protected]8d888c12010-11-30 00:00:25604
[email protected]3ba0fd32010-06-19 05:39:10605 ASSERT_TRUE(file_util::PathExists(crx_path));
[email protected]8d888c12010-11-30 00:00:25606 }
607
[email protected]53da2c962011-03-03 17:08:05608 // Create a CrxInstaller and start installation. To allow the install
[email protected]b8f50ce2012-11-17 12:37:57609 // to happen, use loop_.RunUntilIdle();. Most tests will not use this
[email protected]145a317b2011-04-12 16:03:46610 // method directly. Instead, use InstallCrx(), which waits for
[email protected]53da2c962011-03-03 17:08:05611 // the crx to be installed and does extra error checking.
[email protected]8f512c72011-11-22 21:02:50612 void StartCRXInstall(const FilePath& crx_path) {
[email protected]be083862012-09-01 03:53:45613 StartCRXInstall(crx_path, Extension::NO_FLAGS);
[email protected]8266d662011-07-12 21:53:26614 }
615
[email protected]be083862012-09-01 03:53:45616 void StartCRXInstall(const FilePath& crx_path, int creation_flags) {
[email protected]b2907fd2011-03-25 16:43:37617 ASSERT_TRUE(file_util::PathExists(crx_path))
618 << "Path does not exist: "<< crx_path.value().c_str();
[email protected]d8c8f25f2011-11-02 18:18:01619 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
[email protected]be083862012-09-01 03:53:45620 installer->set_creation_flags(creation_flags);
621 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT)) {
622 installer->set_allow_silent_install(true);
623 }
[email protected]53da2c962011-03-03 17:08:05624 installer->InstallCrx(crx_path);
625 }
626
[email protected]8f512c72011-11-22 21:02:50627 enum InstallState {
628 INSTALL_FAILED,
629 INSTALL_UPDATED,
[email protected]695b5712012-12-06 23:55:28630 INSTALL_NEW,
631 INSTALL_WITHOUT_LOAD,
[email protected]8f512c72011-11-22 21:02:50632 };
633
634 const Extension* PackAndInstallCRX(const FilePath& dir_path,
635 const FilePath& pem_path,
[email protected]be083862012-09-01 03:53:45636 InstallState install_state,
637 int creation_flags) {
[email protected]8f512c72011-11-22 21:02:50638 FilePath crx_path;
[email protected]ea1a3f62012-11-16 20:34:23639 base::ScopedTempDir temp_dir;
[email protected]8f512c72011-11-22 21:02:50640 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
641 crx_path = temp_dir.path().AppendASCII("temp.crx");
642
643 PackCRX(dir_path, pem_path, crx_path);
[email protected]be083862012-09-01 03:53:45644 return InstallCRX(crx_path, install_state, creation_flags);
645 }
646
647 const Extension* PackAndInstallCRX(const FilePath& dir_path,
648 const FilePath& pem_path,
649 InstallState install_state) {
650 return PackAndInstallCRX(dir_path, pem_path, install_state,
651 Extension::NO_FLAGS);
[email protected]145a317b2011-04-12 16:03:46652 }
653
[email protected]8f512c72011-11-22 21:02:50654 const Extension* PackAndInstallCRX(const FilePath& dir_path,
655 InstallState install_state) {
[email protected]be083862012-09-01 03:53:45656 return PackAndInstallCRX(dir_path, FilePath(), install_state,
657 Extension::NO_FLAGS);
658 }
659
660 const Extension* InstallCRX(const FilePath& path,
661 InstallState install_state,
662 int creation_flags) {
663 StartCRXInstall(path, creation_flags);
664 return WaitForCrxInstall(path, install_state);
[email protected]8f512c72011-11-22 21:02:50665 }
666
[email protected]65187152012-06-02 13:14:14667 // Attempts to install an extension. Use INSTALL_FAILED if the installation
668 // is expected to fail.
[email protected]8f512c72011-11-22 21:02:50669 const Extension* InstallCRX(const FilePath& path,
670 InstallState install_state) {
[email protected]be083862012-09-01 03:53:45671 return InstallCRX(path, install_state, Extension::NO_FLAGS);
[email protected]8f512c72011-11-22 21:02:50672 }
673
674 const Extension* InstallCRXFromWebStore(const FilePath& path,
675 InstallState install_state) {
[email protected]be083862012-09-01 03:53:45676 StartCRXInstall(path, Extension::FROM_WEBSTORE);
[email protected]8f512c72011-11-22 21:02:50677 return WaitForCrxInstall(path, install_state);
678 }
679
680 const Extension* InstallCRXWithLocation(const FilePath& crx_path,
681 Extension::Location install_location,
682 InstallState install_state) {
683 EXPECT_TRUE(file_util::PathExists(crx_path))
[email protected]145a317b2011-04-12 16:03:46684 << "Path does not exist: "<< crx_path.value().c_str();
[email protected]14908b72011-04-20 06:54:36685 // no client (silent install)
[email protected]d8c8f25f2011-11-02 18:18:01686 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
[email protected]145a317b2011-04-12 16:03:46687 installer->set_install_source(install_location);
688 installer->InstallCrx(crx_path);
689
[email protected]8f512c72011-11-22 21:02:50690 return WaitForCrxInstall(crx_path, install_state);
[email protected]145a317b2011-04-12 16:03:46691 }
692
[email protected]65187152012-06-02 13:14:14693 // Wait for a CrxInstaller to finish. Used by InstallCRX. Set the
694 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
[email protected]8f512c72011-11-22 21:02:50695 // Returns an Extension pointer if the install succeeded, NULL otherwise.
696 const Extension* WaitForCrxInstall(const FilePath& path,
697 InstallState install_state) {
[email protected]b8f50ce2012-11-17 12:37:57698 loop_.RunUntilIdle();
[email protected]fc670822011-12-17 09:33:49699 std::vector<string16> errors = GetErrors();
[email protected]8f512c72011-11-22 21:02:50700 const Extension* extension = NULL;
701 if (install_state != INSTALL_FAILED) {
702 if (install_state == INSTALL_NEW)
703 ++expected_extensions_count_;
[email protected]902f7cd2009-05-22 19:02:19704
[email protected]a57209872009-05-04 22:53:14705 EXPECT_TRUE(installed_) << path.value();
[email protected]bb28e062009-02-27 17:19:18706 EXPECT_EQ(0u, errors.size()) << path.value();
[email protected]695b5712012-12-06 23:55:28707
708 if (install_state == INSTALL_WITHOUT_LOAD) {
709 EXPECT_EQ(0u, loaded_.size()) << path.value();
710 } else {
711 EXPECT_EQ(1u, loaded_.size()) << path.value();
712 EXPECT_EQ(expected_extensions_count_, service_->extensions()->size()) <<
713 path.value();
714 extension = loaded_[0];
715 EXPECT_TRUE(service_->GetExtensionById(extension->id(), false)) <<
716 path.value();
717 }
718
[email protected]fc670822011-12-17 09:33:49719 for (std::vector<string16>::iterator err = errors.begin();
[email protected]bb28e062009-02-27 17:19:18720 err != errors.end(); ++err) {
[email protected]37eeb5a2009-02-26 23:36:17721 LOG(ERROR) << *err;
722 }
[email protected]cc655912009-01-29 23:19:19723 } else {
[email protected]a57209872009-05-04 22:53:14724 EXPECT_FALSE(installed_) << path.value();
[email protected]86a274072009-06-11 02:06:45725 EXPECT_EQ(0u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18726 EXPECT_EQ(1u, errors.size()) << path.value();
[email protected]cc655912009-01-29 23:19:19727 }
[email protected]bb28e062009-02-27 17:19:18728
[email protected]a57209872009-05-04 22:53:14729 installed_ = NULL;
[email protected]894bb502009-05-21 22:39:57730 loaded_.clear();
[email protected]bb28e062009-02-27 17:19:18731 ExtensionErrorReporter::GetInstance()->ClearErrors();
[email protected]8f512c72011-11-22 21:02:50732 return extension;
[email protected]cc655912009-01-29 23:19:19733 }
734
[email protected]4416c5a2010-06-26 01:28:57735 enum UpdateState {
736 FAILED_SILENTLY,
737 FAILED,
738 UPDATED,
739 INSTALLED,
740 ENABLED
741 };
742
[email protected]98270432012-09-11 20:51:24743 void BlackListWebGL() {
744 static const std::string json_blacklist =
745 "{\n"
746 " \"name\": \"gpu blacklist\",\n"
747 " \"version\": \"1.0\",\n"
748 " \"entries\": [\n"
749 " {\n"
750 " \"id\": 1,\n"
751 " \"blacklist\": [\"webgl\"]\n"
752 " }\n"
753 " ]\n"
754 "}";
[email protected]7e343152012-09-20 21:49:53755 content::GPUInfo gpu_info;
756 content::GpuDataManager::GetInstance()->InitializeForTesting(
757 json_blacklist, gpu_info);
[email protected]98270432012-09-11 20:51:24758 }
759
[email protected]7577a5c52009-07-30 06:21:58760 void UpdateExtension(const std::string& id, const FilePath& in_path,
[email protected]4416c5a2010-06-26 01:28:57761 UpdateState expected_state) {
[email protected]7577a5c52009-07-30 06:21:58762 ASSERT_TRUE(file_util::PathExists(in_path));
[email protected]e957fe52009-06-23 16:51:05763
[email protected]7577a5c52009-07-30 06:21:58764 // We need to copy this to a temporary location because Update() will delete
765 // it.
[email protected]a1295ba22009-09-02 03:33:39766 FilePath path = temp_dir_.path();
767 path = path.Append(in_path.BaseName());
[email protected]7577a5c52009-07-30 06:21:58768 ASSERT_TRUE(file_util::CopyFile(in_path, path));
[email protected]e957fe52009-06-23 16:51:05769
[email protected]4416c5a2010-06-26 01:28:57770 int previous_enabled_extension_count =
771 service_->extensions()->size();
772 int previous_installed_extension_count =
773 previous_enabled_extension_count +
774 service_->disabled_extensions()->size();
775
[email protected]420a0ec2011-06-01 01:07:03776 service_->UpdateExtension(id, path, GURL(), NULL);
[email protected]b8f50ce2012-11-17 12:37:57777 loop_.RunUntilIdle();
[email protected]f3113e232010-06-25 01:36:40778
[email protected]fc670822011-12-17 09:33:49779 std::vector<string16> errors = GetErrors();
[email protected]4416c5a2010-06-26 01:28:57780 int error_count = errors.size();
781 int enabled_extension_count =
782 service_->extensions()->size();
783 int installed_extension_count =
784 enabled_extension_count + service_->disabled_extensions()->size();
785
786 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
787 EXPECT_EQ(expected_error_count, error_count) << path.value();
788
789 if (expected_state <= FAILED) {
790 EXPECT_EQ(previous_enabled_extension_count,
791 enabled_extension_count);
792 EXPECT_EQ(previous_installed_extension_count,
793 installed_extension_count);
[email protected]e957fe52009-06-23 16:51:05794 } else {
[email protected]4416c5a2010-06-26 01:28:57795 int expected_installed_extension_count =
796 (expected_state >= INSTALLED) ? 1 : 0;
797 int expected_enabled_extension_count =
798 (expected_state >= ENABLED) ? 1 : 0;
799 EXPECT_EQ(expected_installed_extension_count,
800 installed_extension_count);
801 EXPECT_EQ(expected_enabled_extension_count,
802 enabled_extension_count);
[email protected]e957fe52009-06-23 16:51:05803 }
[email protected]7577a5c52009-07-30 06:21:58804
[email protected]31d8f5f22012-04-02 15:22:08805 // Update() should the temporary input file.
[email protected]7577a5c52009-07-30 06:21:58806 EXPECT_FALSE(file_util::PathExists(path));
[email protected]e957fe52009-06-23 16:51:05807 }
808
[email protected]fa2416f2011-05-03 08:41:20809 void TerminateExtension(const std::string& id) {
810 const Extension* extension = service_->GetInstalledExtension(id);
811 if (!extension) {
812 ADD_FAILURE();
813 return;
814 }
815 service_->TrackTerminatedExtensionForTest(extension);
816 }
817
818 size_t GetPrefKeyCount() {
[email protected]43d3bf82011-04-11 07:46:58819 const DictionaryValue* dict =
820 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]fa2416f2011-05-03 08:41:20821 if (!dict) {
822 ADD_FAILURE();
823 return 0;
824 }
825 return dict->size();
826 }
827
828 void UninstallExtension(const std::string& id, bool use_helper) {
829 // Verify that the extension is installed.
830 FilePath extension_path = extensions_install_dir_.AppendASCII(id);
831 EXPECT_TRUE(file_util::PathExists(extension_path));
832 size_t pref_key_count = GetPrefKeyCount();
833 EXPECT_GT(pref_key_count, 0u);
834 ValidateIntegerPref(id, "state", Extension::ENABLED);
835
836 // Uninstall it.
837 if (use_helper) {
838 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(service_, id));
839 } else {
840 EXPECT_TRUE(service_->UninstallExtension(id, false, NULL));
841 }
[email protected]8f512c72011-11-22 21:02:50842 --expected_extensions_count_;
[email protected]fa2416f2011-05-03 08:41:20843
844 // We should get an unload notification.
845 EXPECT_FALSE(unloaded_id_.empty());
846 EXPECT_EQ(id, unloaded_id_);
847
848 // Verify uninstalled state.
849 size_t new_pref_key_count = GetPrefKeyCount();
850 if (new_pref_key_count == pref_key_count) {
851 ValidateIntegerPref(id, "location",
852 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
853 } else {
854 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
855 }
856
857 // The extension should not be in the service anymore.
858 EXPECT_FALSE(service_->GetInstalledExtension(id));
[email protected]b8f50ce2012-11-17 12:37:57859 loop_.RunUntilIdle();
[email protected]fa2416f2011-05-03 08:41:20860
861 // The directory should be gone.
862 EXPECT_FALSE(file_util::PathExists(extension_path));
863 }
864
865 void ValidatePrefKeyCount(size_t count) {
866 EXPECT_EQ(count, GetPrefKeyCount());
[email protected]25b34332009-06-05 21:53:19867 }
868
[email protected]6b75ec32009-08-14 06:37:18869 void ValidateBooleanPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34870 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06871 bool expected_val) {
[email protected]e2194742010-08-12 05:54:34872 std::string msg = " while checking: ";
873 msg += extension_id;
874 msg += " ";
[email protected]6b75ec32009-08-14 06:37:18875 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34876 msg += " == ";
877 msg += expected_val ? "true" : "false";
[email protected]6b75ec32009-08-14 06:37:18878
[email protected]2fb7dc982010-09-29 12:24:28879 PrefService* prefs = profile_->GetPrefs();
880 const DictionaryValue* dict =
881 prefs->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18882 ASSERT_TRUE(dict != NULL) << msg;
[email protected]a61890e2012-07-27 22:27:11883 const DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34884 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]6b75ec32009-08-14 06:37:18885 EXPECT_TRUE(pref != NULL) << msg;
886 bool val;
[email protected]4c91487e2009-10-02 04:11:04887 ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06888 EXPECT_EQ(expected_val, val) << msg;
[email protected]6b75ec32009-08-14 06:37:18889 }
890
891 bool IsPrefExist(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34892 const std::string& pref_path) {
[email protected]2fb7dc982010-09-29 12:24:28893 const DictionaryValue* dict =
894 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18895 if (dict == NULL) return false;
[email protected]a61890e2012-07-27 22:27:11896 const DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34897 if (!dict->GetDictionary(extension_id, &pref)) {
[email protected]6b75ec32009-08-14 06:37:18898 return false;
899 }
900 if (pref == NULL) {
901 return false;
902 }
903 bool val;
904 if (!pref->GetBoolean(pref_path, &val)) {
905 return false;
906 }
907 return true;
908 }
909
910 void ValidateIntegerPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34911 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06912 int expected_val) {
[email protected]e2194742010-08-12 05:54:34913 std::string msg = " while checking: ";
914 msg += extension_id;
915 msg += " ";
[email protected]25b34332009-06-05 21:53:19916 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34917 msg += " == ";
918 msg += base::IntToString(expected_val);
[email protected]25b34332009-06-05 21:53:19919
[email protected]2fb7dc982010-09-29 12:24:28920 PrefService* prefs = profile_->GetPrefs();
921 const DictionaryValue* dict =
922 prefs->GetDictionary("extensions.settings");
[email protected]25b34332009-06-05 21:53:19923 ASSERT_TRUE(dict != NULL) << msg;
[email protected]a61890e2012-07-27 22:27:11924 const DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34925 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]25b34332009-06-05 21:53:19926 EXPECT_TRUE(pref != NULL) << msg;
927 int val;
[email protected]4c91487e2009-10-02 04:11:04928 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06929 EXPECT_EQ(expected_val, val) << msg;
930 }
931
932 void ValidateStringPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34933 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06934 const std::string& expected_val) {
[email protected]e2194742010-08-12 05:54:34935 std::string msg = " while checking: ";
936 msg += extension_id;
937 msg += ".manifest.";
[email protected]c6d474f82009-12-16 21:11:06938 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34939 msg += " == ";
940 msg += expected_val;
[email protected]c6d474f82009-12-16 21:11:06941
[email protected]2fb7dc982010-09-29 12:24:28942 const DictionaryValue* dict =
943 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]c6d474f82009-12-16 21:11:06944 ASSERT_TRUE(dict != NULL) << msg;
[email protected]a61890e2012-07-27 22:27:11945 const DictionaryValue* pref = NULL;
[email protected]c6d474f82009-12-16 21:11:06946 std::string manifest_path = extension_id + ".manifest";
[email protected]e2194742010-08-12 05:54:34947 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
[email protected]c6d474f82009-12-16 21:11:06948 EXPECT_TRUE(pref != NULL) << msg;
949 std::string val;
950 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
951 EXPECT_EQ(expected_val, val) << msg;
[email protected]25b34332009-06-05 21:53:19952 }
953
[email protected]8d888c12010-11-30 00:00:25954 void SetPref(const std::string& extension_id,
955 const std::string& pref_path,
956 Value* value,
957 const std::string& msg) {
[email protected]43d3bf82011-04-11 07:46:58958 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
959 DictionaryValue* dict = update.Get();
[email protected]8d888c12010-11-30 00:00:25960 ASSERT_TRUE(dict != NULL) << msg;
961 DictionaryValue* pref = NULL;
962 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
963 EXPECT_TRUE(pref != NULL) << msg;
964 pref->Set(pref_path, value);
965 }
966
[email protected]6b75ec32009-08-14 06:37:18967 void SetPrefInteg(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34968 const std::string& pref_path,
[email protected]6b75ec32009-08-14 06:37:18969 int value) {
[email protected]e2194742010-08-12 05:54:34970 std::string msg = " while setting: ";
971 msg += extension_id;
972 msg += " ";
[email protected]a1257b12009-06-12 02:51:34973 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34974 msg += " = ";
975 msg += base::IntToString(value);
[email protected]a1257b12009-06-12 02:51:34976
[email protected]8d888c12010-11-30 00:00:25977 SetPref(extension_id, pref_path, Value::CreateIntegerValue(value), msg);
978 }
979
980 void SetPrefBool(const std::string& extension_id,
981 const std::string& pref_path,
982 bool value) {
983 std::string msg = " while setting: ";
984 msg += extension_id + " " + pref_path;
985 msg += " = ";
986 msg += (value ? "true" : "false");
987
988 SetPref(extension_id, pref_path, Value::CreateBooleanValue(value), msg);
989 }
990
991 void ClearPref(const std::string& extension_id,
992 const std::string& pref_path) {
993 std::string msg = " while clearing: ";
994 msg += extension_id + " " + pref_path;
995
[email protected]43d3bf82011-04-11 07:46:58996 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
997 DictionaryValue* dict = update.Get();
[email protected]a1257b12009-06-12 02:51:34998 ASSERT_TRUE(dict != NULL) << msg;
999 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:341000 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]a1257b12009-06-12 02:51:341001 EXPECT_TRUE(pref != NULL) << msg;
[email protected]8d888c12010-11-30 00:00:251002 pref->Remove(pref_path, NULL);
1003 }
1004
1005 void SetPrefStringSet(const std::string& extension_id,
1006 const std::string& pref_path,
1007 const std::set<std::string>& value) {
1008 std::string msg = " while setting: ";
1009 msg += extension_id + " " + pref_path;
1010
1011 ListValue* list_value = new ListValue();
1012 for (std::set<std::string>::const_iterator iter = value.begin();
1013 iter != value.end(); ++iter)
1014 list_value->Append(Value::CreateStringValue(*iter));
1015
1016 SetPref(extension_id, pref_path, list_value, msg);
[email protected]a1257b12009-06-12 02:51:341017 }
1018
[email protected]25b34332009-06-05 21:53:191019 protected:
[email protected]1c321ee52012-05-21 03:02:341020 extensions::ExtensionList loaded_;
[email protected]894bb502009-05-21 22:39:571021 std::string unloaded_id_;
[email protected]9adb9692010-10-29 23:14:021022 const Extension* installed_;
[email protected]00b5d0a52012-10-30 13:13:531023 FeatureSwitch::ScopedOverride override_external_install_prompt_;
[email protected]894bb502009-05-21 22:39:571024
[email protected]6014d672008-12-05 00:38:251025 private:
[email protected]6c2381d2011-10-19 02:52:531026 content::NotificationRegistrar registrar_;
[email protected]bb28e062009-02-27 17:19:181027};
[email protected]6014d672008-12-05 00:38:251028
[email protected]0349ab5d2010-08-11 21:41:571029// Receives notifications from a PackExtensionJob, indicating either that
1030// packing succeeded or that there was some error.
[email protected]d9ede582012-08-14 19:21:381031class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
[email protected]0349ab5d2010-08-11 21:41:571032 public:
1033 PackExtensionTestClient(const FilePath& expected_crx_path,
1034 const FilePath& expected_private_key_path);
1035 virtual void OnPackSuccess(const FilePath& crx_path,
1036 const FilePath& private_key_path);
[email protected]93d973a2012-01-08 07:38:261037 virtual void OnPackFailure(const std::string& error_message,
1038 ExtensionCreator::ErrorType type);
[email protected]0349ab5d2010-08-11 21:41:571039
1040 private:
1041 const FilePath expected_crx_path_;
1042 const FilePath expected_private_key_path_;
1043 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1044};
1045
1046PackExtensionTestClient::PackExtensionTestClient(
1047 const FilePath& expected_crx_path,
1048 const FilePath& expected_private_key_path)
1049 : expected_crx_path_(expected_crx_path),
1050 expected_private_key_path_(expected_private_key_path) {}
1051
1052// If packing succeeded, we make sure that the package names match our
1053// expectations.
1054void PackExtensionTestClient::OnPackSuccess(const FilePath& crx_path,
1055 const FilePath& private_key_path) {
1056 // We got the notification and processed it; we don't expect any further tasks
1057 // to be posted to the current thread, so we should stop blocking and continue
1058 // on with the rest of the test.
1059 // This call to |Quit()| matches the call to |Run()| in the
1060 // |PackPunctuatedExtension| test.
1061 MessageLoop::current()->Quit();
1062 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1063 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1064 ASSERT_TRUE(file_util::PathExists(private_key_path));
1065}
1066
1067// The tests are designed so that we never expect to see a packing error.
[email protected]93d973a2012-01-08 07:38:261068void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1069 ExtensionCreator::ErrorType type) {
1070 if (type == ExtensionCreator::kCRXExists)
1071 FAIL() << "Packing should not fail.";
1072 else
1073 FAIL() << "Existing CRX should have been overwritten.";
[email protected]0349ab5d2010-08-11 21:41:571074}
1075
[email protected]54cb3c92009-02-17 22:30:211076// Test loading good extensions from the profile directory.
[email protected]d9a61e12012-11-14 02:43:471077TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
[email protected]183d4b82011-11-11 18:50:261078 PluginService::GetInstance()->Init();
1079
[email protected]a9b00ac2009-06-25 21:03:231080 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:351081 FilePath source_install_dir = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231082 .AppendASCII("good")
1083 .AppendASCII("Extensions");
1084 FilePath pref_path = source_install_dir
1085 .DirName()
1086 .AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:001087 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]6014d672008-12-05 00:38:251088
[email protected]9f1087e2009-06-15 17:29:321089 service_->Init();
[email protected]6014d672008-12-05 00:38:251090
[email protected]e50013c32010-08-18 21:05:241091 uint32 expected_num_extensions = 3u;
[email protected]e50013c32010-08-18 21:05:241092 ASSERT_EQ(expected_num_extensions, loaded_.size());
[email protected]6014d672008-12-05 00:38:251093
[email protected]fbcc40302009-06-12 20:45:451094 EXPECT_EQ(std::string(good0), loaded_[0]->id());
[email protected]e1cec06c2008-12-18 01:22:231095 EXPECT_EQ(std::string("My extension 1"),
[email protected]894bb502009-05-21 22:39:571096 loaded_[0]->name());
[email protected]e1cec06c2008-12-18 01:22:231097 EXPECT_EQ(std::string("The first extension that I made."),
[email protected]894bb502009-05-21 22:39:571098 loaded_[0]->description());
1099 EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location());
[email protected]61b411612009-11-10 23:17:411100 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
[email protected]e50013c32010-08-18 21:05:241101 EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
[email protected]eab9b452009-01-23 20:48:591102
[email protected]25b34332009-06-05 21:53:191103 ValidatePrefKeyCount(3);
[email protected]e2194742010-08-12 05:54:341104 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1105 ValidateIntegerPref(good0, "location", Extension::INTERNAL);
1106 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1107 ValidateIntegerPref(good1, "location", Extension::INTERNAL);
1108 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1109 ValidateIntegerPref(good2, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:191110
[email protected]06e8b8ff2011-07-13 15:03:471111 URLPatternSet expected_patterns;
1112 AddPattern(&expected_patterns, "file:///*");
1113 AddPattern(&expected_patterns, "http://*.google.com/*");
1114 AddPattern(&expected_patterns, "https://*.google.com/*");
[email protected]9adb9692010-10-29 23:14:021115 const Extension* extension = loaded_[0];
[email protected]20f97c92012-07-13 23:12:371116 const extensions::UserScriptList& scripts = extension->content_scripts();
[email protected]e66de892009-03-20 20:38:431117 ASSERT_EQ(2u, scripts.size());
[email protected]06e8b8ff2011-07-13 15:03:471118 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
[email protected]e66de892009-03-20 20:38:431119 EXPECT_EQ(2u, scripts[0].js_scripts().size());
[email protected]052c92702010-06-25 07:25:521120 ExtensionResource resource00(extension->id(),
1121 scripts[0].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:211122 scripts[0].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:291123 FilePath expected_path(extension->path().AppendASCII("script1.js"));
1124 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
1125 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
[email protected]052c92702010-06-25 07:25:521126 ExtensionResource resource01(extension->id(),
1127 scripts[0].js_scripts()[1].extension_root(),
[email protected]9194b3f2009-10-20 15:27:211128 scripts[0].js_scripts()[1].relative_path());
[email protected]a14b16b2009-10-28 12:41:291129 expected_path = extension->path().AppendASCII("script2.js");
1130 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
1131 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
[email protected]c533bb22009-06-03 19:06:111132 EXPECT_TRUE(extension->plugins().empty());
[email protected]06e8b8ff2011-07-13 15:03:471133 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1134 EXPECT_EQ("http://*.news.com/*",
1135 scripts[1].url_patterns().begin()->GetAsString());
[email protected]052c92702010-06-25 07:25:521136 ExtensionResource resource10(extension->id(),
1137 scripts[1].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:211138 scripts[1].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:291139 expected_path =
1140 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1141 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
1142 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
[email protected]06e8b8ff2011-07-13 15:03:471143
1144 expected_patterns.ClearPatterns();
1145 AddPattern(&expected_patterns, "http://*.google.com/*");
1146 AddPattern(&expected_patterns, "https://*.google.com/*");
[email protected]902fd7b2011-07-27 18:42:311147 EXPECT_EQ(expected_patterns,
1148 extension->GetActivePermissions()->explicit_hosts());
[email protected]6014d672008-12-05 00:38:251149
[email protected]25b34332009-06-05 21:53:191150 EXPECT_EQ(std::string(good1), loaded_[1]->id());
[email protected]894bb502009-05-21 22:39:571151 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1152 EXPECT_EQ(std::string(""), loaded_[1]->description());
[email protected]81067e02009-07-27 15:12:091153 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
[email protected]a03d4448f2012-01-10 23:25:281154 loaded_[1]->GetBackgroundURL());
[email protected]894bb502009-05-21 22:39:571155 EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
[email protected]b8fb3032011-04-29 18:45:561156 // We don't parse the plugins section on Chrome OS.
1157#if defined(OS_CHROMEOS)
1158 EXPECT_EQ(0u, loaded_[1]->plugins().size());
1159#else
1160 ASSERT_EQ(2u, loaded_[1]->plugins().size());
[email protected]c533bb22009-06-03 19:06:111161 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1162 loaded_[1]->plugins()[0].path.value());
1163 EXPECT_TRUE(loaded_[1]->plugins()[0].is_public);
1164 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1165 loaded_[1]->plugins()[1].path.value());
1166 EXPECT_FALSE(loaded_[1]->plugins()[1].is_public);
[email protected]e50013c32010-08-18 21:05:241167#endif
[email protected]18a12352009-01-31 01:33:281168
[email protected]b8fb3032011-04-29 18:45:561169 EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location());
1170
[email protected]e50013c32010-08-18 21:05:241171 int index = expected_num_extensions - 1;
1172 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1173 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1174 EXPECT_EQ(std::string(""), loaded_[index]->description());
1175 EXPECT_EQ(0u, loaded_[index]->content_scripts().size());
1176 EXPECT_EQ(Extension::INTERNAL, loaded_[index]->location());
[email protected]6014d672008-12-05 00:38:251177};
[email protected]cc655912009-01-29 23:19:191178
[email protected]54cb3c92009-02-17 22:30:211179// Test loading bad extensions from the profile directory.
[email protected]d9a61e12012-11-14 02:43:471180TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
[email protected]c6d474f82009-12-16 21:11:061181 // Initialize the test dir with a bad Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:351182 FilePath source_install_dir = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231183 .AppendASCII("bad")
1184 .AppendASCII("Extensions");
1185 FilePath pref_path = source_install_dir
1186 .DirName()
1187 .AppendASCII("Preferences");
[email protected]54cb3c92009-02-17 22:30:211188
[email protected]eaa7dd182010-12-14 11:09:001189 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]54cb3c92009-02-17 22:30:211190
[email protected]9f1087e2009-06-15 17:29:321191 service_->Init();
[email protected]54cb3c92009-02-17 22:30:211192
[email protected]a9b00ac2009-06-25 21:03:231193 ASSERT_EQ(4u, GetErrors().size());
1194 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:191195
[email protected]fc670822011-12-17 09:33:491196 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[0]),
[email protected]d7b36dc2009-10-29 21:47:401197 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491198 extension_manifest_errors::kManifestUnreadable)) <<
1199 UTF16ToUTF8(GetErrors()[0]);
[email protected]8d6d9ff2009-02-20 08:14:391200
[email protected]fc670822011-12-17 09:33:491201 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[1]),
[email protected]8d6d9ff2009-02-20 08:14:391202 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491203 extension_manifest_errors::kManifestUnreadable)) <<
1204 UTF16ToUTF8(GetErrors()[1]);
[email protected]8d6d9ff2009-02-20 08:14:391205
[email protected]fc670822011-12-17 09:33:491206 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[2]),
[email protected]8d6d9ff2009-02-20 08:14:391207 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491208 extension_manifest_errors::kMissingFile)) <<
1209 UTF16ToUTF8(GetErrors()[2]);
[email protected]a9b00ac2009-06-25 21:03:231210
[email protected]fc670822011-12-17 09:33:491211 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]),
[email protected]a9b00ac2009-06-25 21:03:231212 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491213 extension_manifest_errors::kManifestUnreadable)) <<
1214 UTF16ToUTF8(GetErrors()[3]);
[email protected]54cb3c92009-02-17 22:30:211215};
1216
[email protected]2f8757c32012-06-19 19:17:471217// Test that partially deleted extensions are cleaned up during startup
[email protected]894bb502009-05-21 22:39:571218// Test loading bad extensions from the profile directory.
[email protected]d9a61e12012-11-14 02:43:471219TEST_F(ExtensionServiceTest, CleanupOnStartup) {
[email protected]183d4b82011-11-11 18:50:261220 PluginService::GetInstance()->Init();
1221
[email protected]e85e34c32011-04-13 18:38:351222 FilePath source_install_dir = data_dir_
[email protected]b6ab96d2009-08-20 18:58:191223 .AppendASCII("good")
1224 .AppendASCII("Extensions");
1225 FilePath pref_path = source_install_dir
1226 .DirName()
1227 .AppendASCII("Preferences");
[email protected]a9b00ac2009-06-25 21:03:231228
[email protected]eaa7dd182010-12-14 11:09:001229 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]894bb502009-05-21 22:39:571230
[email protected]b6ab96d2009-08-20 18:58:191231 // Simulate that one of them got partially deleted by clearing its pref.
[email protected]43d3bf82011-04-11 07:46:581232 {
1233 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1234 DictionaryValue* dict = update.Get();
[email protected]2f8757c32012-06-19 19:17:471235 ASSERT_TRUE(dict != NULL);
[email protected]43d3bf82011-04-11 07:46:581236 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1237 }
[email protected]894bb502009-05-21 22:39:571238
1239 service_->Init();
[email protected]1f4728f2012-12-05 20:40:051240 // Wait for GarbageCollectExtensions task to complete.
[email protected]0db124b02012-11-07 04:55:051241 loop_.RunUntilIdle();
[email protected]894bb502009-05-21 22:39:571242
[email protected]a9b00ac2009-06-25 21:03:231243 file_util::FileEnumerator dirs(extensions_install_dir_, false,
[email protected]9f1087e2009-06-15 17:29:321244 file_util::FileEnumerator::DIRECTORIES);
1245 size_t count = 0;
1246 while (!dirs.Next().empty())
1247 count++;
1248
[email protected]894bb502009-05-21 22:39:571249 // We should have only gotten two extensions now.
[email protected]9f1087e2009-06-15 17:29:321250 EXPECT_EQ(2u, count);
[email protected]e2eb43112009-05-29 21:19:541251
[email protected]894bb502009-05-21 22:39:571252 // And extension1 dir should now be toast.
[email protected]b6ab96d2009-08-20 18:58:191253 FilePath extension_dir = extensions_install_dir_
1254 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1255 ASSERT_FALSE(file_util::PathExists(extension_dir));
[email protected]894bb502009-05-21 22:39:571256}
1257
[email protected]0db124b02012-11-07 04:55:051258// Test that GarbageCollectExtensions deletes the right versions of an
1259// extension.
1260TEST_F(ExtensionServiceTest, GarbageCollectWithPendingUpdates) {
1261 PluginService::GetInstance()->Init();
1262
1263 FilePath source_install_dir = data_dir_
1264 .AppendASCII("pending_updates")
1265 .AppendASCII("Extensions");
1266 FilePath pref_path = source_install_dir
1267 .DirName()
1268 .AppendASCII("Preferences");
1269
1270 InitializeInstalledExtensionService(pref_path, source_install_dir);
1271
1272 // This is the directory that is going to be deleted, so make sure it actually
1273 // is there before the garbage collection.
1274 ASSERT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1275 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1276
1277 service_->GarbageCollectExtensions();
[email protected]1f4728f2012-12-05 20:40:051278 // Wait for GarbageCollectExtensions task to complete.
[email protected]0db124b02012-11-07 04:55:051279 loop_.RunUntilIdle();
1280
1281 // Verify that the pending update for the first extension didn't get
1282 // deleted.
1283 EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1284 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1285 EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1286 "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
1287 EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1288 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1289 EXPECT_FALSE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1290 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1291}
1292
1293// Test that pending updates are properly handled on startup.
1294TEST_F(ExtensionServiceTest, UpdateOnStartup) {
1295 PluginService::GetInstance()->Init();
1296
1297 FilePath source_install_dir = data_dir_
1298 .AppendASCII("pending_updates")
1299 .AppendASCII("Extensions");
1300 FilePath pref_path = source_install_dir
1301 .DirName()
1302 .AppendASCII("Preferences");
1303
1304 InitializeInstalledExtensionService(pref_path, source_install_dir);
1305
1306 // This is the directory that is going to be deleted, so make sure it actually
1307 // is there before the garbage collection.
1308 ASSERT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1309 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1310
1311 service_->Init();
[email protected]1f4728f2012-12-05 20:40:051312 // Wait for GarbageCollectExtensions task to complete.
[email protected]0db124b02012-11-07 04:55:051313 loop_.RunUntilIdle();
1314
1315 // Verify that the pending update for the first extension got installed.
1316 EXPECT_FALSE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1317 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1318 EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1319 "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
1320 EXPECT_TRUE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1321 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1322 EXPECT_FALSE(file_util::PathExists(extensions_install_dir_.AppendASCII(
1323 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1324
1325 // Make sure update information got deleted.
1326 ExtensionPrefs* prefs = service_->extension_prefs();
[email protected]399583b2012-12-11 09:33:421327 EXPECT_FALSE(
1328 prefs->GetDelayedInstallInfo("bjafgdebaacbbbecmhlhpofkepfkgcpa"));
[email protected]0db124b02012-11-07 04:55:051329}
1330
[email protected]d7eaf572009-07-01 21:57:001331// Test installing extensions. This test tries to install few extensions using
1332// crx files. If you need to change those crx files, feel free to repackage
1333// them, throw away the key used and change the id's above.
[email protected]d9a61e12012-11-14 02:43:471334TEST_F(ExtensionServiceTest, InstallExtension) {
[email protected]eaa7dd182010-12-14 11:09:001335 InitializeEmptyExtensionService();
[email protected]a9b00ac2009-06-25 21:03:231336
[email protected]e2eb43112009-05-29 21:19:541337 // Extensions not enabled.
[email protected]7577a5c52009-07-30 06:21:581338 set_extensions_enabled(false);
[email protected]e85e34c32011-04-13 18:38:351339 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:501340 InstallCRX(path, INSTALL_FAILED);
[email protected]7577a5c52009-07-30 06:21:581341 set_extensions_enabled(true);
[email protected]e2eb43112009-05-29 21:19:541342
[email protected]25b34332009-06-05 21:53:191343 ValidatePrefKeyCount(0);
1344
[email protected]e2eb43112009-05-29 21:19:541345 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:351346 path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:501347 InstallCRX(path, INSTALL_NEW);
[email protected]cc655912009-01-29 23:19:191348 // TODO(erikkay): verify the contents of the installed extension.
1349
[email protected]25b34332009-06-05 21:53:191350 int pref_count = 0;
1351 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341352 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1353 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:191354
[email protected]902f7cd2009-05-22 19:02:191355 // An extension with page actions.
[email protected]e85e34c32011-04-13 18:38:351356 path = data_dir_.AppendASCII("page_action.crx");
[email protected]8f512c72011-11-22 21:02:501357 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:191358 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341359 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1360 ValidateIntegerPref(page_action, "location", Extension::INTERNAL);
[email protected]902f7cd2009-05-22 19:02:191361
[email protected]9f1087e2009-06-15 17:29:321362 // Bad signature.
[email protected]e85e34c32011-04-13 18:38:351363 path = data_dir_.AppendASCII("bad_signature.crx");
[email protected]8f512c72011-11-22 21:02:501364 InstallCRX(path, INSTALL_FAILED);
[email protected]d7eaf572009-07-01 21:57:001365 ValidatePrefKeyCount(pref_count);
[email protected]fbcc40302009-06-12 20:45:451366
[email protected]cc655912009-01-29 23:19:191367 // 0-length extension file.
[email protected]e85e34c32011-04-13 18:38:351368 path = data_dir_.AppendASCII("not_an_extension.crx");
[email protected]8f512c72011-11-22 21:02:501369 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:191370 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191371
1372 // Bad magic number.
[email protected]e85e34c32011-04-13 18:38:351373 path = data_dir_.AppendASCII("bad_magic.crx");
[email protected]8f512c72011-11-22 21:02:501374 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:191375 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191376
[email protected]8ef78fd2010-08-19 17:14:321377 // Extensions cannot have folders or files that have underscores except in
[email protected]99872e32009-09-25 22:02:491378 // certain whitelisted cases (eg _locales). This is an example of a broader
1379 // class of validation that we do to the directory structure of the extension.
1380 // We did not used to handle this correctly for installation.
[email protected]e85e34c32011-04-13 18:38:351381 path = data_dir_.AppendASCII("bad_underscore.crx");
[email protected]8f512c72011-11-22 21:02:501382 InstallCRX(path, INSTALL_FAILED);
[email protected]99872e32009-09-25 22:02:491383 ValidatePrefKeyCount(pref_count);
1384
[email protected]cc655912009-01-29 23:19:191385 // TODO(erikkay): add more tests for many of the failure cases.
1386 // TODO(erikkay): add tests for upgrade cases.
1387}
1388
[email protected]1bf73cc32011-10-26 22:38:311389// Tests that flags passed to OnExternalExtensionFileFound() make it to the
1390// extension object.
[email protected]d9a61e12012-11-14 02:43:471391TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
[email protected]a12ce8b22012-01-17 18:40:531392 const char kPrefFromBookmark[] = "from_bookmark";
1393
[email protected]1bf73cc32011-10-26 22:38:311394 InitializeEmptyExtensionService();
1395
1396 FilePath path = data_dir_.AppendASCII("good.crx");
1397 set_extensions_enabled(true);
1398
[email protected]a12ce8b22012-01-17 18:40:531399 // Register and install an external extension.
[email protected]12126d372012-07-11 18:40:531400 Version version("1.0.0.0");
[email protected]f121003b2012-05-04 21:57:471401 service_->OnExternalExtensionFileFound(
1402 good_crx,
[email protected]12126d372012-07-11 18:40:531403 &version,
[email protected]f121003b2012-05-04 21:57:471404 path,
1405 Extension::EXTERNAL_PREF,
1406 Extension::FROM_BOOKMARK,
1407 false /* mark_acknowledged */);
[email protected]b8f50ce2012-11-17 12:37:571408 loop_.RunUntilIdle();
[email protected]1bf73cc32011-10-26 22:38:311409
1410 const Extension* extension = service_->GetExtensionById(good_crx, false);
1411 ASSERT_TRUE(extension);
[email protected]a12ce8b22012-01-17 18:40:531412 ASSERT_TRUE(extension->from_bookmark());
1413 ValidateBooleanPref(good_crx, kPrefFromBookmark, true);
1414
1415 // Upgrade to version 2.0, the flag should be preserved.
1416 path = data_dir_.AppendASCII("good2.crx");
1417 UpdateExtension(good_crx, path, ENABLED);
1418 ValidateBooleanPref(good_crx, kPrefFromBookmark, true);
1419 extension = service_->GetExtensionById(good_crx, false);
1420 ASSERT_TRUE(extension);
1421 ASSERT_TRUE(extension->from_bookmark());
[email protected]1bf73cc32011-10-26 22:38:311422}
1423
[email protected]79c833b52011-04-05 18:31:011424// Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
[email protected]d9a61e12012-11-14 02:43:471425TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
[email protected]eaa7dd182010-12-14 11:09:001426 InitializeEmptyExtensionService();
[email protected]683d0702010-12-06 16:25:571427
[email protected]e85e34c32011-04-13 18:38:351428 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]683d0702010-12-06 16:25:571429 set_extensions_enabled(true);
1430
[email protected]12126d372012-07-11 18:40:531431 Version version("1.0.0.0");
[email protected]683d0702010-12-06 16:25:571432 // Install an external extension.
[email protected]12126d372012-07-11 18:40:531433 service_->OnExternalExtensionFileFound(good_crx, &version,
[email protected]1bf73cc32011-10-26 22:38:311434 path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511435 Extension::NO_FLAGS, false);
[email protected]b8f50ce2012-11-17 12:37:571436 loop_.RunUntilIdle();
[email protected]604322d2011-03-22 16:51:561437 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]683d0702010-12-06 16:25:571438
1439 // Uninstall it and check that its killbit gets set.
[email protected]fa2416f2011-05-03 08:41:201440 UninstallExtension(good_crx, false);
[email protected]79c833b52011-04-05 18:31:011441 ValidateIntegerPref(good_crx, "location",
1442 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571443
1444 // Try to re-install it externally. This should fail because of the killbit.
[email protected]12126d372012-07-11 18:40:531445 service_->OnExternalExtensionFileFound(good_crx, &version,
[email protected]1bf73cc32011-10-26 22:38:311446 path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511447 Extension::NO_FLAGS, false);
[email protected]b8f50ce2012-11-17 12:37:571448 loop_.RunUntilIdle();
[email protected]683d0702010-12-06 16:25:571449 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
[email protected]79c833b52011-04-05 18:31:011450 ValidateIntegerPref(good_crx, "location",
1451 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571452
[email protected]12126d372012-07-11 18:40:531453 version = Version("1.0.0.1");
[email protected]683d0702010-12-06 16:25:571454 // Repeat the same thing with a newer version of the extension.
[email protected]e85e34c32011-04-13 18:38:351455 path = data_dir_.AppendASCII("good2.crx");
[email protected]12126d372012-07-11 18:40:531456 service_->OnExternalExtensionFileFound(good_crx, &version,
[email protected]1bf73cc32011-10-26 22:38:311457 path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511458 Extension::NO_FLAGS, false);
[email protected]b8f50ce2012-11-17 12:37:571459 loop_.RunUntilIdle();
[email protected]683d0702010-12-06 16:25:571460 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
[email protected]79c833b52011-04-05 18:31:011461 ValidateIntegerPref(good_crx, "location",
1462 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571463
1464 // Try adding the same extension from an external update URL.
[email protected]9060d8b02012-01-13 02:14:301465 ASSERT_FALSE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]683d0702010-12-06 16:25:571466 good_crx,
1467 GURL("http:://fake.update/url"),
[email protected]9060d8b02012-01-13 02:14:301468 Extension::EXTERNAL_PREF_DOWNLOAD));
[email protected]b2907fd2011-03-25 16:43:371469
1470 ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
[email protected]683d0702010-12-06 16:25:571471}
1472
[email protected]0f48fca2011-05-19 18:46:351473// Test that uninstalling an external extension does not crash when
1474// the extension could not be loaded.
1475// This extension shown in preferences file requires an experimental permission.
1476// It could not be loaded without such permission.
[email protected]d9a61e12012-11-14 02:43:471477TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
[email protected]0f48fca2011-05-19 18:46:351478 FilePath source_install_dir = data_dir_
1479 .AppendASCII("good")
1480 .AppendASCII("Extensions");
1481 // The preference contains an external extension
1482 // that requires 'experimental' permission.
1483 FilePath pref_path = source_install_dir
1484 .DirName()
1485 .AppendASCII("PreferencesExperimental");
1486
1487 // Aforementioned extension will not be loaded if
1488 // there is no '--enable-experimental-extension-apis' command line flag.
1489 InitializeInstalledExtensionService(pref_path, source_install_dir);
1490
1491 service_->Init();
[email protected]0f48fca2011-05-19 18:46:351492
1493 // Check and try to uninstall it.
1494 // If we don't check whether the extension is loaded before we uninstall it
1495 // in CheckExternalUninstall, a crash will happen here because we will get or
1496 // dereference a NULL pointer (extension) inside UninstallExtension.
[email protected]50067e52011-10-20 23:17:071497 MockExtensionProvider provider(NULL, Extension::EXTERNAL_REGISTRY);
1498 service_->OnExternalProviderReady(&provider);
[email protected]0f48fca2011-05-19 18:46:351499}
1500
[email protected]604322d2011-03-22 16:51:561501// Test that external extensions with incorrect IDs are not installed.
[email protected]d9a61e12012-11-14 02:43:471502TEST_F(ExtensionServiceTest, FailOnWrongId) {
[email protected]604322d2011-03-22 16:51:561503 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351504 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]604322d2011-03-22 16:51:561505 set_extensions_enabled(true);
1506
[email protected]12126d372012-07-11 18:40:531507 Version version("1.0.0.0");
[email protected]604322d2011-03-22 16:51:561508
1509 const std::string wrong_id = all_zero;
1510 const std::string correct_id = good_crx;
1511 ASSERT_NE(correct_id, wrong_id);
1512
1513 // Install an external extension with an ID from the external
1514 // source that is not equal to the ID in the extension manifest.
1515 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531516 wrong_id, &version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511517 Extension::NO_FLAGS, false);
[email protected]604322d2011-03-22 16:51:561518
[email protected]b8f50ce2012-11-17 12:37:571519 loop_.RunUntilIdle();
[email protected]604322d2011-03-22 16:51:561520 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1521
1522 // Try again with the right ID. Expect success.
1523 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531524 correct_id, &version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511525 Extension::NO_FLAGS, false);
[email protected]b8f50ce2012-11-17 12:37:571526 loop_.RunUntilIdle();
[email protected]604322d2011-03-22 16:51:561527 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1528}
1529
1530// Test that external extensions with incorrect versions are not installed.
[email protected]d9a61e12012-11-14 02:43:471531TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
[email protected]604322d2011-03-22 16:51:561532 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351533 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]604322d2011-03-22 16:51:561534 set_extensions_enabled(true);
1535
1536 // Install an external extension with a version from the external
1537 // source that is not equal to the version in the extension manifest.
[email protected]12126d372012-07-11 18:40:531538 Version wrong_version("1.2.3.4");
[email protected]604322d2011-03-22 16:51:561539 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531540 good_crx, &wrong_version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511541 Extension::NO_FLAGS, false);
[email protected]604322d2011-03-22 16:51:561542
[email protected]b8f50ce2012-11-17 12:37:571543 loop_.RunUntilIdle();
[email protected]604322d2011-03-22 16:51:561544 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1545
1546 // Try again with the right version. Expect success.
[email protected]e3987852012-05-04 10:06:301547 service_->pending_extension_manager()->Remove(good_crx);
[email protected]12126d372012-07-11 18:40:531548 Version correct_version("1.0.0.0");
[email protected]604322d2011-03-22 16:51:561549 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531550 good_crx, &correct_version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511551 Extension::NO_FLAGS, false);
[email protected]b8f50ce2012-11-17 12:37:571552 loop_.RunUntilIdle();
[email protected]604322d2011-03-22 16:51:561553 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1554}
1555
[email protected]da0aa3b2009-12-06 21:41:031556// Install a user script (they get converted automatically to an extension)
[email protected]d9a61e12012-11-14 02:43:471557TEST_F(ExtensionServiceTest, InstallUserScript) {
[email protected]da0aa3b2009-12-06 21:41:031558 // The details of script conversion are tested elsewhere, this just tests
[email protected]eaa7dd182010-12-14 11:09:001559 // integration with ExtensionService.
1560 InitializeEmptyExtensionService();
[email protected]da0aa3b2009-12-06 21:41:031561
[email protected]e85e34c32011-04-13 18:38:351562 FilePath path = data_dir_
[email protected]da0aa3b2009-12-06 21:41:031563 .AppendASCII("user_script_basic.user.js");
1564
1565 ASSERT_TRUE(file_util::PathExists(path));
[email protected]d8c8f25f2011-11-02 18:18:011566 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
[email protected]0d3e4a22011-06-23 19:02:521567 installer->set_allow_silent_install(true);
[email protected]6dfbbf82010-03-12 23:09:161568 installer->InstallUserScript(
[email protected]da0aa3b2009-12-06 21:41:031569 path,
[email protected]6dfbbf82010-03-12 23:09:161570 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
[email protected]da0aa3b2009-12-06 21:41:031571
[email protected]b8f50ce2012-11-17 12:37:571572 loop_.RunUntilIdle();
[email protected]fc670822011-12-17 09:33:491573 std::vector<string16> errors = GetErrors();
[email protected]da0aa3b2009-12-06 21:41:031574 EXPECT_TRUE(installed_) << "Nothing was installed.";
1575 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1576 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1577 << JoinString(errors, ',');
1578 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
1579 path.value();
1580
1581 installed_ = NULL;
1582 loaded_.clear();
1583 ExtensionErrorReporter::GetInstance()->ClearErrors();
1584}
1585
[email protected]3c4abc82012-10-22 22:25:541586// Extensions don't install during shutdown.
[email protected]d9a61e12012-11-14 02:43:471587TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
[email protected]3c4abc82012-10-22 22:25:541588 InitializeEmptyExtensionService();
1589
1590 // Simulate shutdown.
1591 service_->set_browser_terminating_for_test(true);
1592
1593 FilePath path = data_dir_.AppendASCII("good.crx");
1594 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
1595 installer->set_allow_silent_install(true);
1596 installer->InstallCrx(path);
[email protected]b8f50ce2012-11-17 12:37:571597 loop_.RunUntilIdle();
[email protected]3c4abc82012-10-22 22:25:541598
1599 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1600 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1601}
1602
[email protected]8d888c12010-11-30 00:00:251603// This tests that the granted permissions preferences are correctly set when
1604// installing an extension.
[email protected]d9a61e12012-11-14 02:43:471605TEST_F(ExtensionServiceTest, GrantedPermissions) {
[email protected]eaa7dd182010-12-14 11:09:001606 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351607 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251608 .AppendASCII("permissions");
1609
[email protected]e85e34c32011-04-13 18:38:351610 FilePath pem_path = path.AppendASCII("unknown.pem");
[email protected]8d888c12010-11-30 00:00:251611 path = path.AppendASCII("unknown");
1612
1613 ASSERT_TRUE(file_util::PathExists(pem_path));
1614 ASSERT_TRUE(file_util::PathExists(path));
1615
1616 ExtensionPrefs* prefs = service_->extension_prefs();
1617
[email protected]c2e66e12012-06-27 06:27:061618 APIPermissionSet expected_api_perms;
[email protected]cced75a2011-05-20 08:31:121619 URLPatternSet expected_host_perms;
[email protected]8d888c12010-11-30 00:00:251620
1621 // Make sure there aren't any granted permissions before the
1622 // extension is installed.
[email protected]c2e66e12012-06-27 06:27:061623 scoped_refptr<PermissionSet> known_perms(
[email protected]0d3e4a22011-06-23 19:02:521624 prefs->GetGrantedPermissions(permissions_crx));
1625 EXPECT_FALSE(known_perms.get());
[email protected]8d888c12010-11-30 00:00:251626
[email protected]8f512c72011-11-22 21:02:501627 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251628
1629 EXPECT_EQ(0u, GetErrors().size());
1630 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:501631 EXPECT_EQ(permissions_crx, extension->id());
[email protected]8d888c12010-11-30 00:00:251632
[email protected]8d888c12010-11-30 00:00:251633 // Verify that the valid API permissions have been recognized.
[email protected]c2e66e12012-06-27 06:27:061634 expected_api_perms.insert(APIPermission::kTab);
[email protected]8d888c12010-11-30 00:00:251635
1636 AddPattern(&expected_host_perms, "http://*.google.com/*");
1637 AddPattern(&expected_host_perms, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151638 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251639 AddPattern(&expected_host_perms, "http://www.example.com/*");
1640
[email protected]8f512c72011-11-22 21:02:501641 known_perms = prefs->GetGrantedPermissions(extension->id());
[email protected]0d3e4a22011-06-23 19:02:521642 EXPECT_TRUE(known_perms.get());
1643 EXPECT_FALSE(known_perms->IsEmpty());
1644 EXPECT_EQ(expected_api_perms, known_perms->apis());
1645 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
[email protected]06e8b8ff2011-07-13 15:03:471646 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251647}
1648
[email protected]be083862012-09-01 03:53:451649
1650#if !defined(OS_CHROMEOS)
1651// This tests that the granted permissions preferences are correctly set for
1652// default apps.
[email protected]d9a61e12012-11-14 02:43:471653TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
[email protected]be083862012-09-01 03:53:451654 InitializeEmptyExtensionService();
1655 InitializeRequestContext();
1656 FilePath path = data_dir_
1657 .AppendASCII("permissions");
1658
1659 FilePath pem_path = path.AppendASCII("unknown.pem");
1660 path = path.AppendASCII("unknown");
1661
1662 ASSERT_TRUE(file_util::PathExists(pem_path));
1663 ASSERT_TRUE(file_util::PathExists(path));
1664
1665 ExtensionPrefs* prefs = service_->extension_prefs();
1666
1667 APIPermissionSet expected_api_perms;
1668 URLPatternSet expected_host_perms;
1669
1670 // Make sure there aren't any granted permissions before the
1671 // extension is installed.
1672 scoped_refptr<PermissionSet> known_perms(
1673 prefs->GetGrantedPermissions(permissions_crx));
1674 EXPECT_FALSE(known_perms.get());
1675
1676 const Extension* extension = PackAndInstallCRX(
1677 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1678
1679 EXPECT_EQ(0u, GetErrors().size());
1680 ASSERT_EQ(1u, service_->extensions()->size());
1681 EXPECT_EQ(permissions_crx, extension->id());
1682
1683 // Verify that the valid API permissions have been recognized.
1684 expected_api_perms.insert(APIPermission::kTab);
1685
1686 known_perms = prefs->GetGrantedPermissions(extension->id());
1687 EXPECT_TRUE(known_perms.get());
1688 EXPECT_FALSE(known_perms->IsEmpty());
1689 EXPECT_EQ(expected_api_perms, known_perms->apis());
1690 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1691}
1692#endif
1693
[email protected]8d888c12010-11-30 00:00:251694#if !defined(OS_CHROMEOS)
1695// Tests that the granted permissions full_access bit gets set correctly when
1696// an extension contains an NPAPI plugin. Don't run this test on Chrome OS
1697// since they don't support plugins.
[email protected]d9a61e12012-11-14 02:43:471698TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
[email protected]183d4b82011-11-11 18:50:261699 PluginService::GetInstance()->Init();
1700
[email protected]eaa7dd182010-12-14 11:09:001701 InitializeEmptyExtensionService();
[email protected]8d888c12010-11-30 00:00:251702
[email protected]e85e34c32011-04-13 18:38:351703 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251704 .AppendASCII("good")
1705 .AppendASCII("Extensions")
1706 .AppendASCII(good1)
1707 .AppendASCII("2");
1708
1709 ASSERT_TRUE(file_util::PathExists(path));
[email protected]8f512c72011-11-22 21:02:501710 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251711 EXPECT_EQ(0u, GetErrors().size());
1712 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8d888c12010-11-30 00:00:251713 ExtensionPrefs* prefs = service_->extension_prefs();
1714
[email protected]c2e66e12012-06-27 06:27:061715 scoped_refptr<PermissionSet> permissions(
[email protected]8f512c72011-11-22 21:02:501716 prefs->GetGrantedPermissions(extension->id()));
[email protected]0d3e4a22011-06-23 19:02:521717 EXPECT_FALSE(permissions->IsEmpty());
1718 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1719 EXPECT_FALSE(permissions->apis().empty());
[email protected]c2e66e12012-06-27 06:27:061720 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
[email protected]8d888c12010-11-30 00:00:251721
[email protected]0d3e4a22011-06-23 19:02:521722 // Full access implies full host access too...
1723 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
[email protected]8d888c12010-11-30 00:00:251724}
1725#endif
1726
1727// Tests that the extension is disabled when permissions are missing from
1728// the extension's granted permissions preferences. (This simulates updating
1729// the browser to a version which recognizes more permissions).
[email protected]d9a61e12012-11-14 02:43:471730TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
[email protected]eaa7dd182010-12-14 11:09:001731 InitializeEmptyExtensionService();
[email protected]8d888c12010-11-30 00:00:251732
[email protected]e85e34c32011-04-13 18:38:351733 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251734 .AppendASCII("permissions")
1735 .AppendASCII("unknown");
1736
1737 ASSERT_TRUE(file_util::PathExists(path));
1738
[email protected]8f512c72011-11-22 21:02:501739 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251740
1741 EXPECT_EQ(0u, GetErrors().size());
1742 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8d888c12010-11-30 00:00:251743 std::string extension_id = extension->id();
1744
1745 ExtensionPrefs* prefs = service_->extension_prefs();
1746
[email protected]c2e66e12012-06-27 06:27:061747 APIPermissionSet expected_api_permissions;
[email protected]cced75a2011-05-20 08:31:121748 URLPatternSet expected_host_permissions;
[email protected]8d888c12010-11-30 00:00:251749
[email protected]c2e66e12012-06-27 06:27:061750 expected_api_permissions.insert(APIPermission::kTab);
[email protected]8d888c12010-11-30 00:00:251751 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1752 AddPattern(&expected_host_permissions, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151753 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251754 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1755
[email protected]8d888c12010-11-30 00:00:251756 std::set<std::string> host_permissions;
1757
1758 // Test that the extension is disabled when an API permission is missing from
1759 // the extension's granted api permissions preference. (This simulates
1760 // updating the browser to a version which recognizes a new API permission).
[email protected]0d3e4a22011-06-23 19:02:521761 SetPref(extension_id, "granted_permissions.api",
1762 new ListValue(), "granted_permissions.api");
[email protected]8d888c12010-11-30 00:00:251763 service_->ReloadExtensions();
1764
1765 EXPECT_EQ(1u, service_->disabled_extensions()->size());
[email protected]8f512c72011-11-22 21:02:501766 extension = *service_->disabled_extensions()->begin();
[email protected]8d888c12010-11-30 00:00:251767
[email protected]ad83ca242011-07-29 01:32:251768 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
[email protected]36429da2011-07-11 20:25:181769 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251770 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1771
1772 // Now grant and re-enable the extension, making sure the prefs are updated.
[email protected]b70a2d92012-06-28 19:51:211773 service_->GrantPermissionsAndEnableExtension(extension, false);
[email protected]8d888c12010-11-30 00:00:251774
[email protected]ad83ca242011-07-29 01:32:251775 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
[email protected]36429da2011-07-11 20:25:181776 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251777 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1778
[email protected]c2e66e12012-06-27 06:27:061779 scoped_refptr<PermissionSet> current_perms(
[email protected]0d3e4a22011-06-23 19:02:521780 prefs->GetGrantedPermissions(extension_id));
1781 ASSERT_TRUE(current_perms.get());
1782 ASSERT_FALSE(current_perms->IsEmpty());
1783 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
1784 ASSERT_EQ(expected_api_permissions, current_perms->apis());
[email protected]06e8b8ff2011-07-13 15:03:471785 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251786
1787 // Tests that the extension is disabled when a host permission is missing from
1788 // the extension's granted host permissions preference. (This simulates
1789 // updating the browser to a version which recognizes additional host
1790 // permissions).
[email protected]8d888c12010-11-30 00:00:251791 host_permissions.clear();
[email protected]902fd7b2011-07-27 18:42:311792 current_perms = NULL;
[email protected]8d888c12010-11-30 00:00:251793
[email protected]8d888c12010-11-30 00:00:251794 host_permissions.insert("http://*.google.com/*");
1795 host_permissions.insert("https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151796 host_permissions.insert("http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251797
[email protected]0d3e4a22011-06-23 19:02:521798 ListValue* api_permissions = new ListValue();
1799 api_permissions->Append(
[email protected]1d8b79a2012-08-16 20:22:541800 Value::CreateStringValue("tabs"));
[email protected]0d3e4a22011-06-23 19:02:521801 SetPref(extension_id, "granted_permissions.api",
1802 api_permissions, "granted_permissions.api");
1803 SetPrefStringSet(
1804 extension_id, "granted_permissions.scriptable_host", host_permissions);
[email protected]8d888c12010-11-30 00:00:251805
1806 service_->ReloadExtensions();
1807
1808 EXPECT_EQ(1u, service_->disabled_extensions()->size());
[email protected]8f512c72011-11-22 21:02:501809 extension = *service_->disabled_extensions()->begin();
[email protected]8d888c12010-11-30 00:00:251810
[email protected]ad83ca242011-07-29 01:32:251811 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
[email protected]36429da2011-07-11 20:25:181812 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251813 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1814
1815 // Now grant and re-enable the extension, making sure the prefs are updated.
[email protected]b70a2d92012-06-28 19:51:211816 service_->GrantPermissionsAndEnableExtension(extension, false);
[email protected]8d888c12010-11-30 00:00:251817
[email protected]36429da2011-07-11 20:25:181818 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251819 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1820
[email protected]902fd7b2011-07-27 18:42:311821 current_perms = prefs->GetGrantedPermissions(extension_id);
[email protected]0d3e4a22011-06-23 19:02:521822 ASSERT_TRUE(current_perms.get());
1823 ASSERT_FALSE(current_perms->IsEmpty());
1824 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
1825 ASSERT_EQ(expected_api_permissions, current_perms->apis());
[email protected]06e8b8ff2011-07-13 15:03:471826 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251827}
1828
[email protected]a17f9462009-06-09 02:56:411829// Test Packaging and installing an extension.
[email protected]d9a61e12012-11-14 02:43:471830TEST_F(ExtensionServiceTest, PackExtension) {
[email protected]eaa7dd182010-12-14 11:09:001831 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351832 FilePath input_directory = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231833 .AppendASCII("good")
1834 .AppendASCII("Extensions")
1835 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1836 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:411837
[email protected]ea1a3f62012-11-16 20:34:231838 base::ScopedTempDir temp_dir;
[email protected]aca3e9b2009-11-03 01:14:211839 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1840 FilePath output_directory = temp_dir.path();
1841
[email protected]a17f9462009-06-09 02:56:411842 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1843 FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
1844
1845 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1846 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
[email protected]93d973a2012-01-08 07:38:261847 privkey_path, ExtensionCreator::kNoRunFlags));
1848 ASSERT_TRUE(file_util::PathExists(crx_path));
1849 ASSERT_TRUE(file_util::PathExists(privkey_path));
1850
1851 // Repeat the run with the pem file gone, and no special flags
1852 // Should refuse to overwrite the existing crx.
1853 file_util::Delete(privkey_path, false);
1854 ASSERT_FALSE(creator->Run(input_directory, crx_path, FilePath(),
1855 privkey_path, ExtensionCreator::kNoRunFlags));
1856
1857 // OK, now try it with a flag to overwrite existing crx. Should work.
1858 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
1859 privkey_path, ExtensionCreator::kOverwriteCRX));
1860
1861 // Repeat the run allowing existing crx, but the existing pem is still
1862 // an error. Should fail.
1863 ASSERT_FALSE(creator->Run(input_directory, crx_path, FilePath(),
1864 privkey_path, ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:411865
[email protected]a17f9462009-06-09 02:56:411866 ASSERT_TRUE(file_util::PathExists(privkey_path));
[email protected]8f512c72011-11-22 21:02:501867 InstallCRX(crx_path, INSTALL_NEW);
[email protected]0dc2ca82009-11-17 07:06:161868
1869 // Try packing with invalid paths.
1870 creator.reset(new ExtensionCreator());
[email protected]93d973a2012-01-08 07:38:261871 ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath(),
1872 ExtensionCreator::kOverwriteCRX));
[email protected]0dc2ca82009-11-17 07:06:161873
1874 // Try packing an empty directory. Should fail because an empty directory is
1875 // not a valid extension.
[email protected]ea1a3f62012-11-16 20:34:231876 base::ScopedTempDir temp_dir2;
[email protected]0dc2ca82009-11-17 07:06:161877 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
1878 creator.reset(new ExtensionCreator());
1879 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
[email protected]93d973a2012-01-08 07:38:261880 FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]0dc2ca82009-11-17 07:06:161881
1882 // Try packing with an invalid manifest.
1883 std::string invalid_manifest_content = "I am not a manifest.";
1884 ASSERT_TRUE(file_util::WriteFile(
[email protected]99efb7b12009-12-18 02:39:161885 temp_dir2.path().Append(Extension::kManifestFilename),
[email protected]0dc2ca82009-11-17 07:06:161886 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
1887 creator.reset(new ExtensionCreator());
1888 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
[email protected]93d973a2012-01-08 07:38:261889 FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:411890}
1891
[email protected]0349ab5d2010-08-11 21:41:571892// Test Packaging and installing an extension whose name contains punctuation.
[email protected]d9a61e12012-11-14 02:43:471893TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
[email protected]eaa7dd182010-12-14 11:09:001894 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351895 FilePath input_directory = data_dir_
[email protected]0349ab5d2010-08-11 21:41:571896 .AppendASCII("good")
1897 .AppendASCII("Extensions")
1898 .AppendASCII(good0)
1899 .AppendASCII("1.0.0.0");
1900
[email protected]ea1a3f62012-11-16 20:34:231901 base::ScopedTempDir temp_dir;
[email protected]0349ab5d2010-08-11 21:41:571902 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1903
1904 // Extension names containing punctuation, and the expected names for the
1905 // packed extensions.
1906 const FilePath punctuated_names[] = {
[email protected]d9034ed22012-02-10 02:04:401907 FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
1908 FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
1909 FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
1910 NormalizePathSeparators(),
[email protected]0349ab5d2010-08-11 21:41:571911 };
1912 const FilePath expected_crx_names[] = {
[email protected]d9034ed22012-02-10 02:04:401913 FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
1914 FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
1915 FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
[email protected]0349ab5d2010-08-11 21:41:571916 };
1917 const FilePath expected_private_key_names[] = {
[email protected]d9034ed22012-02-10 02:04:401918 FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
1919 FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
1920 FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
[email protected]0349ab5d2010-08-11 21:41:571921 };
1922
1923 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
1924 SCOPED_TRACE(punctuated_names[i].value().c_str());
1925 FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
1926
1927 // Copy the extension into the output directory, as PackExtensionJob doesn't
1928 // let us choose where to output the packed extension.
1929 ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true));
1930
1931 FilePath expected_crx_path = temp_dir.path().Append(expected_crx_names[i]);
1932 FilePath expected_private_key_path =
1933 temp_dir.path().Append(expected_private_key_names[i]);
1934 PackExtensionTestClient pack_client(expected_crx_path,
1935 expected_private_key_path);
[email protected]d9ede582012-08-14 19:21:381936 scoped_refptr<extensions::PackExtensionJob> packer(
1937 new extensions::PackExtensionJob(&pack_client, output_dir, FilePath(),
1938 ExtensionCreator::kOverwriteCRX));
[email protected]0349ab5d2010-08-11 21:41:571939 packer->Start();
1940
1941 // The packer will post a notification task to the current thread's message
1942 // loop when it is finished. We manually run the loop here so that we
1943 // block and catch the notification; otherwise, the process would exit.
1944 // This call to |Run()| is matched by a call to |Quit()| in the
1945 // |PackExtensionTestClient|'s notification handling code.
1946 MessageLoop::current()->Run();
1947
1948 if (HasFatalFailure())
1949 return;
1950
[email protected]8f512c72011-11-22 21:02:501951 InstallCRX(expected_crx_path, INSTALL_NEW);
[email protected]0349ab5d2010-08-11 21:41:571952 }
1953}
1954
[email protected]d9a61e12012-11-14 02:43:471955TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
[email protected]ab55c2b2012-06-01 23:55:031956 InitializeEmptyExtensionService();
1957
[email protected]ea1a3f62012-11-16 20:34:231958 base::ScopedTempDir extension_temp_dir;
[email protected]ab55c2b2012-06-01 23:55:031959 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
1960 FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
1961 ASSERT_TRUE(file_util::CopyDirectory(
1962 data_dir_
1963 .AppendASCII("good")
1964 .AppendASCII("Extensions")
1965 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1966 .AppendASCII("1.0.0.0"),
1967 input_directory,
1968 /*recursive=*/true));
1969
[email protected]ea1a3f62012-11-16 20:34:231970 base::ScopedTempDir output_temp_dir;
[email protected]ab55c2b2012-06-01 23:55:031971 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
1972 FilePath output_directory = output_temp_dir.path();
1973
1974 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1975 FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
1976
1977 // Pack the extension once to get a private key.
1978 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1979 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
1980 privkey_path, ExtensionCreator::kNoRunFlags))
1981 << creator->error_message();
1982 ASSERT_TRUE(file_util::PathExists(crx_path));
1983 ASSERT_TRUE(file_util::PathExists(privkey_path));
1984
1985 file_util::Delete(crx_path, false);
1986 // Move the pem file into the extension.
1987 file_util::Move(privkey_path,
1988 input_directory.AppendASCII("privkey.pem"));
1989
1990 // This pack should fail because of the contained private key.
1991 EXPECT_FALSE(creator->Run(input_directory, crx_path, FilePath(),
1992 privkey_path, ExtensionCreator::kNoRunFlags));
1993 EXPECT_THAT(creator->error_message(),
1994 testing::ContainsRegex(
1995 "extension includes the key file.*privkey.pem"));
1996}
1997
[email protected]a17f9462009-06-09 02:56:411998// Test Packaging and installing an extension using an openssl generated key.
1999// The openssl is generated with the following:
[email protected]a1257b12009-06-12 02:51:342000// > openssl genrsa -out privkey.pem 1024
[email protected]df4956e2009-06-10 16:53:422001// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
[email protected]a1257b12009-06-12 02:51:342002// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
[email protected]a17f9462009-06-09 02:56:412003// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
[email protected]d9a61e12012-11-14 02:43:472004TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
[email protected]eaa7dd182010-12-14 11:09:002005 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:352006 FilePath input_directory = data_dir_
[email protected]a9b00ac2009-06-25 21:03:232007 .AppendASCII("good")
2008 .AppendASCII("Extensions")
2009 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2010 .AppendASCII("1.0.0.0");
[email protected]e85e34c32011-04-13 18:38:352011 FilePath privkey_path(data_dir_.AppendASCII(
[email protected]a17f9462009-06-09 02:56:412012 "openssl_privkey_asn1.pem"));
2013 ASSERT_TRUE(file_util::PathExists(privkey_path));
2014
[email protected]ea1a3f62012-11-16 20:34:232015 base::ScopedTempDir temp_dir;
[email protected]aca3e9b2009-11-03 01:14:212016 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2017 FilePath output_directory = temp_dir.path();
2018
[email protected]a17f9462009-06-09 02:56:412019 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2020
2021 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2022 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
[email protected]93d973a2012-01-08 07:38:262023 FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:412024
[email protected]8f512c72011-11-22 21:02:502025 InstallCRX(crx_path, INSTALL_NEW);
[email protected]a17f9462009-06-09 02:56:412026}
[email protected]a17f9462009-06-09 02:56:412027
[email protected]d9a61e12012-11-14 02:43:472028TEST_F(ExtensionServiceTest, InstallTheme) {
[email protected]eaa7dd182010-12-14 11:09:002029 InitializeEmptyExtensionService();
[email protected]e2eb43112009-05-29 21:19:542030
2031 // A theme.
[email protected]e85e34c32011-04-13 18:38:352032 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8f512c72011-11-22 21:02:502033 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:192034 int pref_count = 0;
2035 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:342036 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2037 ValidateIntegerPref(theme_crx, "location", Extension::INTERNAL);
[email protected]e2eb43112009-05-29 21:19:542038
[email protected]6ef635e42009-07-26 06:16:122039 // A theme when extensions are disabled. Themes can be installed, even when
2040 // extensions are disabled.
[email protected]7577a5c52009-07-30 06:21:582041 set_extensions_enabled(false);
[email protected]e85e34c32011-04-13 18:38:352042 path = data_dir_.AppendASCII("theme2.crx");
[email protected]8f512c72011-11-22 21:02:502043 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:192044 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:342045 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2046 ValidateIntegerPref(theme2_crx, "location", Extension::INTERNAL);
[email protected]494c06e2009-07-25 01:06:422047
[email protected]f6dec1e322012-04-30 21:04:512048 // A theme with extension elements. Themes cannot have extension elements,
2049 // so any such elements (like content scripts) should be ignored.
[email protected]7577a5c52009-07-30 06:21:582050 set_extensions_enabled(true);
[email protected]f6dec1e322012-04-30 21:04:512051 {
2052 path = data_dir_.AppendASCII("theme_with_extension.crx");
2053 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2054 ValidatePrefKeyCount(++pref_count);
2055 ASSERT_TRUE(extension);
2056 EXPECT_TRUE(extension->is_theme());
2057 EXPECT_EQ(0u, extension->content_scripts().size());
2058 }
[email protected]12198912009-06-05 03:41:222059
2060 // A theme with image resources missing (misspelt path).
[email protected]e85e34c32011-04-13 18:38:352061 path = data_dir_.AppendASCII("theme_missing_image.crx");
[email protected]8f512c72011-11-22 21:02:502062 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:192063 ValidatePrefKeyCount(pref_count);
[email protected]e2eb43112009-05-29 21:19:542064}
2065
[email protected]d9a61e12012-11-14 02:43:472066TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
[email protected]584245e52010-06-17 01:08:132067 // Load.
[email protected]eaa7dd182010-12-14 11:09:002068 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:352069 FilePath extension_path = data_dir_
[email protected]584245e52010-06-17 01:08:132070 .AppendASCII("theme_i18n");
2071
[email protected]d8c8f25f2011-11-02 18:18:012072 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
[email protected]b8f50ce2012-11-17 12:37:572073 loop_.RunUntilIdle();
[email protected]584245e52010-06-17 01:08:132074 EXPECT_EQ(0u, GetErrors().size());
2075 ASSERT_EQ(1u, loaded_.size());
2076 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502077 const Extension* theme = *service_->extensions()->begin();
2078 EXPECT_EQ("name", theme->name());
2079 EXPECT_EQ("description", theme->description());
[email protected]584245e52010-06-17 01:08:132080}
2081
[email protected]c24fb292012-02-01 22:52:112082// Tests that we can change the ID of an unpacked extension by adding a key
2083// to its manifest.
[email protected]d9a61e12012-11-14 02:43:472084TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) {
[email protected]c24fb292012-02-01 22:52:112085 InitializeEmptyExtensionService();
2086
[email protected]ea1a3f62012-11-16 20:34:232087 base::ScopedTempDir temp;
[email protected]c24fb292012-02-01 22:52:112088 ASSERT_TRUE(temp.CreateUniqueTempDir());
2089
2090 FilePath extension_path = temp.path();
2091 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
2092 FilePath manifest_no_key = data_dir_.
2093 AppendASCII("unpacked").
2094 AppendASCII("manifest_no_key.json");
2095
2096 FilePath manifest_with_key = data_dir_.
2097 AppendASCII("unpacked").
2098 AppendASCII("manifest_with_key.json");
2099
2100 ASSERT_TRUE(file_util::PathExists(manifest_no_key));
2101 ASSERT_TRUE(file_util::PathExists(manifest_with_key));
2102
2103 // Load the unpacked extension with no key.
2104 file_util::CopyFile(manifest_no_key, manifest_path);
2105 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2106
[email protected]b8f50ce2012-11-17 12:37:572107 loop_.RunUntilIdle();
[email protected]c24fb292012-02-01 22:52:112108 EXPECT_EQ(0u, GetErrors().size());
2109 ASSERT_EQ(1u, loaded_.size());
2110 EXPECT_EQ(1u, service_->extensions()->size());
2111
2112 // Add the key to the manifest.
2113 file_util::CopyFile(manifest_with_key, manifest_path);
2114 loaded_.clear();
2115
2116 // Reload the extensions.
2117 service_->ReloadExtensions();
2118 const Extension* extension = service_->GetExtensionById(unpacked, false);
2119 EXPECT_EQ(unpacked, extension->id());
2120 ASSERT_EQ(1u, loaded_.size());
2121
2122 // TODO(jstritar): Right now this just makes sure we don't crash and burn, but
2123 // we should also test that preferences are preserved.
2124}
2125
[email protected]91236521162012-05-24 15:02:512126#if defined(OS_POSIX)
[email protected]d9a61e12012-11-14 02:43:472127TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
[email protected]91236521162012-05-24 15:02:512128 FilePath source_data_dir = data_dir_.
2129 AppendASCII("unpacked").
2130 AppendASCII("symlinks_allowed");
2131
2132 // Paths to test data files.
2133 FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2134 ASSERT_TRUE(file_util::PathExists(source_manifest));
2135 FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2136 ASSERT_TRUE(file_util::PathExists(source_icon));
2137
2138 // Set up the temporary extension directory.
[email protected]ea1a3f62012-11-16 20:34:232139 base::ScopedTempDir temp;
[email protected]91236521162012-05-24 15:02:512140 ASSERT_TRUE(temp.CreateUniqueTempDir());
2141 FilePath extension_path = temp.path();
2142 FilePath manifest = extension_path.Append(Extension::kManifestFilename);
2143 FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2144 file_util::CopyFile(source_manifest, manifest);
2145 file_util::CreateSymbolicLink(source_icon, icon_symlink);
2146
2147 // Load extension.
2148 InitializeEmptyExtensionService();
2149 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
[email protected]b8f50ce2012-11-17 12:37:572150 loop_.RunUntilIdle();
[email protected]91236521162012-05-24 15:02:512151
2152 EXPECT_TRUE(GetErrors().empty());
2153 ASSERT_EQ(1u, loaded_.size());
2154 EXPECT_EQ(1u, service_->extensions()->size());
2155}
2156#endif
2157
[email protected]d9a61e12012-11-14 02:43:472158TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
[email protected]eaa7dd182010-12-14 11:09:002159 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:352160 FilePath theme_path = data_dir_
[email protected]584245e52010-06-17 01:08:132161 .AppendASCII("theme_i18n");
2162
[email protected]8f512c72011-11-22 21:02:502163 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
[email protected]584245e52010-06-17 01:08:132164
[email protected]584245e52010-06-17 01:08:132165 EXPECT_EQ(0u, GetErrors().size());
2166 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502167 EXPECT_EQ("name", theme->name());
2168 EXPECT_EQ("description", theme->description());
[email protected]584245e52010-06-17 01:08:132169}
2170
[email protected]d9a61e12012-11-14 02:43:472171TEST_F(ExtensionServiceTest, InstallApps) {
[email protected]eaa7dd182010-12-14 11:09:002172 InitializeEmptyExtensionService();
[email protected]6d2e60bd2010-06-03 22:37:392173
2174 // An empty app.
[email protected]8f512c72011-11-22 21:02:502175 const Extension* app = PackAndInstallCRX(data_dir_.AppendASCII("app1"),
2176 INSTALL_NEW);
[email protected]6d2e60bd2010-06-03 22:37:392177 int pref_count = 0;
2178 ValidatePrefKeyCount(++pref_count);
[email protected]3ba0fd32010-06-19 05:39:102179 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502180 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2181 ValidateIntegerPref(app->id(), "location", Extension::INTERNAL);
[email protected]6d2e60bd2010-06-03 22:37:392182
2183 // Another app with non-overlapping extent. Should succeed.
[email protected]8f512c72011-11-22 21:02:502184 PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
[email protected]6d2e60bd2010-06-03 22:37:392185 ValidatePrefKeyCount(++pref_count);
2186
2187 // A third app whose extent overlaps the first. Should fail.
[email protected]8f512c72011-11-22 21:02:502188 PackAndInstallCRX(data_dir_.AppendASCII("app3"), INSTALL_FAILED);
[email protected]cd10e282010-10-26 21:04:512189 ValidatePrefKeyCount(pref_count);
[email protected]6d2e60bd2010-06-03 22:37:392190}
2191
[email protected]b6e64fd2011-08-09 19:49:192192// Tests that file access is OFF by default.
[email protected]d9a61e12012-11-14 02:43:472193TEST_F(ExtensionServiceTest, DefaultFileAccess) {
[email protected]b6e64fd2011-08-09 19:49:192194 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:502195 const Extension* extension =
2196 PackAndInstallCRX(data_dir_
2197 .AppendASCII("permissions")
2198 .AppendASCII("files"),
2199 INSTALL_NEW);
[email protected]b6e64fd2011-08-09 19:49:192200 EXPECT_EQ(0u, GetErrors().size());
2201 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502202 EXPECT_FALSE(service_->extension_prefs()->AllowFileAccess(extension->id()));
[email protected]b6e64fd2011-08-09 19:49:192203}
2204
[email protected]d9a61e12012-11-14 02:43:472205TEST_F(ExtensionServiceTest, UpdateApps) {
[email protected]15300d92011-01-19 18:44:302206 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:352207 FilePath extensions_path = data_dir_.AppendASCII("app_update");
[email protected]15300d92011-01-19 18:44:302208
2209 // First install v1 of a hosted app.
[email protected]8f512c72011-11-22 21:02:502210 const Extension* extension =
2211 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
[email protected]15300d92011-01-19 18:44:302212 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502213 std::string id = extension->id();
2214 ASSERT_EQ(std::string("1"), extension->version()->GetString());
[email protected]15300d92011-01-19 18:44:302215
2216 // Now try updating to v2.
2217 UpdateExtension(id,
2218 extensions_path.AppendASCII("v2.crx"),
2219 ENABLED);
2220 ASSERT_EQ(std::string("2"),
[email protected]8f512c72011-11-22 21:02:502221 service_->GetExtensionById(id, false)->version()->GetString());
[email protected]15300d92011-01-19 18:44:302222}
2223
[email protected]e6a6c2e02012-01-13 00:06:482224// Verifies that the NTP page and launch ordinals are kept when updating apps.
[email protected]d9a61e12012-11-14 02:43:472225TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
[email protected]e6a6c2e02012-01-13 00:06:482226 InitializeEmptyExtensionService();
2227 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
2228 FilePath extensions_path = data_dir_.AppendASCII("app_update");
2229
2230 // First install v1 of a hosted app.
2231 const Extension* extension =
2232 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2233 ASSERT_EQ(1u, service_->extensions()->size());
2234 std::string id = extension->id();
2235 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2236
2237 // Modify the ordinals so we can distinguish them from the defaults.
[email protected]36b643212012-09-07 12:53:002238 syncer::StringOrdinal new_page_ordinal =
2239 sorting->GetPageOrdinal(id).CreateAfter();
2240 syncer::StringOrdinal new_launch_ordinal =
[email protected]e6a6c2e02012-01-13 00:06:482241 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2242
2243 sorting->SetPageOrdinal(id, new_page_ordinal);
2244 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2245
2246 // Now try updating to v2.
2247 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2248 ASSERT_EQ(std::string("2"),
2249 service_->GetExtensionById(id, false)->version()->GetString());
2250
2251 // Verify that the ordinals match.
[email protected]36b643212012-09-07 12:53:002252 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2253 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
[email protected]e6a6c2e02012-01-13 00:06:482254}
2255
[email protected]b873cd92012-02-09 21:51:482256// Ensures that the CWS has properly initialized ordinals.
[email protected]d9a61e12012-11-14 02:43:472257TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
[email protected]b873cd92012-02-09 21:51:482258 InitializeEmptyExtensionService();
2259 service_->component_loader()->Add(IDR_WEBSTORE_MANIFEST,
2260 FilePath(FILE_PATH_LITERAL("web_store")));
2261 service_->Init();
2262
[email protected]b873cd92012-02-09 21:51:482263 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
2264 EXPECT_TRUE(
2265 sorting->GetPageOrdinal(extension_misc::kWebStoreAppId).IsValid());
2266 EXPECT_TRUE(
2267 sorting->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId).IsValid());
2268}
2269
[email protected]8b0d36bc2012-08-29 22:09:172270// Flaky failures on Vista. http://crbug.com/145381
2271#if defined(OS_WIN)
2272#define MAYBE_InstallAppsWithUnlimitedStorage \
2273 DISABLED_InstallAppsWithUnlimitedStorage
2274#else
2275#define MAYBE_InstallAppsWithUnlimitedStorage InstallAppsWithUnlimitedStorage
2276#endif
2277
[email protected]d9a61e12012-11-14 02:43:472278TEST_F(ExtensionServiceTest, MAYBE_InstallAppsWithUnlimitedStorage) {
[email protected]eaa7dd182010-12-14 11:09:002279 InitializeEmptyExtensionService();
[email protected]0d6ec3a72011-09-02 02:09:432280 InitializeRequestContext();
[email protected]84df8332011-12-06 18:22:462281 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]c2c263c2010-08-13 21:59:482282
[email protected]c2c263c2010-08-13 21:59:482283 int pref_count = 0;
[email protected]c2c263c2010-08-13 21:59:482284
2285 // Install app1 with unlimited storage.
[email protected]8f512c72011-11-22 21:02:502286 const Extension* extension =
2287 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
[email protected]c2c263c2010-08-13 21:59:482288 ValidatePrefKeyCount(++pref_count);
2289 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]c2c263c2010-08-13 21:59:482290 const std::string id1 = extension->id();
[email protected]0d3e4a22011-06-23 19:02:522291 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:062292 APIPermission::kUnlimitedStorage));
[email protected]cced75a2011-05-20 08:31:122293 EXPECT_TRUE(extension->web_extent().MatchesURL(
[email protected]c2c263c2010-08-13 21:59:482294 extension->GetFullLaunchURL()));
2295 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
[email protected]19eb80152011-02-26 00:28:432296 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2297 IsStorageUnlimited(origin1));
[email protected]c2c263c2010-08-13 21:59:482298
2299 // Install app2 from the same origin with unlimited storage.
[email protected]8f512c72011-11-22 21:02:502300 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
[email protected]c2c263c2010-08-13 21:59:482301 ValidatePrefKeyCount(++pref_count);
2302 ASSERT_EQ(2u, service_->extensions()->size());
[email protected]c2c263c2010-08-13 21:59:482303 const std::string id2 = extension->id();
[email protected]0d3e4a22011-06-23 19:02:522304 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:062305 APIPermission::kUnlimitedStorage));
[email protected]cced75a2011-05-20 08:31:122306 EXPECT_TRUE(extension->web_extent().MatchesURL(
[email protected]c2c263c2010-08-13 21:59:482307 extension->GetFullLaunchURL()));
2308 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
2309 EXPECT_EQ(origin1, origin2);
[email protected]19eb80152011-02-26 00:28:432310 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2311 IsStorageUnlimited(origin2));
2312
[email protected]c2c263c2010-08-13 21:59:482313
2314 // Uninstall one of them, unlimited storage should still be granted
2315 // to the origin.
[email protected]fa2416f2011-05-03 08:41:202316 UninstallExtension(id1, false);
[email protected]c2c263c2010-08-13 21:59:482317 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]19eb80152011-02-26 00:28:432318 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2319 IsStorageUnlimited(origin1));
2320
[email protected]c2c263c2010-08-13 21:59:482321 // Uninstall the other, unlimited storage should be revoked.
[email protected]fa2416f2011-05-03 08:41:202322 UninstallExtension(id2, false);
[email protected]c2c263c2010-08-13 21:59:482323 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]19eb80152011-02-26 00:28:432324 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2325 IsStorageUnlimited(origin2));
[email protected]c2c263c2010-08-13 21:59:482326}
2327
[email protected]d9a61e12012-11-14 02:43:472328TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
[email protected]eaa7dd182010-12-14 11:09:002329 InitializeEmptyExtensionService();
[email protected]0d6ec3a72011-09-02 02:09:432330 InitializeRequestContext();
[email protected]84df8332011-12-06 18:22:462331 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]654512b2010-09-01 02:09:422332
[email protected]654512b2010-09-01 02:09:422333 int pref_count = 0;
2334
[email protected]8f512c72011-11-22 21:02:502335 const Extension* extension =
2336 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
[email protected]654512b2010-09-01 02:09:422337 ValidatePrefKeyCount(++pref_count);
2338 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]654512b2010-09-01 02:09:422339 EXPECT_TRUE(extension->is_app());
2340 const std::string id1 = extension->id();
[email protected]654512b2010-09-01 02:09:422341 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
[email protected]19eb80152011-02-26 00:28:432342 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2343 IsStorageProtected(origin1));
[email protected]654512b2010-09-01 02:09:422344
2345 // App 4 has a different origin (maps.google.com).
[email protected]8f512c72011-11-22 21:02:502346 extension = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
[email protected]654512b2010-09-01 02:09:422347 ValidatePrefKeyCount(++pref_count);
2348 ASSERT_EQ(2u, service_->extensions()->size());
[email protected]654512b2010-09-01 02:09:422349 const std::string id2 = extension->id();
[email protected]654512b2010-09-01 02:09:422350 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
2351 ASSERT_NE(origin1, origin2);
[email protected]19eb80152011-02-26 00:28:432352 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2353 IsStorageProtected(origin2));
[email protected]654512b2010-09-01 02:09:422354
[email protected]fa2416f2011-05-03 08:41:202355 UninstallExtension(id1, false);
[email protected]654512b2010-09-01 02:09:422356 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]654512b2010-09-01 02:09:422357
[email protected]fa2416f2011-05-03 08:41:202358 UninstallExtension(id2, false);
[email protected]654512b2010-09-01 02:09:422359
[email protected]84df8332011-12-06 18:22:462360 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]19eb80152011-02-26 00:28:432361 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2362 IsStorageProtected(origin1));
2363 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2364 IsStorageProtected(origin2));
[email protected]654512b2010-09-01 02:09:422365}
2366
[email protected]894bb502009-05-21 22:39:572367// Test that when an extension version is reinstalled, nothing happens.
[email protected]d9a61e12012-11-14 02:43:472368TEST_F(ExtensionServiceTest, Reinstall) {
[email protected]eaa7dd182010-12-14 11:09:002369 InitializeEmptyExtensionService();
[email protected]894bb502009-05-21 22:39:572370
2371 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:352372 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502373 InstallCRX(path, INSTALL_NEW);
[email protected]894bb502009-05-21 22:39:572374
[email protected]25b34332009-06-05 21:53:192375 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342376 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2377 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:572378
[email protected]ca3dbf52010-05-19 22:27:062379 // Reinstall the same version, it should overwrite the previous one.
[email protected]8f512c72011-11-22 21:02:502380 InstallCRX(path, INSTALL_UPDATED);
[email protected]894bb502009-05-21 22:39:572381
[email protected]25b34332009-06-05 21:53:192382 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342383 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2384 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:572385}
2386
[email protected]620db1762011-07-15 21:57:342387// Test that we can determine if extensions came from the
2388// Chrome web store.
[email protected]d9a61e12012-11-14 02:43:472389TEST_F(ExtensionServiceTest, FromWebStore) {
[email protected]8266d662011-07-12 21:53:262390 InitializeEmptyExtensionService();
2391
2392 // A simple extension that should install without error.
2393 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502394 // Not from web store.
2395 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2396 std::string id = extension->id();
[email protected]8266d662011-07-12 21:53:262397
[email protected]8266d662011-07-12 21:53:262398 ValidatePrefKeyCount(1);
2399 ValidateBooleanPref(good_crx, "from_webstore", false);
[email protected]620db1762011-07-15 21:57:342400 ASSERT_FALSE(extension->from_webstore());
[email protected]8266d662011-07-12 21:53:262401
[email protected]8266d662011-07-12 21:53:262402 // Test install from web store.
[email protected]8f512c72011-11-22 21:02:502403 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
[email protected]8266d662011-07-12 21:53:262404
[email protected]8266d662011-07-12 21:53:262405 ValidatePrefKeyCount(1);
2406 ValidateBooleanPref(good_crx, "from_webstore", true);
[email protected]620db1762011-07-15 21:57:342407
2408 // Reload so extension gets reinitialized with new value.
2409 service_->ReloadExtensions();
[email protected]8f512c72011-11-22 21:02:502410 extension = service_->GetExtensionById(id, false);
[email protected]620db1762011-07-15 21:57:342411 ASSERT_TRUE(extension->from_webstore());
[email protected]3d729722011-09-20 02:57:092412
2413 // Upgrade to version 2.0
2414 path = data_dir_.AppendASCII("good2.crx");
2415 UpdateExtension(good_crx, path, ENABLED);
2416 ValidatePrefKeyCount(1);
2417 ValidateBooleanPref(good_crx, "from_webstore", true);
[email protected]8266d662011-07-12 21:53:262418}
2419
[email protected]fbcc40302009-06-12 20:45:452420// Test upgrading a signed extension.
[email protected]d9a61e12012-11-14 02:43:472421TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
[email protected]eaa7dd182010-12-14 11:09:002422 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:452423
[email protected]e85e34c32011-04-13 18:38:352424 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502425 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2426 std::string id = extension->id();
[email protected]fbcc40302009-06-12 20:45:452427
[email protected]8f512c72011-11-22 21:02:502428 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:452429 ASSERT_EQ(0u, GetErrors().size());
2430
[email protected]8f512c72011-11-22 21:02:502431 // Upgrade to version 1.0.0.1
[email protected]e85e34c32011-04-13 18:38:352432 path = data_dir_.AppendASCII("good2.crx");
[email protected]8f512c72011-11-22 21:02:502433 InstallCRX(path, INSTALL_UPDATED);
2434 extension = service_->GetExtensionById(id, false);
[email protected]fbcc40302009-06-12 20:45:452435
[email protected]8f512c72011-11-22 21:02:502436 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:452437 ASSERT_EQ(0u, GetErrors().size());
2438}
2439
2440// Test upgrading a signed extension with a bad signature.
[email protected]d9a61e12012-11-14 02:43:472441TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
[email protected]eaa7dd182010-12-14 11:09:002442 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:452443
[email protected]e85e34c32011-04-13 18:38:352444 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502445 InstallCRX(path, INSTALL_NEW);
[email protected]fbcc40302009-06-12 20:45:452446
2447 // Try upgrading with a bad signature. This should fail during the unpack,
2448 // because the key will not match the signature.
[email protected]e85e34c32011-04-13 18:38:352449 path = data_dir_.AppendASCII("bad_signature.crx");
[email protected]8f512c72011-11-22 21:02:502450 InstallCRX(path, INSTALL_FAILED);
[email protected]fbcc40302009-06-12 20:45:452451}
2452
[email protected]e957fe52009-06-23 16:51:052453// Test a normal update via the UpdateExtension API
[email protected]d9a61e12012-11-14 02:43:472454TEST_F(ExtensionServiceTest, UpdateExtension) {
[email protected]eaa7dd182010-12-14 11:09:002455 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052456
[email protected]e85e34c32011-04-13 18:38:352457 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:052458
[email protected]8f512c72011-11-22 21:02:502459 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052460 ASSERT_EQ("1.0.0.0", good->VersionString());
2461 ASSERT_EQ(good_crx, good->id());
2462
[email protected]e85e34c32011-04-13 18:38:352463 path = data_dir_.AppendASCII("good2.crx");
[email protected]4416c5a2010-06-26 01:28:572464 UpdateExtension(good_crx, path, ENABLED);
[email protected]8f512c72011-11-22 21:02:502465 ASSERT_EQ("1.0.0.1",
2466 service_->GetExtensionById(good_crx, false)->
2467 version()->GetString());
[email protected]e957fe52009-06-23 16:51:052468}
2469
[email protected]3c4abc82012-10-22 22:25:542470// Extensions should not be updated during browser shutdown.
[email protected]d9a61e12012-11-14 02:43:472471TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
[email protected]3c4abc82012-10-22 22:25:542472 InitializeEmptyExtensionService();
2473
2474 // Install an extension.
2475 FilePath path = data_dir_.AppendASCII("good.crx");
2476 const Extension* good = InstallCRX(path, INSTALL_NEW);
2477 ASSERT_EQ(good_crx, good->id());
2478
2479 // Simulate shutdown.
2480 service_->set_browser_terminating_for_test(true);
2481
2482 // Update should fail and extension should not be updated.
2483 path = data_dir_.AppendASCII("good2.crx");
2484 bool updated = service_->UpdateExtension(good_crx, path, GURL(), NULL);
2485 ASSERT_FALSE(updated);
2486 ASSERT_EQ("1.0.0.0",
2487 service_->GetExtensionById(good_crx, false)->
2488 version()->GetString());
2489}
2490
[email protected]e957fe52009-06-23 16:51:052491// Test updating a not-already-installed extension - this should fail
[email protected]d9a61e12012-11-14 02:43:472492TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
[email protected]eaa7dd182010-12-14 11:09:002493 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052494
[email protected]e85e34c32011-04-13 18:38:352495 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572496 UpdateExtension(good_crx, path, UPDATED);
[email protected]b8f50ce2012-11-17 12:37:572497 loop_.RunUntilIdle();
[email protected]e957fe52009-06-23 16:51:052498
2499 ASSERT_EQ(0u, service_->extensions()->size());
2500 ASSERT_FALSE(installed_);
2501 ASSERT_EQ(0u, loaded_.size());
2502}
2503
2504// Makes sure you can't downgrade an extension via UpdateExtension
[email protected]d9a61e12012-11-14 02:43:472505TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
[email protected]eaa7dd182010-12-14 11:09:002506 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052507
[email protected]e85e34c32011-04-13 18:38:352508 FilePath path = data_dir_.AppendASCII("good2.crx");
[email protected]e957fe52009-06-23 16:51:052509
[email protected]8f512c72011-11-22 21:02:502510 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052511 ASSERT_EQ("1.0.0.1", good->VersionString());
2512 ASSERT_EQ(good_crx, good->id());
2513
2514 // Change path from good2.crx -> good.crx
[email protected]e85e34c32011-04-13 18:38:352515 path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572516 UpdateExtension(good_crx, path, FAILED);
[email protected]8f512c72011-11-22 21:02:502517 ASSERT_EQ("1.0.0.1",
2518 service_->GetExtensionById(good_crx, false)->
2519 version()->GetString());
[email protected]e957fe52009-06-23 16:51:052520}
2521
2522// Make sure calling update with an identical version does nothing
[email protected]d9a61e12012-11-14 02:43:472523TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
[email protected]eaa7dd182010-12-14 11:09:002524 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052525
[email protected]e85e34c32011-04-13 18:38:352526 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:052527
[email protected]8f512c72011-11-22 21:02:502528 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052529 ASSERT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:572530 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]aa142702010-03-26 01:26:332531}
2532
[email protected]dbec3792010-08-10 00:08:452533// Tests that updating an extension does not clobber old state.
[email protected]d9a61e12012-11-14 02:43:472534TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
[email protected]eaa7dd182010-12-14 11:09:002535 InitializeEmptyExtensionService();
[email protected]dbec3792010-08-10 00:08:452536
[email protected]e85e34c32011-04-13 18:38:352537 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]dbec3792010-08-10 00:08:452538
[email protected]8f512c72011-11-22 21:02:502539 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]dbec3792010-08-10 00:08:452540 ASSERT_EQ("1.0.0.0", good->VersionString());
2541 ASSERT_EQ(good_crx, good->id());
2542
2543 // Disable it and allow it to run in incognito. These settings should carry
2544 // over to the updated version.
[email protected]44d62b62012-04-11 00:06:032545 service_->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
[email protected]c3cfb012011-04-06 22:07:352546 service_->SetIsIncognitoEnabled(good->id(), true);
[email protected]c38fd352012-03-28 04:06:122547 service_->extension_prefs()->SetDidExtensionEscalatePermissions(good, true);
[email protected]dbec3792010-08-10 00:08:452548
[email protected]e85e34c32011-04-13 18:38:352549 path = data_dir_.AppendASCII("good2.crx");
[email protected]dbec3792010-08-10 00:08:452550 UpdateExtension(good_crx, path, INSTALLED);
[email protected]98270432012-09-11 20:51:242551 ASSERT_EQ(1u, service_->disabled_extensions()->size());\
[email protected]8f512c72011-11-22 21:02:502552 const Extension* good2 = service_->GetExtensionById(good_crx, true);
[email protected]dbec3792010-08-10 00:08:452553 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
[email protected]c3cfb012011-04-06 22:07:352554 EXPECT_TRUE(service_->IsIncognitoEnabled(good2->id()));
[email protected]c38fd352012-03-28 04:06:122555 EXPECT_TRUE(service_->extension_prefs()->DidExtensionEscalatePermissions(
2556 good2->id()));
[email protected]dbec3792010-08-10 00:08:452557}
2558
[email protected]5eb375e92010-11-26 07:50:412559// Tests that updating preserves extension location.
[email protected]d9a61e12012-11-14 02:43:472560TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
[email protected]eaa7dd182010-12-14 11:09:002561 InitializeEmptyExtensionService();
[email protected]5eb375e92010-11-26 07:50:412562
[email protected]e85e34c32011-04-13 18:38:352563 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]5eb375e92010-11-26 07:50:412564
[email protected]d41e2152012-02-24 04:20:272565 const Extension* good =
2566 InstallCRXWithLocation(path, Extension::EXTERNAL_PREF, INSTALL_NEW);
[email protected]5eb375e92010-11-26 07:50:412567
2568 ASSERT_EQ("1.0.0.0", good->VersionString());
2569 ASSERT_EQ(good_crx, good->id());
2570
[email protected]e85e34c32011-04-13 18:38:352571 path = data_dir_.AppendASCII("good2.crx");
[email protected]5eb375e92010-11-26 07:50:412572 UpdateExtension(good_crx, path, ENABLED);
[email protected]8f512c72011-11-22 21:02:502573 const Extension* good2 = service_->GetExtensionById(good_crx, false);
[email protected]5eb375e92010-11-26 07:50:412574 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2575 EXPECT_EQ(good2->location(), Extension::EXTERNAL_PREF);
2576}
2577
[email protected]66e26872010-12-03 20:07:252578// Makes sure that LOAD extension types can downgrade.
[email protected]d9a61e12012-11-14 02:43:472579TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
[email protected]eaa7dd182010-12-14 11:09:002580 InitializeEmptyExtensionService();
[email protected]66e26872010-12-03 20:07:252581
[email protected]ea1a3f62012-11-16 20:34:232582 base::ScopedTempDir temp;
[email protected]66e26872010-12-03 20:07:252583 ASSERT_TRUE(temp.CreateUniqueTempDir());
2584
2585 // We'll write the extension manifest dynamically to a temporary path
2586 // to make it easier to change the version number.
2587 FilePath extension_path = temp.path();
2588 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
2589 ASSERT_FALSE(file_util::PathExists(manifest_path));
2590
2591 // Start with version 2.0.
2592 DictionaryValue manifest;
2593 manifest.SetString("version", "2.0");
2594 manifest.SetString("name", "LOAD Downgrade Test");
[email protected]b3d52852011-12-07 01:01:112595 manifest.SetInteger("manifest_version", 2);
[email protected]66e26872010-12-03 20:07:252596
2597 JSONFileValueSerializer serializer(manifest_path);
2598 ASSERT_TRUE(serializer.Serialize(manifest));
2599
[email protected]d8c8f25f2011-11-02 18:18:012600 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
[email protected]b8f50ce2012-11-17 12:37:572601 loop_.RunUntilIdle();
[email protected]66e26872010-12-03 20:07:252602
2603 EXPECT_EQ(0u, GetErrors().size());
2604 ASSERT_EQ(1u, loaded_.size());
2605 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2606 EXPECT_EQ(1u, service_->extensions()->size());
2607 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2608
2609 // Now set the version number to 1.0, reload the extensions and verify that
2610 // the downgrade was accepted.
2611 manifest.SetString("version", "1.0");
2612 ASSERT_TRUE(serializer.Serialize(manifest));
2613
[email protected]d8c8f25f2011-11-02 18:18:012614 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
[email protected]b8f50ce2012-11-17 12:37:572615 loop_.RunUntilIdle();
[email protected]66e26872010-12-03 20:07:252616
2617 EXPECT_EQ(0u, GetErrors().size());
2618 ASSERT_EQ(1u, loaded_.size());
2619 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2620 EXPECT_EQ(1u, service_->extensions()->size());
2621 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2622}
2623
[email protected]0d904312012-01-25 23:00:162624#if !defined(OS_CHROMEOS)
2625// LOAD extensions with plugins require approval.
[email protected]d9a61e12012-11-14 02:43:472626TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
[email protected]0d904312012-01-25 23:00:162627 FilePath extension_with_plugin_path = data_dir_
2628 .AppendASCII("good")
2629 .AppendASCII("Extensions")
2630 .AppendASCII(good1)
2631 .AppendASCII("2");
2632 FilePath extension_no_plugin_path = data_dir_
2633 .AppendASCII("good")
2634 .AppendASCII("Extensions")
2635 .AppendASCII(good2)
2636 .AppendASCII("1.0");
2637
2638 PluginService::GetInstance()->Init();
2639 InitializeEmptyExtensionService();
2640 InitializeExtensionProcessManager();
2641 service_->set_show_extensions_prompts(true);
2642
2643 // Start by canceling any install prompts.
2644 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2645 switches::kAppsGalleryInstallAutoConfirmForTests,
2646 "cancel");
2647
2648 // The extension that has a plugin should not install.
2649 extensions::UnpackedInstaller::Create(service_)->Load(
2650 extension_with_plugin_path);
[email protected]b8f50ce2012-11-17 12:37:572651 loop_.RunUntilIdle();
[email protected]0d904312012-01-25 23:00:162652 EXPECT_EQ(0u, GetErrors().size());
2653 EXPECT_EQ(0u, loaded_.size());
2654 EXPECT_EQ(0u, service_->extensions()->size());
2655 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2656
2657 // But the extension with no plugin should since there's no prompt.
2658 extensions::UnpackedInstaller::Create(service_)->Load(
2659 extension_no_plugin_path);
[email protected]b8f50ce2012-11-17 12:37:572660 loop_.RunUntilIdle();
[email protected]0d904312012-01-25 23:00:162661 EXPECT_EQ(0u, GetErrors().size());
2662 EXPECT_EQ(1u, loaded_.size());
2663 EXPECT_EQ(1u, service_->extensions()->size());
2664 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2665 EXPECT_TRUE(service_->extensions()->Contains(good2));
2666
2667 // The plugin extension should install if we accept the dialog.
2668 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2669 switches::kAppsGalleryInstallAutoConfirmForTests,
2670 "accept");
2671
2672 extensions::UnpackedInstaller::Create(service_)->Load(
2673 extension_with_plugin_path);
[email protected]b8f50ce2012-11-17 12:37:572674 loop_.RunUntilIdle();
[email protected]0d904312012-01-25 23:00:162675 EXPECT_EQ(0u, GetErrors().size());
2676 EXPECT_EQ(2u, loaded_.size());
2677 EXPECT_EQ(2u, service_->extensions()->size());
2678 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2679 EXPECT_TRUE(service_->extensions()->Contains(good1));
2680 EXPECT_TRUE(service_->extensions()->Contains(good2));
2681
2682 // Make sure the granted permissions have been setup.
[email protected]c2e66e12012-06-27 06:27:062683 scoped_refptr<PermissionSet> permissions(
[email protected]0d904312012-01-25 23:00:162684 service_->extension_prefs()->GetGrantedPermissions(good1));
2685 EXPECT_FALSE(permissions->IsEmpty());
2686 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2687 EXPECT_FALSE(permissions->apis().empty());
[email protected]c2e66e12012-06-27 06:27:062688 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
[email protected]0d904312012-01-25 23:00:162689
2690 // We should be able to reload the extension without getting another prompt.
2691 loaded_.clear();
2692 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2693 switches::kAppsGalleryInstallAutoConfirmForTests,
2694 "cancel");
2695
2696 service_->ReloadExtension(good1);
[email protected]b8f50ce2012-11-17 12:37:572697 loop_.RunUntilIdle();
[email protected]0d904312012-01-25 23:00:162698 EXPECT_EQ(1u, loaded_.size());
2699 EXPECT_EQ(2u, service_->extensions()->size());
2700 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2701}
2702#endif
2703
[email protected]7fa19f82010-12-21 19:40:082704namespace {
2705
2706bool IsExtension(const Extension& extension) {
2707 return extension.GetType() == Extension::TYPE_EXTENSION;
2708}
2709
2710} // namespace
2711
[email protected]aa142702010-03-26 01:26:332712// Test adding a pending extension.
[email protected]d9a61e12012-11-14 02:43:472713TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
[email protected]eaa7dd182010-12-14 11:09:002714 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332715
[email protected]145a317b2011-04-12 16:03:462716 const std::string kFakeId(all_zero);
[email protected]aa142702010-03-26 01:26:332717 const GURL kFakeUpdateURL("http:://fake.update/url");
[email protected]aa142702010-03-26 01:26:332718 const bool kFakeInstallSilently(true);
2719
[email protected]f4d5e1a2011-04-28 02:08:252720 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082721 kFakeId, kFakeUpdateURL, &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332722 kFakeInstallSilently));
[email protected]b2907fd2011-03-25 16:43:372723
[email protected]3f213ad2012-07-26 23:39:412724 const extensions::PendingExtensionInfo* pending_extension_info;
[email protected]51a3bf8b2012-06-08 22:53:062725 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2726 GetById(kFakeId)));
2727 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2728 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2729 EXPECT_EQ(kFakeInstallSilently, pending_extension_info->install_silently());
[email protected]aa142702010-03-26 01:26:332730}
2731
[email protected]aa142702010-03-26 01:26:332732namespace {
2733const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2734const char kGoodUpdateURL[] = "http://good.update/url";
[email protected]8ef78fd2010-08-19 17:14:322735const bool kGoodIsFromSync = true;
[email protected]aa142702010-03-26 01:26:332736const bool kGoodInstallSilently = true;
[email protected]aa142702010-03-26 01:26:332737} // namespace
2738
2739// Test updating a pending extension.
[email protected]d9a61e12012-11-14 02:43:472740TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
[email protected]eaa7dd182010-12-14 11:09:002741 InitializeEmptyExtensionService();
[email protected]f4d5e1a2011-04-28 02:08:252742 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082743 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332744 kGoodInstallSilently));
[email protected]b2907fd2011-03-25 16:43:372745 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332746
[email protected]e85e34c32011-04-13 18:38:352747 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]6cc7dbae2011-04-29 21:18:332748 UpdateExtension(kGoodId, path, ENABLED);
[email protected]aa142702010-03-26 01:26:332749
[email protected]b2907fd2011-03-25 16:43:372750 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]4416c5a2010-06-26 01:28:572751
[email protected]9adb9692010-10-29 23:14:022752 const Extension* extension = service_->GetExtensionById(kGoodId, true);
[email protected]4416c5a2010-06-26 01:28:572753 ASSERT_TRUE(extension);
[email protected]aa142702010-03-26 01:26:332754}
2755
[email protected]7fa19f82010-12-21 19:40:082756namespace {
2757
2758bool IsTheme(const Extension& extension) {
2759 return extension.is_theme();
2760}
2761
2762} // namespace
2763
[email protected]11edd1e2010-07-21 00:14:502764// Test updating a pending theme.
[email protected]7f2c5552011-12-20 22:53:162765// Disabled due to ASAN failure. http://crbug.com/108320
[email protected]d9a61e12012-11-14 02:43:472766TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
[email protected]eaa7dd182010-12-14 11:09:002767 InitializeEmptyExtensionService();
[email protected]f4d5e1a2011-04-28 02:08:252768 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:332769 theme_crx, GURL(), &IsTheme, false));
[email protected]b2907fd2011-03-25 16:43:372770 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502771
[email protected]e85e34c32011-04-13 18:38:352772 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]11edd1e2010-07-21 00:14:502773 UpdateExtension(theme_crx, path, ENABLED);
2774
[email protected]b2907fd2011-03-25 16:43:372775 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502776
[email protected]9adb9692010-10-29 23:14:022777 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]11edd1e2010-07-21 00:14:502778 ASSERT_TRUE(extension);
2779
[email protected]ad83ca242011-07-29 01:32:252780 EXPECT_FALSE(
2781 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
[email protected]36429da2011-07-11 20:25:182782 EXPECT_TRUE(service_->IsExtensionEnabled(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502783}
2784
[email protected]d74f92e2011-04-18 15:39:232785#if defined(OS_CHROMEOS)
2786// Always fails on ChromeOS: http://crbug.com/79737
[email protected]e00ccc92012-11-01 17:32:302787#define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
[email protected]d74f92e2011-04-18 15:39:232788#else
2789#define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
2790#endif
[email protected]8ef78fd2010-08-19 17:14:322791// Test updating a pending CRX as if the source is an external extension
2792// with an update URL. In this case we don't know if the CRX is a theme
2793// or not.
[email protected]d9a61e12012-11-14 02:43:472794TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
[email protected]eaa7dd182010-12-14 11:09:002795 InitializeEmptyExtensionService();
[email protected]9060d8b02012-01-13 02:14:302796 EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2797 theme_crx, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD));
[email protected]8ef78fd2010-08-19 17:14:322798
[email protected]b2907fd2011-03-25 16:43:372799 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322800
[email protected]e85e34c32011-04-13 18:38:352801 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:322802 UpdateExtension(theme_crx, path, ENABLED);
2803
[email protected]b2907fd2011-03-25 16:43:372804 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322805
[email protected]9adb9692010-10-29 23:14:022806 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]8ef78fd2010-08-19 17:14:322807 ASSERT_TRUE(extension);
2808
[email protected]ad83ca242011-07-29 01:32:252809 EXPECT_FALSE(
2810 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
[email protected]36429da2011-07-11 20:25:182811 EXPECT_TRUE(service_->IsExtensionEnabled(extension->id()));
[email protected]c3cfb012011-04-06 22:07:352812 EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
[email protected]8ef78fd2010-08-19 17:14:322813}
2814
[email protected]1afaf2a52010-11-02 19:29:172815// Test updating a pending CRX as if the source is an external extension
2816// with an update URL. The external update should overwrite a sync update,
2817// but a sync update should not overwrite a non-sync update.
[email protected]d9a61e12012-11-14 02:43:472818TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
[email protected]eaa7dd182010-12-14 11:09:002819 InitializeEmptyExtensionService();
[email protected]1afaf2a52010-11-02 19:29:172820
2821 // Add a crx to be installed from the update mechanism.
[email protected]f4d5e1a2011-04-28 02:08:252822 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082823 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332824 kGoodInstallSilently));
[email protected]1afaf2a52010-11-02 19:29:172825
2826 // Check that there is a pending crx, with is_from_sync set to true.
[email protected]3f213ad2012-07-26 23:39:412827 const extensions::PendingExtensionInfo* pending_extension_info;
[email protected]51a3bf8b2012-06-08 22:53:062828 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2829 GetById(kGoodId)));
2830 EXPECT_TRUE(pending_extension_info->is_from_sync());
[email protected]1afaf2a52010-11-02 19:29:172831
2832 // Add a crx to be updated, with the same ID, from a non-sync source.
[email protected]9060d8b02012-01-13 02:14:302833 EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2834 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD));
[email protected]1afaf2a52010-11-02 19:29:172835
2836 // Check that there is a pending crx, with is_from_sync set to false.
[email protected]51a3bf8b2012-06-08 22:53:062837 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2838 GetById(kGoodId)));
2839 EXPECT_FALSE(pending_extension_info->is_from_sync());
[email protected]b2907fd2011-03-25 16:43:372840 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
[email protected]51a3bf8b2012-06-08 22:53:062841 pending_extension_info->install_source());
[email protected]1afaf2a52010-11-02 19:29:172842
2843 // Add a crx to be installed from the update mechanism.
[email protected]f4d5e1a2011-04-28 02:08:252844 EXPECT_FALSE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082845 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332846 kGoodInstallSilently));
[email protected]1afaf2a52010-11-02 19:29:172847
2848 // Check that the external, non-sync update was not overridden.
[email protected]51a3bf8b2012-06-08 22:53:062849 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2850 GetById(kGoodId)));
2851 EXPECT_FALSE(pending_extension_info->is_from_sync());
[email protected]b2907fd2011-03-25 16:43:372852 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
[email protected]51a3bf8b2012-06-08 22:53:062853 pending_extension_info->install_source());
[email protected]1afaf2a52010-11-02 19:29:172854}
2855
[email protected]8ef78fd2010-08-19 17:14:322856// Updating a theme should fail if the updater is explicitly told that
2857// the CRX is not a theme.
[email protected]d9a61e12012-11-14 02:43:472858TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
[email protected]eaa7dd182010-12-14 11:09:002859 InitializeEmptyExtensionService();
[email protected]f4d5e1a2011-04-28 02:08:252860 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:332861 theme_crx, GURL(), &IsExtension, true));
[email protected]8ef78fd2010-08-19 17:14:322862
[email protected]b2907fd2011-03-25 16:43:372863 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322864
[email protected]e85e34c32011-04-13 18:38:352865 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:322866 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
2867
[email protected]b2907fd2011-03-25 16:43:372868 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322869
[email protected]9adb9692010-10-29 23:14:022870 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]8ef78fd2010-08-19 17:14:322871 ASSERT_FALSE(extension);
2872}
2873
[email protected]aa142702010-03-26 01:26:332874// TODO(akalin): Test updating a pending extension non-silently once
2875// we can mock out ExtensionInstallUI and inject our version into
2876// UpdateExtension().
2877
[email protected]7fa19f82010-12-21 19:40:082878// Test updating a pending extension which fails the should-install test.
[email protected]d9a61e12012-11-14 02:43:472879TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
[email protected]eaa7dd182010-12-14 11:09:002880 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332881 // Add pending extension with a flipped is_theme.
[email protected]f4d5e1a2011-04-28 02:08:252882 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:332883 kGoodId, GURL(kGoodUpdateURL), &IsTheme, kGoodInstallSilently));
[email protected]b2907fd2011-03-25 16:43:372884 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332885
[email protected]e85e34c32011-04-13 18:38:352886 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572887 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:332888
2889 // TODO(akalin): Figure out how to check that the extensions
2890 // directory is cleaned up properly in OnExtensionInstalled().
2891
[email protected]b2907fd2011-03-25 16:43:372892 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332893}
2894
[email protected]11edd1e2010-07-21 00:14:502895// TODO(akalin): Figure out how to test that installs of pending
2896// unsyncable extensions are blocked.
2897
[email protected]aa142702010-03-26 01:26:332898// Test updating a pending extension for one that is not pending.
[email protected]d9a61e12012-11-14 02:43:472899TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
[email protected]eaa7dd182010-12-14 11:09:002900 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332901
[email protected]e85e34c32011-04-13 18:38:352902 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572903 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:332904
[email protected]b2907fd2011-03-25 16:43:372905 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332906}
2907
2908// Test updating a pending extension for one that is already
2909// installed.
[email protected]d9a61e12012-11-14 02:43:472910TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
[email protected]eaa7dd182010-12-14 11:09:002911 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332912
[email protected]e85e34c32011-04-13 18:38:352913 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502914 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]aa142702010-03-26 01:26:332915 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]aa142702010-03-26 01:26:332916
[email protected]8ef78fd2010-08-19 17:14:322917 EXPECT_FALSE(good->is_theme());
2918
[email protected]b2907fd2011-03-25 16:43:372919 // Use AddExtensionImpl() as AddFrom*() would balk.
2920 service_->pending_extension_manager()->AddExtensionImpl(
[email protected]e3987852012-05-04 10:06:302921 good->id(), good->update_url(), Version(), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332922 kGoodIsFromSync, kGoodInstallSilently, Extension::INTERNAL);
2923 UpdateExtension(good->id(), path, ENABLED);
[email protected]aa142702010-03-26 01:26:332924
[email protected]b2907fd2011-03-25 16:43:372925 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]e957fe52009-06-23 16:51:052926}
2927
[email protected]6b75ec32009-08-14 06:37:182928// Test pref settings for blacklist and unblacklist extensions.
[email protected]d9a61e12012-11-14 02:43:472929TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
[email protected]eaa7dd182010-12-14 11:09:002930 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182931 std::vector<std::string> blacklist;
2932 blacklist.push_back(good0);
2933 blacklist.push_back("invalid_id"); // an invalid id
2934 blacklist.push_back(good1);
[email protected]fdd679b2012-11-15 20:49:392935 ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist,
2936 "v1");
2937
[email protected]6b75ec32009-08-14 06:37:182938 // Make sure pref is updated
[email protected]b8f50ce2012-11-17 12:37:572939 loop_.RunUntilIdle();
[email protected]6b75ec32009-08-14 06:37:182940
2941 // blacklist is set for good0,1,2
[email protected]e2194742010-08-12 05:54:342942 ValidateBooleanPref(good0, "blacklist", true);
2943 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182944 // invalid_id should not be inserted to pref.
[email protected]e2194742010-08-12 05:54:342945 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182946
2947 // remove good1, add good2
2948 blacklist.pop_back();
2949 blacklist.push_back(good2);
[email protected]fdd679b2012-11-15 20:49:392950 ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist,
2951 "v2");
[email protected]6b75ec32009-08-14 06:37:182952
[email protected]6b75ec32009-08-14 06:37:182953 // only good0 and good1 should be set
[email protected]e2194742010-08-12 05:54:342954 ValidateBooleanPref(good0, "blacklist", true);
2955 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
2956 ValidateBooleanPref(good2, "blacklist", true);
2957 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182958}
2959
2960// Unload installed extension from blacklist.
[email protected]d9a61e12012-11-14 02:43:472961TEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) {
[email protected]eaa7dd182010-12-14 11:09:002962 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182963
[email protected]e85e34c32011-04-13 18:38:352964 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]6b75ec32009-08-14 06:37:182965
[email protected]8f512c72011-11-22 21:02:502966 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]6b75ec32009-08-14 06:37:182967 EXPECT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:572968 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]6b75ec32009-08-14 06:37:182969
2970 std::vector<std::string> blacklist;
2971 blacklist.push_back(good_crx);
[email protected]fdd679b2012-11-15 20:49:392972 ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist,
2973 "v1");
2974
[email protected]6b75ec32009-08-14 06:37:182975 // Make sure pref is updated
[email protected]b8f50ce2012-11-17 12:37:572976 loop_.RunUntilIdle();
[email protected]6b75ec32009-08-14 06:37:182977
2978 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:342979 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182980 EXPECT_EQ(0u, service_->extensions()->size());
2981
2982 // Remove good_crx from blacklist
2983 blacklist.pop_back();
[email protected]fdd679b2012-11-15 20:49:392984 ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist,
2985 "v2");
2986
[email protected]6b75ec32009-08-14 06:37:182987 // Make sure pref is updated
[email protected]b8f50ce2012-11-17 12:37:572988 loop_.RunUntilIdle();
[email protected]6b75ec32009-08-14 06:37:182989 // blacklist value should not be set for good_crx
[email protected]e2194742010-08-12 05:54:342990 EXPECT_FALSE(IsPrefExist(good_crx, "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182991}
2992
2993// Unload installed extension from blacklist.
[email protected]d9a61e12012-11-14 02:43:472994TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
[email protected]eaa7dd182010-12-14 11:09:002995 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182996 std::vector<std::string> blacklist;
2997 blacklist.push_back(good_crx);
[email protected]fdd679b2012-11-15 20:49:392998 ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist,
2999 "v1");
3000
[email protected]6b75ec32009-08-14 06:37:183001 // Make sure pref is updated
[email protected]b8f50ce2012-11-17 12:37:573002 loop_.RunUntilIdle();
[email protected]6b75ec32009-08-14 06:37:183003
3004 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:343005 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:183006
3007 // We can not install good_crx.
[email protected]e85e34c32011-04-13 18:38:353008 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]695b5712012-12-06 23:55:283009 InstallCRX(path, INSTALL_WITHOUT_LOAD);
[email protected]6b75ec32009-08-14 06:37:183010 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]e2194742010-08-12 05:54:343011 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:183012}
3013
[email protected]4ee07c62012-08-21 12:40:423014// Unload blacklisted extension on policy change.
[email protected]d9a61e12012-11-14 02:43:473015TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
[email protected]4ee07c62012-08-21 12:40:423016 InitializeEmptyExtensionService();
3017 FilePath path = data_dir_.AppendASCII("good.crx");
3018
3019 const Extension* good = InstallCRX(path, INSTALL_NEW);
3020 EXPECT_EQ(good_crx, good->id());
3021 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3022 EXPECT_EQ(1u, service_->extensions()->size());
3023
3024 base::ListValue whitelist;
3025 PrefService* prefs = service_->extension_prefs()->pref_service();
3026 whitelist.Append(base::Value::CreateStringValue(good_crx));
3027 prefs->Set(prefs::kExtensionInstallAllowList, whitelist);
3028
3029 std::vector<std::string> blacklist;
3030 blacklist.push_back(good_crx);
[email protected]fdd679b2012-11-15 20:49:393031 ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist,
3032 "v1");
3033
[email protected]4ee07c62012-08-21 12:40:423034 // Make sure pref is updated
[email protected]695b5712012-12-06 23:55:283035 loop_.RunUntilIdle();
[email protected]4ee07c62012-08-21 12:40:423036
[email protected]695b5712012-12-06 23:55:283037 // The good_crx is blacklisted and the whitelist doesn't negate it.
[email protected]4ee07c62012-08-21 12:40:423038 ValidateBooleanPref(good_crx, "blacklist", true);
3039 EXPECT_EQ(0u, service_->extensions()->size());
3040}
3041
[email protected]6b75ec32009-08-14 06:37:183042// Test loading extensions from the profile directory, except
3043// blacklisted ones.
[email protected]d9a61e12012-11-14 02:43:473044TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
[email protected]6b75ec32009-08-14 06:37:183045 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:353046 FilePath source_install_dir = data_dir_
[email protected]6b75ec32009-08-14 06:37:183047 .AppendASCII("good")
3048 .AppendASCII("Extensions");
3049 FilePath pref_path = source_install_dir
3050 .DirName()
3051 .AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:003052 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]6b75ec32009-08-14 06:37:183053
[email protected]e50013c32010-08-18 21:05:243054 // Blacklist good1.
[email protected]6b75ec32009-08-14 06:37:183055 std::vector<std::string> blacklist;
[email protected]e50013c32010-08-18 21:05:243056 blacklist.push_back(good1);
[email protected]fdd679b2012-11-15 20:49:393057 ExtensionSystem::Get(profile_.get())->blacklist()->SetFromUpdater(blacklist,
3058 "v1");
3059
[email protected]6b75ec32009-08-14 06:37:183060 // Make sure pref is updated
[email protected]b8f50ce2012-11-17 12:37:573061 loop_.RunUntilIdle();
[email protected]6b75ec32009-08-14 06:37:183062
[email protected]e50013c32010-08-18 21:05:243063 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:183064
3065 // Load extensions.
3066 service_->Init();
[email protected]6b75ec32009-08-14 06:37:183067
[email protected]fc670822011-12-17 09:33:493068 std::vector<string16> errors = GetErrors();
3069 for (std::vector<string16>::iterator err = errors.begin();
[email protected]6b75ec32009-08-14 06:37:183070 err != errors.end(); ++err) {
3071 LOG(ERROR) << *err;
3072 }
[email protected]d7b36dc2009-10-29 21:47:403073 ASSERT_EQ(2u, loaded_.size());
[email protected]6b75ec32009-08-14 06:37:183074
[email protected]695b5712012-12-06 23:55:283075 EXPECT_TRUE(service_->GetInstalledExtension(good1));
3076 int include_mask = ExtensionService::INCLUDE_EVERYTHING &
3077 ~ExtensionService::INCLUDE_BLACKLISTED;
3078 EXPECT_FALSE(service_->GetExtensionById(good1, include_mask));
[email protected]6b75ec32009-08-14 06:37:183079}
3080
[email protected]306a2bd2010-08-11 14:56:363081// Will not install extension blacklisted by policy.
[email protected]d9a61e12012-11-14 02:43:473082TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
[email protected]eaa7dd182010-12-14 11:09:003083 InitializeEmptyExtensionService();
[email protected]306a2bd2010-08-11 14:56:363084
[email protected]306a2bd2010-08-11 14:56:363085 // Blacklist everything.
[email protected]43d3bf82011-04-11 07:46:583086 {
3087 ListPrefUpdate update(profile_->GetPrefs(),
3088 prefs::kExtensionInstallDenyList);
3089 ListValue* blacklist = update.Get();
3090 blacklist->Append(Value::CreateStringValue("*"));
3091 }
[email protected]306a2bd2010-08-11 14:56:363092
3093 // Blacklist prevents us from installing good_crx.
[email protected]e85e34c32011-04-13 18:38:353094 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503095 InstallCRX(path, INSTALL_FAILED);
[email protected]306a2bd2010-08-11 14:56:363096 EXPECT_EQ(0u, service_->extensions()->size());
3097
3098 // Now whitelist this particular extension.
[email protected]43d3bf82011-04-11 07:46:583099 {
3100 ListPrefUpdate update(profile_->GetPrefs(),
3101 prefs::kExtensionInstallAllowList);
3102 ListValue* whitelist = update.Get();
3103 whitelist->Append(Value::CreateStringValue(good_crx));
3104 }
3105
[email protected]306a2bd2010-08-11 14:56:363106 // Ensure we can now install good_crx.
[email protected]8f512c72011-11-22 21:02:503107 InstallCRX(path, INSTALL_NEW);
[email protected]306a2bd2010-08-11 14:56:363108 EXPECT_EQ(1u, service_->extensions()->size());
3109}
3110
[email protected]aa96d3a2010-08-21 08:45:253111// Extension blacklisted by policy get unloaded after installing.
[email protected]d9a61e12012-11-14 02:43:473112TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
[email protected]eaa7dd182010-12-14 11:09:003113 InitializeEmptyExtensionService();
[email protected]aa96d3a2010-08-21 08:45:253114
3115 // Install good_crx.
[email protected]e85e34c32011-04-13 18:38:353116 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503117 InstallCRX(path, INSTALL_NEW);
[email protected]aa96d3a2010-08-21 08:45:253118 EXPECT_EQ(1u, service_->extensions()->size());
3119
[email protected]acd78969c2010-12-08 09:49:113120 { // Scope for pref update notification.
3121 PrefService* prefs = profile_->GetPrefs();
[email protected]43d3bf82011-04-11 07:46:583122 ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList);
3123 ListValue* blacklist = update.Get();
[email protected]acd78969c2010-12-08 09:49:113124 ASSERT_TRUE(blacklist != NULL);
[email protected]aa96d3a2010-08-21 08:45:253125
[email protected]acd78969c2010-12-08 09:49:113126 // Blacklist this extension.
3127 blacklist->Append(Value::CreateStringValue(good_crx));
[email protected]acd78969c2010-12-08 09:49:113128 }
[email protected]aa96d3a2010-08-21 08:45:253129
3130 // Extension should not be running now.
[email protected]b8f50ce2012-11-17 12:37:573131 loop_.RunUntilIdle();
[email protected]aa96d3a2010-08-21 08:45:253132 EXPECT_EQ(0u, service_->extensions()->size());
3133}
3134
[email protected]05aad2da2011-10-28 10:12:373135// Tests that component extensions are not blacklisted by policy.
[email protected]d9a61e12012-11-14 02:43:473136TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
[email protected]05aad2da2011-10-28 10:12:373137 InitializeEmptyExtensionService();
3138
3139 // Blacklist everything.
3140 {
3141 ListPrefUpdate update(profile_->GetPrefs(),
3142 prefs::kExtensionInstallDenyList);
3143 ListValue* blacklist = update.Get();
3144 blacklist->Append(Value::CreateStringValue("*"));
3145 }
3146
3147 // Install a component extension.
3148 FilePath path = data_dir_
3149 .AppendASCII("good")
3150 .AppendASCII("Extensions")
3151 .AppendASCII(good0)
3152 .AppendASCII("1.0.0.0");
3153 std::string manifest;
3154 ASSERT_TRUE(file_util::ReadFileToString(
3155 path.Append(Extension::kManifestFilename), &manifest));
[email protected]d8c8f25f2011-11-02 18:18:013156 service_->component_loader()->Add(manifest, path);
[email protected]05aad2da2011-10-28 10:12:373157 service_->Init();
3158
3159 // Extension should be installed despite blacklist.
3160 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503161 EXPECT_TRUE(service_->GetExtensionById(good0, false));
[email protected]05aad2da2011-10-28 10:12:373162
3163 // Poke external providers and make sure the extension is still present.
3164 service_->CheckForExternalUpdates();
3165 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503166 EXPECT_TRUE(service_->GetExtensionById(good0, false));
[email protected]05aad2da2011-10-28 10:12:373167
3168 // Extension should not be uninstalled on blacklist changes.
3169 {
3170 ListPrefUpdate update(profile_->GetPrefs(),
3171 prefs::kExtensionInstallDenyList);
3172 ListValue* blacklist = update.Get();
3173 blacklist->Append(Value::CreateStringValue(good0));
3174 }
[email protected]b8f50ce2012-11-17 12:37:573175 loop_.RunUntilIdle();
[email protected]05aad2da2011-10-28 10:12:373176 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503177 EXPECT_TRUE(service_->GetExtensionById(good0, false));
[email protected]05aad2da2011-10-28 10:12:373178}
3179
3180// Tests that policy-installed extensions are not blacklisted by policy.
[email protected]d9a61e12012-11-14 02:43:473181TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
[email protected]05aad2da2011-10-28 10:12:373182 InitializeEmptyExtensionService();
3183
[email protected]05aad2da2011-10-28 10:12:373184 {
[email protected]e410b5f2012-12-14 14:02:243185 // Blacklist everything.
3186 ListPrefUpdate blacklist_update(profile_->GetPrefs(),
3187 prefs::kExtensionInstallDenyList);
3188 ListValue* blacklist = blacklist_update.Get();
3189 blacklist->AppendString("*");
3190
3191 // Mark good.crx for force-installation.
3192 DictionaryPrefUpdate forcelist_update(profile_->GetPrefs(),
3193 prefs::kExtensionInstallForceList);
3194 extensions::ExternalPolicyLoader::AddExtension(
3195 forcelist_update.Get(), good_crx, "http://example.com/update_url");
[email protected]05aad2da2011-10-28 10:12:373196 }
3197
3198 // Have policy force-install an extension.
3199 MockExtensionProvider* provider =
3200 new MockExtensionProvider(service_,
3201 Extension::EXTERNAL_POLICY_DOWNLOAD);
3202 AddMockExternalProvider(provider);
3203 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3204 data_dir_.AppendASCII("good.crx"));
3205
3206 // Reloading extensions should find our externally registered extension
3207 // and install it.
3208 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:573209 loop_.RunUntilIdle();
[email protected]05aad2da2011-10-28 10:12:373210
3211 // Extension should be installed despite blacklist.
3212 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503213 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]05aad2da2011-10-28 10:12:373214
3215 // Blacklist update should not uninstall the extension.
3216 {
3217 ListPrefUpdate update(profile_->GetPrefs(),
3218 prefs::kExtensionInstallDenyList);
3219 ListValue* blacklist = update.Get();
3220 blacklist->Append(Value::CreateStringValue(good0));
3221 }
[email protected]b8f50ce2012-11-17 12:37:573222 loop_.RunUntilIdle();
[email protected]05aad2da2011-10-28 10:12:373223 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503224 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]05aad2da2011-10-28 10:12:373225}
3226
[email protected]65187152012-06-02 13:14:143227// Tests that extensions cannot be installed if the policy provider prohibits
3228// it. This functionality is implemented in CrxInstaller::ConfirmInstall().
[email protected]d9a61e12012-11-14 02:43:473229TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
[email protected]65187152012-06-02 13:14:143230 InitializeEmptyExtensionService();
3231
3232 management_policy_->UnregisterAllProviders();
3233 extensions::TestManagementPolicyProvider provider_(
3234 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3235 management_policy_->RegisterProvider(&provider_);
3236
3237 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_FAILED);
3238 EXPECT_EQ(0u, service_->extensions()->size());
3239}
3240
3241// Tests that extensions cannot be loaded from prefs if the policy provider
3242// prohibits it. This functionality is implemented in InstalledLoader::Load().
[email protected]d9a61e12012-11-14 02:43:473243TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
[email protected]65187152012-06-02 13:14:143244 InitializeEmptyExtensionService();
3245
3246 // Create a fake extension to be loaded as though it were read from prefs.
3247 FilePath path = data_dir_.AppendASCII("management")
3248 .AppendASCII("simple_extension");
3249 DictionaryValue manifest;
3250 manifest.SetString(keys::kName, "simple_extension");
3251 manifest.SetString(keys::kVersion, "1");
3252 // LOAD is for extensions loaded from the command line. We use it here, even
3253 // though we're testing loading from prefs, so that we don't need to provide
3254 // an extension key.
3255 extensions::ExtensionInfo extension_info(&manifest, "", path,
3256 Extension::LOAD);
3257
3258 // Ensure we can load it with no management policy in place.
3259 management_policy_->UnregisterAllProviders();
3260 EXPECT_EQ(0u, service_->extensions()->size());
3261 extensions::InstalledLoader(service_).Load(extension_info, false);
3262 EXPECT_EQ(1u, service_->extensions()->size());
3263
3264 const Extension* extension = *(service_->extensions()->begin());
3265 EXPECT_TRUE(service_->UninstallExtension(extension->id(), false, NULL));
3266 EXPECT_EQ(0u, service_->extensions()->size());
3267
3268 // Ensure we cannot load it if management policy prohibits installation.
3269 extensions::TestManagementPolicyProvider provider_(
3270 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3271 management_policy_->RegisterProvider(&provider_);
3272
3273 extensions::InstalledLoader(service_).Load(extension_info, false);
3274 EXPECT_EQ(0u, service_->extensions()->size());
3275}
3276
3277// Tests disabling an extension when prohibited by the ManagementPolicy.
[email protected]d9a61e12012-11-14 02:43:473278TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
[email protected]65187152012-06-02 13:14:143279 InitializeEmptyExtensionService();
3280
3281 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3282 EXPECT_EQ(1u, service_->extensions()->size());
3283 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3284
3285 management_policy_->UnregisterAllProviders();
3286 extensions::TestManagementPolicyProvider provider(
3287 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3288 management_policy_->RegisterProvider(&provider);
3289
3290 // Attempt to disable it.
3291 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3292
3293 EXPECT_EQ(1u, service_->extensions()->size());
3294 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3295 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3296}
3297
3298// Tests uninstalling an extension when prohibited by the ManagementPolicy.
[email protected]d9a61e12012-11-14 02:43:473299TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
[email protected]65187152012-06-02 13:14:143300 InitializeEmptyExtensionService();
3301
3302 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3303 EXPECT_EQ(1u, service_->extensions()->size());
3304 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3305
3306 management_policy_->UnregisterAllProviders();
3307 extensions::TestManagementPolicyProvider provider(
3308 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3309 management_policy_->RegisterProvider(&provider);
3310
3311 // Attempt to uninstall it.
3312 EXPECT_FALSE(service_->UninstallExtension(good_crx, false, NULL));
3313
3314 EXPECT_EQ(1u, service_->extensions()->size());
3315 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3316}
3317
3318// Tests that previously installed extensions that are now prohibited from
3319// being installed are removed.
[email protected]d9a61e12012-11-14 02:43:473320TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
[email protected]65187152012-06-02 13:14:143321 InitializeEmptyExtensionService();
3322
3323 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3324 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
3325 EXPECT_EQ(2u, service_->extensions()->size());
3326 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3327
3328 management_policy_->UnregisterAllProviders();
3329 extensions::TestManagementPolicyProvider provider(
3330 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3331 management_policy_->RegisterProvider(&provider);
3332
3333 // Run the policy check.
[email protected]4ee07c62012-08-21 12:40:423334 service_->CheckManagementPolicy();
[email protected]65187152012-06-02 13:14:143335 EXPECT_EQ(0u, service_->extensions()->size());
3336 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3337}
3338
3339// Tests that previously disabled extensions that are now required to be
3340// enabled are re-enabled on reinstall.
[email protected]d9a61e12012-11-14 02:43:473341TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
[email protected]65187152012-06-02 13:14:143342 InitializeEmptyExtensionService();
3343
3344 // Install, then disable, an extension.
3345 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3346 EXPECT_EQ(1u, service_->extensions()->size());
3347 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3348 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3349
3350 // Register an ExtensionMnagementPolicy that requires the extension to remain
3351 // enabled.
3352 management_policy_->UnregisterAllProviders();
3353 extensions::TestManagementPolicyProvider provider(
3354 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
3355 management_policy_->RegisterProvider(&provider);
3356
3357 // Reinstall the extension.
3358 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_UPDATED);
3359 EXPECT_EQ(1u, service_->extensions()->size());
3360 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3361}
3362
[email protected]d9a61e12012-11-14 02:43:473363TEST_F(ExtensionServiceTest, ExternalExtensionAutoAcknowledgement) {
[email protected]a39921b42012-02-28 03:42:543364 InitializeEmptyExtensionService();
3365 set_extensions_enabled(true);
3366
3367 {
3368 // Register and install an external extension.
3369 MockExtensionProvider* provider =
[email protected]f121003b2012-05-04 21:57:473370 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]a39921b42012-02-28 03:42:543371 AddMockExternalProvider(provider);
3372 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3373 data_dir_.AppendASCII("good.crx"));
3374 }
3375 {
3376 // Have policy force-install an extension.
3377 MockExtensionProvider* provider =
3378 new MockExtensionProvider(service_,
3379 Extension::EXTERNAL_POLICY_DOWNLOAD);
3380 AddMockExternalProvider(provider);
3381 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
3382 data_dir_.AppendASCII("page_action.crx"));
3383 }
3384
3385 // Providers are set up. Let them run.
3386 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:573387 loop_.RunUntilIdle();
[email protected]a39921b42012-02-28 03:42:543388
3389 ASSERT_EQ(2u, service_->extensions()->size());
3390 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3391 EXPECT_TRUE(service_->GetExtensionById(page_action, false));
3392 ExtensionPrefs* prefs = service_->extension_prefs();
3393 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
3394 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
3395}
3396
[email protected]a7cd28e2012-10-05 21:03:363397#if !defined(OS_CHROMEOS)
3398// This tests if default apps are installed correctly.
[email protected]d9a61e12012-11-14 02:43:473399TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
[email protected]a7cd28e2012-10-05 21:03:363400 InitializeEmptyExtensionService();
3401 InitializeRequestContext();
3402 set_extensions_enabled(true);
3403
3404 {
3405 std::string json_data =
3406 "{"
3407 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
3408 " \"external_crx\": \"good.crx\","
3409 " \"external_version\": \"1.0.0.0\","
3410 " \"is_bookmark_app\": false"
3411 " }"
3412 "}";
3413 default_apps::Provider* provider =
3414 new default_apps::Provider(
3415 profile_.get(),
3416 service_,
3417 new extensions::ExternalTestingLoader(json_data, data_dir_),
3418 Extension::INTERNAL,
3419 Extension::INVALID,
3420 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
3421
3422 AddMockExternalProvider(provider);
3423 }
3424
3425 ASSERT_EQ(0u, service_->extensions()->size());
3426 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:573427 loop_.RunUntilIdle();
[email protected]a7cd28e2012-10-05 21:03:363428
3429 ASSERT_EQ(1u, service_->extensions()->size());
3430 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3431 const Extension* extension = service_->GetExtensionById(good_crx, false);
3432 EXPECT_TRUE(extension->from_webstore());
3433 EXPECT_TRUE(extension->was_installed_by_default());
3434
3435}
3436#endif
3437
[email protected]cd500f72010-06-25 23:44:323438// Tests disabling extensions
[email protected]d9a61e12012-11-14 02:43:473439TEST_F(ExtensionServiceTest, DisableExtension) {
[email protected]eaa7dd182010-12-14 11:09:003440 InitializeEmptyExtensionService();
[email protected]cd500f72010-06-25 23:44:323441
[email protected]8f512c72011-11-22 21:02:503442 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]84df8332011-12-06 18:22:463443 EXPECT_FALSE(service_->extensions()->is_empty());
[email protected]8f512c72011-11-22 21:02:503444 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3445 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]84df8332011-12-06 18:22:463446 EXPECT_TRUE(service_->disabled_extensions()->is_empty());
[email protected]cd500f72010-06-25 23:44:323447
3448 // Disable it.
[email protected]44d62b62012-04-11 00:06:033449 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
[email protected]cd500f72010-06-25 23:44:323450
[email protected]84df8332011-12-06 18:22:463451 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]8f512c72011-11-22 21:02:503452 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3453 EXPECT_FALSE(service_->GetExtensionById(good_crx, false));
[email protected]84df8332011-12-06 18:22:463454 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
[email protected]fa2416f2011-05-03 08:41:203455}
3456
[email protected]d9a61e12012-11-14 02:43:473457TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
[email protected]fa2416f2011-05-03 08:41:203458 InitializeEmptyExtensionService();
3459
[email protected]8f512c72011-11-22 21:02:503460 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203461 TerminateExtension(good_crx);
3462 EXPECT_TRUE(service_->GetTerminatedExtension(good_crx));
3463
3464 // Disable it.
[email protected]44d62b62012-04-11 00:06:033465 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
[email protected]fa2416f2011-05-03 08:41:203466
3467 EXPECT_FALSE(service_->GetTerminatedExtension(good_crx));
[email protected]8f512c72011-11-22 21:02:503468 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
[email protected]84df8332011-12-06 18:22:463469 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
[email protected]cd500f72010-06-25 23:44:323470}
3471
[email protected]d728e002010-12-08 04:46:233472// Tests disabling all extensions (simulating --disable-extensions flag).
[email protected]d9a61e12012-11-14 02:43:473473TEST_F(ExtensionServiceTest, DisableAllExtensions) {
[email protected]eaa7dd182010-12-14 11:09:003474 InitializeEmptyExtensionService();
[email protected]d728e002010-12-08 04:46:233475
[email protected]e85e34c32011-04-13 18:38:353476 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503477 InstallCRX(path, INSTALL_NEW);
[email protected]d728e002010-12-08 04:46:233478
3479 EXPECT_EQ(1u, service_->extensions()->size());
3480 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3481
3482 // Disable extensions.
3483 service_->set_extensions_enabled(false);
3484 service_->ReloadExtensions();
3485
3486 // There shouldn't be extensions in either list.
3487 EXPECT_EQ(0u, service_->extensions()->size());
3488 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3489
3490 // This shouldn't do anything when all extensions are disabled.
3491 service_->EnableExtension(good_crx);
3492 service_->ReloadExtensions();
3493
3494 // There still shouldn't be extensions in either list.
3495 EXPECT_EQ(0u, service_->extensions()->size());
3496 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3497
3498 // And then re-enable the extensions.
3499 service_->set_extensions_enabled(true);
3500 service_->ReloadExtensions();
3501
3502 EXPECT_EQ(1u, service_->extensions()->size());
3503 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3504}
3505
[email protected]8f512c72011-11-22 21:02:503506// Tests reloading extensions.
[email protected]d9a61e12012-11-14 02:43:473507TEST_F(ExtensionServiceTest, ReloadExtensions) {
[email protected]eaa7dd182010-12-14 11:09:003508 InitializeEmptyExtensionService();
[email protected]26367b62012-10-04 23:03:323509 InitializeRequestContext();
[email protected]cd500f72010-06-25 23:44:323510
3511 // Simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:353512 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]26367b62012-10-04 23:03:323513 InstallCRX(path, INSTALL_NEW,
3514 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
[email protected]cd500f72010-06-25 23:44:323515 const char* extension_id = good_crx;
[email protected]44d62b62012-04-11 00:06:033516 service_->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
[email protected]cd500f72010-06-25 23:44:323517
3518 EXPECT_EQ(0u, service_->extensions()->size());
3519 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3520
3521 service_->ReloadExtensions();
3522
[email protected]26367b62012-10-04 23:03:323523 // The creation flags should not change when reloading the extension.
3524 const Extension* extension = service_->GetExtensionById(good_crx, true);
3525 EXPECT_TRUE(extension->from_webstore());
3526 EXPECT_TRUE(extension->was_installed_by_default());
3527 EXPECT_FALSE(extension->from_bookmark());
3528
[email protected]cd500f72010-06-25 23:44:323529 // Extension counts shouldn't change.
3530 EXPECT_EQ(0u, service_->extensions()->size());
3531 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3532
3533 service_->EnableExtension(extension_id);
3534
3535 EXPECT_EQ(1u, service_->extensions()->size());
3536 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3537
[email protected]5a73f902010-06-30 02:29:413538 // Need to clear |loaded_| manually before reloading as the
3539 // EnableExtension() call above inserted into it and
3540 // UnloadAllExtensions() doesn't send out notifications.
3541 loaded_.clear();
[email protected]cd500f72010-06-25 23:44:323542 service_->ReloadExtensions();
3543
3544 // Extension counts shouldn't change.
3545 EXPECT_EQ(1u, service_->extensions()->size());
3546 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3547}
3548
[email protected]d9a61e12012-11-14 02:43:473549TEST_F(ExtensionServiceTest, UninstallExtension) {
[email protected]eaa7dd182010-12-14 11:09:003550 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503551 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]65187152012-06-02 13:14:143552 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]fa2416f2011-05-03 08:41:203553 UninstallExtension(good_crx, false);
[email protected]65187152012-06-02 13:14:143554 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]fa2416f2011-05-03 08:41:203555}
[email protected]631cf822009-05-15 07:01:253556
[email protected]d9a61e12012-11-14 02:43:473557TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
[email protected]fa2416f2011-05-03 08:41:203558 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503559 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203560 TerminateExtension(good_crx);
3561 UninstallExtension(good_crx, false);
[email protected]631cf822009-05-15 07:01:253562}
3563
[email protected]6aeac8342010-10-01 20:21:183564// Tests the uninstaller helper.
[email protected]d9a61e12012-11-14 02:43:473565TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
[email protected]eaa7dd182010-12-14 11:09:003566 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503567 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203568 UninstallExtension(good_crx, true);
3569}
[email protected]6aeac8342010-10-01 20:21:183570
[email protected]d9a61e12012-11-14 02:43:473571TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
[email protected]fa2416f2011-05-03 08:41:203572 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503573 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203574 TerminateExtension(good_crx);
3575 UninstallExtension(good_crx, true);
[email protected]6aeac8342010-10-01 20:21:183576}
3577
[email protected]98270432012-09-11 20:51:243578// An extension disabled because of unsupported requirements should re-enabled
3579// if updated to a version with supported requirements as long as there are no
3580// other disable reasons.
[email protected]d9a61e12012-11-14 02:43:473581TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
[email protected]98270432012-09-11 20:51:243582 InitializeEmptyExtensionService();
3583 BlackListWebGL();
3584
3585 FilePath path = data_dir_.AppendASCII("requirements");
3586 FilePath pem_path = data_dir_.AppendASCII("requirements")
3587 .AppendASCII("v1_good.pem");
3588 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
3589 pem_path,
3590 INSTALL_NEW);
3591 std::string id = extension_v1->id();
3592 EXPECT_TRUE(service_->IsExtensionEnabled(id));
3593
3594 PackCRX(path.AppendASCII("v2_bad_requirements"), pem_path,
3595 path.AppendASCII("v2_bad_requirements.crx"));
3596 UpdateExtension(id, path.AppendASCII("v2_bad_requirements.crx"), INSTALLED);
3597 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3598
3599 PackCRX(path.AppendASCII("v3_good"), pem_path,
3600 path.AppendASCII("v3_good.crx"));
3601 UpdateExtension(id, path.AppendASCII("v3_good.crx"), ENABLED);
3602 EXPECT_TRUE(service_->IsExtensionEnabled(id));
3603}
3604
3605// Extensions disabled through user action should stay disabled.
[email protected]d9a61e12012-11-14 02:43:473606TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
[email protected]98270432012-09-11 20:51:243607 InitializeEmptyExtensionService();
3608 BlackListWebGL();
3609
3610 FilePath path = data_dir_.AppendASCII("requirements");
3611 FilePath pem_path = data_dir_.AppendASCII("requirements")
3612 .AppendASCII("v1_good.pem");
3613 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
3614 pem_path,
3615 INSTALL_NEW);
3616 std::string id = extension_v1->id();
3617 service_->DisableExtension(id, Extension::DISABLE_USER_ACTION);
3618 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3619
3620 PackCRX(path.AppendASCII("v2_bad_requirements"), pem_path,
3621 path.AppendASCII("v2_bad_requirements.crx"));
3622 UpdateExtension(id, path.AppendASCII("v2_bad_requirements.crx"), INSTALLED);
3623 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3624
3625 PackCRX(path.AppendASCII("v3_good"), pem_path,
3626 path.AppendASCII("v3_good.crx"));
3627 UpdateExtension(id, path.AppendASCII("v3_good.crx"), INSTALLED);
3628 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3629}
3630
3631// The extension should not re-enabled because it was disabled from a
3632// permission increase.
[email protected]d9a61e12012-11-14 02:43:473633TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
[email protected]98270432012-09-11 20:51:243634 InitializeEmptyExtensionService();
3635 BlackListWebGL();
3636
3637 FilePath path = data_dir_.AppendASCII("requirements");
3638 FilePath pem_path = data_dir_.AppendASCII("requirements")
3639 .AppendASCII("v1_good.pem");
3640 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
3641 pem_path,
3642 INSTALL_NEW);
3643 std::string id = extension_v1->id();
3644 EXPECT_TRUE(service_->IsExtensionEnabled(id));
3645
3646 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"), pem_path,
3647 path.AppendASCII("v2_bad_requirements_and_permissions.crx"));
3648 UpdateExtension(
3649 id,
3650 path.AppendASCII("v2_bad_requirements_and_permissions.crx"), INSTALLED);
3651 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3652
3653 PackCRX(path.AppendASCII("v3_bad_permissions"), pem_path,
3654 path.AppendASCII("v3_bad_permissions.crx"));
3655 UpdateExtension(id, path.AppendASCII("v3_bad_permissions.crx"), INSTALLED);
3656 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3657}
3658
3659// Unpacked extensions are not allowed to be installed if they have unsupported
3660// requirements.
[email protected]d9a61e12012-11-14 02:43:473661TEST_F(ExtensionServiceTest, UnpackedRequirements) {
[email protected]98270432012-09-11 20:51:243662 InitializeEmptyExtensionService();
3663 BlackListWebGL();
3664
3665 FilePath path = data_dir_.AppendASCII("requirements")
3666 .AppendASCII("v2_bad_requirements");
3667 extensions::UnpackedInstaller::Create(service_)->Load(path);
[email protected]b8f50ce2012-11-17 12:37:573668 loop_.RunUntilIdle();
[email protected]98270432012-09-11 20:51:243669 EXPECT_EQ(1u, GetErrors().size());
3670 EXPECT_EQ(0u, service_->extensions()->size());
3671}
3672
[email protected]c4148a72011-08-09 23:04:203673class ExtensionCookieCallback {
3674 public:
3675 ExtensionCookieCallback()
3676 : result_(false),
[email protected]51d02152011-12-24 05:55:223677 weak_factory_(MessageLoop::current()) {}
[email protected]c4148a72011-08-09 23:04:203678
3679 void SetCookieCallback(bool result) {
3680 MessageLoop::current()->PostTask(
[email protected]51d02152011-12-24 05:55:223681 FROM_HERE, base::Bind(&MessageLoop::Quit, weak_factory_.GetWeakPtr()));
[email protected]c4148a72011-08-09 23:04:203682 result_ = result;
3683 }
3684
3685 void GetAllCookiesCallback(const net::CookieList& list) {
3686 MessageLoop::current()->PostTask(
[email protected]51d02152011-12-24 05:55:223687 FROM_HERE, base::Bind(&MessageLoop::Quit, weak_factory_.GetWeakPtr()));
[email protected]c4148a72011-08-09 23:04:203688 list_ = list;
3689 }
3690 net::CookieList list_;
3691 bool result_;
[email protected]51d02152011-12-24 05:55:223692 base::WeakPtrFactory<MessageLoop> weak_factory_;
[email protected]c4148a72011-08-09 23:04:203693};
3694
[email protected]0d6ec3a72011-09-02 02:09:433695// Verifies extension state is removed upon uninstall.
[email protected]d9a61e12012-11-14 02:43:473696TEST_F(ExtensionServiceTest, ClearExtensionData) {
[email protected]eaa7dd182010-12-14 11:09:003697 InitializeEmptyExtensionService();
[email protected]c4148a72011-08-09 23:04:203698 ExtensionCookieCallback callback;
[email protected]c10da4b02010-03-25 14:38:323699
3700 // Load a test extension.
[email protected]e85e34c32011-04-13 18:38:353701 FilePath path = data_dir_;
[email protected]c10da4b02010-03-25 14:38:323702 path = path.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503703 const Extension* extension = InstallCRX(path, INSTALL_NEW);
[email protected]c10da4b02010-03-25 14:38:323704 ASSERT_TRUE(extension);
3705 GURL ext_url(extension->url());
3706 string16 origin_id =
3707 webkit_database::DatabaseUtil::GetOriginIdentifier(ext_url);
3708
3709 // Set a cookie for the extension.
[email protected]277ec262011-03-30 21:09:403710 net::CookieMonster* cookie_monster =
3711 profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
3712 cookie_store()->GetCookieMonster();
[email protected]c10da4b02010-03-25 14:38:323713 ASSERT_TRUE(cookie_monster);
3714 net::CookieOptions options;
[email protected]c4148a72011-08-09 23:04:203715 cookie_monster->SetCookieWithOptionsAsync(
3716 ext_url, "dummy=value", options,
3717 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
3718 base::Unretained(&callback)));
[email protected]b8f50ce2012-11-17 12:37:573719 loop_.RunUntilIdle();
[email protected]c4148a72011-08-09 23:04:203720 EXPECT_TRUE(callback.result_);
3721
3722 cookie_monster->GetAllCookiesForURLAsync(
3723 ext_url,
3724 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3725 base::Unretained(&callback)));
[email protected]b8f50ce2012-11-17 12:37:573726 loop_.RunUntilIdle();
[email protected]c4148a72011-08-09 23:04:203727 EXPECT_EQ(1U, callback.list_.size());
[email protected]c10da4b02010-03-25 14:38:323728
3729 // Open a database.
[email protected]55eb70e762012-02-20 17:38:393730 webkit_database::DatabaseTracker* db_tracker =
[email protected]5c8e67c2012-08-29 00:48:523731 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3732 GetDatabaseTracker();
[email protected]c10da4b02010-03-25 14:38:323733 string16 db_name = UTF8ToUTF16("db");
3734 string16 description = UTF8ToUTF16("db_description");
3735 int64 size;
[email protected]7c5f2ec2011-05-26 19:15:263736 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
[email protected]c10da4b02010-03-25 14:38:323737 db_tracker->DatabaseClosed(origin_id, db_name);
3738 std::vector<webkit_database::OriginInfo> origins;
3739 db_tracker->GetAllOriginsInfo(&origins);
3740 EXPECT_EQ(1U, origins.size());
3741 EXPECT_EQ(origin_id, origins[0].GetOrigin());
3742
[email protected]98823c682012-06-11 21:18:243743 // Create local storage. We only simulate this by creating the backing files.
3744 // Note: This test depends on details of how the dom_storage library
3745 // stores data in the host file system.
3746 FilePath lso_dir_path = profile_->GetPath().AppendASCII("Local Storage");
3747 FilePath lso_file_path = lso_dir_path.AppendASCII(
3748 UTF16ToUTF8(origin_id) + ".localstorage");
3749 EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
3750 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
3751 EXPECT_TRUE(file_util::PathExists(lso_file_path));
[email protected]c10da4b02010-03-25 14:38:323752
[email protected]ab308092011-08-25 23:37:193753 // Create indexed db. Similarly, it is enough to only simulate this by
3754 // creating the directory on the disk.
[email protected]b1b502e2012-09-16 07:31:433755 IndexedDBContext* idb_context =
3756 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3757 GetIndexedDBContext();
[email protected]35cc399e2012-02-23 18:19:283758 FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
[email protected]ab308092011-08-25 23:37:193759 EXPECT_TRUE(file_util::CreateDirectory(idb_path));
3760 EXPECT_TRUE(file_util::DirectoryExists(idb_path));
[email protected]e1dcf922010-11-22 19:12:123761
[email protected]c10da4b02010-03-25 14:38:323762 // Uninstall the extension.
[email protected]d6ebc9792011-04-07 18:18:333763 service_->UninstallExtension(good_crx, false, NULL);
[email protected]b8f50ce2012-11-17 12:37:573764 loop_.RunUntilIdle();
[email protected]c10da4b02010-03-25 14:38:323765
3766 // Check that the cookie is gone.
[email protected]c4148a72011-08-09 23:04:203767 cookie_monster->GetAllCookiesForURLAsync(
3768 ext_url,
3769 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3770 base::Unretained(&callback)));
[email protected]b8f50ce2012-11-17 12:37:573771 loop_.RunUntilIdle();
[email protected]c4148a72011-08-09 23:04:203772 EXPECT_EQ(0U, callback.list_.size());
[email protected]c10da4b02010-03-25 14:38:323773
3774 // The database should have vanished as well.
3775 origins.clear();
3776 db_tracker->GetAllOriginsInfo(&origins);
3777 EXPECT_EQ(0U, origins.size());
3778
3779 // Check that the LSO file has been removed.
[email protected]98823c682012-06-11 21:18:243780 EXPECT_FALSE(file_util::PathExists(lso_file_path));
[email protected]e1dcf922010-11-22 19:12:123781
3782 // Check if the indexed db has disappeared too.
[email protected]ab308092011-08-25 23:37:193783 EXPECT_FALSE(file_util::DirectoryExists(idb_path));
[email protected]c10da4b02010-03-25 14:38:323784}
3785
[email protected]0d6ec3a72011-09-02 02:09:433786// Verifies app state is removed upon uninstall.
[email protected]d9a61e12012-11-14 02:43:473787TEST_F(ExtensionServiceTest, ClearAppData) {
[email protected]0d6ec3a72011-09-02 02:09:433788 InitializeEmptyExtensionService();
3789 InitializeRequestContext();
3790 ExtensionCookieCallback callback;
3791
3792 int pref_count = 0;
3793
3794 // Install app1 with unlimited storage.
[email protected]8f512c72011-11-22 21:02:503795 const Extension* extension =
3796 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
[email protected]0d6ec3a72011-09-02 02:09:433797 ValidatePrefKeyCount(++pref_count);
3798 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]0d6ec3a72011-09-02 02:09:433799 const std::string id1 = extension->id();
3800 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:063801 APIPermission::kUnlimitedStorage));
[email protected]0d6ec3a72011-09-02 02:09:433802 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
3803 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
3804 IsStorageUnlimited(origin1));
3805 string16 origin_id =
3806 webkit_database::DatabaseUtil::GetOriginIdentifier(origin1);
3807
3808 // Install app2 from the same origin with unlimited storage.
[email protected]8f512c72011-11-22 21:02:503809 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
[email protected]0d6ec3a72011-09-02 02:09:433810 ValidatePrefKeyCount(++pref_count);
3811 ASSERT_EQ(2u, service_->extensions()->size());
[email protected]0d6ec3a72011-09-02 02:09:433812 const std::string id2 = extension->id();
3813 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:063814 APIPermission::kUnlimitedStorage));
[email protected]0d6ec3a72011-09-02 02:09:433815 EXPECT_TRUE(extension->web_extent().MatchesURL(
3816 extension->GetFullLaunchURL()));
3817 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
3818 EXPECT_EQ(origin1, origin2);
3819 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
3820 IsStorageUnlimited(origin2));
3821
3822 // Set a cookie for the extension.
3823 net::CookieMonster* cookie_monster =
3824 profile_->GetRequestContext()->GetURLRequestContext()->
3825 cookie_store()->GetCookieMonster();
3826 ASSERT_TRUE(cookie_monster);
3827 net::CookieOptions options;
3828 cookie_monster->SetCookieWithOptionsAsync(
3829 origin1, "dummy=value", options,
3830 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
3831 base::Unretained(&callback)));
[email protected]b8f50ce2012-11-17 12:37:573832 loop_.RunUntilIdle();
[email protected]0d6ec3a72011-09-02 02:09:433833 EXPECT_TRUE(callback.result_);
3834
3835 cookie_monster->GetAllCookiesForURLAsync(
3836 origin1,
3837 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3838 base::Unretained(&callback)));
[email protected]b8f50ce2012-11-17 12:37:573839 loop_.RunUntilIdle();
[email protected]0d6ec3a72011-09-02 02:09:433840 EXPECT_EQ(1U, callback.list_.size());
3841
3842 // Open a database.
[email protected]55eb70e762012-02-20 17:38:393843 webkit_database::DatabaseTracker* db_tracker =
[email protected]5c8e67c2012-08-29 00:48:523844 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3845 GetDatabaseTracker();
[email protected]0d6ec3a72011-09-02 02:09:433846 string16 db_name = UTF8ToUTF16("db");
3847 string16 description = UTF8ToUTF16("db_description");
3848 int64 size;
3849 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
3850 db_tracker->DatabaseClosed(origin_id, db_name);
3851 std::vector<webkit_database::OriginInfo> origins;
3852 db_tracker->GetAllOriginsInfo(&origins);
3853 EXPECT_EQ(1U, origins.size());
3854 EXPECT_EQ(origin_id, origins[0].GetOrigin());
3855
[email protected]98823c682012-06-11 21:18:243856 // Create local storage. We only simulate this by creating the backing files.
3857 // Note: This test depends on details of how the dom_storage library
3858 // stores data in the host file system.
3859 FilePath lso_dir_path = profile_->GetPath().AppendASCII("Local Storage");
3860 FilePath lso_file_path = lso_dir_path.AppendASCII(
3861 UTF16ToUTF8(origin_id) + ".localstorage");
3862 EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
3863 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
3864 EXPECT_TRUE(file_util::PathExists(lso_file_path));
[email protected]0d6ec3a72011-09-02 02:09:433865
3866 // Create indexed db. Similarly, it is enough to only simulate this by
3867 // creating the directory on the disk.
[email protected]b1b502e2012-09-16 07:31:433868 IndexedDBContext* idb_context =
3869 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3870 GetIndexedDBContext();
[email protected]35cc399e2012-02-23 18:19:283871 FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
[email protected]0d6ec3a72011-09-02 02:09:433872 EXPECT_TRUE(file_util::CreateDirectory(idb_path));
3873 EXPECT_TRUE(file_util::DirectoryExists(idb_path));
3874
3875 // Uninstall one of them, unlimited storage should still be granted
3876 // to the origin.
3877 UninstallExtension(id1, false);
3878 EXPECT_EQ(1u, service_->extensions()->size());
3879 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
3880 IsStorageUnlimited(origin1));
3881
3882 // Check that the cookie is still there.
3883 cookie_monster->GetAllCookiesForURLAsync(
3884 origin1,
3885 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3886 base::Unretained(&callback)));
[email protected]b8f50ce2012-11-17 12:37:573887 loop_.RunUntilIdle();
[email protected]0d6ec3a72011-09-02 02:09:433888 EXPECT_EQ(1U, callback.list_.size());
3889
3890 // Now uninstall the other. Storage should be cleared for the apps.
3891 UninstallExtension(id2, false);
3892 EXPECT_EQ(0u, service_->extensions()->size());
3893 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
3894 IsStorageUnlimited(origin1));
3895
3896 // Check that the cookie is gone.
3897 cookie_monster->GetAllCookiesForURLAsync(
3898 origin1,
3899 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3900 base::Unretained(&callback)));
[email protected]b8f50ce2012-11-17 12:37:573901 loop_.RunUntilIdle();
[email protected]0d6ec3a72011-09-02 02:09:433902 EXPECT_EQ(0U, callback.list_.size());
3903
3904 // The database should have vanished as well.
3905 origins.clear();
3906 db_tracker->GetAllOriginsInfo(&origins);
3907 EXPECT_EQ(0U, origins.size());
3908
3909 // Check that the LSO file has been removed.
[email protected]98823c682012-06-11 21:18:243910 EXPECT_FALSE(file_util::PathExists(lso_file_path));
[email protected]0d6ec3a72011-09-02 02:09:433911
3912 // Check if the indexed db has disappeared too.
3913 EXPECT_FALSE(file_util::DirectoryExists(idb_path));
3914}
3915
[email protected]894bb502009-05-21 22:39:573916// Tests loading single extensions (like --load-extension)
[email protected]d9a61e12012-11-14 02:43:473917TEST_F(ExtensionServiceTest, LoadExtension) {
[email protected]eaa7dd182010-12-14 11:09:003918 InitializeEmptyExtensionService();
[email protected]3cf4f0992009-02-03 23:00:303919
[email protected]e85e34c32011-04-13 18:38:353920 FilePath ext1 = data_dir_
[email protected]a9b00ac2009-06-25 21:03:233921 .AppendASCII("good")
3922 .AppendASCII("Extensions")
[email protected]5a2721f62009-06-13 07:08:203923 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
3924 .AppendASCII("1.0.0.0");
[email protected]d8c8f25f2011-11-02 18:18:013925 extensions::UnpackedInstaller::Create(service_)->Load(ext1);
[email protected]b8f50ce2012-11-17 12:37:573926 loop_.RunUntilIdle();
[email protected]bb28e062009-02-27 17:19:183927 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:573928 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:323929 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
3930 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:303931
[email protected]e8c729a2010-03-09 19:55:193932 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:193933
[email protected]e85e34c32011-04-13 18:38:353934 FilePath no_manifest = data_dir_
[email protected]a9b00ac2009-06-25 21:03:233935 .AppendASCII("bad")
[email protected]93fd78f42009-07-10 16:43:173936 // .AppendASCII("Extensions")
[email protected]a9b00ac2009-06-25 21:03:233937 .AppendASCII("cccccccccccccccccccccccccccccccc")
3938 .AppendASCII("1");
[email protected]d8c8f25f2011-11-02 18:18:013939 extensions::UnpackedInstaller::Create(service_)->Load(no_manifest);
[email protected]b8f50ce2012-11-17 12:37:573940 loop_.RunUntilIdle();
[email protected]bb28e062009-02-27 17:19:183941 EXPECT_EQ(1u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:573942 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:323943 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]25b34332009-06-05 21:53:193944
3945 // Test uninstall.
[email protected]894bb502009-05-21 22:39:573946 std::string id = loaded_[0]->id();
3947 EXPECT_FALSE(unloaded_id_.length());
[email protected]d6ebc9792011-04-07 18:18:333948 service_->UninstallExtension(id, false, NULL);
[email protected]b8f50ce2012-11-17 12:37:573949 loop_.RunUntilIdle();
[email protected]894bb502009-05-21 22:39:573950 EXPECT_EQ(id, unloaded_id_);
[email protected]9f1087e2009-06-15 17:29:323951 ASSERT_EQ(0u, loaded_.size());
3952 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:303953}
[email protected]0b344962009-03-31 04:21:453954
[email protected]894bb502009-05-21 22:39:573955// Tests that we generate IDs when they are not specified in the manifest for
3956// --load-extension.
[email protected]d9a61e12012-11-14 02:43:473957TEST_F(ExtensionServiceTest, GenerateID) {
[email protected]eaa7dd182010-12-14 11:09:003958 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:453959
[email protected]e85e34c32011-04-13 18:38:353960 FilePath no_id_ext = data_dir_.AppendASCII("no_id");
[email protected]d8c8f25f2011-11-02 18:18:013961 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
[email protected]b8f50ce2012-11-17 12:37:573962 loop_.RunUntilIdle();
[email protected]0b344962009-03-31 04:21:453963 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:573964 ASSERT_EQ(1u, loaded_.size());
[email protected]84ac7f32009-10-06 06:17:543965 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
[email protected]9f1087e2009-06-15 17:29:323966 EXPECT_EQ(loaded_[0]->location(), Extension::LOAD);
[email protected]0b344962009-03-31 04:21:453967
[email protected]e8c729a2010-03-09 19:55:193968 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:193969
[email protected]84ac7f32009-10-06 06:17:543970 std::string previous_id = loaded_[0]->id();
3971
3972 // If we reload the same path, we should get the same extension ID.
[email protected]d8c8f25f2011-11-02 18:18:013973 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
[email protected]b8f50ce2012-11-17 12:37:573974 loop_.RunUntilIdle();
[email protected]84ac7f32009-10-06 06:17:543975 ASSERT_EQ(1u, loaded_.size());
3976 ASSERT_EQ(previous_id, loaded_[0]->id());
[email protected]0b344962009-03-31 04:21:453977}
[email protected]894bb502009-05-21 22:39:573978
[email protected]eaa7dd182010-12-14 11:09:003979void ExtensionServiceTest::TestExternalProvider(
[email protected]d55e7602009-12-16 04:20:423980 MockExtensionProvider* provider, Extension::Location location) {
[email protected]a1257b12009-06-12 02:51:343981 // Verify that starting with no providers loads no extensions.
3982 service_->Init();
[email protected]a1257b12009-06-12 02:51:343983 ASSERT_EQ(0u, loaded_.size());
3984
[email protected]0a60a2e2010-10-25 16:15:213985 provider->set_visit_count(0);
3986
[email protected]a1257b12009-06-12 02:51:343987 // Register a test extension externally using the mock registry provider.
[email protected]e85e34c32011-04-13 18:38:353988 FilePath source_path = data_dir_.AppendASCII("good.crx");
[email protected]894bb502009-05-21 22:39:573989
[email protected]a1257b12009-06-12 02:51:343990 // Add the extension.
[email protected]d55e7602009-12-16 04:20:423991 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
[email protected]894bb502009-05-21 22:39:573992
[email protected]9f1087e2009-06-15 17:29:323993 // Reloading extensions should find our externally registered extension
[email protected]894bb502009-05-21 22:39:573994 // and install it.
[email protected]93fd78f42009-07-10 16:43:173995 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:573996 loop_.RunUntilIdle();
[email protected]894bb502009-05-21 22:39:573997
3998 ASSERT_EQ(0u, GetErrors().size());
3999 ASSERT_EQ(1u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:424000 ASSERT_EQ(location, loaded_[0]->location());
[email protected]894bb502009-05-21 22:39:574001 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:194002 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:344003 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4004 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:574005
[email protected]9f1087e2009-06-15 17:29:324006 // Reload extensions without changing anything. The extension should be
[email protected]894bb502009-05-21 22:39:574007 // loaded again.
4008 loaded_.clear();
[email protected]9f1087e2009-06-15 17:29:324009 service_->ReloadExtensions();
[email protected]b8f50ce2012-11-17 12:37:574010 loop_.RunUntilIdle();
[email protected]894bb502009-05-21 22:39:574011 ASSERT_EQ(0u, GetErrors().size());
4012 ASSERT_EQ(1u, loaded_.size());
[email protected]25b34332009-06-05 21:53:194013 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:344014 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4015 ValidateIntegerPref(good_crx, "location", location);
[email protected]e2eb43112009-05-29 21:19:544016
[email protected]894bb502009-05-21 22:39:574017 // Now update the extension with a new version. We should get upgraded.
4018 source_path = source_path.DirName().AppendASCII("good2.crx");
[email protected]d55e7602009-12-16 04:20:424019 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]894bb502009-05-21 22:39:574020
4021 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:174022 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:574023 loop_.RunUntilIdle();
[email protected]894bb502009-05-21 22:39:574024 ASSERT_EQ(0u, GetErrors().size());
4025 ASSERT_EQ(1u, loaded_.size());
4026 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:194027 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:344028 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4029 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:574030
[email protected]27b985d2009-06-25 17:53:154031 // Uninstall the extension and reload. Nothing should happen because the
[email protected]894bb502009-05-21 22:39:574032 // preference should prevent us from reinstalling.
4033 std::string id = loaded_[0]->id();
[email protected]e410b5f2012-12-14 14:02:244034 bool no_uninstall = management_policy_->MustRemainEnabled(loaded_[0], NULL);
[email protected]d6ebc9792011-04-07 18:18:334035 service_->UninstallExtension(id, false, NULL);
[email protected]b8f50ce2012-11-17 12:37:574036 loop_.RunUntilIdle();
[email protected]894bb502009-05-21 22:39:574037
[email protected]a9b00ac2009-06-25 21:03:234038 FilePath install_path = extensions_install_dir_.AppendASCII(id);
[email protected]e410b5f2012-12-14 14:02:244039 if (no_uninstall) {
[email protected]65187152012-06-02 13:14:144040 // Policy controlled extensions should not have been touched by uninstall.
4041 ASSERT_TRUE(file_util::PathExists(install_path));
4042 } else {
[email protected]95da88c42011-03-31 10:07:334043 // The extension should also be gone from the install directory.
4044 ASSERT_FALSE(file_util::PathExists(install_path));
4045 loaded_.clear();
4046 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:574047 loop_.RunUntilIdle();
[email protected]95da88c42011-03-31 10:07:334048 ASSERT_EQ(0u, loaded_.size());
4049 ValidatePrefKeyCount(1);
[email protected]79c833b52011-04-05 18:31:014050 ValidateIntegerPref(good_crx, "state",
4051 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]95da88c42011-03-31 10:07:334052 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:574053
[email protected]95da88c42011-03-31 10:07:334054 // Now clear the preference and reinstall.
4055 SetPrefInteg(good_crx, "state", Extension::ENABLED);
[email protected]25b34332009-06-05 21:53:194056
[email protected]95da88c42011-03-31 10:07:334057 loaded_.clear();
4058 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:574059 loop_.RunUntilIdle();
[email protected]95da88c42011-03-31 10:07:334060 ASSERT_EQ(1u, loaded_.size());
[email protected]95da88c42011-03-31 10:07:334061 }
[email protected]25b34332009-06-05 21:53:194062 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:344063 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4064 ValidateIntegerPref(good_crx, "location", location);
[email protected]25b34332009-06-05 21:53:194065
[email protected]e410b5f2012-12-14 14:02:244066 if (management_policy_->MustRemainEnabled(loaded_[0], NULL)) {
[email protected]65187152012-06-02 13:14:144067 EXPECT_EQ(2, provider->visit_count());
4068 } else {
[email protected]95da88c42011-03-31 10:07:334069 // Now test an externally triggered uninstall (deleting the registry key or
4070 // the pref entry).
4071 provider->RemoveExtension(good_crx);
[email protected]25b34332009-06-05 21:53:194072
[email protected]95da88c42011-03-31 10:07:334073 loaded_.clear();
[email protected]50067e52011-10-20 23:17:074074 service_->OnExternalProviderReady(provider);
[email protected]b8f50ce2012-11-17 12:37:574075 loop_.RunUntilIdle();
[email protected]95da88c42011-03-31 10:07:334076 ASSERT_EQ(0u, loaded_.size());
4077 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:194078
[email protected]95da88c42011-03-31 10:07:334079 // The extension should also be gone from the install directory.
4080 ASSERT_FALSE(file_util::PathExists(install_path));
[email protected]abe7a8942009-06-23 05:14:294081
[email protected]95da88c42011-03-31 10:07:334082 // Now test the case where user uninstalls and then the extension is removed
4083 // from the external provider.
[email protected]05aad2da2011-10-28 10:12:374084 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]95da88c42011-03-31 10:07:334085 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:574086 loop_.RunUntilIdle();
[email protected]abe7a8942009-06-23 05:14:294087
[email protected]95da88c42011-03-31 10:07:334088 ASSERT_EQ(1u, loaded_.size());
4089 ASSERT_EQ(0u, GetErrors().size());
[email protected]d55e7602009-12-16 04:20:424090
[email protected]95da88c42011-03-31 10:07:334091 // User uninstalls.
4092 loaded_.clear();
[email protected]d6ebc9792011-04-07 18:18:334093 service_->UninstallExtension(id, false, NULL);
[email protected]b8f50ce2012-11-17 12:37:574094 loop_.RunUntilIdle();
[email protected]95da88c42011-03-31 10:07:334095 ASSERT_EQ(0u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:424096
[email protected]95da88c42011-03-31 10:07:334097 // Then remove the extension from the extension provider.
4098 provider->RemoveExtension(good_crx);
[email protected]d55e7602009-12-16 04:20:424099
[email protected]95da88c42011-03-31 10:07:334100 // Should still be at 0.
4101 loaded_.clear();
[email protected]d8c8f25f2011-11-02 18:18:014102 extensions::InstalledLoader(service_).LoadAllExtensions();
[email protected]b8f50ce2012-11-17 12:37:574103 loop_.RunUntilIdle();
[email protected]95da88c42011-03-31 10:07:334104 ASSERT_EQ(0u, loaded_.size());
4105 ValidatePrefKeyCount(1);
[email protected]0a60a2e2010-10-25 16:15:214106
[email protected]95da88c42011-03-31 10:07:334107 EXPECT_EQ(5, provider->visit_count());
[email protected]95da88c42011-03-31 10:07:334108 }
[email protected]d55e7602009-12-16 04:20:424109}
4110
4111// Tests the external installation feature
4112#if defined(OS_WIN)
[email protected]d9a61e12012-11-14 02:43:474113TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
[email protected]aebe23a32010-12-10 22:15:484114 // This should all work, even when normal extension installation is disabled.
[email protected]eaa7dd182010-12-14 11:09:004115 InitializeEmptyExtensionService();
[email protected]aebe23a32010-12-10 22:15:484116 set_extensions_enabled(false);
[email protected]d55e7602009-12-16 04:20:424117
4118 // Now add providers. Extension system takes ownership of the objects.
4119 MockExtensionProvider* reg_provider =
[email protected]14908b72011-04-20 06:54:364120 new MockExtensionProvider(service_, Extension::EXTERNAL_REGISTRY);
[email protected]0a60a2e2010-10-25 16:15:214121 AddMockExternalProvider(reg_provider);
[email protected]d55e7602009-12-16 04:20:424122 TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
4123}
4124#endif
4125
[email protected]d9a61e12012-11-14 02:43:474126TEST_F(ExtensionServiceTest, ExternalInstallPref) {
[email protected]eaa7dd182010-12-14 11:09:004127 InitializeEmptyExtensionService();
[email protected]d55e7602009-12-16 04:20:424128
4129 // Now add providers. Extension system takes ownership of the objects.
4130 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:364131 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]0a60a2e2010-10-25 16:15:214132
4133 AddMockExternalProvider(pref_provider);
[email protected]d55e7602009-12-16 04:20:424134 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
[email protected]27b985d2009-06-25 17:53:154135}
4136
[email protected]d9a61e12012-11-14 02:43:474137TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
[email protected]aebe23a32010-12-10 22:15:484138 // This should all work, even when normal extension installation is disabled.
[email protected]eaa7dd182010-12-14 11:09:004139 InitializeEmptyExtensionService();
[email protected]aebe23a32010-12-10 22:15:484140 set_extensions_enabled(false);
[email protected]55196e92010-09-29 15:04:464141
[email protected]0a60a2e2010-10-25 16:15:214142 // TODO(skerner): The mock provider is not a good model of a provider
4143 // that works with update URLs, because it adds file and version info.
4144 // Extend the mock to work with update URLs. This test checks the
4145 // behavior that is common to all external extension visitors. The
4146 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4147 // what the visitor does results in an extension being downloaded and
4148 // installed.
[email protected]55196e92010-09-29 15:04:464149 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:364150 new MockExtensionProvider(service_,
[email protected]8e4560b62011-01-14 10:09:144151 Extension::EXTERNAL_PREF_DOWNLOAD);
[email protected]0a60a2e2010-10-25 16:15:214152 AddMockExternalProvider(pref_provider);
[email protected]55196e92010-09-29 15:04:464153 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF_DOWNLOAD);
4154}
4155
[email protected]d9a61e12012-11-14 02:43:474156TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
[email protected]95da88c42011-03-31 10:07:334157 // This should all work, even when normal extension installation is disabled.
4158 InitializeEmptyExtensionService();
4159 set_extensions_enabled(false);
4160
4161 // TODO(skerner): The mock provider is not a good model of a provider
4162 // that works with update URLs, because it adds file and version info.
4163 // Extend the mock to work with update URLs. This test checks the
4164 // behavior that is common to all external extension visitors. The
4165 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4166 // what the visitor does results in an extension being downloaded and
4167 // installed.
4168 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:364169 new MockExtensionProvider(service_,
[email protected]95da88c42011-03-31 10:07:334170 Extension::EXTERNAL_POLICY_DOWNLOAD);
4171 AddMockExternalProvider(pref_provider);
4172 TestExternalProvider(pref_provider, Extension::EXTERNAL_POLICY_DOWNLOAD);
4173}
4174
[email protected]aebe23a32010-12-10 22:15:484175// Tests that external extensions get uninstalled when the external extension
4176// providers can't account for them.
[email protected]d9a61e12012-11-14 02:43:474177TEST_F(ExtensionServiceTest, ExternalUninstall) {
[email protected]aebe23a32010-12-10 22:15:484178 // Start the extensions service with one external extension already installed.
[email protected]e85e34c32011-04-13 18:38:354179 FilePath source_install_dir = data_dir_
[email protected]aebe23a32010-12-10 22:15:484180 .AppendASCII("good")
4181 .AppendASCII("Extensions");
4182 FilePath pref_path = source_install_dir
4183 .DirName()
4184 .AppendASCII("PreferencesExternal");
4185
[email protected]5df038b2012-07-16 19:03:274186 // This initializes the extensions service with no ExternalProviders.
[email protected]eaa7dd182010-12-14 11:09:004187 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]aebe23a32010-12-10 22:15:484188 set_extensions_enabled(false);
4189
4190 service_->Init();
[email protected]aebe23a32010-12-10 22:15:484191
4192 ASSERT_EQ(0u, GetErrors().size());
[email protected]1f4728f2012-12-05 20:40:054193 ASSERT_EQ(0u, loaded_.size());
[email protected]aebe23a32010-12-10 22:15:484194
4195 // Verify that it's not the disabled extensions flag causing it not to load.
4196 set_extensions_enabled(true);
4197 service_->ReloadExtensions();
[email protected]b8f50ce2012-11-17 12:37:574198 loop_.RunUntilIdle();
[email protected]aebe23a32010-12-10 22:15:484199
4200 ASSERT_EQ(0u, GetErrors().size());
4201 ASSERT_EQ(0u, loaded_.size());
4202}
4203
[email protected]a29a517a2011-01-21 21:11:124204// Test that running multiple update checks simultaneously does not
4205// keep the update from succeeding.
[email protected]d9a61e12012-11-14 02:43:474206TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
[email protected]a29a517a2011-01-21 21:11:124207 InitializeEmptyExtensionService();
4208
4209 MockExtensionProvider* provider =
[email protected]14908b72011-04-20 06:54:364210 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]a29a517a2011-01-21 21:11:124211 AddMockExternalProvider(provider);
4212
4213 // Verify that starting with no providers loads no extensions.
4214 service_->Init();
[email protected]a29a517a2011-01-21 21:11:124215 ASSERT_EQ(0u, loaded_.size());
4216
4217 // Start two checks for updates.
4218 provider->set_visit_count(0);
4219 service_->CheckForExternalUpdates();
4220 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:574221 loop_.RunUntilIdle();
[email protected]a29a517a2011-01-21 21:11:124222
4223 // Two calls should cause two checks for external extensions.
4224 EXPECT_EQ(2, provider->visit_count());
4225 EXPECT_EQ(0u, GetErrors().size());
4226 EXPECT_EQ(0u, loaded_.size());
4227
4228 // Register a test extension externally using the mock registry provider.
[email protected]e85e34c32011-04-13 18:38:354229 FilePath source_path = data_dir_.AppendASCII("good.crx");
[email protected]a29a517a2011-01-21 21:11:124230 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4231
4232 // Two checks for external updates should find the extension, and install it
4233 // once.
4234 provider->set_visit_count(0);
4235 service_->CheckForExternalUpdates();
4236 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:574237 loop_.RunUntilIdle();
[email protected]a29a517a2011-01-21 21:11:124238 EXPECT_EQ(2, provider->visit_count());
4239 ASSERT_EQ(0u, GetErrors().size());
4240 ASSERT_EQ(1u, loaded_.size());
4241 ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location());
4242 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4243 ValidatePrefKeyCount(1);
4244 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4245 ValidateIntegerPref(good_crx, "location", Extension::EXTERNAL_PREF);
4246
4247 provider->RemoveExtension(good_crx);
4248 provider->set_visit_count(0);
4249 service_->CheckForExternalUpdates();
4250 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:574251 loop_.RunUntilIdle();
[email protected]a29a517a2011-01-21 21:11:124252
4253 // Two calls should cause two checks for external extensions.
4254 // Because the external source no longer includes good_crx,
4255 // good_crx will be uninstalled. So, expect that no extensions
4256 // are loaded.
4257 EXPECT_EQ(2, provider->visit_count());
4258 EXPECT_EQ(0u, GetErrors().size());
4259 EXPECT_EQ(0u, loaded_.size());
4260}
4261
[email protected]9d32ded072011-10-11 16:31:054262namespace {
4263 class ScopedBrowserLocale {
4264 public:
4265 explicit ScopedBrowserLocale(const std::string& new_locale)
4266 : old_locale_(g_browser_process->GetApplicationLocale()) {
4267 g_browser_process->SetApplicationLocale(new_locale);
4268 }
4269
4270 ~ScopedBrowserLocale() {
4271 g_browser_process->SetApplicationLocale(old_locale_);
4272 }
4273
4274 private:
4275 std::string old_locale_;
4276 };
4277}
4278
[email protected]d9a61e12012-11-14 02:43:474279TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
[email protected]eaa7dd182010-12-14 11:09:004280 InitializeEmptyExtensionService();
[email protected]f0841cd2011-01-19 15:07:244281
4282 // Test some valid extension records.
4283 // Set a base path to avoid erroring out on relative paths.
4284 // Paths starting with // are absolute on every platform we support.
4285 FilePath base_path(FILE_PATH_LITERAL("//base/path"));
4286 ASSERT_TRUE(base_path.IsAbsolute());
4287 MockProviderVisitor visitor(base_path);
[email protected]27b985d2009-06-25 17:53:154288 std::string json_data =
4289 "{"
[email protected]f0841cd2011-01-19 15:07:244290 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
[email protected]9e54cb572010-09-03 20:08:064291 " \"external_crx\": \"RandomExtension.crx\","
4292 " \"external_version\": \"1.0\""
4293 " },"
4294 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4295 " \"external_crx\": \"RandomExtension2.crx\","
4296 " \"external_version\": \"2.0\""
4297 " },"
4298 " \"cccccccccccccccccccccccccccccccc\": {"
[email protected]a424d84c2010-09-24 09:31:154299 " \"external_update_url\": \"http:\\\\foo.com/update\""
[email protected]9e54cb572010-09-03 20:08:064300 " }"
[email protected]27b985d2009-06-25 17:53:154301 "}";
[email protected]f0841cd2011-01-19 15:07:244302 EXPECT_EQ(3, visitor.Visit(json_data));
[email protected]27b985d2009-06-25 17:53:154303
[email protected]9e54cb572010-09-03 20:08:064304 // Simulate an external_extensions.json file that contains seven invalid
[email protected]f0841cd2011-01-19 15:07:244305 // records:
[email protected]27b985d2009-06-25 17:53:154306 // - One that is missing the 'external_crx' key.
4307 // - One that is missing the 'external_version' key.
4308 // - One that is specifying .. in the path.
[email protected]8ef78fd2010-08-19 17:14:324309 // - One that specifies both a file and update URL.
4310 // - One that specifies no file or update URL.
4311 // - One that has an update URL that is not well formed.
[email protected]9e54cb572010-09-03 20:08:064312 // - One that contains a malformed version.
[email protected]ab22ba42011-01-14 16:36:384313 // - One that has an invalid id.
4314 // - One that has a non-dictionary value.
[email protected]0d461c52012-07-03 19:29:414315 // - One that has an integer 'external_version' instead of a string.
[email protected]9e54cb572010-09-03 20:08:064316 // The final extension is valid, and we check that it is read to make sure
4317 // failures don't stop valid records from being read.
[email protected]27b985d2009-06-25 17:53:154318 json_data =
4319 "{"
[email protected]9e54cb572010-09-03 20:08:064320 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4321 " \"external_version\": \"1.0\""
4322 " },"
4323 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4324 " \"external_crx\": \"RandomExtension.crx\""
4325 " },"
4326 " \"cccccccccccccccccccccccccccccccc\": {"
4327 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
4328 " \"external_version\": \"2.0\""
4329 " },"
4330 " \"dddddddddddddddddddddddddddddddd\": {"
4331 " \"external_crx\": \"RandomExtension2.crx\","
4332 " \"external_version\": \"2.0\","
4333 " \"external_update_url\": \"http:\\\\foo.com/update\""
4334 " },"
4335 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
4336 " },"
4337 " \"ffffffffffffffffffffffffffffffff\": {"
4338 " \"external_update_url\": \"This string is not a valid URL\""
4339 " },"
4340 " \"gggggggggggggggggggggggggggggggg\": {"
4341 " \"external_crx\": \"RandomExtension3.crx\","
4342 " \"external_version\": \"This is not a valid version!\""
4343 " },"
[email protected]ab22ba42011-01-14 16:36:384344 " \"This is not a valid id!\": {},"
4345 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
[email protected]0d461c52012-07-03 19:29:414346 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
4347 " \"external_crx\": \"RandomExtension4.crx\","
4348 " \"external_version\": 1.0"
4349 " },"
[email protected]ab22ba42011-01-14 16:36:384350 " \"pppppppppppppppppppppppppppppppp\": {"
[email protected]9e54cb572010-09-03 20:08:064351 " \"external_crx\": \"RandomValidExtension.crx\","
4352 " \"external_version\": \"1.0\""
4353 " }"
[email protected]27b985d2009-06-25 17:53:154354 "}";
[email protected]683d0702010-12-06 16:25:574355 EXPECT_EQ(1, visitor.Visit(json_data));
[email protected]f0841cd2011-01-19 15:07:244356
4357 // Check that if a base path is not provided, use of a relative
4358 // path fails.
4359 FilePath empty;
4360 MockProviderVisitor visitor_no_relative_paths(empty);
4361
4362 // Use absolute paths. Expect success.
4363 json_data =
4364 "{"
4365 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4366 " \"external_crx\": \"//RandomExtension1.crx\","
4367 " \"external_version\": \"3.0\""
4368 " },"
4369 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4370 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
4371 " \"external_version\": \"3.0\""
4372 " }"
4373 "}";
4374 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
4375
4376 // Use a relative path. Expect that it will error out.
4377 json_data =
4378 "{"
4379 " \"cccccccccccccccccccccccccccccccc\": {"
4380 " \"external_crx\": \"RandomExtension2.crx\","
4381 " \"external_version\": \"3.0\""
4382 " }"
4383 "}";
4384 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
[email protected]9d32ded072011-10-11 16:31:054385
4386 // Test supported_locales.
4387 json_data =
4388 "{"
4389 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4390 " \"external_crx\": \"RandomExtension.crx\","
4391 " \"external_version\": \"1.0\","
4392 " \"supported_locales\": [ \"en\" ]"
4393 " },"
4394 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4395 " \"external_crx\": \"RandomExtension2.crx\","
4396 " \"external_version\": \"2.0\","
4397 " \"supported_locales\": [ \"en-GB\" ]"
4398 " },"
4399 " \"cccccccccccccccccccccccccccccccc\": {"
4400 " \"external_crx\": \"RandomExtension2.crx\","
4401 " \"external_version\": \"3.0\","
4402 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
4403 " }"
4404 "}";
4405 {
4406 ScopedBrowserLocale guard("en-US");
4407 EXPECT_EQ(2, visitor.Visit(json_data));
4408 }
[email protected]f121003b2012-05-04 21:57:474409
4410 // Test is_bookmark_app.
4411 MockProviderVisitor from_bookmark_visitor(
4412 base_path, Extension::FROM_BOOKMARK);
4413 json_data =
4414 "{"
4415 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4416 " \"external_crx\": \"RandomExtension.crx\","
4417 " \"external_version\": \"1.0\","
4418 " \"is_bookmark_app\": true"
4419 " }"
4420 "}";
4421 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
[email protected]7425d7df2012-11-28 14:35:424422
4423 // Test is_from_webstore.
4424 MockProviderVisitor from_webstore_visitor(
4425 base_path, Extension::FROM_WEBSTORE);
4426 json_data =
4427 "{"
4428 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4429 " \"external_crx\": \"RandomExtension.crx\","
4430 " \"external_version\": \"1.0\","
4431 " \"is_from_webstore\": true"
4432 " }"
4433 "}";
4434 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
[email protected]e18236b2009-06-22 21:32:104435}
[email protected]36a784c2009-06-23 06:21:084436
[email protected]c6d474f82009-12-16 21:11:064437// Test loading good extensions from the profile directory.
[email protected]d9a61e12012-11-14 02:43:474438TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
[email protected]6884a802012-08-07 03:55:224439 // Ensure we're testing in "en" and leave global state untouched.
4440 extension_l10n_util::ScopedLocaleForTest testLocale("en");
4441
[email protected]c6d474f82009-12-16 21:11:064442 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:354443 FilePath source_install_dir = data_dir_
[email protected]c6d474f82009-12-16 21:11:064444 .AppendASCII("l10n");
4445 FilePath pref_path = source_install_dir.AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:004446 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]c6d474f82009-12-16 21:11:064447
4448 service_->Init();
[email protected]c6d474f82009-12-16 21:11:064449
4450 ASSERT_EQ(3u, loaded_.size());
4451
4452 // This was equal to "sr" on load.
4453 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
4454
4455 // These are untouched by re-localization.
4456 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
4457 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
4458
4459 // This one starts with Serbian name, and gets re-localized into English.
4460 EXPECT_EQ("My name is simple.", loaded_[0]->name());
4461
4462 // These are untouched by re-localization.
4463 EXPECT_EQ("My name is simple.", loaded_[1]->name());
4464 EXPECT_EQ("no l10n", loaded_[2]->name());
4465}
4466
[email protected]6c2381d2011-10-19 02:52:534467class ExtensionsReadyRecorder : public content::NotificationObserver {
[email protected]f0488f2f2009-07-01 05:25:224468 public:
4469 ExtensionsReadyRecorder() : ready_(false) {
[email protected]432115822011-07-10 15:52:274470 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
[email protected]ad50def52011-10-19 23:17:074471 content::NotificationService::AllSources());
[email protected]f0488f2f2009-07-01 05:25:224472 }
4473
4474 void set_ready(bool value) { ready_ = value; }
4475 bool ready() { return ready_; }
4476
4477 private:
[email protected]432115822011-07-10 15:52:274478 virtual void Observe(int type,
[email protected]6c2381d2011-10-19 02:52:534479 const content::NotificationSource& source,
4480 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:274481 switch (type) {
4482 case chrome::NOTIFICATION_EXTENSIONS_READY:
[email protected]f0488f2f2009-07-01 05:25:224483 ready_ = true;
4484 break;
4485 default:
4486 NOTREACHED();
4487 }
4488 }
4489
[email protected]6c2381d2011-10-19 02:52:534490 content::NotificationRegistrar registrar_;
[email protected]f0488f2f2009-07-01 05:25:224491 bool ready_;
4492};
4493
[email protected]36a784c2009-06-23 06:21:084494// Test that we get enabled/disabled correctly for all the pref/command-line
[email protected]eaa7dd182010-12-14 11:09:004495// combinations. We don't want to derive from the ExtensionServiceTest class
4496// for this test, so we use ExtensionServiceTestSimple.
[email protected]f0488f2f2009-07-01 05:25:224497//
4498// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
4499// enabled or not.
[email protected]39fdf5202012-11-14 00:38:174500TEST(ExtensionServiceTestSimple, Enabledness) {
[email protected]5a24d2b2012-11-14 20:38:314501 // Make sure the PluginService singleton is destroyed at the end of the test.
[email protected]39fdf5202012-11-14 00:38:174502 base::ShadowingAtExitManager at_exit_manager;
[email protected]5a24d2b2012-11-14 20:38:314503
[email protected]ed8ee722011-04-22 06:49:444504 ExtensionErrorReporter::Init(false); // no noisy errors
[email protected]f0488f2f2009-07-01 05:25:224505 ExtensionsReadyRecorder recorder;
[email protected]aa96d3a2010-08-21 08:45:254506 scoped_ptr<TestingProfile> profile(new TestingProfile());
[email protected]36a784c2009-06-23 06:21:084507 MessageLoop loop;
[email protected]c38831a12011-10-28 12:44:494508 content::TestBrowserThread ui_thread(BrowserThread::UI, &loop);
4509 content::TestBrowserThread file_thread(BrowserThread::FILE, &loop);
[email protected]36a784c2009-06-23 06:21:084510 scoped_ptr<CommandLine> command_line;
[email protected]aa96d3a2010-08-21 08:45:254511 FilePath install_dir = profile->GetPath()
[email protected]eaa7dd182010-12-14 11:09:004512 .AppendASCII(ExtensionService::kInstallDirectoryName);
[email protected]be5a6db2012-11-13 14:39:114513
[email protected]0b300172012-09-27 16:11:524514 webkit::npapi::MockPluginList plugin_list;
[email protected]eb6c7ef2011-12-12 23:12:204515 PluginService::GetInstance()->SetPluginListForTesting(&plugin_list);
[email protected]36a784c2009-06-23 06:21:084516
[email protected]6d60703b2009-08-29 01:29:234517 // By default, we are enabled.
[email protected]947446b2010-10-21 03:36:314518 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
[email protected]bd306722012-07-11 20:43:594519 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244520 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084521 CreateExtensionService(
4522 command_line.get(),
4523 install_dir,
4524 false);
[email protected]6d60703b2009-08-29 01:29:234525 EXPECT_TRUE(service->extensions_enabled());
4526 service->Init();
[email protected]b8f50ce2012-11-17 12:37:574527 loop.RunUntilIdle();
[email protected]6d60703b2009-08-29 01:29:234528 EXPECT_TRUE(recorder.ready());
4529
4530 // If either the command line or pref is set, we are disabled.
4531 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:254532 profile.reset(new TestingProfile());
[email protected]6d60703b2009-08-29 01:29:234533 command_line->AppendSwitch(switches::kDisableExtensions);
[email protected]bd306722012-07-11 20:43:594534 service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244535 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084536 CreateExtensionService(
4537 command_line.get(),
4538 install_dir,
4539 false);
[email protected]36a784c2009-06-23 06:21:084540 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:224541 service->Init();
[email protected]b8f50ce2012-11-17 12:37:574542 loop.RunUntilIdle();
[email protected]f0488f2f2009-07-01 05:25:224543 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:084544
[email protected]f0488f2f2009-07-01 05:25:224545 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:254546 profile.reset(new TestingProfile());
4547 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]bd306722012-07-11 20:43:594548 service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244549 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084550 CreateExtensionService(
4551 command_line.get(),
4552 install_dir,
4553 false);
[email protected]6d60703b2009-08-29 01:29:234554 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:224555 service->Init();
[email protected]b8f50ce2012-11-17 12:37:574556 loop.RunUntilIdle();
[email protected]f0488f2f2009-07-01 05:25:224557 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:084558
[email protected]f0488f2f2009-07-01 05:25:224559 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:254560 profile.reset(new TestingProfile());
4561 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]947446b2010-10-21 03:36:314562 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
[email protected]bd306722012-07-11 20:43:594563 service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244564 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084565 CreateExtensionService(
4566 command_line.get(),
4567 install_dir,
4568 false);
[email protected]6d60703b2009-08-29 01:29:234569 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:224570 service->Init();
[email protected]b8f50ce2012-11-17 12:37:574571 loop.RunUntilIdle();
[email protected]f0488f2f2009-07-01 05:25:224572 EXPECT_TRUE(recorder.ready());
[email protected]7e1951a2010-09-30 10:22:204573
4574 // Explicitly delete all the resources used in this test.
4575 profile.reset();
4576 service = NULL;
[email protected]060d4972012-07-19 17:22:394577 // Execute any pending deletion tasks.
[email protected]b8f50ce2012-11-17 12:37:574578 loop.RunUntilIdle();
[email protected]5a24d2b2012-11-14 20:38:314579
4580 // Ensure that even if the PluginService is re-used for a later test, it
4581 // won't still hold a reference to the stack position of our MockPluginList.
4582 // See crbug.com/159754.
4583 PluginService::GetInstance()->SetPluginListForTesting(NULL);
[email protected]36a784c2009-06-23 06:21:084584}
[email protected]24b538a2010-02-27 01:22:444585
4586// Test loading extensions that require limited and unlimited storage quotas.
[email protected]d9a61e12012-11-14 02:43:474587TEST_F(ExtensionServiceTest, StorageQuota) {
[email protected]eaa7dd182010-12-14 11:09:004588 InitializeEmptyExtensionService();
[email protected]24b538a2010-02-27 01:22:444589
[email protected]e85e34c32011-04-13 18:38:354590 FilePath extensions_path = data_dir_
[email protected]24b538a2010-02-27 01:22:444591 .AppendASCII("storage_quota");
4592
[email protected]e85e34c32011-04-13 18:38:354593 FilePath limited_quota_ext =
4594 extensions_path.AppendASCII("limited_quota")
[email protected]24b538a2010-02-27 01:22:444595 .AppendASCII("1.0");
[email protected]03b612f2010-08-13 21:09:214596
4597 // The old permission name for unlimited quota was "unlimited_storage", but
4598 // we changed it to "unlimitedStorage". This tests both versions.
[email protected]e85e34c32011-04-13 18:38:354599 FilePath unlimited_quota_ext =
4600 extensions_path.AppendASCII("unlimited_quota")
[email protected]24b538a2010-02-27 01:22:444601 .AppendASCII("1.0");
[email protected]e85e34c32011-04-13 18:38:354602 FilePath unlimited_quota_ext2 =
4603 extensions_path.AppendASCII("unlimited_quota")
[email protected]03b612f2010-08-13 21:09:214604 .AppendASCII("2.0");
[email protected]d8c8f25f2011-11-02 18:18:014605 extensions::UnpackedInstaller::Create(service_)->Load(limited_quota_ext);
4606 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext);
4607 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext2);
[email protected]b8f50ce2012-11-17 12:37:574608 loop_.RunUntilIdle();
[email protected]24b538a2010-02-27 01:22:444609
[email protected]03b612f2010-08-13 21:09:214610 ASSERT_EQ(3u, loaded_.size());
[email protected]24b538a2010-02-27 01:22:444611 EXPECT_TRUE(profile_.get());
4612 EXPECT_FALSE(profile_->IsOffTheRecord());
[email protected]7c5f2ec2011-05-26 19:15:264613 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4614 loaded_[0]->url()));
4615 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4616 loaded_[1]->url()));
4617 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4618 loaded_[2]->url()));
[email protected]24b538a2010-02-27 01:22:444619}
[email protected]1952c7d2010-03-04 23:48:344620
[email protected]d8c8f25f2011-11-02 18:18:014621// Tests ComponentLoader::Add().
[email protected]d9a61e12012-11-14 02:43:474622TEST_F(ExtensionServiceTest, ComponentExtensions) {
[email protected]eaa7dd182010-12-14 11:09:004623 InitializeEmptyExtensionService();
[email protected]1952c7d2010-03-04 23:48:344624
[email protected]f0b97f12010-10-11 21:44:354625 // Component extensions should work even when extensions are disabled.
4626 set_extensions_enabled(false);
4627
[email protected]e85e34c32011-04-13 18:38:354628 FilePath path = data_dir_
[email protected]1952c7d2010-03-04 23:48:344629 .AppendASCII("good")
4630 .AppendASCII("Extensions")
4631 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4632 .AppendASCII("1.0.0.0");
4633
4634 std::string manifest;
4635 ASSERT_TRUE(file_util::ReadFileToString(
4636 path.Append(Extension::kManifestFilename), &manifest));
4637
[email protected]d8c8f25f2011-11-02 18:18:014638 service_->component_loader()->Add(manifest, path);
[email protected]1952c7d2010-03-04 23:48:344639 service_->Init();
4640
4641 // Note that we do not pump messages -- the extension should be loaded
4642 // immediately.
4643
4644 EXPECT_EQ(0u, GetErrors().size());
4645 ASSERT_EQ(1u, loaded_.size());
4646 EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location());
4647 EXPECT_EQ(1u, service_->extensions()->size());
4648
[email protected]8c484b742012-11-29 06:05:364649 // Component extensions get a prefs entry on first install.
4650 ValidatePrefKeyCount(1);
[email protected]1952c7d2010-03-04 23:48:344651
4652 // Reload all extensions, and make sure it comes back.
[email protected]8f512c72011-11-22 21:02:504653 std::string extension_id = (*service_->extensions()->begin())->id();
[email protected]1952c7d2010-03-04 23:48:344654 loaded_.clear();
4655 service_->ReloadExtensions();
4656 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:504657 EXPECT_EQ(extension_id, (*service_->extensions()->begin())->id());
[email protected]1952c7d2010-03-04 23:48:344658}
[email protected]145a317b2011-04-12 16:03:464659
[email protected]90310d92011-04-17 07:35:044660namespace {
[email protected]65f173552012-06-28 22:43:584661 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
4662 virtual syncer::SyncError ProcessSyncChanges(
[email protected]3bdba0d2011-08-23 07:17:304663 const tracked_objects::Location& from_here,
[email protected]65f173552012-06-28 22:43:584664 const syncer::SyncChangeList& change_list) OVERRIDE {
4665 return syncer::SyncError();
[email protected]3bdba0d2011-08-23 07:17:304666 }
4667 };
[email protected]90310d92011-04-17 07:35:044668}
4669
[email protected]d9a61e12012-11-14 02:43:474670TEST_F(ExtensionServiceTest, GetSyncData) {
[email protected]b05fb9ff2011-04-23 00:07:564671 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504672 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]45b6fee2011-05-03 09:41:314673 const Extension* extension = service_->GetInstalledExtension(good_crx);
[email protected]b05fb9ff2011-04-23 00:07:564674 ASSERT_TRUE(extension);
[email protected]85fc9202011-05-05 00:04:594675
[email protected]cb02f612012-06-27 03:15:504676 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324677 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584678 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4679 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304680
[email protected]a4a147652012-07-03 23:41:324681 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304682 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204683 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304684 EXPECT_EQ(extension->id(), data.id());
4685 EXPECT_FALSE(data.uninstalled());
4686 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
4687 EXPECT_EQ(service_->IsIncognitoEnabled(good_crx), data.incognito_enabled());
4688 EXPECT_TRUE(data.version().Equals(*extension->version()));
4689 EXPECT_EQ(extension->update_url(), data.update_url());
4690 EXPECT_EQ(extension->name(), data.name());
[email protected]b05fb9ff2011-04-23 00:07:564691}
4692
[email protected]d9a61e12012-11-14 02:43:474693TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
[email protected]45b6fee2011-05-03 09:41:314694 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504695 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]45b6fee2011-05-03 09:41:314696 TerminateExtension(good_crx);
[email protected]85fc9202011-05-05 00:04:594697 const Extension* extension = service_->GetInstalledExtension(good_crx);
4698 ASSERT_TRUE(extension);
[email protected]3bdba0d2011-08-23 07:17:304699
4700 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504701 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324702 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584703 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4704 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304705
[email protected]a4a147652012-07-03 23:41:324706 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304707 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204708 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304709 EXPECT_EQ(extension->id(), data.id());
4710 EXPECT_FALSE(data.uninstalled());
4711 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
4712 EXPECT_EQ(service_->IsIncognitoEnabled(good_crx), data.incognito_enabled());
4713 EXPECT_TRUE(data.version().Equals(*extension->version()));
4714 EXPECT_EQ(extension->update_url(), data.update_url());
4715 EXPECT_EQ(extension->name(), data.name());
[email protected]45b6fee2011-05-03 09:41:314716}
4717
[email protected]d9a61e12012-11-14 02:43:474718TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
[email protected]b05fb9ff2011-04-23 00:07:564719 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504720 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]85fc9202011-05-05 00:04:594721 const Extension* extension = service_->GetInstalledExtension(good_crx);
4722 ASSERT_TRUE(extension);
[email protected]3bdba0d2011-08-23 07:17:304723
4724 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324725 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584726 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4727 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304728
[email protected]a4a147652012-07-03 23:41:324729 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304730 ASSERT_EQ(list.size(), 0U);
[email protected]b05fb9ff2011-04-23 00:07:564731}
4732
[email protected]d9a61e12012-11-14 02:43:474733TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
[email protected]b05fb9ff2011-04-23 00:07:564734 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504735 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]85fc9202011-05-05 00:04:594736 const Extension* extension = service_->GetInstalledExtension(good_crx);
4737 ASSERT_TRUE(extension);
[email protected]b05fb9ff2011-04-23 00:07:564738
[email protected]3bdba0d2011-08-23 07:17:304739 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504740 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324741 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584742 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4743 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304744
[email protected]b05fb9ff2011-04-23 00:07:564745 {
[email protected]a4a147652012-07-03 23:41:324746 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304747 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204748 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304749 EXPECT_TRUE(data.enabled());
4750 EXPECT_FALSE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564751 }
4752
[email protected]44d62b62012-04-11 00:06:034753 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
[email protected]b05fb9ff2011-04-23 00:07:564754 {
[email protected]a4a147652012-07-03 23:41:324755 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304756 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204757 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304758 EXPECT_FALSE(data.enabled());
4759 EXPECT_FALSE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564760 }
4761
4762 service_->SetIsIncognitoEnabled(good_crx, true);
4763 {
[email protected]a4a147652012-07-03 23:41:324764 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304765 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204766 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304767 EXPECT_FALSE(data.enabled());
4768 EXPECT_TRUE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564769 }
4770
4771 service_->EnableExtension(good_crx);
4772 {
[email protected]a4a147652012-07-03 23:41:324773 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304774 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204775 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304776 EXPECT_TRUE(data.enabled());
4777 EXPECT_TRUE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564778 }
4779}
4780
[email protected]d9a61e12012-11-14 02:43:474781TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
[email protected]e8b0f252012-05-05 09:44:424782 InitializeEmptyExtensionService();
4783 InstallCRXWithLocation(data_dir_.AppendASCII("good.crx"),
4784 Extension::EXTERNAL_PREF, INSTALL_NEW);
4785 const Extension* extension = service_->GetInstalledExtension(good_crx);
4786 ASSERT_TRUE(extension);
4787
4788 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504789 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324790 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584791 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4792 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]e8b0f252012-05-05 09:44:424793
4794 UninstallExtension(good_crx, false);
4795 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
4796
4797 sync_pb::EntitySpecifics specifics;
4798 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
4799 sync_pb::ExtensionSpecifics* extension_specifics =
4800 app_specifics->mutable_extension();
4801 extension_specifics->set_id(good_crx);
4802 extension_specifics->set_version("1.0");
4803 extension_specifics->set_enabled(true);
4804
[email protected]65f173552012-06-28 22:43:584805 syncer::SyncData sync_data =
4806 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264807 syncer::SyncChange sync_change(FROM_HERE,
4808 syncer::SyncChange::ACTION_UPDATE,
4809 sync_data);
[email protected]65f173552012-06-28 22:43:584810 syncer::SyncChangeList list(1);
[email protected]e8b0f252012-05-05 09:44:424811 list[0] = sync_change;
4812
4813 service_->ProcessSyncChanges(FROM_HERE, list);
4814 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
4815}
4816
[email protected]d9a61e12012-11-14 02:43:474817TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
[email protected]168389f2011-12-20 17:12:484818 InitializeEmptyExtensionService();
4819 const Extension* app =
4820 PackAndInstallCRX(data_dir_.AppendASCII("app"), INSTALL_NEW);
4821 ASSERT_TRUE(app);
4822 ASSERT_TRUE(app->is_app());
4823
4824 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324825 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584826 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4827 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]168389f2011-12-20 17:12:484828
[email protected]36b643212012-09-07 12:53:004829 syncer::StringOrdinal initial_ordinal =
4830 syncer::StringOrdinal::CreateInitialOrdinal();
[email protected]168389f2011-12-20 17:12:484831 {
[email protected]a4a147652012-07-03 23:41:324832 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484833 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204834
4835 extensions::AppSyncData app_sync_data(list[0]);
[email protected]36b643212012-09-07 12:53:004836 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.app_launch_ordinal()));
4837 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
[email protected]168389f2011-12-20 17:12:484838 }
4839
[email protected]fb82dcd2012-03-21 14:15:464840 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
4841 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
[email protected]168389f2011-12-20 17:12:484842 {
[email protected]a4a147652012-07-03 23:41:324843 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484844 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204845
4846 extensions::AppSyncData app_sync_data(list[0]);
4847 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
[email protected]36b643212012-09-07 12:53:004848 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
[email protected]168389f2011-12-20 17:12:484849 }
4850
[email protected]fb82dcd2012-03-21 14:15:464851 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
[email protected]168389f2011-12-20 17:12:484852 {
[email protected]a4a147652012-07-03 23:41:324853 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484854 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204855
4856 extensions::AppSyncData app_sync_data(list[0]);
4857 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
4858 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal()));
[email protected]168389f2011-12-20 17:12:484859 }
4860}
4861
[email protected]d9a61e12012-11-14 02:43:474862TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
[email protected]168389f2011-12-20 17:12:484863 InitializeEmptyExtensionService();
4864 const size_t kAppCount = 3;
4865 const Extension* apps[kAppCount];
4866 apps[0] = PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
4867 apps[1] = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
4868 apps[2] = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
4869 for (size_t i = 0; i < kAppCount; ++i) {
4870 ASSERT_TRUE(apps[i]);
4871 ASSERT_TRUE(apps[i]->is_app());
4872 }
4873
4874 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324875 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584876 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4877 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]168389f2011-12-20 17:12:484878
4879 service_->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
4880 {
[email protected]a4a147652012-07-03 23:41:324881 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484882 ASSERT_EQ(list.size(), 3U);
[email protected]5db9ada2012-04-11 13:48:204883
4884 extensions::AppSyncData data[kAppCount];
[email protected]bb05cae12012-09-06 00:37:524885 for (size_t i = 0; i < kAppCount; ++i) {
[email protected]5db9ada2012-04-11 13:48:204886 data[i] = extensions::AppSyncData(list[i]);
4887 }
[email protected]168389f2011-12-20 17:12:484888
4889 // The sync data is not always in the same order our apps were installed in,
4890 // so we do that sorting here so we can make sure the values are changed as
4891 // expected.
[email protected]36b643212012-09-07 12:53:004892 syncer::StringOrdinal app_launch_ordinals[kAppCount];
[email protected]168389f2011-12-20 17:12:484893 for (size_t i = 0; i < kAppCount; ++i) {
4894 for (size_t j = 0; j < kAppCount; ++j) {
4895 if (apps[i]->id() == data[j].id())
4896 app_launch_ordinals[i] = data[j].app_launch_ordinal();
4897 }
4898 }
4899
4900 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
4901 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
4902 }
4903}
4904
[email protected]d9a61e12012-11-14 02:43:474905TEST_F(ExtensionServiceTest, GetSyncDataList) {
[email protected]b05fb9ff2011-04-23 00:07:564906 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504907 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4908 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
4909 InstallCRX(data_dir_.AppendASCII("theme.crx"), INSTALL_NEW);
4910 InstallCRX(data_dir_.AppendASCII("theme2.crx"), INSTALL_NEW);
[email protected]b05fb9ff2011-04-23 00:07:564911
[email protected]3bdba0d2011-08-23 07:17:304912 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324913 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584914 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4915 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]cb02f612012-06-27 03:15:504916 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324917 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584918 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4919 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304920
[email protected]44d62b62012-04-11 00:06:034921 service_->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
[email protected]45b6fee2011-05-03 09:41:314922 TerminateExtension(theme2_crx);
[email protected]b05fb9ff2011-04-23 00:07:564923
[email protected]a4a147652012-07-03 23:41:324924 EXPECT_EQ(0u, service_->GetAllSyncData(syncer::APPS).size());
4925 EXPECT_EQ(2u, service_->GetAllSyncData(syncer::EXTENSIONS).size());
[email protected]b05fb9ff2011-04-23 00:07:564926}
4927
[email protected]d9a61e12012-11-14 02:43:474928TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
[email protected]90310d92011-04-17 07:35:044929 InitializeEmptyExtensionService();
[email protected]3bdba0d2011-08-23 07:17:304930 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504931 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324932 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584933 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4934 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:044935
[email protected]3bdba0d2011-08-23 07:17:304936 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:364937 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:304938 ext_specifics->set_id(good_crx);
4939 ext_specifics->set_version("1.0");
[email protected]65f173552012-06-28 22:43:584940 syncer::SyncData sync_data =
4941 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264942 syncer::SyncChange sync_change(FROM_HERE,
4943 syncer::SyncChange::ACTION_DELETE,
4944 sync_data);
[email protected]65f173552012-06-28 22:43:584945 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:304946 list[0] = sync_change;
[email protected]90310d92011-04-17 07:35:044947
4948 // Should do nothing.
[email protected]3bdba0d2011-08-23 07:17:304949 service_->ProcessSyncChanges(FROM_HERE, list);
4950 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
[email protected]90310d92011-04-17 07:35:044951
4952 // Install the extension.
4953 FilePath extension_path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:504954 InstallCRX(extension_path, INSTALL_NEW);
[email protected]90310d92011-04-17 07:35:044955 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
4956
4957 // Should uninstall the extension.
[email protected]3bdba0d2011-08-23 07:17:304958 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:044959 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
4960
4961 // Should again do nothing.
[email protected]3bdba0d2011-08-23 07:17:304962 service_->ProcessSyncChanges(FROM_HERE, list);
4963 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
[email protected]90310d92011-04-17 07:35:044964}
4965
[email protected]d9a61e12012-11-14 02:43:474966TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
[email protected]96e989b2011-08-30 19:35:064967 InitializeEmptyExtensionService();
4968
4969 // Install the extension.
4970 FilePath extension_path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:504971 InstallCRX(extension_path, INSTALL_NEW);
[email protected]96e989b2011-08-30 19:35:064972 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
4973
4974 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:364975 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
[email protected]96e989b2011-08-30 19:35:064976 sync_pb::ExtensionSpecifics* extension_specifics =
4977 app_specifics->mutable_extension();
4978 extension_specifics->set_id(good_crx);
4979 extension_specifics->set_version(
4980 service_->GetInstalledExtension(good_crx)->version()->GetString());
4981
4982 {
4983 extension_specifics->set_enabled(true);
[email protected]65f173552012-06-28 22:43:584984 syncer::SyncData sync_data =
4985 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264986 syncer::SyncChange sync_change(FROM_HERE,
4987 syncer::SyncChange::ACTION_DELETE,
4988 sync_data);
[email protected]65f173552012-06-28 22:43:584989 syncer::SyncChangeList list(1);
[email protected]96e989b2011-08-30 19:35:064990 list[0] = sync_change;
4991
4992 // Should do nothing
4993 service_->ProcessSyncChanges(FROM_HERE, list);
4994 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
4995 }
4996
4997 {
4998 extension_specifics->set_enabled(false);
[email protected]65f173552012-06-28 22:43:584999 syncer::SyncData sync_data =
5000 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265001 syncer::SyncChange sync_change(FROM_HERE,
5002 syncer::SyncChange::ACTION_UPDATE,
5003 sync_data);
[email protected]65f173552012-06-28 22:43:585004 syncer::SyncChangeList list(1);
[email protected]96e989b2011-08-30 19:35:065005 list[0] = sync_change;
5006
5007 // Should again do nothing.
5008 service_->ProcessSyncChanges(FROM_HERE, list);
5009 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
5010 }
5011}
5012
[email protected]d9a61e12012-11-14 02:43:475013TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
[email protected]90310d92011-04-17 07:35:045014 InitializeEmptyExtensionService();
[email protected]406b5a92011-11-08 11:58:265015 InitializeExtensionProcessManager();
[email protected]3bdba0d2011-08-23 07:17:305016 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:505017 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:325018 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:585019 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5020 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:045021
[email protected]8f512c72011-11-22 21:02:505022 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]90310d92011-04-17 07:35:045023 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5024 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
5025
[email protected]3bdba0d2011-08-23 07:17:305026 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:365027 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:305028 ext_specifics->set_id(good_crx);
5029 ext_specifics->set_version(
5030 service_->GetInstalledExtension(good_crx)->version()->GetString());
5031 ext_specifics->set_enabled(false);
[email protected]90310d92011-04-17 07:35:045032
[email protected]3bdba0d2011-08-23 07:17:305033 {
[email protected]65f173552012-06-28 22:43:585034 syncer::SyncData sync_data =
5035 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265036 syncer::SyncChange sync_change(FROM_HERE,
5037 syncer::SyncChange::ACTION_UPDATE,
5038 sync_data);
[email protected]65f173552012-06-28 22:43:585039 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305040 list[0] = sync_change;
5041 service_->ProcessSyncChanges(FROM_HERE, list);
5042 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5043 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
5044 }
[email protected]90310d92011-04-17 07:35:045045
[email protected]3bdba0d2011-08-23 07:17:305046 {
5047 ext_specifics->set_enabled(true);
5048 ext_specifics->set_incognito_enabled(true);
[email protected]65f173552012-06-28 22:43:585049 syncer::SyncData sync_data =
5050 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265051 syncer::SyncChange sync_change(FROM_HERE,
5052 syncer::SyncChange::ACTION_UPDATE,
5053 sync_data);
[email protected]65f173552012-06-28 22:43:585054 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305055 list[0] = sync_change;
5056 service_->ProcessSyncChanges(FROM_HERE, list);
5057 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5058 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
5059 }
[email protected]90310d92011-04-17 07:35:045060
[email protected]3bdba0d2011-08-23 07:17:305061 {
5062 ext_specifics->set_enabled(false);
5063 ext_specifics->set_incognito_enabled(true);
[email protected]65f173552012-06-28 22:43:585064 syncer::SyncData sync_data =
5065 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265066 syncer::SyncChange sync_change(FROM_HERE,
5067 syncer::SyncChange::ACTION_UPDATE,
5068 sync_data);
[email protected]65f173552012-06-28 22:43:585069 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305070 list[0] = sync_change;
5071 service_->ProcessSyncChanges(FROM_HERE, list);
5072 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5073 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
5074 }
[email protected]90310d92011-04-17 07:35:045075
5076 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5077}
5078
[email protected]d9a61e12012-11-14 02:43:475079TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
[email protected]fa2416f2011-05-03 08:41:205080 InitializeExtensionServiceWithUpdater();
[email protected]3bdba0d2011-08-23 07:17:305081 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:505082 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:325083 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:585084 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5085 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]fa2416f2011-05-03 08:41:205086
[email protected]8f512c72011-11-22 21:02:505087 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:205088 TerminateExtension(good_crx);
5089 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5090 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
5091
[email protected]3bdba0d2011-08-23 07:17:305092 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:365093 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:305094 ext_specifics->set_id(good_crx);
5095 ext_specifics->set_version(
5096 service_->GetInstalledExtension(good_crx)->version()->GetString());
5097 ext_specifics->set_enabled(false);
5098 ext_specifics->set_incognito_enabled(true);
[email protected]65f173552012-06-28 22:43:585099 syncer::SyncData sync_data =
5100 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265101 syncer::SyncChange sync_change(FROM_HERE,
5102 syncer::SyncChange::ACTION_UPDATE,
5103 sync_data);
[email protected]65f173552012-06-28 22:43:585104 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305105 list[0] = sync_change;
5106
5107 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]fa2416f2011-05-03 08:41:205108 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5109 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
5110
5111 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5112}
5113
[email protected]d9a61e12012-11-14 02:43:475114TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
[email protected]90310d92011-04-17 07:35:045115 InitializeExtensionServiceWithUpdater();
[email protected]314c3e22012-02-21 03:57:425116 InitializeRequestContext();
[email protected]3bdba0d2011-08-23 07:17:305117 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:505118 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:325119 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:585120 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5121 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:045122
[email protected]8f512c72011-11-22 21:02:505123 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]90310d92011-04-17 07:35:045124 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5125 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
5126
[email protected]3bdba0d2011-08-23 07:17:305127 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:365128 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:305129 ext_specifics->set_id(good_crx);
5130 ext_specifics->set_enabled(true);
[email protected]90310d92011-04-17 07:35:045131
[email protected]3bdba0d2011-08-23 07:17:305132 {
5133 ext_specifics->set_version(
5134 service_->GetInstalledExtension(good_crx)->version()->GetString());
[email protected]65f173552012-06-28 22:43:585135 syncer::SyncData sync_data =
5136 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265137 syncer::SyncChange sync_change(FROM_HERE,
5138 syncer::SyncChange::ACTION_UPDATE,
5139 sync_data);
[email protected]65f173552012-06-28 22:43:585140 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305141 list[0] = sync_change;
5142
5143 // Should do nothing if extension version == sync version.
5144 service_->ProcessSyncChanges(FROM_HERE, list);
5145 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5146 }
[email protected]90310d92011-04-17 07:35:045147
5148 // Should do nothing if extension version > sync version (but see
[email protected]3bdba0d2011-08-23 07:17:305149 // the TODO in ProcessExtensionSyncData).
[email protected]90310d92011-04-17 07:35:045150 {
[email protected]3bdba0d2011-08-23 07:17:305151 ext_specifics->set_version("0.0.0.0");
[email protected]65f173552012-06-28 22:43:585152 syncer::SyncData sync_data =
5153 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265154 syncer::SyncChange sync_change(FROM_HERE,
5155 syncer::SyncChange::ACTION_UPDATE,
5156 sync_data);
[email protected]65f173552012-06-28 22:43:585157 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305158 list[0] = sync_change;
5159
5160 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:045161 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5162 }
5163
5164 // Should kick off an update if extension version < sync version.
5165 {
[email protected]3bdba0d2011-08-23 07:17:305166 ext_specifics->set_version("9.9.9.9");
[email protected]65f173552012-06-28 22:43:585167 syncer::SyncData sync_data =
5168 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265169 syncer::SyncChange sync_change(FROM_HERE,
5170 syncer::SyncChange::ACTION_UPDATE,
5171 sync_data);
[email protected]65f173552012-06-28 22:43:585172 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305173 list[0] = sync_change;
5174
5175 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:045176 EXPECT_TRUE(service_->updater()->WillCheckSoon());
5177 }
5178
5179 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5180}
5181
[email protected]d9a61e12012-11-14 02:43:475182TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
[email protected]90310d92011-04-17 07:35:045183 InitializeExtensionServiceWithUpdater();
[email protected]314c3e22012-02-21 03:57:425184 InitializeRequestContext();
[email protected]3bdba0d2011-08-23 07:17:305185 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:505186 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:325187 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:585188 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5189 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:045190
[email protected]3bdba0d2011-08-23 07:17:305191 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:365192 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:305193 ext_specifics->set_id(good_crx);
5194 ext_specifics->set_enabled(false);
5195 ext_specifics->set_incognito_enabled(true);
5196 ext_specifics->set_update_url("http://www.google.com/");
5197 ext_specifics->set_version("1.2.3.4");
[email protected]65f173552012-06-28 22:43:585198 syncer::SyncData sync_data =
5199 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265200 syncer::SyncChange sync_change(FROM_HERE,
5201 syncer::SyncChange::ACTION_UPDATE,
5202 sync_data);
[email protected]65f173552012-06-28 22:43:585203 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305204 list[0] = sync_change;
5205
[email protected]90310d92011-04-17 07:35:045206
[email protected]06f92562011-04-29 19:27:315207 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
[email protected]81b14cc2011-04-29 00:39:375208 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
[email protected]3bdba0d2011-08-23 07:17:305209 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:045210 EXPECT_TRUE(service_->updater()->WillCheckSoon());
[email protected]06f92562011-04-29 19:27:315211 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
[email protected]81b14cc2011-04-29 00:39:375212 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
[email protected]90310d92011-04-17 07:35:045213
[email protected]3f213ad2012-07-26 23:39:415214 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065215 EXPECT_TRUE((info = service_->pending_extension_manager()->
5216 GetById(good_crx)));
5217 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
5218 EXPECT_TRUE(info->is_from_sync());
5219 EXPECT_TRUE(info->install_silently());
5220 EXPECT_EQ(Extension::INTERNAL, info->install_source());
[email protected]90310d92011-04-17 07:35:045221 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
5222}
5223
[email protected]d9a61e12012-11-14 02:43:475224TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
[email protected]8a87a5332011-08-11 17:54:595225 InitializeEmptyExtensionService();
5226
5227 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:505228 InstallCRX(path, INSTALL_NEW);
[email protected]8a87a5332011-08-11 17:54:595229 ValidatePrefKeyCount(1u);
5230 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5231 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
5232
[email protected]3f213ad2012-07-26 23:39:415233 extensions::PendingExtensionManager* pending =
5234 service_->pending_extension_manager();
[email protected]8a87a5332011-08-11 17:54:595235 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5236
5237 // Skip install when the location is the same.
[email protected]9060d8b02012-01-13 02:14:305238 EXPECT_FALSE(
5239 service_->OnExternalExtensionUpdateUrlFound(
5240 kGoodId, GURL(kGoodUpdateURL), Extension::INTERNAL));
[email protected]8a87a5332011-08-11 17:54:595241 EXPECT_FALSE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:305242
5243 // Install when the location has higher priority.
5244 EXPECT_TRUE(
5245 service_->OnExternalExtensionUpdateUrlFound(
5246 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_POLICY_DOWNLOAD));
[email protected]8a87a5332011-08-11 17:54:595247 EXPECT_TRUE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:305248
5249 // Try the low priority again. Should be rejected.
5250 EXPECT_FALSE(
5251 service_->OnExternalExtensionUpdateUrlFound(
5252 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD));
5253 // The existing record should still be present in the pending extension
5254 // manager.
5255 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5256
[email protected]8a87a5332011-08-11 17:54:595257 pending->Remove(kGoodId);
[email protected]9060d8b02012-01-13 02:14:305258
5259 // Skip install when the location has the same priority as the installed
5260 // location.
5261 EXPECT_FALSE(service_->OnExternalExtensionUpdateUrlFound(
5262 kGoodId, GURL(kGoodUpdateURL), Extension::INTERNAL));
5263
[email protected]8a87a5332011-08-11 17:54:595264 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5265}
5266
[email protected]d9a61e12012-11-14 02:43:475267TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
[email protected]12126d372012-07-11 18:40:535268 Version older_version("0.1.0.0");
5269 Version newer_version("2.0.0.0");
[email protected]9060d8b02012-01-13 02:14:305270
5271 // We don't want the extension to be installed. A path that doesn't
5272 // point to a valid CRX ensures this.
5273 const FilePath kInvalidPathToCrx = FilePath();
5274
5275 const int kCreationFlags = 0;
5276 const bool kDontMarkAcknowledged = false;
5277
5278 InitializeEmptyExtensionService();
5279
5280 // The test below uses install source constants to test that
5281 // priority is enforced. It assumes a specific ranking of install
5282 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
5283 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
5284 // The following assertions verify these assumptions:
5285 ASSERT_EQ(Extension::EXTERNAL_REGISTRY,
5286 Extension::GetHigherPriorityLocation(Extension::EXTERNAL_REGISTRY,
5287 Extension::EXTERNAL_PREF));
5288 ASSERT_EQ(Extension::EXTERNAL_REGISTRY,
5289 Extension::GetHigherPriorityLocation(Extension::EXTERNAL_REGISTRY,
5290 Extension::INTERNAL));
5291 ASSERT_EQ(Extension::EXTERNAL_PREF,
5292 Extension::GetHigherPriorityLocation(Extension::EXTERNAL_PREF,
5293 Extension::INTERNAL));
5294
[email protected]3f213ad2012-07-26 23:39:415295 extensions::PendingExtensionManager* pending =
5296 service_->pending_extension_manager();
[email protected]9060d8b02012-01-13 02:14:305297 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5298
5299 // Simulate an external source adding the extension as INTERNAL.
5300 EXPECT_TRUE(
5301 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535302 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305303 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5304 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5305 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
5306
5307 // Simulate an external source adding the extension as EXTERNAL_PREF.
5308 EXPECT_TRUE(
5309 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535310 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305311 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5312 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5313 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
5314
5315 // Simulate an external source adding as EXTERNAL_PREF again.
[email protected]4ec0f4b2012-12-07 09:41:465316 // This is rejected because the version and the location are the same as
5317 // the previous installation, which is still pending.
5318 EXPECT_FALSE(
[email protected]9060d8b02012-01-13 02:14:305319 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535320 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305321 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5322 EXPECT_TRUE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:305323
5324 // Try INTERNAL again. Should fail.
5325 EXPECT_FALSE(
5326 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535327 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305328 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5329 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5330
5331 // Now the registry adds the extension.
5332 EXPECT_TRUE(
5333 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535334 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305335 Extension::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
5336 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5337 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
5338
5339 // Registry outranks both external pref and internal, so both fail.
5340 EXPECT_FALSE(
5341 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535342 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305343 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5344 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5345
5346 EXPECT_FALSE(
5347 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535348 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305349 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5350 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5351
5352 pending->Remove(kGoodId);
5353
5354 // Install the extension.
5355 FilePath path = data_dir_.AppendASCII("good.crx");
5356 const Extension* ext = InstallCRX(path, INSTALL_NEW);
5357 ValidatePrefKeyCount(1u);
5358 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5359 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
5360
5361 // Now test the logic of OnExternalExtensionFileFound() when the extension
5362 // being added is already installed.
5363
5364 // Tests assume |older_version| is less than the installed version, and
5365 // |newer_version| is greater. Verify this:
[email protected]12126d372012-07-11 18:40:535366 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
5367 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
[email protected]9060d8b02012-01-13 02:14:305368
5369 // An external install for the same location should fail if the version is
5370 // older, or the same, and succeed if the version is newer.
5371
5372 // Older than the installed version...
5373 EXPECT_FALSE(
5374 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535375 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305376 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5377 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5378
5379 // Same version as the installed version...
5380 EXPECT_FALSE(
5381 service_->OnExternalExtensionFileFound(
5382 kGoodId, ext->version(), kInvalidPathToCrx,
5383 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5384 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5385
5386 // Newer than the installed version...
5387 EXPECT_TRUE(
5388 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535389 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305390 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5391 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5392
5393 // An external install for a higher priority install source should succeed
5394 // if the version is greater. |older_version| is not...
5395 EXPECT_FALSE(
5396 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535397 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305398 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5399 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5400
5401 // |newer_version| is newer.
5402 EXPECT_TRUE(
5403 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535404 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305405 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5406 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5407
5408 // An external install for an even higher priority install source should
5409 // succeed if the version is greater.
5410 EXPECT_TRUE(
5411 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535412 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305413 Extension::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
5414 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5415
5416 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
5417 // adding from external pref will now fail.
5418 EXPECT_FALSE(
5419 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535420 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305421 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5422 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5423}
5424
[email protected]d9a61e12012-11-14 02:43:475425TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
[email protected]e3987852012-05-04 10:06:305426 Version kVersion123("1.2.3");
5427 Version kVersion124("1.2.4");
5428 Version kVersion125("1.2.5");
5429 const FilePath kInvalidPathToCrx = FilePath();
5430 const int kCreationFlags = 0;
5431 const bool kDontMarkAcknowledged = false;
5432
5433 InitializeEmptyExtensionService();
5434
[email protected]3f213ad2012-07-26 23:39:415435 extensions::PendingExtensionManager* pending =
5436 service_->pending_extension_manager();
[email protected]e3987852012-05-04 10:06:305437 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5438
5439 // An external provider starts installing from a local crx.
5440 EXPECT_TRUE(
5441 service_->OnExternalExtensionFileFound(
5442 kGoodId, &kVersion123, kInvalidPathToCrx,
5443 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
[email protected]3f213ad2012-07-26 23:39:415444 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065445 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5446 EXPECT_TRUE(info->version().IsValid());
5447 EXPECT_TRUE(info->version().Equals(kVersion123));
[email protected]e3987852012-05-04 10:06:305448
5449 // Adding a newer version overrides the currently pending version.
5450 EXPECT_TRUE(
5451 service_->OnExternalExtensionFileFound(
5452 kGoodId, &kVersion124, kInvalidPathToCrx,
5453 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
[email protected]51a3bf8b2012-06-08 22:53:065454 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5455 EXPECT_TRUE(info->version().IsValid());
5456 EXPECT_TRUE(info->version().Equals(kVersion124));
[email protected]e3987852012-05-04 10:06:305457
5458 // Adding an older version fails.
5459 EXPECT_FALSE(
5460 service_->OnExternalExtensionFileFound(
5461 kGoodId, &kVersion123, kInvalidPathToCrx,
5462 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
[email protected]51a3bf8b2012-06-08 22:53:065463 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5464 EXPECT_TRUE(info->version().IsValid());
5465 EXPECT_TRUE(info->version().Equals(kVersion124));
[email protected]e3987852012-05-04 10:06:305466
5467 // Adding an older version fails even when coming from a higher-priority
5468 // location.
5469 EXPECT_FALSE(
5470 service_->OnExternalExtensionFileFound(
5471 kGoodId, &kVersion123, kInvalidPathToCrx,
5472 Extension::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
[email protected]51a3bf8b2012-06-08 22:53:065473 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5474 EXPECT_TRUE(info->version().IsValid());
5475 EXPECT_TRUE(info->version().Equals(kVersion124));
[email protected]e3987852012-05-04 10:06:305476
5477 // Adding the latest version from the webstore overrides a specific version.
5478 GURL kUpdateUrl("http://example.com/update");
5479 EXPECT_TRUE(
5480 service_->OnExternalExtensionUpdateUrlFound(
5481 kGoodId, kUpdateUrl, Extension::EXTERNAL_POLICY_DOWNLOAD));
[email protected]51a3bf8b2012-06-08 22:53:065482 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5483 EXPECT_FALSE(info->version().IsValid());
[email protected]e3987852012-05-04 10:06:305484}
5485
[email protected]f5bf1842012-02-15 02:52:265486// This makes sure we can package and install CRX files that use whitelisted
5487// permissions.
[email protected]d9a61e12012-11-14 02:43:475488TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
[email protected]f5bf1842012-02-15 02:52:265489 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
5490 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
5491 switches::kWhitelistedExtensionID, test_id);
5492
5493 InitializeEmptyExtensionService();
5494 FilePath path = data_dir_
5495 .AppendASCII("permissions");
5496 FilePath pem_path = path
5497 .AppendASCII("whitelist.pem");
5498 path = path
5499 .AppendASCII("whitelist");
5500
5501 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
5502 EXPECT_EQ(0u, GetErrors().size());
5503 ASSERT_EQ(1u, service_->extensions()->size());
5504 EXPECT_EQ(test_id, extension->id());
5505}
5506
[email protected]145a317b2011-04-12 16:03:465507// Test that when multiple sources try to install an extension,
5508// we consistently choose the right one. To make tests easy to read,
5509// methods that fake requests to install crx files in several ways
5510// are provided.
5511class ExtensionSourcePriorityTest : public ExtensionServiceTest {
5512 public:
5513 void SetUp() {
[email protected]ed8ee722011-04-22 06:49:445514 ExtensionServiceTest::SetUp();
5515
[email protected]145a317b2011-04-12 16:03:465516 // All tests use a single extension. Put the id and path in member vars
5517 // that all methods can read.
5518 crx_id_ = kGoodId;
[email protected]e85e34c32011-04-13 18:38:355519 crx_path_ = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:465520 }
5521
5522 // Fake an external source adding a URL to fetch an extension from.
[email protected]9060d8b02012-01-13 02:14:305523 bool AddPendingExternalPrefUrl() {
5524 return service_->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]145a317b2011-04-12 16:03:465525 crx_id_, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
5526 }
5527
5528 // Fake an external file from external_extensions.json.
[email protected]9060d8b02012-01-13 02:14:305529 bool AddPendingExternalPrefFileInstall() {
[email protected]12126d372012-07-11 18:40:535530 Version version("1.0.0.0");
[email protected]145a317b2011-04-12 16:03:465531
[email protected]9060d8b02012-01-13 02:14:305532 return service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535533 crx_id_, &version, crx_path_, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:515534 Extension::NO_FLAGS, false);
[email protected]145a317b2011-04-12 16:03:465535 }
5536
5537 // Fake a request from sync to install an extension.
5538 bool AddPendingSyncInstall() {
5539 return service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:335540 crx_id_, GURL(kGoodUpdateURL), &IsExtension, kGoodInstallSilently);
[email protected]145a317b2011-04-12 16:03:465541 }
5542
[email protected]145a317b2011-04-12 16:03:465543 // Fake a policy install.
[email protected]9060d8b02012-01-13 02:14:305544 bool AddPendingPolicyInstall() {
[email protected]145a317b2011-04-12 16:03:465545 // Get path to the CRX with id |kGoodId|.
[email protected]9060d8b02012-01-13 02:14:305546 return service_->OnExternalExtensionUpdateUrlFound(
[email protected]145a317b2011-04-12 16:03:465547 crx_id_, GURL(), Extension::EXTERNAL_POLICY_DOWNLOAD);
5548 }
5549
5550 // Get the install source of a pending extension.
5551 Extension::Location GetPendingLocation() {
[email protected]3f213ad2012-07-26 23:39:415552 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065553 EXPECT_TRUE((info = service_->pending_extension_manager()->
5554 GetById(crx_id_)));
5555 return info->install_source();
[email protected]145a317b2011-04-12 16:03:465556 }
5557
5558 // Is an extension pending from a sync request?
5559 bool GetPendingIsFromSync() {
[email protected]3f213ad2012-07-26 23:39:415560 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065561 EXPECT_TRUE((info = service_->pending_extension_manager()->
5562 GetById(crx_id_)));
5563 return info->is_from_sync();
[email protected]145a317b2011-04-12 16:03:465564 }
5565
5566 // Is the CRX id these tests use pending?
5567 bool IsCrxPending() {
5568 return service_->pending_extension_manager()->IsIdPending(crx_id_);
5569 }
5570
5571 // Is an extension installed?
5572 bool IsCrxInstalled() {
5573 return (service_->GetExtensionById(crx_id_, true) != NULL);
5574 }
5575
5576 protected:
5577 // All tests use a single extension. Making the id and path member
5578 // vars avoids pasing the same argument to every method.
5579 std::string crx_id_;
5580 FilePath crx_path_;
5581};
5582
[email protected]3634ebd2011-04-20 00:34:125583// Test that a pending request for installation of an external CRX from
5584// an update URL overrides a pending request to install the same extension
5585// from sync.
[email protected]ed8ee722011-04-22 06:49:445586TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
[email protected]145a317b2011-04-12 16:03:465587 InitializeEmptyExtensionService();
5588
5589 ASSERT_FALSE(IsCrxInstalled());
5590
5591 // Install pending extension from sync.
[email protected]f4d5e1a2011-04-28 02:08:255592 EXPECT_TRUE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465593 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
5594 EXPECT_TRUE(GetPendingIsFromSync());
5595 ASSERT_FALSE(IsCrxInstalled());
5596
5597 // Install pending as external prefs json would.
5598 AddPendingExternalPrefFileInstall();
5599 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
5600 ASSERT_FALSE(IsCrxInstalled());
5601
5602 // Another request from sync should be ignorred.
[email protected]f4d5e1a2011-04-28 02:08:255603 EXPECT_FALSE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465604 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
5605 ASSERT_FALSE(IsCrxInstalled());
5606
[email protected]8f512c72011-11-22 21:02:505607 WaitForCrxInstall(crx_path_, INSTALL_NEW);
[email protected]145a317b2011-04-12 16:03:465608 ASSERT_TRUE(IsCrxInstalled());
5609}
5610
5611// Test that an install of an external CRX from an update overrides
5612// an install of the same extension from sync.
[email protected]ed8ee722011-04-22 06:49:445613TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
[email protected]145a317b2011-04-12 16:03:465614 InitializeEmptyExtensionService();
5615 ASSERT_FALSE(IsCrxInstalled());
5616
[email protected]f4d5e1a2011-04-28 02:08:255617 EXPECT_TRUE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465618 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
5619 EXPECT_TRUE(GetPendingIsFromSync());
5620 ASSERT_FALSE(IsCrxInstalled());
5621
[email protected]9060d8b02012-01-13 02:14:305622 ASSERT_TRUE(AddPendingExternalPrefUrl());
[email protected]145a317b2011-04-12 16:03:465623 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
5624 EXPECT_FALSE(GetPendingIsFromSync());
5625 ASSERT_FALSE(IsCrxInstalled());
5626
[email protected]f4d5e1a2011-04-28 02:08:255627 EXPECT_FALSE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465628 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
5629 EXPECT_FALSE(GetPendingIsFromSync());
5630 ASSERT_FALSE(IsCrxInstalled());
5631}
5632
[email protected]145a317b2011-04-12 16:03:465633// Test that an external install request stops sync from installing
5634// the same extension.
[email protected]ed8ee722011-04-22 06:49:445635TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
[email protected]145a317b2011-04-12 16:03:465636 InitializeEmptyExtensionService();
5637 ASSERT_FALSE(IsCrxInstalled());
5638
5639 // External prefs starts an install.
5640 AddPendingExternalPrefFileInstall();
5641
5642 // Crx installer was made, but has not yet run.
5643 ASSERT_FALSE(IsCrxInstalled());
5644
5645 // Before the CRX installer runs, Sync requests that the same extension
5646 // be installed. Should fail, because an external source is pending.
5647 ASSERT_FALSE(AddPendingSyncInstall());
5648
5649 // Wait for the external source to install.
[email protected]8f512c72011-11-22 21:02:505650 WaitForCrxInstall(crx_path_, INSTALL_NEW);
[email protected]145a317b2011-04-12 16:03:465651 ASSERT_TRUE(IsCrxInstalled());
5652
5653 // Now that the extension is installed, sync request should fail
5654 // because the extension is already installed.
5655 ASSERT_FALSE(AddPendingSyncInstall());
5656}
[email protected]07c9f2f42012-02-29 18:45:225657
[email protected]612a1cb12012-10-17 13:18:035658// Test that installing an external extension displays a GlobalError.
[email protected]d9a61e12012-11-14 02:43:475659TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
[email protected]00b5d0a52012-10-30 13:13:535660 FeatureSwitch::ScopedOverride prompt(
5661 FeatureSwitch::prompt_for_external_extensions(), true);
[email protected]612a1cb12012-10-17 13:18:035662
[email protected]07c9f2f42012-02-29 18:45:225663 InitializeEmptyExtensionService();
[email protected]07c9f2f42012-02-29 18:45:225664 MockExtensionProvider* provider =
[email protected]f121003b2012-05-04 21:57:475665 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]07c9f2f42012-02-29 18:45:225666 AddMockExternalProvider(provider);
5667
[email protected]612a1cb12012-10-17 13:18:035668 service_->UpdateExternalExtensionAlert();
[email protected]07c9f2f42012-02-29 18:45:225669 // Should return false, meaning there aren't any extensions that the user
5670 // needs to know about.
[email protected]612a1cb12012-10-17 13:18:035671 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225672
5673 // This is a normal extension, installed normally.
5674 // This should NOT trigger an alert.
5675 set_extensions_enabled(true);
5676 FilePath path = data_dir_.AppendASCII("good.crx");
5677 InstallCRX(path, INSTALL_NEW);
5678
[email protected]612a1cb12012-10-17 13:18:035679 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:575680 loop_.RunUntilIdle();
[email protected]612a1cb12012-10-17 13:18:035681 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225682
5683 // A hosted app, installed externally.
[email protected]a0b45c52012-10-20 01:18:095684 // This SHOULD trigger an alert.
[email protected]07c9f2f42012-02-29 18:45:225685 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
5686 data_dir_.AppendASCII("hosted_app.crx"));
5687
5688 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:575689 loop_.RunUntilIdle();
[email protected]a0b45c52012-10-20 01:18:095690 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5691 service_->EnableExtension(hosted_app);
[email protected]612a1cb12012-10-17 13:18:035692 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225693
[email protected]612a1cb12012-10-17 13:18:035694 // Another normal extension, but installed externally.
5695 // This SHOULD trigger an alert.
5696 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
5697 data_dir_.AppendASCII("page_action.crx"));
5698
5699 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:575700 loop_.RunUntilIdle();
[email protected]612a1cb12012-10-17 13:18:035701 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225702}
[email protected]612a1cb12012-10-17 13:18:035703
5704// Test that external extensions are initially disabled, and that enabling
5705// them clears the prompt.
[email protected]d9a61e12012-11-14 02:43:475706TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
[email protected]00b5d0a52012-10-30 13:13:535707 FeatureSwitch::ScopedOverride prompt(
5708 FeatureSwitch::prompt_for_external_extensions(), true);
[email protected]612a1cb12012-10-17 13:18:035709
5710 InitializeEmptyExtensionService();
5711 MockExtensionProvider* provider =
5712 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
5713 AddMockExternalProvider(provider);
5714
5715 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
5716 data_dir_.AppendASCII("page_action.crx"));
5717
5718 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:575719 loop_.RunUntilIdle();
[email protected]612a1cb12012-10-17 13:18:035720 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5721 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
5722
5723 const Extension* extension =
5724 service_->disabled_extensions()->GetByID(page_action);
5725 EXPECT_TRUE(extension);
5726 EXPECT_EQ(page_action, extension->id());
5727
5728 service_->EnableExtension(page_action);
5729 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
5730 EXPECT_TRUE(service_->IsExtensionEnabled(page_action));
5731}
5732
5733// Test that installing multiple external extensions works.
[email protected]d9a61e12012-11-14 02:43:475734TEST_F(ExtensionServiceTest, ExternalInstallMultiple) {
[email protected]00b5d0a52012-10-30 13:13:535735 FeatureSwitch::ScopedOverride prompt(
5736 FeatureSwitch::prompt_for_external_extensions(), true);
[email protected]612a1cb12012-10-17 13:18:035737
5738 InitializeEmptyExtensionService();
5739 MockExtensionProvider* provider =
5740 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
5741 AddMockExternalProvider(provider);
5742
5743 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
5744 data_dir_.AppendASCII("page_action.crx"));
5745 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
5746 data_dir_.AppendASCII("good.crx"));
5747 provider->UpdateOrAddExtension(theme_crx, "2.0",
5748 data_dir_.AppendASCII("theme.crx"));
5749
5750 service_->CheckForExternalUpdates();
[email protected]b8f50ce2012-11-17 12:37:575751 loop_.RunUntilIdle();
[email protected]612a1cb12012-10-17 13:18:035752 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5753 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
5754 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5755 EXPECT_FALSE(service_->IsExtensionEnabled(theme_crx));
5756
5757 service_->EnableExtension(page_action);
5758 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5759 service_->EnableExtension(theme_crx);
5760 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5761 service_->EnableExtension(good_crx);
5762 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
5763}
[email protected]00b5d0a52012-10-30 13:13:535764
5765// Test that a sideloaded extension gets wiped out.
5766TEST_F(ExtensionServiceTest, WipeOutExtension) {
5767 FeatureSwitch::ScopedOverride prompt(
5768 FeatureSwitch::sideload_wipeout(), true);
5769
5770 InitializeEmptyExtensionService();
5771 MockExtensionProvider* provider_registry =
5772 new MockExtensionProvider(service_, Extension::EXTERNAL_REGISTRY);
5773 AddMockExternalProvider(provider_registry);
5774 MockExtensionProvider* provider_pref =
5775 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
5776 AddMockExternalProvider(provider_pref);
5777
5778 provider_registry->UpdateOrAddExtension(good_crx, "1.0.0.0",
5779 data_dir_.AppendASCII("good.crx"));
5780 provider_pref->UpdateOrAddExtension(good_crx, "1.0.0.0",
5781 data_dir_.AppendASCII("good.crx"));
5782
5783 service_->CheckForExternalUpdates();
[email protected]7f8f24f2012-11-15 19:40:145784 loop_.RunUntilIdle();
[email protected]00b5d0a52012-10-30 13:13:535785 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
5786 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5787 EXPECT_TRUE(service_->IsExtensionEnabled(page_action));
5788
5789 ExtensionPrefs* prefs = service_->extension_prefs();
5790 EXPECT_NE(0, prefs->GetDisableReasons(good_crx) &
5791 Extension::DISABLE_SIDELOAD_WIPEOUT);
5792 EXPECT_EQ(0, prefs->GetDisableReasons(page_action) &
5793 Extension::DISABLE_SIDELOAD_WIPEOUT);
5794}