172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service_unittest.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <set>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/basictypes.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_reader.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stl_util-inl.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string16.h"
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/task.h"
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/version.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/crx_installer.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_creator.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_error_reporter.h"
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/extensions/extension_special_storage_policy.h"
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_sync_data.h"
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/extension_updater.h"
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/extensions/external_extension_provider_impl.h"
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/external_extension_provider_interface.h"
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/extensions/external_pref_extension_loader.h"
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/extensions/pack_extension_job.cc"
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/pending_extension_info.h"
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/extensions/pending_extension_manager.h"
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/browser_prefs.h"
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/prefs/pref_service_mock_builder.h"
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/prefs/scoped_user_pref_update.h"
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_paths.h"
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_switches.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_constants.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_resource.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/url_pattern.h"
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/testing_profile.h"
51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/appcache/chrome_appcache_service.h"
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/file_system/browser_file_system_helper.h"
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/in_process_webkit/dom_storage_context.h"
55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/in_process_webkit/webkit_context.h"
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/json_value_serializer.h"
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_registrar.h"
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/cookie_monster.h"
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/cookie_options.h"
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/url_request/url_request_context.h"
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h"
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/platform_test.h"
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/database/database_tracker.h"
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/database/database_util.h"
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace keys = extension_manifest_keys;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Extension ids used during testing.
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab";
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj";
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk";
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln";
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad";
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst char* const permissions_crx = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct ExtensionsOrder {
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool operator()(const Extension* a, const Extension* b) {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return a->name() < b->name();
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic std::vector<std::string> GetErrors() {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<std::string>* errors =
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ExtensionErrorReporter::GetInstance()->GetErrors();
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> ret_val;
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<std::string>::const_iterator iter = errors->begin();
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != errors->end(); ++iter) {
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (iter->find(".svn") == std::string::npos) {
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ret_val.push_back(*iter);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The tests rely on the errors being in a certain order, which can vary
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // depending on how filesystem iteration works.
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::stable_sort(ret_val.begin(), ret_val.end());
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return ret_val;
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic void AddPattern(ExtensionExtent* extent, const std::string& pattern) {
112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int schemes = URLPattern::SCHEME_ALL;
113201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  extent->AddPattern(URLPattern(schemes, pattern));
114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochstatic void AssertEqualExtents(ExtensionExtent* extent1,
117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                               ExtensionExtent* extent2) {
118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::vector<URLPattern> patterns1 = extent1->patterns();
119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::vector<URLPattern> patterns2 = extent2->patterns();
120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> strings1;
121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(patterns1.size(), patterns2.size());
122201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
123201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (size_t i = 0; i < patterns1.size(); ++i)
124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    strings1.insert(patterns1.at(i).GetAsString());
125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> strings2;
127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  for (size_t i = 0; i < patterns2.size(); ++i)
128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    strings2.insert(patterns2.at(i).GetAsString());
129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(strings1, strings2);
131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass MockExtensionProvider : public ExternalExtensionProviderInterface {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  explicit MockExtensionProvider(
13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      VisitorInterface* visitor,
13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      Extension::Location location)
14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  : location_(location), visitor_(visitor), visit_count_(0) {
14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MockExtensionProvider() {}
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateOrAddExtension(const std::string& id,
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const std::string& version,
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const FilePath& path) {
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extension_map_[id] = std::make_pair(version, path);
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void RemoveExtension(const std::string& id) {
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extension_map_.erase(id);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ExternalExtensionProvider implementation:
15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void VisitRegisteredExtension() const {
156513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    visit_count_++;
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (DataMap::const_iterator i = extension_map_.begin();
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         i != extension_map_.end(); ++i) {
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      scoped_ptr<Version> version;
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      version.reset(Version::GetVersionFromString(i->second.first));
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      visitor_->OnExternalExtensionFileFound(
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          i->first, version.get(), i->second.second, location_);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    visitor_->OnExternalProviderReady();
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual bool HasExtension(const std::string& id) const {
169513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return extension_map_.find(id) != extension_map_.end();
170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual bool GetExtensionDetails(const std::string& id,
173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                   Extension::Location* location,
174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                   scoped_ptr<Version>* version) const {
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DataMap::const_iterator it = extension_map_.find(id);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (it == extension_map_.end())
177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      return false;
178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    if (version)
180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      version->reset(Version::GetVersionFromString(it->second.first));
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (location)
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *location = location_;
184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    return true;
186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual bool IsReady() {
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void ServiceShutdown() {
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  int visit_count() const { return visit_count_; }
196513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void set_visit_count(int visit_count) {
197513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    visit_count_ = visit_count;
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DataMap extension_map_;
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension::Location location_;
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  VisitorInterface* visitor_;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // visit_count_ tracks the number of calls to VisitRegisteredExtension().
207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Mutable because it must be incremented on each call to
208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // VisitRegisteredExtension(), which must be a const method to inherit
209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // from the class being mocked.
210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  mutable int visit_count_;
211513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass MockProviderVisitor
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : public ExternalExtensionProviderInterface::VisitorInterface {
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The provider will return |fake_base_path| from
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // GetBaseCrxFilePath().  User can test the behavior with
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // and without an empty path using this parameter.
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  explicit MockProviderVisitor(FilePath fake_base_path)
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      : ids_found_(0),
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        fake_base_path_(fake_base_path) {
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  int Visit(const std::string& json_data) {
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Give the test json file to the provider for parsing.
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    provider_.reset(new ExternalExtensionProviderImpl(
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        this,
23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        new ExternalTestingExtensionLoader(json_data, fake_base_path_),
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        Extension::EXTERNAL_PREF,
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        Extension::EXTERNAL_PREF_DOWNLOAD));
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We also parse the file into a dictionary to compare what we get back
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // from the provider.
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    JSONStringValueSerializer serializer(json_data);
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Value* json_value = serializer.Deserialize(NULL, NULL);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      NOTREACHED() << "Unable to deserialize json data";
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return -1;
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DictionaryValue* external_extensions =
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          static_cast<DictionaryValue*>(json_value);
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs_.reset(external_extensions);
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Reset our counter.
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ids_found_ = 0;
25121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Ask the provider to look up all extensions and return them.
25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    provider_->VisitRegisteredExtension();
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ids_found_;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void OnExternalExtensionFileFound(const std::string& id,
2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                            const Version* version,
2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                            const FilePath& path,
2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                            Extension::Location unused) {
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ++ids_found_;
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* pref;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This tests is to make sure that the provider only notifies us of the
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // values we gave it. So if the id we doesn't exist in our internal
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // dictionary then something is wrong.
2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick       << "Got back ID (" << id.c_str() << ") we weren't expecting";
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(path.IsAbsolute());
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!fake_base_path_.empty())
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      EXPECT_TRUE(fake_base_path_.IsParent(path));
27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pref) {
274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_TRUE(provider_->HasExtension(id));
275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Ask provider if the extension we got back is registered.
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Extension::Location location = Extension::INVALID;
278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      scoped_ptr<Version> v1;
279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      FilePath crx_path;
280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      scoped_ptr<Version> v2;
285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(Extension::EXTERNAL_PREF, location);
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Remove it so we won't count it ever again.
2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      prefs_->Remove(id, NULL);
2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
295513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  virtual void OnExternalExtensionUpdateUrlFound(
296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      const std::string& id, const GURL& update_url,
297513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      Extension::Location location) {
2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ++ids_found_;
2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    DictionaryValue* pref;
3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // This tests is to make sure that the provider only notifies us of the
3013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // values we gave it. So if the id we doesn't exist in our internal
3023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // dictionary then something is wrong.
3033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
3043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick       << L"Got back ID (" << id.c_str() << ") we weren't expecting";
305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location);
3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (pref) {
308513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_TRUE(provider_->HasExtension(id));
309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
310513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      // External extensions with update URLs do not have versions.
311513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      scoped_ptr<Version> v1;
312513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      Extension::Location location1 = Extension::INVALID;
313513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
314513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_FALSE(v1.get());
315513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location1);
316513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // Remove it so we won't count it again.
3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      prefs_->Remove(id, NULL);
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual void OnExternalProviderReady() {
32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(provider_->IsReady());
32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int ids_found_;
32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath fake_base_path_;
32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<ExternalExtensionProviderImpl> provider_;
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<DictionaryValue> prefs_;
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionTestingProfile : public TestingProfile {
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExtensionTestingProfile() : service_(NULL) {
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void set_extensions_service(ExtensionService* service) {
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_ = service;
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual ExtensionService* GetExtensionService() { return service_; }
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual ChromeAppCacheService* GetAppCacheService() {
3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!appcache_service_) {
3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      appcache_service_ = new ChromeAppCacheService;
348731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::PostTask(
349731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          BrowserThread::IO, FROM_HERE,
350dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          NewRunnableMethod(
351dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen              appcache_service_.get(),
352dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen              &ChromeAppCacheService::InitializeOnIOThread,
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              IsOffTheRecord()
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  ? FilePath() : GetPath().Append(chrome::kAppCacheDirname),
355dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen              make_scoped_refptr(GetHostContentSettingsMap()),
356dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen              make_scoped_refptr(GetExtensionSpecialStoragePolicy()),
357dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen              false));
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return appcache_service_;
3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
36272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual fileapi::FileSystemContext* GetFileSystemContext() {
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    if (!file_system_context_)
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      file_system_context_ = CreateFileSystemContext(
365dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen          GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy());
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return file_system_context_;
367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service_;
3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<ChromeAppCacheService> appcache_service_;
37272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_refptr<fileapi::FileSystemContext> file_system_context_;
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Our message loop may be used in tests which require it to be an IO loop.
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenExtensionServiceTestBase::ExtensionServiceTestBase()
3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : total_successes_(0),
3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      loop_(MessageLoop::TYPE_IO),
379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      ui_thread_(BrowserThread::UI, &loop_),
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      db_thread_(BrowserThread::DB, &loop_),
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      webkit_thread_(BrowserThread::WEBKIT, &loop_),
382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      file_thread_(BrowserThread::FILE, &loop_),
383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      io_thread_(BrowserThread::IO, &loop_) {
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath test_data_dir;
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADD_FAILURE();
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  data_dir_ = test_data_dir.AppendASCII("extensions");
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenExtensionServiceTestBase::~ExtensionServiceTestBase() {
39321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Drop our reference to ExtensionService and TestingProfile, so that they
394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // can be destroyed while BrowserThreads and MessageLoop are still around
395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // (they are used in the destruction process).
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_ = NULL;
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_.reset(NULL);
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop::current()->RunAllPending();
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionServiceTestBase::InitializeExtensionService(
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const FilePath& pref_file, const FilePath& extensions_install_dir,
403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool autoupdate_enabled) {
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionTestingProfile* profile = new ExtensionTestingProfile();
40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Create a PrefService that only contains user defined preference values.
40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PrefService* prefs =
40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create();
4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Profile::RegisterUserPrefs(prefs);
4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  browser::RegisterUserPrefs(prefs);
4103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile->SetPrefService(prefs);
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile_.reset(profile);
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  service_ = profile->CreateExtensionService(
4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      CommandLine::ForCurrentProcess(),
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      extensions_install_dir,
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      autoupdate_enabled);
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->set_extensions_enabled(true);
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->set_show_extensions_prompts(false);
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  profile->set_extensions_service(service_.get());
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // When we start up, we want to make sure there is no external provider,
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // since the ExtensionService on Windows will use the Registry as a default
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // provider and if there is something already registered there then it will
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // interfere with the tests. Those tests that need an external provider
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // will register one specifically.
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->ClearProvidersForTesting();
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  total_successes_ = 0;
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionServiceTestBase::InitializeInstalledExtensionService(
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& prefs_file, const FilePath& source_install_dir) {
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath path_ = temp_dir_.path();
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::Delete(path_, true);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::CreateDirectory(path_);
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath temp_prefs = path_.Append(FILE_PATH_LITERAL("Preferences"));
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::CopyFile(prefs_file, temp_prefs);
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::Delete(extensions_install_dir_, true);
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true);
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeExtensionService(temp_prefs, extensions_install_dir_, false);
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionServiceTestBase::InitializeEmptyExtensionService() {
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeExtensionServiceHelper(false);
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeExtensionServiceHelper(true);
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->updater()->Start();
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ExtensionServiceTestBase::InitializeExtensionServiceHelper(
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool autoupdate_enabled) {
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath path_ = temp_dir_.path();
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::Delete(path_, true);
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::CreateDirectory(path_);
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath prefs_filename = path_
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .Append(FILE_PATH_LITERAL("TestPreferences"));
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions"));
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::Delete(extensions_install_dir_, true);
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::CreateDirectory(extensions_install_dir_);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeExtensionService(prefs_filename, extensions_install_dir_,
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             autoupdate_enabled);
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
47621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionServiceTestBase::SetUpTestCase() {
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionErrorReporter::Init(false);  // no noisy errors
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionServiceTestBase::SetUp() {
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionErrorReporter::GetInstance()->ClearErrors();
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass ExtensionServiceTest
48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  : public ExtensionServiceTestBase, public NotificationObserver {
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
48721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionServiceTest() : installed_(NULL) {
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::EXTENSION_LOADED,
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::EXTENSION_INSTALLED,
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Observe(NotificationType type,
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationSource& source,
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationDetails& details) {
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (type.value) {
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case NotificationType::EXTENSION_LOADED: {
501513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        const Extension* extension = Details<const Extension>(details).ptr();
502513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        loaded_.push_back(make_scoped_refptr(extension));
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // The tests rely on the errors being in a certain order, which can vary
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // depending on how filesystem iteration works.
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case NotificationType::EXTENSION_UNLOADED: {
51021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        const Extension* e =
51121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen            Details<UnloadedExtensionInfo>(details)->extension;
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        unloaded_id_ = e->id();
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ExtensionList::iterator i =
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            std::find(loaded_.begin(), loaded_.end(), e);
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // TODO(erikkay) fix so this can be an assert.  Right now the tests
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        // are manually calling clear() on loaded_, so this isn't doable.
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (i == loaded_.end())
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          return;
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        loaded_.erase(i);
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case NotificationType::EXTENSION_INSTALLED:
523513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        installed_ = Details<const Extension>(details).ptr();
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK(false);
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void AddMockExternalProvider(ExternalExtensionProviderInterface* provider) {
532513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    service_->AddProviderForTesting(provider);
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void TestExternalProvider(MockExtensionProvider* provider,
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            Extension::Location location);
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void PackAndInstallCrx(const FilePath& dir_path,
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         const FilePath& pem_path,
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         bool should_succeed) {
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath crx_path;
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ScopedTempDir temp_dir;
544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    crx_path = temp_dir_.path().AppendASCII("temp.crx");
546201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Use the existing pem key, if provided.
548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    FilePath pem_output_path;
549201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (pem_path.value().empty()) {
550201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
551201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      ASSERT_TRUE(file_util::Delete(pem_output_path, false));
552201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    } else {
553201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      ASSERT_TRUE(file_util::PathExists(pem_path));
554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(file_util::Delete(crx_path, false));
557201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
559201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    ASSERT_TRUE(creator->Run(dir_path,
560201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                             crx_path,
561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                             pem_path,
562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                             pem_output_path));
563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(file_util::PathExists(crx_path));
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    InstallCrx(crx_path, should_succeed);
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void PackAndInstallCrx(const FilePath& dir_path,
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         bool should_succeed) {
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PackAndInstallCrx(dir_path, FilePath(), should_succeed);
572201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
573201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
574dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Create a CrxInstaller and start installation. To allow the install
575dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // to happen, use loop_.RunAllPending();. Most tests will not use this
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // method directly.  Instead, use InstallCrx(), which waits for
577dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // the crx to be installed and does extra error checking.
578dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  void StartCrxInstall(const FilePath& crx_path) {
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_TRUE(file_util::PathExists(crx_path))
580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        << "Path does not exist: "<< crx_path.value().c_str();
581dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    scoped_refptr<CrxInstaller> installer(
582dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        new CrxInstaller(service_,  // frontend
583dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                         NULL));  // no client (silent install)
584dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    installer->InstallCrx(crx_path);
585dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
586dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void InstallCrx(const FilePath& path,
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        bool should_succeed) {
589dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    StartCrxInstall(path);
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WaitForCrxInstall(path, should_succeed);
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void InstallCrxWithLocation(const FilePath& crx_path,
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              Extension::Location install_location,
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              bool should_succeed) {
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_TRUE(file_util::PathExists(crx_path))
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        << "Path does not exist: "<< crx_path.value().c_str();
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_refptr<CrxInstaller> installer(
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new CrxInstaller(service_,  // frontend
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         NULL));  // no client (silent install)
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    installer->set_install_source(install_location);
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    installer->InstallCrx(crx_path);
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WaitForCrxInstall(crx_path, should_succeed);
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Wait for a CrxInstaller to finish. Used by InstallCrx.
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void WaitForCrxInstall(const FilePath& path,
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                         bool should_succeed) {
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loop_.RunAllPending();
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::string> errors = GetErrors();
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (should_succeed) {
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ++total_successes_;
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_TRUE(installed_) << path.value();
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_EQ(1u, loaded_.size()) << path.value();
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(0u, errors.size()) << path.value();
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(total_successes_, service_->extensions()->size()) <<
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          path.value();
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          path.value();
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      for (std::vector<std::string>::iterator err = errors.begin();
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        err != errors.end(); ++err) {
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        LOG(ERROR) << *err;
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_FALSE(installed_) << path.value();
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(0u, loaded_.size()) << path.value();
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(1u, errors.size()) << path.value();
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    installed_ = NULL;
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loaded_.clear();
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionErrorReporter::GetInstance()->ClearErrors();
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  enum UpdateState {
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FAILED_SILENTLY,
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FAILED,
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UPDATED,
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    INSTALLED,
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ENABLED
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  };
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void UpdateExtension(const std::string& id, const FilePath& in_path,
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       UpdateState expected_state) {
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(file_util::PathExists(in_path));
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We need to copy this to a temporary location because Update() will delete
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // it.
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath path = temp_dir_.path();
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    path = path.Append(in_path.BaseName());
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(file_util::CopyFile(in_path, path));
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int previous_enabled_extension_count =
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        service_->extensions()->size();
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int previous_installed_extension_count =
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        previous_enabled_extension_count +
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        service_->disabled_extensions()->size();
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service_->UpdateExtension(id, path, GURL());
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loop_.RunAllPending();
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::string> errors = GetErrors();
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int error_count = errors.size();
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int enabled_extension_count =
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        service_->extensions()->size();
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int installed_extension_count =
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        enabled_extension_count + service_->disabled_extensions()->size();
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int expected_error_count = (expected_state == FAILED) ? 1 : 0;
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(expected_error_count, error_count) << path.value();
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (expected_state <= FAILED) {
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(previous_enabled_extension_count,
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                enabled_extension_count);
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(previous_installed_extension_count,
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                installed_extension_count);
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int expected_installed_extension_count =
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          (expected_state >= INSTALLED) ? 1 : 0;
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int expected_enabled_extension_count =
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          (expected_state >= ENABLED) ? 1 : 0;
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(expected_installed_extension_count,
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                installed_extension_count);
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(expected_enabled_extension_count,
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                enabled_extension_count);
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Update() should delete the temporary input file.
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(file_util::PathExists(path));
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ValidatePrefKeyCount(size_t count) {
697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const DictionaryValue* dict =
698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        profile_->GetPrefs()->GetDictionary("extensions.settings");
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(dict != NULL);
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(count, dict->size());
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ValidateBooleanPref(const std::string& extension_id,
7043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           const std::string& pref_path,
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           bool expected_val) {
7063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string msg = " while checking: ";
7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += extension_id;
7083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += " ";
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg += pref_path;
7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += " == ";
7113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += expected_val ? "true" : "false";
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    PrefService* prefs = profile_->GetPrefs();
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const DictionaryValue* dict =
7153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        prefs->GetDictionary("extensions.settings");
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(dict != NULL) << msg;
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* pref = NULL;
7183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(pref != NULL) << msg;
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool val;
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg;
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(expected_val, val) << msg;
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool IsPrefExist(const std::string& extension_id,
7263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                   const std::string& pref_path) {
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const DictionaryValue* dict =
7283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        profile_->GetPrefs()->GetDictionary("extensions.settings");
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (dict == NULL) return false;
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* pref = NULL;
7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (!dict->GetDictionary(extension_id, &pref)) {
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pref == NULL) {
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool val;
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!pref->GetBoolean(pref_path, &val)) {
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ValidateIntegerPref(const std::string& extension_id,
7453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                           const std::string& pref_path,
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           int expected_val) {
7473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string msg = " while checking: ";
7483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += extension_id;
7493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += " ";
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg += pref_path;
7513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += " == ";
7523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += base::IntToString(expected_val);
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    PrefService* prefs = profile_->GetPrefs();
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const DictionaryValue* dict =
7563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        prefs->GetDictionary("extensions.settings");
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(dict != NULL) << msg;
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* pref = NULL;
7593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(pref != NULL) << msg;
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int val;
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(expected_val, val) << msg;
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ValidateStringPref(const std::string& extension_id,
7673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          const std::string& pref_path,
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          const std::string& expected_val) {
7693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string msg = " while checking: ";
7703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += extension_id;
7713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += ".manifest.";
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg += pref_path;
7733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += " == ";
7743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += expected_val;
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const DictionaryValue* dict =
7773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        profile_->GetPrefs()->GetDictionary("extensions.settings");
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(dict != NULL) << msg;
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* pref = NULL;
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string manifest_path = extension_id + ".manifest";
7813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(pref != NULL) << msg;
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string val;
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(expected_val, val) << msg;
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
788201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void SetPref(const std::string& extension_id,
789201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch               const std::string& pref_path,
790201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch               Value* value,
791201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch               const std::string& msg) {
792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryValue* dict = update.Get();
794201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    ASSERT_TRUE(dict != NULL) << msg;
795201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DictionaryValue* pref = NULL;
796201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
797201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_TRUE(pref != NULL) << msg;
798201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    pref->Set(pref_path, value);
799201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
800201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void SetPrefInteg(const std::string& extension_id,
8023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                    const std::string& pref_path,
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    int value) {
8043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string msg = " while setting: ";
8053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += extension_id;
8063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += " ";
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    msg += pref_path;
8083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += " = ";
8093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    msg += base::IntToString(value);
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
811201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SetPref(extension_id, pref_path, Value::CreateIntegerValue(value), msg);
812201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
813201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
814201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void SetPrefBool(const std::string& extension_id,
815201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                   const std::string& pref_path,
816201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                   bool value) {
817201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::string msg = " while setting: ";
818201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    msg += extension_id + " " + pref_path;
819201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    msg += " = ";
820201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    msg += (value ? "true" : "false");
821201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
822201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SetPref(extension_id, pref_path, Value::CreateBooleanValue(value), msg);
823201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
824201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
825201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void ClearPref(const std::string& extension_id,
826201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                 const std::string& pref_path) {
827201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::string msg = " while clearing: ";
828201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    msg += extension_id + " " + pref_path;
829201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
830ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryValue* dict = update.Get();
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(dict != NULL) << msg;
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* pref = NULL;
8343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(pref != NULL) << msg;
836201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    pref->Remove(pref_path, NULL);
837201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
838201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
839201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void SetPrefStringSet(const std::string& extension_id,
840201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                        const std::string& pref_path,
841201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                        const std::set<std::string>& value) {
842201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::string msg = " while setting: ";
843201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    msg += extension_id + " " + pref_path;
844201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
845201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    ListValue* list_value = new ListValue();
846201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    for (std::set<std::string>::const_iterator iter = value.begin();
847201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch         iter != value.end(); ++iter)
848201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      list_value->Append(Value::CreateStringValue(*iter));
849201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
850201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SetPref(extension_id, pref_path, list_value, msg);
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionList loaded_;
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string unloaded_id_;
856513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* installed_;
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationRegistrar registrar_;
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickFilePath NormalizeSeparators(const FilePath& path) {
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(FILE_PATH_USES_WIN_SEPARATORS)
8643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return path.NormalizeWindowsPathSeparators();
8653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#else
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return path;
8673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif  // FILE_PATH_USES_WIN_SEPARATORS
8683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
8693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Receives notifications from a PackExtensionJob, indicating either that
8713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// packing succeeded or that there was some error.
8723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass PackExtensionTestClient : public PackExtensionJob::Client {
8733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
8743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  PackExtensionTestClient(const FilePath& expected_crx_path,
8753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                          const FilePath& expected_private_key_path);
8763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void OnPackSuccess(const FilePath& crx_path,
8773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             const FilePath& private_key_path);
8783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void OnPackFailure(const std::string& error_message);
8793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
8813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const FilePath expected_crx_path_;
8823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const FilePath expected_private_key_path_;
8833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
8843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
8853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8863345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickPackExtensionTestClient::PackExtensionTestClient(
8873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const FilePath& expected_crx_path,
8883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const FilePath& expected_private_key_path)
8893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : expected_crx_path_(expected_crx_path),
8903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      expected_private_key_path_(expected_private_key_path) {}
8913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// If packing succeeded, we make sure that the package names match our
8933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// expectations.
8943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid PackExtensionTestClient::OnPackSuccess(const FilePath& crx_path,
8953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                            const FilePath& private_key_path) {
8963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We got the notification and processed it; we don't expect any further tasks
8973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // to be posted to the current thread, so we should stop blocking and continue
8983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // on with the rest of the test.
8993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This call to |Quit()| matches the call to |Run()| in the
9003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // |PackPunctuatedExtension| test.
9013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MessageLoop::current()->Quit();
9023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
9033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
9043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(file_util::PathExists(private_key_path));
9053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
9063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The tests are designed so that we never expect to see a packing error.
9083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid PackExtensionTestClient::OnPackFailure(const std::string& error_message) {
9093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FAIL() << "Packing should not fail.";
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
9113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test loading good extensions from the profile directory.
91321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialize the test dir with a good Preferences/extensions.
915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_install_dir = data_dir_
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("good")
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions");
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath pref_path = source_install_dir
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .DirName()
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Preferences");
92121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeInstalledExtensionService(pref_path, source_install_dir);
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->Init();
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  uint32 expected_num_extensions = 3u;
9263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(expected_num_extensions, loaded_.size());
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(std::string(good0), loaded_[0]->id());
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(std::string("My extension 1"),
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            loaded_[0]->name());
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(std::string("The first extension that I made."),
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            loaded_[0]->description());
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location());
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
9353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(3);
9383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good0, "state", Extension::ENABLED);
9393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good0, "location", Extension::INTERNAL);
9403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good1, "state", Extension::ENABLED);
9413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good1, "location", Extension::INTERNAL);
9423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good2, "state", Extension::ENABLED);
9433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good2, "location", Extension::INTERNAL);
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
945513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = loaded_[0];
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const UserScriptList& scripts = extension->content_scripts();
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2u, scripts.size());
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(3u, scripts[0].url_patterns().size());
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("file://*",
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            scripts[0].url_patterns()[0].GetAsString());
951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("http://*.google.com/*",
952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            scripts[0].url_patterns()[1].GetAsString());
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("https://*.google.com/*",
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            scripts[0].url_patterns()[2].GetAsString());
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2u, scripts[0].js_scripts().size());
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionResource resource00(extension->id(),
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               scripts[0].js_scripts()[0].extension_root(),
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               scripts[0].js_scripts()[0].relative_path());
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath expected_path(extension->path().AppendASCII("script1.js"));
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionResource resource01(extension->id(),
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               scripts[0].js_scripts()[1].extension_root(),
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               scripts[0].js_scripts()[1].relative_path());
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_path = extension->path().AppendASCII("script2.js");
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(extension->plugins().empty());
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, scripts[1].url_patterns().size());
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString());
971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionResource resource10(extension->id(),
972c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               scripts[1].js_scripts()[0].extension_root(),
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               scripts[1].js_scripts()[0].relative_path());
974c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  expected_path =
975c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension->path().AppendASCII("js_files").AppendASCII("script3.js");
976c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::AbsolutePath(&expected_path));
977c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
978c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<URLPattern> permissions = extension->host_permissions();
979c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2u, permissions.size());
980c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("http://*.google.com/*", permissions[0].GetAsString());
981c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("https://*.google.com/*", permissions[1].GetAsString());
982c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
983c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(std::string(good1), loaded_[1]->id());
984c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
985c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(std::string(""), loaded_[1]->description());
986c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
987c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            loaded_[1]->background_url());
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, loaded_[1]->content_scripts().size());
989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We don't parse the plugins section on Chrome OS.
990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0u, loaded_[1]->plugins().size());
992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(2u, loaded_[1]->plugins().size());
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            loaded_[1]->plugins()[0].path.value());
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(loaded_[1]->plugins()[0].is_public);
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            loaded_[1]->plugins()[1].path.value());
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(loaded_[1]->plugins()[1].is_public);
10003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif
1001c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location());
1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
10043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int index = expected_num_extensions - 1;
10053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(std::string(good2), loaded_[index]->id());
10063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
10073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(std::string(""), loaded_[index]->description());
10083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(0u, loaded_[index]->content_scripts().size());
10093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(Extension::INTERNAL, loaded_[index]->location());
1010c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test loading bad extensions from the profile directory.
101321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1014c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialize the test dir with a bad Preferences/extensions.
1015ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_install_dir = data_dir_
1016c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("bad")
1017c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions");
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath pref_path = source_install_dir
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .DirName()
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Preferences");
1021c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeInstalledExtensionService(pref_path, source_install_dir);
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->Init();
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(4u, GetErrors().size());
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, loaded_.size());
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(MatchPattern(GetErrors()[0],
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string("Could not load extension from '*'. ") +
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_manifest_errors::kManifestUnreadable)) << GetErrors()[0];
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(MatchPattern(GetErrors()[1],
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string("Could not load extension from '*'. ") +
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_manifest_errors::kManifestUnreadable)) << GetErrors()[1];
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(MatchPattern(GetErrors()[2],
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string("Could not load extension from '*'. ") +
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_manifest_errors::kMissingFile)) << GetErrors()[2];
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(MatchPattern(GetErrors()[3],
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string("Could not load extension from '*'. ") +
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_manifest_errors::kManifestUnreadable)) << GetErrors()[3];
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1047c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that partially deleted extensions are cleaned up during startup
1048c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test loading bad extensions from the profile directory.
104921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, CleanupOnStartup) {
1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_install_dir = data_dir_
1051c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("good")
1052c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions");
1053c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath pref_path = source_install_dir
1054c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .DirName()
1055c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Preferences");
1056c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeInstalledExtensionService(pref_path, source_install_dir);
1058c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1059c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simulate that one of them got partially deleted by clearing its pref.
1060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
1061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DictionaryValue* dict = update.Get();
1063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_TRUE(dict != NULL);
1064ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1065ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->Init();
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  file_util::FileEnumerator dirs(extensions_install_dir_, false,
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 file_util::FileEnumerator::DIRECTORIES);
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  size_t count = 0;
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  while (!dirs.Next().empty())
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    count++;
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We should have only gotten two extensions now.
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(2u, count);
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And extension1 dir should now be toast.
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath extension_dir = extensions_install_dir_
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(file_util::PathExists(extension_dir));
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test installing extensions. This test tries to install few extensions using
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// crx files. If you need to change those crx files, feel free to repackage
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// them, throw away the key used and change the id's above.
108821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, InstallExtension) {
108921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1090c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extensions not enabled.
1092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_extensions_enabled(false);
1093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, false);
1095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_extensions_enabled(true);
1096c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(0);
1098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A simple extension that should install without error.
1100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("good.crx");
1101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(erikkay): verify the contents of the installed extension.
1103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int pref_count = 0;
1105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(++pref_count);
11063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
11073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
1108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // An extension with page actions.
1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("page_action.crx");
1111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(++pref_count);
11133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(page_action, "state", Extension::ENABLED);
11143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(page_action, "location", Extension::INTERNAL);
1115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bad signature.
1117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("bad_signature.crx");
1118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, false);
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(pref_count);
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // 0-length extension file.
1122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("not_an_extension.crx");
1123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, false);
1124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(pref_count);
1125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bad magic number.
1127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("bad_magic.crx");
1128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, false);
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(pref_count);
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Extensions cannot have folders or files that have underscores except in
1132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // certain whitelisted cases (eg _locales). This is an example of a broader
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // class of validation that we do to the directory structure of the extension.
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We did not used to handle this correctly for installation.
1135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("bad_underscore.crx");
1136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, false);
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(pref_count);
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(erikkay): add more tests for many of the failure cases.
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(erikkay): add tests for upgrade cases.
1141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
114521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
114621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
114821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  set_extensions_enabled(true);
114921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
115072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  scoped_ptr<Version> version;
115172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  version.reset(Version::GetVersionFromString("1.0.0.0"));
115221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Install an external extension.
115372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->OnExternalExtensionFileFound(good_crx, version.get(),
115421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                         path, Extension::EXTERNAL_PREF);
115521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loop_.RunAllPending();
1156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
115721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
115821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Uninstall it and check that its killbit gets set.
1159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(good_crx, false, NULL);
116021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loop_.RunAllPending();
1161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ValidateIntegerPref(good_crx, "location",
1162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      Extension::EXTERNAL_EXTENSION_UNINSTALLED);
116321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
116421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Try to re-install it externally. This should fail because of the killbit.
116572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->OnExternalExtensionFileFound(good_crx, version.get(),
116621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                         path, Extension::EXTERNAL_PREF);
116721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loop_.RunAllPending();
116821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ValidateIntegerPref(good_crx, "location",
1170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      Extension::EXTERNAL_EXTENSION_UNINSTALLED);
117121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
117272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  version.reset(Version::GetVersionFromString("1.0.0.1"));
117321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Repeat the same thing with a newer version of the extension.
1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("good2.crx");
117572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->OnExternalExtensionFileFound(good_crx, version.get(),
117621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                         path, Extension::EXTERNAL_PREF);
117721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loop_.RunAllPending();
117821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ValidateIntegerPref(good_crx, "location",
1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      Extension::EXTERNAL_EXTENSION_UNINSTALLED);
118121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
118221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Try adding the same extension from an external update URL.
1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromExternalUpdateUrl(
118421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      good_crx,
118521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      GURL("http:://fake.update/url"),
118621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      Extension::EXTERNAL_PREF_DOWNLOAD);
1187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
1189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that external extensions with incorrect IDs are not installed.
1192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, FailOnWrongId) {
1193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
1194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  set_extensions_enabled(true);
1196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<Version> version;
1198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  version.reset(Version::GetVersionFromString("1.0.0.0"));
1199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::string wrong_id = all_zero;
1201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::string correct_id = good_crx;
1202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_NE(correct_id, wrong_id);
1203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Install an external extension with an ID from the external
1205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // source that is not equal to the ID in the extension manifest.
1206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->OnExternalExtensionFileFound(
1207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      wrong_id, version.get(), path, Extension::EXTERNAL_PREF);
1208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loop_.RunAllPending();
1210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Try again with the right ID. Expect success.
1213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->OnExternalExtensionFileFound(
1214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      correct_id, version.get(), path, Extension::EXTERNAL_PREF);
1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loop_.RunAllPending();
1216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that external extensions with incorrect versions are not installed.
1220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
1222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  set_extensions_enabled(true);
1224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Install an external extension with a version from the external
1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // source that is not equal to the version in the extension manifest.
1227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<Version> wrong_version;
1228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  wrong_version.reset(Version::GetVersionFromString("1.2.3.4"));
1229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->OnExternalExtensionFileFound(
1230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      good_crx, wrong_version.get(), path, Extension::EXTERNAL_PREF);
1231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loop_.RunAllPending();
1233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Try again with the right version. Expect success.
1236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<Version> correct_version;
1237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  correct_version.reset(Version::GetVersionFromString("1.0.0.0"));
1238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->OnExternalExtensionFileFound(
1239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      good_crx, correct_version.get(), path, Extension::EXTERNAL_PREF);
1240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loop_.RunAllPending();
1241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
124221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
124321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
1244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Install a user script (they get converted automatically to an extension)
124521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, InstallUserScript) {
1246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The details of script conversion are tested elsewhere, this just tests
124721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // integration with ExtensionService.
124821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_
1251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             .AppendASCII("user_script_basic.user.js");
1252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::PathExists(path));
1254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<CrxInstaller> installer(
1255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      new CrxInstaller(service_, NULL));  // silent install
1256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  installer->InstallUserScript(
1257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      path,
1258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> errors = GetErrors();
1262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(installed_) << "Nothing was installed.";
1263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, errors.size()) << "There were errors: "
1265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               << JoinString(errors, ',');
1266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
1267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              path.value();
1268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  installed_ = NULL;
1270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loaded_.clear();
1271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionErrorReporter::GetInstance()->ClearErrors();
1272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// This tests that the granted permissions preferences are correctly set when
1275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// installing an extension.
127621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, GrantedPermissions) {
127721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_
1279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("permissions");
1280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath pem_path = path.AppendASCII("unknown.pem");
1282201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  path = path.AppendASCII("unknown");
1283201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(file_util::PathExists(pem_path));
1285201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(file_util::PathExists(path));
1286201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionPrefs* prefs = service_->extension_prefs();
1288201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1289201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> expected_api_perms;
1290201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> known_api_perms;
1291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool full_access;
1292201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionExtent expected_host_perms;
1293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionExtent known_host_perms;
1294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Make sure there aren't any granted permissions before the
1296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // extension is installed.
1297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_FALSE(prefs->GetGrantedPermissions(
1298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      permissions_crx, &full_access, &known_api_perms, &known_host_perms));
1299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(known_api_perms.empty());
1300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(known_host_perms.is_empty());
1301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(path, pem_path, true);
1303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, GetErrors().size());
1305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(1u, service_->extensions()->size());
1306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::string extension_id = service_->extensions()->at(0)->id();
1307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(permissions_crx, extension_id);
1308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1309201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Verify that the valid API permissions have been recognized.
1311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  expected_api_perms.insert("tabs");
1312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1313201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_perms, "http://*.google.com/*");
1314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_perms, "https://*.google.com/*");
1315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_perms, "http://www.example.com/*");
1317201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1318201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(prefs->GetGrantedPermissions(extension_id,
1319201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &full_access,
1320201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &known_api_perms,
1321201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &known_host_perms));
1322201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1323201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(expected_api_perms, known_api_perms);
1324201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_FALSE(full_access);
1325201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AssertEqualExtents(&expected_host_perms, &known_host_perms);
1326201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1328201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#if !defined(OS_CHROMEOS)
1329201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Tests that the granted permissions full_access bit gets set correctly when
1330201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// an extension contains an NPAPI plugin. Don't run this test on Chrome OS
1331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// since they don't support plugins.
133221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
133321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1334201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_
1336201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("good")
1337201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("Extensions")
1338201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII(good1)
1339201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("2");
1340201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1341201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(file_util::PathExists(path));
1342201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(path, true);
1344201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1345201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, GetErrors().size());
1346201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
1347201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const Extension* extension = service_->extensions()->at(0);
1348201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::string extension_id = extension->id();
1349201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionPrefs* prefs = service_->extension_prefs();
1350201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1351201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool full_access;
1352201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> api_permissions;
1353201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionExtent host_permissions;
1354201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(prefs->GetGrantedPermissions(
1355201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      extension_id, &full_access, &api_permissions, &host_permissions));
1356201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1357201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(full_access);
1358201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(api_permissions.empty());
1359201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(host_permissions.is_empty());
1360201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1361201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#endif
1362201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1363201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Tests that the extension is disabled when permissions are missing from
1364201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// the extension's granted permissions preferences. (This simulates updating
1365201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// the browser to a version which recognizes more permissions).
136621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
136721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1368201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_
1370201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("permissions")
1371201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("unknown");
1372201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1373201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(file_util::PathExists(path));
1374201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(path, true);
1376201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1377201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, GetErrors().size());
1378201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
1379201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const Extension* extension = service_->extensions()->at(0);
1380201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::string extension_id = extension->id();
1381201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1382201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionPrefs* prefs = service_->extension_prefs();
1383201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1384201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> expected_api_permissions;
1385201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionExtent expected_host_permissions;
1386201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1387201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  expected_api_permissions.insert("tabs");
1388201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_permissions, "http://*.google.com/*");
1389201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_permissions, "https://*.google.com/*");
1390201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1391201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AddPattern(&expected_host_permissions, "http://www.example.com/*");
1392201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1393201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> api_permissions;
1394201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> host_permissions;
1395201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1396201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Test that the extension is disabled when an API permission is missing from
1397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // the extension's granted api permissions preference. (This simulates
1398201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // updating the browser to a version which recognizes a new API permission).
1399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions);
1400201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1401201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->ReloadExtensions();
1402201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1403201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1u, service_->disabled_extensions()->size());
1404201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  extension = service_->disabled_extensions()->at(0);
1405201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1406201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED);
1407201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1408201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Now grant and re-enable the extension, making sure the prefs are updated.
1410201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->GrantPermissionsAndEnableExtension(extension);
1411201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1412201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1413201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<std::string> current_api_permissions;
1416201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionExtent current_host_permissions;
1417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool current_full_access;
1418201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1419201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1420201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_full_access,
1421201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_api_permissions,
1422201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_host_permissions));
1423201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1424201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_FALSE(current_full_access);
1425201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(expected_api_permissions, current_api_permissions);
1426201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1427201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1428201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Tests that the extension is disabled when a host permission is missing from
1429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // the extension's granted host permissions preference. (This simulates
1430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // updating the browser to a version which recognizes additional host
1431201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // permissions).
1432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  api_permissions.clear();
1433201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  host_permissions.clear();
1434201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  current_api_permissions.clear();
1435201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  current_host_permissions.ClearPaths();
1436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  api_permissions.insert("tabs");
1438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  host_permissions.insert("http://*.google.com/*");
1439201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  host_permissions.insert("https://*.google.com/*");
1440201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  host_permissions.insert("http://*.google.com.hk/*");
1441201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1442201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions);
1443201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  SetPrefStringSet(extension_id, "granted_permissions.host", host_permissions);
1444201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1445201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->ReloadExtensions();
1446201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1447201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1u, service_->disabled_extensions()->size());
1448201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  extension = service_->disabled_extensions()->at(0);
1449201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1450201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED);
1451201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1452201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1453201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Now grant and re-enable the extension, making sure the prefs are updated.
1454201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->GrantPermissionsAndEnableExtension(extension);
1455201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1456201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1457201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1458201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1459201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1460201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_full_access,
1461201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_api_permissions,
1462201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_host_permissions));
1463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1464201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_FALSE(current_full_access);
1465201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(expected_api_permissions, current_api_permissions);
1466201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1467201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1468201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Tests that the granted permissions preferences are initialized when
1469201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // migrating from the old pref schema.
1470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  current_api_permissions.clear();
1471201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  current_host_permissions.ClearPaths();
1472201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1473201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ClearPref(extension_id, "granted_permissions");
1474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1475201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->ReloadExtensions();
1476201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1477201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
1478201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  extension = service_->extensions()->at(0);
1479201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1480201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED);
1481201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1482201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1483201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id,
1484201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_full_access,
1485201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_api_permissions,
1486201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                           &current_host_permissions));
1487201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1488201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_FALSE(current_full_access);
1489201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(expected_api_permissions, current_api_permissions);
1490201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  AssertEqualExtents(&expected_host_permissions, &current_host_permissions);
1491201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1492201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test Packaging and installing an extension.
149421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, PackExtension) {
149521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath input_directory = data_dir_
1497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("good")
1498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions")
1499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("1.0.0.0");
1501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedTempDir temp_dir;
1503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath output_directory = temp_dir.path();
1505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
1508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(),
1511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      privkey_path));
1512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::PathExists(privkey_path));
1514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(crx_path, true);
1515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try packing with invalid paths.
1517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  creator.reset(new ExtensionCreator());
1518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath()));
1519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try packing an empty directory. Should fail because an empty directory is
1521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // not a valid extension.
1522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedTempDir temp_dir2;
1523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
1524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  creator.reset(new ExtensionCreator());
1525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
1526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            FilePath()));
1527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try packing with an invalid manifest.
1529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string invalid_manifest_content = "I am not a manifest.";
1530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::WriteFile(
1531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      temp_dir2.path().Append(Extension::kManifestFilename),
1532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      invalid_manifest_content.c_str(), invalid_manifest_content.size()));
1533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  creator.reset(new ExtensionCreator());
1534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
1535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            FilePath()));
1536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
15383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test Packaging and installing an extension whose name contains punctuation.
153921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
154021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath input_directory = data_dir_
15423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      .AppendASCII("good")
15433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      .AppendASCII("Extensions")
15443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      .AppendASCII(good0)
15453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      .AppendASCII("1.0.0.0");
15463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ScopedTempDir temp_dir;
15483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
15493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Extension names containing punctuation, and the expected names for the
15513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // packed extensions.
15523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const FilePath punctuated_names[] = {
15533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL("this.extensions.name.has.periods"))),
15553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod"))),
15573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NormalizeSeparators(FilePath(FilePath::StringType(
15583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")))),
15593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
15603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const FilePath expected_crx_names[] = {
15613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL("this.extensions.name.has.periods.crx"))),
15633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx"))),
15653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx"))),
15673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
15683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const FilePath expected_private_key_names[] = {
15693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL("this.extensions.name.has.periods.pem"))),
15713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem"))),
15733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath(FilePath::StringType(
15743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem"))),
15753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  };
15763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
15783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SCOPED_TRACE(punctuated_names[i].value().c_str());
15793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
15803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // Copy the extension into the output directory, as PackExtensionJob doesn't
15823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // let us choose where to output the packed extension.
15833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true));
15843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath expected_crx_path = temp_dir.path().Append(expected_crx_names[i]);
15863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FilePath expected_private_key_path =
15873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        temp_dir.path().Append(expected_private_key_names[i]);
15883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    PackExtensionTestClient pack_client(expected_crx_path,
15893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                        expected_private_key_path);
15903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    scoped_refptr<PackExtensionJob> packer(new PackExtensionJob(&pack_client,
15913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                                output_dir,
15923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                                FilePath()));
15933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    packer->Start();
15943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
15953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // The packer will post a notification task to the current thread's message
15963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // loop when it is finished.  We manually run the loop here so that we
15973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // block and catch the notification; otherwise, the process would exit.
15983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // This call to |Run()| is matched by a call to |Quit()| in the
15993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // |PackExtensionTestClient|'s notification handling code.
16003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    MessageLoop::current()->Run();
16013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
16023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (HasFatalFailure())
16033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return;
16043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    InstallCrx(expected_crx_path, true);
16063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
16073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
16083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test Packaging and installing an extension using an openssl generated key.
1610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The openssl is generated with the following:
1611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// > openssl genrsa -out privkey.pem 1024
1612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
1613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
1614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
161521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
161621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath input_directory = data_dir_
1618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("good")
1619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions")
1620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("1.0.0.0");
1622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath privkey_path(data_dir_.AppendASCII(
1623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "openssl_privkey_asn1.pem"));
1624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::PathExists(privkey_path));
1625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ScopedTempDir temp_dir;
1627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath output_directory = temp_dir.path();
1629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
1633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
1634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      FilePath()));
1635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(crx_path, true);
1637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
163921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, InstallTheme) {
164021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A theme.
1643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("theme.crx");
1644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int pref_count = 0;
1646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(++pref_count);
16473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
16483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(theme_crx, "location", Extension::INTERNAL);
1649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A theme when extensions are disabled. Themes can be installed, even when
1651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // extensions are disabled.
1652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_extensions_enabled(false);
1653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("theme2.crx");
1654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(++pref_count);
16563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
16573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(theme2_crx, "location", Extension::INTERNAL);
1658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A theme with extension elements. Themes cannot have extension elements so
1660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // this test should fail.
1661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_extensions_enabled(true);
1662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("theme_with_extension.crx");
1663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, false);
1664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(pref_count);
1665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A theme with image resources missing (misspelt path).
1667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("theme_missing_image.crx");
1668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, false);
1669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(pref_count);
1670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
1673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Load.
167421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath extension_path = data_dir_
1676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("theme_i18n");
1677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->LoadExtension(extension_path);
1679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, GetErrors().size());
1681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
1682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
1683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("name", service_->extensions()->at(0)->name());
1684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("description", service_->extensions()->at(0)->description());
1685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
168821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath theme_path = data_dir_
1690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("theme_i18n");
1691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(theme_path, true);
1693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, GetErrors().size());
1695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
1696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("name", service_->extensions()->at(0)->name());
1697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("description", service_->extensions()->at(0)->description());
1698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, InstallApps) {
170121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // An empty app.
1704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
1705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int pref_count = 0;
1706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(++pref_count);
1707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, service_->extensions()->size());
1708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id = service_->extensions()->at(0)->id();
17093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(id, "state", Extension::ENABLED);
17103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(id, "location", Extension::INTERNAL);
1711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Another app with non-overlapping extent. Should succeed.
1713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(data_dir_.AppendASCII("app2"), true);
1714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(++pref_count);
1715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A third app whose extent overlaps the first. Should fail.
1717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(data_dir_.AppendASCII("app3"), false);
1718513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ValidatePrefKeyCount(pref_count);
1719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(ExtensionServiceTest, UpdateApps) {
172272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  InitializeEmptyExtensionService();
1723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath extensions_path = data_dir_.AppendASCII("app_update");
172472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
172572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // First install v1 of a hosted app.
1726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(extensions_path.AppendASCII("v1.crx"), true);
172772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(1u, service_->extensions()->size());
172872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::string id = service_->extensions()->at(0)->id();
172972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(std::string("1"),
173072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            service_->extensions()->at(0)->version()->GetString());
173172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
173272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Now try updating to v2.
173372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UpdateExtension(id,
173472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  extensions_path.AppendASCII("v2.crx"),
173572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  ENABLED);
173672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(std::string("2"),
173772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            service_->extensions()->at(0)->version()->GetString());
173872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
173972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
174021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) {
174121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
17423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(service_->extensions()->empty());
17433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int pref_count = 0;
17453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Install app1 with unlimited storage.
1747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
17483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidatePrefKeyCount(++pref_count);
17493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(1u, service_->extensions()->size());
1750513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service_->extensions()->at(0);
17513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::string id1 = extension->id();
17523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(extension->HasApiPermission(
17533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  Extension::kUnlimitedStoragePermission));
17543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(extension->web_extent().ContainsURL(
17553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  extension->GetFullLaunchURL()));
17563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
1757dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1758dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageUnlimited(origin1));
17593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Install app2 from the same origin with unlimited storage.
1761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(data_dir_.AppendASCII("app2"), true);
17623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidatePrefKeyCount(++pref_count);
17633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(2u, service_->extensions()->size());
17643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension = service_->extensions()->at(1);
17653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::string id2 = extension->id();
17663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(extension->HasApiPermission(
17673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  Extension::kUnlimitedStoragePermission));
17683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(extension->web_extent().ContainsURL(
17693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                  extension->GetFullLaunchURL()));
17703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
17713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(origin1, origin2);
1772dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1773dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageUnlimited(origin2));
1774dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
17753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Uninstall one of them, unlimited storage should still be granted
17773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // to the origin.
1778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(id1, false, NULL);
17793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
17803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1u, service_->extensions()->size());
1781dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1782dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageUnlimited(origin1));
1783dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
17843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Uninstall the other, unlimited storage should be revoked.
1786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(id2, false, NULL);
17873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
17883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(0u, service_->extensions()->size());
1789dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1790dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageUnlimited(origin2));
17913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
17923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
179321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
179421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
17953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(service_->extensions()->empty());
17963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
17973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int pref_count = 0;
17983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1799ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(data_dir_.AppendASCII("app1"), true);
18003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidatePrefKeyCount(++pref_count);
18013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(1u, service_->extensions()->size());
1802513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service_->extensions()->at(0);
18033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(extension->is_app());
18043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::string id1 = extension->id();
18053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
1806dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1807dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageProtected(origin1));
18083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
18093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // App 4 has a different origin (maps.google.com).
1810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PackAndInstallCrx(data_dir_.AppendASCII("app4"), true);
18113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidatePrefKeyCount(++pref_count);
18123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(2u, service_->extensions()->size());
18133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension = service_->extensions()->at(1);
18143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const std::string id2 = extension->id();
18153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
18163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_NE(origin1, origin2);
1817dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
1818dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageProtected(origin2));
18193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1820ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(id1, false, NULL);
18213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
18223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1u, service_->extensions()->size());
18233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(id2, false, NULL);
18253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
18263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
18273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_TRUE(service_->extensions()->empty());
1828dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1829dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageProtected(origin1));
1830dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
1831dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      IsStorageProtected(origin2));
18323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
18333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that when an extension version is reinstalled, nothing happens.
183521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, Reinstall) {
183621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A simple extension that should install without error.
1839ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1840dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
1841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(installed_);
1844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
1845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
1846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
18473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
18483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
1849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  installed_ = NULL;
1851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loaded_.clear();
1852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionErrorReporter::GetInstance()->ClearErrors();
1853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reinstall the same version, it should overwrite the previous one.
1855dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
1856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(installed_);
1859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
1860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
1861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
18623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
18633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
1864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test upgrading a signed extension.
186721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpgradeSignedGood) {
186821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1871dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
1872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(installed_);
1875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
1876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
1877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
1878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Upgrade to version 2.0
1880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("good2.crx");
1881dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
1882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(installed_);
1885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
1886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
1887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
1888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test upgrading a signed extension with a bad signature.
189121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpgradeSignedBad) {
189221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1895dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
1896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(installed_);
1899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
1900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
1901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  installed_ = NULL;
1902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try upgrading with a bad signature. This should fail during the unpack,
1904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // because the key will not match the signature.
1905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("bad_signature.crx");
1906dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
1907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(installed_);
1910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
1911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, GetErrors().size());
1912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test a normal update via the UpdateExtension API
191521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdateExtension) {
191621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1921513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* good = service_->extensions()->at(0);
1922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.0", good->VersionString());
1923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(good_crx, good->id());
1924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("good2.crx");
1926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(good_crx, path, ENABLED);
1927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
1928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test updating a not-already-installed extension - this should fail
193121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
193221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(good_crx, path, UPDATED);
1936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
1937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, service_->extensions()->size());
1939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(installed_);
1940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, loaded_.size());
1941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Makes sure you can't downgrade an extension via UpdateExtension
194421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
194521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good2.crx");
1948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1950513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* good = service_->extensions()->at(0);
1951c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.1", good->VersionString());
1952c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(good_crx, good->id());
1953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Change path from good2.crx -> good.crx
1955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("good.crx");
1956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(good_crx, path, FAILED);
1957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.1", service_->extensions()->at(0)->VersionString());
1958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Make sure calling update with an identical version does nothing
196121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
196221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
1965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1967513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* good = service_->extensions()->at(0);
1968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(good_crx, good->id());
1969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(good_crx, path, FAILED_SILENTLY);
1970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1971c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Tests that updating an extension does not clobber old state.
197321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
197421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
19753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
19773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
1979513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* good = service_->extensions()->at(0);
19803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ("1.0.0.0", good->VersionString());
19813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(good_crx, good->id());
19823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
19833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Disable it and allow it to run in incognito. These settings should carry
19843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // over to the updated version.
19853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  service_->DisableExtension(good->id());
1986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->SetIsIncognitoEnabled(good->id(), true);
19873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("good2.crx");
19893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateExtension(good_crx, path, INSTALLED);
19903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(1u, service_->disabled_extensions()->size());
1991513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* good2 = service_->disabled_extensions()->at(0);
19923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ("1.0.0.1", good2->version()->GetString());
1993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->IsIncognitoEnabled(good2->id()));
19943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
19953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1996201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Tests that updating preserves extension location.
199721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
199821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
1999201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2001201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2003201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const Extension* good = service_->extensions()->at(0);
2004201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2005201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ("1.0.0.0", good->VersionString());
2006201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(good_crx, good->id());
2007201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2008201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Simulate non-internal location.
2009201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const_cast<Extension*>(good)->location_ = Extension::EXTERNAL_PREF;
2010201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  path = data_dir_.AppendASCII("good2.crx");
2012201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  UpdateExtension(good_crx, path, ENABLED);
2013201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const Extension* good2 = service_->extensions()->at(0);
2014201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2015201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(good2->location(), Extension::EXTERNAL_PREF);
2016201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
2017201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
201821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Makes sure that LOAD extension types can downgrade.
201921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
202021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
202121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
202221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ScopedTempDir temp;
202321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_TRUE(temp.CreateUniqueTempDir());
202421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
202521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // We'll write the extension manifest dynamically to a temporary path
202621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // to make it easier to change the version number.
202721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  FilePath extension_path = temp.path();
202821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  FilePath manifest_path = extension_path.Append(Extension::kManifestFilename);
202921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_FALSE(file_util::PathExists(manifest_path));
203021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
203121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Start with version 2.0.
203221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DictionaryValue manifest;
203321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  manifest.SetString("version", "2.0");
203421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  manifest.SetString("name", "LOAD Downgrade Test");
203521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
203621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  JSONFileValueSerializer serializer(manifest_path);
203721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_TRUE(serializer.Serialize(manifest));
203821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
203921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  service_->LoadExtension(extension_path);
204021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loop_.RunAllPending();
204121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
204221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(0u, GetErrors().size());
204321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_EQ(1u, loaded_.size());
204421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
204521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(1u, service_->extensions()->size());
204621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ("2.0", loaded_[0]->VersionString());
204721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
204821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Now set the version number to 1.0, reload the extensions and verify that
204921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // the downgrade was accepted.
205021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  manifest.SetString("version", "1.0");
205121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_TRUE(serializer.Serialize(manifest));
205221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
205321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  service_->LoadExtension(extension_path);
205421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loop_.RunAllPending();
205521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
205621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(0u, GetErrors().size());
205721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ASSERT_EQ(1u, loaded_.size());
205821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
205921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(1u, service_->extensions()->size());
206021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ("1.0", loaded_[0]->VersionString());
206121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
206221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
206321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace {
206421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
206521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool IsExtension(const Extension& extension) {
206621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return extension.GetType() == Extension::TYPE_EXTENSION;
206721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
206821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
206921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace
207021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test adding a pending extension.
207221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
207321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::string kFakeId(all_zero);
2076c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const GURL kFakeUpdateURL("http:://fake.update/url");
2077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const bool kFakeInstallSilently(true);
2078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const Extension::State kFakeInitialState(Extension::ENABLED);
2079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const bool kFakeInitialIncognitoEnabled(false);
2080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2081ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromSync(
208221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kFakeId, kFakeUpdateURL, &IsExtension,
208321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kFakeInstallSilently, kFakeInitialState, kFakeInitialIncognitoEnabled);
2084ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2085ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PendingExtensionInfo pending_extension_info;
2086ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      kFakeId, &pending_extension_info));
2088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(kFakeUpdateURL, pending_extension_info.update_url());
2089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(&IsExtension, pending_extension_info.should_allow_install_);
2090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(kFakeInstallSilently, pending_extension_info.install_silently());
2091c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2092c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2093c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
2094c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kGoodUpdateURL[] = "http://good.update/url";
20963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst bool kGoodIsFromSync = true;
2097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst bool kGoodInstallSilently = true;
2098c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst Extension::State kGoodInitialState = Extension::DISABLED;
2099c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst bool kGoodInitialIncognitoEnabled = true;
2100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
2101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test updating a pending extension.
210321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdatePendingExtension) {
210421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromSync(
210621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kGoodId, GURL(kGoodUpdateURL), &IsExtension,
2107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kGoodInstallSilently, kGoodInitialState,
2108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kGoodInitialIncognitoEnabled);
2109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(kGoodId, path, INSTALLED);
2113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service_->GetExtensionById(kGoodId, true);
2117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(extension);
2118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool enabled = service_->GetExtensionById(kGoodId, false);
2120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_EQ(enabled, kGoodInitialState == Extension::ENABLED);
2121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kGoodInitialState,
2122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            service_->extension_prefs()->GetExtensionState(extension->id()));
2123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kGoodInitialIncognitoEnabled,
2124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            service_->IsIncognitoEnabled(extension->id()));
2125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
212721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsennamespace {
212821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
212921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool IsTheme(const Extension& extension) {
213021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return extension.is_theme();
213121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
213221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
213321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace
213421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test updating a pending theme.
213621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdatePendingTheme) {
213721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromSync(
213921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      theme_crx, GURL(), &IsTheme,
21403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      false, Extension::ENABLED, false);
2141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
21423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("theme.crx");
21443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateExtension(theme_crx, path, ENABLED);
21453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
21473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service_->GetExtensionById(theme_crx, true);
21493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(extension);
21503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
21513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(Extension::ENABLED,
21523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            service_->extension_prefs()->GetExtensionState(extension->id()));
2153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
21543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
21553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
2157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Always fails on ChromeOS: http://crbug.com/79737
2158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_UpdatePendingExternalCrx FAILS_UpdatePendingExternalCrx
2159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
2160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
2161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
21623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Test updating a pending CRX as if the source is an external extension
21633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// with an update URL.  In this case we don't know if the CRX is a theme
21643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// or not.
2165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
216621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      theme_crx, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
21693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("theme.crx");
2173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(theme_crx, path, ENABLED);
2174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
2176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service_->GetExtensionById(theme_crx, true);
2178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(extension);
2179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(Extension::ENABLED,
2181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            service_->extension_prefs()->GetExtensionState(extension->id()));
2182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id()));
2183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Test updating a pending CRX as if the source is an external extension
2186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// with an update URL.  The external update should overwrite a sync update,
2187513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// but a sync update should not overwrite a non-sync update.
218821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
218921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2191513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Add a crx to be installed from the update mechanism.
2192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromSync(
219321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kGoodId, GURL(kGoodUpdateURL), &IsExtension,
2194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      kGoodInstallSilently, kGoodInitialState,
2195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      kGoodInitialIncognitoEnabled);
2196513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2197513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Check that there is a pending crx, with is_from_sync set to true.
2198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PendingExtensionInfo pending_extension_info;
2199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      kGoodId, &pending_extension_info));
2201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(pending_extension_info.is_from_sync());
2202513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2203513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Add a crx to be updated, with the same ID, from a non-sync source.
2204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromExternalUpdateUrl(
2205513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD);
2206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Check that there is a pending crx, with is_from_sync set to false.
2208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      kGoodId, &pending_extension_info));
2210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(pending_extension_info.is_from_sync());
2211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
2212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            pending_extension_info.install_source());
2213513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Add a crx to be installed from the update mechanism.
2215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromSync(
221621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kGoodId, GURL(kGoodUpdateURL), &IsExtension,
2217513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      kGoodInstallSilently, kGoodInitialState,
2218513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      kGoodInitialIncognitoEnabled);
2219513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2220513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Check that the external, non-sync update was not overridden.
2221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(service_->pending_extension_manager()->GetById(
2222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      kGoodId, &pending_extension_info));
2223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(pending_extension_info.is_from_sync());
2224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD,
2225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            pending_extension_info.install_source());
2226513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
2227513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
22283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Updating a theme should fail if the updater is explicitly told that
22293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// the CRX is not a theme.
223021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
223121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromSync(
223321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      theme_crx, GURL(), &IsExtension,
22343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      true, Extension::ENABLED, false);
22353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
22373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("theme.crx");
22393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UpdateExtension(theme_crx, path, FAILED_SILENTLY);
22403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
22423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2243513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service_->GetExtensionById(theme_crx, true);
22443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_FALSE(extension);
22453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
22463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(akalin): Test updating a pending extension non-silently once
2248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// we can mock out ExtensionInstallUI and inject our version into
2249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// UpdateExtension().
2250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Test updating a pending extension which fails the should-install test.
225221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
225321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add pending extension with a flipped is_theme.
2255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddFromSync(
225621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kGoodId, GURL(kGoodUpdateURL), &IsTheme,
225721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kGoodInstallSilently, kGoodInitialState,
2258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kGoodInitialIncognitoEnabled);
2259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(kGoodId, path, UPDATED);
2263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(akalin): Figure out how to check that the extensions
2265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // directory is cleaned up properly in OnExtensionInstalled().
2266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(akalin): Figure out how to test that installs of pending
2271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// unsyncable extensions are blocked.
2272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test updating a pending extension for one that is not pending.
227421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
227521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(kGoodId, path, UPDATED);
2279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test updating a pending extension for one that is already
2284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// installed.
228521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
228621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, service_->extensions()->size());
2291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* good = service_->extensions()->at(0);
2292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(good->is_theme());
22943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Use AddExtensionImpl() as AddFrom*() would balk.
2296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->pending_extension_manager()->AddExtensionImpl(
229721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      good->id(), good->update_url(), &IsExtension,
22983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      kGoodIsFromSync, kGoodInstallSilently, kGoodInitialState,
2299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      kGoodInitialIncognitoEnabled, Extension::INTERNAL);
2300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(good->id(), path, INSTALLED);
2301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
2303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test pref settings for blacklist and unblacklist extensions.
230621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
230721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> blacklist;
2309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.push_back(good0);
2310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.push_back("invalid_id");  // an invalid id
2311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.push_back(good1);
2312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->UpdateExtensionBlacklist(blacklist);
2313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure pref is updated
2314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // blacklist is set for good0,1,2
23173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good0, "blacklist", true);
23183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good1, "blacklist", true);
2319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // invalid_id should not be inserted to pref.
23203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
2321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // remove good1, add good2
2323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.pop_back();
2324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.push_back(good2);
2325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->UpdateExtensionBlacklist(blacklist);
2327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // only good0 and good1 should be set
23283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good0, "blacklist", true);
23293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
23303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good2, "blacklist", true);
23313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
2332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Unload installed extension from blacklist.
233521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) {
233621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2341513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* good = service_->extensions()->at(0);
2342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(good_crx, good->id());
2343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UpdateExtension(good_crx, path, FAILED_SILENTLY);
2344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> blacklist;
2346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.push_back(good_crx);
2347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->UpdateExtensionBlacklist(blacklist);
2348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure pref is updated
2349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now, the good_crx is blacklisted.
23523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good_crx, "blacklist", true);
2353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service_->extensions()->size());
2354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Remove good_crx from blacklist
2356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.pop_back();
2357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->UpdateExtensionBlacklist(blacklist);
2358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure pref is updated
2359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // blacklist value should not be set for good_crx
23613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_FALSE(IsPrefExist(good_crx, "blacklist"));
2362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Unload installed extension from blacklist.
236521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
236621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> blacklist;
2368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  blacklist.push_back(good_crx);
2369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->UpdateExtensionBlacklist(blacklist);
2370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure pref is updated
2371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now, the good_crx is blacklisted.
23743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good_crx, "blacklist", true);
2375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We can not install good_crx.
2377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2378dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
2379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service_->extensions()->size());
23813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good_crx, "blacklist", true);
2382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test loading extensions from the profile directory, except
2385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// blacklisted ones.
238621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
2387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialize the test dir with a good Preferences/extensions.
2388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_install_dir = data_dir_
2389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("good")
2390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions");
2391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath pref_path = source_install_dir
2392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .DirName()
2393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Preferences");
239421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeInstalledExtensionService(pref_path, source_install_dir);
2395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
23963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Blacklist good1.
2397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> blacklist;
23983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  blacklist.push_back(good1);
2399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->UpdateExtensionBlacklist(blacklist);
2400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure pref is updated
2401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateBooleanPref(good1, "blacklist", true);
2404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Load extensions.
2406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->Init();
2407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> errors = GetErrors();
2410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<std::string>::iterator err = errors.begin();
2411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    err != errors.end(); ++err) {
2412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LOG(ERROR) << *err;
2413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
2414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(2u, loaded_.size());
2415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
24163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_NE(std::string(good1), loaded_[0]->id());
24173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_NE(std::string(good1), loaded_[1]->id());
24183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
24193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Will not install extension blacklisted by policy.
242121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
242221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
24233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Blacklist everything.
2425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
2426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListPrefUpdate update(profile_->GetPrefs(),
2427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          prefs::kExtensionInstallDenyList);
2428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListValue* blacklist = update.Get();
2429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    blacklist->Append(Value::CreateStringValue("*"));
2430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
24313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Blacklist prevents us from installing good_crx.
2433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2434dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
24353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
24363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(0u, service_->extensions()->size());
24373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Now whitelist this particular extension.
2439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
2440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListPrefUpdate update(profile_->GetPrefs(),
2441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          prefs::kExtensionInstallAllowList);
2442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListValue* whitelist = update.Get();
2443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    whitelist->Append(Value::CreateStringValue(good_crx));
2444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
24463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Ensure we can now install good_crx.
2448dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
24493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
24503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1u, service_->extensions()->size());
24513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
24523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Extension blacklisted by policy get unloaded after installing.
245421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
245521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
24563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Install good_crx.
2458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2459dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  StartCrxInstall(path);
24603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
24613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(1u, service_->extensions()->size());
24623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
246321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  { // Scope for pref update notification.
246421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    PrefService* prefs = profile_->GetPrefs();
2465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList);
2466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListValue* blacklist = update.Get();
246721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ASSERT_TRUE(blacklist != NULL);
246821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
246921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Blacklist this extension.
247021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    blacklist->Append(Value::CreateStringValue(good_crx));
247121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    prefs->ScheduleSavePersistentPrefs();
247221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
24733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
24743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Extension should not be running now.
24753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  loop_.RunAllPending();
24763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(0u, service_->extensions()->size());
2477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests disabling extensions
248021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, DisableExtension) {
248121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A simple extension that should install without error.
2484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* extension_id = good_crx;
2488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(service_->extensions()->empty());
2489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
2490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->GetExtensionById(extension_id, false) != NULL);
2491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->disabled_extensions()->empty());
2492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Disable it.
2494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->DisableExtension(extension_id);
2495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->extensions()->empty());
2497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL);
2498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(service_->GetExtensionById(extension_id, false) != NULL);
2499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(service_->disabled_extensions()->empty());
2500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2502201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Tests disabling all extensions (simulating --disable-extensions flag).
250321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, DisableAllExtensions) {
250421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2505201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2506201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2509201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2510201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
2511201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, service_->disabled_extensions()->size());
2512201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2513201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Disable extensions.
2514201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->set_extensions_enabled(false);
2515201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->ReloadExtensions();
2516201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2517201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // There shouldn't be extensions in either list.
2518201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, service_->extensions()->size());
2519201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, service_->disabled_extensions()->size());
2520201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2521201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // This shouldn't do anything when all extensions are disabled.
2522201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->EnableExtension(good_crx);
2523201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->ReloadExtensions();
2524201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2525201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // There still shouldn't be extensions in either list.
2526201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, service_->extensions()->size());
2527201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, service_->disabled_extensions()->size());
2528201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2529201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // And then re-enable the extensions.
2530201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->set_extensions_enabled(true);
2531201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->ReloadExtensions();
2532201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2533201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
2534201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0u, service_->disabled_extensions()->size());
2535201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
2536201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests reloading extensions
253821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ReloadExtensions) {
253921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Simple extension that should install without error.
2542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* extension_id = good_crx;
2545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->DisableExtension(extension_id);
2546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service_->extensions()->size());
2548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->disabled_extensions()->size());
2549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->ReloadExtensions();
2551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extension counts shouldn't change.
2553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service_->extensions()->size());
2554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->disabled_extensions()->size());
2555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->EnableExtension(extension_id);
2557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
2559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service_->disabled_extensions()->size());
2560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Need to clear |loaded_| manually before reloading as the
2562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // EnableExtension() call above inserted into it and
2563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // UnloadAllExtensions() doesn't send out notifications.
2564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loaded_.clear();
2565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->ReloadExtensions();
2566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extension counts shouldn't change.
2568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
2569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service_->disabled_extensions()->size());
2570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests uninstalling normal extensions
257321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UninstallExtension) {
257421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // A simple extension that should install without error.
2577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The directory should be there now.
2581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const char* extension_id = good_crx;
2582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
2583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(file_util::PathExists(extension_path));
2584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
25863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
25873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", Extension::INTERNAL);
2588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Uninstall it.
2590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(extension_id, false, NULL);
2591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  total_successes_ = 0;
2592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We should get an unload notification.
2594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(unloaded_id_.length());
2595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(extension_id, unloaded_id_);
2596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(0);
2598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The extension should not be in the service anymore.
2600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
2601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The directory should be gone.
2604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(file_util::PathExists(extension_path));
2605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2607731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Tests the uninstaller helper.
260821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
260921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2610731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2611731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // A simple extension that should install without error.
2612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_.AppendASCII("good.crx");
2613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2614731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2615731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The directory should be there now.
2616731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const char* extension_id = good_crx;
2617731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id);
2618731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(file_util::PathExists(extension_path));
2619731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
262021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  bool result = ExtensionService::UninstallExtensionHelper(service_,
2621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                           extension_id);
2622731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  total_successes_ = 0;
2623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2624731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_TRUE(result);
2625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // We should get an unload notification.
2627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_TRUE(unloaded_id_.length());
2628731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_EQ(extension_id, unloaded_id_);
2629731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2630731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ValidatePrefKeyCount(0);
2631731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2632731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The extension should not be in the service anymore.
2633731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ASSERT_FALSE(service_->GetExtensionById(extension_id, false));
2634731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  loop_.RunAllPending();
2635731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2636731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // The directory should be gone.
2637731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(file_util::PathExists(extension_path));
2638731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2639731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Attempt to uninstall again. This should fail as we just removed the
2640731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // extension.
264121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  result = ExtensionService::UninstallExtensionHelper(service_, extension_id);
2642731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  EXPECT_FALSE(result);
2643731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
2644731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Verifies extension state is removed upon uninstall
264621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ClearExtensionData) {
264721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Load a test extension.
2650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_;
2651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  path = path.AppendASCII("good.crx");
2652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(path, true);
2653513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service_->GetExtensionById(good_crx, false);
2654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(extension);
2655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL ext_url(extension->url());
2656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 origin_id =
2657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      webkit_database::DatabaseUtil::GetOriginIdentifier(ext_url);
2658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set a cookie for the extension.
2660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::CookieMonster* cookie_monster =
2661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
2662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      cookie_store()->GetCookieMonster();
2663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(cookie_monster);
2664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  net::CookieOptions options;
2665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  cookie_monster->SetCookieWithOptions(ext_url, "dummy=value", options);
266621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  net::CookieList list = cookie_monster->GetAllCookiesForURL(ext_url);
2667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, list.size());
2668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open a database.
2670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
2671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 db_name = UTF8ToUTF16("db");
2672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 description = UTF8ToUTF16("db_description");
2673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 size;
2674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 available;
2675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size,
2676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             &available);
2677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->DatabaseClosed(origin_id, db_name);
2678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<webkit_database::OriginInfo> origins;
2679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->GetAllOriginsInfo(&origins);
2680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1U, origins.size());
2681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(origin_id, origins[0].GetOrigin());
2682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create local storage. We only simulate this by creating the backing file
2684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // since webkit is not initialized.
2685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DOMStorageContext* context =
2686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_->GetWebKitContext()->dom_storage_context();
2687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath lso_path = context->GetLocalStorageFilePath(origin_id);
2688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(file_util::CreateDirectory(lso_path.DirName()));
2689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0, file_util::WriteFile(lso_path, NULL, 0));
2690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(file_util::PathExists(lso_path));
2691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2692201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Create indexed db. Again, it is enough to only simulate this by creating
2693201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // the file on the disk.
2694201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  IndexedDBContext* idb_context =
2695201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      profile_->GetWebKitContext()->indexed_db_context();
2696201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FilePath idb_path = idb_context->GetIndexedDBFilePath(origin_id);
2697201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(file_util::CreateDirectory(idb_path.DirName()));
2698201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(0, file_util::WriteFile(idb_path, NULL, 0));
2699201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_TRUE(file_util::PathExists(idb_path));
2700201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Uninstall the extension.
2702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(good_crx, false, NULL);
2703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the cookie is gone.
2706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  list = cookie_monster->GetAllCookiesForURL(ext_url);
2707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0U, list.size());
2708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The database should have vanished as well.
2710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  origins.clear();
2711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->GetAllOriginsInfo(&origins);
2712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0U, origins.size());
2713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Check that the LSO file has been removed.
2715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(file_util::PathExists(lso_path));
2716201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2717201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Check if the indexed db has disappeared too.
2718201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_FALSE(file_util::PathExists(idb_path));
2719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests loading single extensions (like --load-extension)
272221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, LoadExtension) {
272321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath ext1 = data_dir_
2726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("good")
2727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions")
2728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("1.0.0.0");
2730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->LoadExtension(ext1);
2731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, GetErrors().size());
2733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
2734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(Extension::LOAD, loaded_[0]->location());
2735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
2736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
2738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath no_manifest = data_dir_
2740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("bad")
2741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // .AppendASCII("Extensions")
2742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("cccccccccccccccccccccccccccccccc")
2743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("1");
2744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->LoadExtension(no_manifest);
2745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, GetErrors().size());
2747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
2748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
2749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Test uninstall.
2751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id = loaded_[0]->id();
2752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(unloaded_id_.length());
2753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(id, false, NULL);
2754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(id, unloaded_id_);
2756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, loaded_.size());
2757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service_->extensions()->size());
2758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we generate IDs when they are not specified in the manifest for
2761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// --load-extension.
276221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, GenerateID) {
276321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath no_id_ext = data_dir_.AppendASCII("no_id");
2767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->LoadExtension(no_id_ext);
2768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, GetErrors().size());
2770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
2771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
2772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(loaded_[0]->location(), Extension::LOAD);
2773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
2775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string previous_id = loaded_[0]->id();
2777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we reload the same path, we should get the same extension ID.
2779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->LoadExtension(no_id_ext);
2780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
2782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(previous_id, loaded_[0]->id());
2783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
278521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenvoid ExtensionServiceTest::TestExternalProvider(
2786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MockExtensionProvider* provider, Extension::Location location) {
2787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Verify that starting with no providers loads no extensions.
2788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->Init();
2789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, loaded_.size());
2791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2792513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  provider->set_visit_count(0);
2793513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Register a test extension externally using the mock registry provider.
2795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_path = data_dir_.AppendASCII("good.crx");
2796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the extension.
2798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
2799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reloading extensions should find our externally registered extension
2801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // and install it.
2802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->CheckForExternalUpdates();
2803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
2806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
2807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(location, loaded_[0]->location());
2808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
2809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
28103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
28113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", location);
2812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reload extensions without changing anything. The extension should be
2814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // loaded again.
2815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loaded_.clear();
2816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->ReloadExtensions();
2817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
2819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
2820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
28213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
28223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", location);
2823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now update the extension with a new version. We should get upgraded.
2825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  source_path = source_path.DirName().AppendASCII("good2.crx");
2826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
2827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loaded_.clear();
2829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->CheckForExternalUpdates();
2830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(0u, GetErrors().size());
2832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
2833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
2834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
28353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
28363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", location);
2837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Uninstall the extension and reload. Nothing should happen because the
2839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // preference should prevent us from reinstalling.
2840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string id = loaded_[0]->id();
2841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->UninstallExtension(id, false, NULL);
2842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
2843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath install_path = extensions_install_dir_.AppendASCII(id);
2845ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // It should not be possible to uninstall a policy controlled extension.
2846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (Extension::UserMayDisable(location)) {
2847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The extension should also be gone from the install directory.
2848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_FALSE(file_util::PathExists(install_path));
2849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loaded_.clear();
2850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->CheckForExternalUpdates();
2851ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loop_.RunAllPending();
2852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_EQ(0u, loaded_.size());
2853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ValidatePrefKeyCount(1);
2854ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ValidateIntegerPref(good_crx, "state",
2855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        Extension::EXTERNAL_EXTENSION_UNINSTALLED);
2856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ValidateIntegerPref(good_crx, "location", location);
2857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Now clear the preference and reinstall.
2859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SetPrefInteg(good_crx, "state", Extension::ENABLED);
2860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    profile_->GetPrefs()->ScheduleSavePersistentPrefs();
2861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loaded_.clear();
2863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->CheckForExternalUpdates();
2864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loop_.RunAllPending();
2865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_EQ(1u, loaded_.size());
2866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
2867ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Policy controlled extesions should not have been touched by uninstall.
2868ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_TRUE(file_util::PathExists(install_path));
2869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(1);
28713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
28723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ValidateIntegerPref(good_crx, "location", location);
2873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2874ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (Extension::UserMayDisable(location)) {
2875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Now test an externally triggered uninstall (deleting the registry key or
2876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // the pref entry).
2877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    provider->RemoveExtension(good_crx);
2878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loaded_.clear();
2880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->OnExternalProviderReady();
2881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loop_.RunAllPending();
2882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_EQ(0u, loaded_.size());
2883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ValidatePrefKeyCount(0);
2884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The extension should also be gone from the install directory.
2886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_FALSE(file_util::PathExists(install_path));
2887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Now test the case where user uninstalls and then the extension is removed
2889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // from the external provider.
2890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
2892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->CheckForExternalUpdates();
2893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loop_.RunAllPending();
2894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_EQ(1u, loaded_.size());
2896ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_EQ(0u, GetErrors().size());
2897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // User uninstalls.
2899ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loaded_.clear();
2900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->UninstallExtension(id, false, NULL);
2901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loop_.RunAllPending();
2902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_EQ(0u, loaded_.size());
2903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Then remove the extension from the extension provider.
2905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    provider->RemoveExtension(good_crx);
2906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Should still be at 0.
2908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loaded_.clear();
2909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->LoadAllExtensions();
2910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    loop_.RunAllPending();
2911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ASSERT_EQ(0u, loaded_.size());
2912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ValidatePrefKeyCount(1);
2913513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(5, provider->visit_count());
2915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
2916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(2, provider->visit_count());
2917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
2918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests the external installation feature
2921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN)
292221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
2923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This should all work, even when normal extension installation is disabled.
292421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  set_extensions_enabled(false);
2926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now add providers. Extension system takes ownership of the objects.
2928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockExtensionProvider* reg_provider =
292972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new MockExtensionProvider(service_.get(), Extension::EXTERNAL_REGISTRY);
2930513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  AddMockExternalProvider(reg_provider);
2931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY);
2932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
2934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ExternalInstallPref) {
293621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
2937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now add providers. Extension system takes ownership of the objects.
2939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockExtensionProvider* pref_provider =
294072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new MockExtensionProvider(service_.get(), Extension::EXTERNAL_PREF);
2941513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
2942513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  AddMockExternalProvider(pref_provider);
2943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF);
2944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
2945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
29473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This should all work, even when normal extension installation is disabled.
294821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
29493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  set_extensions_enabled(false);
29503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2951513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // TODO(skerner): The mock provider is not a good model of a provider
2952513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // that works with update URLs, because it adds file and version info.
2953513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // Extend the mock to work with update URLs.  This test checks the
2954513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // behavior that is common to all external extension visitors.  The
2955513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
2956513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // what the visitor does results in an extension being downloaded and
2957513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // installed.
29583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  MockExtensionProvider* pref_provider =
295972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new MockExtensionProvider(service_.get(),
296072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                Extension::EXTERNAL_PREF_DOWNLOAD);
2961513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  AddMockExternalProvider(pref_provider);
29623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF_DOWNLOAD);
29633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
29643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
2966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // This should all work, even when normal extension installation is disabled.
2967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
2968ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  set_extensions_enabled(false);
2969ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2970ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(skerner): The mock provider is not a good model of a provider
2971ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // that works with update URLs, because it adds file and version info.
2972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Extend the mock to work with update URLs. This test checks the
2973ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // behavior that is common to all external extension visitors. The
2974ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
2975ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // what the visitor does results in an extension being downloaded and
2976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // installed.
2977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockExtensionProvider* pref_provider =
2978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new MockExtensionProvider(service_.get(),
2979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                Extension::EXTERNAL_POLICY_DOWNLOAD);
2980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddMockExternalProvider(pref_provider);
2981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TestExternalProvider(pref_provider, Extension::EXTERNAL_POLICY_DOWNLOAD);
2982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
2983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
2984201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Tests that external extensions get uninstalled when the external extension
2985201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// providers can't account for them.
298621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ExternalUninstall) {
2987201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Start the extensions service with one external extension already installed.
2988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_install_dir = data_dir_
2989201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("good")
2990201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("Extensions");
2991201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FilePath pref_path = source_install_dir
2992201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .DirName()
2993201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      .AppendASCII("PreferencesExternal");
2994201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2995201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // This initializes the extensions service with no ExternalExtensionProviders.
299621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeInstalledExtensionService(pref_path, source_install_dir);
2997201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  set_extensions_enabled(false);
2998201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
2999201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->Init();
3000201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  loop_.RunAllPending();
3001201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3002201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(0u, GetErrors().size());
3003201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(0u, loaded_.size());
3004201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3005201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Verify that it's not the disabled extensions flag causing it not to load.
3006201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  set_extensions_enabled(true);
3007201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service_->ReloadExtensions();
3008201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  loop_.RunAllPending();
3009201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
3010201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(0u, GetErrors().size());
3011201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(0u, loaded_.size());
3012201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
3013201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
301472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that running multiple update checks simultaneously does not
301572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// keep the update from succeeding.
301672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
301772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  InitializeEmptyExtensionService();
301872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
301972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockExtensionProvider* provider =
302072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new MockExtensionProvider(service_.get(), Extension::EXTERNAL_PREF);
302172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  AddMockExternalProvider(provider);
302272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
302372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Verify that starting with no providers loads no extensions.
302472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->Init();
302572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  loop_.RunAllPending();
302672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(0u, loaded_.size());
302772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
302872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Start two checks for updates.
302972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  provider->set_visit_count(0);
303072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->CheckForExternalUpdates();
303172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->CheckForExternalUpdates();
303272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  loop_.RunAllPending();
303372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
303472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Two calls should cause two checks for external extensions.
303572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, provider->visit_count());
303672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(0u, GetErrors().size());
303772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(0u, loaded_.size());
303872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
303972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Register a test extension externally using the mock registry provider.
3040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_path = data_dir_.AppendASCII("good.crx");
304172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
304272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
304372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Two checks for external updates should find the extension, and install it
304472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // once.
304572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  provider->set_visit_count(0);
304672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->CheckForExternalUpdates();
304772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->CheckForExternalUpdates();
304872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  loop_.RunAllPending();
304972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, provider->visit_count());
305072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(0u, GetErrors().size());
305172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(1u, loaded_.size());
305272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location());
305372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
305472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ValidatePrefKeyCount(1);
305572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
305672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ValidateIntegerPref(good_crx, "location", Extension::EXTERNAL_PREF);
305772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
305872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  provider->RemoveExtension(good_crx);
305972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  provider->set_visit_count(0);
306072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->CheckForExternalUpdates();
306172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service_->CheckForExternalUpdates();
306272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  loop_.RunAllPending();
306372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
306472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Two calls should cause two checks for external extensions.
306572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Because the external source no longer includes good_crx,
306672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // good_crx will be uninstalled.  So, expect that no extensions
306772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // are loaded.
306872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, provider->visit_count());
306972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(0u, GetErrors().size());
307072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(0u, loaded_.size());
307172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
307272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
307321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ExternalPrefProvider) {
307421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
307572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
307672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Test some valid extension records.
307772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Set a base path to avoid erroring out on relative paths.
307872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Paths starting with // are absolute on every platform we support.
307972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath base_path(FILE_PATH_LITERAL("//base/path"));
308072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(base_path.IsAbsolute());
308172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockProviderVisitor visitor(base_path);
3082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string json_data =
3083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "{"
308472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
30853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_crx\": \"RandomExtension.crx\","
30863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_version\": \"1.0\""
30873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
30883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
30893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_crx\": \"RandomExtension2.crx\","
30903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_version\": \"2.0\""
30913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
30923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"cccccccccccccccccccccccccccccccc\": {"
30933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_update_url\": \"http:\\\\foo.com/update\""
30943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  }"
3095c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "}";
309672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(3, visitor.Visit(json_data));
3097c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Simulate an external_extensions.json file that contains seven invalid
309972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // records:
3100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - One that is missing the 'external_crx' key.
3101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - One that is missing the 'external_version' key.
3102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // - One that is specifying .. in the path.
31033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // - One that specifies both a file and update URL.
31043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // - One that specifies no file or update URL.
31053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // - One that has an update URL that is not well formed.
31063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // - One that contains a malformed version.
310772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // - One that has an invalid id.
310872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // - One that has a non-dictionary value.
31093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The final extension is valid, and we check that it is read to make sure
31103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // failures don't stop valid records from being read.
3111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  json_data =
3112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "{"
31133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
31143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_version\": \"1.0\""
31153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
31163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
31173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_crx\": \"RandomExtension.crx\""
31183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
31193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"cccccccccccccccccccccccccccccccc\": {"
31203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
31213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_version\": \"2.0\""
31223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
31233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"dddddddddddddddddddddddddddddddd\": {"
31243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_crx\": \"RandomExtension2.crx\","
31253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_version\": \"2.0\","
31263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_update_url\": \"http:\\\\foo.com/update\""
31273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
31283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
31293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
31303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"ffffffffffffffffffffffffffffffff\": {"
31313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_update_url\": \"This string is not a valid URL\""
31323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
31333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  \"gggggggggggggggggggggggggggggggg\": {"
31343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_crx\": \"RandomExtension3.crx\","
31353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_version\": \"This is not a valid version!\""
31363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  },"
313772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  \"This is not a valid id!\": {},"
313872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
313972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  \"pppppppppppppppppppppppppppppppp\": {"
31403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_crx\": \"RandomValidExtension.crx\","
31413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "    \"external_version\": \"1.0\""
31423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      "  }"
3143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "}";
314421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_EQ(1, visitor.Visit(json_data));
314572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
314672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check that if a base path is not provided, use of a relative
314772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // path fails.
314872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath empty;
314972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  MockProviderVisitor visitor_no_relative_paths(empty);
315072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
315172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Use absolute paths.  Expect success.
315272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  json_data =
315372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "{"
315472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
315572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "    \"external_crx\": \"//RandomExtension1.crx\","
315672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "    \"external_version\": \"3.0\""
315772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  },"
315872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
315972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "    \"external_crx\": \"//path/to/RandomExtension2.crx\","
316072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "    \"external_version\": \"3.0\""
316172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  }"
316272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "}";
316372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
316472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
316572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Use a relative path.  Expect that it will error out.
316672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  json_data =
316772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "{"
316872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  \"cccccccccccccccccccccccccccccccc\": {"
316972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "    \"external_crx\": \"RandomExtension2.crx\","
317072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "    \"external_version\": \"3.0\""
317172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "  }"
317272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      "}";
317372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
3174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test loading good extensions from the profile directory.
317721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
3178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Initialize the test dir with a good Preferences/extensions.
3179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath source_install_dir = data_dir_
3180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("l10n");
3181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath pref_path = source_install_dir.AppendASCII("Preferences");
318221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeInstalledExtensionService(pref_path, source_install_dir);
3183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->Init();
3185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
3186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(3u, loaded_.size());
3188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This was equal to "sr" on load.
3190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
3191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These are untouched by re-localization.
3193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
3194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
3195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This one starts with Serbian name, and gets re-localized into English.
3197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("My name is simple.", loaded_[0]->name());
3198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // These are untouched by re-localization.
3200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("My name is simple.", loaded_[1]->name());
3201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ("no l10n", loaded_[2]->name());
3202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionsReadyRecorder : public NotificationObserver {
3205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
3206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsReadyRecorder() : ready_(false) {
3207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    registrar_.Add(this, NotificationType::EXTENSIONS_READY,
3208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   NotificationService::AllSources());
3209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_ready(bool value) { ready_ = value; }
3212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ready() { return ready_; }
3213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
3215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void Observe(NotificationType type,
3216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationSource& source,
3217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       const NotificationDetails& details) {
3218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (type.value) {
3219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      case NotificationType::EXTENSIONS_READY:
3220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ready_ = true;
3221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
3222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
3223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED();
3224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
3225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NotificationRegistrar registrar_;
3228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool ready_;
3229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
3230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test that we get enabled/disabled correctly for all the pref/command-line
323221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// combinations. We don't want to derive from the ExtensionServiceTest class
323321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// for this test, so we use ExtensionServiceTestSimple.
3234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
3235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Also tests that we always fire EXTENSIONS_READY, no matter whether we are
3236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// enabled or not.
323721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST(ExtensionServiceTestSimple, Enabledness) {
3238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsReadyRecorder recorder;
32393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<TestingProfile> profile(new TestingProfile());
3240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop loop;
3241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread ui_thread(BrowserThread::UI, &loop);
3242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread file_thread(BrowserThread::FILE, &loop);
3243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<CommandLine> command_line;
324421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_refptr<ExtensionService> service;
32453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FilePath install_dir = profile->GetPath()
324621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      .AppendASCII(ExtensionService::kInstallDirectoryName);
3247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // By default, we are enabled.
3249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
325021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  service = profile->CreateExtensionService(command_line.get(),
3251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            install_dir,
3252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            false);
3253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(service->extensions_enabled());
3254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->Init();
3255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop.RunAllPending();
3256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(recorder.ready());
3257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If either the command line or pref is set, we are disabled.
3259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  recorder.set_ready(false);
32603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile.reset(new TestingProfile());
3261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  command_line->AppendSwitch(switches::kDisableExtensions);
326221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  service = profile->CreateExtensionService(command_line.get(),
3263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            install_dir,
3264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            false);
3265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(service->extensions_enabled());
3266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->Init();
3267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop.RunAllPending();
3268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(recorder.ready());
3269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  recorder.set_ready(false);
32713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile.reset(new TestingProfile());
32723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
327321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  service = profile->CreateExtensionService(command_line.get(),
3274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            install_dir,
3275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            false);
3276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(service->extensions_enabled());
3277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->Init();
3278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop.RunAllPending();
3279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(recorder.ready());
3280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  recorder.set_ready(false);
32823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile.reset(new TestingProfile());
32833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
3284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
328521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  service = profile->CreateExtensionService(command_line.get(),
3286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            install_dir,
3287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            false);
3288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(service->extensions_enabled());
3289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->Init();
3290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop.RunAllPending();
3291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(recorder.ready());
3292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Explicitly delete all the resources used in this test.
3294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  profile.reset();
3295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  service = NULL;
3296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Test loading extensions that require limited and unlimited storage quotas.
329921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, StorageQuota) {
330021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
3301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath extensions_path = data_dir_
3303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("storage_quota");
3304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath limited_quota_ext =
3306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      extensions_path.AppendASCII("limited_quota")
3307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("1.0");
33083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
33093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The old permission name for unlimited quota was "unlimited_storage", but
33103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // we changed it to "unlimitedStorage". This tests both versions.
3311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath unlimited_quota_ext =
3312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      extensions_path.AppendASCII("unlimited_quota")
3313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("1.0");
3314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath unlimited_quota_ext2 =
3315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      extensions_path.AppendASCII("unlimited_quota")
33163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      .AppendASCII("2.0");
3317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->LoadExtension(limited_quota_ext);
3318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->LoadExtension(unlimited_quota_ext);
33193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  service_->LoadExtension(unlimited_quota_ext2);
3320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loop_.RunAllPending();
3321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(3u, loaded_.size());
3323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(profile_.get());
3324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(profile_->IsOffTheRecord());
3325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Open the database from each origin to make the tracker aware
33273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // of the existence of these origins and to get their quotas.
3328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 limited_quota = -1;
3329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 unlimited_quota = -1;
3330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 limited_quota_identifier =
3331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[0]->url());
3332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 unlimited_quota_identifier =
3333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[1]->url());
33343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  string16 unlimited_quota_identifier2 =
33353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[2]->url());
3336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 db_name = UTF8ToUTF16("db");
3337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 description = UTF8ToUTF16("db_description");
3338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int64 database_size;
3339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker();
33403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
33413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // First check the normal limited quota extension.
3342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->DatabaseOpened(limited_quota_identifier, db_name, description,
3343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             1, &database_size, &limited_quota);
3344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->DatabaseClosed(limited_quota_identifier, db_name);
33453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(profile_->GetDatabaseTracker()->GetDefaultQuota(), limited_quota);
33463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
33473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Now check the two unlimited quota ones.
3348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->DatabaseOpened(unlimited_quota_identifier, db_name, description,
3349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             1, &database_size, &unlimited_quota);
3350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  db_tracker->DatabaseClosed(unlimited_quota_identifier, db_name);
33513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  EXPECT_EQ(kint64max, unlimited_quota);
33523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  db_tracker->DatabaseOpened(unlimited_quota_identifier2, db_name, description,
33533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                             1, &database_size, &unlimited_quota);
33543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  db_tracker->DatabaseClosed(unlimited_quota_identifier2, db_name);
3355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(kint64max, unlimited_quota);
3357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
335921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Tests ExtensionService::register_component_extension().
336021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(ExtensionServiceTest, ComponentExtensions) {
336121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InitializeEmptyExtensionService();
3362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Component extensions should work even when extensions are disabled.
3364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  set_extensions_enabled(false);
3365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath path = data_dir_
3367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("good")
3368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("Extensions")
3369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
3370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      .AppendASCII("1.0.0.0");
3371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string manifest;
3373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(file_util::ReadFileToString(
3374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      path.Append(Extension::kManifestFilename), &manifest));
3375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->register_component_extension(
337721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      ExtensionService::ComponentExtensionInfo(manifest, path));
3378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->Init();
3379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that we do not pump messages -- the extension should be loaded
3381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // immediately.
3382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, GetErrors().size());
3384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, loaded_.size());
3385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location());
3386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service_->extensions()->size());
3387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Component extensions shouldn't get recourded in the prefs.
3389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ValidatePrefKeyCount(0);
3390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reload all extensions, and make sure it comes back.
3392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id = service_->extensions()->at(0)->id();
3393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  loaded_.clear();
3394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service_->ReloadExtensions();
3395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, service_->extensions()->size());
3396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(extension_id, service_->extensions()->at(0)->id());
3397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace {
3400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool AlwaysInstall(const Extension& extension) {
3402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return true;
3403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
3406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
3408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
3409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionSyncData extension_sync_data;
3411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.id = good_crx;
3412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.uninstalled = true;
3413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should do nothing.
3415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Install the extension.
3418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath extension_path = data_dir_.AppendASCII("good.crx");
3419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(extension_path, true);
3420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should uninstall the extension.
3423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
3425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should again do nothing.
3427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
3432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
3433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath extension_path = data_dir_.AppendASCII("good.crx");
3435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(extension_path, true);
3436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionSyncData extension_sync_data;
3440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.id = good_crx;
3441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.version =
3442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      *(service_->GetExtensionById(good_crx, true)->version());
3443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.enabled = false;
3445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
3447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.enabled = true;
3450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.incognito_enabled = true;
3451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
3454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.enabled = false;
3456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.incognito_enabled = true;
3457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
3459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx));
3460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
3462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
3465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeExtensionServiceWithUpdater();
3466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Install the extension.
3468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath extension_path = data_dir_.AppendASCII("good.crx");
3469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InstallCrx(extension_path, true);
3470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
3471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx));
3472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionSyncData extension_sync_data;
3474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.id = good_crx;
3475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.enabled = true;
3476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.version =
3477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      *(service_->GetExtensionById(good_crx, true)->version());
3478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should do nothing if extension version == sync version.
3480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->updater()->WillCheckSoon());
3482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should do nothing if extension version > sync version (but see
3484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the TODO in ProcessSyncData).
3485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
3486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<Version> version(Version::GetVersionFromString("0.0.0.0"));
3487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    extension_sync_data.version = *version;
3488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_FALSE(service_->updater()->WillCheckSoon());
3490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should kick off an update if extension version < sync version.
3493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
3494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<Version> version(Version::GetVersionFromString("9.9.9.9"));
3495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    extension_sync_data.version = *version;
3496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(service_->updater()->WillCheckSoon());
3498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
3501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
3504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeExtensionServiceWithUpdater();
3505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionSyncData extension_sync_data;
3507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.id = good_crx;
3508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.update_url = GURL("http://www.google.com");
3509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  extension_sync_data.enabled = true;
3510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
3511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<Version> version(Version::GetVersionFromString("1.2.3.4"));
3512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    extension_sync_data.version = *version;
3513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service_->ProcessSyncData(extension_sync_data, &AlwaysInstall);
3516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(service_->updater()->WillCheckSoon());
3517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PendingExtensionInfo info;
3519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(
3520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      service_->pending_extension_manager()->GetById(good_crx, &info));
3521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(extension_sync_data.update_url, info.update_url());
3522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(info.is_from_sync());
3523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(info.install_silently());
3524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(extension_sync_data.enabled, info.enable_on_install());
3525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(extension_sync_data.incognito_enabled,
3526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            info.enable_incognito_on_install());
3527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(Extension::INTERNAL, info.install_source());
3528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
3529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that when multiple sources try to install an extension,
3532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// we consistently choose the right one. To make tests easy to read,
3533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// methods that fake requests to install crx files in several ways
3534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// are provided.
3535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass ExtensionSourcePriorityTest : public ExtensionServiceTest {
3536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
3537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void SetUp() {
3538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // All tests use a single extension.  Put the id and path in member vars
3539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // that all methods can read.
3540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    crx_id_ = kGoodId;
3541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    crx_path_ = data_dir_.AppendASCII("good.crx");
3542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Fake an external source adding a URL to fetch an extension from.
3545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void AddPendingExternalPrefUrl() {
3546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->pending_extension_manager()->AddFromExternalUpdateUrl(
3547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        crx_id_, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD);
3548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Fake an external file from external_extensions.json.
3551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void AddPendingExternalPrefFileInstall() {
3552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<Version> version;
3553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    version.reset(Version::GetVersionFromString("1.0.0.0"));
3554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->OnExternalExtensionFileFound(
3556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        crx_id_, version.get(), crx_path_, Extension::EXTERNAL_PREF);
3557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Fake a request from sync to install an extension.
3560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool AddPendingSyncInstall() {
3561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return service_->pending_extension_manager()->AddFromSync(
3562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        crx_id_, GURL(kGoodUpdateURL), &IsExtension,
3563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        kGoodInstallSilently, kGoodInitialState,
3564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        kGoodInitialIncognitoEnabled);
3565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Fake a request to install a default app.
3568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void AddPendingDefaultAppInstall() {
3569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->pending_extension_manager()->AddFromDefaultAppList(crx_id_);
3570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Fake a policy install.
3573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void AddPendingPolicyInstall() {
3574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<Version> version;
3575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    version.reset(Version::GetVersionFromString("1.0.0.0"));
3576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Get path to the CRX with id |kGoodId|.
3578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service_->OnExternalExtensionUpdateUrlFound(
3579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        crx_id_, GURL(), Extension::EXTERNAL_POLICY_DOWNLOAD);
3580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Get the install source of a pending extension.
3583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Extension::Location GetPendingLocation() {
3584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PendingExtensionInfo info;
3585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info));
3586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return info.install_source();
3587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Is an extension pending from a sync request?
3590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool GetPendingIsFromSync() {
3591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PendingExtensionInfo info;
3592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info));
3593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return info.is_from_sync();
3594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Is the CRX id these tests use pending?
3597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool IsCrxPending() {
3598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return service_->pending_extension_manager()->IsIdPending(crx_id_);
3599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Is an extension installed?
3602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool IsCrxInstalled() {
3603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return (service_->GetExtensionById(crx_id_, true) != NULL);
3604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
3605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected:
3607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // All tests use a single extension.  Making the id and path member
3608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // vars avoids pasing the same argument to every method.
3609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::string crx_id_;
3610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath crx_path_;
3611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
3612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
3614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(skerner): crbug/79755
3615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_PendingExternalFileOverSync DISABLED_PendingExternalFileOverSync
3616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
3617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_PendingExternalFileOverSync PendingExternalFileOverSync
3618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
3619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that a pending request for installation of an external CRX from
3620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// an update URL overrides a pending request to install the same extension
3621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// from sync.
3622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalFileOverSync) {
3623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
3624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Install pending extension from sync.
3628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingSyncInstall();
3629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(GetPendingIsFromSync());
3631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Install pending as external prefs json would.
3634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingExternalPrefFileInstall();
3635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Another request from sync should be ignorred.
3639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingSyncInstall();
3640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WaitForCrxInstall(crx_path_, true);
3644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(IsCrxInstalled());
3645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
3648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(skerner): crbug/79755
3649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_PendingExternalUrlOverSync DISABLED_PendingExternalUrlOverSync
3650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
3651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_PendingExternalUrlOverSync PendingExternalUrlOverSync
3652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
3653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that an install of an external CRX from an update overrides
3654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// an install of the same extension from sync.
3655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalUrlOverSync) {
3656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
3657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingSyncInstall();
3660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(GetPendingIsFromSync());
3662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingExternalPrefUrl();
3665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
3666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(GetPendingIsFromSync());
3667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingSyncInstall();
3670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
3671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(GetPendingIsFromSync());
3672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
3676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(skerner): crbug/79755
3677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_PendingExternalFileOverDefaultApp DISABLED_PendingExternalFileOverDefaultApp
3678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
3679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_PendingExternalFileOverDefaultApp PendingExternalFileOverDefaultApp
3680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
3681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that an install of an external CRX overrides a request for a default
3682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// app.
3683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalFileOverDefaultApp) {
3684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
3685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingDefaultAppInstall();
3688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::INTERNAL, GetPendingLocation());
3689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingExternalPrefFileInstall();
3692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingDefaultAppInstall();
3696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation());
3697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WaitForCrxInstall(crx_path_, true);
3700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(IsCrxInstalled());
3701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
3704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(skerner): crbug/79755
3705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_InstallExternalBlocksSyncRequest DISABLED_InstallExternalBlocksSyncRequest
3706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
3707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define MAYBE_InstallExternalBlocksSyncRequest InstallExternalBlocksSyncRequest
3708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
3709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test that an external install request stops sync from installing
3710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the same extension.
3711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(ExtensionSourcePriorityTest, MAYBE_InstallExternalBlocksSyncRequest) {
3712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeEmptyExtensionService();
3713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // External prefs starts an install.
3716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddPendingExternalPrefFileInstall();
3717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Crx installer was made, but has not yet run.
3719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(IsCrxInstalled());
3720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Before the CRX installer runs, Sync requests that the same extension
3722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // be installed. Should fail, because an external source is pending.
3723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(AddPendingSyncInstall());
3724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Wait for the external source to install.
3726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WaitForCrxInstall(crx_path_, true);
3727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(IsCrxInstalled());
3728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Now that the extension is installed, sync request should fail
3730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // because the extension is already installed.
3731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_FALSE(AddPendingSyncInstall());
3732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
3733