• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/extensions/extension_service_unittest.h"
6 
7 #include <algorithm>
8 #include <set>
9 #include <vector>
10 
11 #include "base/basictypes.h"
12 #include "base/command_line.h"
13 #include "base/file_util.h"
14 #include "base/json/json_reader.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_temp_dir.h"
17 #include "base/message_loop.h"
18 #include "base/path_service.h"
19 #include "base/stl_util-inl.h"
20 #include "base/string16.h"
21 #include "base/string_number_conversions.h"
22 #include "base/string_util.h"
23 #include "base/task.h"
24 #include "base/utf_string_conversions.h"
25 #include "base/version.h"
26 #include "chrome/browser/extensions/crx_installer.h"
27 #include "chrome/browser/extensions/extension_creator.h"
28 #include "chrome/browser/extensions/extension_error_reporter.h"
29 #include "chrome/browser/extensions/extension_service.h"
30 #include "chrome/browser/extensions/extension_special_storage_policy.h"
31 #include "chrome/browser/extensions/extension_sync_data.h"
32 #include "chrome/browser/extensions/extension_updater.h"
33 #include "chrome/browser/extensions/external_extension_provider_impl.h"
34 #include "chrome/browser/extensions/external_extension_provider_interface.h"
35 #include "chrome/browser/extensions/external_pref_extension_loader.h"
36 #include "chrome/browser/extensions/pack_extension_job.cc"
37 #include "chrome/browser/extensions/pending_extension_info.h"
38 #include "chrome/browser/extensions/pending_extension_manager.h"
39 #include "chrome/browser/prefs/browser_prefs.h"
40 #include "chrome/browser/prefs/pref_service_mock_builder.h"
41 #include "chrome/browser/prefs/scoped_user_pref_update.h"
42 #include "chrome/common/chrome_paths.h"
43 #include "chrome/common/chrome_switches.h"
44 #include "chrome/common/extensions/extension.h"
45 #include "chrome/common/extensions/extension_constants.h"
46 #include "chrome/common/extensions/extension_resource.h"
47 #include "chrome/common/extensions/url_pattern.h"
48 #include "chrome/common/pref_names.h"
49 #include "chrome/common/url_constants.h"
50 #include "chrome/test/testing_profile.h"
51 #include "content/browser/appcache/chrome_appcache_service.h"
52 #include "content/browser/browser_thread.h"
53 #include "content/browser/file_system/browser_file_system_helper.h"
54 #include "content/browser/in_process_webkit/dom_storage_context.h"
55 #include "content/browser/in_process_webkit/webkit_context.h"
56 #include "content/common/json_value_serializer.h"
57 #include "content/common/notification_registrar.h"
58 #include "content/common/notification_service.h"
59 #include "content/common/notification_type.h"
60 #include "googleurl/src/gurl.h"
61 #include "net/base/cookie_monster.h"
62 #include "net/base/cookie_options.h"
63 #include "net/url_request/url_request_context.h"
64 #include "net/url_request/url_request_context_getter.h"
65 #include "testing/gtest/include/gtest/gtest.h"
66 #include "testing/platform_test.h"
67 #include "webkit/database/database_tracker.h"
68 #include "webkit/database/database_util.h"
69 
70 namespace keys = extension_manifest_keys;
71 
72 namespace {
73 
74 // Extension ids used during testing.
75 const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
76 const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
77 const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj";
78 const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk";
79 const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
80 const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
81 const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln";
82 const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad";
83 const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
84 const char* const permissions_crx = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
85 
86 struct ExtensionsOrder {
operator ()__anond96f6e660111::ExtensionsOrder87   bool operator()(const Extension* a, const Extension* b) {
88     return a->name() < b->name();
89   }
90 };
91 
GetErrors()92 static std::vector<std::string> GetErrors() {
93   const std::vector<std::string>* errors =
94       ExtensionErrorReporter::GetInstance()->GetErrors();
95   std::vector<std::string> ret_val;
96 
97   for (std::vector<std::string>::const_iterator iter = errors->begin();
98        iter != errors->end(); ++iter) {
99     if (iter->find(".svn") == std::string::npos) {
100       ret_val.push_back(*iter);
101     }
102   }
103 
104   // The tests rely on the errors being in a certain order, which can vary
105   // depending on how filesystem iteration works.
106   std::stable_sort(ret_val.begin(), ret_val.end());
107 
108   return ret_val;
109 }
110 
AddPattern(ExtensionExtent * extent,const std::string & pattern)111 static void AddPattern(ExtensionExtent* extent, const std::string& pattern) {
112   int schemes = URLPattern::SCHEME_ALL;
113   extent->AddPattern(URLPattern(schemes, pattern));
114 }
115 
AssertEqualExtents(ExtensionExtent * extent1,ExtensionExtent * extent2)116 static void AssertEqualExtents(ExtensionExtent* extent1,
117                                ExtensionExtent* extent2) {
118   std::vector<URLPattern> patterns1 = extent1->patterns();
119   std::vector<URLPattern> patterns2 = extent2->patterns();
120   std::set<std::string> strings1;
121   EXPECT_EQ(patterns1.size(), patterns2.size());
122 
123   for (size_t i = 0; i < patterns1.size(); ++i)
124     strings1.insert(patterns1.at(i).GetAsString());
125 
126   std::set<std::string> strings2;
127   for (size_t i = 0; i < patterns2.size(); ++i)
128     strings2.insert(patterns2.at(i).GetAsString());
129 
130   EXPECT_EQ(strings1, strings2);
131 }
132 
133 }  // namespace
134 
135 class MockExtensionProvider : public ExternalExtensionProviderInterface {
136  public:
MockExtensionProvider(VisitorInterface * visitor,Extension::Location location)137   explicit MockExtensionProvider(
138       VisitorInterface* visitor,
139       Extension::Location location)
140   : location_(location), visitor_(visitor), visit_count_(0) {
141   }
~MockExtensionProvider()142   virtual ~MockExtensionProvider() {}
143 
UpdateOrAddExtension(const std::string & id,const std::string & version,const FilePath & path)144   void UpdateOrAddExtension(const std::string& id,
145                             const std::string& version,
146                             const FilePath& path) {
147     extension_map_[id] = std::make_pair(version, path);
148   }
149 
RemoveExtension(const std::string & id)150   void RemoveExtension(const std::string& id) {
151     extension_map_.erase(id);
152   }
153 
154   // ExternalExtensionProvider implementation:
VisitRegisteredExtension() const155   virtual void VisitRegisteredExtension() const {
156     visit_count_++;
157     for (DataMap::const_iterator i = extension_map_.begin();
158          i != extension_map_.end(); ++i) {
159       scoped_ptr<Version> version;
160       version.reset(Version::GetVersionFromString(i->second.first));
161 
162       visitor_->OnExternalExtensionFileFound(
163           i->first, version.get(), i->second.second, location_);
164     }
165     visitor_->OnExternalProviderReady();
166   }
167 
HasExtension(const std::string & id) const168   virtual bool HasExtension(const std::string& id) const {
169     return extension_map_.find(id) != extension_map_.end();
170   }
171 
GetExtensionDetails(const std::string & id,Extension::Location * location,scoped_ptr<Version> * version) const172   virtual bool GetExtensionDetails(const std::string& id,
173                                    Extension::Location* location,
174                                    scoped_ptr<Version>* version) const {
175     DataMap::const_iterator it = extension_map_.find(id);
176     if (it == extension_map_.end())
177       return false;
178 
179     if (version)
180       version->reset(Version::GetVersionFromString(it->second.first));
181 
182     if (location)
183       *location = location_;
184 
185     return true;
186   }
187 
IsReady()188   virtual bool IsReady() {
189     return true;
190   }
191 
ServiceShutdown()192   virtual void ServiceShutdown() {
193   }
194 
visit_count() const195   int visit_count() const { return visit_count_; }
set_visit_count(int visit_count)196   void set_visit_count(int visit_count) {
197     visit_count_ = visit_count;
198   }
199 
200  private:
201   typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap;
202   DataMap extension_map_;
203   Extension::Location location_;
204   VisitorInterface* visitor_;
205 
206   // visit_count_ tracks the number of calls to VisitRegisteredExtension().
207   // Mutable because it must be incremented on each call to
208   // VisitRegisteredExtension(), which must be a const method to inherit
209   // from the class being mocked.
210   mutable int visit_count_;
211 
212   DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
213 };
214 
215 class MockProviderVisitor
216     : public ExternalExtensionProviderInterface::VisitorInterface {
217  public:
218 
219   // The provider will return |fake_base_path| from
220   // GetBaseCrxFilePath().  User can test the behavior with
221   // and without an empty path using this parameter.
MockProviderVisitor(FilePath fake_base_path)222   explicit MockProviderVisitor(FilePath fake_base_path)
223       : ids_found_(0),
224         fake_base_path_(fake_base_path) {
225   }
226 
Visit(const std::string & json_data)227   int Visit(const std::string& json_data) {
228     // Give the test json file to the provider for parsing.
229     provider_.reset(new ExternalExtensionProviderImpl(
230         this,
231         new ExternalTestingExtensionLoader(json_data, fake_base_path_),
232         Extension::EXTERNAL_PREF,
233         Extension::EXTERNAL_PREF_DOWNLOAD));
234 
235     // We also parse the file into a dictionary to compare what we get back
236     // from the provider.
237     JSONStringValueSerializer serializer(json_data);
238     Value* json_value = serializer.Deserialize(NULL, NULL);
239 
240     if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
241       NOTREACHED() << "Unable to deserialize json data";
242       return -1;
243     } else {
244       DictionaryValue* external_extensions =
245           static_cast<DictionaryValue*>(json_value);
246       prefs_.reset(external_extensions);
247     }
248 
249     // Reset our counter.
250     ids_found_ = 0;
251     // Ask the provider to look up all extensions and return them.
252     provider_->VisitRegisteredExtension();
253 
254     return ids_found_;
255   }
256 
OnExternalExtensionFileFound(const std::string & id,const Version * version,const FilePath & path,Extension::Location unused)257   virtual void OnExternalExtensionFileFound(const std::string& id,
258                                             const Version* version,
259                                             const FilePath& path,
260                                             Extension::Location unused) {
261     ++ids_found_;
262     DictionaryValue* pref;
263     // This tests is to make sure that the provider only notifies us of the
264     // values we gave it. So if the id we doesn't exist in our internal
265     // dictionary then something is wrong.
266     EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
267        << "Got back ID (" << id.c_str() << ") we weren't expecting";
268 
269     EXPECT_TRUE(path.IsAbsolute());
270     if (!fake_base_path_.empty())
271       EXPECT_TRUE(fake_base_path_.IsParent(path));
272 
273     if (pref) {
274       EXPECT_TRUE(provider_->HasExtension(id));
275 
276       // Ask provider if the extension we got back is registered.
277       Extension::Location location = Extension::INVALID;
278       scoped_ptr<Version> v1;
279       FilePath crx_path;
280 
281       EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
282       EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
283 
284       scoped_ptr<Version> v2;
285       EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
286       EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
287       EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
288       EXPECT_EQ(Extension::EXTERNAL_PREF, location);
289 
290       // Remove it so we won't count it ever again.
291       prefs_->Remove(id, NULL);
292     }
293   }
294 
OnExternalExtensionUpdateUrlFound(const std::string & id,const GURL & update_url,Extension::Location location)295   virtual void OnExternalExtensionUpdateUrlFound(
296       const std::string& id, const GURL& update_url,
297       Extension::Location location) {
298     ++ids_found_;
299     DictionaryValue* pref;
300     // This tests is to make sure that the provider only notifies us of the
301     // values we gave it. So if the id we doesn't exist in our internal
302     // dictionary then something is wrong.
303     EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
304        << L"Got back ID (" << id.c_str() << ") we weren't expecting";
305     EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location);
306 
307     if (pref) {
308       EXPECT_TRUE(provider_->HasExtension(id));
309 
310       // External extensions with update URLs do not have versions.
311       scoped_ptr<Version> v1;
312       Extension::Location location1 = Extension::INVALID;
313       EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
314       EXPECT_FALSE(v1.get());
315       EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location1);
316 
317       // Remove it so we won't count it again.
318       prefs_->Remove(id, NULL);
319     }
320   }
321 
OnExternalProviderReady()322   virtual void OnExternalProviderReady() {
323     EXPECT_TRUE(provider_->IsReady());
324   }
325 
326  private:
327   int ids_found_;
328   FilePath fake_base_path_;
329   scoped_ptr<ExternalExtensionProviderImpl> provider_;
330   scoped_ptr<DictionaryValue> prefs_;
331 
332   DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
333 };
334 
335 class ExtensionTestingProfile : public TestingProfile {
336  public:
ExtensionTestingProfile()337   ExtensionTestingProfile() : service_(NULL) {
338   }
339 
set_extensions_service(ExtensionService * service)340   void set_extensions_service(ExtensionService* service) {
341     service_ = service;
342   }
GetExtensionService()343   virtual ExtensionService* GetExtensionService() { return service_; }
344 
GetAppCacheService()345   virtual ChromeAppCacheService* GetAppCacheService() {
346     if (!appcache_service_) {
347       appcache_service_ = new ChromeAppCacheService;
348       BrowserThread::PostTask(
349           BrowserThread::IO, FROM_HERE,
350           NewRunnableMethod(
351               appcache_service_.get(),
352               &ChromeAppCacheService::InitializeOnIOThread,
353               IsOffTheRecord()
354                   ? FilePath() : GetPath().Append(chrome::kAppCacheDirname),
355               make_scoped_refptr(GetHostContentSettingsMap()),
356               make_scoped_refptr(GetExtensionSpecialStoragePolicy()),
357               false));
358     }
359     return appcache_service_;
360   }
361 
GetFileSystemContext()362   virtual fileapi::FileSystemContext* GetFileSystemContext() {
363     if (!file_system_context_)
364       file_system_context_ = CreateFileSystemContext(
365           GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
366     return file_system_context_;
367   }
368 
369  private:
370   ExtensionService* service_;
371   scoped_refptr<ChromeAppCacheService> appcache_service_;
372   scoped_refptr<fileapi::FileSystemContext> file_system_context_;
373 };
374 
375 // Our message loop may be used in tests which require it to be an IO loop.
ExtensionServiceTestBase()376 ExtensionServiceTestBase::ExtensionServiceTestBase()
377     : total_successes_(0),
378       loop_(MessageLoop::TYPE_IO),
379       ui_thread_(BrowserThread::UI, &loop_),
380       db_thread_(BrowserThread::DB, &loop_),
381       webkit_thread_(BrowserThread::WEBKIT, &loop_),
382       file_thread_(BrowserThread::FILE, &loop_),
383       io_thread_(BrowserThread::IO, &loop_) {
384   FilePath test_data_dir;
385   if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
386     ADD_FAILURE();
387     return;
388   }
389   data_dir_ = test_data_dir.AppendASCII("extensions");
390 }
391 
~ExtensionServiceTestBase()392 ExtensionServiceTestBase::~ExtensionServiceTestBase() {
393   // Drop our reference to ExtensionService and TestingProfile, so that they
394   // can be destroyed while BrowserThreads and MessageLoop are still around
395   // (they are used in the destruction process).
396   service_ = NULL;
397   profile_.reset(NULL);
398   MessageLoop::current()->RunAllPending();
399 }
400 
InitializeExtensionService(const FilePath & pref_file,const FilePath & extensions_install_dir,bool autoupdate_enabled)401 void ExtensionServiceTestBase::InitializeExtensionService(
402     const FilePath& pref_file, const FilePath& extensions_install_dir,
403     bool autoupdate_enabled) {
404   ExtensionTestingProfile* profile = new ExtensionTestingProfile();
405   // Create a PrefService that only contains user defined preference values.
406   PrefService* prefs =
407       PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create();
408   Profile::RegisterUserPrefs(prefs);
409   browser::RegisterUserPrefs(prefs);
410   profile->SetPrefService(prefs);
411 
412   profile_.reset(profile);
413 
414   service_ = profile->CreateExtensionService(
415       CommandLine::ForCurrentProcess(),
416       extensions_install_dir,
417       autoupdate_enabled);
418   service_->set_extensions_enabled(true);
419   service_->set_show_extensions_prompts(false);
420   profile->set_extensions_service(service_.get());
421 
422   // When we start up, we want to make sure there is no external provider,
423   // since the ExtensionService on Windows will use the Registry as a default
424   // provider and if there is something already registered there then it will
425   // interfere with the tests. Those tests that need an external provider
426   // will register one specifically.
427   service_->ClearProvidersForTesting();
428 
429   total_successes_ = 0;
430 }
431 
InitializeInstalledExtensionService(const FilePath & prefs_file,const FilePath & source_install_dir)432 void ExtensionServiceTestBase::InitializeInstalledExtensionService(
433     const FilePath& prefs_file, const FilePath& source_install_dir) {
434   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
435   FilePath path_ = temp_dir_.path();
436   path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
437   file_util::Delete(path_, true);
438   file_util::CreateDirectory(path_);
439   FilePath temp_prefs = path_.Append(FILE_PATH_LITERAL("Preferences"));
440   file_util::CopyFile(prefs_file, temp_prefs);
441 
442   extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
443   file_util::Delete(extensions_install_dir_, true);
444   file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
445 
446   InitializeExtensionService(temp_prefs, extensions_install_dir_, false);
447 }
448 
InitializeEmptyExtensionService()449 void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
450   InitializeExtensionServiceHelper(false);
451 }
452 
InitializeExtensionServiceWithUpdater()453 void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
454   InitializeExtensionServiceHelper(true);
455   service_->updater()->Start();
456 }
457 
InitializeExtensionServiceHelper(bool autoupdate_enabled)458 void ExtensionServiceTestBase::InitializeExtensionServiceHelper(
459     bool autoupdate_enabled) {
460   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
461   FilePath path_ = temp_dir_.path();
462   path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
463   file_util::Delete(path_, true);
464   file_util::CreateDirectory(path_);
465   FilePath prefs_filename = path_
466       .Append(FILE_PATH_LITERAL("TestPreferences"));
467   extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
468   file_util::Delete(extensions_install_dir_, true);
469   file_util::CreateDirectory(extensions_install_dir_);
470 
471   InitializeExtensionService(prefs_filename, extensions_install_dir_,
472                              autoupdate_enabled);
473 }
474 
475 // static
SetUpTestCase()476 void ExtensionServiceTestBase::SetUpTestCase() {
477   ExtensionErrorReporter::Init(false);  // no noisy errors
478 }
479 
SetUp()480 void ExtensionServiceTestBase::SetUp() {
481   ExtensionErrorReporter::GetInstance()->ClearErrors();
482 }
483 
484 class ExtensionServiceTest
485   : public ExtensionServiceTestBase, public NotificationObserver {
486  public:
ExtensionServiceTest()487   ExtensionServiceTest() : installed_(NULL) {
488     registrar_.Add(this, NotificationType::EXTENSION_LOADED,
489                    NotificationService::AllSources());
490     registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
491                    NotificationService::AllSources());
492     registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
493                    NotificationService::AllSources());
494   }
495 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)496   virtual void Observe(NotificationType type,
497                        const NotificationSource& source,
498                        const NotificationDetails& details) {
499     switch (type.value) {
500       case NotificationType::EXTENSION_LOADED: {
501         const Extension* extension = Details<const Extension>(details).ptr();
502         loaded_.push_back(make_scoped_refptr(extension));
503         // The tests rely on the errors being in a certain order, which can vary
504         // depending on how filesystem iteration works.
505         std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
506         break;
507       }
508 
509       case NotificationType::EXTENSION_UNLOADED: {
510         const Extension* e =
511             Details<UnloadedExtensionInfo>(details)->extension;
512         unloaded_id_ = e->id();
513         ExtensionList::iterator i =
514             std::find(loaded_.begin(), loaded_.end(), e);
515         // TODO(erikkay) fix so this can be an assert.  Right now the tests
516         // are manually calling clear() on loaded_, so this isn't doable.
517         if (i == loaded_.end())
518           return;
519         loaded_.erase(i);
520         break;
521       }
522       case NotificationType::EXTENSION_INSTALLED:
523         installed_ = Details<const Extension>(details).ptr();
524         break;
525 
526       default:
527         DCHECK(false);
528     }
529   }
530 
AddMockExternalProvider(ExternalExtensionProviderInterface * provider)531   void AddMockExternalProvider(ExternalExtensionProviderInterface* provider) {
532     service_->AddProviderForTesting(provider);
533   }
534 
535  protected:
536   void TestExternalProvider(MockExtensionProvider* provider,
537                             Extension::Location location);
538 
PackAndInstallCrx(const FilePath & dir_path,const FilePath & pem_path,bool should_succeed)539   void PackAndInstallCrx(const FilePath& dir_path,
540                          const FilePath& pem_path,
541                          bool should_succeed) {
542     FilePath crx_path;
543     ScopedTempDir temp_dir;
544     ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
545     crx_path = temp_dir_.path().AppendASCII("temp.crx");
546 
547     // Use the existing pem key, if provided.
548     FilePath pem_output_path;
549     if (pem_path.value().empty()) {
550       pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
551       ASSERT_TRUE(file_util::Delete(pem_output_path, false));
552     } else {
553       ASSERT_TRUE(file_util::PathExists(pem_path));
554     }
555 
556     ASSERT_TRUE(file_util::Delete(crx_path, false));
557 
558     scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
559     ASSERT_TRUE(creator->Run(dir_path,
560                              crx_path,
561                              pem_path,
562                              pem_output_path));
563 
564     ASSERT_TRUE(file_util::PathExists(crx_path));
565 
566     InstallCrx(crx_path, should_succeed);
567   }
568 
PackAndInstallCrx(const FilePath & dir_path,bool should_succeed)569   void PackAndInstallCrx(const FilePath& dir_path,
570                          bool should_succeed) {
571     PackAndInstallCrx(dir_path, FilePath(), should_succeed);
572   }
573 
574   // Create a CrxInstaller and start installation. To allow the install
575   // to happen, use loop_.RunAllPending();. Most tests will not use this
576   // method directly.  Instead, use InstallCrx(), which waits for
577   // the crx to be installed and does extra error checking.
StartCrxInstall(const FilePath & crx_path)578   void StartCrxInstall(const FilePath& crx_path) {
579     ASSERT_TRUE(file_util::PathExists(crx_path))
580         << "Path does not exist: "<< crx_path.value().c_str();
581     scoped_refptr<CrxInstaller> installer(
582         new CrxInstaller(service_,  // frontend
583                          NULL));  // no client (silent install)
584     installer->InstallCrx(crx_path);
585   }
586 
InstallCrx(const FilePath & path,bool should_succeed)587   void InstallCrx(const FilePath& path,
588                         bool should_succeed) {
589     StartCrxInstall(path);
590     WaitForCrxInstall(path, should_succeed);
591   }
592 
InstallCrxWithLocation(const FilePath & crx_path,Extension::Location install_location,bool should_succeed)593   void InstallCrxWithLocation(const FilePath& crx_path,
594                               Extension::Location install_location,
595                               bool should_succeed) {
596     ASSERT_TRUE(file_util::PathExists(crx_path))
597         << "Path does not exist: "<< crx_path.value().c_str();
598     scoped_refptr<CrxInstaller> installer(
599         new CrxInstaller(service_,  // frontend
600                          NULL));  // no client (silent install)
601 
602     installer->set_install_source(install_location);
603     installer->InstallCrx(crx_path);
604 
605     WaitForCrxInstall(crx_path, should_succeed);
606   }
607 
608   // Wait for a CrxInstaller to finish. Used by InstallCrx.
WaitForCrxInstall(const FilePath & path,bool should_succeed)609   void WaitForCrxInstall(const FilePath& path,
610                          bool should_succeed) {
611     loop_.RunAllPending();
612     std::vector<std::string> errors = GetErrors();
613     if (should_succeed) {
614       ++total_successes_;
615 
616       EXPECT_TRUE(installed_) << path.value();
617 
618       ASSERT_EQ(1u, loaded_.size()) << path.value();
619       EXPECT_EQ(0u, errors.size()) << path.value();
620       EXPECT_EQ(total_successes_, service_->extensions()->size()) <<
621           path.value();
622       EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
623           path.value();
624       for (std::vector<std::string>::iterator err = errors.begin();
625         err != errors.end(); ++err) {
626         LOG(ERROR) << *err;
627       }
628     } else {
629       EXPECT_FALSE(installed_) << path.value();
630       EXPECT_EQ(0u, loaded_.size()) << path.value();
631       EXPECT_EQ(1u, errors.size()) << path.value();
632     }
633 
634     installed_ = NULL;
635     loaded_.clear();
636     ExtensionErrorReporter::GetInstance()->ClearErrors();
637   }
638 
639   enum UpdateState {
640     FAILED_SILENTLY,
641     FAILED,
642     UPDATED,
643     INSTALLED,
644     ENABLED
645   };
646 
UpdateExtension(const std::string & id,const FilePath & in_path,UpdateState expected_state)647   void UpdateExtension(const std::string& id, const FilePath& in_path,
648                        UpdateState expected_state) {
649     ASSERT_TRUE(file_util::PathExists(in_path));
650 
651     // We need to copy this to a temporary location because Update() will delete
652     // it.
653     FilePath path = temp_dir_.path();
654     path = path.Append(in_path.BaseName());
655     ASSERT_TRUE(file_util::CopyFile(in_path, path));
656 
657     int previous_enabled_extension_count =
658         service_->extensions()->size();
659     int previous_installed_extension_count =
660         previous_enabled_extension_count +
661         service_->disabled_extensions()->size();
662 
663     service_->UpdateExtension(id, path, GURL());
664     loop_.RunAllPending();
665 
666     std::vector<std::string> errors = GetErrors();
667     int error_count = errors.size();
668     int enabled_extension_count =
669         service_->extensions()->size();
670     int installed_extension_count =
671         enabled_extension_count + service_->disabled_extensions()->size();
672 
673     int expected_error_count = (expected_state == FAILED) ? 1 : 0;
674     EXPECT_EQ(expected_error_count, error_count) << path.value();
675 
676     if (expected_state <= FAILED) {
677       EXPECT_EQ(previous_enabled_extension_count,
678                 enabled_extension_count);
679       EXPECT_EQ(previous_installed_extension_count,
680                 installed_extension_count);
681     } else {
682       int expected_installed_extension_count =
683           (expected_state >= INSTALLED) ? 1 : 0;
684       int expected_enabled_extension_count =
685           (expected_state >= ENABLED) ? 1 : 0;
686       EXPECT_EQ(expected_installed_extension_count,
687                 installed_extension_count);
688       EXPECT_EQ(expected_enabled_extension_count,
689                 enabled_extension_count);
690     }
691 
692     // Update() should delete the temporary input file.
693     EXPECT_FALSE(file_util::PathExists(path));
694   }
695 
ValidatePrefKeyCount(size_t count)696   void ValidatePrefKeyCount(size_t count) {
697     const DictionaryValue* dict =
698         profile_->GetPrefs()->GetDictionary("extensions.settings");
699     ASSERT_TRUE(dict != NULL);
700     EXPECT_EQ(count, dict->size());
701   }
702 
ValidateBooleanPref(const std::string & extension_id,const std::string & pref_path,bool expected_val)703   void ValidateBooleanPref(const std::string& extension_id,
704                            const std::string& pref_path,
705                            bool expected_val) {
706     std::string msg = " while checking: ";
707     msg += extension_id;
708     msg += " ";
709     msg += pref_path;
710     msg += " == ";
711     msg += expected_val ? "true" : "false";
712 
713     PrefService* prefs = profile_->GetPrefs();
714     const DictionaryValue* dict =
715         prefs->GetDictionary("extensions.settings");
716     ASSERT_TRUE(dict != NULL) << msg;
717     DictionaryValue* pref = NULL;
718     ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
719     EXPECT_TRUE(pref != NULL) << msg;
720     bool val;
721     ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg;
722     EXPECT_EQ(expected_val, val) << msg;
723   }
724 
IsPrefExist(const std::string & extension_id,const std::string & pref_path)725   bool IsPrefExist(const std::string& extension_id,
726                    const std::string& pref_path) {
727     const DictionaryValue* dict =
728         profile_->GetPrefs()->GetDictionary("extensions.settings");
729     if (dict == NULL) return false;
730     DictionaryValue* pref = NULL;
731     if (!dict->GetDictionary(extension_id, &pref)) {
732       return false;
733     }
734     if (pref == NULL) {
735       return false;
736     }
737     bool val;
738     if (!pref->GetBoolean(pref_path, &val)) {
739       return false;
740     }
741     return true;
742   }
743 
ValidateIntegerPref(const std::string & extension_id,const std::string & pref_path,int expected_val)744   void ValidateIntegerPref(const std::string& extension_id,
745                            const std::string& pref_path,
746                            int expected_val) {
747     std::string msg = " while checking: ";
748     msg += extension_id;
749     msg += " ";
750     msg += pref_path;
751     msg += " == ";
752     msg += base::IntToString(expected_val);
753 
754     PrefService* prefs = profile_->GetPrefs();
755     const DictionaryValue* dict =
756         prefs->GetDictionary("extensions.settings");
757     ASSERT_TRUE(dict != NULL) << msg;
758     DictionaryValue* pref = NULL;
759     ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
760     EXPECT_TRUE(pref != NULL) << msg;
761     int val;
762     ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
763     EXPECT_EQ(expected_val, val) << msg;
764   }
765 
ValidateStringPref(const std::string & extension_id,const std::string & pref_path,const std::string & expected_val)766   void ValidateStringPref(const std::string& extension_id,
767                           const std::string& pref_path,
768                           const std::string& expected_val) {
769     std::string msg = " while checking: ";
770     msg += extension_id;
771     msg += ".manifest.";
772     msg += pref_path;
773     msg += " == ";
774     msg += expected_val;
775 
776     const DictionaryValue* dict =
777         profile_->GetPrefs()->GetDictionary("extensions.settings");
778     ASSERT_TRUE(dict != NULL) << msg;
779     DictionaryValue* pref = NULL;
780     std::string manifest_path = extension_id + ".manifest";
781     ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
782     EXPECT_TRUE(pref != NULL) << msg;
783     std::string val;
784     ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
785     EXPECT_EQ(expected_val, val) << msg;
786   }
787 
SetPref(const std::string & extension_id,const std::string & pref_path,Value * value,const std::string & msg)788   void SetPref(const std::string& extension_id,
789                const std::string& pref_path,
790                Value* value,
791                const std::string& msg) {
792     DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
793     DictionaryValue* dict = update.Get();
794     ASSERT_TRUE(dict != NULL) << msg;
795     DictionaryValue* pref = NULL;
796     ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
797     EXPECT_TRUE(pref != NULL) << msg;
798     pref->Set(pref_path, value);
799   }
800 
SetPrefInteg(const std::string & extension_id,const std::string & pref_path,int value)801   void SetPrefInteg(const std::string& extension_id,
802                     const std::string& pref_path,
803                     int value) {
804     std::string msg = " while setting: ";
805     msg += extension_id;
806     msg += " ";
807     msg += pref_path;
808     msg += " = ";
809     msg += base::IntToString(value);
810 
811     SetPref(extension_id, pref_path, Value::CreateIntegerValue(value), msg);
812   }
813 
SetPrefBool(const std::string & extension_id,const std::string & pref_path,bool value)814   void SetPrefBool(const std::string& extension_id,
815                    const std::string& pref_path,
816                    bool value) {
817     std::string msg = " while setting: ";
818     msg += extension_id + " " + pref_path;
819     msg += " = ";
820     msg += (value ? "true" : "false");
821 
822     SetPref(extension_id, pref_path, Value::CreateBooleanValue(value), msg);
823   }
824 
ClearPref(const std::string & extension_id,const std::string & pref_path)825   void ClearPref(const std::string& extension_id,
826                  const std::string& pref_path) {
827     std::string msg = " while clearing: ";
828     msg += extension_id + " " + pref_path;
829 
830     DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
831     DictionaryValue* dict = update.Get();
832     ASSERT_TRUE(dict != NULL) << msg;
833     DictionaryValue* pref = NULL;
834     ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
835     EXPECT_TRUE(pref != NULL) << msg;
836     pref->Remove(pref_path, NULL);
837   }
838 
SetPrefStringSet(const std::string & extension_id,const std::string & pref_path,const std::set<std::string> & value)839   void SetPrefStringSet(const std::string& extension_id,
840                         const std::string& pref_path,
841                         const std::set<std::string>& value) {
842     std::string msg = " while setting: ";
843     msg += extension_id + " " + pref_path;
844 
845     ListValue* list_value = new ListValue();
846     for (std::set<std::string>::const_iterator iter = value.begin();
847          iter != value.end(); ++iter)
848       list_value->Append(Value::CreateStringValue(*iter));
849 
850     SetPref(extension_id, pref_path, list_value, msg);
851   }
852 
853  protected:
854   ExtensionList loaded_;
855   std::string unloaded_id_;
856   const Extension* installed_;
857 
858  private:
859   NotificationRegistrar registrar_;
860 };
861 
NormalizeSeparators(const FilePath & path)862 FilePath NormalizeSeparators(const FilePath& path) {
863 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
864   return path.NormalizeWindowsPathSeparators();
865 #else
866   return path;
867 #endif  // FILE_PATH_USES_WIN_SEPARATORS
868 }
869 
870 // Receives notifications from a PackExtensionJob, indicating either that
871 // packing succeeded or that there was some error.
872 class PackExtensionTestClient : public PackExtensionJob::Client {
873  public:
874   PackExtensionTestClient(const FilePath& expected_crx_path,
875                           const FilePath& expected_private_key_path);
876   virtual void OnPackSuccess(const FilePath& crx_path,
877                              const FilePath& private_key_path);
878   virtual void OnPackFailure(const std::string& error_message);
879 
880  private:
881   const FilePath expected_crx_path_;
882   const FilePath expected_private_key_path_;
883   DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
884 };
885 
PackExtensionTestClient(const FilePath & expected_crx_path,const FilePath & expected_private_key_path)886 PackExtensionTestClient::PackExtensionTestClient(
887     const FilePath& expected_crx_path,
888     const FilePath& expected_private_key_path)
889     : expected_crx_path_(expected_crx_path),
890       expected_private_key_path_(expected_private_key_path) {}
891 
892 // If packing succeeded, we make sure that the package names match our
893 // expectations.
OnPackSuccess(const FilePath & crx_path,const FilePath & private_key_path)894 void PackExtensionTestClient::OnPackSuccess(const FilePath& crx_path,
895                                             const FilePath& private_key_path) {
896   // We got the notification and processed it; we don't expect any further tasks
897   // to be posted to the current thread, so we should stop blocking and continue
898   // on with the rest of the test.
899   // This call to |Quit()| matches the call to |Run()| in the
900   // |PackPunctuatedExtension| test.
901   MessageLoop::current()->Quit();
902   EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
903   EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
904   ASSERT_TRUE(file_util::PathExists(private_key_path));
905 }
906 
907 // The tests are designed so that we never expect to see a packing error.
OnPackFailure(const std::string & error_message)908 void PackExtensionTestClient::OnPackFailure(const std::string& error_message) {
909   FAIL() << "Packing should not fail.";
910 }
911 
912 // Test loading good extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAllExtensionsFromDirectorySuccess)913 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
914   // Initialize the test dir with a good Preferences/extensions.
915   FilePath source_install_dir = data_dir_
916       .AppendASCII("good")
917       .AppendASCII("Extensions");
918   FilePath pref_path = source_install_dir
919       .DirName()
920       .AppendASCII("Preferences");
921   InitializeInstalledExtensionService(pref_path, source_install_dir);
922 
923   service_->Init();
924 
925   uint32 expected_num_extensions = 3u;
926   ASSERT_EQ(expected_num_extensions, loaded_.size());
927 
928   EXPECT_EQ(std::string(good0), loaded_[0]->id());
929   EXPECT_EQ(std::string("My extension 1"),
930             loaded_[0]->name());
931   EXPECT_EQ(std::string("The first extension that I made."),
932             loaded_[0]->description());
933   EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location());
934   EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
935   EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
936 
937   ValidatePrefKeyCount(3);
938   ValidateIntegerPref(good0, "state", Extension::ENABLED);
939   ValidateIntegerPref(good0, "location", Extension::INTERNAL);
940   ValidateIntegerPref(good1, "state", Extension::ENABLED);
941   ValidateIntegerPref(good1, "location", Extension::INTERNAL);
942   ValidateIntegerPref(good2, "state", Extension::ENABLED);
943   ValidateIntegerPref(good2, "location", Extension::INTERNAL);
944 
945   const Extension* extension = loaded_[0];
946   const UserScriptList& scripts = extension->content_scripts();
947   ASSERT_EQ(2u, scripts.size());
948   EXPECT_EQ(3u, scripts[0].url_patterns().size());
949   EXPECT_EQ("file://*",
950             scripts[0].url_patterns()[0].GetAsString());
951   EXPECT_EQ("http://*.google.com/*",
952             scripts[0].url_patterns()[1].GetAsString());
953   EXPECT_EQ("https://*.google.com/*",
954             scripts[0].url_patterns()[2].GetAsString());
955   EXPECT_EQ(2u, scripts[0].js_scripts().size());
956   ExtensionResource resource00(extension->id(),
957                                scripts[0].js_scripts()[0].extension_root(),
958                                scripts[0].js_scripts()[0].relative_path());
959   FilePath expected_path(extension->path().AppendASCII("script1.js"));
960   ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
961   EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
962   ExtensionResource resource01(extension->id(),
963                                scripts[0].js_scripts()[1].extension_root(),
964                                scripts[0].js_scripts()[1].relative_path());
965   expected_path = extension->path().AppendASCII("script2.js");
966   ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
967   EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
968   EXPECT_TRUE(extension->plugins().empty());
969   EXPECT_EQ(1u, scripts[1].url_patterns().size());
970   EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString());
971   ExtensionResource resource10(extension->id(),
972                                scripts[1].js_scripts()[0].extension_root(),
973                                scripts[1].js_scripts()[0].relative_path());
974   expected_path =
975       extension->path().AppendASCII("js_files").AppendASCII("script3.js");
976   ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
977   EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
978   const std::vector<URLPattern> permissions = extension->host_permissions();
979   ASSERT_EQ(2u, permissions.size());
980   EXPECT_EQ("http://*.google.com/*", permissions[0].GetAsString());
981   EXPECT_EQ("https://*.google.com/*", permissions[1].GetAsString());
982 
983   EXPECT_EQ(std::string(good1), loaded_[1]->id());
984   EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
985   EXPECT_EQ(std::string(""), loaded_[1]->description());
986   EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
987             loaded_[1]->background_url());
988   EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
989   // We don't parse the plugins section on Chrome OS.
990 #if defined(OS_CHROMEOS)
991   EXPECT_EQ(0u, loaded_[1]->plugins().size());
992 #else
993   ASSERT_EQ(2u, loaded_[1]->plugins().size());
994   EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
995             loaded_[1]->plugins()[0].path.value());
996   EXPECT_TRUE(loaded_[1]->plugins()[0].is_public);
997   EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
998             loaded_[1]->plugins()[1].path.value());
999   EXPECT_FALSE(loaded_[1]->plugins()[1].is_public);
1000 #endif
1001 
1002   EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location());
1003 
1004   int index = expected_num_extensions - 1;
1005   EXPECT_EQ(std::string(good2), loaded_[index]->id());
1006   EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1007   EXPECT_EQ(std::string(""), loaded_[index]->description());
1008   EXPECT_EQ(0u, loaded_[index]->content_scripts().size());
1009   EXPECT_EQ(Extension::INTERNAL, loaded_[index]->location());
1010 };
1011 
1012 // Test loading bad extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAllExtensionsFromDirectoryFail)1013 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1014   // Initialize the test dir with a bad Preferences/extensions.
1015   FilePath source_install_dir = data_dir_
1016       .AppendASCII("bad")
1017       .AppendASCII("Extensions");
1018   FilePath pref_path = source_install_dir
1019       .DirName()
1020       .AppendASCII("Preferences");
1021 
1022   InitializeInstalledExtensionService(pref_path, source_install_dir);
1023 
1024   service_->Init();
1025   loop_.RunAllPending();
1026 
1027   ASSERT_EQ(4u, GetErrors().size());
1028   ASSERT_EQ(0u, loaded_.size());
1029 
1030   EXPECT_TRUE(MatchPattern(GetErrors()[0],
1031       std::string("Could not load extension from '*'. ") +
1032       extension_manifest_errors::kManifestUnreadable)) << GetErrors()[0];
1033 
1034   EXPECT_TRUE(MatchPattern(GetErrors()[1],
1035       std::string("Could not load extension from '*'. ") +
1036       extension_manifest_errors::kManifestUnreadable)) << GetErrors()[1];
1037 
1038   EXPECT_TRUE(MatchPattern(GetErrors()[2],
1039       std::string("Could not load extension from '*'. ") +
1040       extension_manifest_errors::kMissingFile)) << GetErrors()[2];
1041 
1042   EXPECT_TRUE(MatchPattern(GetErrors()[3],
1043       std::string("Could not load extension from '*'. ") +
1044       extension_manifest_errors::kManifestUnreadable)) << GetErrors()[3];
1045 };
1046 
1047 // Test that partially deleted extensions are cleaned up during startup
1048 // Test loading bad extensions from the profile directory.
TEST_F(ExtensionServiceTest,CleanupOnStartup)1049 TEST_F(ExtensionServiceTest, CleanupOnStartup) {
1050   FilePath source_install_dir = data_dir_
1051       .AppendASCII("good")
1052       .AppendASCII("Extensions");
1053   FilePath pref_path = source_install_dir
1054       .DirName()
1055       .AppendASCII("Preferences");
1056 
1057   InitializeInstalledExtensionService(pref_path, source_install_dir);
1058 
1059   // Simulate that one of them got partially deleted by clearing its pref.
1060   {
1061     DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1062     DictionaryValue* dict = update.Get();
1063     ASSERT_TRUE(dict != NULL);
1064     dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1065   }
1066 
1067   service_->Init();
1068   loop_.RunAllPending();
1069 
1070   file_util::FileEnumerator dirs(extensions_install_dir_, false,
1071                                  file_util::FileEnumerator::DIRECTORIES);
1072   size_t count = 0;
1073   while (!dirs.Next().empty())
1074     count++;
1075 
1076   // We should have only gotten two extensions now.
1077   EXPECT_EQ(2u, count);
1078 
1079   // And extension1 dir should now be toast.
1080   FilePath extension_dir = extensions_install_dir_
1081       .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1082   ASSERT_FALSE(file_util::PathExists(extension_dir));
1083 }
1084 
1085 // Test installing extensions. This test tries to install few extensions using
1086 // crx files. If you need to change those crx files, feel free to repackage
1087 // them, throw away the key used and change the id's above.
TEST_F(ExtensionServiceTest,InstallExtension)1088 TEST_F(ExtensionServiceTest, InstallExtension) {
1089   InitializeEmptyExtensionService();
1090 
1091   // Extensions not enabled.
1092   set_extensions_enabled(false);
1093   FilePath path = data_dir_.AppendASCII("good.crx");
1094   InstallCrx(path, false);
1095   set_extensions_enabled(true);
1096 
1097   ValidatePrefKeyCount(0);
1098 
1099   // A simple extension that should install without error.
1100   path = data_dir_.AppendASCII("good.crx");
1101   InstallCrx(path, true);
1102   // TODO(erikkay): verify the contents of the installed extension.
1103 
1104   int pref_count = 0;
1105   ValidatePrefKeyCount(++pref_count);
1106   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1107   ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
1108 
1109   // An extension with page actions.
1110   path = data_dir_.AppendASCII("page_action.crx");
1111   InstallCrx(path, true);
1112   ValidatePrefKeyCount(++pref_count);
1113   ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1114   ValidateIntegerPref(page_action, "location", Extension::INTERNAL);
1115 
1116   // Bad signature.
1117   path = data_dir_.AppendASCII("bad_signature.crx");
1118   InstallCrx(path, false);
1119   ValidatePrefKeyCount(pref_count);
1120 
1121   // 0-length extension file.
1122   path = data_dir_.AppendASCII("not_an_extension.crx");
1123   InstallCrx(path, false);
1124   ValidatePrefKeyCount(pref_count);
1125 
1126   // Bad magic number.
1127   path = data_dir_.AppendASCII("bad_magic.crx");
1128   InstallCrx(path, false);
1129   ValidatePrefKeyCount(pref_count);
1130 
1131   // Extensions cannot have folders or files that have underscores except in
1132   // certain whitelisted cases (eg _locales). This is an example of a broader
1133   // class of validation that we do to the directory structure of the extension.
1134   // We did not used to handle this correctly for installation.
1135   path = data_dir_.AppendASCII("bad_underscore.crx");
1136   InstallCrx(path, false);
1137   ValidatePrefKeyCount(pref_count);
1138 
1139   // TODO(erikkay): add more tests for many of the failure cases.
1140   // TODO(erikkay): add tests for upgrade cases.
1141 }
1142 
1143 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
TEST_F(ExtensionServiceTest,UninstallingExternalExtensions)1144 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1145   InitializeEmptyExtensionService();
1146 
1147   FilePath path = data_dir_.AppendASCII("good.crx");
1148   set_extensions_enabled(true);
1149 
1150   scoped_ptr<Version> version;
1151   version.reset(Version::GetVersionFromString("1.0.0.0"));
1152   // Install an external extension.
1153   service_->OnExternalExtensionFileFound(good_crx, version.get(),
1154                                          path, Extension::EXTERNAL_PREF);
1155   loop_.RunAllPending();
1156   ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1157 
1158   // Uninstall it and check that its killbit gets set.
1159   service_->UninstallExtension(good_crx, false, NULL);
1160   loop_.RunAllPending();
1161   ValidateIntegerPref(good_crx, "location",
1162                       Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1163 
1164   // Try to re-install it externally. This should fail because of the killbit.
1165   service_->OnExternalExtensionFileFound(good_crx, version.get(),
1166                                          path, Extension::EXTERNAL_PREF);
1167   loop_.RunAllPending();
1168   ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1169   ValidateIntegerPref(good_crx, "location",
1170                       Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1171 
1172   version.reset(Version::GetVersionFromString("1.0.0.1"));
1173   // Repeat the same thing with a newer version of the extension.
1174   path = data_dir_.AppendASCII("good2.crx");
1175   service_->OnExternalExtensionFileFound(good_crx, version.get(),
1176                                          path, Extension::EXTERNAL_PREF);
1177   loop_.RunAllPending();
1178   ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1179   ValidateIntegerPref(good_crx, "location",
1180                       Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1181 
1182   // Try adding the same extension from an external update URL.
1183   service_->pending_extension_manager()->AddFromExternalUpdateUrl(
1184       good_crx,
1185       GURL("http:://fake.update/url"),
1186       Extension::EXTERNAL_PREF_DOWNLOAD);
1187 
1188   ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
1189 }
1190 
1191 // Test that external extensions with incorrect IDs are not installed.
TEST_F(ExtensionServiceTest,FailOnWrongId)1192 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1193   InitializeEmptyExtensionService();
1194   FilePath path = data_dir_.AppendASCII("good.crx");
1195   set_extensions_enabled(true);
1196 
1197   scoped_ptr<Version> version;
1198   version.reset(Version::GetVersionFromString("1.0.0.0"));
1199 
1200   const std::string wrong_id = all_zero;
1201   const std::string correct_id = good_crx;
1202   ASSERT_NE(correct_id, wrong_id);
1203 
1204   // Install an external extension with an ID from the external
1205   // source that is not equal to the ID in the extension manifest.
1206   service_->OnExternalExtensionFileFound(
1207       wrong_id, version.get(), path, Extension::EXTERNAL_PREF);
1208 
1209   loop_.RunAllPending();
1210   ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1211 
1212   // Try again with the right ID. Expect success.
1213   service_->OnExternalExtensionFileFound(
1214       correct_id, version.get(), path, Extension::EXTERNAL_PREF);
1215   loop_.RunAllPending();
1216   ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1217 }
1218 
1219 // Test that external extensions with incorrect versions are not installed.
TEST_F(ExtensionServiceTest,FailOnWrongVersion)1220 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1221   InitializeEmptyExtensionService();
1222   FilePath path = data_dir_.AppendASCII("good.crx");
1223   set_extensions_enabled(true);
1224 
1225   // Install an external extension with a version from the external
1226   // source that is not equal to the version in the extension manifest.
1227   scoped_ptr<Version> wrong_version;
1228   wrong_version.reset(Version::GetVersionFromString("1.2.3.4"));
1229   service_->OnExternalExtensionFileFound(
1230       good_crx, wrong_version.get(), path, Extension::EXTERNAL_PREF);
1231 
1232   loop_.RunAllPending();
1233   ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1234 
1235   // Try again with the right version. Expect success.
1236   scoped_ptr<Version> correct_version;
1237   correct_version.reset(Version::GetVersionFromString("1.0.0.0"));
1238   service_->OnExternalExtensionFileFound(
1239       good_crx, correct_version.get(), path, Extension::EXTERNAL_PREF);
1240   loop_.RunAllPending();
1241   ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1242 }
1243 
1244 // Install a user script (they get converted automatically to an extension)
TEST_F(ExtensionServiceTest,InstallUserScript)1245 TEST_F(ExtensionServiceTest, InstallUserScript) {
1246   // The details of script conversion are tested elsewhere, this just tests
1247   // integration with ExtensionService.
1248   InitializeEmptyExtensionService();
1249 
1250   FilePath path = data_dir_
1251              .AppendASCII("user_script_basic.user.js");
1252 
1253   ASSERT_TRUE(file_util::PathExists(path));
1254   scoped_refptr<CrxInstaller> installer(
1255       new CrxInstaller(service_, NULL));  // silent install
1256   installer->InstallUserScript(
1257       path,
1258       GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1259 
1260   loop_.RunAllPending();
1261   std::vector<std::string> errors = GetErrors();
1262   EXPECT_TRUE(installed_) << "Nothing was installed.";
1263   ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1264   EXPECT_EQ(0u, errors.size()) << "There were errors: "
1265                                << JoinString(errors, ',');
1266   EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
1267               path.value();
1268 
1269   installed_ = NULL;
1270   loaded_.clear();
1271   ExtensionErrorReporter::GetInstance()->ClearErrors();
1272 }
1273 
1274 // This tests that the granted permissions preferences are correctly set when
1275 // installing an extension.
TEST_F(ExtensionServiceTest,GrantedPermissions)1276 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1277   InitializeEmptyExtensionService();
1278   FilePath path = data_dir_
1279       .AppendASCII("permissions");
1280 
1281   FilePath pem_path = path.AppendASCII("unknown.pem");
1282   path = path.AppendASCII("unknown");
1283 
1284   ASSERT_TRUE(file_util::PathExists(pem_path));
1285   ASSERT_TRUE(file_util::PathExists(path));
1286 
1287   ExtensionPrefs* prefs = service_->extension_prefs();
1288 
1289   std::set<std::string> expected_api_perms;
1290   std::set<std::string> known_api_perms;
1291   bool full_access;
1292   ExtensionExtent expected_host_perms;
1293   ExtensionExtent known_host_perms;
1294 
1295   // Make sure there aren't any granted permissions before the
1296   // extension is installed.
1297   EXPECT_FALSE(prefs->GetGrantedPermissions(
1298       permissions_crx, &full_access, &known_api_perms, &known_host_perms));
1299   EXPECT_TRUE(known_api_perms.empty());
1300   EXPECT_TRUE(known_host_perms.is_empty());
1301 
1302   PackAndInstallCrx(path, pem_path, true);
1303 
1304   EXPECT_EQ(0u, GetErrors().size());
1305   ASSERT_EQ(1u, service_->extensions()->size());
1306   std::string extension_id = service_->extensions()->at(0)->id();
1307   EXPECT_EQ(permissions_crx, extension_id);
1308 
1309 
1310   // Verify that the valid API permissions have been recognized.
1311   expected_api_perms.insert("tabs");
1312 
1313   AddPattern(&expected_host_perms, "http://*.google.com/*");
1314   AddPattern(&expected_host_perms, "https://*.google.com/*");
1315   AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1316   AddPattern(&expected_host_perms, "http://www.example.com/*");
1317 
1318   EXPECT_TRUE(prefs->GetGrantedPermissions(extension_id,
1319                                            &full_access,
1320                                            &known_api_perms,
1321                                            &known_host_perms));
1322 
1323   EXPECT_EQ(expected_api_perms, known_api_perms);
1324   EXPECT_FALSE(full_access);
1325   AssertEqualExtents(&expected_host_perms, &known_host_perms);
1326 }
1327 
1328 #if !defined(OS_CHROMEOS)
1329 // Tests that the granted permissions full_access bit gets set correctly when
1330 // an extension contains an NPAPI plugin. Don't run this test on Chrome OS
1331 // since they don't support plugins.
TEST_F(ExtensionServiceTest,GrantedFullAccessPermissions)1332 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1333   InitializeEmptyExtensionService();
1334 
1335   FilePath path = data_dir_
1336       .AppendASCII("good")
1337       .AppendASCII("Extensions")
1338       .AppendASCII(good1)
1339       .AppendASCII("2");
1340 
1341   ASSERT_TRUE(file_util::PathExists(path));
1342 
1343   PackAndInstallCrx(path, true);
1344 
1345   EXPECT_EQ(0u, GetErrors().size());
1346   EXPECT_EQ(1u, service_->extensions()->size());
1347   const Extension* extension = service_->extensions()->at(0);
1348   std::string extension_id = extension->id();
1349   ExtensionPrefs* prefs = service_->extension_prefs();
1350 
1351   bool full_access;
1352   std::set<std::string> api_permissions;
1353   ExtensionExtent host_permissions;
1354   EXPECT_TRUE(prefs->GetGrantedPermissions(
1355       extension_id, &full_access, &api_permissions, &host_permissions));
1356 
1357   EXPECT_TRUE(full_access);
1358   EXPECT_TRUE(api_permissions.empty());
1359   EXPECT_TRUE(host_permissions.is_empty());
1360 }
1361 #endif
1362 
1363 // Tests that the extension is disabled when permissions are missing from
1364 // the extension's granted permissions preferences. (This simulates updating
1365 // the browser to a version which recognizes more permissions).
TEST_F(ExtensionServiceTest,GrantedAPIAndHostPermissions)1366 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1367   InitializeEmptyExtensionService();
1368 
1369   FilePath path = data_dir_
1370       .AppendASCII("permissions")
1371       .AppendASCII("unknown");
1372 
1373   ASSERT_TRUE(file_util::PathExists(path));
1374 
1375   PackAndInstallCrx(path, true);
1376 
1377   EXPECT_EQ(0u, GetErrors().size());
1378   EXPECT_EQ(1u, service_->extensions()->size());
1379   const Extension* extension = service_->extensions()->at(0);
1380   std::string extension_id = extension->id();
1381 
1382   ExtensionPrefs* prefs = service_->extension_prefs();
1383 
1384   std::set<std::string> expected_api_permissions;
1385   ExtensionExtent expected_host_permissions;
1386 
1387   expected_api_permissions.insert("tabs");
1388   AddPattern(&expected_host_permissions, "http://*.google.com/*");
1389   AddPattern(&expected_host_permissions, "https://*.google.com/*");
1390   AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1391   AddPattern(&expected_host_permissions, "http://www.example.com/*");
1392 
1393   std::set<std::string> api_permissions;
1394   std::set<std::string> host_permissions;
1395 
1396   // Test that the extension is disabled when an API permission is missing from
1397   // the extension's granted api permissions preference. (This simulates
1398   // updating the browser to a version which recognizes a new API permission).
1399   SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions);
1400 
1401   service_->ReloadExtensions();
1402 
1403   EXPECT_EQ(1u, service_->disabled_extensions()->size());
1404   extension = service_->disabled_extensions()->at(0);
1405 
1406   ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED);
1407   ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1408 
1409   // Now grant and re-enable the extension, making sure the prefs are updated.
1410   service_->GrantPermissionsAndEnableExtension(extension);
1411 
1412   ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1413   ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1414 
1415   std::set<std::string> current_api_permissions;
1416   ExtensionExtent current_host_permissions;
1417   bool current_full_access;
1418 
1419   ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1420                                            &current_full_access,
1421                                            &current_api_permissions,
1422                                            &current_host_permissions));
1423 
1424   ASSERT_FALSE(current_full_access);
1425   ASSERT_EQ(expected_api_permissions, current_api_permissions);
1426   AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1427 
1428   // Tests that the extension is disabled when a host permission is missing from
1429   // the extension's granted host permissions preference. (This simulates
1430   // updating the browser to a version which recognizes additional host
1431   // permissions).
1432   api_permissions.clear();
1433   host_permissions.clear();
1434   current_api_permissions.clear();
1435   current_host_permissions.ClearPaths();
1436 
1437   api_permissions.insert("tabs");
1438   host_permissions.insert("http://*.google.com/*");
1439   host_permissions.insert("https://*.google.com/*");
1440   host_permissions.insert("http://*.google.com.hk/*");
1441 
1442   SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions);
1443   SetPrefStringSet(extension_id, "granted_permissions.host", host_permissions);
1444 
1445   service_->ReloadExtensions();
1446 
1447   EXPECT_EQ(1u, service_->disabled_extensions()->size());
1448   extension = service_->disabled_extensions()->at(0);
1449 
1450   ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED);
1451   ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1452 
1453   // Now grant and re-enable the extension, making sure the prefs are updated.
1454   service_->GrantPermissionsAndEnableExtension(extension);
1455 
1456   ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1457   ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1458 
1459   ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1460                                            &current_full_access,
1461                                            &current_api_permissions,
1462                                            &current_host_permissions));
1463 
1464   ASSERT_FALSE(current_full_access);
1465   ASSERT_EQ(expected_api_permissions, current_api_permissions);
1466   AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1467 
1468   // Tests that the granted permissions preferences are initialized when
1469   // migrating from the old pref schema.
1470   current_api_permissions.clear();
1471   current_host_permissions.ClearPaths();
1472 
1473   ClearPref(extension_id, "granted_permissions");
1474 
1475   service_->ReloadExtensions();
1476 
1477   EXPECT_EQ(1u, service_->extensions()->size());
1478   extension = service_->extensions()->at(0);
1479 
1480   ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1481   ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1482 
1483   ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1484                                            &current_full_access,
1485                                            &current_api_permissions,
1486                                            &current_host_permissions));
1487 
1488   ASSERT_FALSE(current_full_access);
1489   ASSERT_EQ(expected_api_permissions, current_api_permissions);
1490   AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1491 }
1492 
1493 // Test Packaging and installing an extension.
TEST_F(ExtensionServiceTest,PackExtension)1494 TEST_F(ExtensionServiceTest, PackExtension) {
1495   InitializeEmptyExtensionService();
1496   FilePath input_directory = data_dir_
1497       .AppendASCII("good")
1498       .AppendASCII("Extensions")
1499       .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1500       .AppendASCII("1.0.0.0");
1501 
1502   ScopedTempDir temp_dir;
1503   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1504   FilePath output_directory = temp_dir.path();
1505 
1506   FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1507   FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
1508 
1509   scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1510   ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
1511       privkey_path));
1512 
1513   ASSERT_TRUE(file_util::PathExists(privkey_path));
1514   InstallCrx(crx_path, true);
1515 
1516   // Try packing with invalid paths.
1517   creator.reset(new ExtensionCreator());
1518   ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath()));
1519 
1520   // Try packing an empty directory. Should fail because an empty directory is
1521   // not a valid extension.
1522   ScopedTempDir temp_dir2;
1523   ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
1524   creator.reset(new ExtensionCreator());
1525   ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
1526                             FilePath()));
1527 
1528   // Try packing with an invalid manifest.
1529   std::string invalid_manifest_content = "I am not a manifest.";
1530   ASSERT_TRUE(file_util::WriteFile(
1531       temp_dir2.path().Append(Extension::kManifestFilename),
1532       invalid_manifest_content.c_str(), invalid_manifest_content.size()));
1533   creator.reset(new ExtensionCreator());
1534   ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
1535                             FilePath()));
1536 }
1537 
1538 // Test Packaging and installing an extension whose name contains punctuation.
TEST_F(ExtensionServiceTest,PackPunctuatedExtension)1539 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
1540   InitializeEmptyExtensionService();
1541   FilePath input_directory = data_dir_
1542       .AppendASCII("good")
1543       .AppendASCII("Extensions")
1544       .AppendASCII(good0)
1545       .AppendASCII("1.0.0.0");
1546 
1547   ScopedTempDir temp_dir;
1548   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1549 
1550   // Extension names containing punctuation, and the expected names for the
1551   // packed extensions.
1552   const FilePath punctuated_names[] = {
1553     FilePath(FilePath::StringType(
1554         FILE_PATH_LITERAL("this.extensions.name.has.periods"))),
1555     FilePath(FilePath::StringType(
1556         FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod"))),
1557     NormalizeSeparators(FilePath(FilePath::StringType(
1558         FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")))),
1559   };
1560   const FilePath expected_crx_names[] = {
1561     FilePath(FilePath::StringType(
1562         FILE_PATH_LITERAL("this.extensions.name.has.periods.crx"))),
1563     FilePath(FilePath::StringType(
1564         FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx"))),
1565     FilePath(FilePath::StringType(
1566         FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx"))),
1567   };
1568   const FilePath expected_private_key_names[] = {
1569     FilePath(FilePath::StringType(
1570         FILE_PATH_LITERAL("this.extensions.name.has.periods.pem"))),
1571     FilePath(FilePath::StringType(
1572         FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem"))),
1573     FilePath(FilePath::StringType(
1574         FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem"))),
1575   };
1576 
1577   for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
1578     SCOPED_TRACE(punctuated_names[i].value().c_str());
1579     FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
1580 
1581     // Copy the extension into the output directory, as PackExtensionJob doesn't
1582     // let us choose where to output the packed extension.
1583     ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true));
1584 
1585     FilePath expected_crx_path = temp_dir.path().Append(expected_crx_names[i]);
1586     FilePath expected_private_key_path =
1587         temp_dir.path().Append(expected_private_key_names[i]);
1588     PackExtensionTestClient pack_client(expected_crx_path,
1589                                         expected_private_key_path);
1590     scoped_refptr<PackExtensionJob> packer(new PackExtensionJob(&pack_client,
1591                                                                 output_dir,
1592                                                                 FilePath()));
1593     packer->Start();
1594 
1595     // The packer will post a notification task to the current thread's message
1596     // loop when it is finished.  We manually run the loop here so that we
1597     // block and catch the notification; otherwise, the process would exit.
1598     // This call to |Run()| is matched by a call to |Quit()| in the
1599     // |PackExtensionTestClient|'s notification handling code.
1600     MessageLoop::current()->Run();
1601 
1602     if (HasFatalFailure())
1603       return;
1604 
1605     InstallCrx(expected_crx_path, true);
1606   }
1607 }
1608 
1609 // Test Packaging and installing an extension using an openssl generated key.
1610 // The openssl is generated with the following:
1611 // > openssl genrsa -out privkey.pem 1024
1612 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
1613 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
1614 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
TEST_F(ExtensionServiceTest,PackExtensionOpenSSLKey)1615 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
1616   InitializeEmptyExtensionService();
1617   FilePath input_directory = data_dir_
1618       .AppendASCII("good")
1619       .AppendASCII("Extensions")
1620       .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1621       .AppendASCII("1.0.0.0");
1622   FilePath privkey_path(data_dir_.AppendASCII(
1623       "openssl_privkey_asn1.pem"));
1624   ASSERT_TRUE(file_util::PathExists(privkey_path));
1625 
1626   ScopedTempDir temp_dir;
1627   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1628   FilePath output_directory = temp_dir.path();
1629 
1630   FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1631 
1632   scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1633   ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
1634       FilePath()));
1635 
1636   InstallCrx(crx_path, true);
1637 }
1638 
TEST_F(ExtensionServiceTest,InstallTheme)1639 TEST_F(ExtensionServiceTest, InstallTheme) {
1640   InitializeEmptyExtensionService();
1641 
1642   // A theme.
1643   FilePath path = data_dir_.AppendASCII("theme.crx");
1644   InstallCrx(path, true);
1645   int pref_count = 0;
1646   ValidatePrefKeyCount(++pref_count);
1647   ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
1648   ValidateIntegerPref(theme_crx, "location", Extension::INTERNAL);
1649 
1650   // A theme when extensions are disabled. Themes can be installed, even when
1651   // extensions are disabled.
1652   set_extensions_enabled(false);
1653   path = data_dir_.AppendASCII("theme2.crx");
1654   InstallCrx(path, true);
1655   ValidatePrefKeyCount(++pref_count);
1656   ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
1657   ValidateIntegerPref(theme2_crx, "location", Extension::INTERNAL);
1658 
1659   // A theme with extension elements. Themes cannot have extension elements so
1660   // this test should fail.
1661   set_extensions_enabled(true);
1662   path = data_dir_.AppendASCII("theme_with_extension.crx");
1663   InstallCrx(path, false);
1664   ValidatePrefKeyCount(pref_count);
1665 
1666   // A theme with image resources missing (misspelt path).
1667   path = data_dir_.AppendASCII("theme_missing_image.crx");
1668   InstallCrx(path, false);
1669   ValidatePrefKeyCount(pref_count);
1670 }
1671 
TEST_F(ExtensionServiceTest,LoadLocalizedTheme)1672 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
1673   // Load.
1674   InitializeEmptyExtensionService();
1675   FilePath extension_path = data_dir_
1676       .AppendASCII("theme_i18n");
1677 
1678   service_->LoadExtension(extension_path);
1679   loop_.RunAllPending();
1680   EXPECT_EQ(0u, GetErrors().size());
1681   ASSERT_EQ(1u, loaded_.size());
1682   EXPECT_EQ(1u, service_->extensions()->size());
1683   EXPECT_EQ("name", service_->extensions()->at(0)->name());
1684   EXPECT_EQ("description", service_->extensions()->at(0)->description());
1685 }
1686 
TEST_F(ExtensionServiceTest,InstallLocalizedTheme)1687 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
1688   InitializeEmptyExtensionService();
1689   FilePath theme_path = data_dir_
1690       .AppendASCII("theme_i18n");
1691 
1692   PackAndInstallCrx(theme_path, true);
1693 
1694   EXPECT_EQ(0u, GetErrors().size());
1695   EXPECT_EQ(1u, service_->extensions()->size());
1696   EXPECT_EQ("name", service_->extensions()->at(0)->name());
1697   EXPECT_EQ("description", service_->extensions()->at(0)->description());
1698 }
1699 
TEST_F(ExtensionServiceTest,InstallApps)1700 TEST_F(ExtensionServiceTest, InstallApps) {
1701   InitializeEmptyExtensionService();
1702 
1703   // An empty app.
1704   PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
1705   int pref_count = 0;
1706   ValidatePrefKeyCount(++pref_count);
1707   ASSERT_EQ(1u, service_->extensions()->size());
1708   std::string id = service_->extensions()->at(0)->id();
1709   ValidateIntegerPref(id, "state", Extension::ENABLED);
1710   ValidateIntegerPref(id, "location", Extension::INTERNAL);
1711 
1712   // Another app with non-overlapping extent. Should succeed.
1713   PackAndInstallCrx(data_dir_.AppendASCII("app2"), true);
1714   ValidatePrefKeyCount(++pref_count);
1715 
1716   // A third app whose extent overlaps the first. Should fail.
1717   PackAndInstallCrx(data_dir_.AppendASCII("app3"), false);
1718   ValidatePrefKeyCount(pref_count);
1719 }
1720 
TEST_F(ExtensionServiceTest,UpdateApps)1721 TEST_F(ExtensionServiceTest, UpdateApps) {
1722   InitializeEmptyExtensionService();
1723   FilePath extensions_path = data_dir_.AppendASCII("app_update");
1724 
1725   // First install v1 of a hosted app.
1726   InstallCrx(extensions_path.AppendASCII("v1.crx"), true);
1727   ASSERT_EQ(1u, service_->extensions()->size());
1728   std::string id = service_->extensions()->at(0)->id();
1729   ASSERT_EQ(std::string("1"),
1730             service_->extensions()->at(0)->version()->GetString());
1731 
1732   // Now try updating to v2.
1733   UpdateExtension(id,
1734                   extensions_path.AppendASCII("v2.crx"),
1735                   ENABLED);
1736   ASSERT_EQ(std::string("2"),
1737             service_->extensions()->at(0)->version()->GetString());
1738 }
1739 
TEST_F(ExtensionServiceTest,InstallAppsWithUnlimtedStorage)1740 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) {
1741   InitializeEmptyExtensionService();
1742   EXPECT_TRUE(service_->extensions()->empty());
1743 
1744   int pref_count = 0;
1745 
1746   // Install app1 with unlimited storage.
1747   PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
1748   ValidatePrefKeyCount(++pref_count);
1749   ASSERT_EQ(1u, service_->extensions()->size());
1750   const Extension* extension = service_->extensions()->at(0);
1751   const std::string id1 = extension->id();
1752   EXPECT_TRUE(extension->HasApiPermission(
1753                   Extension::kUnlimitedStoragePermission));
1754   EXPECT_TRUE(extension->web_extent().ContainsURL(
1755                   extension->GetFullLaunchURL()));
1756   const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
1757   EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1758       IsStorageUnlimited(origin1));
1759 
1760   // Install app2 from the same origin with unlimited storage.
1761   PackAndInstallCrx(data_dir_.AppendASCII("app2"), true);
1762   ValidatePrefKeyCount(++pref_count);
1763   ASSERT_EQ(2u, service_->extensions()->size());
1764   extension = service_->extensions()->at(1);
1765   const std::string id2 = extension->id();
1766   EXPECT_TRUE(extension->HasApiPermission(
1767                   Extension::kUnlimitedStoragePermission));
1768   EXPECT_TRUE(extension->web_extent().ContainsURL(
1769                   extension->GetFullLaunchURL()));
1770   const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
1771   EXPECT_EQ(origin1, origin2);
1772   EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1773       IsStorageUnlimited(origin2));
1774 
1775 
1776   // Uninstall one of them, unlimited storage should still be granted
1777   // to the origin.
1778   service_->UninstallExtension(id1, false, NULL);
1779   loop_.RunAllPending();
1780   EXPECT_EQ(1u, service_->extensions()->size());
1781   EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1782       IsStorageUnlimited(origin1));
1783 
1784 
1785   // Uninstall the other, unlimited storage should be revoked.
1786   service_->UninstallExtension(id2, false, NULL);
1787   loop_.RunAllPending();
1788   EXPECT_EQ(0u, service_->extensions()->size());
1789   EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1790       IsStorageUnlimited(origin2));
1791 }
1792 
TEST_F(ExtensionServiceTest,InstallAppsAndCheckStorageProtection)1793 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
1794   InitializeEmptyExtensionService();
1795   EXPECT_TRUE(service_->extensions()->empty());
1796 
1797   int pref_count = 0;
1798 
1799   PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
1800   ValidatePrefKeyCount(++pref_count);
1801   ASSERT_EQ(1u, service_->extensions()->size());
1802   const Extension* extension = service_->extensions()->at(0);
1803   EXPECT_TRUE(extension->is_app());
1804   const std::string id1 = extension->id();
1805   const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
1806   EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1807       IsStorageProtected(origin1));
1808 
1809   // App 4 has a different origin (maps.google.com).
1810   PackAndInstallCrx(data_dir_.AppendASCII("app4"), true);
1811   ValidatePrefKeyCount(++pref_count);
1812   ASSERT_EQ(2u, service_->extensions()->size());
1813   extension = service_->extensions()->at(1);
1814   const std::string id2 = extension->id();
1815   const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
1816   ASSERT_NE(origin1, origin2);
1817   EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1818       IsStorageProtected(origin2));
1819 
1820   service_->UninstallExtension(id1, false, NULL);
1821   loop_.RunAllPending();
1822   EXPECT_EQ(1u, service_->extensions()->size());
1823 
1824   service_->UninstallExtension(id2, false, NULL);
1825   loop_.RunAllPending();
1826 
1827   EXPECT_TRUE(service_->extensions()->empty());
1828   EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1829       IsStorageProtected(origin1));
1830   EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1831       IsStorageProtected(origin2));
1832 }
1833 
1834 // Test that when an extension version is reinstalled, nothing happens.
TEST_F(ExtensionServiceTest,Reinstall)1835 TEST_F(ExtensionServiceTest, Reinstall) {
1836   InitializeEmptyExtensionService();
1837 
1838   // A simple extension that should install without error.
1839   FilePath path = data_dir_.AppendASCII("good.crx");
1840   StartCrxInstall(path);
1841   loop_.RunAllPending();
1842 
1843   ASSERT_TRUE(installed_);
1844   ASSERT_EQ(1u, loaded_.size());
1845   ASSERT_EQ(0u, GetErrors().size());
1846   ValidatePrefKeyCount(1);
1847   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1848   ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
1849 
1850   installed_ = NULL;
1851   loaded_.clear();
1852   ExtensionErrorReporter::GetInstance()->ClearErrors();
1853 
1854   // Reinstall the same version, it should overwrite the previous one.
1855   StartCrxInstall(path);
1856   loop_.RunAllPending();
1857 
1858   ASSERT_TRUE(installed_);
1859   ASSERT_EQ(1u, loaded_.size());
1860   ASSERT_EQ(0u, GetErrors().size());
1861   ValidatePrefKeyCount(1);
1862   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1863   ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
1864 }
1865 
1866 // Test upgrading a signed extension.
TEST_F(ExtensionServiceTest,UpgradeSignedGood)1867 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
1868   InitializeEmptyExtensionService();
1869 
1870   FilePath path = data_dir_.AppendASCII("good.crx");
1871   StartCrxInstall(path);
1872   loop_.RunAllPending();
1873 
1874   ASSERT_TRUE(installed_);
1875   ASSERT_EQ(1u, loaded_.size());
1876   ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
1877   ASSERT_EQ(0u, GetErrors().size());
1878 
1879   // Upgrade to version 2.0
1880   path = data_dir_.AppendASCII("good2.crx");
1881   StartCrxInstall(path);
1882   loop_.RunAllPending();
1883 
1884   ASSERT_TRUE(installed_);
1885   ASSERT_EQ(1u, loaded_.size());
1886   ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
1887   ASSERT_EQ(0u, GetErrors().size());
1888 }
1889 
1890 // Test upgrading a signed extension with a bad signature.
TEST_F(ExtensionServiceTest,UpgradeSignedBad)1891 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
1892   InitializeEmptyExtensionService();
1893 
1894   FilePath path = data_dir_.AppendASCII("good.crx");
1895   StartCrxInstall(path);
1896   loop_.RunAllPending();
1897 
1898   ASSERT_TRUE(installed_);
1899   ASSERT_EQ(1u, loaded_.size());
1900   ASSERT_EQ(0u, GetErrors().size());
1901   installed_ = NULL;
1902 
1903   // Try upgrading with a bad signature. This should fail during the unpack,
1904   // because the key will not match the signature.
1905   path = data_dir_.AppendASCII("bad_signature.crx");
1906   StartCrxInstall(path);
1907   loop_.RunAllPending();
1908 
1909   ASSERT_FALSE(installed_);
1910   ASSERT_EQ(1u, loaded_.size());
1911   ASSERT_EQ(1u, GetErrors().size());
1912 }
1913 
1914 // Test a normal update via the UpdateExtension API
TEST_F(ExtensionServiceTest,UpdateExtension)1915 TEST_F(ExtensionServiceTest, UpdateExtension) {
1916   InitializeEmptyExtensionService();
1917 
1918   FilePath path = data_dir_.AppendASCII("good.crx");
1919 
1920   InstallCrx(path, true);
1921   const Extension* good = service_->extensions()->at(0);
1922   ASSERT_EQ("1.0.0.0", good->VersionString());
1923   ASSERT_EQ(good_crx, good->id());
1924 
1925   path = data_dir_.AppendASCII("good2.crx");
1926   UpdateExtension(good_crx, path, ENABLED);
1927   ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
1928 }
1929 
1930 // Test updating a not-already-installed extension - this should fail
TEST_F(ExtensionServiceTest,UpdateNotInstalledExtension)1931 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
1932   InitializeEmptyExtensionService();
1933 
1934   FilePath path = data_dir_.AppendASCII("good.crx");
1935   UpdateExtension(good_crx, path, UPDATED);
1936   loop_.RunAllPending();
1937 
1938   ASSERT_EQ(0u, service_->extensions()->size());
1939   ASSERT_FALSE(installed_);
1940   ASSERT_EQ(0u, loaded_.size());
1941 }
1942 
1943 // Makes sure you can't downgrade an extension via UpdateExtension
TEST_F(ExtensionServiceTest,UpdateWillNotDowngrade)1944 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
1945   InitializeEmptyExtensionService();
1946 
1947   FilePath path = data_dir_.AppendASCII("good2.crx");
1948 
1949   InstallCrx(path, true);
1950   const Extension* good = service_->extensions()->at(0);
1951   ASSERT_EQ("1.0.0.1", good->VersionString());
1952   ASSERT_EQ(good_crx, good->id());
1953 
1954   // Change path from good2.crx -> good.crx
1955   path = data_dir_.AppendASCII("good.crx");
1956   UpdateExtension(good_crx, path, FAILED);
1957   ASSERT_EQ("1.0.0.1", service_->extensions()->at(0)->VersionString());
1958 }
1959 
1960 // Make sure calling update with an identical version does nothing
TEST_F(ExtensionServiceTest,UpdateToSameVersionIsNoop)1961 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
1962   InitializeEmptyExtensionService();
1963 
1964   FilePath path = data_dir_.AppendASCII("good.crx");
1965 
1966   InstallCrx(path, true);
1967   const Extension* good = service_->extensions()->at(0);
1968   ASSERT_EQ(good_crx, good->id());
1969   UpdateExtension(good_crx, path, FAILED_SILENTLY);
1970 }
1971 
1972 // Tests that updating an extension does not clobber old state.
TEST_F(ExtensionServiceTest,UpdateExtensionPreservesState)1973 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
1974   InitializeEmptyExtensionService();
1975 
1976   FilePath path = data_dir_.AppendASCII("good.crx");
1977 
1978   InstallCrx(path, true);
1979   const Extension* good = service_->extensions()->at(0);
1980   ASSERT_EQ("1.0.0.0", good->VersionString());
1981   ASSERT_EQ(good_crx, good->id());
1982 
1983   // Disable it and allow it to run in incognito. These settings should carry
1984   // over to the updated version.
1985   service_->DisableExtension(good->id());
1986   service_->SetIsIncognitoEnabled(good->id(), true);
1987 
1988   path = data_dir_.AppendASCII("good2.crx");
1989   UpdateExtension(good_crx, path, INSTALLED);
1990   ASSERT_EQ(1u, service_->disabled_extensions()->size());
1991   const Extension* good2 = service_->disabled_extensions()->at(0);
1992   ASSERT_EQ("1.0.0.1", good2->version()->GetString());
1993   EXPECT_TRUE(service_->IsIncognitoEnabled(good2->id()));
1994 }
1995 
1996 // Tests that updating preserves extension location.
TEST_F(ExtensionServiceTest,UpdateExtensionPreservesLocation)1997 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
1998   InitializeEmptyExtensionService();
1999 
2000   FilePath path = data_dir_.AppendASCII("good.crx");
2001 
2002   InstallCrx(path, true);
2003   const Extension* good = service_->extensions()->at(0);
2004 
2005   ASSERT_EQ("1.0.0.0", good->VersionString());
2006   ASSERT_EQ(good_crx, good->id());
2007 
2008   // Simulate non-internal location.
2009   const_cast<Extension*>(good)->location_ = Extension::EXTERNAL_PREF;
2010 
2011   path = data_dir_.AppendASCII("good2.crx");
2012   UpdateExtension(good_crx, path, ENABLED);
2013   const Extension* good2 = service_->extensions()->at(0);
2014   ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2015   EXPECT_EQ(good2->location(), Extension::EXTERNAL_PREF);
2016 }
2017 
2018 // Makes sure that LOAD extension types can downgrade.
TEST_F(ExtensionServiceTest,LoadExtensionsCanDowngrade)2019 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2020   InitializeEmptyExtensionService();
2021 
2022   ScopedTempDir temp;
2023   ASSERT_TRUE(temp.CreateUniqueTempDir());
2024 
2025   // We'll write the extension manifest dynamically to a temporary path
2026   // to make it easier to change the version number.
2027   FilePath extension_path = temp.path();
2028   FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
2029   ASSERT_FALSE(file_util::PathExists(manifest_path));
2030 
2031   // Start with version 2.0.
2032   DictionaryValue manifest;
2033   manifest.SetString("version", "2.0");
2034   manifest.SetString("name", "LOAD Downgrade Test");
2035 
2036   JSONFileValueSerializer serializer(manifest_path);
2037   ASSERT_TRUE(serializer.Serialize(manifest));
2038 
2039   service_->LoadExtension(extension_path);
2040   loop_.RunAllPending();
2041 
2042   EXPECT_EQ(0u, GetErrors().size());
2043   ASSERT_EQ(1u, loaded_.size());
2044   EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2045   EXPECT_EQ(1u, service_->extensions()->size());
2046   EXPECT_EQ("2.0", loaded_[0]->VersionString());
2047 
2048   // Now set the version number to 1.0, reload the extensions and verify that
2049   // the downgrade was accepted.
2050   manifest.SetString("version", "1.0");
2051   ASSERT_TRUE(serializer.Serialize(manifest));
2052 
2053   service_->LoadExtension(extension_path);
2054   loop_.RunAllPending();
2055 
2056   EXPECT_EQ(0u, GetErrors().size());
2057   ASSERT_EQ(1u, loaded_.size());
2058   EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2059   EXPECT_EQ(1u, service_->extensions()->size());
2060   EXPECT_EQ("1.0", loaded_[0]->VersionString());
2061 }
2062 
2063 namespace {
2064 
IsExtension(const Extension & extension)2065 bool IsExtension(const Extension& extension) {
2066   return extension.GetType() == Extension::TYPE_EXTENSION;
2067 }
2068 
2069 }  // namespace
2070 
2071 // Test adding a pending extension.
TEST_F(ExtensionServiceTest,AddPendingExtensionFromSync)2072 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
2073   InitializeEmptyExtensionService();
2074 
2075   const std::string kFakeId(all_zero);
2076   const GURL kFakeUpdateURL("http:://fake.update/url");
2077   const bool kFakeInstallSilently(true);
2078   const Extension::State kFakeInitialState(Extension::ENABLED);
2079   const bool kFakeInitialIncognitoEnabled(false);
2080 
2081   service_->pending_extension_manager()->AddFromSync(
2082       kFakeId, kFakeUpdateURL, &IsExtension,
2083       kFakeInstallSilently, kFakeInitialState, kFakeInitialIncognitoEnabled);
2084 
2085   PendingExtensionInfo pending_extension_info;
2086   ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2087       kFakeId, &pending_extension_info));
2088   EXPECT_EQ(kFakeUpdateURL, pending_extension_info.update_url());
2089   EXPECT_EQ(&IsExtension, pending_extension_info.should_allow_install_);
2090   EXPECT_EQ(kFakeInstallSilently, pending_extension_info.install_silently());
2091 }
2092 
2093 namespace {
2094 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2095 const char kGoodUpdateURL[] = "http://good.update/url";
2096 const bool kGoodIsFromSync = true;
2097 const bool kGoodInstallSilently = true;
2098 const Extension::State kGoodInitialState = Extension::DISABLED;
2099 const bool kGoodInitialIncognitoEnabled = true;
2100 }  // namespace
2101 
2102 // Test updating a pending extension.
TEST_F(ExtensionServiceTest,UpdatePendingExtension)2103 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2104   InitializeEmptyExtensionService();
2105   service_->pending_extension_manager()->AddFromSync(
2106       kGoodId, GURL(kGoodUpdateURL), &IsExtension,
2107       kGoodInstallSilently, kGoodInitialState,
2108       kGoodInitialIncognitoEnabled);
2109   EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2110 
2111   FilePath path = data_dir_.AppendASCII("good.crx");
2112   UpdateExtension(kGoodId, path, INSTALLED);
2113 
2114   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2115 
2116   const Extension* extension = service_->GetExtensionById(kGoodId, true);
2117   ASSERT_TRUE(extension);
2118 
2119   bool enabled = service_->GetExtensionById(kGoodId, false);
2120   EXPECT_EQ(enabled, kGoodInitialState == Extension::ENABLED);
2121   EXPECT_EQ(kGoodInitialState,
2122             service_->extension_prefs()->GetExtensionState(extension->id()));
2123   EXPECT_EQ(kGoodInitialIncognitoEnabled,
2124             service_->IsIncognitoEnabled(extension->id()));
2125 }
2126 
2127 namespace {
2128 
IsTheme(const Extension & extension)2129 bool IsTheme(const Extension& extension) {
2130   return extension.is_theme();
2131 }
2132 
2133 }  // namespace
2134 
2135 // Test updating a pending theme.
TEST_F(ExtensionServiceTest,UpdatePendingTheme)2136 TEST_F(ExtensionServiceTest, UpdatePendingTheme) {
2137   InitializeEmptyExtensionService();
2138   service_->pending_extension_manager()->AddFromSync(
2139       theme_crx, GURL(), &IsTheme,
2140       false, Extension::ENABLED, false);
2141   EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2142 
2143   FilePath path = data_dir_.AppendASCII("theme.crx");
2144   UpdateExtension(theme_crx, path, ENABLED);
2145 
2146   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2147 
2148   const Extension* extension = service_->GetExtensionById(theme_crx, true);
2149   ASSERT_TRUE(extension);
2150 
2151   EXPECT_EQ(Extension::ENABLED,
2152             service_->extension_prefs()->GetExtensionState(extension->id()));
2153   EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
2154 }
2155 
2156 #if defined(OS_CHROMEOS)
2157 // Always fails on ChromeOS: http://crbug.com/79737
2158 #define MAYBE_UpdatePendingExternalCrx FAILS_UpdatePendingExternalCrx
2159 #else
2160 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
2161 #endif
2162 // Test updating a pending CRX as if the source is an external extension
2163 // with an update URL.  In this case we don't know if the CRX is a theme
2164 // or not.
TEST_F(ExtensionServiceTest,MAYBE_UpdatePendingExternalCrx)2165 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
2166   InitializeEmptyExtensionService();
2167   service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2168       theme_crx, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
2169 
2170   EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2171 
2172   FilePath path = data_dir_.AppendASCII("theme.crx");
2173   UpdateExtension(theme_crx, path, ENABLED);
2174 
2175   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2176 
2177   const Extension* extension = service_->GetExtensionById(theme_crx, true);
2178   ASSERT_TRUE(extension);
2179 
2180   EXPECT_EQ(Extension::ENABLED,
2181             service_->extension_prefs()->GetExtensionState(extension->id()));
2182   EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
2183 }
2184 
2185 // Test updating a pending CRX as if the source is an external extension
2186 // with an update URL.  The external update should overwrite a sync update,
2187 // but a sync update should not overwrite a non-sync update.
TEST_F(ExtensionServiceTest,UpdatePendingExternalCrxWinsOverSync)2188 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
2189   InitializeEmptyExtensionService();
2190 
2191   // Add a crx to be installed from the update mechanism.
2192   service_->pending_extension_manager()->AddFromSync(
2193       kGoodId, GURL(kGoodUpdateURL), &IsExtension,
2194       kGoodInstallSilently, kGoodInitialState,
2195       kGoodInitialIncognitoEnabled);
2196 
2197   // Check that there is a pending crx, with is_from_sync set to true.
2198   PendingExtensionInfo pending_extension_info;
2199   ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2200       kGoodId, &pending_extension_info));
2201   EXPECT_TRUE(pending_extension_info.is_from_sync());
2202 
2203   // Add a crx to be updated, with the same ID, from a non-sync source.
2204   service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2205       kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD);
2206 
2207   // Check that there is a pending crx, with is_from_sync set to false.
2208   ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2209       kGoodId, &pending_extension_info));
2210   EXPECT_FALSE(pending_extension_info.is_from_sync());
2211   EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
2212             pending_extension_info.install_source());
2213 
2214   // Add a crx to be installed from the update mechanism.
2215   service_->pending_extension_manager()->AddFromSync(
2216       kGoodId, GURL(kGoodUpdateURL), &IsExtension,
2217       kGoodInstallSilently, kGoodInitialState,
2218       kGoodInitialIncognitoEnabled);
2219 
2220   // Check that the external, non-sync update was not overridden.
2221   ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2222       kGoodId, &pending_extension_info));
2223   EXPECT_FALSE(pending_extension_info.is_from_sync());
2224   EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
2225             pending_extension_info.install_source());
2226 }
2227 
2228 // Updating a theme should fail if the updater is explicitly told that
2229 // the CRX is not a theme.
TEST_F(ExtensionServiceTest,UpdatePendingCrxThemeMismatch)2230 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
2231   InitializeEmptyExtensionService();
2232   service_->pending_extension_manager()->AddFromSync(
2233       theme_crx, GURL(), &IsExtension,
2234       true, Extension::ENABLED, false);
2235 
2236   EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2237 
2238   FilePath path = data_dir_.AppendASCII("theme.crx");
2239   UpdateExtension(theme_crx, path, FAILED_SILENTLY);
2240 
2241   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2242 
2243   const Extension* extension = service_->GetExtensionById(theme_crx, true);
2244   ASSERT_FALSE(extension);
2245 }
2246 
2247 // TODO(akalin): Test updating a pending extension non-silently once
2248 // we can mock out ExtensionInstallUI and inject our version into
2249 // UpdateExtension().
2250 
2251 // Test updating a pending extension which fails the should-install test.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionFailedShouldInstallTest)2252 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
2253   InitializeEmptyExtensionService();
2254   // Add pending extension with a flipped is_theme.
2255   service_->pending_extension_manager()->AddFromSync(
2256       kGoodId, GURL(kGoodUpdateURL), &IsTheme,
2257       kGoodInstallSilently, kGoodInitialState,
2258       kGoodInitialIncognitoEnabled);
2259   EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2260 
2261   FilePath path = data_dir_.AppendASCII("good.crx");
2262   UpdateExtension(kGoodId, path, UPDATED);
2263 
2264   // TODO(akalin): Figure out how to check that the extensions
2265   // directory is cleaned up properly in OnExtensionInstalled().
2266 
2267   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2268 }
2269 
2270 // TODO(akalin): Figure out how to test that installs of pending
2271 // unsyncable extensions are blocked.
2272 
2273 // Test updating a pending extension for one that is not pending.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionNotPending)2274 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
2275   InitializeEmptyExtensionService();
2276 
2277   FilePath path = data_dir_.AppendASCII("good.crx");
2278   UpdateExtension(kGoodId, path, UPDATED);
2279 
2280   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2281 }
2282 
2283 // Test updating a pending extension for one that is already
2284 // installed.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionAlreadyInstalled)2285 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
2286   InitializeEmptyExtensionService();
2287 
2288   FilePath path = data_dir_.AppendASCII("good.crx");
2289   InstallCrx(path, true);
2290   ASSERT_EQ(1u, service_->extensions()->size());
2291   const Extension* good = service_->extensions()->at(0);
2292 
2293   EXPECT_FALSE(good->is_theme());
2294 
2295   // Use AddExtensionImpl() as AddFrom*() would balk.
2296   service_->pending_extension_manager()->AddExtensionImpl(
2297       good->id(), good->update_url(), &IsExtension,
2298       kGoodIsFromSync, kGoodInstallSilently, kGoodInitialState,
2299       kGoodInitialIncognitoEnabled, Extension::INTERNAL);
2300   UpdateExtension(good->id(), path, INSTALLED);
2301 
2302   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2303 }
2304 
2305 // Test pref settings for blacklist and unblacklist extensions.
TEST_F(ExtensionServiceTest,SetUnsetBlacklistInPrefs)2306 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
2307   InitializeEmptyExtensionService();
2308   std::vector<std::string> blacklist;
2309   blacklist.push_back(good0);
2310   blacklist.push_back("invalid_id");  // an invalid id
2311   blacklist.push_back(good1);
2312   service_->UpdateExtensionBlacklist(blacklist);
2313   // Make sure pref is updated
2314   loop_.RunAllPending();
2315 
2316   // blacklist is set for good0,1,2
2317   ValidateBooleanPref(good0, "blacklist", true);
2318   ValidateBooleanPref(good1, "blacklist", true);
2319   // invalid_id should not be inserted to pref.
2320   EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
2321 
2322   // remove good1, add good2
2323   blacklist.pop_back();
2324   blacklist.push_back(good2);
2325 
2326   service_->UpdateExtensionBlacklist(blacklist);
2327   // only good0 and good1 should be set
2328   ValidateBooleanPref(good0, "blacklist", true);
2329   EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
2330   ValidateBooleanPref(good2, "blacklist", true);
2331   EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
2332 }
2333 
2334 // Unload installed extension from blacklist.
TEST_F(ExtensionServiceTest,UnloadBlacklistedExtension)2335 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) {
2336   InitializeEmptyExtensionService();
2337 
2338   FilePath path = data_dir_.AppendASCII("good.crx");
2339 
2340   InstallCrx(path, true);
2341   const Extension* good = service_->extensions()->at(0);
2342   EXPECT_EQ(good_crx, good->id());
2343   UpdateExtension(good_crx, path, FAILED_SILENTLY);
2344 
2345   std::vector<std::string> blacklist;
2346   blacklist.push_back(good_crx);
2347   service_->UpdateExtensionBlacklist(blacklist);
2348   // Make sure pref is updated
2349   loop_.RunAllPending();
2350 
2351   // Now, the good_crx is blacklisted.
2352   ValidateBooleanPref(good_crx, "blacklist", true);
2353   EXPECT_EQ(0u, service_->extensions()->size());
2354 
2355   // Remove good_crx from blacklist
2356   blacklist.pop_back();
2357   service_->UpdateExtensionBlacklist(blacklist);
2358   // Make sure pref is updated
2359   loop_.RunAllPending();
2360   // blacklist value should not be set for good_crx
2361   EXPECT_FALSE(IsPrefExist(good_crx, "blacklist"));
2362 }
2363 
2364 // Unload installed extension from blacklist.
TEST_F(ExtensionServiceTest,BlacklistedExtensionWillNotInstall)2365 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
2366   InitializeEmptyExtensionService();
2367   std::vector<std::string> blacklist;
2368   blacklist.push_back(good_crx);
2369   service_->UpdateExtensionBlacklist(blacklist);
2370   // Make sure pref is updated
2371   loop_.RunAllPending();
2372 
2373   // Now, the good_crx is blacklisted.
2374   ValidateBooleanPref(good_crx, "blacklist", true);
2375 
2376   // We can not install good_crx.
2377   FilePath path = data_dir_.AppendASCII("good.crx");
2378   StartCrxInstall(path);
2379   loop_.RunAllPending();
2380   EXPECT_EQ(0u, service_->extensions()->size());
2381   ValidateBooleanPref(good_crx, "blacklist", true);
2382 }
2383 
2384 // Test loading extensions from the profile directory, except
2385 // blacklisted ones.
TEST_F(ExtensionServiceTest,WillNotLoadBlacklistedExtensionsFromDirectory)2386 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
2387   // Initialize the test dir with a good Preferences/extensions.
2388   FilePath source_install_dir = data_dir_
2389       .AppendASCII("good")
2390       .AppendASCII("Extensions");
2391   FilePath pref_path = source_install_dir
2392       .DirName()
2393       .AppendASCII("Preferences");
2394   InitializeInstalledExtensionService(pref_path, source_install_dir);
2395 
2396   // Blacklist good1.
2397   std::vector<std::string> blacklist;
2398   blacklist.push_back(good1);
2399   service_->UpdateExtensionBlacklist(blacklist);
2400   // Make sure pref is updated
2401   loop_.RunAllPending();
2402 
2403   ValidateBooleanPref(good1, "blacklist", true);
2404 
2405   // Load extensions.
2406   service_->Init();
2407   loop_.RunAllPending();
2408 
2409   std::vector<std::string> errors = GetErrors();
2410   for (std::vector<std::string>::iterator err = errors.begin();
2411     err != errors.end(); ++err) {
2412     LOG(ERROR) << *err;
2413   }
2414   ASSERT_EQ(2u, loaded_.size());
2415 
2416   EXPECT_NE(std::string(good1), loaded_[0]->id());
2417   EXPECT_NE(std::string(good1), loaded_[1]->id());
2418 }
2419 
2420 // Will not install extension blacklisted by policy.
TEST_F(ExtensionServiceTest,BlacklistedByPolicyWillNotInstall)2421 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
2422   InitializeEmptyExtensionService();
2423 
2424   // Blacklist everything.
2425   {
2426     ListPrefUpdate update(profile_->GetPrefs(),
2427                           prefs::kExtensionInstallDenyList);
2428     ListValue* blacklist = update.Get();
2429     blacklist->Append(Value::CreateStringValue("*"));
2430   }
2431 
2432   // Blacklist prevents us from installing good_crx.
2433   FilePath path = data_dir_.AppendASCII("good.crx");
2434   StartCrxInstall(path);
2435   loop_.RunAllPending();
2436   EXPECT_EQ(0u, service_->extensions()->size());
2437 
2438   // Now whitelist this particular extension.
2439   {
2440     ListPrefUpdate update(profile_->GetPrefs(),
2441                           prefs::kExtensionInstallAllowList);
2442     ListValue* whitelist = update.Get();
2443     whitelist->Append(Value::CreateStringValue(good_crx));
2444   }
2445 
2446 
2447   // Ensure we can now install good_crx.
2448   StartCrxInstall(path);
2449   loop_.RunAllPending();
2450   EXPECT_EQ(1u, service_->extensions()->size());
2451 }
2452 
2453 // Extension blacklisted by policy get unloaded after installing.
TEST_F(ExtensionServiceTest,BlacklistedByPolicyRemovedIfRunning)2454 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
2455   InitializeEmptyExtensionService();
2456 
2457   // Install good_crx.
2458   FilePath path = data_dir_.AppendASCII("good.crx");
2459   StartCrxInstall(path);
2460   loop_.RunAllPending();
2461   EXPECT_EQ(1u, service_->extensions()->size());
2462 
2463   { // Scope for pref update notification.
2464     PrefService* prefs = profile_->GetPrefs();
2465     ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList);
2466     ListValue* blacklist = update.Get();
2467     ASSERT_TRUE(blacklist != NULL);
2468 
2469     // Blacklist this extension.
2470     blacklist->Append(Value::CreateStringValue(good_crx));
2471     prefs->ScheduleSavePersistentPrefs();
2472   }
2473 
2474   // Extension should not be running now.
2475   loop_.RunAllPending();
2476   EXPECT_EQ(0u, service_->extensions()->size());
2477 }
2478 
2479 // Tests disabling extensions
TEST_F(ExtensionServiceTest,DisableExtension)2480 TEST_F(ExtensionServiceTest, DisableExtension) {
2481   InitializeEmptyExtensionService();
2482 
2483   // A simple extension that should install without error.
2484   FilePath path = data_dir_.AppendASCII("good.crx");
2485   InstallCrx(path, true);
2486 
2487   const char* extension_id = good_crx;
2488   EXPECT_FALSE(service_->extensions()->empty());
2489   EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
2490   EXPECT_TRUE(service_->GetExtensionById(extension_id, false) != NULL);
2491   EXPECT_TRUE(service_->disabled_extensions()->empty());
2492 
2493   // Disable it.
2494   service_->DisableExtension(extension_id);
2495 
2496   EXPECT_TRUE(service_->extensions()->empty());
2497   EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
2498   EXPECT_FALSE(service_->GetExtensionById(extension_id, false) != NULL);
2499   EXPECT_FALSE(service_->disabled_extensions()->empty());
2500 }
2501 
2502 // Tests disabling all extensions (simulating --disable-extensions flag).
TEST_F(ExtensionServiceTest,DisableAllExtensions)2503 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
2504   InitializeEmptyExtensionService();
2505 
2506 
2507   FilePath path = data_dir_.AppendASCII("good.crx");
2508   InstallCrx(path, true);
2509 
2510   EXPECT_EQ(1u, service_->extensions()->size());
2511   EXPECT_EQ(0u, service_->disabled_extensions()->size());
2512 
2513   // Disable extensions.
2514   service_->set_extensions_enabled(false);
2515   service_->ReloadExtensions();
2516 
2517   // There shouldn't be extensions in either list.
2518   EXPECT_EQ(0u, service_->extensions()->size());
2519   EXPECT_EQ(0u, service_->disabled_extensions()->size());
2520 
2521   // This shouldn't do anything when all extensions are disabled.
2522   service_->EnableExtension(good_crx);
2523   service_->ReloadExtensions();
2524 
2525   // There still shouldn't be extensions in either list.
2526   EXPECT_EQ(0u, service_->extensions()->size());
2527   EXPECT_EQ(0u, service_->disabled_extensions()->size());
2528 
2529   // And then re-enable the extensions.
2530   service_->set_extensions_enabled(true);
2531   service_->ReloadExtensions();
2532 
2533   EXPECT_EQ(1u, service_->extensions()->size());
2534   EXPECT_EQ(0u, service_->disabled_extensions()->size());
2535 }
2536 
2537 // Tests reloading extensions
TEST_F(ExtensionServiceTest,ReloadExtensions)2538 TEST_F(ExtensionServiceTest, ReloadExtensions) {
2539   InitializeEmptyExtensionService();
2540 
2541   // Simple extension that should install without error.
2542   FilePath path = data_dir_.AppendASCII("good.crx");
2543   InstallCrx(path, true);
2544   const char* extension_id = good_crx;
2545   service_->DisableExtension(extension_id);
2546 
2547   EXPECT_EQ(0u, service_->extensions()->size());
2548   EXPECT_EQ(1u, service_->disabled_extensions()->size());
2549 
2550   service_->ReloadExtensions();
2551 
2552   // Extension counts shouldn't change.
2553   EXPECT_EQ(0u, service_->extensions()->size());
2554   EXPECT_EQ(1u, service_->disabled_extensions()->size());
2555 
2556   service_->EnableExtension(extension_id);
2557 
2558   EXPECT_EQ(1u, service_->extensions()->size());
2559   EXPECT_EQ(0u, service_->disabled_extensions()->size());
2560 
2561   // Need to clear |loaded_| manually before reloading as the
2562   // EnableExtension() call above inserted into it and
2563   // UnloadAllExtensions() doesn't send out notifications.
2564   loaded_.clear();
2565   service_->ReloadExtensions();
2566 
2567   // Extension counts shouldn't change.
2568   EXPECT_EQ(1u, service_->extensions()->size());
2569   EXPECT_EQ(0u, service_->disabled_extensions()->size());
2570 }
2571 
2572 // Tests uninstalling normal extensions
TEST_F(ExtensionServiceTest,UninstallExtension)2573 TEST_F(ExtensionServiceTest, UninstallExtension) {
2574   InitializeEmptyExtensionService();
2575 
2576   // A simple extension that should install without error.
2577   FilePath path = data_dir_.AppendASCII("good.crx");
2578   InstallCrx(path, true);
2579 
2580   // The directory should be there now.
2581   const char* extension_id = good_crx;
2582   FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
2583   EXPECT_TRUE(file_util::PathExists(extension_path));
2584 
2585   ValidatePrefKeyCount(1);
2586   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2587   ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
2588 
2589   // Uninstall it.
2590   service_->UninstallExtension(extension_id, false, NULL);
2591   total_successes_ = 0;
2592 
2593   // We should get an unload notification.
2594   ASSERT_TRUE(unloaded_id_.length());
2595   EXPECT_EQ(extension_id, unloaded_id_);
2596 
2597   ValidatePrefKeyCount(0);
2598 
2599   // The extension should not be in the service anymore.
2600   ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
2601   loop_.RunAllPending();
2602 
2603   // The directory should be gone.
2604   EXPECT_FALSE(file_util::PathExists(extension_path));
2605 }
2606 
2607 // Tests the uninstaller helper.
TEST_F(ExtensionServiceTest,UninstallExtensionHelper)2608 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
2609   InitializeEmptyExtensionService();
2610 
2611   // A simple extension that should install without error.
2612   FilePath path = data_dir_.AppendASCII("good.crx");
2613   InstallCrx(path, true);
2614 
2615   // The directory should be there now.
2616   const char* extension_id = good_crx;
2617   FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
2618   EXPECT_TRUE(file_util::PathExists(extension_path));
2619 
2620   bool result = ExtensionService::UninstallExtensionHelper(service_,
2621                                                            extension_id);
2622   total_successes_ = 0;
2623 
2624   EXPECT_TRUE(result);
2625 
2626   // We should get an unload notification.
2627   ASSERT_TRUE(unloaded_id_.length());
2628   EXPECT_EQ(extension_id, unloaded_id_);
2629 
2630   ValidatePrefKeyCount(0);
2631 
2632   // The extension should not be in the service anymore.
2633   ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
2634   loop_.RunAllPending();
2635 
2636   // The directory should be gone.
2637   EXPECT_FALSE(file_util::PathExists(extension_path));
2638 
2639   // Attempt to uninstall again. This should fail as we just removed the
2640   // extension.
2641   result = ExtensionService::UninstallExtensionHelper(service_, extension_id);
2642   EXPECT_FALSE(result);
2643 }
2644 
2645 // Verifies extension state is removed upon uninstall
TEST_F(ExtensionServiceTest,ClearExtensionData)2646 TEST_F(ExtensionServiceTest, ClearExtensionData) {
2647   InitializeEmptyExtensionService();
2648 
2649   // Load a test extension.
2650   FilePath path = data_dir_;
2651   path = path.AppendASCII("good.crx");
2652   InstallCrx(path, true);
2653   const Extension* extension = service_->GetExtensionById(good_crx, false);
2654   ASSERT_TRUE(extension);
2655   GURL ext_url(extension->url());
2656   string16 origin_id =
2657       webkit_database::DatabaseUtil::GetOriginIdentifier(ext_url);
2658 
2659   // Set a cookie for the extension.
2660   net::CookieMonster* cookie_monster =
2661       profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
2662       cookie_store()->GetCookieMonster();
2663   ASSERT_TRUE(cookie_monster);
2664   net::CookieOptions options;
2665   cookie_monster->SetCookieWithOptions(ext_url, "dummy=value", options);
2666   net::CookieList list = cookie_monster->GetAllCookiesForURL(ext_url);
2667   EXPECT_EQ(1U, list.size());
2668 
2669   // Open a database.
2670   webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
2671   string16 db_name = UTF8ToUTF16("db");
2672   string16 description = UTF8ToUTF16("db_description");
2673   int64 size;
2674   int64 available;
2675   db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size,
2676                              &available);
2677   db_tracker->DatabaseClosed(origin_id, db_name);
2678   std::vector<webkit_database::OriginInfo> origins;
2679   db_tracker->GetAllOriginsInfo(&origins);
2680   EXPECT_EQ(1U, origins.size());
2681   EXPECT_EQ(origin_id, origins[0].GetOrigin());
2682 
2683   // Create local storage. We only simulate this by creating the backing file
2684   // since webkit is not initialized.
2685   DOMStorageContext* context =
2686       profile_->GetWebKitContext()->dom_storage_context();
2687   FilePath lso_path = context->GetLocalStorageFilePath(origin_id);
2688   EXPECT_TRUE(file_util::CreateDirectory(lso_path.DirName()));
2689   EXPECT_EQ(0, file_util::WriteFile(lso_path, NULL, 0));
2690   EXPECT_TRUE(file_util::PathExists(lso_path));
2691 
2692   // Create indexed db. Again, it is enough to only simulate this by creating
2693   // the file on the disk.
2694   IndexedDBContext* idb_context =
2695       profile_->GetWebKitContext()->indexed_db_context();
2696   FilePath idb_path = idb_context->GetIndexedDBFilePath(origin_id);
2697   EXPECT_TRUE(file_util::CreateDirectory(idb_path.DirName()));
2698   EXPECT_EQ(0, file_util::WriteFile(idb_path, NULL, 0));
2699   EXPECT_TRUE(file_util::PathExists(idb_path));
2700 
2701   // Uninstall the extension.
2702   service_->UninstallExtension(good_crx, false, NULL);
2703   loop_.RunAllPending();
2704 
2705   // Check that the cookie is gone.
2706   list = cookie_monster->GetAllCookiesForURL(ext_url);
2707   EXPECT_EQ(0U, list.size());
2708 
2709   // The database should have vanished as well.
2710   origins.clear();
2711   db_tracker->GetAllOriginsInfo(&origins);
2712   EXPECT_EQ(0U, origins.size());
2713 
2714   // Check that the LSO file has been removed.
2715   EXPECT_FALSE(file_util::PathExists(lso_path));
2716 
2717   // Check if the indexed db has disappeared too.
2718   EXPECT_FALSE(file_util::PathExists(idb_path));
2719 }
2720 
2721 // Tests loading single extensions (like --load-extension)
TEST_F(ExtensionServiceTest,LoadExtension)2722 TEST_F(ExtensionServiceTest, LoadExtension) {
2723   InitializeEmptyExtensionService();
2724 
2725   FilePath ext1 = data_dir_
2726       .AppendASCII("good")
2727       .AppendASCII("Extensions")
2728       .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2729       .AppendASCII("1.0.0.0");
2730   service_->LoadExtension(ext1);
2731   loop_.RunAllPending();
2732   EXPECT_EQ(0u, GetErrors().size());
2733   ASSERT_EQ(1u, loaded_.size());
2734   EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2735   EXPECT_EQ(1u, service_->extensions()->size());
2736 
2737   ValidatePrefKeyCount(1);
2738 
2739   FilePath no_manifest = data_dir_
2740       .AppendASCII("bad")
2741       // .AppendASCII("Extensions")
2742       .AppendASCII("cccccccccccccccccccccccccccccccc")
2743       .AppendASCII("1");
2744   service_->LoadExtension(no_manifest);
2745   loop_.RunAllPending();
2746   EXPECT_EQ(1u, GetErrors().size());
2747   ASSERT_EQ(1u, loaded_.size());
2748   EXPECT_EQ(1u, service_->extensions()->size());
2749 
2750   // Test uninstall.
2751   std::string id = loaded_[0]->id();
2752   EXPECT_FALSE(unloaded_id_.length());
2753   service_->UninstallExtension(id, false, NULL);
2754   loop_.RunAllPending();
2755   EXPECT_EQ(id, unloaded_id_);
2756   ASSERT_EQ(0u, loaded_.size());
2757   EXPECT_EQ(0u, service_->extensions()->size());
2758 }
2759 
2760 // Tests that we generate IDs when they are not specified in the manifest for
2761 // --load-extension.
TEST_F(ExtensionServiceTest,GenerateID)2762 TEST_F(ExtensionServiceTest, GenerateID) {
2763   InitializeEmptyExtensionService();
2764 
2765 
2766   FilePath no_id_ext = data_dir_.AppendASCII("no_id");
2767   service_->LoadExtension(no_id_ext);
2768   loop_.RunAllPending();
2769   EXPECT_EQ(0u, GetErrors().size());
2770   ASSERT_EQ(1u, loaded_.size());
2771   ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
2772   EXPECT_EQ(loaded_[0]->location(), Extension::LOAD);
2773 
2774   ValidatePrefKeyCount(1);
2775 
2776   std::string previous_id = loaded_[0]->id();
2777 
2778   // If we reload the same path, we should get the same extension ID.
2779   service_->LoadExtension(no_id_ext);
2780   loop_.RunAllPending();
2781   ASSERT_EQ(1u, loaded_.size());
2782   ASSERT_EQ(previous_id, loaded_[0]->id());
2783 }
2784 
TestExternalProvider(MockExtensionProvider * provider,Extension::Location location)2785 void ExtensionServiceTest::TestExternalProvider(
2786     MockExtensionProvider* provider, Extension::Location location) {
2787   // Verify that starting with no providers loads no extensions.
2788   service_->Init();
2789   loop_.RunAllPending();
2790   ASSERT_EQ(0u, loaded_.size());
2791 
2792   provider->set_visit_count(0);
2793 
2794   // Register a test extension externally using the mock registry provider.
2795   FilePath source_path = data_dir_.AppendASCII("good.crx");
2796 
2797   // Add the extension.
2798   provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
2799 
2800   // Reloading extensions should find our externally registered extension
2801   // and install it.
2802   service_->CheckForExternalUpdates();
2803   loop_.RunAllPending();
2804 
2805   ASSERT_EQ(0u, GetErrors().size());
2806   ASSERT_EQ(1u, loaded_.size());
2807   ASSERT_EQ(location, loaded_[0]->location());
2808   ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
2809   ValidatePrefKeyCount(1);
2810   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2811   ValidateIntegerPref(good_crx, "location", location);
2812 
2813   // Reload extensions without changing anything. The extension should be
2814   // loaded again.
2815   loaded_.clear();
2816   service_->ReloadExtensions();
2817   loop_.RunAllPending();
2818   ASSERT_EQ(0u, GetErrors().size());
2819   ASSERT_EQ(1u, loaded_.size());
2820   ValidatePrefKeyCount(1);
2821   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2822   ValidateIntegerPref(good_crx, "location", location);
2823 
2824   // Now update the extension with a new version. We should get upgraded.
2825   source_path = source_path.DirName().AppendASCII("good2.crx");
2826   provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
2827 
2828   loaded_.clear();
2829   service_->CheckForExternalUpdates();
2830   loop_.RunAllPending();
2831   ASSERT_EQ(0u, GetErrors().size());
2832   ASSERT_EQ(1u, loaded_.size());
2833   ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
2834   ValidatePrefKeyCount(1);
2835   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2836   ValidateIntegerPref(good_crx, "location", location);
2837 
2838   // Uninstall the extension and reload. Nothing should happen because the
2839   // preference should prevent us from reinstalling.
2840   std::string id = loaded_[0]->id();
2841   service_->UninstallExtension(id, false, NULL);
2842   loop_.RunAllPending();
2843 
2844   FilePath install_path = extensions_install_dir_.AppendASCII(id);
2845   // It should not be possible to uninstall a policy controlled extension.
2846   if (Extension::UserMayDisable(location)) {
2847     // The extension should also be gone from the install directory.
2848     ASSERT_FALSE(file_util::PathExists(install_path));
2849     loaded_.clear();
2850     service_->CheckForExternalUpdates();
2851     loop_.RunAllPending();
2852     ASSERT_EQ(0u, loaded_.size());
2853     ValidatePrefKeyCount(1);
2854     ValidateIntegerPref(good_crx, "state",
2855                         Extension::EXTERNAL_EXTENSION_UNINSTALLED);
2856     ValidateIntegerPref(good_crx, "location", location);
2857 
2858     // Now clear the preference and reinstall.
2859     SetPrefInteg(good_crx, "state", Extension::ENABLED);
2860     profile_->GetPrefs()->ScheduleSavePersistentPrefs();
2861 
2862     loaded_.clear();
2863     service_->CheckForExternalUpdates();
2864     loop_.RunAllPending();
2865     ASSERT_EQ(1u, loaded_.size());
2866   } else {
2867     // Policy controlled extesions should not have been touched by uninstall.
2868     ASSERT_TRUE(file_util::PathExists(install_path));
2869   }
2870   ValidatePrefKeyCount(1);
2871   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2872   ValidateIntegerPref(good_crx, "location", location);
2873 
2874   if (Extension::UserMayDisable(location)) {
2875     // Now test an externally triggered uninstall (deleting the registry key or
2876     // the pref entry).
2877     provider->RemoveExtension(good_crx);
2878 
2879     loaded_.clear();
2880     service_->OnExternalProviderReady();
2881     loop_.RunAllPending();
2882     ASSERT_EQ(0u, loaded_.size());
2883     ValidatePrefKeyCount(0);
2884 
2885     // The extension should also be gone from the install directory.
2886     ASSERT_FALSE(file_util::PathExists(install_path));
2887 
2888     // Now test the case where user uninstalls and then the extension is removed
2889     // from the external provider.
2890 
2891   provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
2892     service_->CheckForExternalUpdates();
2893     loop_.RunAllPending();
2894 
2895     ASSERT_EQ(1u, loaded_.size());
2896     ASSERT_EQ(0u, GetErrors().size());
2897 
2898     // User uninstalls.
2899     loaded_.clear();
2900     service_->UninstallExtension(id, false, NULL);
2901     loop_.RunAllPending();
2902     ASSERT_EQ(0u, loaded_.size());
2903 
2904     // Then remove the extension from the extension provider.
2905     provider->RemoveExtension(good_crx);
2906 
2907     // Should still be at 0.
2908     loaded_.clear();
2909     service_->LoadAllExtensions();
2910     loop_.RunAllPending();
2911     ASSERT_EQ(0u, loaded_.size());
2912     ValidatePrefKeyCount(1);
2913 
2914     EXPECT_EQ(5, provider->visit_count());
2915   } else {
2916     EXPECT_EQ(2, provider->visit_count());
2917   }
2918 }
2919 
2920 // Tests the external installation feature
2921 #if defined(OS_WIN)
TEST_F(ExtensionServiceTest,ExternalInstallRegistry)2922 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
2923   // This should all work, even when normal extension installation is disabled.
2924   InitializeEmptyExtensionService();
2925   set_extensions_enabled(false);
2926 
2927   // Now add providers. Extension system takes ownership of the objects.
2928   MockExtensionProvider* reg_provider =
2929       new MockExtensionProvider(service_.get(), Extension::EXTERNAL_REGISTRY);
2930   AddMockExternalProvider(reg_provider);
2931   TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
2932 }
2933 #endif
2934 
TEST_F(ExtensionServiceTest,ExternalInstallPref)2935 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
2936   InitializeEmptyExtensionService();
2937 
2938   // Now add providers. Extension system takes ownership of the objects.
2939   MockExtensionProvider* pref_provider =
2940       new MockExtensionProvider(service_.get(), Extension::EXTERNAL_PREF);
2941 
2942   AddMockExternalProvider(pref_provider);
2943   TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
2944 }
2945 
TEST_F(ExtensionServiceTest,ExternalInstallPrefUpdateUrl)2946 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
2947   // This should all work, even when normal extension installation is disabled.
2948   InitializeEmptyExtensionService();
2949   set_extensions_enabled(false);
2950 
2951   // TODO(skerner): The mock provider is not a good model of a provider
2952   // that works with update URLs, because it adds file and version info.
2953   // Extend the mock to work with update URLs.  This test checks the
2954   // behavior that is common to all external extension visitors.  The
2955   // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
2956   // what the visitor does results in an extension being downloaded and
2957   // installed.
2958   MockExtensionProvider* pref_provider =
2959       new MockExtensionProvider(service_.get(),
2960                                 Extension::EXTERNAL_PREF_DOWNLOAD);
2961   AddMockExternalProvider(pref_provider);
2962   TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF_DOWNLOAD);
2963 }
2964 
TEST_F(ExtensionServiceTest,ExternalInstallPolicyUpdateUrl)2965 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
2966   // This should all work, even when normal extension installation is disabled.
2967   InitializeEmptyExtensionService();
2968   set_extensions_enabled(false);
2969 
2970   // TODO(skerner): The mock provider is not a good model of a provider
2971   // that works with update URLs, because it adds file and version info.
2972   // Extend the mock to work with update URLs. This test checks the
2973   // behavior that is common to all external extension visitors. The
2974   // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
2975   // what the visitor does results in an extension being downloaded and
2976   // installed.
2977   MockExtensionProvider* pref_provider =
2978       new MockExtensionProvider(service_.get(),
2979                                 Extension::EXTERNAL_POLICY_DOWNLOAD);
2980   AddMockExternalProvider(pref_provider);
2981   TestExternalProvider(pref_provider, Extension::EXTERNAL_POLICY_DOWNLOAD);
2982 }
2983 
2984 // Tests that external extensions get uninstalled when the external extension
2985 // providers can't account for them.
TEST_F(ExtensionServiceTest,ExternalUninstall)2986 TEST_F(ExtensionServiceTest, ExternalUninstall) {
2987   // Start the extensions service with one external extension already installed.
2988   FilePath source_install_dir = data_dir_
2989       .AppendASCII("good")
2990       .AppendASCII("Extensions");
2991   FilePath pref_path = source_install_dir
2992       .DirName()
2993       .AppendASCII("PreferencesExternal");
2994 
2995   // This initializes the extensions service with no ExternalExtensionProviders.
2996   InitializeInstalledExtensionService(pref_path, source_install_dir);
2997   set_extensions_enabled(false);
2998 
2999   service_->Init();
3000   loop_.RunAllPending();
3001 
3002   ASSERT_EQ(0u, GetErrors().size());
3003   ASSERT_EQ(0u, loaded_.size());
3004 
3005   // Verify that it's not the disabled extensions flag causing it not to load.
3006   set_extensions_enabled(true);
3007   service_->ReloadExtensions();
3008   loop_.RunAllPending();
3009 
3010   ASSERT_EQ(0u, GetErrors().size());
3011   ASSERT_EQ(0u, loaded_.size());
3012 }
3013 
3014 // Test that running multiple update checks simultaneously does not
3015 // keep the update from succeeding.
TEST_F(ExtensionServiceTest,MultipleExternalUpdateCheck)3016 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
3017   InitializeEmptyExtensionService();
3018 
3019   MockExtensionProvider* provider =
3020       new MockExtensionProvider(service_.get(), Extension::EXTERNAL_PREF);
3021   AddMockExternalProvider(provider);
3022 
3023   // Verify that starting with no providers loads no extensions.
3024   service_->Init();
3025   loop_.RunAllPending();
3026   ASSERT_EQ(0u, loaded_.size());
3027 
3028   // Start two checks for updates.
3029   provider->set_visit_count(0);
3030   service_->CheckForExternalUpdates();
3031   service_->CheckForExternalUpdates();
3032   loop_.RunAllPending();
3033 
3034   // Two calls should cause two checks for external extensions.
3035   EXPECT_EQ(2, provider->visit_count());
3036   EXPECT_EQ(0u, GetErrors().size());
3037   EXPECT_EQ(0u, loaded_.size());
3038 
3039   // Register a test extension externally using the mock registry provider.
3040   FilePath source_path = data_dir_.AppendASCII("good.crx");
3041   provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
3042 
3043   // Two checks for external updates should find the extension, and install it
3044   // once.
3045   provider->set_visit_count(0);
3046   service_->CheckForExternalUpdates();
3047   service_->CheckForExternalUpdates();
3048   loop_.RunAllPending();
3049   EXPECT_EQ(2, provider->visit_count());
3050   ASSERT_EQ(0u, GetErrors().size());
3051   ASSERT_EQ(1u, loaded_.size());
3052   ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location());
3053   ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
3054   ValidatePrefKeyCount(1);
3055   ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
3056   ValidateIntegerPref(good_crx, "location", Extension::EXTERNAL_PREF);
3057 
3058   provider->RemoveExtension(good_crx);
3059   provider->set_visit_count(0);
3060   service_->CheckForExternalUpdates();
3061   service_->CheckForExternalUpdates();
3062   loop_.RunAllPending();
3063 
3064   // Two calls should cause two checks for external extensions.
3065   // Because the external source no longer includes good_crx,
3066   // good_crx will be uninstalled.  So, expect that no extensions
3067   // are loaded.
3068   EXPECT_EQ(2, provider->visit_count());
3069   EXPECT_EQ(0u, GetErrors().size());
3070   EXPECT_EQ(0u, loaded_.size());
3071 }
3072 
TEST_F(ExtensionServiceTest,ExternalPrefProvider)3073 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
3074   InitializeEmptyExtensionService();
3075 
3076   // Test some valid extension records.
3077   // Set a base path to avoid erroring out on relative paths.
3078   // Paths starting with // are absolute on every platform we support.
3079   FilePath base_path(FILE_PATH_LITERAL("//base/path"));
3080   ASSERT_TRUE(base_path.IsAbsolute());
3081   MockProviderVisitor visitor(base_path);
3082   std::string json_data =
3083       "{"
3084       "  \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
3085       "    \"external_crx\": \"RandomExtension.crx\","
3086       "    \"external_version\": \"1.0\""
3087       "  },"
3088       "  \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
3089       "    \"external_crx\": \"RandomExtension2.crx\","
3090       "    \"external_version\": \"2.0\""
3091       "  },"
3092       "  \"cccccccccccccccccccccccccccccccc\": {"
3093       "    \"external_update_url\": \"http:\\\\foo.com/update\""
3094       "  }"
3095       "}";
3096   EXPECT_EQ(3, visitor.Visit(json_data));
3097 
3098   // Simulate an external_extensions.json file that contains seven invalid
3099   // records:
3100   // - One that is missing the 'external_crx' key.
3101   // - One that is missing the 'external_version' key.
3102   // - One that is specifying .. in the path.
3103   // - One that specifies both a file and update URL.
3104   // - One that specifies no file or update URL.
3105   // - One that has an update URL that is not well formed.
3106   // - One that contains a malformed version.
3107   // - One that has an invalid id.
3108   // - One that has a non-dictionary value.
3109   // The final extension is valid, and we check that it is read to make sure
3110   // failures don't stop valid records from being read.
3111   json_data =
3112       "{"
3113       "  \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
3114       "    \"external_version\": \"1.0\""
3115       "  },"
3116       "  \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
3117       "    \"external_crx\": \"RandomExtension.crx\""
3118       "  },"
3119       "  \"cccccccccccccccccccccccccccccccc\": {"
3120       "    \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
3121       "    \"external_version\": \"2.0\""
3122       "  },"
3123       "  \"dddddddddddddddddddddddddddddddd\": {"
3124       "    \"external_crx\": \"RandomExtension2.crx\","
3125       "    \"external_version\": \"2.0\","
3126       "    \"external_update_url\": \"http:\\\\foo.com/update\""
3127       "  },"
3128       "  \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
3129       "  },"
3130       "  \"ffffffffffffffffffffffffffffffff\": {"
3131       "    \"external_update_url\": \"This string is not a valid URL\""
3132       "  },"
3133       "  \"gggggggggggggggggggggggggggggggg\": {"
3134       "    \"external_crx\": \"RandomExtension3.crx\","
3135       "    \"external_version\": \"This is not a valid version!\""
3136       "  },"
3137       "  \"This is not a valid id!\": {},"
3138       "  \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
3139       "  \"pppppppppppppppppppppppppppppppp\": {"
3140       "    \"external_crx\": \"RandomValidExtension.crx\","
3141       "    \"external_version\": \"1.0\""
3142       "  }"
3143       "}";
3144   EXPECT_EQ(1, visitor.Visit(json_data));
3145 
3146   // Check that if a base path is not provided, use of a relative
3147   // path fails.
3148   FilePath empty;
3149   MockProviderVisitor visitor_no_relative_paths(empty);
3150 
3151   // Use absolute paths.  Expect success.
3152   json_data =
3153       "{"
3154       "  \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
3155       "    \"external_crx\": \"//RandomExtension1.crx\","
3156       "    \"external_version\": \"3.0\""
3157       "  },"
3158       "  \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
3159       "    \"external_crx\": \"//path/to/RandomExtension2.crx\","
3160       "    \"external_version\": \"3.0\""
3161       "  }"
3162       "}";
3163   EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
3164 
3165   // Use a relative path.  Expect that it will error out.
3166   json_data =
3167       "{"
3168       "  \"cccccccccccccccccccccccccccccccc\": {"
3169       "    \"external_crx\": \"RandomExtension2.crx\","
3170       "    \"external_version\": \"3.0\""
3171       "  }"
3172       "}";
3173   EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
3174 }
3175 
3176 // Test loading good extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAndRelocalizeExtensions)3177 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
3178   // Initialize the test dir with a good Preferences/extensions.
3179   FilePath source_install_dir = data_dir_
3180       .AppendASCII("l10n");
3181   FilePath pref_path = source_install_dir.AppendASCII("Preferences");
3182   InitializeInstalledExtensionService(pref_path, source_install_dir);
3183 
3184   service_->Init();
3185   loop_.RunAllPending();
3186 
3187   ASSERT_EQ(3u, loaded_.size());
3188 
3189   // This was equal to "sr" on load.
3190   ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
3191 
3192   // These are untouched by re-localization.
3193   ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
3194   EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
3195 
3196   // This one starts with Serbian name, and gets re-localized into English.
3197   EXPECT_EQ("My name is simple.", loaded_[0]->name());
3198 
3199   // These are untouched by re-localization.
3200   EXPECT_EQ("My name is simple.", loaded_[1]->name());
3201   EXPECT_EQ("no l10n", loaded_[2]->name());
3202 }
3203 
3204 class ExtensionsReadyRecorder : public NotificationObserver {
3205  public:
ExtensionsReadyRecorder()3206   ExtensionsReadyRecorder() : ready_(false) {
3207     registrar_.Add(this, NotificationType::EXTENSIONS_READY,
3208                    NotificationService::AllSources());
3209   }
3210 
set_ready(bool value)3211   void set_ready(bool value) { ready_ = value; }
ready()3212   bool ready() { return ready_; }
3213 
3214  private:
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)3215   virtual void Observe(NotificationType type,
3216                        const NotificationSource& source,
3217                        const NotificationDetails& details) {
3218     switch (type.value) {
3219       case NotificationType::EXTENSIONS_READY:
3220         ready_ = true;
3221         break;
3222       default:
3223         NOTREACHED();
3224     }
3225   }
3226 
3227   NotificationRegistrar registrar_;
3228   bool ready_;
3229 };
3230 
3231 // Test that we get enabled/disabled correctly for all the pref/command-line
3232 // combinations. We don't want to derive from the ExtensionServiceTest class
3233 // for this test, so we use ExtensionServiceTestSimple.
3234 //
3235 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
3236 // enabled or not.
TEST(ExtensionServiceTestSimple,Enabledness)3237 TEST(ExtensionServiceTestSimple, Enabledness) {
3238   ExtensionsReadyRecorder recorder;
3239   scoped_ptr<TestingProfile> profile(new TestingProfile());
3240   MessageLoop loop;
3241   BrowserThread ui_thread(BrowserThread::UI, &loop);
3242   BrowserThread file_thread(BrowserThread::FILE, &loop);
3243   scoped_ptr<CommandLine> command_line;
3244   scoped_refptr<ExtensionService> service;
3245   FilePath install_dir = profile->GetPath()
3246       .AppendASCII(ExtensionService::kInstallDirectoryName);
3247 
3248   // By default, we are enabled.
3249   command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
3250   service = profile->CreateExtensionService(command_line.get(),
3251                                             install_dir,
3252                                             false);
3253   EXPECT_TRUE(service->extensions_enabled());
3254   service->Init();
3255   loop.RunAllPending();
3256   EXPECT_TRUE(recorder.ready());
3257 
3258   // If either the command line or pref is set, we are disabled.
3259   recorder.set_ready(false);
3260   profile.reset(new TestingProfile());
3261   command_line->AppendSwitch(switches::kDisableExtensions);
3262   service = profile->CreateExtensionService(command_line.get(),
3263                                             install_dir,
3264                                             false);
3265   EXPECT_FALSE(service->extensions_enabled());
3266   service->Init();
3267   loop.RunAllPending();
3268   EXPECT_TRUE(recorder.ready());
3269 
3270   recorder.set_ready(false);
3271   profile.reset(new TestingProfile());
3272   profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
3273   service = profile->CreateExtensionService(command_line.get(),
3274                                             install_dir,
3275                                             false);
3276   EXPECT_FALSE(service->extensions_enabled());
3277   service->Init();
3278   loop.RunAllPending();
3279   EXPECT_TRUE(recorder.ready());
3280 
3281   recorder.set_ready(false);
3282   profile.reset(new TestingProfile());
3283   profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
3284   command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
3285   service = profile->CreateExtensionService(command_line.get(),
3286                                             install_dir,
3287                                             false);
3288   EXPECT_FALSE(service->extensions_enabled());
3289   service->Init();
3290   loop.RunAllPending();
3291   EXPECT_TRUE(recorder.ready());
3292 
3293   // Explicitly delete all the resources used in this test.
3294   profile.reset();
3295   service = NULL;
3296 }
3297 
3298 // Test loading extensions that require limited and unlimited storage quotas.
TEST_F(ExtensionServiceTest,StorageQuota)3299 TEST_F(ExtensionServiceTest, StorageQuota) {
3300   InitializeEmptyExtensionService();
3301 
3302   FilePath extensions_path = data_dir_
3303       .AppendASCII("storage_quota");
3304 
3305   FilePath limited_quota_ext =
3306       extensions_path.AppendASCII("limited_quota")
3307       .AppendASCII("1.0");
3308 
3309   // The old permission name for unlimited quota was "unlimited_storage", but
3310   // we changed it to "unlimitedStorage". This tests both versions.
3311   FilePath unlimited_quota_ext =
3312       extensions_path.AppendASCII("unlimited_quota")
3313       .AppendASCII("1.0");
3314   FilePath unlimited_quota_ext2 =
3315       extensions_path.AppendASCII("unlimited_quota")
3316       .AppendASCII("2.0");
3317   service_->LoadExtension(limited_quota_ext);
3318   service_->LoadExtension(unlimited_quota_ext);
3319   service_->LoadExtension(unlimited_quota_ext2);
3320   loop_.RunAllPending();
3321 
3322   ASSERT_EQ(3u, loaded_.size());
3323   EXPECT_TRUE(profile_.get());
3324   EXPECT_FALSE(profile_->IsOffTheRecord());
3325 
3326   // Open the database from each origin to make the tracker aware
3327   // of the existence of these origins and to get their quotas.
3328   int64 limited_quota = -1;
3329   int64 unlimited_quota = -1;
3330   string16 limited_quota_identifier =
3331       webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[0]->url());
3332   string16 unlimited_quota_identifier =
3333       webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[1]->url());
3334   string16 unlimited_quota_identifier2 =
3335       webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[2]->url());
3336   string16 db_name = UTF8ToUTF16("db");
3337   string16 description = UTF8ToUTF16("db_description");
3338   int64 database_size;
3339   webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
3340 
3341   // First check the normal limited quota extension.
3342   db_tracker->DatabaseOpened(limited_quota_identifier, db_name, description,
3343                              1, &database_size, &limited_quota);
3344   db_tracker->DatabaseClosed(limited_quota_identifier, db_name);
3345   EXPECT_EQ(profile_->GetDatabaseTracker()->GetDefaultQuota(), limited_quota);
3346 
3347   // Now check the two unlimited quota ones.
3348   db_tracker->DatabaseOpened(unlimited_quota_identifier, db_name, description,
3349                              1, &database_size, &unlimited_quota);
3350   db_tracker->DatabaseClosed(unlimited_quota_identifier, db_name);
3351   EXPECT_EQ(kint64max, unlimited_quota);
3352   db_tracker->DatabaseOpened(unlimited_quota_identifier2, db_name, description,
3353                              1, &database_size, &unlimited_quota);
3354   db_tracker->DatabaseClosed(unlimited_quota_identifier2, db_name);
3355 
3356   EXPECT_EQ(kint64max, unlimited_quota);
3357 }
3358 
3359 // Tests ExtensionService::register_component_extension().
TEST_F(ExtensionServiceTest,ComponentExtensions)3360 TEST_F(ExtensionServiceTest, ComponentExtensions) {
3361   InitializeEmptyExtensionService();
3362 
3363   // Component extensions should work even when extensions are disabled.
3364   set_extensions_enabled(false);
3365 
3366   FilePath path = data_dir_
3367       .AppendASCII("good")
3368       .AppendASCII("Extensions")
3369       .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
3370       .AppendASCII("1.0.0.0");
3371 
3372   std::string manifest;
3373   ASSERT_TRUE(file_util::ReadFileToString(
3374       path.Append(Extension::kManifestFilename), &manifest));
3375 
3376   service_->register_component_extension(
3377       ExtensionService::ComponentExtensionInfo(manifest, path));
3378   service_->Init();
3379 
3380   // Note that we do not pump messages -- the extension should be loaded
3381   // immediately.
3382 
3383   EXPECT_EQ(0u, GetErrors().size());
3384   ASSERT_EQ(1u, loaded_.size());
3385   EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location());
3386   EXPECT_EQ(1u, service_->extensions()->size());
3387 
3388   // Component extensions shouldn't get recourded in the prefs.
3389   ValidatePrefKeyCount(0);
3390 
3391   // Reload all extensions, and make sure it comes back.
3392   std::string extension_id = service_->extensions()->at(0)->id();
3393   loaded_.clear();
3394   service_->ReloadExtensions();
3395   ASSERT_EQ(1u, service_->extensions()->size());
3396   EXPECT_EQ(extension_id, service_->extensions()->at(0)->id());
3397 }
3398 
3399 namespace {
3400 
AlwaysInstall(const Extension & extension)3401 bool AlwaysInstall(const Extension& extension) {
3402   return true;
3403 }
3404 
3405 }  // namespace
3406 
TEST_F(ExtensionServiceTest,ProcessSyncDataUninstall)3407 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
3408   InitializeEmptyExtensionService();
3409 
3410   ExtensionSyncData extension_sync_data;
3411   extension_sync_data.id = good_crx;
3412   extension_sync_data.uninstalled = true;
3413 
3414   // Should do nothing.
3415   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3416 
3417   // Install the extension.
3418   FilePath extension_path = data_dir_.AppendASCII("good.crx");
3419   InstallCrx(extension_path, true);
3420   EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3421 
3422   // Should uninstall the extension.
3423   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3424   EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
3425 
3426   // Should again do nothing.
3427   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3428 }
3429 
3430 
TEST_F(ExtensionServiceTest,ProcessSyncDataSettings)3431 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
3432   InitializeEmptyExtensionService();
3433 
3434   FilePath extension_path = data_dir_.AppendASCII("good.crx");
3435   InstallCrx(extension_path, true);
3436   EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3437   EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3438 
3439   ExtensionSyncData extension_sync_data;
3440   extension_sync_data.id = good_crx;
3441   extension_sync_data.version =
3442       *(service_->GetExtensionById(good_crx, true)->version());
3443 
3444   extension_sync_data.enabled = false;
3445   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3446   EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
3447   EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3448 
3449   extension_sync_data.enabled = true;
3450   extension_sync_data.incognito_enabled = true;
3451   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3452   EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3453   EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
3454 
3455   extension_sync_data.enabled = false;
3456   extension_sync_data.incognito_enabled = true;
3457   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3458   EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
3459   EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
3460 
3461   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
3462 }
3463 
TEST_F(ExtensionServiceTest,ProcessSyncDataVersionCheck)3464 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
3465   InitializeExtensionServiceWithUpdater();
3466 
3467   // Install the extension.
3468   FilePath extension_path = data_dir_.AppendASCII("good.crx");
3469   InstallCrx(extension_path, true);
3470   EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3471   EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3472 
3473   ExtensionSyncData extension_sync_data;
3474   extension_sync_data.id = good_crx;
3475   extension_sync_data.enabled = true;
3476   extension_sync_data.version =
3477       *(service_->GetExtensionById(good_crx, true)->version());
3478 
3479   // Should do nothing if extension version == sync version.
3480   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3481   EXPECT_FALSE(service_->updater()->WillCheckSoon());
3482 
3483   // Should do nothing if extension version > sync version (but see
3484   // the TODO in ProcessSyncData).
3485   {
3486     scoped_ptr<Version> version(Version::GetVersionFromString("0.0.0.0"));
3487     extension_sync_data.version = *version;
3488     service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3489     EXPECT_FALSE(service_->updater()->WillCheckSoon());
3490   }
3491 
3492   // Should kick off an update if extension version < sync version.
3493   {
3494     scoped_ptr<Version> version(Version::GetVersionFromString("9.9.9.9"));
3495     extension_sync_data.version = *version;
3496     service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3497     EXPECT_TRUE(service_->updater()->WillCheckSoon());
3498   }
3499 
3500   EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
3501 }
3502 
TEST_F(ExtensionServiceTest,ProcessSyncDataNotInstalled)3503 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
3504   InitializeExtensionServiceWithUpdater();
3505 
3506   ExtensionSyncData extension_sync_data;
3507   extension_sync_data.id = good_crx;
3508   extension_sync_data.update_url = GURL("http://www.google.com");
3509   extension_sync_data.enabled = true;
3510   {
3511     scoped_ptr<Version> version(Version::GetVersionFromString("1.2.3.4"));
3512     extension_sync_data.version = *version;
3513   }
3514 
3515   service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3516   EXPECT_TRUE(service_->updater()->WillCheckSoon());
3517 
3518   PendingExtensionInfo info;
3519   EXPECT_TRUE(
3520       service_->pending_extension_manager()->GetById(good_crx, &info));
3521   EXPECT_EQ(extension_sync_data.update_url, info.update_url());
3522   EXPECT_TRUE(info.is_from_sync());
3523   EXPECT_TRUE(info.install_silently());
3524   EXPECT_EQ(extension_sync_data.enabled, info.enable_on_install());
3525   EXPECT_EQ(extension_sync_data.incognito_enabled,
3526             info.enable_incognito_on_install());
3527   EXPECT_EQ(Extension::INTERNAL, info.install_source());
3528   // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
3529 }
3530 
3531 // Test that when multiple sources try to install an extension,
3532 // we consistently choose the right one. To make tests easy to read,
3533 // methods that fake requests to install crx files in several ways
3534 // are provided.
3535 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
3536  public:
SetUp()3537   void SetUp() {
3538     // All tests use a single extension.  Put the id and path in member vars
3539     // that all methods can read.
3540     crx_id_ = kGoodId;
3541     crx_path_ = data_dir_.AppendASCII("good.crx");
3542   }
3543 
3544   // Fake an external source adding a URL to fetch an extension from.
AddPendingExternalPrefUrl()3545   void AddPendingExternalPrefUrl() {
3546     service_->pending_extension_manager()->AddFromExternalUpdateUrl(
3547         crx_id_, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
3548   }
3549 
3550   // Fake an external file from external_extensions.json.
AddPendingExternalPrefFileInstall()3551   void AddPendingExternalPrefFileInstall() {
3552     scoped_ptr<Version> version;
3553     version.reset(Version::GetVersionFromString("1.0.0.0"));
3554 
3555     service_->OnExternalExtensionFileFound(
3556         crx_id_, version.get(), crx_path_, Extension::EXTERNAL_PREF);
3557   }
3558 
3559   // Fake a request from sync to install an extension.
AddPendingSyncInstall()3560   bool AddPendingSyncInstall() {
3561     return service_->pending_extension_manager()->AddFromSync(
3562         crx_id_, GURL(kGoodUpdateURL), &IsExtension,
3563         kGoodInstallSilently, kGoodInitialState,
3564         kGoodInitialIncognitoEnabled);
3565   }
3566 
3567   // Fake a request to install a default app.
AddPendingDefaultAppInstall()3568   void AddPendingDefaultAppInstall() {
3569     service_->pending_extension_manager()->AddFromDefaultAppList(crx_id_);
3570   }
3571 
3572   // Fake a policy install.
AddPendingPolicyInstall()3573   void AddPendingPolicyInstall() {
3574     scoped_ptr<Version> version;
3575     version.reset(Version::GetVersionFromString("1.0.0.0"));
3576 
3577     // Get path to the CRX with id |kGoodId|.
3578     service_->OnExternalExtensionUpdateUrlFound(
3579         crx_id_, GURL(), Extension::EXTERNAL_POLICY_DOWNLOAD);
3580   }
3581 
3582   // Get the install source of a pending extension.
GetPendingLocation()3583   Extension::Location GetPendingLocation() {
3584     PendingExtensionInfo info;
3585     EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info));
3586     return info.install_source();
3587   }
3588 
3589   // Is an extension pending from a sync request?
GetPendingIsFromSync()3590   bool GetPendingIsFromSync() {
3591     PendingExtensionInfo info;
3592     EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info));
3593     return info.is_from_sync();
3594   }
3595 
3596   // Is the CRX id these tests use pending?
IsCrxPending()3597   bool IsCrxPending() {
3598     return service_->pending_extension_manager()->IsIdPending(crx_id_);
3599   }
3600 
3601   // Is an extension installed?
IsCrxInstalled()3602   bool IsCrxInstalled() {
3603     return (service_->GetExtensionById(crx_id_, true) != NULL);
3604   }
3605 
3606  protected:
3607   // All tests use a single extension.  Making the id and path member
3608   // vars avoids pasing the same argument to every method.
3609   std::string crx_id_;
3610   FilePath crx_path_;
3611 };
3612 
3613 #if defined(OS_CHROMEOS)
3614 // TODO(skerner): crbug/79755
3615 #define MAYBE_PendingExternalFileOverSync DISABLED_PendingExternalFileOverSync
3616 #else
3617 #define MAYBE_PendingExternalFileOverSync PendingExternalFileOverSync
3618 #endif
3619 // Test that a pending request for installation of an external CRX from
3620 // an update URL overrides a pending request to install the same extension
3621 // from sync.
TEST_F(ExtensionSourcePriorityTest,MAYBE_PendingExternalFileOverSync)3622 TEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalFileOverSync) {
3623   InitializeEmptyExtensionService();
3624 
3625   ASSERT_FALSE(IsCrxInstalled());
3626 
3627   // Install pending extension from sync.
3628   AddPendingSyncInstall();
3629   ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3630   EXPECT_TRUE(GetPendingIsFromSync());
3631   ASSERT_FALSE(IsCrxInstalled());
3632 
3633   // Install pending as external prefs json would.
3634   AddPendingExternalPrefFileInstall();
3635   ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3636   ASSERT_FALSE(IsCrxInstalled());
3637 
3638   // Another request from sync should be ignorred.
3639   AddPendingSyncInstall();
3640   ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3641   ASSERT_FALSE(IsCrxInstalled());
3642 
3643   WaitForCrxInstall(crx_path_, true);
3644   ASSERT_TRUE(IsCrxInstalled());
3645 }
3646 
3647 #if defined(OS_CHROMEOS)
3648 // TODO(skerner): crbug/79755
3649 #define MAYBE_PendingExternalUrlOverSync DISABLED_PendingExternalUrlOverSync
3650 #else
3651 #define MAYBE_PendingExternalUrlOverSync PendingExternalUrlOverSync
3652 #endif
3653 // Test that an install of an external CRX from an update overrides
3654 // an install of the same extension from sync.
TEST_F(ExtensionSourcePriorityTest,MAYBE_PendingExternalUrlOverSync)3655 TEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalUrlOverSync) {
3656   InitializeEmptyExtensionService();
3657   ASSERT_FALSE(IsCrxInstalled());
3658 
3659   AddPendingSyncInstall();
3660   ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3661   EXPECT_TRUE(GetPendingIsFromSync());
3662   ASSERT_FALSE(IsCrxInstalled());
3663 
3664   AddPendingExternalPrefUrl();
3665   ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
3666   EXPECT_FALSE(GetPendingIsFromSync());
3667   ASSERT_FALSE(IsCrxInstalled());
3668 
3669   AddPendingSyncInstall();
3670   ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
3671   EXPECT_FALSE(GetPendingIsFromSync());
3672   ASSERT_FALSE(IsCrxInstalled());
3673 }
3674 
3675 #if defined(OS_CHROMEOS)
3676 // TODO(skerner): crbug/79755
3677 #define MAYBE_PendingExternalFileOverDefaultApp DISABLED_PendingExternalFileOverDefaultApp
3678 #else
3679 #define MAYBE_PendingExternalFileOverDefaultApp PendingExternalFileOverDefaultApp
3680 #endif
3681 // Test that an install of an external CRX overrides a request for a default
3682 // app.
TEST_F(ExtensionSourcePriorityTest,MAYBE_PendingExternalFileOverDefaultApp)3683 TEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalFileOverDefaultApp) {
3684   InitializeEmptyExtensionService();
3685   ASSERT_FALSE(IsCrxInstalled());
3686 
3687   AddPendingDefaultAppInstall();
3688   ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3689   ASSERT_FALSE(IsCrxInstalled());
3690 
3691   AddPendingExternalPrefFileInstall();
3692   ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3693   ASSERT_FALSE(IsCrxInstalled());
3694 
3695   AddPendingDefaultAppInstall();
3696   ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3697   ASSERT_FALSE(IsCrxInstalled());
3698 
3699   WaitForCrxInstall(crx_path_, true);
3700   ASSERT_TRUE(IsCrxInstalled());
3701 }
3702 
3703 #if defined(OS_CHROMEOS)
3704 // TODO(skerner): crbug/79755
3705 #define MAYBE_InstallExternalBlocksSyncRequest DISABLED_InstallExternalBlocksSyncRequest
3706 #else
3707 #define MAYBE_InstallExternalBlocksSyncRequest InstallExternalBlocksSyncRequest
3708 #endif
3709 // Test that an external install request stops sync from installing
3710 // the same extension.
TEST_F(ExtensionSourcePriorityTest,MAYBE_InstallExternalBlocksSyncRequest)3711 TEST_F(ExtensionSourcePriorityTest, MAYBE_InstallExternalBlocksSyncRequest) {
3712   InitializeEmptyExtensionService();
3713   ASSERT_FALSE(IsCrxInstalled());
3714 
3715   // External prefs starts an install.
3716   AddPendingExternalPrefFileInstall();
3717 
3718   // Crx installer was made, but has not yet run.
3719   ASSERT_FALSE(IsCrxInstalled());
3720 
3721   // Before the CRX installer runs, Sync requests that the same extension
3722   // be installed. Should fail, because an external source is pending.
3723   ASSERT_FALSE(AddPendingSyncInstall());
3724 
3725   // Wait for the external source to install.
3726   WaitForCrxInstall(crx_path_, true);
3727   ASSERT_TRUE(IsCrxInstalled());
3728 
3729   // Now that the extension is installed, sync request should fail
3730   // because the extension is already installed.
3731   ASSERT_FALSE(AddPendingSyncInstall());
3732 }
3733