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
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <map>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/stl_util-inl.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_split.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/stringprintf.h"
143f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/version.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_error_reporter.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_updater.h"
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/test_extension_prefs.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension_constants.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/net/test_url_fetcher_factory.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/test/testing_profile.h"
26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/escape.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/load_flags.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_status.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "testing/gtest/include/gtest/gtest.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "libxml/globals.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::Time;
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing base::TimeDelta;
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochnamespace {
374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kEmptyUpdateUrlData[] = "";
394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochint expected_load_flags =
41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    net::LOAD_DO_NOT_SEND_COOKIES |
42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    net::LOAD_DO_NOT_SAVE_COOKIES |
43513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    net::LOAD_DISABLE_CACHE;
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst ManifestFetchData::PingData kNeverPingedData(
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged);
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}  // namespace
494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Base class for further specialized test classes.
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass MockService : public ExtensionServiceInterface {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MockService()
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : pending_extension_manager_(ALLOW_THIS_IN_INITIALIZER_LIST(*this)) {}
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~MockService() {}
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual const ExtensionList* extensions() const {
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ADD_FAILURE();
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual const ExtensionList* disabled_extensions() const {
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ADD_FAILURE();
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return NULL;
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void UpdateExtension(const std::string& id,
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               const FilePath& path,
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               const GURL& download_url) {
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FAIL();
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual const Extension* GetExtensionById(const std::string& id,
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            bool include_disabled) const {
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ADD_FAILURE();
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool UninstallExtension(const std::string& extension_id,
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  bool external_uninstall,
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  std::string* error) {
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADD_FAILURE();
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool IsExtensionEnabled(const std::string& extension_id) const {
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADD_FAILURE();
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool IsExternalExtensionUninstalled(
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const std::string& extension_id) const {
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADD_FAILURE();
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return false;
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void EnableExtension(const std::string& extension_id) {
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FAIL();
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void DisableExtension(const std::string& extension_id) {
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FAIL();
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void UpdateExtensionBlacklist(
1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const std::vector<std::string>& blacklist) {
1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FAIL();
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  virtual void CheckAdminBlacklist() {
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    FAIL();
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool IsIncognitoEnabled(const std::string& id) const {
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ADD_FAILURE();
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void SetIsIncognitoEnabled(const std::string& id,
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                     bool enabled) {
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FAIL();
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void CheckForUpdatesSoon() {
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FAIL();
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual PendingExtensionManager* pending_extension_manager() {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADD_FAILURE() << "Subclass should override this if it will "
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  << "be accessed by a test.";
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return &pending_extension_manager_;
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void ProcessSyncData(
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      const ExtensionSyncData& extension_sync_data,
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PendingExtensionInfo::ShouldAllowInstallPredicate
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          should_allow_install) {
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FAIL();
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Profile* profile() { return &profile_; }
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionPrefs* extension_prefs() { return prefs_.prefs(); }
14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PrefService* pref_service() { return prefs_.pref_service(); }
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Creates test extensions and inserts them into list. The name and
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // version are all based on their index. If |update_url| is non-null, it
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // will be used as the update_url for each extension.
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The |id| is used to distinguish extension names and make sure that
15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // no two extensions share the same name.
15372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void CreateTestExtensions(int id, int count, ExtensionList *list,
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                            const std::string* update_url,
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                            Extension::Location location) {
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (int i = 1; i <= count; i++) {
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DictionaryValue manifest;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      manifest.SetString(extension_manifest_keys::kVersion,
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                         base::StringPrintf("%d.0.0.0", i));
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      manifest.SetString(extension_manifest_keys::kName,
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                         base::StringPrintf("Extension %d.%d", id, i));
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (update_url)
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        manifest.SetString(extension_manifest_keys::kUpdateURL, *update_url);
164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      scoped_refptr<Extension> e =
165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch          prefs_.AddExtensionWithManifest(manifest, location);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ASSERT_TRUE(e != NULL);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      list->push_back(e);
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PendingExtensionManager pending_extension_manager_;
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  TestExtensionPrefs prefs_;
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  TestingProfile profile_;
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MockService);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string GenerateId(std::string input) {
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string result;
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(Extension::GenerateId(input, &result));
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool ShouldInstallExtensionsOnly(const Extension& extension) {
18821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return extension.GetType() == Extension::TYPE_EXTENSION;
18921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool ShouldInstallThemesOnly(const Extension& extension) {
19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return extension.is_theme();
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool ShouldAlwaysInstall(const Extension& extension) {
19621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return true;
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Loads some pending extension records into a pending extension manager.
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SetupPendingExtensionManagerForTest(
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int count,
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const GURL& update_url,
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PendingExtensionManager* pending_extension_manager) {
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (int i = 1; i <= count; i++) {
205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const bool kIsFromSync = true;
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const bool kInstallSilently = true;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const Extension::State kInitialState = Extension::ENABLED;
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const bool kInitialIncognitoEnabled = false;
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::string id = GenerateId(base::StringPrintf("extension%i", i));
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    pending_extension_manager->AddForTesting(
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        id,
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        PendingExtensionInfo(update_url,
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             should_allow_install,
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             kIsFromSync,
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             kInstallSilently,
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             kInitialState,
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             kInitialIncognitoEnabled,
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             Extension::INTERNAL));
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ServiceForManifestTests : public MockService {
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ServiceForManifestTests() {}
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~ServiceForManifestTests() {}
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual const Extension* GetExtensionById(const std::string& id,
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            bool include_disabled) const {
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (ExtensionList::const_iterator iter = extensions_.begin();
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        iter != extensions_.end(); ++iter) {
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if ((*iter)->id() == id) {
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return *iter;
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual const ExtensionList* extensions() const { return &extensions_; }
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual PendingExtensionManager* pending_extension_manager() {
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return &pending_extension_manager_;
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void set_extensions(ExtensionList extensions) {
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extensions_ = extensions;
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionList extensions_;
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ServiceForDownloadTests : public MockService {
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void UpdateExtension(const std::string& id,
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               const FilePath& extension_path,
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               const GURL& download_url) {
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extension_id_ = id;
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    install_path_ = extension_path;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    download_url_ = download_url;
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual PendingExtensionManager* pending_extension_manager() {
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return &pending_extension_manager_;
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual const Extension* GetExtensionById(const std::string& id, bool) const {
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    last_inquired_extension_id_ = id;
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::string& extension_id() const { return extension_id_; }
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const FilePath& install_path() const { return install_path_; }
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const GURL& download_url() const { return download_url_; }
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::string& last_inquired_extension_id() const {
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return last_inquired_extension_id_;
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id_;
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath install_path_;
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL download_url_;
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The last extension ID that GetExtensionById was called with.
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Mutable because the method that sets it (GetExtensionById) is const
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // in the actual extension service, but must record the last extension
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ID in this test class.
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  mutable std::string last_inquired_extension_id_;
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ServiceForBlacklistTests : public MockService {
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ServiceForBlacklistTests()
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch     : MockService(),
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       processed_blacklist_(false) {
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual void UpdateExtensionBlacklist(
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<std::string>& blacklist) {
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    processed_blacklist_ = true;
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool processed_blacklist() { return processed_blacklist_; }
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::string& extension_id() { return extension_id_; }
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool processed_blacklist_;
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id_;
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath install_path_;
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kUpdateFrequencySecs = 15;
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Takes a string with KEY=VALUE parameters separated by '&' in |params| and
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// puts the key/value pairs into |result|. For keys with no value, the empty
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// "foo", and "c" to "".
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void ExtractParameters(const std::string& params,
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              std::map<std::string, std::string>* result) {
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<std::string> pairs;
323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base::SplitString(params, '&', &pairs);
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < pairs.size(); i++) {
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::string> key_val;
326731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::SplitString(pairs[i], '=', &key_val);
327dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (!key_val.empty()) {
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::string key = key_val[0];
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_TRUE(result->find(key) == result->end());
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (*result)[key] = (key_val.size() == 2) ? key_val[1] : "";
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// All of our tests that need to use private APIs of ExtensionUpdater live
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// inside this class (which is a friend to ExtensionUpdater).
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionUpdaterTest : public testing::Test {
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void SimulateTimerFired(ExtensionUpdater* updater) {
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(updater->timer_.IsRunning());
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    updater->timer_.Stop();
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    updater->TimerFired();
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static void SimulateCheckSoon(const ExtensionUpdater& updater,
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                MessageLoop* message_loop) {
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(updater.will_check_soon_);
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    message_loop->RunAllPending();
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Adds a Result with the given data to results.
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void AddParseResult(
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const std::string& id,
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const std::string& version,
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const std::string& url,
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      UpdateManifest::Results* results) {
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateManifest::Result result;
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result.extension_id = id;
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result.version = version;
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result.crx_url = GURL(url);
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    results->list.push_back(result);
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestExtensionUpdateCheckRequests(bool pending) {
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    MessageLoop message_loop;
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread file_thread(BrowserThread::FILE, &message_loop);
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread io_thread(BrowserThread::IO);
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    io_thread.Start();
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Create an extension with an update_url.
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForManifestTests service;
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string update_url("http://foo.com/bar");
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionList extensions;
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PendingExtensionManager* pending_extension_manager =
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.pending_extension_manager();
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pending) {
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SetupPendingExtensionManagerForTest(1, GURL(update_url),
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                          pending_extension_manager);
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
38372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      service.CreateTestExtensions(1, 1, &extensions, &update_url,
384731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   Extension::INTERNAL);
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service.set_extensions(extensions);
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Set up and start the updater.
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcherFactory factory;
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(&factory);
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), 60*60*24);
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Disable blacklist checks (tested elsewhere) so that we only see the
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // update HTTP request.
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.set_blacklist_checks_enabled(false);
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Tell the update that it's time to do update checks.
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SimulateTimerFired(&updater);
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Get the url our mock fetcher was asked to fetch.
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcher* fetcher =
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        factory.GetFetcherByID(ExtensionUpdater::kManifestFetcherId);
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& url = fetcher->original_url();
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(url.is_empty());
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(url.is_valid());
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(url.SchemeIs("http"));
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("foo.com", url.host());
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("/bar", url.path());
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Validate the extension request parameters in the query. It should
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // look something like "?x=id%3D<id>%26v%3D<version>%26uc".
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(url.has_query());
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::string> parts;
416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::SplitString(url.query(), '=', &parts);
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2u, parts.size());
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("x", parts[0]);
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string decoded = UnescapeURLComponent(parts[1],
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               UnescapeRule::URL_SPECIAL_CHARS);
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::map<std::string, std::string> params;
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtractParameters(decoded, &params);
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pending) {
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_EQ(pending_extension_manager->begin()->first, params["id"]);
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ("0.0.0.0", params["v"]);
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(extensions[0]->id(), params["id"]);
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("", params["uc"]);
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestBlacklistUpdateCheckRequests() {
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForManifestTests service;
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Setup and start the updater.
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop message_loop;
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
439731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread io_thread(BrowserThread::IO);
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    io_thread.Start();
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcherFactory factory;
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(&factory);
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), 60*60*24);
447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Tell the updater that it's time to do update checks.
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SimulateTimerFired(&updater);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Get the url our mock fetcher was asked to fetch.
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcher* fetcher =
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        factory.GetFetcherByID(ExtensionUpdater::kManifestFetcherId);
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_FALSE(fetcher == NULL);
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& url = fetcher->original_url();
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(url.is_empty());
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(url.is_valid());
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(url.SchemeIs("https"));
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("clients2.google.com", url.host());
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("/service/update2/crx", url.path());
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Validate the extension request parameters in the query. It should
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // look something like "?x=id%3D<id>%26v%3D<version>%26uc".
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(url.has_query());
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<std::string> parts;
468731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    base::SplitString(url.query(), '=', &parts);
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2u, parts.size());
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("x", parts[0]);
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string decoded = UnescapeURLComponent(parts[1],
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                               UnescapeRule::URL_SPECIAL_CHARS);
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::map<std::string, std::string> params;
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtractParameters(decoded, &params);
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("com.google.crx.blacklist", params["id"]);
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("0", params["v"]);
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ("", params["uc"]);
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(ContainsKey(params, "ping"));
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4814a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  static void TestUpdateUrlDataEmpty() {
4824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
4834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string version = "1.0";
4844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Make sure that an empty update URL data string does not cause a ap=
4864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // option to appear in the x= parameter.
4874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ManifestFetchData fetch_data(GURL("http://localhost/foo"));
4884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    fetch_data.AddExtension(id, version,
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            kNeverPingedData, "");
4904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    EXPECT_EQ("http://localhost/foo\?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
4914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              "%26v%3D1.0%26uc",
4924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              fetch_data.full_url().spec());
4934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
4944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  static void TestUpdateUrlDataSimple() {
4964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
4974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string version = "1.0";
4984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
4994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Make sure that an update URL data string causes an appropriate ap=
5004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // option to appear in the x= parameter.
5014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ManifestFetchData fetch_data(GURL("http://localhost/foo"));
5024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    fetch_data.AddExtension(id, version,
503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            kNeverPingedData, "bar");
5044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    EXPECT_EQ("http://localhost/foo\?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
5054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              "%26v%3D1.0%26uc%26ap%3Dbar",
5064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              fetch_data.full_url().spec());
5074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
5084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  static void TestUpdateUrlDataCompound() {
5104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
5114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string version = "1.0";
5124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Make sure that an update URL data string causes an appropriate ap=
5144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // option to appear in the x= parameter.
5154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ManifestFetchData fetch_data(GURL("http://localhost/foo"));
5164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    fetch_data.AddExtension(id, version,
517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            kNeverPingedData, "a=1&b=2&c");
5184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    EXPECT_EQ("http://localhost/foo\?x=id%3Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
5194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              "%26v%3D1.0%26uc%26ap%3Da%253D1%2526b%253D2%2526c",
5204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch              fetch_data.full_url().spec());
5214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
5224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
523201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  static void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
5244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    MockService service;
525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ManifestFetchesBuilder builder(&service, service.extension_prefs());
5264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ExtensionList extensions;
5274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    std::string url(gallery_url);
5284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service.CreateTestExtensions(1, 1, &extensions, &url, Extension::INTERNAL);
5304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    builder.AddExtension(*extensions[0]);
5314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    std::vector<ManifestFetchData*> fetches = builder.GetFetches();
5324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    EXPECT_EQ(1u, fetches.size());
5334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    scoped_ptr<ManifestFetchData> fetch(fetches[0]);
5344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    fetches.clear();
5354a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
5364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // Make sure that extensions that update from the gallery ignore any
5374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // update URL data.
5384a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    const std::string& update_url = fetch->full_url().spec();
5394a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    std::string::size_type x = update_url.find("x=");
5404a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    EXPECT_NE(std::string::npos, x);
5414a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    std::string::size_type ap = update_url.find("ap%3D", x);
5424a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    EXPECT_EQ(std::string::npos, ap);
5434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
5444a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestDetermineUpdates() {
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    MessageLoop message_loop;
547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread file_thread(BrowserThread::FILE, &message_loop);
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Create a set of test extensions
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForManifestTests service;
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionList tmp;
55372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service.CreateTestExtensions(1, 3, &tmp, NULL, Extension::INTERNAL);
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service.set_extensions(tmp);
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Check passing an empty list of parse results to DetermineUpdates
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ManifestFetchData fetch_data(GURL("http://localhost/foo"));
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateManifest::Results updates;
564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::vector<int> updateable = updater.DetermineUpdates(fetch_data,
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                           updates);
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(updateable.empty());
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Create two updates - expect that DetermineUpdates will return the first
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // one (v1.0 installed, v1.1 available) but not the second one (both
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // installed and available at v2.0).
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<Version> one(Version::GetVersionFromString("1.0"));
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(tmp[0]->version()->Equals(*one));
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetch_data.AddExtension(tmp[0]->id(), tmp[0]->VersionString(),
574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            kNeverPingedData,
5754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                            kEmptyUpdateUrlData);
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddParseResult(tmp[0]->id(),
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "1.1", "http://localhost/e1_1.1.crx", &updates);
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetch_data.AddExtension(tmp[1]->id(), tmp[1]->VersionString(),
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            kNeverPingedData,
5804a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                            kEmptyUpdateUrlData);
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    AddParseResult(tmp[1]->id(),
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        tmp[1]->VersionString(), "http://localhost/e2_2.0.crx", &updates);
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updateable = updater.DetermineUpdates(fetch_data, updates);
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(1u, updateable.size());
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, updateable[0]);
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestDetermineUpdatesPending() {
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Create a set of test extensions
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForManifestTests service;
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PendingExtensionManager* pending_extension_manager =
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.pending_extension_manager();
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop message_loop;
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ManifestFetchData fetch_data(GURL("http://localhost/foo"));
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateManifest::Results updates;
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PendingExtensionManager::const_iterator it;
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (it = pending_extension_manager->begin();
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         it != pending_extension_manager->end(); ++it) {
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      fetch_data.AddExtension(it->first, "1.0.0.0",
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              kNeverPingedData,
6094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                              kEmptyUpdateUrlData);
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      AddParseResult(it->first,
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     "1.1", "http://localhost/e1_1.1.crx", &updates);
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<int> updateable =
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        updater.DetermineUpdates(fetch_data, updates);
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // All the apps should be updateable.
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(3u, updateable.size());
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_EQ(static_cast<int>(i), updateable[i]);
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestMultipleManifestDownloading() {
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop ui_loop;
624731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread ui_thread(BrowserThread::UI, &ui_loop);
625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread file_thread(BrowserThread::FILE);
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_thread.Start();
627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread io_thread(BrowserThread::IO);
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    io_thread.Start();
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcherFactory factory;
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcher* fetcher = NULL;
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(&factory);
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<ServiceForDownloadTests> service(new ServiceForDownloadTests);
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(service.get(), service->extension_prefs(),
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             service->pref_service(),
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             service->profile(),
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             kUpdateFrequencySecs);
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url1("http://localhost/manifest1");
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url2("http://localhost/manifest2");
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Request 2 update checks - the first should begin immediately and the
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // second one should be queued up.
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ManifestFetchData* fetch1 = new ManifestFetchData(url1);
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ManifestFetchData* fetch2 = new ManifestFetchData(url2);
647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ManifestFetchData::PingData zeroDays(0, 0);
648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    fetch1->AddExtension("1111", "1.0", zeroDays, kEmptyUpdateUrlData);
649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    fetch2->AddExtension("12345", "2.0", kNeverPingedData,
6504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                         kEmptyUpdateUrlData);
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.StartUpdateCheck(fetch1);
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.StartUpdateCheck(fetch2);
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string invalid_xml = "invalid xml";
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher = factory.GetFetcherByID(ExtensionUpdater::kManifestFetcherId);
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher->load_flags() == expected_load_flags);
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher->delegate()->OnURLFetchComplete(
65972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        fetcher, url1, net::URLRequestStatus(), 200, ResponseCookies(),
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        invalid_xml);
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Now that the first request is complete, make sure the second one has
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // been started.
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string kValidXml =
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "<?xml version='1.0' encoding='UTF-8'?>"
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "<gupdate xmlns='http://www.google.com/update2/response'"
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "                protocol='2.0'>"
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        " <app appid='12345'>"
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "               version='1.2.3.4' prodversionmin='2.0.143.0' />"
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        " </app>"
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        "</gupdate>";
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher = factory.GetFetcherByID(ExtensionUpdater::kManifestFetcherId);
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher->load_flags() == expected_load_flags);
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher->delegate()->OnURLFetchComplete(
67772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        fetcher, url2, net::URLRequestStatus(), 200, ResponseCookies(),
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        kValidXml);
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This should run the manifest parsing, then we want to make sure that our
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // service was called with GetExtensionById with the matching id from
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // kValidXml.
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_thread.Stop();
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    io_thread.Stop();
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_loop.RunAllPending();
686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ("12345", service->last_inquired_extension_id());
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    xmlCleanupGlobals();
688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The FILE thread is needed for |service|'s cleanup,
690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // because of ImportantFileWriter.
691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    file_thread.Start();
692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service.reset();
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestSingleExtensionDownloading(bool pending) {
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop ui_loop;
697731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread ui_thread(BrowserThread::UI, &ui_loop);
698731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread file_thread(BrowserThread::FILE);
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_thread.Start();
700731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread io_thread(BrowserThread::IO);
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    io_thread.Start();
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcherFactory factory;
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcher* fetcher = NULL;
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(&factory);
706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    scoped_ptr<ServiceForDownloadTests> service(new ServiceForDownloadTests);
707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(service.get(), service->extension_prefs(),
708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             service->pref_service(),
709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             service->profile(),
710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                             kUpdateFrequencySecs);
711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL test_url("http://localhost/extension.crx");
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string hash = "";
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    scoped_ptr<Version> version(Version::GetVersionFromString("0.0.1"));
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_TRUE(version.get());
719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.FetchUpdatedExtension(id, test_url, hash, version->GetString());
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (pending) {
7223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      const bool kIsFromSync = true;
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const bool kInstallSilently = true;
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const Extension::State kInitialState = Extension::ENABLED;
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const bool kInitialIncognitoEnabled = false;
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      PendingExtensionManager* pending_extension_manager =
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          service->pending_extension_manager();
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      pending_extension_manager->AddForTesting(
729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          id,
73021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          PendingExtensionInfo(test_url, &ShouldAlwaysInstall, kIsFromSync,
7313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                               kInstallSilently, kInitialState,
732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               kInitialIncognitoEnabled, Extension::INTERNAL));
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Call back the ExtensionUpdater with a 200 response and some test data
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string extension_data("whatever");
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId);
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher->load_flags() == expected_load_flags);
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher->delegate()->OnURLFetchComplete(
74172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        fetcher, test_url, net::URLRequestStatus(), 200, ResponseCookies(),
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        extension_data);
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_thread.Stop();
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ui_loop.RunAllPending();
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Expect that ExtensionUpdater asked the mock extensions service to install
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // a file with the test data for the right id.
749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(id, service->extension_id());
750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FilePath tmpfile_path = service->install_path();
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(tmpfile_path.empty());
752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(test_url, service->download_url());
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string file_contents;
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(file_util::ReadFileToString(tmpfile_path, &file_contents));
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(extension_data == file_contents);
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // The FILE thread is needed for |service|'s cleanup,
758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // because of ImportantFileWriter.
759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    file_thread.Start();
760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    service.reset();
761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_util::Delete(tmpfile_path, false);
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(NULL);
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestBlacklistDownloading() {
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoop message_loop;
768731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread file_thread(BrowserThread::FILE, &message_loop);
770731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread io_thread(BrowserThread::IO);
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    io_thread.Start();
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcherFactory factory;
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcher* fetcher = NULL;
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(&factory);
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForBlacklistTests service;
777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
780ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL test_url("http://localhost/extension.crx");
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string id = "com.google.crx.blacklist";
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string hash =
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      "2CE109E9D0FAF820B2434E166297934E6177B65AB9951DBC3E204CAD4689B39C";
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string version = "0.0.1";
789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.FetchUpdatedExtension(id, test_url, hash, version);
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Call back the ExtensionUpdater with a 200 response and some test data
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string extension_data("aaabbb");
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId);
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher->load_flags() == expected_load_flags);
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher->delegate()->OnURLFetchComplete(
79772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        fetcher, test_url, net::URLRequestStatus(), 200, ResponseCookies(),
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        extension_data);
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop.RunAllPending();
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The updater should have called extension service to process the
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // blacklist.
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(service.processed_blacklist());
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(version, service.pref_service()->
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetString(prefs::kExtensionBlacklistUpdateVersion));
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(NULL);
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestMultipleExtensionDownloading() {
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    MessageLoopForUI message_loop;
814731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
815731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread file_thread(BrowserThread::FILE, &message_loop);
816731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread io_thread(BrowserThread::IO);
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    io_thread.Start();
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcherFactory factory;
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcher* fetcher = NULL;
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(&factory);
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForDownloadTests service;
823ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
825ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
826ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url1("http://localhost/extension1.crx");
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url2("http://localhost/extension2.crx");
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string hash1 = "";
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string hash2 = "";
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string version1 = "0.1";
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string version2 = "0.1";
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Start two fetches
840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.FetchUpdatedExtension(id1, url1, hash1, version1);
841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.FetchUpdatedExtension(id2, url2, hash2, version2);
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make the first fetch complete.
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string extension_data1("whatever");
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId);
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher->load_flags() == expected_load_flags);
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher->delegate()->OnURLFetchComplete(
84972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        fetcher, url1, net::URLRequestStatus(), 200, ResponseCookies(),
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        extension_data1);
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop.RunAllPending();
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Expect that the service was asked to do an install with the right data.
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath tmpfile_path = service.install_path();
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(tmpfile_path.empty());
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(id1, service.extension_id());
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(url1, service.download_url());
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop.RunAllPending();
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_util::Delete(tmpfile_path, false);
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure the second fetch finished and asked the service to do an
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // update.
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string extension_data2("whatever2");
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher = factory.GetFetcherByID(ExtensionUpdater::kExtensionFetcherId);
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher->load_flags() == expected_load_flags);
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher->delegate()->OnURLFetchComplete(
86872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        fetcher, url2, net::URLRequestStatus(), 200, ResponseCookies(),
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        extension_data2);
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop.RunAllPending();
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(id2, service.extension_id());
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(url2, service.download_url());
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(service.install_path().empty());
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure the correct crx contents were passed for the update call.
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string file_contents;
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(file_util::ReadFileToString(service.install_path(),
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            &file_contents));
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(extension_data2 == file_contents);
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_util::Delete(service.install_path(), false);
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Test requests to both a Google server and a non-google server. This allows
884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // us to test various combinations of installed (ie roll call) and active
885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // (ie app launch) ping scenarios. The invariant is that each type of ping
886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // value should be present at most once per day, and can be calculated based
887ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // on the delta between now and the last ping time (or in the case of active
888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // pings, that delta plus whether the app has been active).
889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static void TestGalleryRequests(int rollcall_ping_days,
890ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  int active_ping_days,
891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  bool active_bit) {
892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    MessageLoop message_loop;
893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread file_thread(BrowserThread::FILE, &message_loop);
895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcherFactory factory;
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    URLFetcher::set_factory(&factory);
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Set up 2 mock extensions, one with a google.com update url and one
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // without.
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForManifestTests service;
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionList tmp;
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url1("http://clients2.google.com/service/update2/crx");
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url2("http://www.somewebsite.com");
90572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
906731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                 Extension::INTERNAL);
90772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
908731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                 Extension::INTERNAL);
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(2u, tmp.size());
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service.set_extensions(tmp);
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionPrefs* prefs = service.extension_prefs();
913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const std::string& id = tmp[0]->id();
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Time now = Time::Now();
915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (rollcall_ping_days == 0) {
916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (rollcall_ping_days > 0) {
918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Time last_ping_day = now -
919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           TimeDelta::FromDays(rollcall_ping_days) -
920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                           TimeDelta::FromSeconds(15);
921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      prefs->SetLastPingDay(id, last_ping_day);
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Store a value for the last day we sent an active ping.
925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (active_ping_days == 0) {
926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else if (active_ping_days > 0) {
928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Time last_active_ping_day = now -
929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  TimeDelta::FromDays(active_ping_days) -
930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  TimeDelta::FromSeconds(15);
931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      prefs->SetLastActivePingDay(id, last_active_ping_day);
932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (active_bit)
934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      prefs->SetActiveBit(id, true);
935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.set_blacklist_checks_enabled(false);
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make the updater do manifest fetching, and note the urls it tries to
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // fetch.
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<GURL> fetched_urls;
945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.CheckNow();
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    TestURLFetcher* fetcher =
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      factory.GetFetcherByID(ExtensionUpdater::kManifestFetcherId);
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetched_urls.push_back(fetcher->original_url());
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher->delegate()->OnURLFetchComplete(
95172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      fetcher, fetched_urls[0], net::URLRequestStatus(), 500,
95272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ResponseCookies(), "");
953c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetcher =
954c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      factory.GetFetcherByID(ExtensionUpdater::kManifestFetcherId);
955c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetched_urls.push_back(fetcher->original_url());
956c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
957c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The urls could have been fetched in either order, so use the host to
958c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // tell them apart and note the query each used.
959c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string url1_query;
960c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string url2_query;
961c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (fetched_urls[0].host() == url1.host()) {
962c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url1_query = fetched_urls[0].query();
963c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url2_query = fetched_urls[1].query();
964c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (fetched_urls[0].host() == url2.host()) {
965c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url1_query = fetched_urls[1].query();
966c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url2_query = fetched_urls[0].query();
967c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
968c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
969c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
970c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
971ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // First make sure the non-google query had no ping parameter.
972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    std::string search_string = "ping%3D";
973c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
974ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
975ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Now make sure the google query had the correct ping parameter.
976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool ping_expected = false;
977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool did_rollcall = false;
978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (rollcall_ping_days != 0) {
979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      search_string += "r%253D" + base::IntToString(rollcall_ping_days);
980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      did_rollcall = true;
981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ping_expected = true;
982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (active_bit && active_ping_days != 0) {
984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (did_rollcall)
985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        search_string += "%2526";
986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      search_string += "a%253D" + base::IntToString(active_ping_days);
987ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ping_expected = true;
988c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool ping_found = url1_query.find(search_string) != std::string::npos;
990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        << " was looking for " << search_string;
992c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
993c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
994c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This makes sure that the extension updater properly stores the results
995c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
996c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the first time we fetched the extension, or 2) We sent a ping value of
997c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // >= 1 day for the extension.
998c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static void TestHandleManifestResults() {
999c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ServiceForManifestTests service;
10004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    MessageLoop message_loop;
1001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
1004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
1005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
1006c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1007c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL update_url("http://www.google.com/manifest");
1008c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionList tmp;
100972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
1010731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                 Extension::INTERNAL);
1011c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    service.set_extensions(tmp);
1012c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1013c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ManifestFetchData fetch_data(update_url);
1014513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    const Extension* extension = tmp[0];
1015c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    fetch_data.AddExtension(extension->id(), extension->VersionString(),
1016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            kNeverPingedData,
10174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                            kEmptyUpdateUrlData);
1018c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    UpdateManifest::Results results;
1019c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    results.daystart_elapsed_seconds = 750;
1020c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.HandleManifestResults(fetch_data, &results);
1022c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Time last_ping_day =
1023c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        service.extension_prefs()->LastPingDay(extension->id());
1024c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_FALSE(last_ping_day.is_null());
1025c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
1026c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
1027c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1028c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
1029c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1030c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Because we test some private methods of ExtensionUpdater, it's easer for the
1031c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
1032c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// subclasses where friendship with ExtenionUpdater is not inherited.
1033c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1034c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
1035c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestExtensionUpdateCheckRequests(false);
1036c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1037c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1038c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
1039c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestExtensionUpdateCheckRequests(true);
1040c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1041c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1042c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This test is disabled on Mac, see http://crbug.com/26035.
1043c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestBlacklistUpdateCheckRequests) {
1044c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestBlacklistUpdateCheckRequests();
1045c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1046c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST(ExtensionUpdaterTest, TestUpdateUrlData) {
1048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop message_loop;
1049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread file_thread(BrowserThread::FILE, &message_loop);
1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
10514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  ExtensionUpdaterTest::TestUpdateUrlDataEmpty();
10524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  ExtensionUpdaterTest::TestUpdateUrlDataSimple();
10534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  ExtensionUpdaterTest::TestUpdateUrlDataCompound();
10544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  ExtensionUpdaterTest::TestUpdateUrlDataFromGallery(
1055201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      Extension::GalleryUpdateUrl(false).spec());
10564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  ExtensionUpdaterTest::TestUpdateUrlDataFromGallery(
1057201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      Extension::GalleryUpdateUrl(true).spec());
10584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
10594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1060c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestDetermineUpdates) {
1061c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestDetermineUpdates();
1062c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1063c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1064c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
1065c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestDetermineUpdatesPending();
1066c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1067c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1068c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
1069c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestMultipleManifestDownloading();
1070c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1071c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1072c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
1073c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestSingleExtensionDownloading(false);
1074c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1075c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1076c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
1077c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestSingleExtensionDownloading(true);
1078c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1079c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1080c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This test is disabled on Mac, see http://crbug.com/26035.
1081c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestBlacklistDownloading) {
1082c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestBlacklistDownloading();
1083c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1084c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1085c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestMultipleExtensionDownloading) {
1086c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestMultipleExtensionDownloading();
1087c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1088c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1089c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestGalleryRequests) {
1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We want to test a variety of combinations of expected ping conditions for
1091ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // rollcall and active pings.
1092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
1093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < arraysize(ping_cases); i++) {
1095ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (size_t j = 0; j < arraysize(ping_cases); j++) {
1096ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (size_t k = 0; k < 2; k++) {
1097ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        int rollcall_ping_days = ping_cases[i];
1098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        int active_ping_days = ping_cases[j];
1099ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Skip cases where rollcall_ping_days == -1, but active_ping_days > 0,
1100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // because rollcall_ping_days == -1 means the app was just installed and
1101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // this is the first update check after installation.
1102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
1103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            active_ping_days > 0)
1104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          continue;
1105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        bool active_bit = k > 0;
1107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ExtensionUpdaterTest::TestGalleryRequests(
1108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            rollcall_ping_days, active_ping_days, active_bit);
1109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ASSERT_FALSE(HasFailure()) <<
1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          " rollcall_ping_days=" << ping_cases[i] <<
1111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          " active_ping_days=" << ping_cases[j] <<
1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          " active_bit=" << active_bit;
1113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
1114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1118c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestHandleManifestResults) {
1119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdaterTest::TestHandleManifestResults();
1120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1122c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
1123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop message_loop;
1124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread file_thread(BrowserThread::FILE, &message_loop);
1125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MockService service;
1127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ManifestFetchesBuilder builder(&service, service.extension_prefs());
1128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Non-internal non-external extensions should be rejected.
1130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  {
1131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionList extensions;
113272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    service.CreateTestExtensions(1, 1, &extensions, NULL, Extension::INVALID);
1133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ASSERT_FALSE(extensions.empty());
1134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    builder.AddExtension(*extensions[0]);
1135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(builder.GetFetches().empty());
1136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
1137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extensions with invalid update URLs should be rejected.
1139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  builder.AddPendingExtension(
1140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GenerateId("foo"), PendingExtensionInfo(GURL("http:google.com:foo"),
114121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                              &ShouldInstallExtensionsOnly,
1142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                              false, false, true, false,
1143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                              Extension::INTERNAL));
1144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(builder.GetFetches().empty());
1145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extensions with empty IDs should be rejected.
1147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  builder.AddPendingExtension(
114821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      "", PendingExtensionInfo(GURL(), &ShouldInstallExtensionsOnly,
1149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                               false, false, true, false,
1150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                               Extension::INTERNAL));
1151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(builder.GetFetches().empty());
1152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TODO(akalin): Test that extensions with empty update URLs
11543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // converted from user scripts are rejected.
11553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Extensions with empty update URLs should have a default one
1157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // filled in.
1158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  builder.AddPendingExtension(
1159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GenerateId("foo"), PendingExtensionInfo(GURL(),
116021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                              &ShouldInstallExtensionsOnly,
1161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                              false, false, true, false,
1162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                              Extension::INTERNAL));
1163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<ManifestFetchData*> fetches = builder.GetFetches();
1164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(1u, fetches.size());
1165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<ManifestFetchData> fetch(fetches[0]);
1166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  fetches.clear();
1167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(fetch->base_url().is_empty());
1168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(fetch->full_url().is_empty());
1169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
1170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben MurdochTEST(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
11724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    MessageLoop message_loop;
1173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread file_thread(BrowserThread::FILE, &message_loop);
1175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
11764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ServiceForManifestTests service;
11774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    TestURLFetcherFactory factory;
11784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    URLFetcher::set_factory(&factory);
1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
1181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
1182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.StartUpdateCheck(new ManifestFetchData(GURL()));
11844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // This should delete the newly-created ManifestFetchData.
1185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.StartUpdateCheck(new ManifestFetchData(GURL()));
11864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // This should add into |manifests_pending_|.
1187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.StartUpdateCheck(new ManifestFetchData(
11884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        GURL("http://www.google.com")));
11894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    // This should clear out |manifests_pending_|.
1190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Stop();
11914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
11924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST(ExtensionUpdaterTest, TestCheckSoon) {
11944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    MessageLoop message_loop;
1195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread ui_thread(BrowserThread::UI, &message_loop);
1196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread file_thread(BrowserThread::FILE, &message_loop);
1197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
11984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    ServiceForManifestTests service;
1199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TestURLFetcherFactory factory;
1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    URLFetcher::set_factory(&factory);
1201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdater updater(
1202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &service, service.extension_prefs(), service.pref_service(),
1203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        service.profile(), kUpdateFrequencySecs);
1204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_FALSE(updater.WillCheckSoon());
1205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Start();
1206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_FALSE(updater.WillCheckSoon());
1207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.CheckSoon();
1208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(updater.WillCheckSoon());
1209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.CheckSoon();
1210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(updater.WillCheckSoon());
1211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ExtensionUpdaterTest::SimulateCheckSoon(updater, &message_loop);
1212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_FALSE(updater.WillCheckSoon());
1213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.CheckSoon();
1214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(updater.WillCheckSoon());
1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updater.Stop();
1216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_FALSE(updater.WillCheckSoon());
12174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
12184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
1219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(asargent) - (http://crbug.com/12780) add tests for:
1220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -prodversionmin (shouldn't update if browser version too old)
1221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -manifests & updates arriving out of order / interleaved
1222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -malformed update url (empty, file://, has query, has a # fragment, etc.)
1223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -An extension gets uninstalled while updates are in progress (so it doesn't
1224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//  "come back from the dead")
1225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -An extension gets manually updated to v3 while we're downloading v2 (ie
1226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//  you don't get downgraded accidentally)
1227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -An update manifest mentions multiple updates
1228