blob: 53d6e5c8321c91660c2c75260e969605bab7b1cd [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]24b538a2010-02-27 01:22:4411#include "base/basictypes.h"
[email protected]c4148a72011-08-09 23:04:2012#include "base/bind.h"
[email protected]36a784c2009-06-23 06:21:0813#include "base/command_line.h"
[email protected]6014d672008-12-05 00:38:2514#include "base/file_util.h"
[email protected]ffbec692012-02-26 20:26:4215#include "base/json/json_file_value_serializer.h"
[email protected]93d49d72009-10-23 20:00:2016#include "base/json/json_reader.h"
[email protected]ffbec692012-02-26 20:26:4217#include "base/json/json_string_value_serializer.h"
[email protected]3b63f8f42011-03-28 01:54:1518#include "base/memory/scoped_ptr.h"
[email protected]71cb8aa2011-12-29 19:14:0019#include "base/memory/weak_ptr.h"
[email protected]6014d672008-12-05 00:38:2520#include "base/message_loop.h"
21#include "base/path_service.h"
[email protected]e0785902011-05-19 23:34:1722#include "base/scoped_temp_dir.h"
[email protected]7286e3fc2011-07-19 22:13:2423#include "base/stl_util.h"
[email protected]24b538a2010-02-27 01:22:4424#include "base/string16.h"
[email protected]e83326f2010-07-31 17:29:2525#include "base/string_number_conversions.h"
[email protected]6014d672008-12-05 00:38:2526#include "base/string_util.h"
[email protected]be1ce6a72010-08-03 14:35:2227#include "base/utf_string_conversions.h"
[email protected]aa142702010-03-26 01:26:3328#include "base/version.h"
[email protected]9d32ded072011-10-11 16:31:0529#include "chrome/browser/browser_process.h"
[email protected]5db9ada2012-04-11 13:48:2030#include "chrome/browser/extensions/app_sync_data.h"
[email protected]d8c8f25f2011-11-02 18:18:0131#include "chrome/browser/extensions/component_loader.h"
[email protected]eb6c7ef2011-12-12 23:12:2032#include "chrome/browser/extensions/crx_installer.h"
[email protected]a7cd28e2012-10-05 21:03:3633#include "chrome/browser/extensions/default_apps.h"
[email protected]a17f9462009-06-09 02:56:4134#include "chrome/browser/extensions/extension_creator.h"
[email protected]14a000d2010-04-29 21:44:2435#include "chrome/browser/extensions/extension_error_reporter.h"
[email protected]89226982012-07-16 20:09:1836#include "chrome/browser/extensions/extension_error_ui.h"
[email protected]eaa7dd182010-12-14 11:09:0037#include "chrome/browser/extensions/extension_service.h"
[email protected]1bcf30e2012-03-10 01:06:4138#include "chrome/browser/extensions/extension_sorting.h"
[email protected]19eb80152011-02-26 00:28:4339#include "chrome/browser/extensions/extension_special_storage_policy.h"
[email protected]90310d92011-04-17 07:35:0440#include "chrome/browser/extensions/extension_sync_data.h"
[email protected]31d8f5f22012-04-02 15:22:0841#include "chrome/browser/extensions/extension_system.h"
[email protected]612a1cb12012-10-17 13:18:0342#include "chrome/browser/extensions/external_install_ui.h"
[email protected]5df038b2012-07-16 19:03:2743#include "chrome/browser/extensions/external_pref_loader.h"
44#include "chrome/browser/extensions/external_provider_impl.h"
45#include "chrome/browser/extensions/external_provider_interface.h"
[email protected]d8c8f25f2011-11-02 18:18:0146#include "chrome/browser/extensions/installed_loader.h"
[email protected]f0bfe622012-06-22 01:01:4447#include "chrome/browser/extensions/pack_extension_job.h"
[email protected]90310d92011-04-17 07:35:0448#include "chrome/browser/extensions/pending_extension_info.h"
49#include "chrome/browser/extensions/pending_extension_manager.h"
[email protected]31d8f5f22012-04-02 15:22:0850#include "chrome/browser/extensions/test_extension_system.h"
[email protected]65187152012-06-02 13:14:1451#include "chrome/browser/extensions/test_management_policy.h"
[email protected]d8c8f25f2011-11-02 18:18:0152#include "chrome/browser/extensions/unpacked_installer.h"
[email protected]42a08162012-03-16 18:09:1153#include "chrome/browser/extensions/updater/extension_updater.h"
[email protected]0f5e57f52012-09-20 20:53:1854#include "chrome/browser/plugins/plugin_prefs_factory.h"
[email protected]37858e52010-08-26 00:22:0255#include "chrome/browser/prefs/browser_prefs.h"
[email protected]f2d1f612010-12-09 15:10:1756#include "chrome/browser/prefs/pref_service_mock_builder.h"
[email protected]f89ee342011-03-07 09:28:2757#include "chrome/browser/prefs/scoped_user_pref_update.h"
[email protected]31d8f5f22012-04-02 15:22:0858#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:2759#include "chrome/common/chrome_notification_types.h"
[email protected]37858e52010-08-26 00:22:0260#include "chrome/common/chrome_paths.h"
61#include "chrome/common/chrome_switches.h"
[email protected]5b1a0e22009-05-26 19:00:5862#include "chrome/common/extensions/extension.h"
[email protected]6884a802012-08-07 03:55:2263#include "chrome/common/extensions/extension_l10n_util.h"
[email protected]a52c0e92012-03-23 06:02:2464#include "chrome/common/extensions/extension_manifest_constants.h"
[email protected]942690b132010-05-11 06:42:1465#include "chrome/common/extensions/extension_resource.h"
[email protected]612a1cb12012-10-17 13:18:0366#include "chrome/common/extensions/feature_switch.h"
[email protected]bebe1d02012-08-02 20:17:0967#include "chrome/common/extensions/permissions/permission_set.h"
[email protected]7197f4992009-03-23 05:05:4968#include "chrome/common/extensions/url_pattern.h"
[email protected]36a784c2009-06-23 06:21:0869#include "chrome/common/pref_names.h"
[email protected]24b538a2010-02-27 01:22:4470#include "chrome/common/url_constants.h"
[email protected]a4ff9eae2011-08-01 19:58:1671#include "chrome/test/base/testing_profile.h"
[email protected]35cc399e2012-02-23 18:19:2872#include "content/public/browser/dom_storage_context.h"
[email protected]98270432012-09-11 20:51:2473#include "content/public/browser/gpu_data_manager.h"
[email protected]35cc399e2012-02-23 18:19:2874#include "content/public/browser/indexed_db_context.h"
[email protected]6c2381d2011-10-19 02:52:5375#include "content/public/browser/notification_registrar.h"
[email protected]ad50def52011-10-19 23:17:0776#include "content/public/browser/notification_service.h"
[email protected]e67385f2011-12-21 06:00:5677#include "content/public/browser/plugin_service.h"
[email protected]5c8e67c2012-08-29 00:48:5278#include "content/public/browser/storage_partition.h"
[email protected]55eb70e762012-02-20 17:38:3979#include "content/public/common/content_constants.h"
[email protected]7e343152012-09-20 21:49:5380#include "content/public/common/gpu_info.h"
[email protected]e97882f2012-06-04 02:23:1781#include "content/public/test/test_browser_thread.h"
[email protected]24b538a2010-02-27 01:22:4482#include "googleurl/src/gurl.h"
[email protected]b873cd92012-02-09 21:51:4883#include "grit/browser_resources.h"
[email protected]5b9bc352012-07-18 13:13:3484#include "net/cookies/canonical_cookie.h"
[email protected]aa84a7e2012-03-15 21:29:0685#include "net/cookies/cookie_monster.h"
86#include "net/cookies/cookie_options.h"
[email protected]dbbad7a2010-08-13 18:18:3687#include "net/url_request/url_request_context.h"
[email protected]abe2c032011-03-31 18:49:3488#include "net/url_request/url_request_context_getter.h"
[email protected]36b643212012-09-07 12:53:0089#include "sync/api/string_ordinal.h"
[email protected]895a1e52012-05-15 02:50:1290#include "sync/api/sync_error_factory.h"
91#include "sync/api/sync_error_factory_mock.h"
[email protected]1bcf30e2012-03-10 01:06:4192#include "sync/protocol/app_specifics.pb.h"
93#include "sync/protocol/extension_specifics.pb.h"
94#include "sync/protocol/sync.pb.h"
[email protected]6014d672008-12-05 00:38:2595#include "testing/gtest/include/gtest/gtest.h"
[email protected]f66c110c2008-12-05 20:26:2996#include "testing/platform_test.h"
[email protected]24b538a2010-02-27 01:22:4497#include "webkit/database/database_tracker.h"
98#include "webkit/database/database_util.h"
[email protected]eb6c7ef2011-12-12 23:12:2099#include "webkit/plugins/npapi/mock_plugin_list.h"
[email protected]c62983a72011-05-09 06:29:59100#include "webkit/quota/quota_manager.h"
[email protected]6014d672008-12-05 00:38:25101
[email protected]55eb70e762012-02-20 17:38:39102using content::BrowserContext;
[email protected]631bb742011-11-02 11:29:39103using content::BrowserThread;
[email protected]35cc399e2012-02-23 18:19:28104using content::DOMStorageContext;
105using content::IndexedDBContext;
[email protected]e67385f2011-12-21 06:00:56106using content::PluginService;
[email protected]c2e66e12012-06-27 06:27:06107using extensions::APIPermission;
108using extensions::APIPermissionSet;
[email protected]bf3d9df2012-07-24 23:20:27109using extensions::CrxInstaller;
[email protected]1c321ee52012-05-21 03:02:34110using extensions::Extension;
[email protected]6d777492012-07-11 17:33:43111using extensions::ExtensionCreator;
[email protected]45759612012-07-10 17:21:23112using extensions::ExtensionPrefs;
[email protected]bd306722012-07-11 20:43:59113using extensions::ExtensionSystem;
[email protected]c2e66e12012-06-27 06:27:06114using extensions::PermissionSet;
[email protected]631bb742011-11-02 11:29:39115
[email protected]c6d474f82009-12-16 21:11:06116namespace keys = extension_manifest_keys;
117
[email protected]f0397fa2008-12-11 17:59:58118namespace {
119
[email protected]df4956e2009-06-10 16:53:42120// Extension ids used during testing.
[email protected]5a2721f62009-06-13 07:08:20121const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
122const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
123const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj";
124const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk";
125const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
126const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
[email protected]07c9f2f42012-02-29 18:45:22127const char* const hosted_app = "kbmnembihfiondgfjekmnmcbddelicoi";
[email protected]d7eaf572009-07-01 21:57:00128const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln";
[email protected]5a2721f62009-06-13 07:08:20129const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad";
130const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
[email protected]8d888c12010-11-30 00:00:25131const char* const permissions_crx = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
[email protected]c24fb292012-02-01 22:52:11132const char* const unpacked = "cbcdidchbppangcjoddlpdjlenngjldk";
[email protected]df4956e2009-06-10 16:53:42133
[email protected]f0397fa2008-12-11 17:59:58134struct ExtensionsOrder {
135 bool operator()(const Extension* a, const Extension* b) {
136 return a->name() < b->name();
137 }
138};
139
[email protected]fc670822011-12-17 09:33:49140static std::vector<string16> GetErrors() {
141 const std::vector<string16>* errors =
[email protected]bb28e062009-02-27 17:19:18142 ExtensionErrorReporter::GetInstance()->GetErrors();
[email protected]fc670822011-12-17 09:33:49143 std::vector<string16> ret_val;
[email protected]bb28e062009-02-27 17:19:18144
[email protected]fc670822011-12-17 09:33:49145 for (std::vector<string16>::const_iterator iter = errors->begin();
[email protected]bb28e062009-02-27 17:19:18146 iter != errors->end(); ++iter) {
[email protected]fc670822011-12-17 09:33:49147 std::string utf8_error = UTF16ToUTF8(*iter);
148 if (utf8_error.find(".svn") == std::string::npos) {
[email protected]bb28e062009-02-27 17:19:18149 ret_val.push_back(*iter);
150 }
151 }
152
153 // The tests rely on the errors being in a certain order, which can vary
154 // depending on how filesystem iteration works.
155 std::stable_sort(ret_val.begin(), ret_val.end());
156
157 return ret_val;
158}
159
[email protected]cced75a2011-05-20 08:31:12160static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
[email protected]8d888c12010-11-30 00:00:25161 int schemes = URLPattern::SCHEME_ALL;
162 extent->AddPattern(URLPattern(schemes, pattern));
163}
164
[email protected]f0397fa2008-12-11 17:59:58165} // namespace
[email protected]6014d672008-12-05 00:38:25166
[email protected]5df038b2012-07-16 19:03:27167class MockExtensionProvider : public extensions::ExternalProviderInterface {
[email protected]a1257b12009-06-12 02:51:34168 public:
[email protected]a12ce8b22012-01-17 18:40:53169 MockExtensionProvider(
[email protected]8e4560b62011-01-14 10:09:14170 VisitorInterface* visitor,
171 Extension::Location location)
[email protected]f121003b2012-05-04 21:57:47172 : location_(location), visitor_(visitor), visit_count_(0) {
[email protected]a12ce8b22012-01-17 18:40:53173 }
174
[email protected]a1257b12009-06-12 02:51:34175 virtual ~MockExtensionProvider() {}
176
177 void UpdateOrAddExtension(const std::string& id,
178 const std::string& version,
[email protected]f5ad7542009-07-24 17:38:59179 const FilePath& path) {
[email protected]a1257b12009-06-12 02:51:34180 extension_map_[id] = std::make_pair(version, path);
181 }
182
183 void RemoveExtension(const std::string& id) {
184 extension_map_.erase(id);
185 }
186
[email protected]5df038b2012-07-16 19:03:27187 // ExternalProvider implementation:
[email protected]a12ce8b22012-01-17 18:40:53188 virtual void VisitRegisteredExtension() OVERRIDE {
[email protected]0a60a2e2010-10-25 16:15:21189 visit_count_++;
[email protected]a1257b12009-06-12 02:51:34190 for (DataMap::const_iterator i = extension_map_.begin();
191 i != extension_map_.end(); ++i) {
[email protected]12126d372012-07-11 18:40:53192 Version version(i->second.first);
[email protected]a1257b12009-06-12 02:51:34193
[email protected]8e4560b62011-01-14 10:09:14194 visitor_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:53195 i->first, &version, i->second.second, location_,
[email protected]f121003b2012-05-04 21:57:47196 Extension::NO_FLAGS, false);
[email protected]a1257b12009-06-12 02:51:34197 }
[email protected]50067e52011-10-20 23:17:07198 visitor_->OnExternalProviderReady(this);
[email protected]a1257b12009-06-12 02:51:34199 }
200
[email protected]a12ce8b22012-01-17 18:40:53201 virtual bool HasExtension(const std::string& id) const OVERRIDE {
[email protected]0a60a2e2010-10-25 16:15:21202 return extension_map_.find(id) != extension_map_.end();
203 }
204
[email protected]a12ce8b22012-01-17 18:40:53205 virtual bool GetExtensionDetails(
206 const std::string& id,
207 Extension::Location* location,
208 scoped_ptr<Version>* version) const OVERRIDE {
[email protected]a1257b12009-06-12 02:51:34209 DataMap::const_iterator it = extension_map_.find(id);
210 if (it == extension_map_.end())
[email protected]0a60a2e2010-10-25 16:15:21211 return false;
212
213 if (version)
[email protected]12126d372012-07-11 18:40:53214 version->reset(new Version(it->second.first));
[email protected]a1257b12009-06-12 02:51:34215
216 if (location)
217 *location = location_;
[email protected]0a60a2e2010-10-25 16:15:21218
219 return true;
220 }
[email protected]8e4560b62011-01-14 10:09:14221
[email protected]a12ce8b22012-01-17 18:40:53222 virtual bool IsReady() const OVERRIDE {
[email protected]8e4560b62011-01-14 10:09:14223 return true;
224 }
225
[email protected]a12ce8b22012-01-17 18:40:53226 virtual void ServiceShutdown() OVERRIDE {
[email protected]8e4560b62011-01-14 10:09:14227 }
228
[email protected]0a60a2e2010-10-25 16:15:21229 int visit_count() const { return visit_count_; }
230 void set_visit_count(int visit_count) {
231 visit_count_ = visit_count;
[email protected]a1257b12009-06-12 02:51:34232 }
233
234 private:
235 typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap;
236 DataMap extension_map_;
237 Extension::Location location_;
[email protected]8e4560b62011-01-14 10:09:14238 VisitorInterface* visitor_;
[email protected]27b985d2009-06-25 17:53:15239
[email protected]0a60a2e2010-10-25 16:15:21240 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
241 // Mutable because it must be incremented on each call to
242 // VisitRegisteredExtension(), which must be a const method to inherit
243 // from the class being mocked.
244 mutable int visit_count_;
245
[email protected]27b985d2009-06-25 17:53:15246 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
247};
248
[email protected]8e4560b62011-01-14 10:09:14249class MockProviderVisitor
[email protected]5df038b2012-07-16 19:03:27250 : public extensions::ExternalProviderInterface::VisitorInterface {
[email protected]27b985d2009-06-25 17:53:15251 public:
[email protected]f0841cd2011-01-19 15:07:24252 // The provider will return |fake_base_path| from
253 // GetBaseCrxFilePath(). User can test the behavior with
254 // and without an empty path using this parameter.
255 explicit MockProviderVisitor(FilePath fake_base_path)
256 : ids_found_(0),
[email protected]f121003b2012-05-04 21:57:47257 fake_base_path_(fake_base_path),
258 expected_creation_flags_(Extension::NO_FLAGS) {
259 }
260
261 MockProviderVisitor(FilePath fake_base_path, int expected_creation_flags)
262 : ids_found_(0),
263 fake_base_path_(fake_base_path),
264 expected_creation_flags_(expected_creation_flags) {
[email protected]27b985d2009-06-25 17:53:15265 }
266
[email protected]683d0702010-12-06 16:25:57267 int Visit(const std::string& json_data) {
[email protected]27b985d2009-06-25 17:53:15268 // Give the test json file to the provider for parsing.
[email protected]5df038b2012-07-16 19:03:27269 provider_.reset(new extensions::ExternalProviderImpl(
[email protected]8e4560b62011-01-14 10:09:14270 this,
[email protected]5df038b2012-07-16 19:03:27271 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
[email protected]8e4560b62011-01-14 10:09:14272 Extension::EXTERNAL_PREF,
[email protected]1bf73cc32011-10-26 22:38:31273 Extension::EXTERNAL_PREF_DOWNLOAD,
274 Extension::NO_FLAGS));
[email protected]27b985d2009-06-25 17:53:15275
276 // We also parse the file into a dictionary to compare what we get back
277 // from the provider.
278 JSONStringValueSerializer serializer(json_data);
[email protected]ba399672010-04-06 15:42:39279 Value* json_value = serializer.Deserialize(NULL, NULL);
[email protected]27b985d2009-06-25 17:53:15280
[email protected]ba399672010-04-06 15:42:39281 if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
[email protected]e2194742010-08-12 05:54:34282 NOTREACHED() << "Unable to deserialize json data";
[email protected]27b985d2009-06-25 17:53:15283 return -1;
284 } else {
285 DictionaryValue* external_extensions =
286 static_cast<DictionaryValue*>(json_value);
287 prefs_.reset(external_extensions);
288 }
289
290 // Reset our counter.
291 ids_found_ = 0;
[email protected]683d0702010-12-06 16:25:57292 // Ask the provider to look up all extensions and return them.
[email protected]8e4560b62011-01-14 10:09:14293 provider_->VisitRegisteredExtension();
[email protected]27b985d2009-06-25 17:53:15294
295 return ids_found_;
296 }
297
[email protected]9060d8b02012-01-13 02:14:30298 virtual bool OnExternalExtensionFileFound(const std::string& id,
[email protected]8ef78fd2010-08-19 17:14:32299 const Version* version,
300 const FilePath& path,
[email protected]1bf73cc32011-10-26 22:38:31301 Extension::Location unused,
[email protected]47fc70c2011-12-06 07:29:51302 int creation_flags,
303 bool mark_acknowledged) {
[email protected]f121003b2012-05-04 21:57:47304 EXPECT_EQ(expected_creation_flags_, creation_flags);
[email protected]1bf73cc32011-10-26 22:38:31305
[email protected]27b985d2009-06-25 17:53:15306 ++ids_found_;
307 DictionaryValue* pref;
308 // This tests is to make sure that the provider only notifies us of the
309 // values we gave it. So if the id we doesn't exist in our internal
310 // dictionary then something is wrong.
[email protected]e2194742010-08-12 05:54:34311 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
312 << "Got back ID (" << id.c_str() << ") we weren't expecting";
[email protected]27b985d2009-06-25 17:53:15313
[email protected]f0841cd2011-01-19 15:07:24314 EXPECT_TRUE(path.IsAbsolute());
315 if (!fake_base_path_.empty())
316 EXPECT_TRUE(fake_base_path_.IsParent(path));
317
[email protected]27b985d2009-06-25 17:53:15318 if (pref) {
[email protected]0a60a2e2010-10-25 16:15:21319 EXPECT_TRUE(provider_->HasExtension(id));
320
[email protected]27b985d2009-06-25 17:53:15321 // Ask provider if the extension we got back is registered.
322 Extension::Location location = Extension::INVALID;
[email protected]0a60a2e2010-10-25 16:15:21323 scoped_ptr<Version> v1;
324 FilePath crx_path;
325
326 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
327 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
328
329 scoped_ptr<Version> v2;
330 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
[email protected]27b985d2009-06-25 17:53:15331 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
332 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
333 EXPECT_EQ(Extension::EXTERNAL_PREF, location);
334
335 // Remove it so we won't count it ever again.
[email protected]e2194742010-08-12 05:54:34336 prefs_->Remove(id, NULL);
[email protected]27b985d2009-06-25 17:53:15337 }
[email protected]9060d8b02012-01-13 02:14:30338 return true;
[email protected]27b985d2009-06-25 17:53:15339 }
340
[email protected]9060d8b02012-01-13 02:14:30341 virtual bool OnExternalExtensionUpdateUrlFound(
[email protected]21a5a672010-11-04 10:47:42342 const std::string& id, const GURL& update_url,
343 Extension::Location location) {
[email protected]8ef78fd2010-08-19 17:14:32344 ++ids_found_;
345 DictionaryValue* pref;
346 // This tests is to make sure that the provider only notifies us of the
347 // values we gave it. So if the id we doesn't exist in our internal
348 // dictionary then something is wrong.
349 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
350 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
[email protected]21a5a672010-11-04 10:47:42351 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location);
[email protected]8ef78fd2010-08-19 17:14:32352
353 if (pref) {
[email protected]0a60a2e2010-10-25 16:15:21354 EXPECT_TRUE(provider_->HasExtension(id));
355
356 // External extensions with update URLs do not have versions.
357 scoped_ptr<Version> v1;
[email protected]21a5a672010-11-04 10:47:42358 Extension::Location location1 = Extension::INVALID;
359 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
[email protected]0a60a2e2010-10-25 16:15:21360 EXPECT_FALSE(v1.get());
[email protected]21a5a672010-11-04 10:47:42361 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location1);
[email protected]0a60a2e2010-10-25 16:15:21362
[email protected]8ef78fd2010-08-19 17:14:32363 // Remove it so we won't count it again.
364 prefs_->Remove(id, NULL);
365 }
[email protected]9060d8b02012-01-13 02:14:30366 return true;
[email protected]8ef78fd2010-08-19 17:14:32367 }
368
[email protected]50067e52011-10-20 23:17:07369 virtual void OnExternalProviderReady(
[email protected]5df038b2012-07-16 19:03:27370 const extensions::ExternalProviderInterface* provider) {
[email protected]50067e52011-10-20 23:17:07371 EXPECT_EQ(provider, provider_.get());
372 EXPECT_TRUE(provider->IsReady());
[email protected]8e4560b62011-01-14 10:09:14373 }
374
[email protected]27b985d2009-06-25 17:53:15375 private:
376 int ids_found_;
[email protected]f0841cd2011-01-19 15:07:24377 FilePath fake_base_path_;
[email protected]f121003b2012-05-04 21:57:47378 int expected_creation_flags_;
[email protected]5df038b2012-07-16 19:03:27379 scoped_ptr<extensions::ExternalProviderImpl> provider_;
[email protected]27b985d2009-06-25 17:53:15380 scoped_ptr<DictionaryValue> prefs_;
381
382 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
[email protected]a1257b12009-06-12 02:51:34383};
384
[email protected]bf73f0b2010-02-10 19:26:59385// Our message loop may be used in tests which require it to be an IO loop.
[email protected]eaa7dd182010-12-14 11:09:00386ExtensionServiceTestBase::ExtensionServiceTestBase()
[email protected]32e2e9b2011-11-18 18:56:45387 : loop_(MessageLoop::TYPE_IO),
388 service_(NULL),
[email protected]65187152012-06-02 13:14:14389 management_policy_(NULL),
[email protected]8f512c72011-11-22 21:02:50390 expected_extensions_count_(0),
[email protected]ca4b5fa32010-10-09 12:42:18391 ui_thread_(BrowserThread::UI, &loop_),
392 db_thread_(BrowserThread::DB, &loop_),
[email protected]e1dd5622011-12-20 12:28:58393 webkit_thread_(BrowserThread::WEBKIT_DEPRECATED, &loop_),
[email protected]ca4b5fa32010-10-09 12:42:18394 file_thread_(BrowserThread::FILE, &loop_),
[email protected]31dbf9d2011-12-07 01:25:30395 file_user_blocking_thread_(BrowserThread::FILE_USER_BLOCKING, &loop_),
[email protected]ca4b5fa32010-10-09 12:42:18396 io_thread_(BrowserThread::IO, &loop_) {
[email protected]e85e34c32011-04-13 18:38:35397 FilePath test_data_dir;
398 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
399 ADD_FAILURE();
400 return;
401 }
402 data_dir_ = test_data_dir.AppendASCII("extensions");
[email protected]bf73f0b2010-02-10 19:26:59403}
404
[email protected]eaa7dd182010-12-14 11:09:00405ExtensionServiceTestBase::~ExtensionServiceTestBase() {
406 // Drop our reference to ExtensionService and TestingProfile, so that they
[email protected]ca4b5fa32010-10-09 12:42:18407 // can be destroyed while BrowserThreads and MessageLoop are still around
408 // (they are used in the destruction process).
[email protected]bf73f0b2010-02-10 19:26:59409 service_ = NULL;
[email protected]314c3e22012-02-21 03:57:42410 MessageLoop::current()->RunAllPending();
[email protected]c10da4b02010-03-25 14:38:32411 profile_.reset(NULL);
[email protected]bf73f0b2010-02-10 19:26:59412 MessageLoop::current()->RunAllPending();
413}
414
[email protected]eaa7dd182010-12-14 11:09:00415void ExtensionServiceTestBase::InitializeExtensionService(
[email protected]bb05cae12012-09-06 00:37:52416 const FilePath& profile_path,
417 const FilePath& pref_file,
418 const FilePath& extensions_install_dir,
[email protected]90310d92011-04-17 07:35:04419 bool autoupdate_enabled) {
[email protected]bb05cae12012-09-06 00:37:52420 TestingProfile::Builder profile_builder;
[email protected]f2d1f612010-12-09 15:10:17421 // Create a PrefService that only contains user defined preference values.
[email protected]bb05cae12012-09-06 00:37:52422 scoped_ptr<PrefService> prefs(
423 PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create());
424 Profile::RegisterUserPrefs(prefs.get());
425 chrome::RegisterUserPrefs(prefs.get());
426 profile_builder.SetPrefService(prefs.Pass());
427 profile_builder.SetPath(profile_path);
428 profile_ = profile_builder.Build();
[email protected]bf73f0b2010-02-10 19:26:59429
[email protected]bd306722012-07-11 20:43:59430 service_ = static_cast<extensions::TestExtensionSystem*>(
[email protected]bb05cae12012-09-06 00:37:52431 ExtensionSystem::Get(profile_.get()))->CreateExtensionService(
[email protected]31d8f5f22012-04-02 15:22:08432 CommandLine::ForCurrentProcess(),
433 extensions_install_dir,
434 autoupdate_enabled);
[email protected]bf73f0b2010-02-10 19:26:59435 service_->set_extensions_enabled(true);
436 service_->set_show_extensions_prompts(false);
[email protected]bf73f0b2010-02-10 19:26:59437
[email protected]bd306722012-07-11 20:43:59438 management_policy_ = static_cast<extensions::TestExtensionSystem*>(
[email protected]bb05cae12012-09-06 00:37:52439 ExtensionSystem::Get(profile_.get()))->CreateManagementPolicy();
[email protected]65187152012-06-02 13:14:14440
[email protected]bf73f0b2010-02-10 19:26:59441 // When we start up, we want to make sure there is no external provider,
442 // since the ExtensionService on Windows will use the Registry as a default
443 // provider and if there is something already registered there then it will
444 // interfere with the tests. Those tests that need an external provider
445 // will register one specifically.
446 service_->ClearProvidersForTesting();
447
[email protected]8f512c72011-11-22 21:02:50448 expected_extensions_count_ = 0;
[email protected]bf73f0b2010-02-10 19:26:59449}
450
[email protected]eaa7dd182010-12-14 11:09:00451void ExtensionServiceTestBase::InitializeInstalledExtensionService(
[email protected]bf73f0b2010-02-10 19:26:59452 const FilePath& prefs_file, const FilePath& source_install_dir) {
453 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]bb05cae12012-09-06 00:37:52454 FilePath path = temp_dir_.path();
455 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
456 file_util::Delete(path, true);
457 file_util::CreateDirectory(path);
458 FilePath temp_prefs = path.Append(FILE_PATH_LITERAL("Preferences"));
[email protected]bf73f0b2010-02-10 19:26:59459 file_util::CopyFile(prefs_file, temp_prefs);
460
[email protected]bb05cae12012-09-06 00:37:52461 extensions_install_dir_ = path.Append(FILE_PATH_LITERAL("Extensions"));
[email protected]bf73f0b2010-02-10 19:26:59462 file_util::Delete(extensions_install_dir_, true);
463 file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
464
[email protected]bb05cae12012-09-06 00:37:52465 InitializeExtensionService(path, temp_prefs, extensions_install_dir_, false);
[email protected]bf73f0b2010-02-10 19:26:59466}
467
[email protected]eaa7dd182010-12-14 11:09:00468void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
[email protected]90310d92011-04-17 07:35:04469 InitializeExtensionServiceHelper(false);
470}
471
[email protected]406b5a92011-11-08 11:58:26472void ExtensionServiceTestBase::InitializeExtensionProcessManager() {
[email protected]bd306722012-07-11 20:43:59473 static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:24474 ExtensionSystem::Get(profile_.get()))->
[email protected]31d8f5f22012-04-02 15:22:08475 CreateExtensionProcessManager();
[email protected]406b5a92011-11-08 11:58:26476}
477
[email protected]90310d92011-04-17 07:35:04478void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
479 InitializeExtensionServiceHelper(true);
480 service_->updater()->Start();
481}
482
483void ExtensionServiceTestBase::InitializeExtensionServiceHelper(
484 bool autoupdate_enabled) {
[email protected]bf73f0b2010-02-10 19:26:59485 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]bb05cae12012-09-06 00:37:52486 FilePath path = temp_dir_.path();
487 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
488 file_util::Delete(path, true);
489 file_util::CreateDirectory(path);
490 FilePath prefs_filename = path.Append(FILE_PATH_LITERAL("TestPreferences"));
491 extensions_install_dir_ = path.Append(FILE_PATH_LITERAL("Extensions"));
[email protected]bf73f0b2010-02-10 19:26:59492 file_util::Delete(extensions_install_dir_, true);
493 file_util::CreateDirectory(extensions_install_dir_);
494
[email protected]bb05cae12012-09-06 00:37:52495 InitializeExtensionService(path, prefs_filename, extensions_install_dir_,
[email protected]90310d92011-04-17 07:35:04496 autoupdate_enabled);
[email protected]bf73f0b2010-02-10 19:26:59497}
498
[email protected]0d6ec3a72011-09-02 02:09:43499void ExtensionServiceTestBase::InitializeRequestContext() {
500 ASSERT_TRUE(profile_.get());
[email protected]31d8f5f22012-04-02 15:22:08501 TestingProfile* profile =
502 static_cast<TestingProfile*>(profile_.get());
[email protected]0d6ec3a72011-09-02 02:09:43503 profile->CreateRequestContext();
504}
505
[email protected]bf73f0b2010-02-10 19:26:59506// static
[email protected]eaa7dd182010-12-14 11:09:00507void ExtensionServiceTestBase::SetUpTestCase() {
[email protected]bf73f0b2010-02-10 19:26:59508 ExtensionErrorReporter::Init(false); // no noisy errors
509}
510
[email protected]eaa7dd182010-12-14 11:09:00511void ExtensionServiceTestBase::SetUp() {
[email protected]bf73f0b2010-02-10 19:26:59512 ExtensionErrorReporter::GetInstance()->ClearErrors();
513}
514
[email protected]eaa7dd182010-12-14 11:09:00515class ExtensionServiceTest
[email protected]6c2381d2011-10-19 02:52:53516 : public ExtensionServiceTestBase, public content::NotificationObserver {
[email protected]bf73f0b2010-02-10 19:26:59517 public:
[email protected]612a1cb12012-10-17 13:18:03518 ExtensionServiceTest()
519 : installed_(NULL),
520 override_external_install_prompt_(
521 extensions::FeatureSwitch::prompt_for_external_extensions(),
522 false) {
[email protected]432115822011-07-10 15:52:27523 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
[email protected]ad50def52011-10-19 23:17:07524 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27525 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
[email protected]ad50def52011-10-19 23:17:07526 content::NotificationService::AllSources());
[email protected]432115822011-07-10 15:52:27527 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
[email protected]ad50def52011-10-19 23:17:07528 content::NotificationService::AllSources());
[email protected]a9b00ac2009-06-25 21:03:23529 }
[email protected]cc655912009-01-29 23:19:19530
[email protected]432115822011-07-10 15:52:27531 virtual void Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53532 const content::NotificationSource& source,
533 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:27534 switch (type) {
535 case chrome::NOTIFICATION_EXTENSION_LOADED: {
[email protected]6c2381d2011-10-19 02:52:53536 const Extension* extension =
537 content::Details<const Extension>(details).ptr();
[email protected]00cd9c42010-11-02 20:15:57538 loaded_.push_back(make_scoped_refptr(extension));
[email protected]894bb502009-05-21 22:39:57539 // The tests rely on the errors being in a certain order, which can vary
540 // depending on how filesystem iteration works.
541 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
542 break;
543 }
544
[email protected]432115822011-07-10 15:52:27545 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
[email protected]a9f39a312010-12-23 22:14:27546 const Extension* e =
[email protected]1c321ee52012-05-21 03:02:34547 content::Details<extensions::UnloadedExtensionInfo>(
548 details)->extension;
[email protected]9f1087e2009-06-15 17:29:32549 unloaded_id_ = e->id();
[email protected]1c321ee52012-05-21 03:02:34550 extensions::ExtensionList::iterator i =
[email protected]9f1087e2009-06-15 17:29:32551 std::find(loaded_.begin(), loaded_.end(), e);
552 // TODO(erikkay) fix so this can be an assert. Right now the tests
553 // are manually calling clear() on loaded_, so this isn't doable.
554 if (i == loaded_.end())
555 return;
556 loaded_.erase(i);
[email protected]894bb502009-05-21 22:39:57557 break;
[email protected]9f1087e2009-06-15 17:29:32558 }
[email protected]432115822011-07-10 15:52:27559 case chrome::NOTIFICATION_EXTENSION_INSTALLED:
[email protected]6c2381d2011-10-19 02:52:53560 installed_ = content::Details<const Extension>(details).ptr();
[email protected]894bb502009-05-21 22:39:57561 break;
562
[email protected]894bb502009-05-21 22:39:57563 default:
564 DCHECK(false);
[email protected]3acbd422008-12-08 18:25:00565 }
566 }
567
[email protected]5df038b2012-07-16 19:03:27568 void AddMockExternalProvider(
569 extensions::ExternalProviderInterface* provider) {
[email protected]0a60a2e2010-10-25 16:15:21570 service_->AddProviderForTesting(provider);
[email protected]a1257b12009-06-12 02:51:34571 }
572
[email protected]9197f3b2009-06-02 00:49:27573 protected:
[email protected]d55e7602009-12-16 04:20:42574 void TestExternalProvider(MockExtensionProvider* provider,
575 Extension::Location location);
576
[email protected]8f512c72011-11-22 21:02:50577 void PackCRX(const FilePath& dir_path,
578 const FilePath& pem_path,
579 const FilePath& crx_path) {
[email protected]8d888c12010-11-30 00:00:25580 // Use the existing pem key, if provided.
581 FilePath pem_output_path;
582 if (pem_path.value().empty()) {
583 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
[email protected]8d888c12010-11-30 00:00:25584 } else {
585 ASSERT_TRUE(file_util::PathExists(pem_path));
586 }
[email protected]3ba0fd32010-06-19 05:39:10587
588 ASSERT_TRUE(file_util::Delete(crx_path, false));
[email protected]8d888c12010-11-30 00:00:25589
[email protected]3ba0fd32010-06-19 05:39:10590 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
[email protected]8d888c12010-11-30 00:00:25591 ASSERT_TRUE(creator->Run(dir_path,
592 crx_path,
593 pem_path,
[email protected]93d973a2012-01-08 07:38:26594 pem_output_path,
595 ExtensionCreator::kOverwriteCRX));
[email protected]8d888c12010-11-30 00:00:25596
[email protected]3ba0fd32010-06-19 05:39:10597 ASSERT_TRUE(file_util::PathExists(crx_path));
[email protected]8d888c12010-11-30 00:00:25598 }
599
[email protected]53da2c962011-03-03 17:08:05600 // Create a CrxInstaller and start installation. To allow the install
601 // to happen, use loop_.RunAllPending();. Most tests will not use this
[email protected]145a317b2011-04-12 16:03:46602 // method directly. Instead, use InstallCrx(), which waits for
[email protected]53da2c962011-03-03 17:08:05603 // the crx to be installed and does extra error checking.
[email protected]8f512c72011-11-22 21:02:50604 void StartCRXInstall(const FilePath& crx_path) {
[email protected]be083862012-09-01 03:53:45605 StartCRXInstall(crx_path, Extension::NO_FLAGS);
[email protected]8266d662011-07-12 21:53:26606 }
607
[email protected]be083862012-09-01 03:53:45608 void StartCRXInstall(const FilePath& crx_path, int creation_flags) {
[email protected]b2907fd2011-03-25 16:43:37609 ASSERT_TRUE(file_util::PathExists(crx_path))
610 << "Path does not exist: "<< crx_path.value().c_str();
[email protected]d8c8f25f2011-11-02 18:18:01611 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
[email protected]be083862012-09-01 03:53:45612 installer->set_creation_flags(creation_flags);
613 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT)) {
614 installer->set_allow_silent_install(true);
615 }
[email protected]53da2c962011-03-03 17:08:05616 installer->InstallCrx(crx_path);
617 }
618
[email protected]8f512c72011-11-22 21:02:50619 enum InstallState {
620 INSTALL_FAILED,
621 INSTALL_UPDATED,
622 INSTALL_NEW
623 };
624
625 const Extension* PackAndInstallCRX(const FilePath& dir_path,
626 const FilePath& pem_path,
[email protected]be083862012-09-01 03:53:45627 InstallState install_state,
628 int creation_flags) {
[email protected]8f512c72011-11-22 21:02:50629 FilePath crx_path;
630 ScopedTempDir temp_dir;
631 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
632 crx_path = temp_dir.path().AppendASCII("temp.crx");
633
634 PackCRX(dir_path, pem_path, crx_path);
[email protected]be083862012-09-01 03:53:45635 return InstallCRX(crx_path, install_state, creation_flags);
636 }
637
638 const Extension* PackAndInstallCRX(const FilePath& dir_path,
639 const FilePath& pem_path,
640 InstallState install_state) {
641 return PackAndInstallCRX(dir_path, pem_path, install_state,
642 Extension::NO_FLAGS);
[email protected]145a317b2011-04-12 16:03:46643 }
644
[email protected]8f512c72011-11-22 21:02:50645 const Extension* PackAndInstallCRX(const FilePath& dir_path,
646 InstallState install_state) {
[email protected]be083862012-09-01 03:53:45647 return PackAndInstallCRX(dir_path, FilePath(), install_state,
648 Extension::NO_FLAGS);
649 }
650
651 const Extension* InstallCRX(const FilePath& path,
652 InstallState install_state,
653 int creation_flags) {
654 StartCRXInstall(path, creation_flags);
655 return WaitForCrxInstall(path, install_state);
[email protected]8f512c72011-11-22 21:02:50656 }
657
[email protected]65187152012-06-02 13:14:14658 // Attempts to install an extension. Use INSTALL_FAILED if the installation
659 // is expected to fail.
[email protected]8f512c72011-11-22 21:02:50660 const Extension* InstallCRX(const FilePath& path,
661 InstallState install_state) {
[email protected]be083862012-09-01 03:53:45662 return InstallCRX(path, install_state, Extension::NO_FLAGS);
[email protected]8f512c72011-11-22 21:02:50663 }
664
665 const Extension* InstallCRXFromWebStore(const FilePath& path,
666 InstallState install_state) {
[email protected]be083862012-09-01 03:53:45667 StartCRXInstall(path, Extension::FROM_WEBSTORE);
[email protected]8f512c72011-11-22 21:02:50668 return WaitForCrxInstall(path, install_state);
669 }
670
671 const Extension* InstallCRXWithLocation(const FilePath& crx_path,
672 Extension::Location install_location,
673 InstallState install_state) {
674 EXPECT_TRUE(file_util::PathExists(crx_path))
[email protected]145a317b2011-04-12 16:03:46675 << "Path does not exist: "<< crx_path.value().c_str();
[email protected]14908b72011-04-20 06:54:36676 // no client (silent install)
[email protected]d8c8f25f2011-11-02 18:18:01677 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
[email protected]145a317b2011-04-12 16:03:46678
679 installer->set_install_source(install_location);
680 installer->InstallCrx(crx_path);
681
[email protected]8f512c72011-11-22 21:02:50682 return WaitForCrxInstall(crx_path, install_state);
[email protected]145a317b2011-04-12 16:03:46683 }
684
[email protected]65187152012-06-02 13:14:14685 // Wait for a CrxInstaller to finish. Used by InstallCRX. Set the
686 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
[email protected]8f512c72011-11-22 21:02:50687 // Returns an Extension pointer if the install succeeded, NULL otherwise.
688 const Extension* WaitForCrxInstall(const FilePath& path,
689 InstallState install_state) {
[email protected]894bb502009-05-21 22:39:57690 loop_.RunAllPending();
[email protected]fc670822011-12-17 09:33:49691 std::vector<string16> errors = GetErrors();
[email protected]8f512c72011-11-22 21:02:50692 const Extension* extension = NULL;
693 if (install_state != INSTALL_FAILED) {
694 if (install_state == INSTALL_NEW)
695 ++expected_extensions_count_;
[email protected]902f7cd2009-05-22 19:02:19696
[email protected]a57209872009-05-04 22:53:14697 EXPECT_TRUE(installed_) << path.value();
[email protected]9197f3b2009-06-02 00:49:27698
[email protected]8f512c72011-11-22 21:02:50699 EXPECT_EQ(1u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18700 EXPECT_EQ(0u, errors.size()) << path.value();
[email protected]8f512c72011-11-22 21:02:50701 EXPECT_EQ(expected_extensions_count_, service_->extensions()->size()) <<
[email protected]902f7cd2009-05-22 19:02:19702 path.value();
[email protected]8f512c72011-11-22 21:02:50703 extension = loaded_[0];
704 EXPECT_TRUE(service_->GetExtensionById(extension->id(), false)) <<
[email protected]d2d89d82009-06-08 21:01:53705 path.value();
[email protected]fc670822011-12-17 09:33:49706 for (std::vector<string16>::iterator err = errors.begin();
[email protected]bb28e062009-02-27 17:19:18707 err != errors.end(); ++err) {
[email protected]37eeb5a2009-02-26 23:36:17708 LOG(ERROR) << *err;
709 }
[email protected]cc655912009-01-29 23:19:19710 } else {
[email protected]a57209872009-05-04 22:53:14711 EXPECT_FALSE(installed_) << path.value();
[email protected]86a274072009-06-11 02:06:45712 EXPECT_EQ(0u, loaded_.size()) << path.value();
[email protected]bb28e062009-02-27 17:19:18713 EXPECT_EQ(1u, errors.size()) << path.value();
[email protected]cc655912009-01-29 23:19:19714 }
[email protected]bb28e062009-02-27 17:19:18715
[email protected]a57209872009-05-04 22:53:14716 installed_ = NULL;
[email protected]894bb502009-05-21 22:39:57717 loaded_.clear();
[email protected]bb28e062009-02-27 17:19:18718 ExtensionErrorReporter::GetInstance()->ClearErrors();
[email protected]8f512c72011-11-22 21:02:50719 return extension;
[email protected]cc655912009-01-29 23:19:19720 }
721
[email protected]4416c5a2010-06-26 01:28:57722 enum UpdateState {
723 FAILED_SILENTLY,
724 FAILED,
725 UPDATED,
726 INSTALLED,
727 ENABLED
728 };
729
[email protected]98270432012-09-11 20:51:24730 void BlackListWebGL() {
731 static const std::string json_blacklist =
732 "{\n"
733 " \"name\": \"gpu blacklist\",\n"
734 " \"version\": \"1.0\",\n"
735 " \"entries\": [\n"
736 " {\n"
737 " \"id\": 1,\n"
738 " \"blacklist\": [\"webgl\"]\n"
739 " }\n"
740 " ]\n"
741 "}";
[email protected]7e343152012-09-20 21:49:53742 content::GPUInfo gpu_info;
743 content::GpuDataManager::GetInstance()->InitializeForTesting(
744 json_blacklist, gpu_info);
[email protected]98270432012-09-11 20:51:24745 }
746
[email protected]7577a5c52009-07-30 06:21:58747 void UpdateExtension(const std::string& id, const FilePath& in_path,
[email protected]4416c5a2010-06-26 01:28:57748 UpdateState expected_state) {
[email protected]7577a5c52009-07-30 06:21:58749 ASSERT_TRUE(file_util::PathExists(in_path));
[email protected]e957fe52009-06-23 16:51:05750
[email protected]7577a5c52009-07-30 06:21:58751 // We need to copy this to a temporary location because Update() will delete
752 // it.
[email protected]a1295ba22009-09-02 03:33:39753 FilePath path = temp_dir_.path();
754 path = path.Append(in_path.BaseName());
[email protected]7577a5c52009-07-30 06:21:58755 ASSERT_TRUE(file_util::CopyFile(in_path, path));
[email protected]e957fe52009-06-23 16:51:05756
[email protected]4416c5a2010-06-26 01:28:57757 int previous_enabled_extension_count =
758 service_->extensions()->size();
759 int previous_installed_extension_count =
760 previous_enabled_extension_count +
761 service_->disabled_extensions()->size();
762
[email protected]420a0ec2011-06-01 01:07:03763 service_->UpdateExtension(id, path, GURL(), NULL);
[email protected]e957fe52009-06-23 16:51:05764 loop_.RunAllPending();
[email protected]f3113e232010-06-25 01:36:40765
[email protected]fc670822011-12-17 09:33:49766 std::vector<string16> errors = GetErrors();
[email protected]4416c5a2010-06-26 01:28:57767 int error_count = errors.size();
768 int enabled_extension_count =
769 service_->extensions()->size();
770 int installed_extension_count =
771 enabled_extension_count + service_->disabled_extensions()->size();
772
773 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
774 EXPECT_EQ(expected_error_count, error_count) << path.value();
775
776 if (expected_state <= FAILED) {
777 EXPECT_EQ(previous_enabled_extension_count,
778 enabled_extension_count);
779 EXPECT_EQ(previous_installed_extension_count,
780 installed_extension_count);
[email protected]e957fe52009-06-23 16:51:05781 } else {
[email protected]4416c5a2010-06-26 01:28:57782 int expected_installed_extension_count =
783 (expected_state >= INSTALLED) ? 1 : 0;
784 int expected_enabled_extension_count =
785 (expected_state >= ENABLED) ? 1 : 0;
786 EXPECT_EQ(expected_installed_extension_count,
787 installed_extension_count);
788 EXPECT_EQ(expected_enabled_extension_count,
789 enabled_extension_count);
[email protected]e957fe52009-06-23 16:51:05790 }
[email protected]7577a5c52009-07-30 06:21:58791
[email protected]31d8f5f22012-04-02 15:22:08792 // Update() should the temporary input file.
[email protected]7577a5c52009-07-30 06:21:58793 EXPECT_FALSE(file_util::PathExists(path));
[email protected]e957fe52009-06-23 16:51:05794 }
795
[email protected]fa2416f2011-05-03 08:41:20796 void TerminateExtension(const std::string& id) {
797 const Extension* extension = service_->GetInstalledExtension(id);
798 if (!extension) {
799 ADD_FAILURE();
800 return;
801 }
802 service_->TrackTerminatedExtensionForTest(extension);
803 }
804
805 size_t GetPrefKeyCount() {
[email protected]43d3bf82011-04-11 07:46:58806 const DictionaryValue* dict =
807 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]fa2416f2011-05-03 08:41:20808 if (!dict) {
809 ADD_FAILURE();
810 return 0;
811 }
812 return dict->size();
813 }
814
815 void UninstallExtension(const std::string& id, bool use_helper) {
816 // Verify that the extension is installed.
817 FilePath extension_path = extensions_install_dir_.AppendASCII(id);
818 EXPECT_TRUE(file_util::PathExists(extension_path));
819 size_t pref_key_count = GetPrefKeyCount();
820 EXPECT_GT(pref_key_count, 0u);
821 ValidateIntegerPref(id, "state", Extension::ENABLED);
822
823 // Uninstall it.
824 if (use_helper) {
825 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(service_, id));
826 } else {
827 EXPECT_TRUE(service_->UninstallExtension(id, false, NULL));
828 }
[email protected]8f512c72011-11-22 21:02:50829 --expected_extensions_count_;
[email protected]fa2416f2011-05-03 08:41:20830
831 // We should get an unload notification.
832 EXPECT_FALSE(unloaded_id_.empty());
833 EXPECT_EQ(id, unloaded_id_);
834
835 // Verify uninstalled state.
836 size_t new_pref_key_count = GetPrefKeyCount();
837 if (new_pref_key_count == pref_key_count) {
838 ValidateIntegerPref(id, "location",
839 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
840 } else {
841 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
842 }
843
844 // The extension should not be in the service anymore.
845 EXPECT_FALSE(service_->GetInstalledExtension(id));
846 loop_.RunAllPending();
847
848 // The directory should be gone.
849 EXPECT_FALSE(file_util::PathExists(extension_path));
850 }
851
852 void ValidatePrefKeyCount(size_t count) {
853 EXPECT_EQ(count, GetPrefKeyCount());
[email protected]25b34332009-06-05 21:53:19854 }
855
[email protected]6b75ec32009-08-14 06:37:18856 void ValidateBooleanPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34857 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06858 bool expected_val) {
[email protected]e2194742010-08-12 05:54:34859 std::string msg = " while checking: ";
860 msg += extension_id;
861 msg += " ";
[email protected]6b75ec32009-08-14 06:37:18862 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34863 msg += " == ";
864 msg += expected_val ? "true" : "false";
[email protected]6b75ec32009-08-14 06:37:18865
[email protected]2fb7dc982010-09-29 12:24:28866 PrefService* prefs = profile_->GetPrefs();
867 const DictionaryValue* dict =
868 prefs->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18869 ASSERT_TRUE(dict != NULL) << msg;
[email protected]a61890e2012-07-27 22:27:11870 const DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34871 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]6b75ec32009-08-14 06:37:18872 EXPECT_TRUE(pref != NULL) << msg;
873 bool val;
[email protected]4c91487e2009-10-02 04:11:04874 ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06875 EXPECT_EQ(expected_val, val) << msg;
[email protected]6b75ec32009-08-14 06:37:18876 }
877
878 bool IsPrefExist(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34879 const std::string& pref_path) {
[email protected]2fb7dc982010-09-29 12:24:28880 const DictionaryValue* dict =
881 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]6b75ec32009-08-14 06:37:18882 if (dict == NULL) return false;
[email protected]a61890e2012-07-27 22:27:11883 const DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34884 if (!dict->GetDictionary(extension_id, &pref)) {
[email protected]6b75ec32009-08-14 06:37:18885 return false;
886 }
887 if (pref == NULL) {
888 return false;
889 }
890 bool val;
891 if (!pref->GetBoolean(pref_path, &val)) {
892 return false;
893 }
894 return true;
895 }
896
897 void ValidateIntegerPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34898 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06899 int expected_val) {
[email protected]e2194742010-08-12 05:54:34900 std::string msg = " while checking: ";
901 msg += extension_id;
902 msg += " ";
[email protected]25b34332009-06-05 21:53:19903 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34904 msg += " == ";
905 msg += base::IntToString(expected_val);
[email protected]25b34332009-06-05 21:53:19906
[email protected]2fb7dc982010-09-29 12:24:28907 PrefService* prefs = profile_->GetPrefs();
908 const DictionaryValue* dict =
909 prefs->GetDictionary("extensions.settings");
[email protected]25b34332009-06-05 21:53:19910 ASSERT_TRUE(dict != NULL) << msg;
[email protected]a61890e2012-07-27 22:27:11911 const DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34912 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]25b34332009-06-05 21:53:19913 EXPECT_TRUE(pref != NULL) << msg;
914 int val;
[email protected]4c91487e2009-10-02 04:11:04915 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
[email protected]c6d474f82009-12-16 21:11:06916 EXPECT_EQ(expected_val, val) << msg;
917 }
918
919 void ValidateStringPref(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34920 const std::string& pref_path,
[email protected]c6d474f82009-12-16 21:11:06921 const std::string& expected_val) {
[email protected]e2194742010-08-12 05:54:34922 std::string msg = " while checking: ";
923 msg += extension_id;
924 msg += ".manifest.";
[email protected]c6d474f82009-12-16 21:11:06925 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34926 msg += " == ";
927 msg += expected_val;
[email protected]c6d474f82009-12-16 21:11:06928
[email protected]2fb7dc982010-09-29 12:24:28929 const DictionaryValue* dict =
930 profile_->GetPrefs()->GetDictionary("extensions.settings");
[email protected]c6d474f82009-12-16 21:11:06931 ASSERT_TRUE(dict != NULL) << msg;
[email protected]a61890e2012-07-27 22:27:11932 const DictionaryValue* pref = NULL;
[email protected]c6d474f82009-12-16 21:11:06933 std::string manifest_path = extension_id + ".manifest";
[email protected]e2194742010-08-12 05:54:34934 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
[email protected]c6d474f82009-12-16 21:11:06935 EXPECT_TRUE(pref != NULL) << msg;
936 std::string val;
937 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
938 EXPECT_EQ(expected_val, val) << msg;
[email protected]25b34332009-06-05 21:53:19939 }
940
[email protected]8d888c12010-11-30 00:00:25941 void SetPref(const std::string& extension_id,
942 const std::string& pref_path,
943 Value* value,
944 const std::string& msg) {
[email protected]43d3bf82011-04-11 07:46:58945 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
946 DictionaryValue* dict = update.Get();
[email protected]8d888c12010-11-30 00:00:25947 ASSERT_TRUE(dict != NULL) << msg;
948 DictionaryValue* pref = NULL;
949 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
950 EXPECT_TRUE(pref != NULL) << msg;
951 pref->Set(pref_path, value);
952 }
953
[email protected]6b75ec32009-08-14 06:37:18954 void SetPrefInteg(const std::string& extension_id,
[email protected]e2194742010-08-12 05:54:34955 const std::string& pref_path,
[email protected]6b75ec32009-08-14 06:37:18956 int value) {
[email protected]e2194742010-08-12 05:54:34957 std::string msg = " while setting: ";
958 msg += extension_id;
959 msg += " ";
[email protected]a1257b12009-06-12 02:51:34960 msg += pref_path;
[email protected]e2194742010-08-12 05:54:34961 msg += " = ";
962 msg += base::IntToString(value);
[email protected]a1257b12009-06-12 02:51:34963
[email protected]8d888c12010-11-30 00:00:25964 SetPref(extension_id, pref_path, Value::CreateIntegerValue(value), msg);
965 }
966
967 void SetPrefBool(const std::string& extension_id,
968 const std::string& pref_path,
969 bool value) {
970 std::string msg = " while setting: ";
971 msg += extension_id + " " + pref_path;
972 msg += " = ";
973 msg += (value ? "true" : "false");
974
975 SetPref(extension_id, pref_path, Value::CreateBooleanValue(value), msg);
976 }
977
978 void ClearPref(const std::string& extension_id,
979 const std::string& pref_path) {
980 std::string msg = " while clearing: ";
981 msg += extension_id + " " + pref_path;
982
[email protected]43d3bf82011-04-11 07:46:58983 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
984 DictionaryValue* dict = update.Get();
[email protected]a1257b12009-06-12 02:51:34985 ASSERT_TRUE(dict != NULL) << msg;
986 DictionaryValue* pref = NULL;
[email protected]e2194742010-08-12 05:54:34987 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
[email protected]a1257b12009-06-12 02:51:34988 EXPECT_TRUE(pref != NULL) << msg;
[email protected]8d888c12010-11-30 00:00:25989 pref->Remove(pref_path, NULL);
990 }
991
992 void SetPrefStringSet(const std::string& extension_id,
993 const std::string& pref_path,
994 const std::set<std::string>& value) {
995 std::string msg = " while setting: ";
996 msg += extension_id + " " + pref_path;
997
998 ListValue* list_value = new ListValue();
999 for (std::set<std::string>::const_iterator iter = value.begin();
1000 iter != value.end(); ++iter)
1001 list_value->Append(Value::CreateStringValue(*iter));
1002
1003 SetPref(extension_id, pref_path, list_value, msg);
[email protected]a1257b12009-06-12 02:51:341004 }
1005
[email protected]25b34332009-06-05 21:53:191006 protected:
[email protected]1c321ee52012-05-21 03:02:341007 extensions::ExtensionList loaded_;
[email protected]894bb502009-05-21 22:39:571008 std::string unloaded_id_;
[email protected]9adb9692010-10-29 23:14:021009 const Extension* installed_;
[email protected]612a1cb12012-10-17 13:18:031010 extensions::FeatureSwitch::ScopedOverride override_external_install_prompt_;
[email protected]894bb502009-05-21 22:39:571011
[email protected]6014d672008-12-05 00:38:251012 private:
[email protected]6c2381d2011-10-19 02:52:531013 content::NotificationRegistrar registrar_;
[email protected]bb28e062009-02-27 17:19:181014};
[email protected]6014d672008-12-05 00:38:251015
[email protected]0349ab5d2010-08-11 21:41:571016// Receives notifications from a PackExtensionJob, indicating either that
1017// packing succeeded or that there was some error.
[email protected]d9ede582012-08-14 19:21:381018class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
[email protected]0349ab5d2010-08-11 21:41:571019 public:
1020 PackExtensionTestClient(const FilePath& expected_crx_path,
1021 const FilePath& expected_private_key_path);
1022 virtual void OnPackSuccess(const FilePath& crx_path,
1023 const FilePath& private_key_path);
[email protected]93d973a2012-01-08 07:38:261024 virtual void OnPackFailure(const std::string& error_message,
1025 ExtensionCreator::ErrorType type);
[email protected]0349ab5d2010-08-11 21:41:571026
1027 private:
1028 const FilePath expected_crx_path_;
1029 const FilePath expected_private_key_path_;
1030 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1031};
1032
1033PackExtensionTestClient::PackExtensionTestClient(
1034 const FilePath& expected_crx_path,
1035 const FilePath& expected_private_key_path)
1036 : expected_crx_path_(expected_crx_path),
1037 expected_private_key_path_(expected_private_key_path) {}
1038
1039// If packing succeeded, we make sure that the package names match our
1040// expectations.
1041void PackExtensionTestClient::OnPackSuccess(const FilePath& crx_path,
1042 const FilePath& private_key_path) {
1043 // We got the notification and processed it; we don't expect any further tasks
1044 // to be posted to the current thread, so we should stop blocking and continue
1045 // on with the rest of the test.
1046 // This call to |Quit()| matches the call to |Run()| in the
1047 // |PackPunctuatedExtension| test.
1048 MessageLoop::current()->Quit();
1049 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1050 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1051 ASSERT_TRUE(file_util::PathExists(private_key_path));
1052}
1053
1054// The tests are designed so that we never expect to see a packing error.
[email protected]93d973a2012-01-08 07:38:261055void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1056 ExtensionCreator::ErrorType type) {
1057 if (type == ExtensionCreator::kCRXExists)
1058 FAIL() << "Packing should not fail.";
1059 else
1060 FAIL() << "Existing CRX should have been overwritten.";
[email protected]0349ab5d2010-08-11 21:41:571061}
1062
[email protected]54cb3c92009-02-17 22:30:211063// Test loading good extensions from the profile directory.
[email protected]eaa7dd182010-12-14 11:09:001064TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
[email protected]183d4b82011-11-11 18:50:261065 PluginService::GetInstance()->Init();
1066
[email protected]a9b00ac2009-06-25 21:03:231067 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:351068 FilePath source_install_dir = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231069 .AppendASCII("good")
1070 .AppendASCII("Extensions");
1071 FilePath pref_path = source_install_dir
1072 .DirName()
1073 .AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:001074 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]6014d672008-12-05 00:38:251075
[email protected]9f1087e2009-06-15 17:29:321076 service_->Init();
[email protected]6014d672008-12-05 00:38:251077
[email protected]e50013c32010-08-18 21:05:241078 uint32 expected_num_extensions = 3u;
[email protected]e50013c32010-08-18 21:05:241079 ASSERT_EQ(expected_num_extensions, loaded_.size());
[email protected]6014d672008-12-05 00:38:251080
[email protected]fbcc40302009-06-12 20:45:451081 EXPECT_EQ(std::string(good0), loaded_[0]->id());
[email protected]e1cec06c2008-12-18 01:22:231082 EXPECT_EQ(std::string("My extension 1"),
[email protected]894bb502009-05-21 22:39:571083 loaded_[0]->name());
[email protected]e1cec06c2008-12-18 01:22:231084 EXPECT_EQ(std::string("The first extension that I made."),
[email protected]894bb502009-05-21 22:39:571085 loaded_[0]->description());
1086 EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location());
[email protected]61b411612009-11-10 23:17:411087 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
[email protected]e50013c32010-08-18 21:05:241088 EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
[email protected]eab9b452009-01-23 20:48:591089
[email protected]25b34332009-06-05 21:53:191090 ValidatePrefKeyCount(3);
[email protected]e2194742010-08-12 05:54:341091 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1092 ValidateIntegerPref(good0, "location", Extension::INTERNAL);
1093 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1094 ValidateIntegerPref(good1, "location", Extension::INTERNAL);
1095 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1096 ValidateIntegerPref(good2, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:191097
[email protected]06e8b8ff2011-07-13 15:03:471098 URLPatternSet expected_patterns;
1099 AddPattern(&expected_patterns, "file:///*");
1100 AddPattern(&expected_patterns, "http://*.google.com/*");
1101 AddPattern(&expected_patterns, "https://*.google.com/*");
[email protected]9adb9692010-10-29 23:14:021102 const Extension* extension = loaded_[0];
[email protected]20f97c92012-07-13 23:12:371103 const extensions::UserScriptList& scripts = extension->content_scripts();
[email protected]e66de892009-03-20 20:38:431104 ASSERT_EQ(2u, scripts.size());
[email protected]06e8b8ff2011-07-13 15:03:471105 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
[email protected]e66de892009-03-20 20:38:431106 EXPECT_EQ(2u, scripts[0].js_scripts().size());
[email protected]052c92702010-06-25 07:25:521107 ExtensionResource resource00(extension->id(),
1108 scripts[0].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:211109 scripts[0].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:291110 FilePath expected_path(extension->path().AppendASCII("script1.js"));
1111 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
1112 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
[email protected]052c92702010-06-25 07:25:521113 ExtensionResource resource01(extension->id(),
1114 scripts[0].js_scripts()[1].extension_root(),
[email protected]9194b3f2009-10-20 15:27:211115 scripts[0].js_scripts()[1].relative_path());
[email protected]a14b16b2009-10-28 12:41:291116 expected_path = extension->path().AppendASCII("script2.js");
1117 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
1118 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
[email protected]c533bb22009-06-03 19:06:111119 EXPECT_TRUE(extension->plugins().empty());
[email protected]06e8b8ff2011-07-13 15:03:471120 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1121 EXPECT_EQ("http://*.news.com/*",
1122 scripts[1].url_patterns().begin()->GetAsString());
[email protected]052c92702010-06-25 07:25:521123 ExtensionResource resource10(extension->id(),
1124 scripts[1].js_scripts()[0].extension_root(),
[email protected]9194b3f2009-10-20 15:27:211125 scripts[1].js_scripts()[0].relative_path());
[email protected]a14b16b2009-10-28 12:41:291126 expected_path =
1127 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1128 ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
1129 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
[email protected]06e8b8ff2011-07-13 15:03:471130
1131 expected_patterns.ClearPatterns();
1132 AddPattern(&expected_patterns, "http://*.google.com/*");
1133 AddPattern(&expected_patterns, "https://*.google.com/*");
[email protected]902fd7b2011-07-27 18:42:311134 EXPECT_EQ(expected_patterns,
1135 extension->GetActivePermissions()->explicit_hosts());
[email protected]6014d672008-12-05 00:38:251136
[email protected]25b34332009-06-05 21:53:191137 EXPECT_EQ(std::string(good1), loaded_[1]->id());
[email protected]894bb502009-05-21 22:39:571138 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1139 EXPECT_EQ(std::string(""), loaded_[1]->description());
[email protected]81067e02009-07-27 15:12:091140 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
[email protected]a03d4448f2012-01-10 23:25:281141 loaded_[1]->GetBackgroundURL());
[email protected]894bb502009-05-21 22:39:571142 EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
[email protected]b8fb3032011-04-29 18:45:561143 // We don't parse the plugins section on Chrome OS.
1144#if defined(OS_CHROMEOS)
1145 EXPECT_EQ(0u, loaded_[1]->plugins().size());
1146#else
1147 ASSERT_EQ(2u, loaded_[1]->plugins().size());
[email protected]c533bb22009-06-03 19:06:111148 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1149 loaded_[1]->plugins()[0].path.value());
1150 EXPECT_TRUE(loaded_[1]->plugins()[0].is_public);
1151 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1152 loaded_[1]->plugins()[1].path.value());
1153 EXPECT_FALSE(loaded_[1]->plugins()[1].is_public);
[email protected]e50013c32010-08-18 21:05:241154#endif
[email protected]18a12352009-01-31 01:33:281155
[email protected]b8fb3032011-04-29 18:45:561156 EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location());
1157
[email protected]e50013c32010-08-18 21:05:241158 int index = expected_num_extensions - 1;
1159 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1160 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1161 EXPECT_EQ(std::string(""), loaded_[index]->description());
1162 EXPECT_EQ(0u, loaded_[index]->content_scripts().size());
1163 EXPECT_EQ(Extension::INTERNAL, loaded_[index]->location());
[email protected]6014d672008-12-05 00:38:251164};
[email protected]cc655912009-01-29 23:19:191165
[email protected]54cb3c92009-02-17 22:30:211166// Test loading bad extensions from the profile directory.
[email protected]eaa7dd182010-12-14 11:09:001167TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
[email protected]c6d474f82009-12-16 21:11:061168 // Initialize the test dir with a bad Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:351169 FilePath source_install_dir = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231170 .AppendASCII("bad")
1171 .AppendASCII("Extensions");
1172 FilePath pref_path = source_install_dir
1173 .DirName()
1174 .AppendASCII("Preferences");
[email protected]54cb3c92009-02-17 22:30:211175
[email protected]eaa7dd182010-12-14 11:09:001176 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]54cb3c92009-02-17 22:30:211177
[email protected]9f1087e2009-06-15 17:29:321178 service_->Init();
[email protected]54cb3c92009-02-17 22:30:211179
[email protected]a9b00ac2009-06-25 21:03:231180 ASSERT_EQ(4u, GetErrors().size());
1181 ASSERT_EQ(0u, loaded_.size());
[email protected]25b34332009-06-05 21:53:191182
[email protected]fc670822011-12-17 09:33:491183 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[0]),
[email protected]d7b36dc2009-10-29 21:47:401184 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491185 extension_manifest_errors::kManifestUnreadable)) <<
1186 UTF16ToUTF8(GetErrors()[0]);
[email protected]8d6d9ff2009-02-20 08:14:391187
[email protected]fc670822011-12-17 09:33:491188 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[1]),
[email protected]8d6d9ff2009-02-20 08:14:391189 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491190 extension_manifest_errors::kManifestUnreadable)) <<
1191 UTF16ToUTF8(GetErrors()[1]);
[email protected]8d6d9ff2009-02-20 08:14:391192
[email protected]fc670822011-12-17 09:33:491193 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[2]),
[email protected]8d6d9ff2009-02-20 08:14:391194 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491195 extension_manifest_errors::kMissingFile)) <<
1196 UTF16ToUTF8(GetErrors()[2]);
[email protected]a9b00ac2009-06-25 21:03:231197
[email protected]fc670822011-12-17 09:33:491198 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]),
[email protected]a9b00ac2009-06-25 21:03:231199 std::string("Could not load extension from '*'. ") +
[email protected]fc670822011-12-17 09:33:491200 extension_manifest_errors::kManifestUnreadable)) <<
1201 UTF16ToUTF8(GetErrors()[3]);
[email protected]54cb3c92009-02-17 22:30:211202};
1203
[email protected]2f8757c32012-06-19 19:17:471204// Test that partially deleted extensions are cleaned up during startup
[email protected]894bb502009-05-21 22:39:571205// Test loading bad extensions from the profile directory.
[email protected]2f8757c32012-06-19 19:17:471206TEST_F(ExtensionServiceTest, CleanupOnStartup) {
[email protected]183d4b82011-11-11 18:50:261207 PluginService::GetInstance()->Init();
1208
[email protected]e85e34c32011-04-13 18:38:351209 FilePath source_install_dir = data_dir_
[email protected]b6ab96d2009-08-20 18:58:191210 .AppendASCII("good")
1211 .AppendASCII("Extensions");
1212 FilePath pref_path = source_install_dir
1213 .DirName()
1214 .AppendASCII("Preferences");
[email protected]a9b00ac2009-06-25 21:03:231215
[email protected]eaa7dd182010-12-14 11:09:001216 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]894bb502009-05-21 22:39:571217
[email protected]b6ab96d2009-08-20 18:58:191218 // Simulate that one of them got partially deleted by clearing its pref.
[email protected]43d3bf82011-04-11 07:46:581219 {
1220 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1221 DictionaryValue* dict = update.Get();
[email protected]2f8757c32012-06-19 19:17:471222 ASSERT_TRUE(dict != NULL);
[email protected]43d3bf82011-04-11 07:46:581223 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1224 }
[email protected]894bb502009-05-21 22:39:571225
1226 service_->Init();
[email protected]8f512c72011-11-22 21:02:501227 // Wait for GarbageCollectExtensions task to complete.
[email protected]894bb502009-05-21 22:39:571228 loop_.RunAllPending();
1229
[email protected]a9b00ac2009-06-25 21:03:231230 file_util::FileEnumerator dirs(extensions_install_dir_, false,
[email protected]9f1087e2009-06-15 17:29:321231 file_util::FileEnumerator::DIRECTORIES);
1232 size_t count = 0;
1233 while (!dirs.Next().empty())
1234 count++;
1235
[email protected]894bb502009-05-21 22:39:571236 // We should have only gotten two extensions now.
[email protected]9f1087e2009-06-15 17:29:321237 EXPECT_EQ(2u, count);
[email protected]e2eb43112009-05-29 21:19:541238
[email protected]894bb502009-05-21 22:39:571239 // And extension1 dir should now be toast.
[email protected]b6ab96d2009-08-20 18:58:191240 FilePath extension_dir = extensions_install_dir_
1241 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1242 ASSERT_FALSE(file_util::PathExists(extension_dir));
[email protected]894bb502009-05-21 22:39:571243}
1244
[email protected]d7eaf572009-07-01 21:57:001245// Test installing extensions. This test tries to install few extensions using
1246// crx files. If you need to change those crx files, feel free to repackage
1247// them, throw away the key used and change the id's above.
[email protected]eaa7dd182010-12-14 11:09:001248TEST_F(ExtensionServiceTest, InstallExtension) {
1249 InitializeEmptyExtensionService();
[email protected]a9b00ac2009-06-25 21:03:231250
[email protected]e2eb43112009-05-29 21:19:541251 // Extensions not enabled.
[email protected]7577a5c52009-07-30 06:21:581252 set_extensions_enabled(false);
[email protected]e85e34c32011-04-13 18:38:351253 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:501254 InstallCRX(path, INSTALL_FAILED);
[email protected]7577a5c52009-07-30 06:21:581255 set_extensions_enabled(true);
[email protected]e2eb43112009-05-29 21:19:541256
[email protected]25b34332009-06-05 21:53:191257 ValidatePrefKeyCount(0);
1258
[email protected]e2eb43112009-05-29 21:19:541259 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:351260 path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:501261 InstallCRX(path, INSTALL_NEW);
[email protected]cc655912009-01-29 23:19:191262 // TODO(erikkay): verify the contents of the installed extension.
1263
[email protected]25b34332009-06-05 21:53:191264 int pref_count = 0;
1265 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341266 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1267 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]25b34332009-06-05 21:53:191268
[email protected]902f7cd2009-05-22 19:02:191269 // An extension with page actions.
[email protected]e85e34c32011-04-13 18:38:351270 path = data_dir_.AppendASCII("page_action.crx");
[email protected]8f512c72011-11-22 21:02:501271 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:191272 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341273 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1274 ValidateIntegerPref(page_action, "location", Extension::INTERNAL);
[email protected]902f7cd2009-05-22 19:02:191275
[email protected]9f1087e2009-06-15 17:29:321276 // Bad signature.
[email protected]e85e34c32011-04-13 18:38:351277 path = data_dir_.AppendASCII("bad_signature.crx");
[email protected]8f512c72011-11-22 21:02:501278 InstallCRX(path, INSTALL_FAILED);
[email protected]d7eaf572009-07-01 21:57:001279 ValidatePrefKeyCount(pref_count);
[email protected]fbcc40302009-06-12 20:45:451280
[email protected]cc655912009-01-29 23:19:191281 // 0-length extension file.
[email protected]e85e34c32011-04-13 18:38:351282 path = data_dir_.AppendASCII("not_an_extension.crx");
[email protected]8f512c72011-11-22 21:02:501283 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:191284 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191285
1286 // Bad magic number.
[email protected]e85e34c32011-04-13 18:38:351287 path = data_dir_.AppendASCII("bad_magic.crx");
[email protected]8f512c72011-11-22 21:02:501288 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:191289 ValidatePrefKeyCount(pref_count);
[email protected]cc655912009-01-29 23:19:191290
[email protected]8ef78fd2010-08-19 17:14:321291 // Extensions cannot have folders or files that have underscores except in
[email protected]99872e32009-09-25 22:02:491292 // certain whitelisted cases (eg _locales). This is an example of a broader
1293 // class of validation that we do to the directory structure of the extension.
1294 // We did not used to handle this correctly for installation.
[email protected]e85e34c32011-04-13 18:38:351295 path = data_dir_.AppendASCII("bad_underscore.crx");
[email protected]8f512c72011-11-22 21:02:501296 InstallCRX(path, INSTALL_FAILED);
[email protected]99872e32009-09-25 22:02:491297 ValidatePrefKeyCount(pref_count);
1298
[email protected]cc655912009-01-29 23:19:191299 // TODO(erikkay): add more tests for many of the failure cases.
1300 // TODO(erikkay): add tests for upgrade cases.
1301}
1302
[email protected]1bf73cc32011-10-26 22:38:311303// Tests that flags passed to OnExternalExtensionFileFound() make it to the
1304// extension object.
1305TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
[email protected]a12ce8b22012-01-17 18:40:531306 const char kPrefFromBookmark[] = "from_bookmark";
1307
[email protected]1bf73cc32011-10-26 22:38:311308 InitializeEmptyExtensionService();
1309
1310 FilePath path = data_dir_.AppendASCII("good.crx");
1311 set_extensions_enabled(true);
1312
[email protected]a12ce8b22012-01-17 18:40:531313 // Register and install an external extension.
[email protected]12126d372012-07-11 18:40:531314 Version version("1.0.0.0");
[email protected]f121003b2012-05-04 21:57:471315 service_->OnExternalExtensionFileFound(
1316 good_crx,
[email protected]12126d372012-07-11 18:40:531317 &version,
[email protected]f121003b2012-05-04 21:57:471318 path,
1319 Extension::EXTERNAL_PREF,
1320 Extension::FROM_BOOKMARK,
1321 false /* mark_acknowledged */);
[email protected]1bf73cc32011-10-26 22:38:311322 loop_.RunAllPending();
1323
1324 const Extension* extension = service_->GetExtensionById(good_crx, false);
1325 ASSERT_TRUE(extension);
[email protected]a12ce8b22012-01-17 18:40:531326 ASSERT_TRUE(extension->from_bookmark());
1327 ValidateBooleanPref(good_crx, kPrefFromBookmark, true);
1328
1329 // Upgrade to version 2.0, the flag should be preserved.
1330 path = data_dir_.AppendASCII("good2.crx");
1331 UpdateExtension(good_crx, path, ENABLED);
1332 ValidateBooleanPref(good_crx, kPrefFromBookmark, true);
1333 extension = service_->GetExtensionById(good_crx, false);
1334 ASSERT_TRUE(extension);
1335 ASSERT_TRUE(extension->from_bookmark());
[email protected]1bf73cc32011-10-26 22:38:311336}
1337
[email protected]79c833b52011-04-05 18:31:011338// Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1339TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
[email protected]eaa7dd182010-12-14 11:09:001340 InitializeEmptyExtensionService();
[email protected]683d0702010-12-06 16:25:571341
[email protected]e85e34c32011-04-13 18:38:351342 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]683d0702010-12-06 16:25:571343 set_extensions_enabled(true);
1344
[email protected]12126d372012-07-11 18:40:531345 Version version("1.0.0.0");
[email protected]683d0702010-12-06 16:25:571346 // Install an external extension.
[email protected]12126d372012-07-11 18:40:531347 service_->OnExternalExtensionFileFound(good_crx, &version,
[email protected]1bf73cc32011-10-26 22:38:311348 path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511349 Extension::NO_FLAGS, false);
[email protected]683d0702010-12-06 16:25:571350 loop_.RunAllPending();
[email protected]604322d2011-03-22 16:51:561351 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]683d0702010-12-06 16:25:571352
1353 // Uninstall it and check that its killbit gets set.
[email protected]fa2416f2011-05-03 08:41:201354 UninstallExtension(good_crx, false);
[email protected]79c833b52011-04-05 18:31:011355 ValidateIntegerPref(good_crx, "location",
1356 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571357
1358 // Try to re-install it externally. This should fail because of the killbit.
[email protected]12126d372012-07-11 18:40:531359 service_->OnExternalExtensionFileFound(good_crx, &version,
[email protected]1bf73cc32011-10-26 22:38:311360 path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511361 Extension::NO_FLAGS, false);
[email protected]683d0702010-12-06 16:25:571362 loop_.RunAllPending();
1363 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
[email protected]79c833b52011-04-05 18:31:011364 ValidateIntegerPref(good_crx, "location",
1365 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571366
[email protected]12126d372012-07-11 18:40:531367 version = Version("1.0.0.1");
[email protected]683d0702010-12-06 16:25:571368 // Repeat the same thing with a newer version of the extension.
[email protected]e85e34c32011-04-13 18:38:351369 path = data_dir_.AppendASCII("good2.crx");
[email protected]12126d372012-07-11 18:40:531370 service_->OnExternalExtensionFileFound(good_crx, &version,
[email protected]1bf73cc32011-10-26 22:38:311371 path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511372 Extension::NO_FLAGS, false);
[email protected]683d0702010-12-06 16:25:571373 loop_.RunAllPending();
1374 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
[email protected]79c833b52011-04-05 18:31:011375 ValidateIntegerPref(good_crx, "location",
1376 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]683d0702010-12-06 16:25:571377
1378 // Try adding the same extension from an external update URL.
[email protected]9060d8b02012-01-13 02:14:301379 ASSERT_FALSE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]683d0702010-12-06 16:25:571380 good_crx,
1381 GURL("http:://fake.update/url"),
[email protected]9060d8b02012-01-13 02:14:301382 Extension::EXTERNAL_PREF_DOWNLOAD));
[email protected]b2907fd2011-03-25 16:43:371383
1384 ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
[email protected]683d0702010-12-06 16:25:571385}
1386
[email protected]0f48fca2011-05-19 18:46:351387// Test that uninstalling an external extension does not crash when
1388// the extension could not be loaded.
1389// This extension shown in preferences file requires an experimental permission.
1390// It could not be loaded without such permission.
1391TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1392 FilePath source_install_dir = data_dir_
1393 .AppendASCII("good")
1394 .AppendASCII("Extensions");
1395 // The preference contains an external extension
1396 // that requires 'experimental' permission.
1397 FilePath pref_path = source_install_dir
1398 .DirName()
1399 .AppendASCII("PreferencesExperimental");
1400
1401 // Aforementioned extension will not be loaded if
1402 // there is no '--enable-experimental-extension-apis' command line flag.
1403 InitializeInstalledExtensionService(pref_path, source_install_dir);
1404
1405 service_->Init();
[email protected]0f48fca2011-05-19 18:46:351406
1407 // Check and try to uninstall it.
1408 // If we don't check whether the extension is loaded before we uninstall it
1409 // in CheckExternalUninstall, a crash will happen here because we will get or
1410 // dereference a NULL pointer (extension) inside UninstallExtension.
[email protected]50067e52011-10-20 23:17:071411 MockExtensionProvider provider(NULL, Extension::EXTERNAL_REGISTRY);
1412 service_->OnExternalProviderReady(&provider);
[email protected]0f48fca2011-05-19 18:46:351413}
1414
[email protected]604322d2011-03-22 16:51:561415// Test that external extensions with incorrect IDs are not installed.
1416TEST_F(ExtensionServiceTest, FailOnWrongId) {
1417 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351418 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]604322d2011-03-22 16:51:561419 set_extensions_enabled(true);
1420
[email protected]12126d372012-07-11 18:40:531421 Version version("1.0.0.0");
[email protected]604322d2011-03-22 16:51:561422
1423 const std::string wrong_id = all_zero;
1424 const std::string correct_id = good_crx;
1425 ASSERT_NE(correct_id, wrong_id);
1426
1427 // Install an external extension with an ID from the external
1428 // source that is not equal to the ID in the extension manifest.
1429 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531430 wrong_id, &version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511431 Extension::NO_FLAGS, false);
[email protected]604322d2011-03-22 16:51:561432
1433 loop_.RunAllPending();
1434 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1435
1436 // Try again with the right ID. Expect success.
1437 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531438 correct_id, &version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511439 Extension::NO_FLAGS, false);
[email protected]604322d2011-03-22 16:51:561440 loop_.RunAllPending();
1441 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1442}
1443
1444// Test that external extensions with incorrect versions are not installed.
1445TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1446 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351447 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]604322d2011-03-22 16:51:561448 set_extensions_enabled(true);
1449
1450 // Install an external extension with a version from the external
1451 // source that is not equal to the version in the extension manifest.
[email protected]12126d372012-07-11 18:40:531452 Version wrong_version("1.2.3.4");
[email protected]604322d2011-03-22 16:51:561453 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531454 good_crx, &wrong_version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511455 Extension::NO_FLAGS, false);
[email protected]604322d2011-03-22 16:51:561456
1457 loop_.RunAllPending();
1458 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1459
1460 // Try again with the right version. Expect success.
[email protected]e3987852012-05-04 10:06:301461 service_->pending_extension_manager()->Remove(good_crx);
[email protected]12126d372012-07-11 18:40:531462 Version correct_version("1.0.0.0");
[email protected]604322d2011-03-22 16:51:561463 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:531464 good_crx, &correct_version, path, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:511465 Extension::NO_FLAGS, false);
[email protected]604322d2011-03-22 16:51:561466 loop_.RunAllPending();
1467 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1468}
1469
[email protected]da0aa3b2009-12-06 21:41:031470// Install a user script (they get converted automatically to an extension)
[email protected]eaa7dd182010-12-14 11:09:001471TEST_F(ExtensionServiceTest, InstallUserScript) {
[email protected]da0aa3b2009-12-06 21:41:031472 // The details of script conversion are tested elsewhere, this just tests
[email protected]eaa7dd182010-12-14 11:09:001473 // integration with ExtensionService.
1474 InitializeEmptyExtensionService();
[email protected]da0aa3b2009-12-06 21:41:031475
[email protected]e85e34c32011-04-13 18:38:351476 FilePath path = data_dir_
[email protected]da0aa3b2009-12-06 21:41:031477 .AppendASCII("user_script_basic.user.js");
1478
1479 ASSERT_TRUE(file_util::PathExists(path));
[email protected]d8c8f25f2011-11-02 18:18:011480 scoped_refptr<CrxInstaller> installer(CrxInstaller::Create(service_, NULL));
[email protected]0d3e4a22011-06-23 19:02:521481 installer->set_allow_silent_install(true);
[email protected]6dfbbf82010-03-12 23:09:161482 installer->InstallUserScript(
[email protected]da0aa3b2009-12-06 21:41:031483 path,
[email protected]6dfbbf82010-03-12 23:09:161484 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
[email protected]da0aa3b2009-12-06 21:41:031485
1486 loop_.RunAllPending();
[email protected]fc670822011-12-17 09:33:491487 std::vector<string16> errors = GetErrors();
[email protected]da0aa3b2009-12-06 21:41:031488 EXPECT_TRUE(installed_) << "Nothing was installed.";
1489 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1490 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1491 << JoinString(errors, ',');
1492 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
1493 path.value();
1494
1495 installed_ = NULL;
1496 loaded_.clear();
1497 ExtensionErrorReporter::GetInstance()->ClearErrors();
1498}
1499
[email protected]8d888c12010-11-30 00:00:251500// This tests that the granted permissions preferences are correctly set when
1501// installing an extension.
[email protected]eaa7dd182010-12-14 11:09:001502TEST_F(ExtensionServiceTest, GrantedPermissions) {
1503 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351504 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251505 .AppendASCII("permissions");
1506
[email protected]e85e34c32011-04-13 18:38:351507 FilePath pem_path = path.AppendASCII("unknown.pem");
[email protected]8d888c12010-11-30 00:00:251508 path = path.AppendASCII("unknown");
1509
1510 ASSERT_TRUE(file_util::PathExists(pem_path));
1511 ASSERT_TRUE(file_util::PathExists(path));
1512
1513 ExtensionPrefs* prefs = service_->extension_prefs();
1514
[email protected]c2e66e12012-06-27 06:27:061515 APIPermissionSet expected_api_perms;
[email protected]cced75a2011-05-20 08:31:121516 URLPatternSet expected_host_perms;
[email protected]8d888c12010-11-30 00:00:251517
1518 // Make sure there aren't any granted permissions before the
1519 // extension is installed.
[email protected]c2e66e12012-06-27 06:27:061520 scoped_refptr<PermissionSet> known_perms(
[email protected]0d3e4a22011-06-23 19:02:521521 prefs->GetGrantedPermissions(permissions_crx));
1522 EXPECT_FALSE(known_perms.get());
[email protected]8d888c12010-11-30 00:00:251523
[email protected]8f512c72011-11-22 21:02:501524 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251525
1526 EXPECT_EQ(0u, GetErrors().size());
1527 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:501528 EXPECT_EQ(permissions_crx, extension->id());
[email protected]8d888c12010-11-30 00:00:251529
[email protected]8d888c12010-11-30 00:00:251530 // Verify that the valid API permissions have been recognized.
[email protected]c2e66e12012-06-27 06:27:061531 expected_api_perms.insert(APIPermission::kTab);
[email protected]8d888c12010-11-30 00:00:251532
1533 AddPattern(&expected_host_perms, "http://*.google.com/*");
1534 AddPattern(&expected_host_perms, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151535 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251536 AddPattern(&expected_host_perms, "http://www.example.com/*");
1537
[email protected]8f512c72011-11-22 21:02:501538 known_perms = prefs->GetGrantedPermissions(extension->id());
[email protected]0d3e4a22011-06-23 19:02:521539 EXPECT_TRUE(known_perms.get());
1540 EXPECT_FALSE(known_perms->IsEmpty());
1541 EXPECT_EQ(expected_api_perms, known_perms->apis());
1542 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
[email protected]06e8b8ff2011-07-13 15:03:471543 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251544}
1545
[email protected]be083862012-09-01 03:53:451546
1547#if !defined(OS_CHROMEOS)
1548// This tests that the granted permissions preferences are correctly set for
1549// default apps.
1550TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1551 InitializeEmptyExtensionService();
1552 InitializeRequestContext();
1553 FilePath path = data_dir_
1554 .AppendASCII("permissions");
1555
1556 FilePath pem_path = path.AppendASCII("unknown.pem");
1557 path = path.AppendASCII("unknown");
1558
1559 ASSERT_TRUE(file_util::PathExists(pem_path));
1560 ASSERT_TRUE(file_util::PathExists(path));
1561
1562 ExtensionPrefs* prefs = service_->extension_prefs();
1563
1564 APIPermissionSet expected_api_perms;
1565 URLPatternSet expected_host_perms;
1566
1567 // Make sure there aren't any granted permissions before the
1568 // extension is installed.
1569 scoped_refptr<PermissionSet> known_perms(
1570 prefs->GetGrantedPermissions(permissions_crx));
1571 EXPECT_FALSE(known_perms.get());
1572
1573 const Extension* extension = PackAndInstallCRX(
1574 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1575
1576 EXPECT_EQ(0u, GetErrors().size());
1577 ASSERT_EQ(1u, service_->extensions()->size());
1578 EXPECT_EQ(permissions_crx, extension->id());
1579
1580 // Verify that the valid API permissions have been recognized.
1581 expected_api_perms.insert(APIPermission::kTab);
1582
1583 known_perms = prefs->GetGrantedPermissions(extension->id());
1584 EXPECT_TRUE(known_perms.get());
1585 EXPECT_FALSE(known_perms->IsEmpty());
1586 EXPECT_EQ(expected_api_perms, known_perms->apis());
1587 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1588}
1589#endif
1590
[email protected]8d888c12010-11-30 00:00:251591#if !defined(OS_CHROMEOS)
1592// Tests that the granted permissions full_access bit gets set correctly when
1593// an extension contains an NPAPI plugin. Don't run this test on Chrome OS
1594// since they don't support plugins.
[email protected]eaa7dd182010-12-14 11:09:001595TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
[email protected]183d4b82011-11-11 18:50:261596 PluginService::GetInstance()->Init();
1597
[email protected]eaa7dd182010-12-14 11:09:001598 InitializeEmptyExtensionService();
[email protected]8d888c12010-11-30 00:00:251599
[email protected]e85e34c32011-04-13 18:38:351600 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251601 .AppendASCII("good")
1602 .AppendASCII("Extensions")
1603 .AppendASCII(good1)
1604 .AppendASCII("2");
1605
1606 ASSERT_TRUE(file_util::PathExists(path));
[email protected]8f512c72011-11-22 21:02:501607 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251608 EXPECT_EQ(0u, GetErrors().size());
1609 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8d888c12010-11-30 00:00:251610 ExtensionPrefs* prefs = service_->extension_prefs();
1611
[email protected]c2e66e12012-06-27 06:27:061612 scoped_refptr<PermissionSet> permissions(
[email protected]8f512c72011-11-22 21:02:501613 prefs->GetGrantedPermissions(extension->id()));
[email protected]0d3e4a22011-06-23 19:02:521614 EXPECT_FALSE(permissions->IsEmpty());
1615 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1616 EXPECT_FALSE(permissions->apis().empty());
[email protected]c2e66e12012-06-27 06:27:061617 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
[email protected]8d888c12010-11-30 00:00:251618
[email protected]0d3e4a22011-06-23 19:02:521619 // Full access implies full host access too...
1620 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
[email protected]8d888c12010-11-30 00:00:251621}
1622#endif
1623
1624// Tests that the extension is disabled when permissions are missing from
1625// the extension's granted permissions preferences. (This simulates updating
1626// the browser to a version which recognizes more permissions).
[email protected]eaa7dd182010-12-14 11:09:001627TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1628 InitializeEmptyExtensionService();
[email protected]8d888c12010-11-30 00:00:251629
[email protected]e85e34c32011-04-13 18:38:351630 FilePath path = data_dir_
[email protected]8d888c12010-11-30 00:00:251631 .AppendASCII("permissions")
1632 .AppendASCII("unknown");
1633
1634 ASSERT_TRUE(file_util::PathExists(path));
1635
[email protected]8f512c72011-11-22 21:02:501636 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
[email protected]8d888c12010-11-30 00:00:251637
1638 EXPECT_EQ(0u, GetErrors().size());
1639 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8d888c12010-11-30 00:00:251640 std::string extension_id = extension->id();
1641
1642 ExtensionPrefs* prefs = service_->extension_prefs();
1643
[email protected]c2e66e12012-06-27 06:27:061644 APIPermissionSet expected_api_permissions;
[email protected]cced75a2011-05-20 08:31:121645 URLPatternSet expected_host_permissions;
[email protected]8d888c12010-11-30 00:00:251646
[email protected]c2e66e12012-06-27 06:27:061647 expected_api_permissions.insert(APIPermission::kTab);
[email protected]8d888c12010-11-30 00:00:251648 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1649 AddPattern(&expected_host_permissions, "https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151650 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251651 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1652
[email protected]8d888c12010-11-30 00:00:251653 std::set<std::string> host_permissions;
1654
1655 // Test that the extension is disabled when an API permission is missing from
1656 // the extension's granted api permissions preference. (This simulates
1657 // updating the browser to a version which recognizes a new API permission).
[email protected]0d3e4a22011-06-23 19:02:521658 SetPref(extension_id, "granted_permissions.api",
1659 new ListValue(), "granted_permissions.api");
[email protected]8d888c12010-11-30 00:00:251660 service_->ReloadExtensions();
1661
1662 EXPECT_EQ(1u, service_->disabled_extensions()->size());
[email protected]8f512c72011-11-22 21:02:501663 extension = *service_->disabled_extensions()->begin();
[email protected]8d888c12010-11-30 00:00:251664
[email protected]ad83ca242011-07-29 01:32:251665 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
[email protected]36429da2011-07-11 20:25:181666 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251667 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1668
1669 // Now grant and re-enable the extension, making sure the prefs are updated.
[email protected]b70a2d92012-06-28 19:51:211670 service_->GrantPermissionsAndEnableExtension(extension, false);
[email protected]8d888c12010-11-30 00:00:251671
[email protected]ad83ca242011-07-29 01:32:251672 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
[email protected]36429da2011-07-11 20:25:181673 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251674 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1675
[email protected]c2e66e12012-06-27 06:27:061676 scoped_refptr<PermissionSet> current_perms(
[email protected]0d3e4a22011-06-23 19:02:521677 prefs->GetGrantedPermissions(extension_id));
1678 ASSERT_TRUE(current_perms.get());
1679 ASSERT_FALSE(current_perms->IsEmpty());
1680 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
1681 ASSERT_EQ(expected_api_permissions, current_perms->apis());
[email protected]06e8b8ff2011-07-13 15:03:471682 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251683
1684 // Tests that the extension is disabled when a host permission is missing from
1685 // the extension's granted host permissions preference. (This simulates
1686 // updating the browser to a version which recognizes additional host
1687 // permissions).
[email protected]8d888c12010-11-30 00:00:251688 host_permissions.clear();
[email protected]902fd7b2011-07-27 18:42:311689 current_perms = NULL;
[email protected]8d888c12010-11-30 00:00:251690
[email protected]8d888c12010-11-30 00:00:251691 host_permissions.insert("http://*.google.com/*");
1692 host_permissions.insert("https://*.google.com/*");
[email protected]d6a5c78c2010-12-07 05:18:151693 host_permissions.insert("http://*.google.com.hk/*");
[email protected]8d888c12010-11-30 00:00:251694
[email protected]0d3e4a22011-06-23 19:02:521695 ListValue* api_permissions = new ListValue();
1696 api_permissions->Append(
[email protected]1d8b79a2012-08-16 20:22:541697 Value::CreateStringValue("tabs"));
[email protected]0d3e4a22011-06-23 19:02:521698 SetPref(extension_id, "granted_permissions.api",
1699 api_permissions, "granted_permissions.api");
1700 SetPrefStringSet(
1701 extension_id, "granted_permissions.scriptable_host", host_permissions);
[email protected]8d888c12010-11-30 00:00:251702
1703 service_->ReloadExtensions();
1704
1705 EXPECT_EQ(1u, service_->disabled_extensions()->size());
[email protected]8f512c72011-11-22 21:02:501706 extension = *service_->disabled_extensions()->begin();
[email protected]8d888c12010-11-30 00:00:251707
[email protected]ad83ca242011-07-29 01:32:251708 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
[email protected]36429da2011-07-11 20:25:181709 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251710 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1711
1712 // Now grant and re-enable the extension, making sure the prefs are updated.
[email protected]b70a2d92012-06-28 19:51:211713 service_->GrantPermissionsAndEnableExtension(extension, false);
[email protected]8d888c12010-11-30 00:00:251714
[email protected]36429da2011-07-11 20:25:181715 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
[email protected]8d888c12010-11-30 00:00:251716 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1717
[email protected]902fd7b2011-07-27 18:42:311718 current_perms = prefs->GetGrantedPermissions(extension_id);
[email protected]0d3e4a22011-06-23 19:02:521719 ASSERT_TRUE(current_perms.get());
1720 ASSERT_FALSE(current_perms->IsEmpty());
1721 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
1722 ASSERT_EQ(expected_api_permissions, current_perms->apis());
[email protected]06e8b8ff2011-07-13 15:03:471723 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
[email protected]8d888c12010-11-30 00:00:251724}
1725
[email protected]a17f9462009-06-09 02:56:411726// Test Packaging and installing an extension.
[email protected]eaa7dd182010-12-14 11:09:001727TEST_F(ExtensionServiceTest, PackExtension) {
1728 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351729 FilePath input_directory = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231730 .AppendASCII("good")
1731 .AppendASCII("Extensions")
1732 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1733 .AppendASCII("1.0.0.0");
[email protected]a17f9462009-06-09 02:56:411734
[email protected]aca3e9b2009-11-03 01:14:211735 ScopedTempDir temp_dir;
1736 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1737 FilePath output_directory = temp_dir.path();
1738
[email protected]a17f9462009-06-09 02:56:411739 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1740 FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
1741
1742 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1743 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
[email protected]93d973a2012-01-08 07:38:261744 privkey_path, ExtensionCreator::kNoRunFlags));
1745 ASSERT_TRUE(file_util::PathExists(crx_path));
1746 ASSERT_TRUE(file_util::PathExists(privkey_path));
1747
1748 // Repeat the run with the pem file gone, and no special flags
1749 // Should refuse to overwrite the existing crx.
1750 file_util::Delete(privkey_path, false);
1751 ASSERT_FALSE(creator->Run(input_directory, crx_path, FilePath(),
1752 privkey_path, ExtensionCreator::kNoRunFlags));
1753
1754 // OK, now try it with a flag to overwrite existing crx. Should work.
1755 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
1756 privkey_path, ExtensionCreator::kOverwriteCRX));
1757
1758 // Repeat the run allowing existing crx, but the existing pem is still
1759 // an error. Should fail.
1760 ASSERT_FALSE(creator->Run(input_directory, crx_path, FilePath(),
1761 privkey_path, ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:411762
[email protected]a17f9462009-06-09 02:56:411763 ASSERT_TRUE(file_util::PathExists(privkey_path));
[email protected]8f512c72011-11-22 21:02:501764 InstallCRX(crx_path, INSTALL_NEW);
[email protected]0dc2ca82009-11-17 07:06:161765
1766 // Try packing with invalid paths.
1767 creator.reset(new ExtensionCreator());
[email protected]93d973a2012-01-08 07:38:261768 ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath(),
1769 ExtensionCreator::kOverwriteCRX));
[email protected]0dc2ca82009-11-17 07:06:161770
1771 // Try packing an empty directory. Should fail because an empty directory is
1772 // not a valid extension.
1773 ScopedTempDir temp_dir2;
1774 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
1775 creator.reset(new ExtensionCreator());
1776 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
[email protected]93d973a2012-01-08 07:38:261777 FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]0dc2ca82009-11-17 07:06:161778
1779 // Try packing with an invalid manifest.
1780 std::string invalid_manifest_content = "I am not a manifest.";
1781 ASSERT_TRUE(file_util::WriteFile(
[email protected]99efb7b12009-12-18 02:39:161782 temp_dir2.path().Append(Extension::kManifestFilename),
[email protected]0dc2ca82009-11-17 07:06:161783 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
1784 creator.reset(new ExtensionCreator());
1785 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
[email protected]93d973a2012-01-08 07:38:261786 FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:411787}
1788
[email protected]0349ab5d2010-08-11 21:41:571789// Test Packaging and installing an extension whose name contains punctuation.
[email protected]eaa7dd182010-12-14 11:09:001790TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
1791 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351792 FilePath input_directory = data_dir_
[email protected]0349ab5d2010-08-11 21:41:571793 .AppendASCII("good")
1794 .AppendASCII("Extensions")
1795 .AppendASCII(good0)
1796 .AppendASCII("1.0.0.0");
1797
1798 ScopedTempDir temp_dir;
1799 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1800
1801 // Extension names containing punctuation, and the expected names for the
1802 // packed extensions.
1803 const FilePath punctuated_names[] = {
[email protected]d9034ed22012-02-10 02:04:401804 FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
1805 FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
1806 FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
1807 NormalizePathSeparators(),
[email protected]0349ab5d2010-08-11 21:41:571808 };
1809 const FilePath expected_crx_names[] = {
[email protected]d9034ed22012-02-10 02:04:401810 FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
1811 FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
1812 FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
[email protected]0349ab5d2010-08-11 21:41:571813 };
1814 const FilePath expected_private_key_names[] = {
[email protected]d9034ed22012-02-10 02:04:401815 FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
1816 FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
1817 FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
[email protected]0349ab5d2010-08-11 21:41:571818 };
1819
1820 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
1821 SCOPED_TRACE(punctuated_names[i].value().c_str());
1822 FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
1823
1824 // Copy the extension into the output directory, as PackExtensionJob doesn't
1825 // let us choose where to output the packed extension.
1826 ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true));
1827
1828 FilePath expected_crx_path = temp_dir.path().Append(expected_crx_names[i]);
1829 FilePath expected_private_key_path =
1830 temp_dir.path().Append(expected_private_key_names[i]);
1831 PackExtensionTestClient pack_client(expected_crx_path,
1832 expected_private_key_path);
[email protected]d9ede582012-08-14 19:21:381833 scoped_refptr<extensions::PackExtensionJob> packer(
1834 new extensions::PackExtensionJob(&pack_client, output_dir, FilePath(),
1835 ExtensionCreator::kOverwriteCRX));
[email protected]0349ab5d2010-08-11 21:41:571836 packer->Start();
1837
1838 // The packer will post a notification task to the current thread's message
1839 // loop when it is finished. We manually run the loop here so that we
1840 // block and catch the notification; otherwise, the process would exit.
1841 // This call to |Run()| is matched by a call to |Quit()| in the
1842 // |PackExtensionTestClient|'s notification handling code.
1843 MessageLoop::current()->Run();
1844
1845 if (HasFatalFailure())
1846 return;
1847
[email protected]8f512c72011-11-22 21:02:501848 InstallCRX(expected_crx_path, INSTALL_NEW);
[email protected]0349ab5d2010-08-11 21:41:571849 }
1850}
1851
[email protected]ab55c2b2012-06-01 23:55:031852TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
1853 InitializeEmptyExtensionService();
1854
1855 ScopedTempDir extension_temp_dir;
1856 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
1857 FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
1858 ASSERT_TRUE(file_util::CopyDirectory(
1859 data_dir_
1860 .AppendASCII("good")
1861 .AppendASCII("Extensions")
1862 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1863 .AppendASCII("1.0.0.0"),
1864 input_directory,
1865 /*recursive=*/true));
1866
1867 ScopedTempDir output_temp_dir;
1868 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
1869 FilePath output_directory = output_temp_dir.path();
1870
1871 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1872 FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
1873
1874 // Pack the extension once to get a private key.
1875 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1876 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
1877 privkey_path, ExtensionCreator::kNoRunFlags))
1878 << creator->error_message();
1879 ASSERT_TRUE(file_util::PathExists(crx_path));
1880 ASSERT_TRUE(file_util::PathExists(privkey_path));
1881
1882 file_util::Delete(crx_path, false);
1883 // Move the pem file into the extension.
1884 file_util::Move(privkey_path,
1885 input_directory.AppendASCII("privkey.pem"));
1886
1887 // This pack should fail because of the contained private key.
1888 EXPECT_FALSE(creator->Run(input_directory, crx_path, FilePath(),
1889 privkey_path, ExtensionCreator::kNoRunFlags));
1890 EXPECT_THAT(creator->error_message(),
1891 testing::ContainsRegex(
1892 "extension includes the key file.*privkey.pem"));
1893}
1894
[email protected]a17f9462009-06-09 02:56:411895// Test Packaging and installing an extension using an openssl generated key.
1896// The openssl is generated with the following:
[email protected]a1257b12009-06-12 02:51:341897// > openssl genrsa -out privkey.pem 1024
[email protected]df4956e2009-06-10 16:53:421898// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
[email protected]a1257b12009-06-12 02:51:341899// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
[email protected]a17f9462009-06-09 02:56:411900// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
[email protected]eaa7dd182010-12-14 11:09:001901TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
1902 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351903 FilePath input_directory = data_dir_
[email protected]a9b00ac2009-06-25 21:03:231904 .AppendASCII("good")
1905 .AppendASCII("Extensions")
1906 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1907 .AppendASCII("1.0.0.0");
[email protected]e85e34c32011-04-13 18:38:351908 FilePath privkey_path(data_dir_.AppendASCII(
[email protected]a17f9462009-06-09 02:56:411909 "openssl_privkey_asn1.pem"));
1910 ASSERT_TRUE(file_util::PathExists(privkey_path));
1911
[email protected]aca3e9b2009-11-03 01:14:211912 ScopedTempDir temp_dir;
1913 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1914 FilePath output_directory = temp_dir.path();
1915
[email protected]a17f9462009-06-09 02:56:411916 FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1917
1918 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1919 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
[email protected]93d973a2012-01-08 07:38:261920 FilePath(), ExtensionCreator::kOverwriteCRX));
[email protected]a17f9462009-06-09 02:56:411921
[email protected]8f512c72011-11-22 21:02:501922 InstallCRX(crx_path, INSTALL_NEW);
[email protected]a17f9462009-06-09 02:56:411923}
[email protected]a17f9462009-06-09 02:56:411924
[email protected]eaa7dd182010-12-14 11:09:001925TEST_F(ExtensionServiceTest, InstallTheme) {
1926 InitializeEmptyExtensionService();
[email protected]e2eb43112009-05-29 21:19:541927
1928 // A theme.
[email protected]e85e34c32011-04-13 18:38:351929 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8f512c72011-11-22 21:02:501930 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:191931 int pref_count = 0;
1932 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341933 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
1934 ValidateIntegerPref(theme_crx, "location", Extension::INTERNAL);
[email protected]e2eb43112009-05-29 21:19:541935
[email protected]6ef635e42009-07-26 06:16:121936 // A theme when extensions are disabled. Themes can be installed, even when
1937 // extensions are disabled.
[email protected]7577a5c52009-07-30 06:21:581938 set_extensions_enabled(false);
[email protected]e85e34c32011-04-13 18:38:351939 path = data_dir_.AppendASCII("theme2.crx");
[email protected]8f512c72011-11-22 21:02:501940 InstallCRX(path, INSTALL_NEW);
[email protected]25b34332009-06-05 21:53:191941 ValidatePrefKeyCount(++pref_count);
[email protected]e2194742010-08-12 05:54:341942 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
1943 ValidateIntegerPref(theme2_crx, "location", Extension::INTERNAL);
[email protected]494c06e2009-07-25 01:06:421944
[email protected]f6dec1e322012-04-30 21:04:511945 // A theme with extension elements. Themes cannot have extension elements,
1946 // so any such elements (like content scripts) should be ignored.
[email protected]7577a5c52009-07-30 06:21:581947 set_extensions_enabled(true);
[email protected]f6dec1e322012-04-30 21:04:511948 {
1949 path = data_dir_.AppendASCII("theme_with_extension.crx");
1950 const Extension* extension = InstallCRX(path, INSTALL_NEW);
1951 ValidatePrefKeyCount(++pref_count);
1952 ASSERT_TRUE(extension);
1953 EXPECT_TRUE(extension->is_theme());
1954 EXPECT_EQ(0u, extension->content_scripts().size());
1955 }
[email protected]12198912009-06-05 03:41:221956
1957 // A theme with image resources missing (misspelt path).
[email protected]e85e34c32011-04-13 18:38:351958 path = data_dir_.AppendASCII("theme_missing_image.crx");
[email protected]8f512c72011-11-22 21:02:501959 InstallCRX(path, INSTALL_FAILED);
[email protected]25b34332009-06-05 21:53:191960 ValidatePrefKeyCount(pref_count);
[email protected]e2eb43112009-05-29 21:19:541961}
1962
[email protected]eaa7dd182010-12-14 11:09:001963TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
[email protected]584245e52010-06-17 01:08:131964 // Load.
[email protected]eaa7dd182010-12-14 11:09:001965 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:351966 FilePath extension_path = data_dir_
[email protected]584245e52010-06-17 01:08:131967 .AppendASCII("theme_i18n");
1968
[email protected]d8c8f25f2011-11-02 18:18:011969 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
[email protected]584245e52010-06-17 01:08:131970 loop_.RunAllPending();
1971 EXPECT_EQ(0u, GetErrors().size());
1972 ASSERT_EQ(1u, loaded_.size());
1973 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:501974 const Extension* theme = *service_->extensions()->begin();
1975 EXPECT_EQ("name", theme->name());
1976 EXPECT_EQ("description", theme->description());
[email protected]584245e52010-06-17 01:08:131977}
1978
[email protected]c24fb292012-02-01 22:52:111979// Tests that we can change the ID of an unpacked extension by adding a key
1980// to its manifest.
1981TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) {
1982 InitializeEmptyExtensionService();
1983
1984 ScopedTempDir temp;
1985 ASSERT_TRUE(temp.CreateUniqueTempDir());
1986
1987 FilePath extension_path = temp.path();
1988 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
1989 FilePath manifest_no_key = data_dir_.
1990 AppendASCII("unpacked").
1991 AppendASCII("manifest_no_key.json");
1992
1993 FilePath manifest_with_key = data_dir_.
1994 AppendASCII("unpacked").
1995 AppendASCII("manifest_with_key.json");
1996
1997 ASSERT_TRUE(file_util::PathExists(manifest_no_key));
1998 ASSERT_TRUE(file_util::PathExists(manifest_with_key));
1999
2000 // Load the unpacked extension with no key.
2001 file_util::CopyFile(manifest_no_key, manifest_path);
2002 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2003
2004 loop_.RunAllPending();
2005 EXPECT_EQ(0u, GetErrors().size());
2006 ASSERT_EQ(1u, loaded_.size());
2007 EXPECT_EQ(1u, service_->extensions()->size());
2008
2009 // Add the key to the manifest.
2010 file_util::CopyFile(manifest_with_key, manifest_path);
2011 loaded_.clear();
2012
2013 // Reload the extensions.
2014 service_->ReloadExtensions();
2015 const Extension* extension = service_->GetExtensionById(unpacked, false);
2016 EXPECT_EQ(unpacked, extension->id());
2017 ASSERT_EQ(1u, loaded_.size());
2018
2019 // TODO(jstritar): Right now this just makes sure we don't crash and burn, but
2020 // we should also test that preferences are preserved.
2021}
2022
[email protected]91236521162012-05-24 15:02:512023#if defined(OS_POSIX)
2024TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2025 FilePath source_data_dir = data_dir_.
2026 AppendASCII("unpacked").
2027 AppendASCII("symlinks_allowed");
2028
2029 // Paths to test data files.
2030 FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2031 ASSERT_TRUE(file_util::PathExists(source_manifest));
2032 FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2033 ASSERT_TRUE(file_util::PathExists(source_icon));
2034
2035 // Set up the temporary extension directory.
2036 ScopedTempDir temp;
2037 ASSERT_TRUE(temp.CreateUniqueTempDir());
2038 FilePath extension_path = temp.path();
2039 FilePath manifest = extension_path.Append(Extension::kManifestFilename);
2040 FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2041 file_util::CopyFile(source_manifest, manifest);
2042 file_util::CreateSymbolicLink(source_icon, icon_symlink);
2043
2044 // Load extension.
2045 InitializeEmptyExtensionService();
2046 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2047 loop_.RunAllPending();
2048
2049 EXPECT_TRUE(GetErrors().empty());
2050 ASSERT_EQ(1u, loaded_.size());
2051 EXPECT_EQ(1u, service_->extensions()->size());
2052}
2053#endif
2054
[email protected]eaa7dd182010-12-14 11:09:002055TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2056 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:352057 FilePath theme_path = data_dir_
[email protected]584245e52010-06-17 01:08:132058 .AppendASCII("theme_i18n");
2059
[email protected]8f512c72011-11-22 21:02:502060 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
[email protected]584245e52010-06-17 01:08:132061
[email protected]584245e52010-06-17 01:08:132062 EXPECT_EQ(0u, GetErrors().size());
2063 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502064 EXPECT_EQ("name", theme->name());
2065 EXPECT_EQ("description", theme->description());
[email protected]584245e52010-06-17 01:08:132066}
2067
[email protected]eaa7dd182010-12-14 11:09:002068TEST_F(ExtensionServiceTest, InstallApps) {
2069 InitializeEmptyExtensionService();
[email protected]6d2e60bd2010-06-03 22:37:392070
2071 // An empty app.
[email protected]8f512c72011-11-22 21:02:502072 const Extension* app = PackAndInstallCRX(data_dir_.AppendASCII("app1"),
2073 INSTALL_NEW);
[email protected]6d2e60bd2010-06-03 22:37:392074 int pref_count = 0;
2075 ValidatePrefKeyCount(++pref_count);
[email protected]3ba0fd32010-06-19 05:39:102076 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502077 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2078 ValidateIntegerPref(app->id(), "location", Extension::INTERNAL);
[email protected]6d2e60bd2010-06-03 22:37:392079
2080 // Another app with non-overlapping extent. Should succeed.
[email protected]8f512c72011-11-22 21:02:502081 PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
[email protected]6d2e60bd2010-06-03 22:37:392082 ValidatePrefKeyCount(++pref_count);
2083
2084 // A third app whose extent overlaps the first. Should fail.
[email protected]8f512c72011-11-22 21:02:502085 PackAndInstallCRX(data_dir_.AppendASCII("app3"), INSTALL_FAILED);
[email protected]cd10e282010-10-26 21:04:512086 ValidatePrefKeyCount(pref_count);
[email protected]6d2e60bd2010-06-03 22:37:392087}
2088
[email protected]b6e64fd2011-08-09 19:49:192089// Tests that file access is OFF by default.
2090TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2091 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:502092 const Extension* extension =
2093 PackAndInstallCRX(data_dir_
2094 .AppendASCII("permissions")
2095 .AppendASCII("files"),
2096 INSTALL_NEW);
[email protected]b6e64fd2011-08-09 19:49:192097 EXPECT_EQ(0u, GetErrors().size());
2098 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502099 EXPECT_FALSE(service_->extension_prefs()->AllowFileAccess(extension->id()));
[email protected]b6e64fd2011-08-09 19:49:192100}
2101
[email protected]15300d92011-01-19 18:44:302102TEST_F(ExtensionServiceTest, UpdateApps) {
2103 InitializeEmptyExtensionService();
[email protected]e85e34c32011-04-13 18:38:352104 FilePath extensions_path = data_dir_.AppendASCII("app_update");
[email protected]15300d92011-01-19 18:44:302105
2106 // First install v1 of a hosted app.
[email protected]8f512c72011-11-22 21:02:502107 const Extension* extension =
2108 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
[email protected]15300d92011-01-19 18:44:302109 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:502110 std::string id = extension->id();
2111 ASSERT_EQ(std::string("1"), extension->version()->GetString());
[email protected]15300d92011-01-19 18:44:302112
2113 // Now try updating to v2.
2114 UpdateExtension(id,
2115 extensions_path.AppendASCII("v2.crx"),
2116 ENABLED);
2117 ASSERT_EQ(std::string("2"),
[email protected]8f512c72011-11-22 21:02:502118 service_->GetExtensionById(id, false)->version()->GetString());
[email protected]15300d92011-01-19 18:44:302119}
2120
[email protected]e6a6c2e02012-01-13 00:06:482121// Verifies that the NTP page and launch ordinals are kept when updating apps.
2122TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2123 InitializeEmptyExtensionService();
2124 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
2125 FilePath extensions_path = data_dir_.AppendASCII("app_update");
2126
2127 // First install v1 of a hosted app.
2128 const Extension* extension =
2129 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2130 ASSERT_EQ(1u, service_->extensions()->size());
2131 std::string id = extension->id();
2132 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2133
2134 // Modify the ordinals so we can distinguish them from the defaults.
[email protected]36b643212012-09-07 12:53:002135 syncer::StringOrdinal new_page_ordinal =
2136 sorting->GetPageOrdinal(id).CreateAfter();
2137 syncer::StringOrdinal new_launch_ordinal =
[email protected]e6a6c2e02012-01-13 00:06:482138 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2139
2140 sorting->SetPageOrdinal(id, new_page_ordinal);
2141 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2142
2143 // Now try updating to v2.
2144 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2145 ASSERT_EQ(std::string("2"),
2146 service_->GetExtensionById(id, false)->version()->GetString());
2147
2148 // Verify that the ordinals match.
[email protected]36b643212012-09-07 12:53:002149 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2150 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
[email protected]e6a6c2e02012-01-13 00:06:482151}
2152
[email protected]b873cd92012-02-09 21:51:482153// Ensures that the CWS has properly initialized ordinals.
2154TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2155 InitializeEmptyExtensionService();
2156 service_->component_loader()->Add(IDR_WEBSTORE_MANIFEST,
2157 FilePath(FILE_PATH_LITERAL("web_store")));
2158 service_->Init();
2159
[email protected]b873cd92012-02-09 21:51:482160 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
2161 EXPECT_TRUE(
2162 sorting->GetPageOrdinal(extension_misc::kWebStoreAppId).IsValid());
2163 EXPECT_TRUE(
2164 sorting->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId).IsValid());
2165}
2166
[email protected]8b0d36bc2012-08-29 22:09:172167// Flaky failures on Vista. http://crbug.com/145381
2168#if defined(OS_WIN)
2169#define MAYBE_InstallAppsWithUnlimitedStorage \
2170 DISABLED_InstallAppsWithUnlimitedStorage
2171#else
2172#define MAYBE_InstallAppsWithUnlimitedStorage InstallAppsWithUnlimitedStorage
2173#endif
2174
2175TEST_F(ExtensionServiceTest, MAYBE_InstallAppsWithUnlimitedStorage) {
[email protected]eaa7dd182010-12-14 11:09:002176 InitializeEmptyExtensionService();
[email protected]0d6ec3a72011-09-02 02:09:432177 InitializeRequestContext();
[email protected]84df8332011-12-06 18:22:462178 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]c2c263c2010-08-13 21:59:482179
[email protected]c2c263c2010-08-13 21:59:482180 int pref_count = 0;
[email protected]c2c263c2010-08-13 21:59:482181
2182 // Install app1 with unlimited storage.
[email protected]8f512c72011-11-22 21:02:502183 const Extension* extension =
2184 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
[email protected]c2c263c2010-08-13 21:59:482185 ValidatePrefKeyCount(++pref_count);
2186 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]c2c263c2010-08-13 21:59:482187 const std::string id1 = extension->id();
[email protected]0d3e4a22011-06-23 19:02:522188 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:062189 APIPermission::kUnlimitedStorage));
[email protected]cced75a2011-05-20 08:31:122190 EXPECT_TRUE(extension->web_extent().MatchesURL(
[email protected]c2c263c2010-08-13 21:59:482191 extension->GetFullLaunchURL()));
2192 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
[email protected]19eb80152011-02-26 00:28:432193 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2194 IsStorageUnlimited(origin1));
[email protected]c2c263c2010-08-13 21:59:482195
2196 // Install app2 from the same origin with unlimited storage.
[email protected]8f512c72011-11-22 21:02:502197 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
[email protected]c2c263c2010-08-13 21:59:482198 ValidatePrefKeyCount(++pref_count);
2199 ASSERT_EQ(2u, service_->extensions()->size());
[email protected]c2c263c2010-08-13 21:59:482200 const std::string id2 = extension->id();
[email protected]0d3e4a22011-06-23 19:02:522201 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:062202 APIPermission::kUnlimitedStorage));
[email protected]cced75a2011-05-20 08:31:122203 EXPECT_TRUE(extension->web_extent().MatchesURL(
[email protected]c2c263c2010-08-13 21:59:482204 extension->GetFullLaunchURL()));
2205 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
2206 EXPECT_EQ(origin1, origin2);
[email protected]19eb80152011-02-26 00:28:432207 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2208 IsStorageUnlimited(origin2));
2209
[email protected]c2c263c2010-08-13 21:59:482210
2211 // Uninstall one of them, unlimited storage should still be granted
2212 // to the origin.
[email protected]fa2416f2011-05-03 08:41:202213 UninstallExtension(id1, false);
[email protected]c2c263c2010-08-13 21:59:482214 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]19eb80152011-02-26 00:28:432215 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2216 IsStorageUnlimited(origin1));
2217
[email protected]c2c263c2010-08-13 21:59:482218 // Uninstall the other, unlimited storage should be revoked.
[email protected]fa2416f2011-05-03 08:41:202219 UninstallExtension(id2, false);
[email protected]c2c263c2010-08-13 21:59:482220 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]19eb80152011-02-26 00:28:432221 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2222 IsStorageUnlimited(origin2));
[email protected]c2c263c2010-08-13 21:59:482223}
2224
[email protected]eaa7dd182010-12-14 11:09:002225TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2226 InitializeEmptyExtensionService();
[email protected]0d6ec3a72011-09-02 02:09:432227 InitializeRequestContext();
[email protected]84df8332011-12-06 18:22:462228 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]654512b2010-09-01 02:09:422229
[email protected]654512b2010-09-01 02:09:422230 int pref_count = 0;
2231
[email protected]8f512c72011-11-22 21:02:502232 const Extension* extension =
2233 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
[email protected]654512b2010-09-01 02:09:422234 ValidatePrefKeyCount(++pref_count);
2235 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]654512b2010-09-01 02:09:422236 EXPECT_TRUE(extension->is_app());
2237 const std::string id1 = extension->id();
[email protected]654512b2010-09-01 02:09:422238 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
[email protected]19eb80152011-02-26 00:28:432239 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2240 IsStorageProtected(origin1));
[email protected]654512b2010-09-01 02:09:422241
2242 // App 4 has a different origin (maps.google.com).
[email protected]8f512c72011-11-22 21:02:502243 extension = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
[email protected]654512b2010-09-01 02:09:422244 ValidatePrefKeyCount(++pref_count);
2245 ASSERT_EQ(2u, service_->extensions()->size());
[email protected]654512b2010-09-01 02:09:422246 const std::string id2 = extension->id();
[email protected]654512b2010-09-01 02:09:422247 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
2248 ASSERT_NE(origin1, origin2);
[email protected]19eb80152011-02-26 00:28:432249 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2250 IsStorageProtected(origin2));
[email protected]654512b2010-09-01 02:09:422251
[email protected]fa2416f2011-05-03 08:41:202252 UninstallExtension(id1, false);
[email protected]654512b2010-09-01 02:09:422253 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]654512b2010-09-01 02:09:422254
[email protected]fa2416f2011-05-03 08:41:202255 UninstallExtension(id2, false);
[email protected]654512b2010-09-01 02:09:422256
[email protected]84df8332011-12-06 18:22:462257 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]19eb80152011-02-26 00:28:432258 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2259 IsStorageProtected(origin1));
2260 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2261 IsStorageProtected(origin2));
[email protected]654512b2010-09-01 02:09:422262}
2263
[email protected]894bb502009-05-21 22:39:572264// Test that when an extension version is reinstalled, nothing happens.
[email protected]eaa7dd182010-12-14 11:09:002265TEST_F(ExtensionServiceTest, Reinstall) {
2266 InitializeEmptyExtensionService();
[email protected]894bb502009-05-21 22:39:572267
2268 // A simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:352269 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502270 InstallCRX(path, INSTALL_NEW);
[email protected]894bb502009-05-21 22:39:572271
[email protected]25b34332009-06-05 21:53:192272 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342273 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2274 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:572275
[email protected]ca3dbf52010-05-19 22:27:062276 // Reinstall the same version, it should overwrite the previous one.
[email protected]8f512c72011-11-22 21:02:502277 InstallCRX(path, INSTALL_UPDATED);
[email protected]894bb502009-05-21 22:39:572278
[email protected]25b34332009-06-05 21:53:192279 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:342280 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2281 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
[email protected]894bb502009-05-21 22:39:572282}
2283
[email protected]620db1762011-07-15 21:57:342284// Test that we can determine if extensions came from the
2285// Chrome web store.
[email protected]8266d662011-07-12 21:53:262286TEST_F(ExtensionServiceTest, FromWebStore) {
2287 InitializeEmptyExtensionService();
2288
2289 // A simple extension that should install without error.
2290 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502291 // Not from web store.
2292 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2293 std::string id = extension->id();
[email protected]8266d662011-07-12 21:53:262294
[email protected]8266d662011-07-12 21:53:262295 ValidatePrefKeyCount(1);
2296 ValidateBooleanPref(good_crx, "from_webstore", false);
[email protected]620db1762011-07-15 21:57:342297 ASSERT_FALSE(extension->from_webstore());
[email protected]8266d662011-07-12 21:53:262298
[email protected]8266d662011-07-12 21:53:262299 // Test install from web store.
[email protected]8f512c72011-11-22 21:02:502300 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
[email protected]8266d662011-07-12 21:53:262301
[email protected]8266d662011-07-12 21:53:262302 ValidatePrefKeyCount(1);
2303 ValidateBooleanPref(good_crx, "from_webstore", true);
[email protected]620db1762011-07-15 21:57:342304
2305 // Reload so extension gets reinitialized with new value.
2306 service_->ReloadExtensions();
[email protected]8f512c72011-11-22 21:02:502307 extension = service_->GetExtensionById(id, false);
[email protected]620db1762011-07-15 21:57:342308 ASSERT_TRUE(extension->from_webstore());
[email protected]3d729722011-09-20 02:57:092309
2310 // Upgrade to version 2.0
2311 path = data_dir_.AppendASCII("good2.crx");
2312 UpdateExtension(good_crx, path, ENABLED);
2313 ValidatePrefKeyCount(1);
2314 ValidateBooleanPref(good_crx, "from_webstore", true);
[email protected]8266d662011-07-12 21:53:262315}
2316
[email protected]fbcc40302009-06-12 20:45:452317// Test upgrading a signed extension.
[email protected]eaa7dd182010-12-14 11:09:002318TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2319 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:452320
[email protected]e85e34c32011-04-13 18:38:352321 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502322 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2323 std::string id = extension->id();
[email protected]fbcc40302009-06-12 20:45:452324
[email protected]8f512c72011-11-22 21:02:502325 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:452326 ASSERT_EQ(0u, GetErrors().size());
2327
[email protected]8f512c72011-11-22 21:02:502328 // Upgrade to version 1.0.0.1
[email protected]e85e34c32011-04-13 18:38:352329 path = data_dir_.AppendASCII("good2.crx");
[email protected]8f512c72011-11-22 21:02:502330 InstallCRX(path, INSTALL_UPDATED);
2331 extension = service_->GetExtensionById(id, false);
[email protected]fbcc40302009-06-12 20:45:452332
[email protected]8f512c72011-11-22 21:02:502333 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
[email protected]fbcc40302009-06-12 20:45:452334 ASSERT_EQ(0u, GetErrors().size());
2335}
2336
2337// Test upgrading a signed extension with a bad signature.
[email protected]eaa7dd182010-12-14 11:09:002338TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2339 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:452340
[email protected]e85e34c32011-04-13 18:38:352341 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502342 InstallCRX(path, INSTALL_NEW);
[email protected]fbcc40302009-06-12 20:45:452343
2344 // Try upgrading with a bad signature. This should fail during the unpack,
2345 // because the key will not match the signature.
[email protected]e85e34c32011-04-13 18:38:352346 path = data_dir_.AppendASCII("bad_signature.crx");
[email protected]8f512c72011-11-22 21:02:502347 InstallCRX(path, INSTALL_FAILED);
[email protected]fbcc40302009-06-12 20:45:452348}
2349
[email protected]e957fe52009-06-23 16:51:052350// Test a normal update via the UpdateExtension API
[email protected]eaa7dd182010-12-14 11:09:002351TEST_F(ExtensionServiceTest, UpdateExtension) {
2352 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052353
[email protected]e85e34c32011-04-13 18:38:352354 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:052355
[email protected]8f512c72011-11-22 21:02:502356 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052357 ASSERT_EQ("1.0.0.0", good->VersionString());
2358 ASSERT_EQ(good_crx, good->id());
2359
[email protected]e85e34c32011-04-13 18:38:352360 path = data_dir_.AppendASCII("good2.crx");
[email protected]4416c5a2010-06-26 01:28:572361 UpdateExtension(good_crx, path, ENABLED);
[email protected]8f512c72011-11-22 21:02:502362 ASSERT_EQ("1.0.0.1",
2363 service_->GetExtensionById(good_crx, false)->
2364 version()->GetString());
[email protected]e957fe52009-06-23 16:51:052365}
2366
2367// Test updating a not-already-installed extension - this should fail
[email protected]eaa7dd182010-12-14 11:09:002368TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2369 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052370
[email protected]e85e34c32011-04-13 18:38:352371 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572372 UpdateExtension(good_crx, path, UPDATED);
[email protected]e957fe52009-06-23 16:51:052373 loop_.RunAllPending();
2374
2375 ASSERT_EQ(0u, service_->extensions()->size());
2376 ASSERT_FALSE(installed_);
2377 ASSERT_EQ(0u, loaded_.size());
2378}
2379
2380// Makes sure you can't downgrade an extension via UpdateExtension
[email protected]eaa7dd182010-12-14 11:09:002381TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2382 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052383
[email protected]e85e34c32011-04-13 18:38:352384 FilePath path = data_dir_.AppendASCII("good2.crx");
[email protected]e957fe52009-06-23 16:51:052385
[email protected]8f512c72011-11-22 21:02:502386 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052387 ASSERT_EQ("1.0.0.1", good->VersionString());
2388 ASSERT_EQ(good_crx, good->id());
2389
2390 // Change path from good2.crx -> good.crx
[email protected]e85e34c32011-04-13 18:38:352391 path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572392 UpdateExtension(good_crx, path, FAILED);
[email protected]8f512c72011-11-22 21:02:502393 ASSERT_EQ("1.0.0.1",
2394 service_->GetExtensionById(good_crx, false)->
2395 version()->GetString());
[email protected]e957fe52009-06-23 16:51:052396}
2397
2398// Make sure calling update with an identical version does nothing
[email protected]eaa7dd182010-12-14 11:09:002399TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2400 InitializeEmptyExtensionService();
[email protected]e957fe52009-06-23 16:51:052401
[email protected]e85e34c32011-04-13 18:38:352402 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]e957fe52009-06-23 16:51:052403
[email protected]8f512c72011-11-22 21:02:502404 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]e957fe52009-06-23 16:51:052405 ASSERT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:572406 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]aa142702010-03-26 01:26:332407}
2408
[email protected]dbec3792010-08-10 00:08:452409// Tests that updating an extension does not clobber old state.
[email protected]eaa7dd182010-12-14 11:09:002410TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2411 InitializeEmptyExtensionService();
[email protected]dbec3792010-08-10 00:08:452412
[email protected]e85e34c32011-04-13 18:38:352413 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]dbec3792010-08-10 00:08:452414
[email protected]8f512c72011-11-22 21:02:502415 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]dbec3792010-08-10 00:08:452416 ASSERT_EQ("1.0.0.0", good->VersionString());
2417 ASSERT_EQ(good_crx, good->id());
2418
2419 // Disable it and allow it to run in incognito. These settings should carry
2420 // over to the updated version.
[email protected]44d62b62012-04-11 00:06:032421 service_->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
[email protected]c3cfb012011-04-06 22:07:352422 service_->SetIsIncognitoEnabled(good->id(), true);
[email protected]c38fd352012-03-28 04:06:122423 service_->extension_prefs()->SetDidExtensionEscalatePermissions(good, true);
[email protected]dbec3792010-08-10 00:08:452424
[email protected]e85e34c32011-04-13 18:38:352425 path = data_dir_.AppendASCII("good2.crx");
[email protected]dbec3792010-08-10 00:08:452426 UpdateExtension(good_crx, path, INSTALLED);
[email protected]98270432012-09-11 20:51:242427 ASSERT_EQ(1u, service_->disabled_extensions()->size());\
[email protected]8f512c72011-11-22 21:02:502428 const Extension* good2 = service_->GetExtensionById(good_crx, true);
[email protected]dbec3792010-08-10 00:08:452429 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
[email protected]c3cfb012011-04-06 22:07:352430 EXPECT_TRUE(service_->IsIncognitoEnabled(good2->id()));
[email protected]c38fd352012-03-28 04:06:122431 EXPECT_TRUE(service_->extension_prefs()->DidExtensionEscalatePermissions(
2432 good2->id()));
[email protected]dbec3792010-08-10 00:08:452433}
2434
[email protected]5eb375e92010-11-26 07:50:412435// Tests that updating preserves extension location.
[email protected]eaa7dd182010-12-14 11:09:002436TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2437 InitializeEmptyExtensionService();
[email protected]5eb375e92010-11-26 07:50:412438
[email protected]e85e34c32011-04-13 18:38:352439 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]5eb375e92010-11-26 07:50:412440
[email protected]d41e2152012-02-24 04:20:272441 const Extension* good =
2442 InstallCRXWithLocation(path, Extension::EXTERNAL_PREF, INSTALL_NEW);
[email protected]5eb375e92010-11-26 07:50:412443
2444 ASSERT_EQ("1.0.0.0", good->VersionString());
2445 ASSERT_EQ(good_crx, good->id());
2446
[email protected]e85e34c32011-04-13 18:38:352447 path = data_dir_.AppendASCII("good2.crx");
[email protected]5eb375e92010-11-26 07:50:412448 UpdateExtension(good_crx, path, ENABLED);
[email protected]8f512c72011-11-22 21:02:502449 const Extension* good2 = service_->GetExtensionById(good_crx, false);
[email protected]5eb375e92010-11-26 07:50:412450 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2451 EXPECT_EQ(good2->location(), Extension::EXTERNAL_PREF);
2452}
2453
[email protected]66e26872010-12-03 20:07:252454// Makes sure that LOAD extension types can downgrade.
[email protected]eaa7dd182010-12-14 11:09:002455TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2456 InitializeEmptyExtensionService();
[email protected]66e26872010-12-03 20:07:252457
2458 ScopedTempDir temp;
2459 ASSERT_TRUE(temp.CreateUniqueTempDir());
2460
2461 // We'll write the extension manifest dynamically to a temporary path
2462 // to make it easier to change the version number.
2463 FilePath extension_path = temp.path();
2464 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
2465 ASSERT_FALSE(file_util::PathExists(manifest_path));
2466
2467 // Start with version 2.0.
2468 DictionaryValue manifest;
2469 manifest.SetString("version", "2.0");
2470 manifest.SetString("name", "LOAD Downgrade Test");
[email protected]b3d52852011-12-07 01:01:112471 manifest.SetInteger("manifest_version", 2);
[email protected]66e26872010-12-03 20:07:252472
2473 JSONFileValueSerializer serializer(manifest_path);
2474 ASSERT_TRUE(serializer.Serialize(manifest));
2475
[email protected]d8c8f25f2011-11-02 18:18:012476 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
[email protected]66e26872010-12-03 20:07:252477 loop_.RunAllPending();
2478
2479 EXPECT_EQ(0u, GetErrors().size());
2480 ASSERT_EQ(1u, loaded_.size());
2481 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2482 EXPECT_EQ(1u, service_->extensions()->size());
2483 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2484
2485 // Now set the version number to 1.0, reload the extensions and verify that
2486 // the downgrade was accepted.
2487 manifest.SetString("version", "1.0");
2488 ASSERT_TRUE(serializer.Serialize(manifest));
2489
[email protected]d8c8f25f2011-11-02 18:18:012490 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
[email protected]66e26872010-12-03 20:07:252491 loop_.RunAllPending();
2492
2493 EXPECT_EQ(0u, GetErrors().size());
2494 ASSERT_EQ(1u, loaded_.size());
2495 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2496 EXPECT_EQ(1u, service_->extensions()->size());
2497 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2498}
2499
[email protected]0d904312012-01-25 23:00:162500#if !defined(OS_CHROMEOS)
2501// LOAD extensions with plugins require approval.
2502TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
2503 FilePath extension_with_plugin_path = data_dir_
2504 .AppendASCII("good")
2505 .AppendASCII("Extensions")
2506 .AppendASCII(good1)
2507 .AppendASCII("2");
2508 FilePath extension_no_plugin_path = data_dir_
2509 .AppendASCII("good")
2510 .AppendASCII("Extensions")
2511 .AppendASCII(good2)
2512 .AppendASCII("1.0");
2513
2514 PluginService::GetInstance()->Init();
2515 InitializeEmptyExtensionService();
2516 InitializeExtensionProcessManager();
2517 service_->set_show_extensions_prompts(true);
2518
2519 // Start by canceling any install prompts.
2520 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2521 switches::kAppsGalleryInstallAutoConfirmForTests,
2522 "cancel");
2523
2524 // The extension that has a plugin should not install.
2525 extensions::UnpackedInstaller::Create(service_)->Load(
2526 extension_with_plugin_path);
2527 loop_.RunAllPending();
2528 EXPECT_EQ(0u, GetErrors().size());
2529 EXPECT_EQ(0u, loaded_.size());
2530 EXPECT_EQ(0u, service_->extensions()->size());
2531 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2532
2533 // But the extension with no plugin should since there's no prompt.
2534 extensions::UnpackedInstaller::Create(service_)->Load(
2535 extension_no_plugin_path);
2536 loop_.RunAllPending();
2537 EXPECT_EQ(0u, GetErrors().size());
2538 EXPECT_EQ(1u, loaded_.size());
2539 EXPECT_EQ(1u, service_->extensions()->size());
2540 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2541 EXPECT_TRUE(service_->extensions()->Contains(good2));
2542
2543 // The plugin extension should install if we accept the dialog.
2544 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2545 switches::kAppsGalleryInstallAutoConfirmForTests,
2546 "accept");
2547
2548 extensions::UnpackedInstaller::Create(service_)->Load(
2549 extension_with_plugin_path);
2550 loop_.RunAllPending();
2551 EXPECT_EQ(0u, GetErrors().size());
2552 EXPECT_EQ(2u, loaded_.size());
2553 EXPECT_EQ(2u, service_->extensions()->size());
2554 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2555 EXPECT_TRUE(service_->extensions()->Contains(good1));
2556 EXPECT_TRUE(service_->extensions()->Contains(good2));
2557
2558 // Make sure the granted permissions have been setup.
[email protected]c2e66e12012-06-27 06:27:062559 scoped_refptr<PermissionSet> permissions(
[email protected]0d904312012-01-25 23:00:162560 service_->extension_prefs()->GetGrantedPermissions(good1));
2561 EXPECT_FALSE(permissions->IsEmpty());
2562 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2563 EXPECT_FALSE(permissions->apis().empty());
[email protected]c2e66e12012-06-27 06:27:062564 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
[email protected]0d904312012-01-25 23:00:162565
2566 // We should be able to reload the extension without getting another prompt.
2567 loaded_.clear();
2568 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
2569 switches::kAppsGalleryInstallAutoConfirmForTests,
2570 "cancel");
2571
2572 service_->ReloadExtension(good1);
2573 loop_.RunAllPending();
2574 EXPECT_EQ(1u, loaded_.size());
2575 EXPECT_EQ(2u, service_->extensions()->size());
2576 EXPECT_EQ(0u, service_->disabled_extensions()->size());
2577}
2578#endif
2579
[email protected]7fa19f82010-12-21 19:40:082580namespace {
2581
2582bool IsExtension(const Extension& extension) {
2583 return extension.GetType() == Extension::TYPE_EXTENSION;
2584}
2585
2586} // namespace
2587
[email protected]aa142702010-03-26 01:26:332588// Test adding a pending extension.
[email protected]7fa19f82010-12-21 19:40:082589TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
[email protected]eaa7dd182010-12-14 11:09:002590 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332591
[email protected]145a317b2011-04-12 16:03:462592 const std::string kFakeId(all_zero);
[email protected]aa142702010-03-26 01:26:332593 const GURL kFakeUpdateURL("http:://fake.update/url");
[email protected]aa142702010-03-26 01:26:332594 const bool kFakeInstallSilently(true);
2595
[email protected]f4d5e1a2011-04-28 02:08:252596 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082597 kFakeId, kFakeUpdateURL, &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332598 kFakeInstallSilently));
[email protected]b2907fd2011-03-25 16:43:372599
[email protected]3f213ad2012-07-26 23:39:412600 const extensions::PendingExtensionInfo* pending_extension_info;
[email protected]51a3bf8b2012-06-08 22:53:062601 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2602 GetById(kFakeId)));
2603 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2604 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2605 EXPECT_EQ(kFakeInstallSilently, pending_extension_info->install_silently());
[email protected]aa142702010-03-26 01:26:332606}
2607
[email protected]aa142702010-03-26 01:26:332608namespace {
2609const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2610const char kGoodUpdateURL[] = "http://good.update/url";
[email protected]8ef78fd2010-08-19 17:14:322611const bool kGoodIsFromSync = true;
[email protected]aa142702010-03-26 01:26:332612const bool kGoodInstallSilently = true;
[email protected]aa142702010-03-26 01:26:332613} // namespace
2614
2615// Test updating a pending extension.
[email protected]eaa7dd182010-12-14 11:09:002616TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2617 InitializeEmptyExtensionService();
[email protected]f4d5e1a2011-04-28 02:08:252618 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082619 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332620 kGoodInstallSilently));
[email protected]b2907fd2011-03-25 16:43:372621 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332622
[email protected]e85e34c32011-04-13 18:38:352623 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]6cc7dbae2011-04-29 21:18:332624 UpdateExtension(kGoodId, path, ENABLED);
[email protected]aa142702010-03-26 01:26:332625
[email protected]b2907fd2011-03-25 16:43:372626 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]4416c5a2010-06-26 01:28:572627
[email protected]9adb9692010-10-29 23:14:022628 const Extension* extension = service_->GetExtensionById(kGoodId, true);
[email protected]4416c5a2010-06-26 01:28:572629 ASSERT_TRUE(extension);
[email protected]aa142702010-03-26 01:26:332630}
2631
[email protected]7fa19f82010-12-21 19:40:082632namespace {
2633
2634bool IsTheme(const Extension& extension) {
2635 return extension.is_theme();
2636}
2637
2638} // namespace
2639
[email protected]11edd1e2010-07-21 00:14:502640// Test updating a pending theme.
[email protected]7f2c5552011-12-20 22:53:162641// Disabled due to ASAN failure. http://crbug.com/108320
2642TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
[email protected]eaa7dd182010-12-14 11:09:002643 InitializeEmptyExtensionService();
[email protected]f4d5e1a2011-04-28 02:08:252644 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:332645 theme_crx, GURL(), &IsTheme, false));
[email protected]b2907fd2011-03-25 16:43:372646 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502647
[email protected]e85e34c32011-04-13 18:38:352648 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]11edd1e2010-07-21 00:14:502649 UpdateExtension(theme_crx, path, ENABLED);
2650
[email protected]b2907fd2011-03-25 16:43:372651 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502652
[email protected]9adb9692010-10-29 23:14:022653 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]11edd1e2010-07-21 00:14:502654 ASSERT_TRUE(extension);
2655
[email protected]ad83ca242011-07-29 01:32:252656 EXPECT_FALSE(
2657 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
[email protected]36429da2011-07-11 20:25:182658 EXPECT_TRUE(service_->IsExtensionEnabled(theme_crx));
[email protected]11edd1e2010-07-21 00:14:502659}
2660
[email protected]d74f92e2011-04-18 15:39:232661#if defined(OS_CHROMEOS)
2662// Always fails on ChromeOS: http://crbug.com/79737
2663#define MAYBE_UpdatePendingExternalCrx FAILS_UpdatePendingExternalCrx
2664#else
2665#define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
2666#endif
[email protected]8ef78fd2010-08-19 17:14:322667// Test updating a pending CRX as if the source is an external extension
2668// with an update URL. In this case we don't know if the CRX is a theme
2669// or not.
[email protected]d74f92e2011-04-18 15:39:232670TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
[email protected]eaa7dd182010-12-14 11:09:002671 InitializeEmptyExtensionService();
[email protected]9060d8b02012-01-13 02:14:302672 EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2673 theme_crx, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD));
[email protected]8ef78fd2010-08-19 17:14:322674
[email protected]b2907fd2011-03-25 16:43:372675 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322676
[email protected]e85e34c32011-04-13 18:38:352677 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:322678 UpdateExtension(theme_crx, path, ENABLED);
2679
[email protected]b2907fd2011-03-25 16:43:372680 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322681
[email protected]9adb9692010-10-29 23:14:022682 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]8ef78fd2010-08-19 17:14:322683 ASSERT_TRUE(extension);
2684
[email protected]ad83ca242011-07-29 01:32:252685 EXPECT_FALSE(
2686 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
[email protected]36429da2011-07-11 20:25:182687 EXPECT_TRUE(service_->IsExtensionEnabled(extension->id()));
[email protected]c3cfb012011-04-06 22:07:352688 EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
[email protected]8ef78fd2010-08-19 17:14:322689}
2690
[email protected]1afaf2a52010-11-02 19:29:172691// Test updating a pending CRX as if the source is an external extension
2692// with an update URL. The external update should overwrite a sync update,
2693// but a sync update should not overwrite a non-sync update.
[email protected]eaa7dd182010-12-14 11:09:002694TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
2695 InitializeEmptyExtensionService();
[email protected]1afaf2a52010-11-02 19:29:172696
2697 // Add a crx to be installed from the update mechanism.
[email protected]f4d5e1a2011-04-28 02:08:252698 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082699 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332700 kGoodInstallSilently));
[email protected]1afaf2a52010-11-02 19:29:172701
2702 // Check that there is a pending crx, with is_from_sync set to true.
[email protected]3f213ad2012-07-26 23:39:412703 const extensions::PendingExtensionInfo* pending_extension_info;
[email protected]51a3bf8b2012-06-08 22:53:062704 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2705 GetById(kGoodId)));
2706 EXPECT_TRUE(pending_extension_info->is_from_sync());
[email protected]1afaf2a52010-11-02 19:29:172707
2708 // Add a crx to be updated, with the same ID, from a non-sync source.
[email protected]9060d8b02012-01-13 02:14:302709 EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2710 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD));
[email protected]1afaf2a52010-11-02 19:29:172711
2712 // Check that there is a pending crx, with is_from_sync set to false.
[email protected]51a3bf8b2012-06-08 22:53:062713 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2714 GetById(kGoodId)));
2715 EXPECT_FALSE(pending_extension_info->is_from_sync());
[email protected]b2907fd2011-03-25 16:43:372716 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
[email protected]51a3bf8b2012-06-08 22:53:062717 pending_extension_info->install_source());
[email protected]1afaf2a52010-11-02 19:29:172718
2719 // Add a crx to be installed from the update mechanism.
[email protected]f4d5e1a2011-04-28 02:08:252720 EXPECT_FALSE(service_->pending_extension_manager()->AddFromSync(
[email protected]7fa19f82010-12-21 19:40:082721 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332722 kGoodInstallSilently));
[email protected]1afaf2a52010-11-02 19:29:172723
2724 // Check that the external, non-sync update was not overridden.
[email protected]51a3bf8b2012-06-08 22:53:062725 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
2726 GetById(kGoodId)));
2727 EXPECT_FALSE(pending_extension_info->is_from_sync());
[email protected]b2907fd2011-03-25 16:43:372728 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
[email protected]51a3bf8b2012-06-08 22:53:062729 pending_extension_info->install_source());
[email protected]1afaf2a52010-11-02 19:29:172730}
2731
[email protected]8ef78fd2010-08-19 17:14:322732// Updating a theme should fail if the updater is explicitly told that
2733// the CRX is not a theme.
[email protected]eaa7dd182010-12-14 11:09:002734TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
2735 InitializeEmptyExtensionService();
[email protected]f4d5e1a2011-04-28 02:08:252736 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:332737 theme_crx, GURL(), &IsExtension, true));
[email protected]8ef78fd2010-08-19 17:14:322738
[email protected]b2907fd2011-03-25 16:43:372739 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322740
[email protected]e85e34c32011-04-13 18:38:352741 FilePath path = data_dir_.AppendASCII("theme.crx");
[email protected]8ef78fd2010-08-19 17:14:322742 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
2743
[email protected]b2907fd2011-03-25 16:43:372744 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
[email protected]8ef78fd2010-08-19 17:14:322745
[email protected]9adb9692010-10-29 23:14:022746 const Extension* extension = service_->GetExtensionById(theme_crx, true);
[email protected]8ef78fd2010-08-19 17:14:322747 ASSERT_FALSE(extension);
2748}
2749
[email protected]aa142702010-03-26 01:26:332750// TODO(akalin): Test updating a pending extension non-silently once
2751// we can mock out ExtensionInstallUI and inject our version into
2752// UpdateExtension().
2753
[email protected]7fa19f82010-12-21 19:40:082754// Test updating a pending extension which fails the should-install test.
2755TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
[email protected]eaa7dd182010-12-14 11:09:002756 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332757 // Add pending extension with a flipped is_theme.
[email protected]f4d5e1a2011-04-28 02:08:252758 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:332759 kGoodId, GURL(kGoodUpdateURL), &IsTheme, kGoodInstallSilently));
[email protected]b2907fd2011-03-25 16:43:372760 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332761
[email protected]e85e34c32011-04-13 18:38:352762 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572763 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:332764
2765 // TODO(akalin): Figure out how to check that the extensions
2766 // directory is cleaned up properly in OnExtensionInstalled().
2767
[email protected]b2907fd2011-03-25 16:43:372768 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332769}
2770
[email protected]11edd1e2010-07-21 00:14:502771// TODO(akalin): Figure out how to test that installs of pending
2772// unsyncable extensions are blocked.
2773
[email protected]aa142702010-03-26 01:26:332774// Test updating a pending extension for one that is not pending.
[email protected]eaa7dd182010-12-14 11:09:002775TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
2776 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332777
[email protected]e85e34c32011-04-13 18:38:352778 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]4416c5a2010-06-26 01:28:572779 UpdateExtension(kGoodId, path, UPDATED);
[email protected]aa142702010-03-26 01:26:332780
[email protected]b2907fd2011-03-25 16:43:372781 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]aa142702010-03-26 01:26:332782}
2783
2784// Test updating a pending extension for one that is already
2785// installed.
[email protected]eaa7dd182010-12-14 11:09:002786TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
2787 InitializeEmptyExtensionService();
[email protected]aa142702010-03-26 01:26:332788
[email protected]e85e34c32011-04-13 18:38:352789 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502790 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]aa142702010-03-26 01:26:332791 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]aa142702010-03-26 01:26:332792
[email protected]8ef78fd2010-08-19 17:14:322793 EXPECT_FALSE(good->is_theme());
2794
[email protected]b2907fd2011-03-25 16:43:372795 // Use AddExtensionImpl() as AddFrom*() would balk.
2796 service_->pending_extension_manager()->AddExtensionImpl(
[email protected]e3987852012-05-04 10:06:302797 good->id(), good->update_url(), Version(), &IsExtension,
[email protected]6cc7dbae2011-04-29 21:18:332798 kGoodIsFromSync, kGoodInstallSilently, Extension::INTERNAL);
2799 UpdateExtension(good->id(), path, ENABLED);
[email protected]aa142702010-03-26 01:26:332800
[email protected]b2907fd2011-03-25 16:43:372801 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
[email protected]e957fe52009-06-23 16:51:052802}
2803
[email protected]6b75ec32009-08-14 06:37:182804// Test pref settings for blacklist and unblacklist extensions.
[email protected]eaa7dd182010-12-14 11:09:002805TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
2806 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182807 std::vector<std::string> blacklist;
2808 blacklist.push_back(good0);
2809 blacklist.push_back("invalid_id"); // an invalid id
2810 blacklist.push_back(good1);
2811 service_->UpdateExtensionBlacklist(blacklist);
2812 // Make sure pref is updated
2813 loop_.RunAllPending();
2814
2815 // blacklist is set for good0,1,2
[email protected]e2194742010-08-12 05:54:342816 ValidateBooleanPref(good0, "blacklist", true);
2817 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182818 // invalid_id should not be inserted to pref.
[email protected]e2194742010-08-12 05:54:342819 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182820
2821 // remove good1, add good2
2822 blacklist.pop_back();
2823 blacklist.push_back(good2);
2824
2825 service_->UpdateExtensionBlacklist(blacklist);
2826 // only good0 and good1 should be set
[email protected]e2194742010-08-12 05:54:342827 ValidateBooleanPref(good0, "blacklist", true);
2828 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
2829 ValidateBooleanPref(good2, "blacklist", true);
2830 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182831}
2832
2833// Unload installed extension from blacklist.
[email protected]eaa7dd182010-12-14 11:09:002834TEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) {
2835 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182836
[email protected]e85e34c32011-04-13 18:38:352837 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]6b75ec32009-08-14 06:37:182838
[email protected]8f512c72011-11-22 21:02:502839 const Extension* good = InstallCRX(path, INSTALL_NEW);
[email protected]6b75ec32009-08-14 06:37:182840 EXPECT_EQ(good_crx, good->id());
[email protected]4416c5a2010-06-26 01:28:572841 UpdateExtension(good_crx, path, FAILED_SILENTLY);
[email protected]6b75ec32009-08-14 06:37:182842
2843 std::vector<std::string> blacklist;
2844 blacklist.push_back(good_crx);
2845 service_->UpdateExtensionBlacklist(blacklist);
2846 // Make sure pref is updated
2847 loop_.RunAllPending();
2848
2849 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:342850 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182851 EXPECT_EQ(0u, service_->extensions()->size());
2852
2853 // Remove good_crx from blacklist
2854 blacklist.pop_back();
2855 service_->UpdateExtensionBlacklist(blacklist);
2856 // Make sure pref is updated
2857 loop_.RunAllPending();
2858 // blacklist value should not be set for good_crx
[email protected]e2194742010-08-12 05:54:342859 EXPECT_FALSE(IsPrefExist(good_crx, "blacklist"));
[email protected]6b75ec32009-08-14 06:37:182860}
2861
2862// Unload installed extension from blacklist.
[email protected]eaa7dd182010-12-14 11:09:002863TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
2864 InitializeEmptyExtensionService();
[email protected]6b75ec32009-08-14 06:37:182865 std::vector<std::string> blacklist;
2866 blacklist.push_back(good_crx);
2867 service_->UpdateExtensionBlacklist(blacklist);
2868 // Make sure pref is updated
2869 loop_.RunAllPending();
2870
2871 // Now, the good_crx is blacklisted.
[email protected]e2194742010-08-12 05:54:342872 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182873
2874 // We can not install good_crx.
[email protected]e85e34c32011-04-13 18:38:352875 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:502876 InstallCRX(path, INSTALL_FAILED);
[email protected]6b75ec32009-08-14 06:37:182877 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]e2194742010-08-12 05:54:342878 ValidateBooleanPref(good_crx, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:182879}
2880
[email protected]4ee07c62012-08-21 12:40:422881// Unload blacklisted extension on policy change.
2882TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
2883 InitializeEmptyExtensionService();
2884 FilePath path = data_dir_.AppendASCII("good.crx");
2885
2886 const Extension* good = InstallCRX(path, INSTALL_NEW);
2887 EXPECT_EQ(good_crx, good->id());
2888 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2889 EXPECT_EQ(1u, service_->extensions()->size());
2890
2891 base::ListValue whitelist;
2892 PrefService* prefs = service_->extension_prefs()->pref_service();
2893 whitelist.Append(base::Value::CreateStringValue(good_crx));
2894 prefs->Set(prefs::kExtensionInstallAllowList, whitelist);
2895
2896 std::vector<std::string> blacklist;
2897 blacklist.push_back(good_crx);
2898 service_->UpdateExtensionBlacklist(blacklist);
2899 // Make sure pref is updated
2900
2901 // Now, the good_crx is blacklisted but whitelist negates it.
2902 ValidateBooleanPref(good_crx, "blacklist", true);
2903 EXPECT_EQ(1u, service_->extensions()->size());
2904
2905 whitelist.Clear();
2906 prefs->Set(prefs::kExtensionInstallAllowList, whitelist);
2907
2908 // Now, the good_crx is blacklisted for good.
2909 ValidateBooleanPref(good_crx, "blacklist", true);
2910 EXPECT_EQ(0u, service_->extensions()->size());
2911}
2912
2913// Allow Google-blacklisted extension if policy explicitly allows it (blacklist
2914// then set policy).
2915TEST_F(ExtensionServiceTest, WhitelistGoogleBlacklistedExtension) {
2916 InitializeEmptyExtensionService();
2917
2918 std::vector<std::string> blacklist;
2919 blacklist.push_back(good_crx);
2920 service_->UpdateExtensionBlacklist(blacklist);
2921
2922 FilePath path = data_dir_.AppendASCII("good.crx");
2923 InstallCRX(path, INSTALL_FAILED);
2924
2925 base::ListValue whitelist;
2926 whitelist.Append(base::Value::CreateStringValue(good_crx));
2927 service_->extension_prefs()->pref_service()->Set(
2928 prefs::kExtensionInstallAllowList, whitelist);
2929
2930 InstallCRX(path, INSTALL_NEW);
2931}
2932
2933// Allow Google-blacklisted extension if policy requires it (blacklist then set
2934// policy).
2935TEST_F(ExtensionServiceTest, ForcelistGoogleBlacklistedExtension) {
2936 InitializeEmptyExtensionService();
2937
2938 std::vector<std::string> blacklist;
2939 blacklist.push_back(good_crx);
2940 service_->UpdateExtensionBlacklist(blacklist);
2941
2942 FilePath path = data_dir_.AppendASCII("good.crx");
2943 InstallCRX(path, INSTALL_FAILED);
2944
2945 base::ListValue forcelist;
2946 forcelist.Append(base::Value::CreateStringValue(good_crx));
2947 service_->extension_prefs()->pref_service()->Set(
2948 prefs::kExtensionInstallAllowList, forcelist);
2949
2950 InstallCRX(path, INSTALL_NEW);
2951}
2952
2953// Allow Google-blacklisted extension if policy explicitly allows it (set policy
2954// then blacklist).
2955TEST_F(ExtensionServiceTest, GoogleBlacklistWhitelistedExtension) {
2956 InitializeEmptyExtensionService();
2957
2958 base::ListValue whitelist;
2959 whitelist.Append(base::Value::CreateStringValue(good_crx));
2960 service_->extension_prefs()->pref_service()->Set(
2961 prefs::kExtensionInstallAllowList, whitelist);
2962
2963 std::vector<std::string> blacklist;
2964 blacklist.push_back(good_crx);
2965 service_->UpdateExtensionBlacklist(blacklist);
2966
2967 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
2968}
2969
2970// Allow Google-blacklisted extension if policy requires it (set policy then
2971// blacklist).
2972TEST_F(ExtensionServiceTest, GoogleBlacklistForcelistedExtension) {
2973 InitializeEmptyExtensionService();
2974
2975 base::ListValue forcelist;
2976 forcelist.Append(base::Value::CreateStringValue(good_crx));
2977 service_->extension_prefs()->pref_service()->Set(
2978 prefs::kExtensionInstallAllowList, forcelist);
2979
2980 std::vector<std::string> blacklist;
2981 blacklist.push_back(good_crx);
2982 service_->UpdateExtensionBlacklist(blacklist);
2983
2984 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
2985}
2986
[email protected]6b75ec32009-08-14 06:37:182987// Test loading extensions from the profile directory, except
2988// blacklisted ones.
[email protected]eaa7dd182010-12-14 11:09:002989TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
[email protected]6b75ec32009-08-14 06:37:182990 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:352991 FilePath source_install_dir = data_dir_
[email protected]6b75ec32009-08-14 06:37:182992 .AppendASCII("good")
2993 .AppendASCII("Extensions");
2994 FilePath pref_path = source_install_dir
2995 .DirName()
2996 .AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:002997 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]6b75ec32009-08-14 06:37:182998
[email protected]e50013c32010-08-18 21:05:242999 // Blacklist good1.
[email protected]6b75ec32009-08-14 06:37:183000 std::vector<std::string> blacklist;
[email protected]e50013c32010-08-18 21:05:243001 blacklist.push_back(good1);
[email protected]6b75ec32009-08-14 06:37:183002 service_->UpdateExtensionBlacklist(blacklist);
3003 // Make sure pref is updated
3004 loop_.RunAllPending();
3005
[email protected]e50013c32010-08-18 21:05:243006 ValidateBooleanPref(good1, "blacklist", true);
[email protected]6b75ec32009-08-14 06:37:183007
3008 // Load extensions.
3009 service_->Init();
[email protected]6b75ec32009-08-14 06:37:183010
[email protected]fc670822011-12-17 09:33:493011 std::vector<string16> errors = GetErrors();
3012 for (std::vector<string16>::iterator err = errors.begin();
[email protected]6b75ec32009-08-14 06:37:183013 err != errors.end(); ++err) {
3014 LOG(ERROR) << *err;
3015 }
[email protected]d7b36dc2009-10-29 21:47:403016 ASSERT_EQ(2u, loaded_.size());
[email protected]6b75ec32009-08-14 06:37:183017
[email protected]8f512c72011-11-22 21:02:503018 EXPECT_FALSE(service_->GetExtensionById(good1, true));
[email protected]6b75ec32009-08-14 06:37:183019}
3020
[email protected]306a2bd2010-08-11 14:56:363021// Will not install extension blacklisted by policy.
[email protected]eaa7dd182010-12-14 11:09:003022TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3023 InitializeEmptyExtensionService();
[email protected]306a2bd2010-08-11 14:56:363024
[email protected]306a2bd2010-08-11 14:56:363025 // Blacklist everything.
[email protected]43d3bf82011-04-11 07:46:583026 {
3027 ListPrefUpdate update(profile_->GetPrefs(),
3028 prefs::kExtensionInstallDenyList);
3029 ListValue* blacklist = update.Get();
3030 blacklist->Append(Value::CreateStringValue("*"));
3031 }
[email protected]306a2bd2010-08-11 14:56:363032
3033 // Blacklist prevents us from installing good_crx.
[email protected]e85e34c32011-04-13 18:38:353034 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503035 InstallCRX(path, INSTALL_FAILED);
[email protected]306a2bd2010-08-11 14:56:363036 EXPECT_EQ(0u, service_->extensions()->size());
3037
3038 // Now whitelist this particular extension.
[email protected]43d3bf82011-04-11 07:46:583039 {
3040 ListPrefUpdate update(profile_->GetPrefs(),
3041 prefs::kExtensionInstallAllowList);
3042 ListValue* whitelist = update.Get();
3043 whitelist->Append(Value::CreateStringValue(good_crx));
3044 }
3045
[email protected]306a2bd2010-08-11 14:56:363046 // Ensure we can now install good_crx.
[email protected]8f512c72011-11-22 21:02:503047 InstallCRX(path, INSTALL_NEW);
[email protected]306a2bd2010-08-11 14:56:363048 EXPECT_EQ(1u, service_->extensions()->size());
3049}
3050
[email protected]aa96d3a2010-08-21 08:45:253051// Extension blacklisted by policy get unloaded after installing.
[email protected]eaa7dd182010-12-14 11:09:003052TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3053 InitializeEmptyExtensionService();
[email protected]aa96d3a2010-08-21 08:45:253054
3055 // Install good_crx.
[email protected]e85e34c32011-04-13 18:38:353056 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503057 InstallCRX(path, INSTALL_NEW);
[email protected]aa96d3a2010-08-21 08:45:253058 EXPECT_EQ(1u, service_->extensions()->size());
3059
[email protected]acd78969c2010-12-08 09:49:113060 { // Scope for pref update notification.
3061 PrefService* prefs = profile_->GetPrefs();
[email protected]43d3bf82011-04-11 07:46:583062 ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList);
3063 ListValue* blacklist = update.Get();
[email protected]acd78969c2010-12-08 09:49:113064 ASSERT_TRUE(blacklist != NULL);
[email protected]aa96d3a2010-08-21 08:45:253065
[email protected]acd78969c2010-12-08 09:49:113066 // Blacklist this extension.
3067 blacklist->Append(Value::CreateStringValue(good_crx));
[email protected]acd78969c2010-12-08 09:49:113068 }
[email protected]aa96d3a2010-08-21 08:45:253069
3070 // Extension should not be running now.
3071 loop_.RunAllPending();
3072 EXPECT_EQ(0u, service_->extensions()->size());
3073}
3074
[email protected]05aad2da2011-10-28 10:12:373075// Tests that component extensions are not blacklisted by policy.
3076TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3077 InitializeEmptyExtensionService();
3078
3079 // Blacklist everything.
3080 {
3081 ListPrefUpdate update(profile_->GetPrefs(),
3082 prefs::kExtensionInstallDenyList);
3083 ListValue* blacklist = update.Get();
3084 blacklist->Append(Value::CreateStringValue("*"));
3085 }
3086
3087 // Install a component extension.
3088 FilePath path = data_dir_
3089 .AppendASCII("good")
3090 .AppendASCII("Extensions")
3091 .AppendASCII(good0)
3092 .AppendASCII("1.0.0.0");
3093 std::string manifest;
3094 ASSERT_TRUE(file_util::ReadFileToString(
3095 path.Append(Extension::kManifestFilename), &manifest));
[email protected]d8c8f25f2011-11-02 18:18:013096 service_->component_loader()->Add(manifest, path);
[email protected]05aad2da2011-10-28 10:12:373097 service_->Init();
3098
3099 // Extension should be installed despite blacklist.
3100 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503101 EXPECT_TRUE(service_->GetExtensionById(good0, false));
[email protected]05aad2da2011-10-28 10:12:373102
3103 // Poke external providers and make sure the extension is still present.
3104 service_->CheckForExternalUpdates();
3105 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503106 EXPECT_TRUE(service_->GetExtensionById(good0, false));
[email protected]05aad2da2011-10-28 10:12:373107
3108 // Extension should not be uninstalled on blacklist changes.
3109 {
3110 ListPrefUpdate update(profile_->GetPrefs(),
3111 prefs::kExtensionInstallDenyList);
3112 ListValue* blacklist = update.Get();
3113 blacklist->Append(Value::CreateStringValue(good0));
3114 }
3115 loop_.RunAllPending();
3116 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503117 EXPECT_TRUE(service_->GetExtensionById(good0, false));
[email protected]05aad2da2011-10-28 10:12:373118}
3119
3120// Tests that policy-installed extensions are not blacklisted by policy.
3121TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3122 InitializeEmptyExtensionService();
3123
3124 // Blacklist everything.
3125 {
3126 ListPrefUpdate update(profile_->GetPrefs(),
3127 prefs::kExtensionInstallDenyList);
3128 ListValue* blacklist = update.Get();
3129 blacklist->Append(Value::CreateStringValue("*"));
3130 }
3131
3132 // Have policy force-install an extension.
3133 MockExtensionProvider* provider =
3134 new MockExtensionProvider(service_,
3135 Extension::EXTERNAL_POLICY_DOWNLOAD);
3136 AddMockExternalProvider(provider);
3137 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3138 data_dir_.AppendASCII("good.crx"));
3139
3140 // Reloading extensions should find our externally registered extension
3141 // and install it.
3142 service_->CheckForExternalUpdates();
3143 loop_.RunAllPending();
3144
3145 // Extension should be installed despite blacklist.
3146 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503147 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]05aad2da2011-10-28 10:12:373148
3149 // Blacklist update should not uninstall the extension.
3150 {
3151 ListPrefUpdate update(profile_->GetPrefs(),
3152 prefs::kExtensionInstallDenyList);
3153 ListValue* blacklist = update.Get();
3154 blacklist->Append(Value::CreateStringValue(good0));
3155 }
3156 loop_.RunAllPending();
3157 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:503158 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]05aad2da2011-10-28 10:12:373159}
3160
[email protected]65187152012-06-02 13:14:143161// Tests that extensions cannot be installed if the policy provider prohibits
3162// it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3163TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3164 InitializeEmptyExtensionService();
3165
3166 management_policy_->UnregisterAllProviders();
3167 extensions::TestManagementPolicyProvider provider_(
3168 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3169 management_policy_->RegisterProvider(&provider_);
3170
3171 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_FAILED);
3172 EXPECT_EQ(0u, service_->extensions()->size());
3173}
3174
3175// Tests that extensions cannot be loaded from prefs if the policy provider
3176// prohibits it. This functionality is implemented in InstalledLoader::Load().
3177TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3178 InitializeEmptyExtensionService();
3179
3180 // Create a fake extension to be loaded as though it were read from prefs.
3181 FilePath path = data_dir_.AppendASCII("management")
3182 .AppendASCII("simple_extension");
3183 DictionaryValue manifest;
3184 manifest.SetString(keys::kName, "simple_extension");
3185 manifest.SetString(keys::kVersion, "1");
3186 // LOAD is for extensions loaded from the command line. We use it here, even
3187 // though we're testing loading from prefs, so that we don't need to provide
3188 // an extension key.
3189 extensions::ExtensionInfo extension_info(&manifest, "", path,
3190 Extension::LOAD);
3191
3192 // Ensure we can load it with no management policy in place.
3193 management_policy_->UnregisterAllProviders();
3194 EXPECT_EQ(0u, service_->extensions()->size());
3195 extensions::InstalledLoader(service_).Load(extension_info, false);
3196 EXPECT_EQ(1u, service_->extensions()->size());
3197
3198 const Extension* extension = *(service_->extensions()->begin());
3199 EXPECT_TRUE(service_->UninstallExtension(extension->id(), false, NULL));
3200 EXPECT_EQ(0u, service_->extensions()->size());
3201
3202 // Ensure we cannot load it if management policy prohibits installation.
3203 extensions::TestManagementPolicyProvider provider_(
3204 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3205 management_policy_->RegisterProvider(&provider_);
3206
3207 extensions::InstalledLoader(service_).Load(extension_info, false);
3208 EXPECT_EQ(0u, service_->extensions()->size());
3209}
3210
3211// Tests disabling an extension when prohibited by the ManagementPolicy.
3212TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3213 InitializeEmptyExtensionService();
3214
3215 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3216 EXPECT_EQ(1u, service_->extensions()->size());
3217 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3218
3219 management_policy_->UnregisterAllProviders();
3220 extensions::TestManagementPolicyProvider provider(
3221 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3222 management_policy_->RegisterProvider(&provider);
3223
3224 // Attempt to disable it.
3225 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3226
3227 EXPECT_EQ(1u, service_->extensions()->size());
3228 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3229 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3230}
3231
3232// Tests uninstalling an extension when prohibited by the ManagementPolicy.
3233TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3234 InitializeEmptyExtensionService();
3235
3236 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3237 EXPECT_EQ(1u, service_->extensions()->size());
3238 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3239
3240 management_policy_->UnregisterAllProviders();
3241 extensions::TestManagementPolicyProvider provider(
3242 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3243 management_policy_->RegisterProvider(&provider);
3244
3245 // Attempt to uninstall it.
3246 EXPECT_FALSE(service_->UninstallExtension(good_crx, false, NULL));
3247
3248 EXPECT_EQ(1u, service_->extensions()->size());
3249 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3250}
3251
3252// Tests that previously installed extensions that are now prohibited from
3253// being installed are removed.
3254TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3255 InitializeEmptyExtensionService();
3256
3257 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3258 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
3259 EXPECT_EQ(2u, service_->extensions()->size());
3260 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3261
3262 management_policy_->UnregisterAllProviders();
3263 extensions::TestManagementPolicyProvider provider(
3264 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3265 management_policy_->RegisterProvider(&provider);
3266
3267 // Run the policy check.
[email protected]4ee07c62012-08-21 12:40:423268 service_->CheckManagementPolicy();
[email protected]65187152012-06-02 13:14:143269 EXPECT_EQ(0u, service_->extensions()->size());
3270 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3271}
3272
3273// Tests that previously disabled extensions that are now required to be
3274// enabled are re-enabled on reinstall.
3275TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
3276 InitializeEmptyExtensionService();
3277
3278 // Install, then disable, an extension.
3279 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3280 EXPECT_EQ(1u, service_->extensions()->size());
3281 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3282 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3283
3284 // Register an ExtensionMnagementPolicy that requires the extension to remain
3285 // enabled.
3286 management_policy_->UnregisterAllProviders();
3287 extensions::TestManagementPolicyProvider provider(
3288 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
3289 management_policy_->RegisterProvider(&provider);
3290
3291 // Reinstall the extension.
3292 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_UPDATED);
3293 EXPECT_EQ(1u, service_->extensions()->size());
3294 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3295}
3296
[email protected]a39921b42012-02-28 03:42:543297TEST_F(ExtensionServiceTest, ExternalExtensionAutoAcknowledgement) {
3298 InitializeEmptyExtensionService();
3299 set_extensions_enabled(true);
3300
3301 {
3302 // Register and install an external extension.
3303 MockExtensionProvider* provider =
[email protected]f121003b2012-05-04 21:57:473304 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]a39921b42012-02-28 03:42:543305 AddMockExternalProvider(provider);
3306 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3307 data_dir_.AppendASCII("good.crx"));
3308 }
3309 {
3310 // Have policy force-install an extension.
3311 MockExtensionProvider* provider =
3312 new MockExtensionProvider(service_,
3313 Extension::EXTERNAL_POLICY_DOWNLOAD);
3314 AddMockExternalProvider(provider);
3315 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
3316 data_dir_.AppendASCII("page_action.crx"));
3317 }
3318
3319 // Providers are set up. Let them run.
3320 service_->CheckForExternalUpdates();
3321 loop_.RunAllPending();
3322
3323 ASSERT_EQ(2u, service_->extensions()->size());
3324 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3325 EXPECT_TRUE(service_->GetExtensionById(page_action, false));
3326 ExtensionPrefs* prefs = service_->extension_prefs();
3327 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
3328 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
3329}
3330
[email protected]a7cd28e2012-10-05 21:03:363331#if !defined(OS_CHROMEOS)
3332// This tests if default apps are installed correctly.
3333TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
3334 InitializeEmptyExtensionService();
3335 InitializeRequestContext();
3336 set_extensions_enabled(true);
3337
3338 {
3339 std::string json_data =
3340 "{"
3341 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
3342 " \"external_crx\": \"good.crx\","
3343 " \"external_version\": \"1.0.0.0\","
3344 " \"is_bookmark_app\": false"
3345 " }"
3346 "}";
3347 default_apps::Provider* provider =
3348 new default_apps::Provider(
3349 profile_.get(),
3350 service_,
3351 new extensions::ExternalTestingLoader(json_data, data_dir_),
3352 Extension::INTERNAL,
3353 Extension::INVALID,
3354 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
3355
3356 AddMockExternalProvider(provider);
3357 }
3358
3359 ASSERT_EQ(0u, service_->extensions()->size());
3360 service_->CheckForExternalUpdates();
3361 loop_.RunAllPending();
3362
3363 ASSERT_EQ(1u, service_->extensions()->size());
3364 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3365 const Extension* extension = service_->GetExtensionById(good_crx, false);
3366 EXPECT_TRUE(extension->from_webstore());
3367 EXPECT_TRUE(extension->was_installed_by_default());
3368
3369}
3370#endif
3371
[email protected]cd500f72010-06-25 23:44:323372// Tests disabling extensions
[email protected]eaa7dd182010-12-14 11:09:003373TEST_F(ExtensionServiceTest, DisableExtension) {
3374 InitializeEmptyExtensionService();
[email protected]cd500f72010-06-25 23:44:323375
[email protected]8f512c72011-11-22 21:02:503376 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]84df8332011-12-06 18:22:463377 EXPECT_FALSE(service_->extensions()->is_empty());
[email protected]8f512c72011-11-22 21:02:503378 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3379 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
[email protected]84df8332011-12-06 18:22:463380 EXPECT_TRUE(service_->disabled_extensions()->is_empty());
[email protected]cd500f72010-06-25 23:44:323381
3382 // Disable it.
[email protected]44d62b62012-04-11 00:06:033383 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
[email protected]cd500f72010-06-25 23:44:323384
[email protected]84df8332011-12-06 18:22:463385 EXPECT_TRUE(service_->extensions()->is_empty());
[email protected]8f512c72011-11-22 21:02:503386 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3387 EXPECT_FALSE(service_->GetExtensionById(good_crx, false));
[email protected]84df8332011-12-06 18:22:463388 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
[email protected]fa2416f2011-05-03 08:41:203389}
3390
3391TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
3392 InitializeEmptyExtensionService();
3393
[email protected]8f512c72011-11-22 21:02:503394 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203395 TerminateExtension(good_crx);
3396 EXPECT_TRUE(service_->GetTerminatedExtension(good_crx));
3397
3398 // Disable it.
[email protected]44d62b62012-04-11 00:06:033399 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
[email protected]fa2416f2011-05-03 08:41:203400
3401 EXPECT_FALSE(service_->GetTerminatedExtension(good_crx));
[email protected]8f512c72011-11-22 21:02:503402 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
[email protected]84df8332011-12-06 18:22:463403 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
[email protected]cd500f72010-06-25 23:44:323404}
3405
[email protected]d728e002010-12-08 04:46:233406// Tests disabling all extensions (simulating --disable-extensions flag).
[email protected]eaa7dd182010-12-14 11:09:003407TEST_F(ExtensionServiceTest, DisableAllExtensions) {
3408 InitializeEmptyExtensionService();
[email protected]d728e002010-12-08 04:46:233409
[email protected]e85e34c32011-04-13 18:38:353410 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503411 InstallCRX(path, INSTALL_NEW);
[email protected]d728e002010-12-08 04:46:233412
3413 EXPECT_EQ(1u, service_->extensions()->size());
3414 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3415
3416 // Disable extensions.
3417 service_->set_extensions_enabled(false);
3418 service_->ReloadExtensions();
3419
3420 // There shouldn't be extensions in either list.
3421 EXPECT_EQ(0u, service_->extensions()->size());
3422 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3423
3424 // This shouldn't do anything when all extensions are disabled.
3425 service_->EnableExtension(good_crx);
3426 service_->ReloadExtensions();
3427
3428 // There still shouldn't be extensions in either list.
3429 EXPECT_EQ(0u, service_->extensions()->size());
3430 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3431
3432 // And then re-enable the extensions.
3433 service_->set_extensions_enabled(true);
3434 service_->ReloadExtensions();
3435
3436 EXPECT_EQ(1u, service_->extensions()->size());
3437 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3438}
3439
[email protected]8f512c72011-11-22 21:02:503440// Tests reloading extensions.
[email protected]eaa7dd182010-12-14 11:09:003441TEST_F(ExtensionServiceTest, ReloadExtensions) {
3442 InitializeEmptyExtensionService();
[email protected]26367b62012-10-04 23:03:323443 InitializeRequestContext();
[email protected]cd500f72010-06-25 23:44:323444
3445 // Simple extension that should install without error.
[email protected]e85e34c32011-04-13 18:38:353446 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]26367b62012-10-04 23:03:323447 InstallCRX(path, INSTALL_NEW,
3448 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
[email protected]cd500f72010-06-25 23:44:323449 const char* extension_id = good_crx;
[email protected]44d62b62012-04-11 00:06:033450 service_->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
[email protected]cd500f72010-06-25 23:44:323451
3452 EXPECT_EQ(0u, service_->extensions()->size());
3453 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3454
3455 service_->ReloadExtensions();
3456
[email protected]26367b62012-10-04 23:03:323457 // The creation flags should not change when reloading the extension.
3458 const Extension* extension = service_->GetExtensionById(good_crx, true);
3459 EXPECT_TRUE(extension->from_webstore());
3460 EXPECT_TRUE(extension->was_installed_by_default());
3461 EXPECT_FALSE(extension->from_bookmark());
3462
[email protected]cd500f72010-06-25 23:44:323463 // Extension counts shouldn't change.
3464 EXPECT_EQ(0u, service_->extensions()->size());
3465 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3466
3467 service_->EnableExtension(extension_id);
3468
3469 EXPECT_EQ(1u, service_->extensions()->size());
3470 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3471
[email protected]5a73f902010-06-30 02:29:413472 // Need to clear |loaded_| manually before reloading as the
3473 // EnableExtension() call above inserted into it and
3474 // UnloadAllExtensions() doesn't send out notifications.
3475 loaded_.clear();
[email protected]cd500f72010-06-25 23:44:323476 service_->ReloadExtensions();
3477
3478 // Extension counts shouldn't change.
3479 EXPECT_EQ(1u, service_->extensions()->size());
3480 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3481}
3482
[email protected]7dda8e12011-11-29 19:20:173483TEST_F(ExtensionServiceTest, UninstallExtension) {
[email protected]eaa7dd182010-12-14 11:09:003484 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503485 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]65187152012-06-02 13:14:143486 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]fa2416f2011-05-03 08:41:203487 UninstallExtension(good_crx, false);
[email protected]65187152012-06-02 13:14:143488 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]fa2416f2011-05-03 08:41:203489}
[email protected]631cf822009-05-15 07:01:253490
[email protected]fa2416f2011-05-03 08:41:203491TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
3492 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503493 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203494 TerminateExtension(good_crx);
3495 UninstallExtension(good_crx, false);
[email protected]631cf822009-05-15 07:01:253496}
3497
[email protected]6aeac8342010-10-01 20:21:183498// Tests the uninstaller helper.
[email protected]eaa7dd182010-12-14 11:09:003499TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
3500 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503501 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203502 UninstallExtension(good_crx, true);
3503}
[email protected]6aeac8342010-10-01 20:21:183504
[email protected]fa2416f2011-05-03 08:41:203505TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
3506 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:503507 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:203508 TerminateExtension(good_crx);
3509 UninstallExtension(good_crx, true);
[email protected]6aeac8342010-10-01 20:21:183510}
3511
[email protected]98270432012-09-11 20:51:243512// An extension disabled because of unsupported requirements should re-enabled
3513// if updated to a version with supported requirements as long as there are no
3514// other disable reasons.
3515TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
3516 InitializeEmptyExtensionService();
3517 BlackListWebGL();
3518
3519 FilePath path = data_dir_.AppendASCII("requirements");
3520 FilePath pem_path = data_dir_.AppendASCII("requirements")
3521 .AppendASCII("v1_good.pem");
3522 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
3523 pem_path,
3524 INSTALL_NEW);
3525 std::string id = extension_v1->id();
3526 EXPECT_TRUE(service_->IsExtensionEnabled(id));
3527
3528 PackCRX(path.AppendASCII("v2_bad_requirements"), pem_path,
3529 path.AppendASCII("v2_bad_requirements.crx"));
3530 UpdateExtension(id, path.AppendASCII("v2_bad_requirements.crx"), INSTALLED);
3531 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3532
3533 PackCRX(path.AppendASCII("v3_good"), pem_path,
3534 path.AppendASCII("v3_good.crx"));
3535 UpdateExtension(id, path.AppendASCII("v3_good.crx"), ENABLED);
3536 EXPECT_TRUE(service_->IsExtensionEnabled(id));
3537}
3538
3539// Extensions disabled through user action should stay disabled.
3540TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
3541 InitializeEmptyExtensionService();
3542 BlackListWebGL();
3543
3544 FilePath path = data_dir_.AppendASCII("requirements");
3545 FilePath pem_path = data_dir_.AppendASCII("requirements")
3546 .AppendASCII("v1_good.pem");
3547 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
3548 pem_path,
3549 INSTALL_NEW);
3550 std::string id = extension_v1->id();
3551 service_->DisableExtension(id, Extension::DISABLE_USER_ACTION);
3552 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3553
3554 PackCRX(path.AppendASCII("v2_bad_requirements"), pem_path,
3555 path.AppendASCII("v2_bad_requirements.crx"));
3556 UpdateExtension(id, path.AppendASCII("v2_bad_requirements.crx"), INSTALLED);
3557 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3558
3559 PackCRX(path.AppendASCII("v3_good"), pem_path,
3560 path.AppendASCII("v3_good.crx"));
3561 UpdateExtension(id, path.AppendASCII("v3_good.crx"), INSTALLED);
3562 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3563}
3564
3565// The extension should not re-enabled because it was disabled from a
3566// permission increase.
3567TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
3568 InitializeEmptyExtensionService();
3569 BlackListWebGL();
3570
3571 FilePath path = data_dir_.AppendASCII("requirements");
3572 FilePath pem_path = data_dir_.AppendASCII("requirements")
3573 .AppendASCII("v1_good.pem");
3574 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
3575 pem_path,
3576 INSTALL_NEW);
3577 std::string id = extension_v1->id();
3578 EXPECT_TRUE(service_->IsExtensionEnabled(id));
3579
3580 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"), pem_path,
3581 path.AppendASCII("v2_bad_requirements_and_permissions.crx"));
3582 UpdateExtension(
3583 id,
3584 path.AppendASCII("v2_bad_requirements_and_permissions.crx"), INSTALLED);
3585 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3586
3587 PackCRX(path.AppendASCII("v3_bad_permissions"), pem_path,
3588 path.AppendASCII("v3_bad_permissions.crx"));
3589 UpdateExtension(id, path.AppendASCII("v3_bad_permissions.crx"), INSTALLED);
3590 EXPECT_FALSE(service_->IsExtensionEnabled(id));
3591}
3592
3593// Unpacked extensions are not allowed to be installed if they have unsupported
3594// requirements.
3595TEST_F(ExtensionServiceTest, UnpackedRequirements) {
3596 InitializeEmptyExtensionService();
3597 BlackListWebGL();
3598
3599 FilePath path = data_dir_.AppendASCII("requirements")
3600 .AppendASCII("v2_bad_requirements");
3601 extensions::UnpackedInstaller::Create(service_)->Load(path);
3602 loop_.RunAllPending();
3603 EXPECT_EQ(1u, GetErrors().size());
3604 EXPECT_EQ(0u, service_->extensions()->size());
3605}
3606
[email protected]c4148a72011-08-09 23:04:203607class ExtensionCookieCallback {
3608 public:
3609 ExtensionCookieCallback()
3610 : result_(false),
[email protected]51d02152011-12-24 05:55:223611 weak_factory_(MessageLoop::current()) {}
[email protected]c4148a72011-08-09 23:04:203612
3613 void SetCookieCallback(bool result) {
3614 MessageLoop::current()->PostTask(
[email protected]51d02152011-12-24 05:55:223615 FROM_HERE, base::Bind(&MessageLoop::Quit, weak_factory_.GetWeakPtr()));
[email protected]c4148a72011-08-09 23:04:203616 result_ = result;
3617 }
3618
3619 void GetAllCookiesCallback(const net::CookieList& list) {
3620 MessageLoop::current()->PostTask(
[email protected]51d02152011-12-24 05:55:223621 FROM_HERE, base::Bind(&MessageLoop::Quit, weak_factory_.GetWeakPtr()));
[email protected]c4148a72011-08-09 23:04:203622 list_ = list;
3623 }
3624 net::CookieList list_;
3625 bool result_;
[email protected]51d02152011-12-24 05:55:223626 base::WeakPtrFactory<MessageLoop> weak_factory_;
[email protected]c4148a72011-08-09 23:04:203627};
3628
[email protected]0d6ec3a72011-09-02 02:09:433629// Verifies extension state is removed upon uninstall.
[email protected]eaa7dd182010-12-14 11:09:003630TEST_F(ExtensionServiceTest, ClearExtensionData) {
3631 InitializeEmptyExtensionService();
[email protected]c4148a72011-08-09 23:04:203632 ExtensionCookieCallback callback;
[email protected]c10da4b02010-03-25 14:38:323633
3634 // Load a test extension.
[email protected]e85e34c32011-04-13 18:38:353635 FilePath path = data_dir_;
[email protected]c10da4b02010-03-25 14:38:323636 path = path.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:503637 const Extension* extension = InstallCRX(path, INSTALL_NEW);
[email protected]c10da4b02010-03-25 14:38:323638 ASSERT_TRUE(extension);
3639 GURL ext_url(extension->url());
3640 string16 origin_id =
3641 webkit_database::DatabaseUtil::GetOriginIdentifier(ext_url);
3642
3643 // Set a cookie for the extension.
[email protected]277ec262011-03-30 21:09:403644 net::CookieMonster* cookie_monster =
3645 profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
3646 cookie_store()->GetCookieMonster();
[email protected]c10da4b02010-03-25 14:38:323647 ASSERT_TRUE(cookie_monster);
3648 net::CookieOptions options;
[email protected]c4148a72011-08-09 23:04:203649 cookie_monster->SetCookieWithOptionsAsync(
3650 ext_url, "dummy=value", options,
3651 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
3652 base::Unretained(&callback)));
3653 loop_.RunAllPending();
3654 EXPECT_TRUE(callback.result_);
3655
3656 cookie_monster->GetAllCookiesForURLAsync(
3657 ext_url,
3658 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3659 base::Unretained(&callback)));
3660 loop_.RunAllPending();
3661 EXPECT_EQ(1U, callback.list_.size());
[email protected]c10da4b02010-03-25 14:38:323662
3663 // Open a database.
[email protected]55eb70e762012-02-20 17:38:393664 webkit_database::DatabaseTracker* db_tracker =
[email protected]5c8e67c2012-08-29 00:48:523665 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3666 GetDatabaseTracker();
[email protected]c10da4b02010-03-25 14:38:323667 string16 db_name = UTF8ToUTF16("db");
3668 string16 description = UTF8ToUTF16("db_description");
3669 int64 size;
[email protected]7c5f2ec2011-05-26 19:15:263670 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
[email protected]c10da4b02010-03-25 14:38:323671 db_tracker->DatabaseClosed(origin_id, db_name);
3672 std::vector<webkit_database::OriginInfo> origins;
3673 db_tracker->GetAllOriginsInfo(&origins);
3674 EXPECT_EQ(1U, origins.size());
3675 EXPECT_EQ(origin_id, origins[0].GetOrigin());
3676
[email protected]98823c682012-06-11 21:18:243677 // Create local storage. We only simulate this by creating the backing files.
3678 // Note: This test depends on details of how the dom_storage library
3679 // stores data in the host file system.
3680 FilePath lso_dir_path = profile_->GetPath().AppendASCII("Local Storage");
3681 FilePath lso_file_path = lso_dir_path.AppendASCII(
3682 UTF16ToUTF8(origin_id) + ".localstorage");
3683 EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
3684 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
3685 EXPECT_TRUE(file_util::PathExists(lso_file_path));
[email protected]c10da4b02010-03-25 14:38:323686
[email protected]ab308092011-08-25 23:37:193687 // Create indexed db. Similarly, it is enough to only simulate this by
3688 // creating the directory on the disk.
[email protected]b1b502e2012-09-16 07:31:433689 IndexedDBContext* idb_context =
3690 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3691 GetIndexedDBContext();
[email protected]35cc399e2012-02-23 18:19:283692 FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
[email protected]ab308092011-08-25 23:37:193693 EXPECT_TRUE(file_util::CreateDirectory(idb_path));
3694 EXPECT_TRUE(file_util::DirectoryExists(idb_path));
[email protected]e1dcf922010-11-22 19:12:123695
[email protected]c10da4b02010-03-25 14:38:323696 // Uninstall the extension.
[email protected]d6ebc9792011-04-07 18:18:333697 service_->UninstallExtension(good_crx, false, NULL);
[email protected]c10da4b02010-03-25 14:38:323698 loop_.RunAllPending();
3699
3700 // Check that the cookie is gone.
[email protected]c4148a72011-08-09 23:04:203701 cookie_monster->GetAllCookiesForURLAsync(
3702 ext_url,
3703 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3704 base::Unretained(&callback)));
3705 loop_.RunAllPending();
3706 EXPECT_EQ(0U, callback.list_.size());
[email protected]c10da4b02010-03-25 14:38:323707
3708 // The database should have vanished as well.
3709 origins.clear();
3710 db_tracker->GetAllOriginsInfo(&origins);
3711 EXPECT_EQ(0U, origins.size());
3712
3713 // Check that the LSO file has been removed.
[email protected]98823c682012-06-11 21:18:243714 EXPECT_FALSE(file_util::PathExists(lso_file_path));
[email protected]e1dcf922010-11-22 19:12:123715
3716 // Check if the indexed db has disappeared too.
[email protected]ab308092011-08-25 23:37:193717 EXPECT_FALSE(file_util::DirectoryExists(idb_path));
[email protected]c10da4b02010-03-25 14:38:323718}
3719
[email protected]0d6ec3a72011-09-02 02:09:433720// Verifies app state is removed upon uninstall.
3721TEST_F(ExtensionServiceTest, ClearAppData) {
3722 InitializeEmptyExtensionService();
3723 InitializeRequestContext();
3724 ExtensionCookieCallback callback;
3725
3726 int pref_count = 0;
3727
3728 // Install app1 with unlimited storage.
[email protected]8f512c72011-11-22 21:02:503729 const Extension* extension =
3730 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
[email protected]0d6ec3a72011-09-02 02:09:433731 ValidatePrefKeyCount(++pref_count);
3732 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]0d6ec3a72011-09-02 02:09:433733 const std::string id1 = extension->id();
3734 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:063735 APIPermission::kUnlimitedStorage));
[email protected]0d6ec3a72011-09-02 02:09:433736 const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
3737 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
3738 IsStorageUnlimited(origin1));
3739 string16 origin_id =
3740 webkit_database::DatabaseUtil::GetOriginIdentifier(origin1);
3741
3742 // Install app2 from the same origin with unlimited storage.
[email protected]8f512c72011-11-22 21:02:503743 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
[email protected]0d6ec3a72011-09-02 02:09:433744 ValidatePrefKeyCount(++pref_count);
3745 ASSERT_EQ(2u, service_->extensions()->size());
[email protected]0d6ec3a72011-09-02 02:09:433746 const std::string id2 = extension->id();
3747 EXPECT_TRUE(extension->HasAPIPermission(
[email protected]c2e66e12012-06-27 06:27:063748 APIPermission::kUnlimitedStorage));
[email protected]0d6ec3a72011-09-02 02:09:433749 EXPECT_TRUE(extension->web_extent().MatchesURL(
3750 extension->GetFullLaunchURL()));
3751 const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
3752 EXPECT_EQ(origin1, origin2);
3753 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
3754 IsStorageUnlimited(origin2));
3755
3756 // Set a cookie for the extension.
3757 net::CookieMonster* cookie_monster =
3758 profile_->GetRequestContext()->GetURLRequestContext()->
3759 cookie_store()->GetCookieMonster();
3760 ASSERT_TRUE(cookie_monster);
3761 net::CookieOptions options;
3762 cookie_monster->SetCookieWithOptionsAsync(
3763 origin1, "dummy=value", options,
3764 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
3765 base::Unretained(&callback)));
3766 loop_.RunAllPending();
3767 EXPECT_TRUE(callback.result_);
3768
3769 cookie_monster->GetAllCookiesForURLAsync(
3770 origin1,
3771 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3772 base::Unretained(&callback)));
3773 loop_.RunAllPending();
3774 EXPECT_EQ(1U, callback.list_.size());
3775
3776 // Open a database.
[email protected]55eb70e762012-02-20 17:38:393777 webkit_database::DatabaseTracker* db_tracker =
[email protected]5c8e67c2012-08-29 00:48:523778 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3779 GetDatabaseTracker();
[email protected]0d6ec3a72011-09-02 02:09:433780 string16 db_name = UTF8ToUTF16("db");
3781 string16 description = UTF8ToUTF16("db_description");
3782 int64 size;
3783 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
3784 db_tracker->DatabaseClosed(origin_id, db_name);
3785 std::vector<webkit_database::OriginInfo> origins;
3786 db_tracker->GetAllOriginsInfo(&origins);
3787 EXPECT_EQ(1U, origins.size());
3788 EXPECT_EQ(origin_id, origins[0].GetOrigin());
3789
[email protected]98823c682012-06-11 21:18:243790 // Create local storage. We only simulate this by creating the backing files.
3791 // Note: This test depends on details of how the dom_storage library
3792 // stores data in the host file system.
3793 FilePath lso_dir_path = profile_->GetPath().AppendASCII("Local Storage");
3794 FilePath lso_file_path = lso_dir_path.AppendASCII(
3795 UTF16ToUTF8(origin_id) + ".localstorage");
3796 EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
3797 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
3798 EXPECT_TRUE(file_util::PathExists(lso_file_path));
[email protected]0d6ec3a72011-09-02 02:09:433799
3800 // Create indexed db. Similarly, it is enough to only simulate this by
3801 // creating the directory on the disk.
[email protected]b1b502e2012-09-16 07:31:433802 IndexedDBContext* idb_context =
3803 BrowserContext::GetDefaultStoragePartition(profile_.get())->
3804 GetIndexedDBContext();
[email protected]35cc399e2012-02-23 18:19:283805 FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
[email protected]0d6ec3a72011-09-02 02:09:433806 EXPECT_TRUE(file_util::CreateDirectory(idb_path));
3807 EXPECT_TRUE(file_util::DirectoryExists(idb_path));
3808
3809 // Uninstall one of them, unlimited storage should still be granted
3810 // to the origin.
3811 UninstallExtension(id1, false);
3812 EXPECT_EQ(1u, service_->extensions()->size());
3813 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
3814 IsStorageUnlimited(origin1));
3815
3816 // Check that the cookie is still there.
3817 cookie_monster->GetAllCookiesForURLAsync(
3818 origin1,
3819 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3820 base::Unretained(&callback)));
3821 loop_.RunAllPending();
3822 EXPECT_EQ(1U, callback.list_.size());
3823
3824 // Now uninstall the other. Storage should be cleared for the apps.
3825 UninstallExtension(id2, false);
3826 EXPECT_EQ(0u, service_->extensions()->size());
3827 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
3828 IsStorageUnlimited(origin1));
3829
3830 // Check that the cookie is gone.
3831 cookie_monster->GetAllCookiesForURLAsync(
3832 origin1,
3833 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
3834 base::Unretained(&callback)));
3835 loop_.RunAllPending();
3836 EXPECT_EQ(0U, callback.list_.size());
3837
3838 // The database should have vanished as well.
3839 origins.clear();
3840 db_tracker->GetAllOriginsInfo(&origins);
3841 EXPECT_EQ(0U, origins.size());
3842
3843 // Check that the LSO file has been removed.
[email protected]98823c682012-06-11 21:18:243844 EXPECT_FALSE(file_util::PathExists(lso_file_path));
[email protected]0d6ec3a72011-09-02 02:09:433845
3846 // Check if the indexed db has disappeared too.
3847 EXPECT_FALSE(file_util::DirectoryExists(idb_path));
3848}
3849
[email protected]894bb502009-05-21 22:39:573850// Tests loading single extensions (like --load-extension)
[email protected]eaa7dd182010-12-14 11:09:003851TEST_F(ExtensionServiceTest, LoadExtension) {
3852 InitializeEmptyExtensionService();
[email protected]3cf4f0992009-02-03 23:00:303853
[email protected]e85e34c32011-04-13 18:38:353854 FilePath ext1 = data_dir_
[email protected]a9b00ac2009-06-25 21:03:233855 .AppendASCII("good")
3856 .AppendASCII("Extensions")
[email protected]5a2721f62009-06-13 07:08:203857 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
3858 .AppendASCII("1.0.0.0");
[email protected]d8c8f25f2011-11-02 18:18:013859 extensions::UnpackedInstaller::Create(service_)->Load(ext1);
[email protected]894bb502009-05-21 22:39:573860 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:183861 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:573862 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:323863 EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
3864 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:303865
[email protected]e8c729a2010-03-09 19:55:193866 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:193867
[email protected]e85e34c32011-04-13 18:38:353868 FilePath no_manifest = data_dir_
[email protected]a9b00ac2009-06-25 21:03:233869 .AppendASCII("bad")
[email protected]93fd78f42009-07-10 16:43:173870 // .AppendASCII("Extensions")
[email protected]a9b00ac2009-06-25 21:03:233871 .AppendASCII("cccccccccccccccccccccccccccccccc")
3872 .AppendASCII("1");
[email protected]d8c8f25f2011-11-02 18:18:013873 extensions::UnpackedInstaller::Create(service_)->Load(no_manifest);
[email protected]894bb502009-05-21 22:39:573874 loop_.RunAllPending();
[email protected]bb28e062009-02-27 17:19:183875 EXPECT_EQ(1u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:573876 ASSERT_EQ(1u, loaded_.size());
[email protected]9f1087e2009-06-15 17:29:323877 EXPECT_EQ(1u, service_->extensions()->size());
[email protected]25b34332009-06-05 21:53:193878
3879 // Test uninstall.
[email protected]894bb502009-05-21 22:39:573880 std::string id = loaded_[0]->id();
3881 EXPECT_FALSE(unloaded_id_.length());
[email protected]d6ebc9792011-04-07 18:18:333882 service_->UninstallExtension(id, false, NULL);
[email protected]894bb502009-05-21 22:39:573883 loop_.RunAllPending();
3884 EXPECT_EQ(id, unloaded_id_);
[email protected]9f1087e2009-06-15 17:29:323885 ASSERT_EQ(0u, loaded_.size());
3886 EXPECT_EQ(0u, service_->extensions()->size());
[email protected]3cf4f0992009-02-03 23:00:303887}
[email protected]0b344962009-03-31 04:21:453888
[email protected]894bb502009-05-21 22:39:573889// Tests that we generate IDs when they are not specified in the manifest for
3890// --load-extension.
[email protected]eaa7dd182010-12-14 11:09:003891TEST_F(ExtensionServiceTest, GenerateID) {
3892 InitializeEmptyExtensionService();
[email protected]fbcc40302009-06-12 20:45:453893
[email protected]e85e34c32011-04-13 18:38:353894 FilePath no_id_ext = data_dir_.AppendASCII("no_id");
[email protected]d8c8f25f2011-11-02 18:18:013895 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
[email protected]894bb502009-05-21 22:39:573896 loop_.RunAllPending();
[email protected]0b344962009-03-31 04:21:453897 EXPECT_EQ(0u, GetErrors().size());
[email protected]894bb502009-05-21 22:39:573898 ASSERT_EQ(1u, loaded_.size());
[email protected]84ac7f32009-10-06 06:17:543899 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
[email protected]9f1087e2009-06-15 17:29:323900 EXPECT_EQ(loaded_[0]->location(), Extension::LOAD);
[email protected]0b344962009-03-31 04:21:453901
[email protected]e8c729a2010-03-09 19:55:193902 ValidatePrefKeyCount(1);
[email protected]25b34332009-06-05 21:53:193903
[email protected]84ac7f32009-10-06 06:17:543904 std::string previous_id = loaded_[0]->id();
3905
3906 // If we reload the same path, we should get the same extension ID.
[email protected]d8c8f25f2011-11-02 18:18:013907 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
[email protected]894bb502009-05-21 22:39:573908 loop_.RunAllPending();
[email protected]84ac7f32009-10-06 06:17:543909 ASSERT_EQ(1u, loaded_.size());
3910 ASSERT_EQ(previous_id, loaded_[0]->id());
[email protected]0b344962009-03-31 04:21:453911}
[email protected]894bb502009-05-21 22:39:573912
[email protected]eaa7dd182010-12-14 11:09:003913void ExtensionServiceTest::TestExternalProvider(
[email protected]d55e7602009-12-16 04:20:423914 MockExtensionProvider* provider, Extension::Location location) {
[email protected]a1257b12009-06-12 02:51:343915 // Verify that starting with no providers loads no extensions.
3916 service_->Init();
[email protected]a1257b12009-06-12 02:51:343917 ASSERT_EQ(0u, loaded_.size());
3918
[email protected]0a60a2e2010-10-25 16:15:213919 provider->set_visit_count(0);
3920
[email protected]a1257b12009-06-12 02:51:343921 // Register a test extension externally using the mock registry provider.
[email protected]e85e34c32011-04-13 18:38:353922 FilePath source_path = data_dir_.AppendASCII("good.crx");
[email protected]894bb502009-05-21 22:39:573923
[email protected]a1257b12009-06-12 02:51:343924 // Add the extension.
[email protected]d55e7602009-12-16 04:20:423925 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
[email protected]894bb502009-05-21 22:39:573926
[email protected]9f1087e2009-06-15 17:29:323927 // Reloading extensions should find our externally registered extension
[email protected]894bb502009-05-21 22:39:573928 // and install it.
[email protected]93fd78f42009-07-10 16:43:173929 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:573930 loop_.RunAllPending();
3931
3932 ASSERT_EQ(0u, GetErrors().size());
3933 ASSERT_EQ(1u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:423934 ASSERT_EQ(location, loaded_[0]->location());
[email protected]894bb502009-05-21 22:39:573935 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:193936 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:343937 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
3938 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:573939
[email protected]9f1087e2009-06-15 17:29:323940 // Reload extensions without changing anything. The extension should be
[email protected]894bb502009-05-21 22:39:573941 // loaded again.
3942 loaded_.clear();
[email protected]9f1087e2009-06-15 17:29:323943 service_->ReloadExtensions();
[email protected]894bb502009-05-21 22:39:573944 loop_.RunAllPending();
3945 ASSERT_EQ(0u, GetErrors().size());
3946 ASSERT_EQ(1u, loaded_.size());
[email protected]25b34332009-06-05 21:53:193947 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:343948 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
3949 ValidateIntegerPref(good_crx, "location", location);
[email protected]e2eb43112009-05-29 21:19:543950
[email protected]894bb502009-05-21 22:39:573951 // Now update the extension with a new version. We should get upgraded.
3952 source_path = source_path.DirName().AppendASCII("good2.crx");
[email protected]d55e7602009-12-16 04:20:423953 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]894bb502009-05-21 22:39:573954
3955 loaded_.clear();
[email protected]93fd78f42009-07-10 16:43:173956 service_->CheckForExternalUpdates();
[email protected]894bb502009-05-21 22:39:573957 loop_.RunAllPending();
3958 ASSERT_EQ(0u, GetErrors().size());
3959 ASSERT_EQ(1u, loaded_.size());
3960 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
[email protected]25b34332009-06-05 21:53:193961 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:343962 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
3963 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:573964
[email protected]27b985d2009-06-25 17:53:153965 // Uninstall the extension and reload. Nothing should happen because the
[email protected]894bb502009-05-21 22:39:573966 // preference should prevent us from reinstalling.
3967 std::string id = loaded_[0]->id();
[email protected]d6ebc9792011-04-07 18:18:333968 service_->UninstallExtension(id, false, NULL);
[email protected]894bb502009-05-21 22:39:573969 loop_.RunAllPending();
3970
[email protected]a9b00ac2009-06-25 21:03:233971 FilePath install_path = extensions_install_dir_.AppendASCII(id);
[email protected]65187152012-06-02 13:14:143972 if (Extension::IsRequired(location)) {
3973 // Policy controlled extensions should not have been touched by uninstall.
3974 ASSERT_TRUE(file_util::PathExists(install_path));
3975 } else {
[email protected]95da88c42011-03-31 10:07:333976 // The extension should also be gone from the install directory.
3977 ASSERT_FALSE(file_util::PathExists(install_path));
3978 loaded_.clear();
3979 service_->CheckForExternalUpdates();
3980 loop_.RunAllPending();
3981 ASSERT_EQ(0u, loaded_.size());
3982 ValidatePrefKeyCount(1);
[email protected]79c833b52011-04-05 18:31:013983 ValidateIntegerPref(good_crx, "state",
3984 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
[email protected]95da88c42011-03-31 10:07:333985 ValidateIntegerPref(good_crx, "location", location);
[email protected]894bb502009-05-21 22:39:573986
[email protected]95da88c42011-03-31 10:07:333987 // Now clear the preference and reinstall.
3988 SetPrefInteg(good_crx, "state", Extension::ENABLED);
[email protected]25b34332009-06-05 21:53:193989
[email protected]95da88c42011-03-31 10:07:333990 loaded_.clear();
3991 service_->CheckForExternalUpdates();
3992 loop_.RunAllPending();
3993 ASSERT_EQ(1u, loaded_.size());
[email protected]95da88c42011-03-31 10:07:333994 }
[email protected]25b34332009-06-05 21:53:193995 ValidatePrefKeyCount(1);
[email protected]e2194742010-08-12 05:54:343996 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
3997 ValidateIntegerPref(good_crx, "location", location);
[email protected]25b34332009-06-05 21:53:193998
[email protected]65187152012-06-02 13:14:143999 if (Extension::IsRequired(location)) {
4000 EXPECT_EQ(2, provider->visit_count());
4001 } else {
[email protected]95da88c42011-03-31 10:07:334002 // Now test an externally triggered uninstall (deleting the registry key or
4003 // the pref entry).
4004 provider->RemoveExtension(good_crx);
[email protected]25b34332009-06-05 21:53:194005
[email protected]95da88c42011-03-31 10:07:334006 loaded_.clear();
[email protected]50067e52011-10-20 23:17:074007 service_->OnExternalProviderReady(provider);
[email protected]95da88c42011-03-31 10:07:334008 loop_.RunAllPending();
4009 ASSERT_EQ(0u, loaded_.size());
4010 ValidatePrefKeyCount(0);
[email protected]25b34332009-06-05 21:53:194011
[email protected]95da88c42011-03-31 10:07:334012 // The extension should also be gone from the install directory.
4013 ASSERT_FALSE(file_util::PathExists(install_path));
[email protected]abe7a8942009-06-23 05:14:294014
[email protected]95da88c42011-03-31 10:07:334015 // Now test the case where user uninstalls and then the extension is removed
4016 // from the external provider.
[email protected]05aad2da2011-10-28 10:12:374017 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
[email protected]95da88c42011-03-31 10:07:334018 service_->CheckForExternalUpdates();
4019 loop_.RunAllPending();
[email protected]abe7a8942009-06-23 05:14:294020
[email protected]95da88c42011-03-31 10:07:334021 ASSERT_EQ(1u, loaded_.size());
4022 ASSERT_EQ(0u, GetErrors().size());
[email protected]d55e7602009-12-16 04:20:424023
[email protected]95da88c42011-03-31 10:07:334024 // User uninstalls.
4025 loaded_.clear();
[email protected]d6ebc9792011-04-07 18:18:334026 service_->UninstallExtension(id, false, NULL);
[email protected]95da88c42011-03-31 10:07:334027 loop_.RunAllPending();
4028 ASSERT_EQ(0u, loaded_.size());
[email protected]d55e7602009-12-16 04:20:424029
[email protected]95da88c42011-03-31 10:07:334030 // Then remove the extension from the extension provider.
4031 provider->RemoveExtension(good_crx);
[email protected]d55e7602009-12-16 04:20:424032
[email protected]95da88c42011-03-31 10:07:334033 // Should still be at 0.
4034 loaded_.clear();
[email protected]d8c8f25f2011-11-02 18:18:014035 extensions::InstalledLoader(service_).LoadAllExtensions();
[email protected]95da88c42011-03-31 10:07:334036 loop_.RunAllPending();
4037 ASSERT_EQ(0u, loaded_.size());
4038 ValidatePrefKeyCount(1);
[email protected]0a60a2e2010-10-25 16:15:214039
[email protected]95da88c42011-03-31 10:07:334040 EXPECT_EQ(5, provider->visit_count());
[email protected]95da88c42011-03-31 10:07:334041 }
[email protected]d55e7602009-12-16 04:20:424042}
4043
4044// Tests the external installation feature
4045#if defined(OS_WIN)
[email protected]eaa7dd182010-12-14 11:09:004046TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
[email protected]aebe23a32010-12-10 22:15:484047 // This should all work, even when normal extension installation is disabled.
[email protected]eaa7dd182010-12-14 11:09:004048 InitializeEmptyExtensionService();
[email protected]aebe23a32010-12-10 22:15:484049 set_extensions_enabled(false);
[email protected]d55e7602009-12-16 04:20:424050
4051 // Now add providers. Extension system takes ownership of the objects.
4052 MockExtensionProvider* reg_provider =
[email protected]14908b72011-04-20 06:54:364053 new MockExtensionProvider(service_, Extension::EXTERNAL_REGISTRY);
[email protected]0a60a2e2010-10-25 16:15:214054 AddMockExternalProvider(reg_provider);
[email protected]d55e7602009-12-16 04:20:424055 TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
4056}
4057#endif
4058
[email protected]eaa7dd182010-12-14 11:09:004059TEST_F(ExtensionServiceTest, ExternalInstallPref) {
4060 InitializeEmptyExtensionService();
[email protected]d55e7602009-12-16 04:20:424061
4062 // Now add providers. Extension system takes ownership of the objects.
4063 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:364064 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]0a60a2e2010-10-25 16:15:214065
4066 AddMockExternalProvider(pref_provider);
[email protected]d55e7602009-12-16 04:20:424067 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
[email protected]27b985d2009-06-25 17:53:154068}
4069
[email protected]eaa7dd182010-12-14 11:09:004070TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
[email protected]aebe23a32010-12-10 22:15:484071 // This should all work, even when normal extension installation is disabled.
[email protected]eaa7dd182010-12-14 11:09:004072 InitializeEmptyExtensionService();
[email protected]aebe23a32010-12-10 22:15:484073 set_extensions_enabled(false);
[email protected]55196e92010-09-29 15:04:464074
[email protected]0a60a2e2010-10-25 16:15:214075 // TODO(skerner): The mock provider is not a good model of a provider
4076 // that works with update URLs, because it adds file and version info.
4077 // Extend the mock to work with update URLs. This test checks the
4078 // behavior that is common to all external extension visitors. The
4079 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4080 // what the visitor does results in an extension being downloaded and
4081 // installed.
[email protected]55196e92010-09-29 15:04:464082 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:364083 new MockExtensionProvider(service_,
[email protected]8e4560b62011-01-14 10:09:144084 Extension::EXTERNAL_PREF_DOWNLOAD);
[email protected]0a60a2e2010-10-25 16:15:214085 AddMockExternalProvider(pref_provider);
[email protected]55196e92010-09-29 15:04:464086 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF_DOWNLOAD);
4087}
4088
[email protected]95da88c42011-03-31 10:07:334089TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
4090 // This should all work, even when normal extension installation is disabled.
4091 InitializeEmptyExtensionService();
4092 set_extensions_enabled(false);
4093
4094 // TODO(skerner): The mock provider is not a good model of a provider
4095 // that works with update URLs, because it adds file and version info.
4096 // Extend the mock to work with update URLs. This test checks the
4097 // behavior that is common to all external extension visitors. The
4098 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4099 // what the visitor does results in an extension being downloaded and
4100 // installed.
4101 MockExtensionProvider* pref_provider =
[email protected]14908b72011-04-20 06:54:364102 new MockExtensionProvider(service_,
[email protected]95da88c42011-03-31 10:07:334103 Extension::EXTERNAL_POLICY_DOWNLOAD);
4104 AddMockExternalProvider(pref_provider);
4105 TestExternalProvider(pref_provider, Extension::EXTERNAL_POLICY_DOWNLOAD);
4106}
4107
[email protected]aebe23a32010-12-10 22:15:484108// Tests that external extensions get uninstalled when the external extension
4109// providers can't account for them.
[email protected]eaa7dd182010-12-14 11:09:004110TEST_F(ExtensionServiceTest, ExternalUninstall) {
[email protected]aebe23a32010-12-10 22:15:484111 // Start the extensions service with one external extension already installed.
[email protected]e85e34c32011-04-13 18:38:354112 FilePath source_install_dir = data_dir_
[email protected]aebe23a32010-12-10 22:15:484113 .AppendASCII("good")
4114 .AppendASCII("Extensions");
4115 FilePath pref_path = source_install_dir
4116 .DirName()
4117 .AppendASCII("PreferencesExternal");
4118
[email protected]5df038b2012-07-16 19:03:274119 // This initializes the extensions service with no ExternalProviders.
[email protected]eaa7dd182010-12-14 11:09:004120 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]aebe23a32010-12-10 22:15:484121 set_extensions_enabled(false);
4122
4123 service_->Init();
[email protected]aebe23a32010-12-10 22:15:484124
4125 ASSERT_EQ(0u, GetErrors().size());
4126 ASSERT_EQ(0u, loaded_.size());
4127
4128 // Verify that it's not the disabled extensions flag causing it not to load.
4129 set_extensions_enabled(true);
4130 service_->ReloadExtensions();
4131 loop_.RunAllPending();
4132
4133 ASSERT_EQ(0u, GetErrors().size());
4134 ASSERT_EQ(0u, loaded_.size());
4135}
4136
[email protected]a29a517a2011-01-21 21:11:124137// Test that running multiple update checks simultaneously does not
4138// keep the update from succeeding.
4139TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
4140 InitializeEmptyExtensionService();
4141
4142 MockExtensionProvider* provider =
[email protected]14908b72011-04-20 06:54:364143 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]a29a517a2011-01-21 21:11:124144 AddMockExternalProvider(provider);
4145
4146 // Verify that starting with no providers loads no extensions.
4147 service_->Init();
[email protected]a29a517a2011-01-21 21:11:124148 ASSERT_EQ(0u, loaded_.size());
4149
4150 // Start two checks for updates.
4151 provider->set_visit_count(0);
4152 service_->CheckForExternalUpdates();
4153 service_->CheckForExternalUpdates();
4154 loop_.RunAllPending();
4155
4156 // Two calls should cause two checks for external extensions.
4157 EXPECT_EQ(2, provider->visit_count());
4158 EXPECT_EQ(0u, GetErrors().size());
4159 EXPECT_EQ(0u, loaded_.size());
4160
4161 // Register a test extension externally using the mock registry provider.
[email protected]e85e34c32011-04-13 18:38:354162 FilePath source_path = data_dir_.AppendASCII("good.crx");
[email protected]a29a517a2011-01-21 21:11:124163 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4164
4165 // Two checks for external updates should find the extension, and install it
4166 // once.
4167 provider->set_visit_count(0);
4168 service_->CheckForExternalUpdates();
4169 service_->CheckForExternalUpdates();
4170 loop_.RunAllPending();
4171 EXPECT_EQ(2, provider->visit_count());
4172 ASSERT_EQ(0u, GetErrors().size());
4173 ASSERT_EQ(1u, loaded_.size());
4174 ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location());
4175 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4176 ValidatePrefKeyCount(1);
4177 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4178 ValidateIntegerPref(good_crx, "location", Extension::EXTERNAL_PREF);
4179
4180 provider->RemoveExtension(good_crx);
4181 provider->set_visit_count(0);
4182 service_->CheckForExternalUpdates();
4183 service_->CheckForExternalUpdates();
4184 loop_.RunAllPending();
4185
4186 // Two calls should cause two checks for external extensions.
4187 // Because the external source no longer includes good_crx,
4188 // good_crx will be uninstalled. So, expect that no extensions
4189 // are loaded.
4190 EXPECT_EQ(2, provider->visit_count());
4191 EXPECT_EQ(0u, GetErrors().size());
4192 EXPECT_EQ(0u, loaded_.size());
4193}
4194
[email protected]9d32ded072011-10-11 16:31:054195namespace {
4196 class ScopedBrowserLocale {
4197 public:
4198 explicit ScopedBrowserLocale(const std::string& new_locale)
4199 : old_locale_(g_browser_process->GetApplicationLocale()) {
4200 g_browser_process->SetApplicationLocale(new_locale);
4201 }
4202
4203 ~ScopedBrowserLocale() {
4204 g_browser_process->SetApplicationLocale(old_locale_);
4205 }
4206
4207 private:
4208 std::string old_locale_;
4209 };
4210}
4211
[email protected]eaa7dd182010-12-14 11:09:004212TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
4213 InitializeEmptyExtensionService();
[email protected]f0841cd2011-01-19 15:07:244214
4215 // Test some valid extension records.
4216 // Set a base path to avoid erroring out on relative paths.
4217 // Paths starting with // are absolute on every platform we support.
4218 FilePath base_path(FILE_PATH_LITERAL("//base/path"));
4219 ASSERT_TRUE(base_path.IsAbsolute());
4220 MockProviderVisitor visitor(base_path);
[email protected]27b985d2009-06-25 17:53:154221 std::string json_data =
4222 "{"
[email protected]f0841cd2011-01-19 15:07:244223 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
[email protected]9e54cb572010-09-03 20:08:064224 " \"external_crx\": \"RandomExtension.crx\","
4225 " \"external_version\": \"1.0\""
4226 " },"
4227 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4228 " \"external_crx\": \"RandomExtension2.crx\","
4229 " \"external_version\": \"2.0\""
4230 " },"
4231 " \"cccccccccccccccccccccccccccccccc\": {"
[email protected]a424d84c2010-09-24 09:31:154232 " \"external_update_url\": \"http:\\\\foo.com/update\""
[email protected]9e54cb572010-09-03 20:08:064233 " }"
[email protected]27b985d2009-06-25 17:53:154234 "}";
[email protected]f0841cd2011-01-19 15:07:244235 EXPECT_EQ(3, visitor.Visit(json_data));
[email protected]27b985d2009-06-25 17:53:154236
[email protected]9e54cb572010-09-03 20:08:064237 // Simulate an external_extensions.json file that contains seven invalid
[email protected]f0841cd2011-01-19 15:07:244238 // records:
[email protected]27b985d2009-06-25 17:53:154239 // - One that is missing the 'external_crx' key.
4240 // - One that is missing the 'external_version' key.
4241 // - One that is specifying .. in the path.
[email protected]8ef78fd2010-08-19 17:14:324242 // - One that specifies both a file and update URL.
4243 // - One that specifies no file or update URL.
4244 // - One that has an update URL that is not well formed.
[email protected]9e54cb572010-09-03 20:08:064245 // - One that contains a malformed version.
[email protected]ab22ba42011-01-14 16:36:384246 // - One that has an invalid id.
4247 // - One that has a non-dictionary value.
[email protected]0d461c52012-07-03 19:29:414248 // - One that has an integer 'external_version' instead of a string.
[email protected]9e54cb572010-09-03 20:08:064249 // The final extension is valid, and we check that it is read to make sure
4250 // failures don't stop valid records from being read.
[email protected]27b985d2009-06-25 17:53:154251 json_data =
4252 "{"
[email protected]9e54cb572010-09-03 20:08:064253 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4254 " \"external_version\": \"1.0\""
4255 " },"
4256 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4257 " \"external_crx\": \"RandomExtension.crx\""
4258 " },"
4259 " \"cccccccccccccccccccccccccccccccc\": {"
4260 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
4261 " \"external_version\": \"2.0\""
4262 " },"
4263 " \"dddddddddddddddddddddddddddddddd\": {"
4264 " \"external_crx\": \"RandomExtension2.crx\","
4265 " \"external_version\": \"2.0\","
4266 " \"external_update_url\": \"http:\\\\foo.com/update\""
4267 " },"
4268 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
4269 " },"
4270 " \"ffffffffffffffffffffffffffffffff\": {"
4271 " \"external_update_url\": \"This string is not a valid URL\""
4272 " },"
4273 " \"gggggggggggggggggggggggggggggggg\": {"
4274 " \"external_crx\": \"RandomExtension3.crx\","
4275 " \"external_version\": \"This is not a valid version!\""
4276 " },"
[email protected]ab22ba42011-01-14 16:36:384277 " \"This is not a valid id!\": {},"
4278 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
[email protected]0d461c52012-07-03 19:29:414279 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
4280 " \"external_crx\": \"RandomExtension4.crx\","
4281 " \"external_version\": 1.0"
4282 " },"
[email protected]ab22ba42011-01-14 16:36:384283 " \"pppppppppppppppppppppppppppppppp\": {"
[email protected]9e54cb572010-09-03 20:08:064284 " \"external_crx\": \"RandomValidExtension.crx\","
4285 " \"external_version\": \"1.0\""
4286 " }"
[email protected]27b985d2009-06-25 17:53:154287 "}";
[email protected]683d0702010-12-06 16:25:574288 EXPECT_EQ(1, visitor.Visit(json_data));
[email protected]f0841cd2011-01-19 15:07:244289
4290 // Check that if a base path is not provided, use of a relative
4291 // path fails.
4292 FilePath empty;
4293 MockProviderVisitor visitor_no_relative_paths(empty);
4294
4295 // Use absolute paths. Expect success.
4296 json_data =
4297 "{"
4298 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4299 " \"external_crx\": \"//RandomExtension1.crx\","
4300 " \"external_version\": \"3.0\""
4301 " },"
4302 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4303 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
4304 " \"external_version\": \"3.0\""
4305 " }"
4306 "}";
4307 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
4308
4309 // Use a relative path. Expect that it will error out.
4310 json_data =
4311 "{"
4312 " \"cccccccccccccccccccccccccccccccc\": {"
4313 " \"external_crx\": \"RandomExtension2.crx\","
4314 " \"external_version\": \"3.0\""
4315 " }"
4316 "}";
4317 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
[email protected]9d32ded072011-10-11 16:31:054318
4319 // Test supported_locales.
4320 json_data =
4321 "{"
4322 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4323 " \"external_crx\": \"RandomExtension.crx\","
4324 " \"external_version\": \"1.0\","
4325 " \"supported_locales\": [ \"en\" ]"
4326 " },"
4327 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4328 " \"external_crx\": \"RandomExtension2.crx\","
4329 " \"external_version\": \"2.0\","
4330 " \"supported_locales\": [ \"en-GB\" ]"
4331 " },"
4332 " \"cccccccccccccccccccccccccccccccc\": {"
4333 " \"external_crx\": \"RandomExtension2.crx\","
4334 " \"external_version\": \"3.0\","
4335 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
4336 " }"
4337 "}";
4338 {
4339 ScopedBrowserLocale guard("en-US");
4340 EXPECT_EQ(2, visitor.Visit(json_data));
4341 }
[email protected]f121003b2012-05-04 21:57:474342
4343 // Test is_bookmark_app.
4344 MockProviderVisitor from_bookmark_visitor(
4345 base_path, Extension::FROM_BOOKMARK);
4346 json_data =
4347 "{"
4348 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4349 " \"external_crx\": \"RandomExtension.crx\","
4350 " \"external_version\": \"1.0\","
4351 " \"is_bookmark_app\": true"
4352 " }"
4353 "}";
4354 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
[email protected]e18236b2009-06-22 21:32:104355}
[email protected]36a784c2009-06-23 06:21:084356
[email protected]c6d474f82009-12-16 21:11:064357// Test loading good extensions from the profile directory.
[email protected]eaa7dd182010-12-14 11:09:004358TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
[email protected]6884a802012-08-07 03:55:224359 // Ensure we're testing in "en" and leave global state untouched.
4360 extension_l10n_util::ScopedLocaleForTest testLocale("en");
4361
[email protected]c6d474f82009-12-16 21:11:064362 // Initialize the test dir with a good Preferences/extensions.
[email protected]e85e34c32011-04-13 18:38:354363 FilePath source_install_dir = data_dir_
[email protected]c6d474f82009-12-16 21:11:064364 .AppendASCII("l10n");
4365 FilePath pref_path = source_install_dir.AppendASCII("Preferences");
[email protected]eaa7dd182010-12-14 11:09:004366 InitializeInstalledExtensionService(pref_path, source_install_dir);
[email protected]c6d474f82009-12-16 21:11:064367
4368 service_->Init();
[email protected]c6d474f82009-12-16 21:11:064369
4370 ASSERT_EQ(3u, loaded_.size());
4371
4372 // This was equal to "sr" on load.
4373 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
4374
4375 // These are untouched by re-localization.
4376 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
4377 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
4378
4379 // This one starts with Serbian name, and gets re-localized into English.
4380 EXPECT_EQ("My name is simple.", loaded_[0]->name());
4381
4382 // These are untouched by re-localization.
4383 EXPECT_EQ("My name is simple.", loaded_[1]->name());
4384 EXPECT_EQ("no l10n", loaded_[2]->name());
4385}
4386
[email protected]6c2381d2011-10-19 02:52:534387class ExtensionsReadyRecorder : public content::NotificationObserver {
[email protected]f0488f2f2009-07-01 05:25:224388 public:
4389 ExtensionsReadyRecorder() : ready_(false) {
[email protected]432115822011-07-10 15:52:274390 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
[email protected]ad50def52011-10-19 23:17:074391 content::NotificationService::AllSources());
[email protected]f0488f2f2009-07-01 05:25:224392 }
4393
4394 void set_ready(bool value) { ready_ = value; }
4395 bool ready() { return ready_; }
4396
4397 private:
[email protected]432115822011-07-10 15:52:274398 virtual void Observe(int type,
[email protected]6c2381d2011-10-19 02:52:534399 const content::NotificationSource& source,
4400 const content::NotificationDetails& details) {
[email protected]432115822011-07-10 15:52:274401 switch (type) {
4402 case chrome::NOTIFICATION_EXTENSIONS_READY:
[email protected]f0488f2f2009-07-01 05:25:224403 ready_ = true;
4404 break;
4405 default:
4406 NOTREACHED();
4407 }
4408 }
4409
[email protected]6c2381d2011-10-19 02:52:534410 content::NotificationRegistrar registrar_;
[email protected]f0488f2f2009-07-01 05:25:224411 bool ready_;
4412};
4413
[email protected]36a784c2009-06-23 06:21:084414// Test that we get enabled/disabled correctly for all the pref/command-line
[email protected]eaa7dd182010-12-14 11:09:004415// combinations. We don't want to derive from the ExtensionServiceTest class
4416// for this test, so we use ExtensionServiceTestSimple.
[email protected]f0488f2f2009-07-01 05:25:224417//
4418// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
4419// enabled or not.
[email protected]eaa7dd182010-12-14 11:09:004420TEST(ExtensionServiceTestSimple, Enabledness) {
[email protected]ed8ee722011-04-22 06:49:444421 ExtensionErrorReporter::Init(false); // no noisy errors
[email protected]f0488f2f2009-07-01 05:25:224422 ExtensionsReadyRecorder recorder;
[email protected]aa96d3a2010-08-21 08:45:254423 scoped_ptr<TestingProfile> profile(new TestingProfile());
[email protected]36a784c2009-06-23 06:21:084424 MessageLoop loop;
[email protected]c38831a12011-10-28 12:44:494425 content::TestBrowserThread ui_thread(BrowserThread::UI, &loop);
4426 content::TestBrowserThread file_thread(BrowserThread::FILE, &loop);
[email protected]36a784c2009-06-23 06:21:084427 scoped_ptr<CommandLine> command_line;
[email protected]aa96d3a2010-08-21 08:45:254428 FilePath install_dir = profile->GetPath()
[email protected]eaa7dd182010-12-14 11:09:004429 .AppendASCII(ExtensionService::kInstallDirectoryName);
[email protected]0b300172012-09-27 16:11:524430 webkit::npapi::MockPluginList plugin_list;
[email protected]eb6c7ef2011-12-12 23:12:204431 PluginService::GetInstance()->SetPluginListForTesting(&plugin_list);
[email protected]36a784c2009-06-23 06:21:084432
[email protected]6d60703b2009-08-29 01:29:234433 // By default, we are enabled.
[email protected]947446b2010-10-21 03:36:314434 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
[email protected]bd306722012-07-11 20:43:594435 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244436 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084437 CreateExtensionService(
4438 command_line.get(),
4439 install_dir,
4440 false);
[email protected]6d60703b2009-08-29 01:29:234441 EXPECT_TRUE(service->extensions_enabled());
4442 service->Init();
4443 loop.RunAllPending();
4444 EXPECT_TRUE(recorder.ready());
4445
4446 // If either the command line or pref is set, we are disabled.
4447 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:254448 profile.reset(new TestingProfile());
[email protected]6d60703b2009-08-29 01:29:234449 command_line->AppendSwitch(switches::kDisableExtensions);
[email protected]bd306722012-07-11 20:43:594450 service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244451 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084452 CreateExtensionService(
4453 command_line.get(),
4454 install_dir,
4455 false);
[email protected]36a784c2009-06-23 06:21:084456 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:224457 service->Init();
4458 loop.RunAllPending();
4459 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:084460
[email protected]f0488f2f2009-07-01 05:25:224461 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:254462 profile.reset(new TestingProfile());
4463 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]bd306722012-07-11 20:43:594464 service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244465 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084466 CreateExtensionService(
4467 command_line.get(),
4468 install_dir,
4469 false);
[email protected]6d60703b2009-08-29 01:29:234470 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:224471 service->Init();
4472 loop.RunAllPending();
4473 EXPECT_TRUE(recorder.ready());
[email protected]36a784c2009-06-23 06:21:084474
[email protected]f0488f2f2009-07-01 05:25:224475 recorder.set_ready(false);
[email protected]aa96d3a2010-08-21 08:45:254476 profile.reset(new TestingProfile());
4477 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
[email protected]947446b2010-10-21 03:36:314478 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
[email protected]bd306722012-07-11 20:43:594479 service = static_cast<extensions::TestExtensionSystem*>(
[email protected]749d59a2012-04-05 00:23:244480 ExtensionSystem::Get(profile.get()))->
[email protected]31d8f5f22012-04-02 15:22:084481 CreateExtensionService(
4482 command_line.get(),
4483 install_dir,
4484 false);
[email protected]6d60703b2009-08-29 01:29:234485 EXPECT_FALSE(service->extensions_enabled());
[email protected]f0488f2f2009-07-01 05:25:224486 service->Init();
4487 loop.RunAllPending();
4488 EXPECT_TRUE(recorder.ready());
[email protected]7e1951a2010-09-30 10:22:204489
4490 // Explicitly delete all the resources used in this test.
4491 profile.reset();
4492 service = NULL;
[email protected]060d4972012-07-19 17:22:394493 // Execute any pending deletion tasks.
4494 loop.RunAllPending();
[email protected]36a784c2009-06-23 06:21:084495}
[email protected]24b538a2010-02-27 01:22:444496
4497// Test loading extensions that require limited and unlimited storage quotas.
[email protected]eaa7dd182010-12-14 11:09:004498TEST_F(ExtensionServiceTest, StorageQuota) {
4499 InitializeEmptyExtensionService();
[email protected]24b538a2010-02-27 01:22:444500
[email protected]e85e34c32011-04-13 18:38:354501 FilePath extensions_path = data_dir_
[email protected]24b538a2010-02-27 01:22:444502 .AppendASCII("storage_quota");
4503
[email protected]e85e34c32011-04-13 18:38:354504 FilePath limited_quota_ext =
4505 extensions_path.AppendASCII("limited_quota")
[email protected]24b538a2010-02-27 01:22:444506 .AppendASCII("1.0");
[email protected]03b612f2010-08-13 21:09:214507
4508 // The old permission name for unlimited quota was "unlimited_storage", but
4509 // we changed it to "unlimitedStorage". This tests both versions.
[email protected]e85e34c32011-04-13 18:38:354510 FilePath unlimited_quota_ext =
4511 extensions_path.AppendASCII("unlimited_quota")
[email protected]24b538a2010-02-27 01:22:444512 .AppendASCII("1.0");
[email protected]e85e34c32011-04-13 18:38:354513 FilePath unlimited_quota_ext2 =
4514 extensions_path.AppendASCII("unlimited_quota")
[email protected]03b612f2010-08-13 21:09:214515 .AppendASCII("2.0");
[email protected]d8c8f25f2011-11-02 18:18:014516 extensions::UnpackedInstaller::Create(service_)->Load(limited_quota_ext);
4517 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext);
4518 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext2);
[email protected]24b538a2010-02-27 01:22:444519 loop_.RunAllPending();
4520
[email protected]03b612f2010-08-13 21:09:214521 ASSERT_EQ(3u, loaded_.size());
[email protected]24b538a2010-02-27 01:22:444522 EXPECT_TRUE(profile_.get());
4523 EXPECT_FALSE(profile_->IsOffTheRecord());
[email protected]7c5f2ec2011-05-26 19:15:264524 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4525 loaded_[0]->url()));
4526 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4527 loaded_[1]->url()));
4528 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4529 loaded_[2]->url()));
[email protected]24b538a2010-02-27 01:22:444530}
[email protected]1952c7d2010-03-04 23:48:344531
[email protected]d8c8f25f2011-11-02 18:18:014532// Tests ComponentLoader::Add().
[email protected]eaa7dd182010-12-14 11:09:004533TEST_F(ExtensionServiceTest, ComponentExtensions) {
4534 InitializeEmptyExtensionService();
[email protected]1952c7d2010-03-04 23:48:344535
[email protected]f0b97f12010-10-11 21:44:354536 // Component extensions should work even when extensions are disabled.
4537 set_extensions_enabled(false);
4538
[email protected]e85e34c32011-04-13 18:38:354539 FilePath path = data_dir_
[email protected]1952c7d2010-03-04 23:48:344540 .AppendASCII("good")
4541 .AppendASCII("Extensions")
4542 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4543 .AppendASCII("1.0.0.0");
4544
4545 std::string manifest;
4546 ASSERT_TRUE(file_util::ReadFileToString(
4547 path.Append(Extension::kManifestFilename), &manifest));
4548
[email protected]d8c8f25f2011-11-02 18:18:014549 service_->component_loader()->Add(manifest, path);
[email protected]1952c7d2010-03-04 23:48:344550 service_->Init();
4551
4552 // Note that we do not pump messages -- the extension should be loaded
4553 // immediately.
4554
4555 EXPECT_EQ(0u, GetErrors().size());
4556 ASSERT_EQ(1u, loaded_.size());
4557 EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location());
4558 EXPECT_EQ(1u, service_->extensions()->size());
4559
[email protected]d8c8f25f2011-11-02 18:18:014560 // Component extensions shouldn't get recorded in the prefs.
[email protected]1952c7d2010-03-04 23:48:344561 ValidatePrefKeyCount(0);
4562
4563 // Reload all extensions, and make sure it comes back.
[email protected]8f512c72011-11-22 21:02:504564 std::string extension_id = (*service_->extensions()->begin())->id();
[email protected]1952c7d2010-03-04 23:48:344565 loaded_.clear();
4566 service_->ReloadExtensions();
4567 ASSERT_EQ(1u, service_->extensions()->size());
[email protected]8f512c72011-11-22 21:02:504568 EXPECT_EQ(extension_id, (*service_->extensions()->begin())->id());
[email protected]1952c7d2010-03-04 23:48:344569}
[email protected]145a317b2011-04-12 16:03:464570
[email protected]90310d92011-04-17 07:35:044571namespace {
[email protected]65f173552012-06-28 22:43:584572 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
4573 virtual syncer::SyncError ProcessSyncChanges(
[email protected]3bdba0d2011-08-23 07:17:304574 const tracked_objects::Location& from_here,
[email protected]65f173552012-06-28 22:43:584575 const syncer::SyncChangeList& change_list) OVERRIDE {
4576 return syncer::SyncError();
[email protected]3bdba0d2011-08-23 07:17:304577 }
4578 };
[email protected]90310d92011-04-17 07:35:044579}
4580
[email protected]b05fb9ff2011-04-23 00:07:564581TEST_F(ExtensionServiceTest, GetSyncData) {
4582 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504583 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]45b6fee2011-05-03 09:41:314584 const Extension* extension = service_->GetInstalledExtension(good_crx);
[email protected]b05fb9ff2011-04-23 00:07:564585 ASSERT_TRUE(extension);
[email protected]85fc9202011-05-05 00:04:594586
[email protected]cb02f612012-06-27 03:15:504587 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324588 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584589 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4590 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304591
[email protected]a4a147652012-07-03 23:41:324592 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304593 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204594 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304595 EXPECT_EQ(extension->id(), data.id());
4596 EXPECT_FALSE(data.uninstalled());
4597 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
4598 EXPECT_EQ(service_->IsIncognitoEnabled(good_crx), data.incognito_enabled());
4599 EXPECT_TRUE(data.version().Equals(*extension->version()));
4600 EXPECT_EQ(extension->update_url(), data.update_url());
4601 EXPECT_EQ(extension->name(), data.name());
[email protected]b05fb9ff2011-04-23 00:07:564602}
4603
[email protected]45b6fee2011-05-03 09:41:314604TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
4605 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504606 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]45b6fee2011-05-03 09:41:314607 TerminateExtension(good_crx);
[email protected]85fc9202011-05-05 00:04:594608 const Extension* extension = service_->GetInstalledExtension(good_crx);
4609 ASSERT_TRUE(extension);
[email protected]3bdba0d2011-08-23 07:17:304610
4611 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504612 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324613 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584614 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4615 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304616
[email protected]a4a147652012-07-03 23:41:324617 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304618 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204619 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304620 EXPECT_EQ(extension->id(), data.id());
4621 EXPECT_FALSE(data.uninstalled());
4622 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
4623 EXPECT_EQ(service_->IsIncognitoEnabled(good_crx), data.incognito_enabled());
4624 EXPECT_TRUE(data.version().Equals(*extension->version()));
4625 EXPECT_EQ(extension->update_url(), data.update_url());
4626 EXPECT_EQ(extension->name(), data.name());
[email protected]45b6fee2011-05-03 09:41:314627}
4628
[email protected]b05fb9ff2011-04-23 00:07:564629TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
4630 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504631 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]85fc9202011-05-05 00:04:594632 const Extension* extension = service_->GetInstalledExtension(good_crx);
4633 ASSERT_TRUE(extension);
[email protected]3bdba0d2011-08-23 07:17:304634
4635 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324636 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584637 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4638 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304639
[email protected]a4a147652012-07-03 23:41:324640 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304641 ASSERT_EQ(list.size(), 0U);
[email protected]b05fb9ff2011-04-23 00:07:564642}
4643
[email protected]168389f2011-12-20 17:12:484644TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
[email protected]b05fb9ff2011-04-23 00:07:564645 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504646 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]85fc9202011-05-05 00:04:594647 const Extension* extension = service_->GetInstalledExtension(good_crx);
4648 ASSERT_TRUE(extension);
[email protected]b05fb9ff2011-04-23 00:07:564649
[email protected]3bdba0d2011-08-23 07:17:304650 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504651 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324652 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584653 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4654 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304655
[email protected]b05fb9ff2011-04-23 00:07:564656 {
[email protected]a4a147652012-07-03 23:41:324657 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304658 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204659 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304660 EXPECT_TRUE(data.enabled());
4661 EXPECT_FALSE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564662 }
4663
[email protected]44d62b62012-04-11 00:06:034664 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
[email protected]b05fb9ff2011-04-23 00:07:564665 {
[email protected]a4a147652012-07-03 23:41:324666 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304667 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204668 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304669 EXPECT_FALSE(data.enabled());
4670 EXPECT_FALSE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564671 }
4672
4673 service_->SetIsIncognitoEnabled(good_crx, true);
4674 {
[email protected]a4a147652012-07-03 23:41:324675 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304676 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204677 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304678 EXPECT_FALSE(data.enabled());
4679 EXPECT_TRUE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564680 }
4681
4682 service_->EnableExtension(good_crx);
4683 {
[email protected]a4a147652012-07-03 23:41:324684 syncer::SyncDataList list = service_->GetAllSyncData(syncer::EXTENSIONS);
[email protected]3bdba0d2011-08-23 07:17:304685 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204686 extensions::ExtensionSyncData data(list[0]);
[email protected]3bdba0d2011-08-23 07:17:304687 EXPECT_TRUE(data.enabled());
4688 EXPECT_TRUE(data.incognito_enabled());
[email protected]b05fb9ff2011-04-23 00:07:564689 }
4690}
4691
[email protected]e8b0f252012-05-05 09:44:424692TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
4693 InitializeEmptyExtensionService();
4694 InstallCRXWithLocation(data_dir_.AppendASCII("good.crx"),
4695 Extension::EXTERNAL_PREF, INSTALL_NEW);
4696 const Extension* extension = service_->GetInstalledExtension(good_crx);
4697 ASSERT_TRUE(extension);
4698
4699 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504700 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324701 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584702 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4703 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]e8b0f252012-05-05 09:44:424704
4705 UninstallExtension(good_crx, false);
4706 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
4707
4708 sync_pb::EntitySpecifics specifics;
4709 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
4710 sync_pb::ExtensionSpecifics* extension_specifics =
4711 app_specifics->mutable_extension();
4712 extension_specifics->set_id(good_crx);
4713 extension_specifics->set_version("1.0");
4714 extension_specifics->set_enabled(true);
4715
[email protected]65f173552012-06-28 22:43:584716 syncer::SyncData sync_data =
4717 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264718 syncer::SyncChange sync_change(FROM_HERE,
4719 syncer::SyncChange::ACTION_UPDATE,
4720 sync_data);
[email protected]65f173552012-06-28 22:43:584721 syncer::SyncChangeList list(1);
[email protected]e8b0f252012-05-05 09:44:424722 list[0] = sync_change;
4723
4724 service_->ProcessSyncChanges(FROM_HERE, list);
4725 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
4726}
4727
[email protected]168389f2011-12-20 17:12:484728TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
4729 InitializeEmptyExtensionService();
4730 const Extension* app =
4731 PackAndInstallCRX(data_dir_.AppendASCII("app"), INSTALL_NEW);
4732 ASSERT_TRUE(app);
4733 ASSERT_TRUE(app->is_app());
4734
4735 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324736 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584737 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4738 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]168389f2011-12-20 17:12:484739
[email protected]36b643212012-09-07 12:53:004740 syncer::StringOrdinal initial_ordinal =
4741 syncer::StringOrdinal::CreateInitialOrdinal();
[email protected]168389f2011-12-20 17:12:484742 {
[email protected]a4a147652012-07-03 23:41:324743 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484744 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204745
4746 extensions::AppSyncData app_sync_data(list[0]);
[email protected]36b643212012-09-07 12:53:004747 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.app_launch_ordinal()));
4748 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
[email protected]168389f2011-12-20 17:12:484749 }
4750
[email protected]fb82dcd2012-03-21 14:15:464751 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
4752 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
[email protected]168389f2011-12-20 17:12:484753 {
[email protected]a4a147652012-07-03 23:41:324754 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484755 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204756
4757 extensions::AppSyncData app_sync_data(list[0]);
4758 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
[email protected]36b643212012-09-07 12:53:004759 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
[email protected]168389f2011-12-20 17:12:484760 }
4761
[email protected]fb82dcd2012-03-21 14:15:464762 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
[email protected]168389f2011-12-20 17:12:484763 {
[email protected]a4a147652012-07-03 23:41:324764 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484765 ASSERT_EQ(list.size(), 1U);
[email protected]5db9ada2012-04-11 13:48:204766
4767 extensions::AppSyncData app_sync_data(list[0]);
4768 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
4769 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal()));
[email protected]168389f2011-12-20 17:12:484770 }
4771}
4772
4773TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
4774 InitializeEmptyExtensionService();
4775 const size_t kAppCount = 3;
4776 const Extension* apps[kAppCount];
4777 apps[0] = PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
4778 apps[1] = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
4779 apps[2] = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
4780 for (size_t i = 0; i < kAppCount; ++i) {
4781 ASSERT_TRUE(apps[i]);
4782 ASSERT_TRUE(apps[i]->is_app());
4783 }
4784
4785 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324786 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584787 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4788 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]168389f2011-12-20 17:12:484789
4790 service_->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
4791 {
[email protected]a4a147652012-07-03 23:41:324792 syncer::SyncDataList list = service_->GetAllSyncData(syncer::APPS);
[email protected]168389f2011-12-20 17:12:484793 ASSERT_EQ(list.size(), 3U);
[email protected]5db9ada2012-04-11 13:48:204794
4795 extensions::AppSyncData data[kAppCount];
[email protected]bb05cae12012-09-06 00:37:524796 for (size_t i = 0; i < kAppCount; ++i) {
[email protected]5db9ada2012-04-11 13:48:204797 data[i] = extensions::AppSyncData(list[i]);
4798 }
[email protected]168389f2011-12-20 17:12:484799
4800 // The sync data is not always in the same order our apps were installed in,
4801 // so we do that sorting here so we can make sure the values are changed as
4802 // expected.
[email protected]36b643212012-09-07 12:53:004803 syncer::StringOrdinal app_launch_ordinals[kAppCount];
[email protected]168389f2011-12-20 17:12:484804 for (size_t i = 0; i < kAppCount; ++i) {
4805 for (size_t j = 0; j < kAppCount; ++j) {
4806 if (apps[i]->id() == data[j].id())
4807 app_launch_ordinals[i] = data[j].app_launch_ordinal();
4808 }
4809 }
4810
4811 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
4812 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
4813 }
4814}
4815
[email protected]b05fb9ff2011-04-23 00:07:564816TEST_F(ExtensionServiceTest, GetSyncDataList) {
4817 InitializeEmptyExtensionService();
[email protected]8f512c72011-11-22 21:02:504818 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4819 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
4820 InstallCRX(data_dir_.AppendASCII("theme.crx"), INSTALL_NEW);
4821 InstallCRX(data_dir_.AppendASCII("theme2.crx"), INSTALL_NEW);
[email protected]b05fb9ff2011-04-23 00:07:564822
[email protected]3bdba0d2011-08-23 07:17:304823 TestSyncProcessorStub processor;
[email protected]a4a147652012-07-03 23:41:324824 service_->MergeDataAndStartSyncing(syncer::APPS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584825 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4826 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]cb02f612012-06-27 03:15:504827 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324828 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584829 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4830 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]3bdba0d2011-08-23 07:17:304831
[email protected]44d62b62012-04-11 00:06:034832 service_->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
[email protected]45b6fee2011-05-03 09:41:314833 TerminateExtension(theme2_crx);
[email protected]b05fb9ff2011-04-23 00:07:564834
[email protected]a4a147652012-07-03 23:41:324835 EXPECT_EQ(0u, service_->GetAllSyncData(syncer::APPS).size());
4836 EXPECT_EQ(2u, service_->GetAllSyncData(syncer::EXTENSIONS).size());
[email protected]b05fb9ff2011-04-23 00:07:564837}
4838
[email protected]90310d92011-04-17 07:35:044839TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
4840 InitializeEmptyExtensionService();
[email protected]3bdba0d2011-08-23 07:17:304841 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504842 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324843 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584844 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4845 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:044846
[email protected]3bdba0d2011-08-23 07:17:304847 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:364848 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:304849 ext_specifics->set_id(good_crx);
4850 ext_specifics->set_version("1.0");
[email protected]65f173552012-06-28 22:43:584851 syncer::SyncData sync_data =
4852 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264853 syncer::SyncChange sync_change(FROM_HERE,
4854 syncer::SyncChange::ACTION_DELETE,
4855 sync_data);
[email protected]65f173552012-06-28 22:43:584856 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:304857 list[0] = sync_change;
[email protected]90310d92011-04-17 07:35:044858
4859 // Should do nothing.
[email protected]3bdba0d2011-08-23 07:17:304860 service_->ProcessSyncChanges(FROM_HERE, list);
4861 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
[email protected]90310d92011-04-17 07:35:044862
4863 // Install the extension.
4864 FilePath extension_path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:504865 InstallCRX(extension_path, INSTALL_NEW);
[email protected]90310d92011-04-17 07:35:044866 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
4867
4868 // Should uninstall the extension.
[email protected]3bdba0d2011-08-23 07:17:304869 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:044870 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
4871
4872 // Should again do nothing.
[email protected]3bdba0d2011-08-23 07:17:304873 service_->ProcessSyncChanges(FROM_HERE, list);
4874 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
[email protected]90310d92011-04-17 07:35:044875}
4876
[email protected]96e989b2011-08-30 19:35:064877TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
4878 InitializeEmptyExtensionService();
4879
4880 // Install the extension.
4881 FilePath extension_path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:504882 InstallCRX(extension_path, INSTALL_NEW);
[email protected]96e989b2011-08-30 19:35:064883 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
4884
4885 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:364886 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
[email protected]96e989b2011-08-30 19:35:064887 sync_pb::ExtensionSpecifics* extension_specifics =
4888 app_specifics->mutable_extension();
4889 extension_specifics->set_id(good_crx);
4890 extension_specifics->set_version(
4891 service_->GetInstalledExtension(good_crx)->version()->GetString());
4892
4893 {
4894 extension_specifics->set_enabled(true);
[email protected]65f173552012-06-28 22:43:584895 syncer::SyncData sync_data =
4896 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264897 syncer::SyncChange sync_change(FROM_HERE,
4898 syncer::SyncChange::ACTION_DELETE,
4899 sync_data);
[email protected]65f173552012-06-28 22:43:584900 syncer::SyncChangeList list(1);
[email protected]96e989b2011-08-30 19:35:064901 list[0] = sync_change;
4902
4903 // Should do nothing
4904 service_->ProcessSyncChanges(FROM_HERE, list);
4905 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
4906 }
4907
4908 {
4909 extension_specifics->set_enabled(false);
[email protected]65f173552012-06-28 22:43:584910 syncer::SyncData sync_data =
4911 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264912 syncer::SyncChange sync_change(FROM_HERE,
4913 syncer::SyncChange::ACTION_UPDATE,
4914 sync_data);
[email protected]65f173552012-06-28 22:43:584915 syncer::SyncChangeList list(1);
[email protected]96e989b2011-08-30 19:35:064916 list[0] = sync_change;
4917
4918 // Should again do nothing.
4919 service_->ProcessSyncChanges(FROM_HERE, list);
4920 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
4921 }
4922}
4923
[email protected]90310d92011-04-17 07:35:044924TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
4925 InitializeEmptyExtensionService();
[email protected]406b5a92011-11-08 11:58:264926 InitializeExtensionProcessManager();
[email protected]3bdba0d2011-08-23 07:17:304927 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504928 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324929 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584930 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4931 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:044932
[email protected]8f512c72011-11-22 21:02:504933 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]90310d92011-04-17 07:35:044934 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
4935 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
4936
[email protected]3bdba0d2011-08-23 07:17:304937 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:364938 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:304939 ext_specifics->set_id(good_crx);
4940 ext_specifics->set_version(
4941 service_->GetInstalledExtension(good_crx)->version()->GetString());
4942 ext_specifics->set_enabled(false);
[email protected]90310d92011-04-17 07:35:044943
[email protected]3bdba0d2011-08-23 07:17:304944 {
[email protected]65f173552012-06-28 22:43:584945 syncer::SyncData sync_data =
4946 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264947 syncer::SyncChange sync_change(FROM_HERE,
4948 syncer::SyncChange::ACTION_UPDATE,
4949 sync_data);
[email protected]65f173552012-06-28 22:43:584950 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:304951 list[0] = sync_change;
4952 service_->ProcessSyncChanges(FROM_HERE, list);
4953 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
4954 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
4955 }
[email protected]90310d92011-04-17 07:35:044956
[email protected]3bdba0d2011-08-23 07:17:304957 {
4958 ext_specifics->set_enabled(true);
4959 ext_specifics->set_incognito_enabled(true);
[email protected]65f173552012-06-28 22:43:584960 syncer::SyncData sync_data =
4961 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264962 syncer::SyncChange sync_change(FROM_HERE,
4963 syncer::SyncChange::ACTION_UPDATE,
4964 sync_data);
[email protected]65f173552012-06-28 22:43:584965 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:304966 list[0] = sync_change;
4967 service_->ProcessSyncChanges(FROM_HERE, list);
4968 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
4969 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
4970 }
[email protected]90310d92011-04-17 07:35:044971
[email protected]3bdba0d2011-08-23 07:17:304972 {
4973 ext_specifics->set_enabled(false);
4974 ext_specifics->set_incognito_enabled(true);
[email protected]65f173552012-06-28 22:43:584975 syncer::SyncData sync_data =
4976 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:264977 syncer::SyncChange sync_change(FROM_HERE,
4978 syncer::SyncChange::ACTION_UPDATE,
4979 sync_data);
[email protected]65f173552012-06-28 22:43:584980 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:304981 list[0] = sync_change;
4982 service_->ProcessSyncChanges(FROM_HERE, list);
4983 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
4984 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
4985 }
[email protected]90310d92011-04-17 07:35:044986
4987 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
4988}
4989
[email protected]fa2416f2011-05-03 08:41:204990TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
4991 InitializeExtensionServiceWithUpdater();
[email protected]3bdba0d2011-08-23 07:17:304992 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:504993 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:324994 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:584995 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
4996 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]fa2416f2011-05-03 08:41:204997
[email protected]8f512c72011-11-22 21:02:504998 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]fa2416f2011-05-03 08:41:204999 TerminateExtension(good_crx);
5000 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5001 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
5002
[email protected]3bdba0d2011-08-23 07:17:305003 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:365004 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:305005 ext_specifics->set_id(good_crx);
5006 ext_specifics->set_version(
5007 service_->GetInstalledExtension(good_crx)->version()->GetString());
5008 ext_specifics->set_enabled(false);
5009 ext_specifics->set_incognito_enabled(true);
[email protected]65f173552012-06-28 22:43:585010 syncer::SyncData sync_data =
5011 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265012 syncer::SyncChange sync_change(FROM_HERE,
5013 syncer::SyncChange::ACTION_UPDATE,
5014 sync_data);
[email protected]65f173552012-06-28 22:43:585015 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305016 list[0] = sync_change;
5017
5018 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]fa2416f2011-05-03 08:41:205019 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5020 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
5021
5022 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5023}
5024
[email protected]90310d92011-04-17 07:35:045025TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
5026 InitializeExtensionServiceWithUpdater();
[email protected]314c3e22012-02-21 03:57:425027 InitializeRequestContext();
[email protected]3bdba0d2011-08-23 07:17:305028 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:505029 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:325030 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:585031 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5032 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:045033
[email protected]8f512c72011-11-22 21:02:505034 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
[email protected]90310d92011-04-17 07:35:045035 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5036 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
5037
[email protected]3bdba0d2011-08-23 07:17:305038 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:365039 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:305040 ext_specifics->set_id(good_crx);
5041 ext_specifics->set_enabled(true);
[email protected]90310d92011-04-17 07:35:045042
[email protected]3bdba0d2011-08-23 07:17:305043 {
5044 ext_specifics->set_version(
5045 service_->GetInstalledExtension(good_crx)->version()->GetString());
[email protected]65f173552012-06-28 22:43:585046 syncer::SyncData sync_data =
5047 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265048 syncer::SyncChange sync_change(FROM_HERE,
5049 syncer::SyncChange::ACTION_UPDATE,
5050 sync_data);
[email protected]65f173552012-06-28 22:43:585051 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305052 list[0] = sync_change;
5053
5054 // Should do nothing if extension version == sync version.
5055 service_->ProcessSyncChanges(FROM_HERE, list);
5056 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5057 }
[email protected]90310d92011-04-17 07:35:045058
5059 // Should do nothing if extension version > sync version (but see
[email protected]3bdba0d2011-08-23 07:17:305060 // the TODO in ProcessExtensionSyncData).
[email protected]90310d92011-04-17 07:35:045061 {
[email protected]3bdba0d2011-08-23 07:17:305062 ext_specifics->set_version("0.0.0.0");
[email protected]65f173552012-06-28 22:43:585063 syncer::SyncData sync_data =
5064 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265065 syncer::SyncChange sync_change(FROM_HERE,
5066 syncer::SyncChange::ACTION_UPDATE,
5067 sync_data);
[email protected]65f173552012-06-28 22:43:585068 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305069 list[0] = sync_change;
5070
5071 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:045072 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5073 }
5074
5075 // Should kick off an update if extension version < sync version.
5076 {
[email protected]3bdba0d2011-08-23 07:17:305077 ext_specifics->set_version("9.9.9.9");
[email protected]65f173552012-06-28 22:43:585078 syncer::SyncData sync_data =
5079 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265080 syncer::SyncChange sync_change(FROM_HERE,
5081 syncer::SyncChange::ACTION_UPDATE,
5082 sync_data);
[email protected]65f173552012-06-28 22:43:585083 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305084 list[0] = sync_change;
5085
5086 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:045087 EXPECT_TRUE(service_->updater()->WillCheckSoon());
5088 }
5089
5090 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5091}
5092
5093TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
5094 InitializeExtensionServiceWithUpdater();
[email protected]314c3e22012-02-21 03:57:425095 InitializeRequestContext();
[email protected]3bdba0d2011-08-23 07:17:305096 TestSyncProcessorStub processor;
[email protected]cb02f612012-06-27 03:15:505097 service_->MergeDataAndStartSyncing(
[email protected]a4a147652012-07-03 23:41:325098 syncer::EXTENSIONS, syncer::SyncDataList(),
[email protected]65f173552012-06-28 22:43:585099 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5100 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
[email protected]90310d92011-04-17 07:35:045101
[email protected]3bdba0d2011-08-23 07:17:305102 sync_pb::EntitySpecifics specifics;
[email protected]4557d222012-03-04 23:33:365103 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
[email protected]3bdba0d2011-08-23 07:17:305104 ext_specifics->set_id(good_crx);
5105 ext_specifics->set_enabled(false);
5106 ext_specifics->set_incognito_enabled(true);
5107 ext_specifics->set_update_url("http://www.google.com/");
5108 ext_specifics->set_version("1.2.3.4");
[email protected]65f173552012-06-28 22:43:585109 syncer::SyncData sync_data =
5110 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
[email protected]b78170f2012-07-11 03:34:265111 syncer::SyncChange sync_change(FROM_HERE,
5112 syncer::SyncChange::ACTION_UPDATE,
5113 sync_data);
[email protected]65f173552012-06-28 22:43:585114 syncer::SyncChangeList list(1);
[email protected]3bdba0d2011-08-23 07:17:305115 list[0] = sync_change;
5116
[email protected]90310d92011-04-17 07:35:045117
[email protected]06f92562011-04-29 19:27:315118 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
[email protected]81b14cc2011-04-29 00:39:375119 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
[email protected]3bdba0d2011-08-23 07:17:305120 service_->ProcessSyncChanges(FROM_HERE, list);
[email protected]90310d92011-04-17 07:35:045121 EXPECT_TRUE(service_->updater()->WillCheckSoon());
[email protected]06f92562011-04-29 19:27:315122 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
[email protected]81b14cc2011-04-29 00:39:375123 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
[email protected]90310d92011-04-17 07:35:045124
[email protected]3f213ad2012-07-26 23:39:415125 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065126 EXPECT_TRUE((info = service_->pending_extension_manager()->
5127 GetById(good_crx)));
5128 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
5129 EXPECT_TRUE(info->is_from_sync());
5130 EXPECT_TRUE(info->install_silently());
5131 EXPECT_EQ(Extension::INTERNAL, info->install_source());
[email protected]90310d92011-04-17 07:35:045132 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
5133}
5134
[email protected]9060d8b02012-01-13 02:14:305135TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
[email protected]8a87a5332011-08-11 17:54:595136 InitializeEmptyExtensionService();
5137
5138 FilePath path = data_dir_.AppendASCII("good.crx");
[email protected]8f512c72011-11-22 21:02:505139 InstallCRX(path, INSTALL_NEW);
[email protected]8a87a5332011-08-11 17:54:595140 ValidatePrefKeyCount(1u);
5141 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5142 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
5143
[email protected]3f213ad2012-07-26 23:39:415144 extensions::PendingExtensionManager* pending =
5145 service_->pending_extension_manager();
[email protected]8a87a5332011-08-11 17:54:595146 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5147
5148 // Skip install when the location is the same.
[email protected]9060d8b02012-01-13 02:14:305149 EXPECT_FALSE(
5150 service_->OnExternalExtensionUpdateUrlFound(
5151 kGoodId, GURL(kGoodUpdateURL), Extension::INTERNAL));
[email protected]8a87a5332011-08-11 17:54:595152 EXPECT_FALSE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:305153
5154 // Install when the location has higher priority.
5155 EXPECT_TRUE(
5156 service_->OnExternalExtensionUpdateUrlFound(
5157 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_POLICY_DOWNLOAD));
[email protected]8a87a5332011-08-11 17:54:595158 EXPECT_TRUE(pending->IsIdPending(kGoodId));
[email protected]9060d8b02012-01-13 02:14:305159
5160 // Try the low priority again. Should be rejected.
5161 EXPECT_FALSE(
5162 service_->OnExternalExtensionUpdateUrlFound(
5163 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD));
5164 // The existing record should still be present in the pending extension
5165 // manager.
5166 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5167
[email protected]8a87a5332011-08-11 17:54:595168 pending->Remove(kGoodId);
[email protected]9060d8b02012-01-13 02:14:305169
5170 // Skip install when the location has the same priority as the installed
5171 // location.
5172 EXPECT_FALSE(service_->OnExternalExtensionUpdateUrlFound(
5173 kGoodId, GURL(kGoodUpdateURL), Extension::INTERNAL));
5174
[email protected]8a87a5332011-08-11 17:54:595175 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5176}
5177
[email protected]9060d8b02012-01-13 02:14:305178TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
[email protected]12126d372012-07-11 18:40:535179 Version older_version("0.1.0.0");
5180 Version newer_version("2.0.0.0");
[email protected]9060d8b02012-01-13 02:14:305181
5182 // We don't want the extension to be installed. A path that doesn't
5183 // point to a valid CRX ensures this.
5184 const FilePath kInvalidPathToCrx = FilePath();
5185
5186 const int kCreationFlags = 0;
5187 const bool kDontMarkAcknowledged = false;
5188
5189 InitializeEmptyExtensionService();
5190
5191 // The test below uses install source constants to test that
5192 // priority is enforced. It assumes a specific ranking of install
5193 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
5194 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
5195 // The following assertions verify these assumptions:
5196 ASSERT_EQ(Extension::EXTERNAL_REGISTRY,
5197 Extension::GetHigherPriorityLocation(Extension::EXTERNAL_REGISTRY,
5198 Extension::EXTERNAL_PREF));
5199 ASSERT_EQ(Extension::EXTERNAL_REGISTRY,
5200 Extension::GetHigherPriorityLocation(Extension::EXTERNAL_REGISTRY,
5201 Extension::INTERNAL));
5202 ASSERT_EQ(Extension::EXTERNAL_PREF,
5203 Extension::GetHigherPriorityLocation(Extension::EXTERNAL_PREF,
5204 Extension::INTERNAL));
5205
[email protected]3f213ad2012-07-26 23:39:415206 extensions::PendingExtensionManager* pending =
5207 service_->pending_extension_manager();
[email protected]9060d8b02012-01-13 02:14:305208 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5209
5210 // Simulate an external source adding the extension as INTERNAL.
5211 EXPECT_TRUE(
5212 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535213 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305214 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5215 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5216 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
5217
5218 // Simulate an external source adding the extension as EXTERNAL_PREF.
5219 EXPECT_TRUE(
5220 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535221 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305222 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5223 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5224 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
5225
5226 // Simulate an external source adding as EXTERNAL_PREF again.
5227 EXPECT_TRUE(
5228 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535229 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305230 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5231 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5232 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
5233
5234 // Try INTERNAL again. Should fail.
5235 EXPECT_FALSE(
5236 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535237 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305238 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5239 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5240
5241 // Now the registry adds the extension.
5242 EXPECT_TRUE(
5243 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535244 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305245 Extension::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
5246 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5247 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
5248
5249 // Registry outranks both external pref and internal, so both fail.
5250 EXPECT_FALSE(
5251 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535252 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305253 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5254 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5255
5256 EXPECT_FALSE(
5257 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535258 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305259 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5260 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5261
5262 pending->Remove(kGoodId);
5263
5264 // Install the extension.
5265 FilePath path = data_dir_.AppendASCII("good.crx");
5266 const Extension* ext = InstallCRX(path, INSTALL_NEW);
5267 ValidatePrefKeyCount(1u);
5268 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5269 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
5270
5271 // Now test the logic of OnExternalExtensionFileFound() when the extension
5272 // being added is already installed.
5273
5274 // Tests assume |older_version| is less than the installed version, and
5275 // |newer_version| is greater. Verify this:
[email protected]12126d372012-07-11 18:40:535276 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
5277 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
[email protected]9060d8b02012-01-13 02:14:305278
5279 // An external install for the same location should fail if the version is
5280 // older, or the same, and succeed if the version is newer.
5281
5282 // Older than the installed version...
5283 EXPECT_FALSE(
5284 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535285 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305286 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5287 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5288
5289 // Same version as the installed version...
5290 EXPECT_FALSE(
5291 service_->OnExternalExtensionFileFound(
5292 kGoodId, ext->version(), kInvalidPathToCrx,
5293 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5294 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5295
5296 // Newer than the installed version...
5297 EXPECT_TRUE(
5298 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535299 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305300 Extension::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
5301 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5302
5303 // An external install for a higher priority install source should succeed
5304 // if the version is greater. |older_version| is not...
5305 EXPECT_FALSE(
5306 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535307 kGoodId, &older_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305308 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5309 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5310
5311 // |newer_version| is newer.
5312 EXPECT_TRUE(
5313 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535314 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305315 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5316 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5317
5318 // An external install for an even higher priority install source should
5319 // succeed if the version is greater.
5320 EXPECT_TRUE(
5321 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535322 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305323 Extension::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
5324 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5325
5326 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
5327 // adding from external pref will now fail.
5328 EXPECT_FALSE(
5329 service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535330 kGoodId, &newer_version, kInvalidPathToCrx,
[email protected]9060d8b02012-01-13 02:14:305331 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
5332 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5333}
5334
[email protected]e3987852012-05-04 10:06:305335TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
5336 Version kVersion123("1.2.3");
5337 Version kVersion124("1.2.4");
5338 Version kVersion125("1.2.5");
5339 const FilePath kInvalidPathToCrx = FilePath();
5340 const int kCreationFlags = 0;
5341 const bool kDontMarkAcknowledged = false;
5342
5343 InitializeEmptyExtensionService();
5344
[email protected]3f213ad2012-07-26 23:39:415345 extensions::PendingExtensionManager* pending =
5346 service_->pending_extension_manager();
[email protected]e3987852012-05-04 10:06:305347 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5348
5349 // An external provider starts installing from a local crx.
5350 EXPECT_TRUE(
5351 service_->OnExternalExtensionFileFound(
5352 kGoodId, &kVersion123, kInvalidPathToCrx,
5353 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
[email protected]3f213ad2012-07-26 23:39:415354 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065355 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5356 EXPECT_TRUE(info->version().IsValid());
5357 EXPECT_TRUE(info->version().Equals(kVersion123));
[email protected]e3987852012-05-04 10:06:305358
5359 // Adding a newer version overrides the currently pending version.
5360 EXPECT_TRUE(
5361 service_->OnExternalExtensionFileFound(
5362 kGoodId, &kVersion124, kInvalidPathToCrx,
5363 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
[email protected]51a3bf8b2012-06-08 22:53:065364 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5365 EXPECT_TRUE(info->version().IsValid());
5366 EXPECT_TRUE(info->version().Equals(kVersion124));
[email protected]e3987852012-05-04 10:06:305367
5368 // Adding an older version fails.
5369 EXPECT_FALSE(
5370 service_->OnExternalExtensionFileFound(
5371 kGoodId, &kVersion123, kInvalidPathToCrx,
5372 Extension::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
[email protected]51a3bf8b2012-06-08 22:53:065373 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5374 EXPECT_TRUE(info->version().IsValid());
5375 EXPECT_TRUE(info->version().Equals(kVersion124));
[email protected]e3987852012-05-04 10:06:305376
5377 // Adding an older version fails even when coming from a higher-priority
5378 // location.
5379 EXPECT_FALSE(
5380 service_->OnExternalExtensionFileFound(
5381 kGoodId, &kVersion123, kInvalidPathToCrx,
5382 Extension::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
[email protected]51a3bf8b2012-06-08 22:53:065383 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5384 EXPECT_TRUE(info->version().IsValid());
5385 EXPECT_TRUE(info->version().Equals(kVersion124));
[email protected]e3987852012-05-04 10:06:305386
5387 // Adding the latest version from the webstore overrides a specific version.
5388 GURL kUpdateUrl("http://example.com/update");
5389 EXPECT_TRUE(
5390 service_->OnExternalExtensionUpdateUrlFound(
5391 kGoodId, kUpdateUrl, Extension::EXTERNAL_POLICY_DOWNLOAD));
[email protected]51a3bf8b2012-06-08 22:53:065392 EXPECT_TRUE((info = pending->GetById(kGoodId)));
5393 EXPECT_FALSE(info->version().IsValid());
[email protected]e3987852012-05-04 10:06:305394}
5395
[email protected]f5bf1842012-02-15 02:52:265396// This makes sure we can package and install CRX files that use whitelisted
5397// permissions.
5398TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
5399 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
5400 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
5401 switches::kWhitelistedExtensionID, test_id);
5402
5403 InitializeEmptyExtensionService();
5404 FilePath path = data_dir_
5405 .AppendASCII("permissions");
5406 FilePath pem_path = path
5407 .AppendASCII("whitelist.pem");
5408 path = path
5409 .AppendASCII("whitelist");
5410
5411 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
5412 EXPECT_EQ(0u, GetErrors().size());
5413 ASSERT_EQ(1u, service_->extensions()->size());
5414 EXPECT_EQ(test_id, extension->id());
5415}
5416
[email protected]145a317b2011-04-12 16:03:465417// Test that when multiple sources try to install an extension,
5418// we consistently choose the right one. To make tests easy to read,
5419// methods that fake requests to install crx files in several ways
5420// are provided.
5421class ExtensionSourcePriorityTest : public ExtensionServiceTest {
5422 public:
5423 void SetUp() {
[email protected]ed8ee722011-04-22 06:49:445424 ExtensionServiceTest::SetUp();
5425
[email protected]145a317b2011-04-12 16:03:465426 // All tests use a single extension. Put the id and path in member vars
5427 // that all methods can read.
5428 crx_id_ = kGoodId;
[email protected]e85e34c32011-04-13 18:38:355429 crx_path_ = data_dir_.AppendASCII("good.crx");
[email protected]145a317b2011-04-12 16:03:465430 }
5431
5432 // Fake an external source adding a URL to fetch an extension from.
[email protected]9060d8b02012-01-13 02:14:305433 bool AddPendingExternalPrefUrl() {
5434 return service_->pending_extension_manager()->AddFromExternalUpdateUrl(
[email protected]145a317b2011-04-12 16:03:465435 crx_id_, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
5436 }
5437
5438 // Fake an external file from external_extensions.json.
[email protected]9060d8b02012-01-13 02:14:305439 bool AddPendingExternalPrefFileInstall() {
[email protected]12126d372012-07-11 18:40:535440 Version version("1.0.0.0");
[email protected]145a317b2011-04-12 16:03:465441
[email protected]9060d8b02012-01-13 02:14:305442 return service_->OnExternalExtensionFileFound(
[email protected]12126d372012-07-11 18:40:535443 crx_id_, &version, crx_path_, Extension::EXTERNAL_PREF,
[email protected]47fc70c2011-12-06 07:29:515444 Extension::NO_FLAGS, false);
[email protected]145a317b2011-04-12 16:03:465445 }
5446
5447 // Fake a request from sync to install an extension.
5448 bool AddPendingSyncInstall() {
5449 return service_->pending_extension_manager()->AddFromSync(
[email protected]6cc7dbae2011-04-29 21:18:335450 crx_id_, GURL(kGoodUpdateURL), &IsExtension, kGoodInstallSilently);
[email protected]145a317b2011-04-12 16:03:465451 }
5452
[email protected]145a317b2011-04-12 16:03:465453 // Fake a policy install.
[email protected]9060d8b02012-01-13 02:14:305454 bool AddPendingPolicyInstall() {
[email protected]145a317b2011-04-12 16:03:465455 // Get path to the CRX with id |kGoodId|.
[email protected]9060d8b02012-01-13 02:14:305456 return service_->OnExternalExtensionUpdateUrlFound(
[email protected]145a317b2011-04-12 16:03:465457 crx_id_, GURL(), Extension::EXTERNAL_POLICY_DOWNLOAD);
5458 }
5459
5460 // Get the install source of a pending extension.
5461 Extension::Location GetPendingLocation() {
[email protected]3f213ad2012-07-26 23:39:415462 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065463 EXPECT_TRUE((info = service_->pending_extension_manager()->
5464 GetById(crx_id_)));
5465 return info->install_source();
[email protected]145a317b2011-04-12 16:03:465466 }
5467
5468 // Is an extension pending from a sync request?
5469 bool GetPendingIsFromSync() {
[email protected]3f213ad2012-07-26 23:39:415470 const extensions::PendingExtensionInfo* info;
[email protected]51a3bf8b2012-06-08 22:53:065471 EXPECT_TRUE((info = service_->pending_extension_manager()->
5472 GetById(crx_id_)));
5473 return info->is_from_sync();
[email protected]145a317b2011-04-12 16:03:465474 }
5475
5476 // Is the CRX id these tests use pending?
5477 bool IsCrxPending() {
5478 return service_->pending_extension_manager()->IsIdPending(crx_id_);
5479 }
5480
5481 // Is an extension installed?
5482 bool IsCrxInstalled() {
5483 return (service_->GetExtensionById(crx_id_, true) != NULL);
5484 }
5485
5486 protected:
5487 // All tests use a single extension. Making the id and path member
5488 // vars avoids pasing the same argument to every method.
5489 std::string crx_id_;
5490 FilePath crx_path_;
5491};
5492
[email protected]3634ebd2011-04-20 00:34:125493// Test that a pending request for installation of an external CRX from
5494// an update URL overrides a pending request to install the same extension
5495// from sync.
[email protected]ed8ee722011-04-22 06:49:445496TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
[email protected]145a317b2011-04-12 16:03:465497 InitializeEmptyExtensionService();
5498
5499 ASSERT_FALSE(IsCrxInstalled());
5500
5501 // Install pending extension from sync.
[email protected]f4d5e1a2011-04-28 02:08:255502 EXPECT_TRUE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465503 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
5504 EXPECT_TRUE(GetPendingIsFromSync());
5505 ASSERT_FALSE(IsCrxInstalled());
5506
5507 // Install pending as external prefs json would.
5508 AddPendingExternalPrefFileInstall();
5509 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
5510 ASSERT_FALSE(IsCrxInstalled());
5511
5512 // Another request from sync should be ignorred.
[email protected]f4d5e1a2011-04-28 02:08:255513 EXPECT_FALSE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465514 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
5515 ASSERT_FALSE(IsCrxInstalled());
5516
[email protected]8f512c72011-11-22 21:02:505517 WaitForCrxInstall(crx_path_, INSTALL_NEW);
[email protected]145a317b2011-04-12 16:03:465518 ASSERT_TRUE(IsCrxInstalled());
5519}
5520
5521// Test that an install of an external CRX from an update overrides
5522// an install of the same extension from sync.
[email protected]ed8ee722011-04-22 06:49:445523TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
[email protected]145a317b2011-04-12 16:03:465524 InitializeEmptyExtensionService();
5525 ASSERT_FALSE(IsCrxInstalled());
5526
[email protected]f4d5e1a2011-04-28 02:08:255527 EXPECT_TRUE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465528 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
5529 EXPECT_TRUE(GetPendingIsFromSync());
5530 ASSERT_FALSE(IsCrxInstalled());
5531
[email protected]9060d8b02012-01-13 02:14:305532 ASSERT_TRUE(AddPendingExternalPrefUrl());
[email protected]145a317b2011-04-12 16:03:465533 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
5534 EXPECT_FALSE(GetPendingIsFromSync());
5535 ASSERT_FALSE(IsCrxInstalled());
5536
[email protected]f4d5e1a2011-04-28 02:08:255537 EXPECT_FALSE(AddPendingSyncInstall());
[email protected]145a317b2011-04-12 16:03:465538 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
5539 EXPECT_FALSE(GetPendingIsFromSync());
5540 ASSERT_FALSE(IsCrxInstalled());
5541}
5542
[email protected]145a317b2011-04-12 16:03:465543// Test that an external install request stops sync from installing
5544// the same extension.
[email protected]ed8ee722011-04-22 06:49:445545TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
[email protected]145a317b2011-04-12 16:03:465546 InitializeEmptyExtensionService();
5547 ASSERT_FALSE(IsCrxInstalled());
5548
5549 // External prefs starts an install.
5550 AddPendingExternalPrefFileInstall();
5551
5552 // Crx installer was made, but has not yet run.
5553 ASSERT_FALSE(IsCrxInstalled());
5554
5555 // Before the CRX installer runs, Sync requests that the same extension
5556 // be installed. Should fail, because an external source is pending.
5557 ASSERT_FALSE(AddPendingSyncInstall());
5558
5559 // Wait for the external source to install.
[email protected]8f512c72011-11-22 21:02:505560 WaitForCrxInstall(crx_path_, INSTALL_NEW);
[email protected]145a317b2011-04-12 16:03:465561 ASSERT_TRUE(IsCrxInstalled());
5562
5563 // Now that the extension is installed, sync request should fail
5564 // because the extension is already installed.
5565 ASSERT_FALSE(AddPendingSyncInstall());
5566}
[email protected]07c9f2f42012-02-29 18:45:225567
[email protected]612a1cb12012-10-17 13:18:035568#if !defined(OS_CHROMEOS)
5569// Test that installing an external extension displays a GlobalError.
5570TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
5571 extensions::FeatureSwitch::ScopedOverride prompt(
5572 extensions::FeatureSwitch::prompt_for_external_extensions(), true);
5573
[email protected]07c9f2f42012-02-29 18:45:225574 InitializeEmptyExtensionService();
[email protected]07c9f2f42012-02-29 18:45:225575 MockExtensionProvider* provider =
[email protected]f121003b2012-05-04 21:57:475576 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
[email protected]07c9f2f42012-02-29 18:45:225577 AddMockExternalProvider(provider);
5578
[email protected]612a1cb12012-10-17 13:18:035579 service_->UpdateExternalExtensionAlert();
[email protected]07c9f2f42012-02-29 18:45:225580 // Should return false, meaning there aren't any extensions that the user
5581 // needs to know about.
[email protected]612a1cb12012-10-17 13:18:035582 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225583
5584 // This is a normal extension, installed normally.
5585 // This should NOT trigger an alert.
5586 set_extensions_enabled(true);
5587 FilePath path = data_dir_.AppendASCII("good.crx");
5588 InstallCRX(path, INSTALL_NEW);
5589
[email protected]612a1cb12012-10-17 13:18:035590 service_->CheckForExternalUpdates();
5591 loop_.RunAllPending();
5592 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225593
5594 // A hosted app, installed externally.
5595 // This should NOT trigger an alert.
5596 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
5597 data_dir_.AppendASCII("hosted_app.crx"));
5598
5599 service_->CheckForExternalUpdates();
5600 loop_.RunAllPending();
[email protected]612a1cb12012-10-17 13:18:035601 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225602
[email protected]612a1cb12012-10-17 13:18:035603 // Another normal extension, but installed externally.
5604 // This SHOULD trigger an alert.
5605 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
5606 data_dir_.AppendASCII("page_action.crx"));
5607
5608 service_->CheckForExternalUpdates();
5609 loop_.RunAllPending();
5610 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
[email protected]07c9f2f42012-02-29 18:45:225611}
[email protected]612a1cb12012-10-17 13:18:035612
5613// Test that external extensions are initially disabled, and that enabling
5614// them clears the prompt.
5615TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
5616 extensions::FeatureSwitch::ScopedOverride prompt(
5617 extensions::FeatureSwitch::prompt_for_external_extensions(), true);
5618
5619 InitializeEmptyExtensionService();
5620 MockExtensionProvider* provider =
5621 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
5622 AddMockExternalProvider(provider);
5623
5624 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
5625 data_dir_.AppendASCII("page_action.crx"));
5626
5627 service_->CheckForExternalUpdates();
5628 loop_.RunAllPending();
5629 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5630 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
5631
5632 const Extension* extension =
5633 service_->disabled_extensions()->GetByID(page_action);
5634 EXPECT_TRUE(extension);
5635 EXPECT_EQ(page_action, extension->id());
5636
5637 service_->EnableExtension(page_action);
5638 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
5639 EXPECT_TRUE(service_->IsExtensionEnabled(page_action));
5640}
5641
5642// Test that installing multiple external extensions works.
5643TEST_F(ExtensionServiceTest, ExternalInstallMultiple) {
5644 extensions::FeatureSwitch::ScopedOverride prompt(
5645 extensions::FeatureSwitch::prompt_for_external_extensions(), true);
5646
5647 InitializeEmptyExtensionService();
5648 MockExtensionProvider* provider =
5649 new MockExtensionProvider(service_, Extension::EXTERNAL_PREF);
5650 AddMockExternalProvider(provider);
5651
5652 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
5653 data_dir_.AppendASCII("page_action.crx"));
5654 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
5655 data_dir_.AppendASCII("good.crx"));
5656 provider->UpdateOrAddExtension(theme_crx, "2.0",
5657 data_dir_.AppendASCII("theme.crx"));
5658
5659 service_->CheckForExternalUpdates();
5660 loop_.RunAllPending();
5661 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5662 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
5663 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5664 EXPECT_FALSE(service_->IsExtensionEnabled(theme_crx));
5665
5666 service_->EnableExtension(page_action);
5667 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5668 service_->EnableExtension(theme_crx);
5669 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
5670 service_->EnableExtension(good_crx);
5671 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
5672}
5673#endif // !defined(OS_CHROMEOS)