15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind_helpers.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sequenced_task_runner.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h"
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/crx_installer.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_error_reporter.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_sync_data.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_prefs.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_service.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/test_extension_system.h"
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/extensions/updater/chrome_extension_downloader_factory.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_downloader.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_updater.h"
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/updater/request_queue_impl.h"
3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "chrome/browser/google/google_brand.h"
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/prefs/pref_service_syncable.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/testing_profile.h"
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/omaha_query_params/omaha_query_params.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/test/test_browser_thread_bundle.h"
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/test/test_utils.h"
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/updater/manifest_fetch_data.h"
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_urls.h"
573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h"
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "google_apis/gaia/fake_identity_provider.h"
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "google_apis/gaia/fake_oauth2_token_service.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml/globals.h"
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/backoff_entry.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "net/http/http_request_headers.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/test_url_fetcher_factory.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "url/third_party/mozilla/url_parse.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS)
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/settings/device_settings_service.h"
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing omaha_query_params::OmahaQueryParams;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::DoAll;
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using testing::Invoke;
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing testing::InvokeWithoutArgs;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Mock;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::SetArgPointee;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ExtensionDownloaderDelegate::Error Error;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ExtensionDownloaderDelegate::PingResult PingResult;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const net::BackoffEntry::Policy kNoBackoffPolicy = {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Number of initial errors (in sequence) to ignore before applying
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // exponential back-off rules.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  1000,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Initial delay for exponential back-off in ms.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  0,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Factor by which the waiting time will be multiplied.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  0,
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fuzzing percentage. ex: 10% will spread requests randomly
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // between 90%-100% of the calculated time.
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  0,
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Maximum amount of time we are willing to delay our request in ms.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  0,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Time to keep an entry from being discarded even when it
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // has no significant state, -1 to never discard.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  -1,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't use initial delay unless the last request was an error.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  false,
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEmptyUpdateUrlData[] = "";
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kAuthUserQueryKey[] = "authuser";
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int kExpectedLoadFlags =
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::LOAD_DO_NOT_SEND_COOKIES |
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::LOAD_DO_NOT_SAVE_COOKIES |
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::LOAD_DISABLE_CACHE;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)int kExpectedLoadFlagsForDownloadWithCookies = net::LOAD_DISABLE_CACHE;
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Fake authentication constants
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kFakeAccountId[] = "bobloblaw@lawblog.example.com";
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)const char kFakeOAuth2Token[] = "ce n'est pas un jeton";
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ManifestFetchData::PingData kNeverPingedData(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ManifestFetchData::kNeverPinged, ManifestFetchData::kNeverPinged, true);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockExtensionDownloaderDelegate : public ExtensionDownloaderDelegate {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD4(OnExtensionDownloadFailed, void(const std::string&,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               Error,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               const PingResult&,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                               const std::set<int>&));
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD7(OnExtensionDownloadFinished, void(const std::string&,
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 const base::FilePath&,
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                 bool,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 const GURL&,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 const std::string&,
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 const PingResult&,
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 const std::set<int>&));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(GetPingDataForExtension,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               bool(const std::string&, ManifestFetchData::PingData*));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(GetUpdateUrlData, std::string(const std::string&));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD1(IsExtensionPending, bool(const std::string&));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD2(GetExtensionExistingVersion,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               bool(const std::string&, std::string*));
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Wait() {
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_refptr<content::MessageLoopRunner> runner =
1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        new content::MessageLoopRunner;
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quit_closure_ = runner->QuitClosure();
1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    runner->Run();
1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quit_closure_.Reset();
1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Quit() {
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quit_closure_.Run();
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DelegateTo(ExtensionDownloaderDelegate* delegate) {
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ON_CALL(*this, OnExtensionDownloadFailed(_, _, _, _))
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillByDefault(Invoke(delegate,
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &ExtensionDownloaderDelegate::OnExtensionDownloadFailed));
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ON_CALL(*this, OnExtensionDownloadFinished(_, _, _, _, _, _, _))
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillByDefault(Invoke(delegate,
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &ExtensionDownloaderDelegate::OnExtensionDownloadFinished));
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ON_CALL(*this, GetPingDataForExtension(_, _))
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillByDefault(Invoke(delegate,
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &ExtensionDownloaderDelegate::GetPingDataForExtension));
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ON_CALL(*this, GetUpdateUrlData(_))
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillByDefault(Invoke(delegate,
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &ExtensionDownloaderDelegate::GetUpdateUrlData));
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ON_CALL(*this, IsExtensionPending(_))
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillByDefault(Invoke(delegate,
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &ExtensionDownloaderDelegate::IsExtensionPending));
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ON_CALL(*this, GetExtensionExistingVersion(_, _))
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        .WillByDefault(Invoke(delegate,
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            &ExtensionDownloaderDelegate::GetExtensionExistingVersion));
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::Closure quit_closure_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNotificationsObserved[] = {
1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED,
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class that observes the notifications sent by the ExtensionUpdater and
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the ExtensionDownloader.
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NotificationsObserver : public content::NotificationObserver {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NotificationsObserver() {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      count_[i] = 0;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      registrar_.Add(this,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     kNotificationsObserved[i],
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     content::NotificationService::AllSources());
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~NotificationsObserver() {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      registrar_.Remove(this,
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        kNotificationsObserved[i],
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        content::NotificationService::AllSources());
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t StartedCount() { return count_[0]; }
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t UpdatedCount() { return count_[1]; }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Updated(const std::string& id) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return updated_.find(id) != updated_.end();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void Wait() {
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_refptr<content::MessageLoopRunner> runner =
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        new content::MessageLoopRunner;
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quit_closure_ = runner->QuitClosure();
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    runner->Run();
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quit_closure_.Reset();
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!quit_closure_.is_null())
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      quit_closure_.Run();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(kNotificationsObserved); ++i) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (kNotificationsObserved[i] == type) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        count_[i]++;
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        if (type == extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          updated_.insert(
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              content::Details<UpdateDetails>(details)->id);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t count_[arraysize(kNotificationsObserved)];
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<std::string> updated_;
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  base::Closure quit_closure_;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NotificationsObserver);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Extracts the integer value of the |authuser| query parameter. Returns 0 if
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// the parameter is not set.
267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int GetAuthUserQueryValue(const GURL& url) {
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::string query_string = url.query();
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  url::Component query(0, query_string.length());
270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  url::Component key, value;
271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  while (
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      url::ExtractQueryKeyValue(query_string.c_str(), &query, &key, &value)) {
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::string key_string = query_string.substr(key.begin, key.len);
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (key_string == kAuthUserQueryKey) {
275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      int user_index = 0;
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      base::StringToInt(query_string.substr(value.begin, value.len),
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        &user_index);
278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return user_index;
279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return 0;
282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for further specialized test classes.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockService : public TestExtensionService {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MockService(TestExtensionPrefs* prefs)
2906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      : prefs_(prefs),
2916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        pending_extension_manager_(&profile_),
2926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        downloader_delegate_override_(NULL) {
2936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MockService() {}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE() << "Subclass should override this if it will "
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  << "be accessed by a test.";
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &pending_extension_manager_;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile() { return &profile_; }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* request_context() {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return profile_.GetRequestContext();
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionPrefs* extension_prefs() { return prefs_->prefs(); }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* pref_service() { return prefs_->pref_service(); }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  FakeOAuth2TokenService* fake_token_service() {
3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return fake_token_service_.get();
3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates test extensions and inserts them into list. The name and
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // version are all based on their index. If |update_url| is non-null, it
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be used as the update_url for each extension.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |id| is used to distinguish extension names and make sure that
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // no two extensions share the same name.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateTestExtensions(int id, int count, ExtensionList *list,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string* update_url,
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            Manifest::Location location) {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 1; i <= count; i++) {
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::DictionaryValue manifest;
3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      manifest.SetString(manifest_keys::kVersion,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::StringPrintf("%d.0.0.0", i));
3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      manifest.SetString(manifest_keys::kName,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::StringPrintf("Extension %d.%d", id, i));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (update_url)
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        manifest.SetString(manifest_keys::kUpdateURL, *update_url);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<Extension> e =
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          prefs_->AddExtensionWithManifest(manifest, location);
335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      ASSERT_TRUE(e.get() != NULL);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      list->push_back(e);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ExtensionDownloader::Factory GetDownloaderFactory() {
3416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return base::Bind(&MockService::CreateExtensionDownloader,
3426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      base::Unretained(this));
3436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ExtensionDownloader::Factory GetAuthenticatedDownloaderFactory() {
3466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return base::Bind(&MockService::CreateExtensionDownloaderWithIdentity,
3476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                      base::Unretained(this));
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void OverrideDownloaderDelegate(ExtensionDownloaderDelegate* delegate) {
3516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    downloader_delegate_override_ = delegate;
3526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestExtensionPrefs* const prefs_;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestingProfile profile_;
357effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  PendingExtensionManager pending_extension_manager_;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<ExtensionDownloader> CreateExtensionDownloader(
3616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ExtensionDownloaderDelegate* delegate) {
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return ChromeExtensionDownloaderFactory::CreateForRequestContext(
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        request_context(),
3646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        downloader_delegate_override_ ? downloader_delegate_override_
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      : delegate);
3666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<ExtensionDownloader> CreateExtensionDownloaderWithIdentity(
3696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      ExtensionDownloaderDelegate* delegate) {
3706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<FakeIdentityProvider> fake_identity_provider;
3716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    fake_token_service_.reset(new FakeOAuth2TokenService());
3726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    fake_identity_provider.reset(new FakeIdentityProvider(
3736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          fake_token_service_.get()));
3746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    fake_identity_provider->LogIn(kFakeAccountId);
3756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    fake_token_service_->AddAccount(kFakeAccountId);
3766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    scoped_ptr<ExtensionDownloader> downloader(
3786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        CreateExtensionDownloader(delegate));
3796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    downloader->SetWebstoreIdentityProvider(
3806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fake_identity_provider.PassAs<IdentityProvider>());
3816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    return downloader.Pass();
3826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
3836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<FakeOAuth2TokenService> fake_token_service_;
3856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ExtensionDownloaderDelegate* downloader_delegate_override_;
3876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockService);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
392868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ShouldInstallExtensionsOnly(const Extension* extension) {
393868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return extension->GetType() == Manifest::TYPE_EXTENSION;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
396868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ShouldInstallThemesOnly(const Extension* extension) {
397868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return extension->is_theme();
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool ShouldAlwaysInstall(const Extension* extension) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Loads some pending extension records into a pending extension manager.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SetupPendingExtensionManagerForTest(
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int count,
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& update_url,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PendingExtensionManager* pending_extension_manager) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 1; i <= count; ++i) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PendingExtensionInfo::ShouldAllowInstallPredicate should_allow_install =
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (i % 2 == 0) ? &ShouldInstallThemesOnly : &ShouldInstallExtensionsOnly;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool kIsFromSync = true;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool kInstallSilently = true;
4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const bool kMarkAcknowledged = false;
415cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const bool kRemoteInstall = false;
41603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::string id =
41703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        crx_file::id_util::GenerateId(base::StringPrintf("extension%i", i));
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_extension_manager->AddForTesting(
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        PendingExtensionInfo(id,
421effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                             std::string(),
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             update_url,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Version(),
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             should_allow_install,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             kIsFromSync,
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             kInstallSilently,
4274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             Manifest::INTERNAL,
4284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             Extension::NO_FLAGS,
429cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             kMarkAcknowledged,
430cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             kRemoteInstall));
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ServiceForManifestTests : public MockService {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ServiceForManifestTests(TestExtensionPrefs* prefs)
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      : MockService(prefs),
4386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        registry_(ExtensionRegistry::Get(profile())) {
4396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ServiceForManifestTests() {}
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const Extension* GetExtensionById(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& id, bool include_disabled) const OVERRIDE {
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Extension* result = registry_->enabled_extensions().GetByID(id);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result || !include_disabled)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return result;
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return registry_->disabled_extensions().GetByID(id);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const ExtensionSet* extensions() const OVERRIDE {
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return &registry_->enabled_extensions();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &pending_extension_manager_;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const Extension* GetPendingExtensionUpdate(
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& id) const OVERRIDE {
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsExtensionEnabled(const std::string& id) const OVERRIDE {
4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return !registry_->disabled_extensions().Contains(id);
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void set_extensions(ExtensionList extensions,
4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                      ExtensionList disabled_extensions) {
4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    registry_->ClearAll();
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ExtensionList::const_iterator it = extensions.begin();
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != extensions.end(); ++it) {
4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry_->AddEnabled(*it);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ExtensionList::const_iterator it = disabled_extensions.begin();
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != disabled_extensions.end(); ++it) {
4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      registry_->AddDisabled(*it);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ExtensionRegistry* registry_;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ServiceForDownloadTests : public MockService {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ServiceForDownloadTests(TestExtensionPrefs* prefs)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : MockService(prefs) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add a fake crx installer to be returned by a call to UpdateExtension()
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // with a specific ID.  Caller keeps ownership of |crx_installer|.
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddFakeCrxInstaller(const std::string& id, CrxInstaller* crx_installer) {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fake_crx_installers_[id] = crx_installer;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool UpdateExtension(
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& id,
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::FilePath& extension_path,
5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool file_ownership_passed,
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CrxInstaller** out_crx_installer) OVERRIDE {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_id_ = id;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    install_path_ = extension_path;
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ContainsKey(fake_crx_installers_, id)) {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *out_crx_installer = fake_crx_installers_[id];
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual PendingExtensionManager* pending_extension_manager() OVERRIDE {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &pending_extension_manager_;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual const Extension* GetExtensionById(
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& id, bool) const OVERRIDE {
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_inquired_extension_id_ = id;
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& extension_id() const { return extension_id_; }
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const base::FilePath& install_path() const { return install_path_; }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hold the set of ids that UpdateExtension() should fake success on.
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdateExtension(id, ...) will return true iff fake_crx_installers_
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contains key |id|.  |out_install_notification_source| will be set
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to Source<CrxInstaller(fake_crx_installers_[i]).
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<std::string, CrxInstaller*> fake_crx_installers_;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string extension_id_;
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath install_path_;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL download_url_;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The last extension ID that GetExtensionById was called with.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mutable because the method that sets it (GetExtensionById) is const
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the actual extension service, but must record the last extension
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ID in this test class.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable std::string last_inquired_extension_id_;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kUpdateFrequencySecs = 15;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Takes a string with KEY=VALUE parameters separated by '&' in |params| and
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// puts the key/value pairs into |result|. For keys with no value, the empty
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// string is used. So for "a=1&b=foo&c", result would map "a" to "1", "b" to
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "foo", and "c" to "".
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void ExtractParameters(const std::string& params,
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              std::map<std::string, std::string>* result) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> pairs;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitString(params, '&', &pairs);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < pairs.size(); i++) {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<std::string> key_val;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::SplitString(pairs[i], '=', &key_val);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!key_val.empty()) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string key = key_val[0];
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(result->find(key) == result->end());
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      (*result)[key] = (key_val.size() == 2) ? key_val[1] : std::string();
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static void VerifyQueryAndExtractParameters(
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& query,
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<std::string, std::string>* result) {
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, std::string> params;
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtractParameters(query, &params);
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string omaha_params = OmahaQueryParams::Get(OmahaQueryParams::CRX);
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, std::string> expected;
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtractParameters(omaha_params, &expected);
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::map<std::string, std::string>::iterator it = expected.begin();
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != expected.end(); ++it) {
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(it->second, params[it->first]);
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1U, params.count("x"));
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string decoded = net::UnescapeURLComponent(
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      params["x"], net::UnescapeRule::URL_SPECIAL_CHARS);
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtractParameters(decoded, result);
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All of our tests that need to use private APIs of ExtensionUpdater live
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// inside this class (which is a friend to ExtensionUpdater).
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExtensionUpdaterTest : public testing::Test {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionUpdaterTest()
593a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      : thread_bundle_(
5947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            content::TestBrowserThreadBundle::IO_MAINLOOP) {
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() OVERRIDE {
5987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Some tests create URLRequestContextGetters, whose destruction must run
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on the IO thread. Make sure the IO loop spins before shutdown so that
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // those objects are released.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunUntilIdle();
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs_.reset();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunUntilIdle() {
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prefs_->pref_service()->CommitPendingWrite();
6117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::RunLoop().RunUntilIdle();
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SimulateTimerFired(ExtensionUpdater* updater) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(updater->timer_.IsRunning());
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    updater->timer_.Stop();
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    updater->TimerFired();
6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::RunAllBlockingPoolTasksUntilIdle();
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds a Result with the given data to results.
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AddParseResult(const std::string& id,
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const std::string& version,
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const std::string& url,
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      UpdateManifest::Results* results) {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateManifest::Result result;
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.extension_id = id;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.version = version;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.crx_url = GURL(url);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results->list.push_back(result);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartUpdateCheck(ExtensionDownloader* downloader,
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ManifestFetchData* fetch_data) {
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader->StartUpdateCheck(scoped_ptr<ManifestFetchData>(fetch_data));
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t ManifestFetchersCount(ExtensionDownloader* downloader) {
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return downloader->manifests_queue_.size() +
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (downloader->manifest_fetcher_.get() ? 1 : 0);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestExtensionUpdateCheckRequests(bool pending) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create an extension with an update_url.
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServiceForManifestTests service(prefs_.get());
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string update_url("http://foo.com/bar");
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionList extensions;
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotificationsObserver observer;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PendingExtensionManager* pending_extension_manager =
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        service.pending_extension_manager();
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pending) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetupPendingExtensionManagerForTest(1, GURL(update_url),
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          pending_extension_manager);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service.CreateTestExtensions(1, 1, &extensions, &update_url,
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   Manifest::INTERNAL);
6575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      service.set_extensions(extensions, ExtensionList());
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up and start the updater.
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcherFactory factory;
6626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionUpdater updater(&service,
6636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.extension_prefs(),
6646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.pref_service(),
6656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.profile(),
6666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             60 * 60 * 24,
6676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             NULL,
6686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.GetDownloaderFactory());
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    updater.Start();
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Tell the update that it's time to do update checks.
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0u, observer.StartedCount());
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SimulateTimerFired(&updater);
6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, observer.StartedCount());
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Get the url our mock fetcher was asked to fetch.
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcher* fetcher =
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url = fetcher->GetOriginalURL();
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(url.is_empty());
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(url.is_valid());
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(url.SchemeIs("http"));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("foo.com", url.host());
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("/bar", url.path());
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Validate the extension request parameters in the query. It should
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // look something like "x=id%3D<id>%26v%3D<version>%26uc".
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(url.has_query());
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::map<std::string, std::string> params;
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VerifyQueryAndExtractParameters(url.query(), &params);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pending) {
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(pending_extension_manager->IsIdPending(params["id"]));
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ("0.0.0.0", params["v"]);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(extensions[0]->id(), params["id"]);
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(extensions[0]->VersionString(), params["v"]);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("", params["uc"]);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestUpdateUrlDataEmpty() {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string version = "1.0";
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that an empty update URL data string does not cause a ap=
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // option to appear in the x= parameter.
7071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch_data(
7081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateManifestFetchData(GURL("http://localhost/foo")));
7091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch_data->AddExtension(
7101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        id, version, &kNeverPingedData, std::string(), std::string(), false);
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<std::string, std::string> params;
7131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(id, params["id"]);
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(version, params["v"]);
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(0U, params.count("ap"));
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestUpdateUrlDataSimple() {
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string version = "1.0";
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that an update URL data string causes an appropriate ap=
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // option to appear in the x= parameter.
7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch_data(
7261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateManifestFetchData(GURL("http://localhost/foo")));
7271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch_data->AddExtension(
7281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        id, version, &kNeverPingedData, "bar", std::string(), false);
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<std::string, std::string> params;
7301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(id, params["id"]);
7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(version, params["v"]);
7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ("bar", params["ap"]);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestUpdateUrlDataCompound() {
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string version = "1.0";
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that an update URL data string causes an appropriate ap=
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // option to appear in the x= parameter.
7421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch_data(
7431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateManifestFetchData(GURL("http://localhost/foo")));
7441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch_data->AddExtension(
7451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        id, version, &kNeverPingedData, "a=1&b=2&c", std::string(), false);
7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<std::string, std::string> params;
7471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(id, params["id"]);
7492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(version, params["v"]);
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ("a%3D1%26b%3D2%26c", params["ap"]);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestUpdateUrlDataFromGallery(const std::string& gallery_url) {
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcherFactory factory;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockService service(prefs_.get());
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockExtensionDownloaderDelegate delegate;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionDownloader downloader(&delegate, service.request_context());
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionList extensions;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string url(gallery_url);
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service.CreateTestExtensions(1, 1, &extensions, &url, Manifest::INTERNAL);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id = extensions[0]->id();
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(delegate, GetPingDataForExtension(id, _));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
767868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    downloader.AddExtension(*extensions[0].get(), 0);
7685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    downloader.StartAllPending(NULL);
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcher* fetcher =
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(fetcher);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that extensions that update from the gallery ignore any
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // update URL data.
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& update_url = fetcher->GetOriginalURL().spec();
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string::size_type x = update_url.find("x=");
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_NE(std::string::npos, x);
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string::size_type ap = update_url.find("ap%3D", x);
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(std::string::npos, ap);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestInstallSource() {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string version = "1.0";
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string install_source = "instally";
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that an installsource= appears in the x= parameter.
7871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch_data(
7881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateManifestFetchData(GURL("http://localhost/foo")));
7891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch_data->AddExtension(id, version, &kNeverPingedData,
7901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             kEmptyUpdateUrlData, install_source, false);
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::map<std::string, std::string> params;
7921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    VerifyQueryAndExtractParameters(fetch_data->full_url().query(), &params);
7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(id, params["id"]);
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(version, params["v"]);
7952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(install_source, params["installsource"]);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestDetermineUpdates() {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestingProfile profile;
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockExtensionDownloaderDelegate delegate;
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check passing an empty list of parse results to DetermineUpdates
8041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch_data(
8051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateManifestFetchData(GURL("http://localhost/foo")));
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateManifest::Results updates;
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<int> updateable;
8081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    downloader.DetermineUpdates(*fetch_data, updates, &updateable);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(updateable.empty());
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create two updates - expect that DetermineUpdates will return the first
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // one (v1.0 installed, v1.1 available) but not the second one (both
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // installed and available at v2.0).
81403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const std::string id1 = crx_file::id_util::GenerateId("1");
81503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const std::string id2 = crx_file::id_util::GenerateId("2");
8161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch_data->AddExtension(
8171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        id1, "1.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
8181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        false);
819c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    AddParseResult(id1, "1.1", "http://localhost/e1_1.1.crx", &updates);
8201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch_data->AddExtension(
8211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        id2, "2.0.0.0", &kNeverPingedData, kEmptyUpdateUrlData, std::string(),
8221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        false);
823c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    AddParseResult(id2, "2.0.0.0", "http://localhost/e2_2.0.crx", &updates);
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(false));
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(delegate, GetExtensionExistingVersion(id1, _))
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(DoAll(SetArgPointee<1>("1.0.0.0"),
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Return(true)));
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(delegate, GetExtensionExistingVersion(id2, _))
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(DoAll(SetArgPointee<1>("2.0.0.0"),
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        Return(true)));
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    downloader.DetermineUpdates(*fetch_data, updates, &updateable);
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1u, updateable.size());
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, updateable[0]);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestDetermineUpdatesPending() {
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Create a set of test extensions
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServiceForManifestTests service(prefs_.get());
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PendingExtensionManager* pending_extension_manager =
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        service.pending_extension_manager();
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetupPendingExtensionManagerForTest(3, GURL(), pending_extension_manager);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestingProfile profile;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockExtensionDownloaderDelegate delegate;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionDownloader downloader(&delegate, profile.GetRequestContext());
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch_data(
8501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateManifestFetchData(GURL("http://localhost/foo")));
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateManifest::Results updates;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::list<std::string> ids_for_update_check;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_extension_manager->GetPendingIdsForUpdateCheck(
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ids_for_update_check);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::list<std::string>::const_iterator it;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (it = ids_for_update_check.begin();
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         it != ids_for_update_check.end(); ++it) {
8601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      fetch_data->AddExtension(*it,
8611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               "1.0.0.0",
8621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               &kNeverPingedData,
8631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               kEmptyUpdateUrlData,
8641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               std::string(),
8651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                               false);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddParseResult(*it, "1.1", "http://localhost/e1_1.1.crx", &updates);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The delegate will tell the downloader that all the extensions are
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pending.
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_CALL(delegate, IsExtensionPending(_)).WillRepeatedly(Return(true));
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<int> updateable;
8741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    downloader.DetermineUpdates(*fetch_data, updates, &updateable);
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // All the apps should be updateable.
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(3u, updateable.size());
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (std::vector<int>::size_type i = 0; i < updateable.size(); ++i) {
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(static_cast<int>(i), updateable[i]);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestMultipleManifestDownloading() {
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcherFactory factory;
884cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    factory.set_remove_fetcher_on_delete(true);
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcher* fetcher = NULL;
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockService service(prefs_.get());
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MockExtensionDownloaderDelegate delegate;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionDownloader downloader(&delegate, service.request_context());
8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL kUpdateUrl("http://localhost/manifest1");
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch1(CreateManifestFetchData(kUpdateUrl));
8941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch2(CreateManifestFetchData(kUpdateUrl));
8951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch3(CreateManifestFetchData(kUpdateUrl));
8961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch4(CreateManifestFetchData(kUpdateUrl));
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ManifestFetchData::PingData zeroDays(0, 0, true);
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fetch1->AddExtension(
8991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fetch2->AddExtension(
9011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "2222", "2.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fetch3->AddExtension(
9031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "3333", "3.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fetch4->AddExtension(
9051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "4444", "4.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This will start the first fetcher and queue the others. The next in queue
908cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // is started as each fetcher receives its response. Note that the fetchers
909cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // don't necessarily run in the order that they are started from here.
910cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GURL fetch1_url = fetch1->full_url();
911cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GURL fetch2_url = fetch2->full_url();
912cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GURL fetch3_url = fetch3->full_url();
913cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    GURL fetch4_url = fetch4->full_url();
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.StartUpdateCheck(fetch1.Pass());
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.StartUpdateCheck(fetch2.Pass());
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.StartUpdateCheck(fetch3.Pass());
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.StartUpdateCheck(fetch4.Pass());
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunUntilIdle();
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
920cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for (int i = 0; i < 4; ++i) {
921cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
922cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ASSERT_TRUE(fetcher);
923cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ASSERT_TRUE(fetcher->delegate());
924cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
925cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (fetcher->GetOriginalURL() == fetch1_url) {
928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // The first fetch will fail.
929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_CALL(delegate, OnExtensionDownloadFailed(
930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_url(kUpdateUrl);
932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_status(net::URLRequestStatus());
933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_response_code(400);
934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->delegate()->OnURLFetchComplete(fetcher);
935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        RunUntilIdle();
936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        Mock::VerifyAndClearExpectations(&delegate);
937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetch1_url = GURL();
938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else if (fetcher->GetOriginalURL() == fetch2_url) {
939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // The second fetch gets invalid data.
940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        const std::string kInvalidXml = "invalid xml";
941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_CALL(delegate, OnExtensionDownloadFailed(
942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "2222", ExtensionDownloaderDelegate::MANIFEST_INVALID, _, _))
943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            .WillOnce(InvokeWithoutArgs(
944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                &delegate,
945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                &MockExtensionDownloaderDelegate::Quit));
946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_url(kUpdateUrl);
947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_status(net::URLRequestStatus());
948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_response_code(200);
949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->SetResponseString(kInvalidXml);
950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->delegate()->OnURLFetchComplete(fetcher);
951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        delegate.Wait();
952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        Mock::VerifyAndClearExpectations(&delegate);
953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetch2_url = GURL();
954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else if (fetcher->GetOriginalURL() == fetch3_url) {
955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // The third fetcher doesn't have an update available.
956cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        const std::string kNoUpdate =
957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "<?xml version='1.0' encoding='UTF-8'?>"
958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "<gupdate xmlns='http://www.google.com/update2/response'"
959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                protocol='2.0'>"
960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            " <app appid='3333'>"
961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  <updatecheck codebase='http://example.com/extension_3.0.0.0.crx'"
962cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "               version='3.0.0.0' prodversionmin='3.0.0.0' />"
963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            " </app>"
964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "</gupdate>";
965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_CALL(delegate, IsExtensionPending("3333"))
966cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            .WillOnce(Return(false));
967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_CALL(delegate, GetExtensionExistingVersion("3333", _))
968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            .WillOnce(DoAll(SetArgPointee<1>("3.0.0.0"),
969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            Return(true)));
970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_CALL(delegate, OnExtensionDownloadFailed(
971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "3333", ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE, _, _))
972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            .WillOnce(InvokeWithoutArgs(
973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                &delegate,
974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                &MockExtensionDownloaderDelegate::Quit));
975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_url(kUpdateUrl);
976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_status(net::URLRequestStatus());
977cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_response_code(200);
978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->SetResponseString(kNoUpdate);
979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->delegate()->OnURLFetchComplete(fetcher);
980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        delegate.Wait();
981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        Mock::VerifyAndClearExpectations(&delegate);
982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetch3_url = GURL();
983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else if (fetcher->GetOriginalURL() == fetch4_url) {
984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // The last fetcher has an update.
985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NotificationsObserver observer;
986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        const std::string kUpdateAvailable =
987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "<?xml version='1.0' encoding='UTF-8'?>"
988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "<gupdate xmlns='http://www.google.com/update2/response'"
989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "                protocol='2.0'>"
990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            " <app appid='4444'>"
991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
992cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "               version='4.0.42.0' prodversionmin='4.0.42.0' />"
993cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            " </app>"
994cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "</gupdate>";
995cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_CALL(delegate, IsExtensionPending("4444"))
996cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            .WillOnce(Return(false));
997cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_CALL(delegate, GetExtensionExistingVersion("4444", _))
998cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            .WillOnce(DoAll(SetArgPointee<1>("4.0.0.0"),
999cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                            Return(true)));
1000cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_url(kUpdateUrl);
1001cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_status(net::URLRequestStatus());
1002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_response_code(200);
1003cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->SetResponseString(kUpdateAvailable);
1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->delegate()->OnURLFetchComplete(fetcher);
1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        observer.Wait();
1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        Mock::VerifyAndClearExpectations(&delegate);
1007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Verify that the downloader decided to update this extension.
1009cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_EQ(1u, observer.UpdatedCount());
1010cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_TRUE(observer.Updated("4444"));
1011cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetch4_url = GURL();
1012cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else {
1013cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
1014cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
1015cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
1018cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (fetcher)
1019cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ADD_FAILURE() << "Unexpected fetch: " << fetcher->GetOriginalURL();
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void TestManifestRetryDownloading() {
10232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::TestURLFetcherFactory factory;
10242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::TestURLFetcher* fetcher = NULL;
10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NotificationsObserver observer;
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockService service(prefs_.get());
10272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MockExtensionDownloaderDelegate delegate;
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ExtensionDownloader downloader(&delegate, service.request_context());
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.manifests_queue_.set_backoff_policy(&kNoBackoffPolicy);
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GURL kUpdateUrl("http://localhost/manifest1");
10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch(CreateManifestFetchData(kUpdateUrl));
10342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ManifestFetchData::PingData zeroDays(0, 0, true);
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fetch->AddExtension(
10361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This will start the first fetcher.
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.StartUpdateCheck(fetch.Pass());
10402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
10412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ExtensionDownloader should retry kMaxRetries times and then fail.
10432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate, OnExtensionDownloadFailed(
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i <= ExtensionDownloader::kMaxRetries; ++i) {
10462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // All fetches will fail.
10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
10482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
10502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->set_url(kUpdateUrl);
10512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->set_status(net::URLRequestStatus());
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Code 5xx causes ExtensionDownloader to retry.
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->set_response_code(500);
10542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->delegate()->OnURLFetchComplete(fetcher);
10552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RunUntilIdle();
10562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(&delegate);
10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For response codes that are not in the 5xx range ExtensionDownloader
10612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // should not retry.
10621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch.reset(CreateManifestFetchData(kUpdateUrl));
1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fetch->AddExtension(
10641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "1111", "1.0", &zeroDays, kEmptyUpdateUrlData, std::string(), false);
10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This will start the first fetcher.
10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    downloader.StartUpdateCheck(fetch.Pass());
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate, OnExtensionDownloadFailed(
10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "1111", ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED, _, _));
10722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The first fetch will fail, and require retrying.
10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
10742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
10752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_url(kUpdateUrl);
10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_response_code(500);
10792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // The second fetch will fail with response 400 and should not cause
10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ExtensionDownloader to retry.
10842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
10862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
10872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_url(kUpdateUrl);
10882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
10892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->set_response_code(400);
10902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
10912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunUntilIdle();
10922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Mock::VerifyAndClearExpectations(&delegate);
10942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void TestSingleExtensionDownloading(bool pending, bool retry, bool fail) {
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcherFactory factory;
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcher* fetcher = NULL;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<ServiceForDownloadTests> service(
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new ServiceForDownloadTests(prefs_.get()));
11016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionUpdater updater(service.get(),
11026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service->extension_prefs(),
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             service->pref_service(),
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             service->profile(),
11055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             kUpdateFrequencySecs,
11066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             NULL,
11076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service->GetDownloaderFactory());
11085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MockExtensionDownloaderDelegate delegate;
11095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delegate.DelegateTo(&updater);
11106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    service->OverrideDownloaderDelegate(&delegate);
11116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    updater.Start();
11126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    updater.EnsureDownloaderCreated();
11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    updater.downloader_->extensions_queue_.set_backoff_policy(
11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &kNoBackoffPolicy);
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL test_url("http://localhost/extension.crx");
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string hash;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Version version("0.0.1");
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::set<int> requests;
11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    requests.insert(0);
11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
11242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ExtensionDownloader::ExtensionFetch(
11252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            id, test_url, hash, version.GetString(), requests));
11262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    updater.downloader_->FetchUpdatedExtension(fetch.Pass());
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pending) {
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const bool kIsFromSync = true;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const bool kInstallSilently = true;
11314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      const bool kMarkAcknowledged = false;
1132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const bool kRemoteInstall = false;
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PendingExtensionManager* pending_extension_manager =
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          service->pending_extension_manager();
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_extension_manager->AddForTesting(
1136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          PendingExtensionInfo(id,
1137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                               std::string(),
1138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                               test_url,
1139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                               version,
1140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                               &ShouldAlwaysInstall,
1141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                               kIsFromSync,
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               kInstallSilently,
11434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               Manifest::INTERNAL,
11444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                               Extension::NO_FLAGS,
1145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               kMarkAcknowledged,
1146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                               kRemoteInstall));
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Call back the ExtensionUpdater with a 200 response and some test data
11502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (retry) {
11562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Reply with response code 500 to cause ExtensionDownloader to retry
11572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->set_url(test_url);
11582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->set_status(net::URLRequestStatus());
11592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->set_response_code(500);
11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher->delegate()->OnURLFetchComplete(fetcher);
11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RunUntilIdle();
11632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fetcher = factory.GetFetcherByID(
11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ExtensionDownloader::kExtensionFetcherId);
11652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
11662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
11672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_url(test_url);
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
11715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (fail) {
11725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->set_response_code(404);
11735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(delegate, OnExtensionDownloadFailed(id, _, _, requests));
11745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
11755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->set_response_code(200);
11765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->SetResponseFilePath(extension_file_path);
11775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_CALL(delegate, OnExtensionDownloadFinished(
11785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          id, _, _, _, version.GetString(), _, requests));
11795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunUntilIdle();
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (fail) {
11855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Don't expect any extension to have been installed.
11865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_TRUE(service->extension_id().empty());
11875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
11885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Expect that ExtensionUpdater asked the mock extensions service to
11895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // install a file with the test data for the right id.
11905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(id, service->extension_id());
11915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::FilePath tmpfile_path = service->install_path();
11925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(tmpfile_path.empty());
11935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(extension_file_path, tmpfile_path);
11945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
11955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
11965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Update a single extension in an environment where the download request
11986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // initially responds with a 403 status. If |identity_provider| is not NULL,
11996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // this will first expect a request which includes an Authorization header
12006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // with an OAuth2 bearer token; otherwise, or if OAuth2 failure is simulated,
12016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // this expects the downloader to fall back onto cookie-based credentials.
12026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void TestProtectedDownload(
12036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const std::string& url_prefix,
12046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      bool enable_oauth2,
12056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      bool succeed_with_oauth2,
12066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      int valid_authuser,
12076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      int max_authuser) {
12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::TestURLFetcherFactory factory;
12095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::TestURLFetcher* fetcher = NULL;
12105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<ServiceForDownloadTests> service(
12115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new ServiceForDownloadTests(prefs_.get()));
12126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const ExtensionDownloader::Factory& downloader_factory =
12136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        enable_oauth2 ? service->GetAuthenticatedDownloaderFactory()
12146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            : service->GetDownloaderFactory();
12156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionUpdater updater(
12166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        service.get(),
12176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        service->extension_prefs(),
12186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        service->pref_service(),
12196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        service->profile(),
12206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        kUpdateFrequencySecs,
12216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        NULL,
12226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        downloader_factory);
12235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    updater.Start();
12246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    updater.EnsureDownloaderCreated();
12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    updater.downloader_->extensions_queue_.set_backoff_policy(
12265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        &kNoBackoffPolicy);
12275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    GURL test_url(base::StringPrintf("%s/extension.crx", url_prefix.c_str()));
12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
12305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string hash;
12316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Version version("0.0.1");
12325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::set<int> requests;
12335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    requests.insert(0);
12345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch(
12355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        new ExtensionDownloader::ExtensionFetch(
12365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            id, test_url, hash, version.GetString(), requests));
12375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    updater.downloader_->FetchUpdatedExtension(fetch.Pass());
12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
12405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
12416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Fake a 403 response.
12445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fetcher->set_url(test_url);
12455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
12465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fetcher->set_response_code(403);
12475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
12486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
12496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (service->fake_token_service()) {
12506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      service->fake_token_service()->IssueAllTokensForAccount(
12516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          kFakeAccountId, kFakeOAuth2Token, base::Time::Now());
12526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
12535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RunUntilIdle();
12545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    bool using_oauth2 = false;
12566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    int expected_load_flags = kExpectedLoadFlags;
12576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Verify that the fetch has had its credentials properly incremented.
12585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
12595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
12606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    net::HttpRequestHeaders fetch_headers;
12616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    fetcher->GetExtraRequestHeaders(&fetch_headers);
12626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // If the download URL is not https, no credentials should be provided.
12636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!test_url.SchemeIsSecure()) {
12646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // No cookies.
12656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      EXPECT_EQ(kExpectedLoadFlags, fetcher->GetLoadFlags());
12666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // No Authorization header.
12676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      EXPECT_FALSE(fetch_headers.HasHeader(
12686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          net::HttpRequestHeaders::kAuthorization));
12696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      expected_load_flags = kExpectedLoadFlags;
12705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
12716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // HTTPS is in use, so credentials are allowed.
12726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (enable_oauth2 && test_url.DomainIs("google.com")) {
12736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // If an IdentityProvider is present and the URL is a google.com
12746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // URL, the fetcher should be in OAuth2 mode after the intitial
12756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // challenge.
12766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_TRUE(fetch_headers.HasHeader(
12776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            net::HttpRequestHeaders::kAuthorization));
12786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        std::string expected_header_value = base::StringPrintf("Bearer %s",
12796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            kFakeOAuth2Token);
12806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        std::string actual_header_value;
12816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetch_headers.GetHeader(net::HttpRequestHeaders::kAuthorization,
12826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                &actual_header_value);
12836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_EQ(expected_header_value, actual_header_value);
12846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        using_oauth2 = true;
12856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      } else {
12866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // No IdentityProvider (or no google.com), so expect cookies instead of
12876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // an Authorization header.
12886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_FALSE(fetch_headers.HasHeader(
12896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            net::HttpRequestHeaders::kAuthorization));
12906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
12916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            fetcher->GetLoadFlags());
12926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
12936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    bool success = false;
12976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (using_oauth2) {
12986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (succeed_with_oauth2) {
12996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        success = true;
13006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      } else {
13016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // Simulate OAuth2 failure and ensure that we fall back on cookies.
1302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_url(test_url);
1303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_status(net::URLRequestStatus());
13046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher->set_response_code(403);
1305cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->delegate()->OnURLFetchComplete(fetcher);
1306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        RunUntilIdle();
1307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
13086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        const ExtensionDownloader::ExtensionFetch& fetch =
13096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            *updater.downloader_->extensions_queue_.active_request();
13106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_EQ(0, GetAuthUserQueryValue(fetch.url));
13116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_EQ(ExtensionDownloader::ExtensionFetch::CREDENTIALS_COOKIES,
13126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                  fetch.credentials);
13136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
13146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher = factory.GetFetcherByID(
13156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            ExtensionDownloader::kExtensionFetcherId);
13166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
13176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher->GetExtraRequestHeaders(&fetch_headers);
13186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_FALSE(fetch_headers.HasHeader(
13196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            net::HttpRequestHeaders::kAuthorization));
13206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_EQ(kExpectedLoadFlagsForDownloadWithCookies,
13216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            fetcher->GetLoadFlags());
13226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        expected_load_flags = kExpectedLoadFlagsForDownloadWithCookies;
1323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
13246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
13266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (!success) {
13276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // Not yet ready to simulate a successful fetch. At this point we begin
13286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // simulating cookie-based authentication with increasing values of
13296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // authuser (starting from 0.)
13306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      int user_index = 0;
13316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      for (; user_index <= max_authuser; ++user_index) {
1332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        const ExtensionDownloader::ExtensionFetch& fetch =
1333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            *updater.downloader_->extensions_queue_.active_request();
1334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_EQ(user_index, GetAuthUserQueryValue(fetch.url));
1335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (user_index == valid_authuser) {
13366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          success = true;
1337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          break;
1338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
13396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // Simulate an authorization failure which should elicit an increment
13406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        // of the authuser value.
1341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher =
1342cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
13446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_EQ(expected_load_flags, fetcher->GetLoadFlags());
1345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_url(fetch.url);
1346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_status(net::URLRequestStatus());
1347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->set_response_code(403);
1348cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        fetcher->delegate()->OnURLFetchComplete(fetcher);
1349cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        RunUntilIdle();
1350cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
13516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
13526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      // Simulate exhaustion of all available authusers.
13536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      if (!success && user_index > max_authuser) {
13546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        const ExtensionDownloader::ExtensionFetch& fetch =
13556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            *updater.downloader_->extensions_queue_.active_request();
13566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher =
13576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
13586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
13596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher->set_url(fetch.url);
13606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher->set_status(net::URLRequestStatus());
13616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher->set_response_code(401);
13626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        fetcher->delegate()->OnURLFetchComplete(fetcher);
13636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        RunUntilIdle();
13646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
1365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
13676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // Simulate successful authorization with a 200 response.
13686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (success) {
1369cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      fetcher =
1370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
1371cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
13725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
13735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->set_url(test_url);
13745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->set_status(net::URLRequestStatus());
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->set_response_code(200);
13765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->SetResponseFilePath(extension_file_path);
13775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      fetcher->delegate()->OnURLFetchComplete(fetcher);
13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      RunUntilIdle();
13795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Verify installation would proceed as normal.
13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(id, service->extension_id());
13825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::FilePath tmpfile_path = service->install_path();
13835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_FALSE(tmpfile_path.empty());
13845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EXPECT_EQ(extension_file_path, tmpfile_path);
13855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Two extensions are updated.  If |updates_start_running| is true, the
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mock extensions service has UpdateExtension(...) return true, and
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the test is responsible for creating fake CrxInstallers.  Otherwise,
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UpdateExtension() returns false, signaling install failures.
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestMultipleExtensionDownloading(bool updates_start_running) {
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcherFactory factory;
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcher* fetcher = NULL;
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServiceForDownloadTests service(prefs_.get());
13966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionUpdater updater(&service,
13976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.extension_prefs(),
13986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.pref_service(),
13996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.profile(),
14006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             kUpdateFrequencySecs,
14016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             NULL,
14026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.GetDownloaderFactory());
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    updater.Start();
14046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    updater.EnsureDownloaderCreated();
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    updater.downloader_->extensions_queue_.set_backoff_policy(
14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        &kNoBackoffPolicy);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(updater.crx_install_is_running_);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url1("http://localhost/extension1.crx");
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url2("http://localhost/extension2.crx");
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string id1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string id2 = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string hash1;
1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string hash2;
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string version1 = "0.1";
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string version2 = "0.1";
14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::set<int> requests;
14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    requests.insert(0);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Start two fetches
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch1(
14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ExtensionDownloader::ExtensionFetch(
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            id1, url1, hash1, version1, requests));
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<ExtensionDownloader::ExtensionFetch> fetch2(
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        new ExtensionDownloader::ExtensionFetch(
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            id2, url2, hash2, version2, requests));
14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    updater.downloader_->FetchUpdatedExtension(fetch1.Pass());
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    updater.downloader_->FetchUpdatedExtension(fetch2.Pass());
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make the first fetch complete.
14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath extension_file_path(FILE_PATH_LITERAL("/whatever"));
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We need some CrxInstallers, and CrxInstallers require a real
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ExtensionService.  Create one on the testing profile.  Any action
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the CrxInstallers take is on the testing profile's extension
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // service, not on our mock |service|.  This allows us to fake
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the CrxInstaller actions we want.
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestingProfile profile;
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static_cast<TestExtensionSystem*>(
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ExtensionSystem::Get(&profile))->
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CreateExtensionService(
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            CommandLine::ForCurrentProcess(),
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            base::FilePath(),
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            false);
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionService* extension_service =
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ExtensionSystem::Get(&profile)->extension_service();
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_service->set_extensions_enabled(true);
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_service->set_show_extensions_prompts(false);
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<CrxInstaller> fake_crx1(
1458ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        CrxInstaller::CreateSilent(extension_service));
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<CrxInstaller> fake_crx2(
1460ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        CrxInstaller::CreateSilent(extension_service));
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (updates_start_running) {
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Add fake CrxInstaller to be returned by service.UpdateExtension().
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service.AddFakeCrxInstaller(id1, fake_crx1.get());
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      service.AddFakeCrxInstaller(id2, fake_crx2.get());
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we don't add fake CRX installers, the mock service fakes a failure
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // starting the install.
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_url(url1);
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_response_code(200);
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->SetResponseFilePath(extension_file_path);
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunUntilIdle();
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Expect that the service was asked to do an install with the right data.
14802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath tmpfile_path = service.install_path();
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(tmpfile_path.empty());
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(id1, service.extension_id());
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunUntilIdle();
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the second fetch finished and asked the service to do an
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // update.
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath extension_file_path2(FILE_PATH_LITERAL("/whatever2"));
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kExtensionFetcherId);
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(fetcher->GetLoadFlags() == kExpectedLoadFlags);
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_url(url2);
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_response_code(200);
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->SetResponseFilePath(extension_file_path2);
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunUntilIdle();
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (updates_start_running) {
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(updater.crx_install_is_running_);
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The second install should not have run, because the first has not
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // sent a notification that it finished.
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(id1, service.extension_id());
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Fake install notice.  This should start the second installation,
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // which will be checked below.
15082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fake_crx1->NotifyCrxInstallComplete(false);
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(updater.crx_install_is_running_);
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(id2, service.extension_id());
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(service.install_path().empty());
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the correct crx contents were passed for the update call.
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(extension_file_path2, service.install_path());
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (updates_start_running) {
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(updater.crx_install_is_running_);
15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fake_crx2->NotifyCrxInstallComplete(false);
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(updater.crx_install_is_running_);
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestGalleryRequestsWithBrand(bool use_organic_brand_code) {
152746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    google_brand::BrandForTesting brand_for_testing(
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        use_organic_brand_code ? "GGLS" : "TEST");
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We want to test a variety of combinations of expected ping conditions for
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // rollcall and active pings.
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ping_cases[] = { ManifestFetchData::kNeverPinged, 0, 1, 5 };
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < arraysize(ping_cases); i++) {
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (size_t j = 0; j < arraysize(ping_cases); j++) {
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (size_t k = 0; k < 2; k++) {
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int rollcall_ping_days = ping_cases[i];
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          int active_ping_days = ping_cases[j];
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Skip cases where rollcall_ping_days == -1, but
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // active_ping_days > 0, because rollcall_ping_days == -1 means the
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // app was just installed and this is the first update check after
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // installation.
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          if (rollcall_ping_days == ManifestFetchData::kNeverPinged &&
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              active_ping_days > 0)
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            continue;
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          bool active_bit = k > 0;
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          TestGalleryRequests(rollcall_ping_days, active_ping_days, active_bit,
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              !use_organic_brand_code);
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ASSERT_FALSE(HasFailure()) <<
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            " rollcall_ping_days=" << ping_cases[i] <<
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            " active_ping_days=" << ping_cases[j] <<
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            " active_bit=" << active_bit;
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test requests to both a Google server and a non-google server. This allows
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // us to test various combinations of installed (ie roll call) and active
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (ie app launch) ping scenarios. The invariant is that each type of ping
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // value should be present at most once per day, and can be calculated based
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the delta between now and the last ping time (or in the case of active
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // pings, that delta plus whether the app has been active).
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestGalleryRequests(int rollcall_ping_days,
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int active_ping_days,
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool active_bit,
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           bool expect_brand_code) {
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcherFactory factory;
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up 2 mock extensions, one with a google.com update url and one
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // without.
15737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    prefs_.reset(new TestExtensionPrefs(base::MessageLoopProxy::current()));
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServiceForManifestTests service(prefs_.get());
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionList tmp;
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url1("http://clients2.google.com/service/update2/crx");
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL url2("http://www.somewebsite.com");
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service.CreateTestExtensions(1, 1, &tmp, &url1.possibly_invalid_spec(),
15792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 Manifest::INTERNAL);
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service.CreateTestExtensions(2, 1, &tmp, &url2.possibly_invalid_spec(),
15812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 Manifest::INTERNAL);
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(2u, tmp.size());
15835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    service.set_extensions(tmp, ExtensionList());
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionPrefs* prefs = service.extension_prefs();
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& id = tmp[0]->id();
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Time now = Time::Now();
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rollcall_ping_days == 0) {
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs->SetLastPingDay(id, now - TimeDelta::FromSeconds(15));
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (rollcall_ping_days > 0) {
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time last_ping_day = now -
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           TimeDelta::FromDays(rollcall_ping_days) -
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           TimeDelta::FromSeconds(15);
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs->SetLastPingDay(id, last_ping_day);
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Store a value for the last day we sent an active ping.
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active_ping_days == 0) {
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs->SetLastActivePingDay(id, now - TimeDelta::FromSeconds(15));
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (active_ping_days > 0) {
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Time last_active_ping_day = now -
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  TimeDelta::FromDays(active_ping_days) -
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  TimeDelta::FromSeconds(15);
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs->SetLastActivePingDay(id, last_active_ping_day);
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active_bit)
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs->SetActiveBit(id, true);
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionUpdater updater(&service,
16106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.extension_prefs(),
16116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.pref_service(),
16126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.profile(),
16136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             kUpdateFrequencySecs,
16146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             NULL,
16156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.GetDownloaderFactory());
16162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ExtensionUpdater::CheckParams params;
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    updater.Start();
16182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    updater.CheckNow(params);
16191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    content::RunAllBlockingPoolTasksUntilIdle();
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make the updater do manifest fetching, and note the urls it tries to
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // fetch.
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<GURL> fetched_urls;
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::TestURLFetcher* fetcher =
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(fetcher != NULL && fetcher->delegate() != NULL);
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetched_urls.push_back(fetcher->GetOriginalURL());
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_url(fetched_urls[0]);
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_status(net::URLRequestStatus());
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->set_response_code(500);
1632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    fetcher->SetResponseString(std::string());
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher->delegate()->OnURLFetchComplete(fetcher);
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher = factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetched_urls.push_back(fetcher->GetOriginalURL());
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The urls could have been fetched in either order, so use the host to
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tell them apart and note the query each used.
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string url1_query;
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string url2_query;
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (fetched_urls[0].host() == url1.host()) {
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1_query = fetched_urls[0].query();
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2_query = fetched_urls[1].query();
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (fetched_urls[0].host() == url2.host()) {
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url1_query = fetched_urls[1].query();
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url2_query = fetched_urls[0].query();
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // First make sure the non-google query had no ping parameter.
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string search_string = "ping%3D";
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(url2_query.find(search_string) == std::string::npos);
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Now make sure the google query had the correct ping parameter.
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ping_expected = false;
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool did_rollcall = false;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rollcall_ping_days != 0) {
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      search_string += "r%253D" + base::IntToString(rollcall_ping_days);
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      did_rollcall = true;
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ping_expected = true;
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (active_bit && active_ping_days != 0) {
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (did_rollcall)
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        search_string += "%2526";
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      search_string += "a%253D" + base::IntToString(active_ping_days);
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ping_expected = true;
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool ping_found = url1_query.find(search_string) != std::string::npos;
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(ping_expected, ping_found) << "query was: " << url1_query
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << " was looking for " << search_string;
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the non-google query has no brand parameter.
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string brand_string = "brand%3D";
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(url2_query.find(brand_string) == std::string::npos);
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure the google query has a brand parameter, but only if the
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // brand is non-organic.
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expect_brand_code) {
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(url1_query.find(brand_string) != std::string::npos);
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Chromium builds never add the brand to the parameter, even for google
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // queries.
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(url1_query.find(brand_string) == std::string::npos);
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunUntilIdle();
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This makes sure that the extension updater properly stores the results
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of a <daystart> tag from a manifest fetch in one of two cases: 1) This is
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the first time we fetched the extension, or 2) We sent a ping value of
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // >= 1 day for the extension.
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void TestHandleManifestResults() {
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ServiceForManifestTests service(prefs_.get());
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL update_url("http://www.google.com/manifest");
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionList tmp;
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service.CreateTestExtensions(1, 1, &tmp, &update_url.spec(),
17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 Manifest::INTERNAL);
17055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    service.set_extensions(tmp, ExtensionList());
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    ExtensionUpdater updater(&service,
17086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.extension_prefs(),
17096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.pref_service(),
17106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.profile(),
17116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             kUpdateFrequencySecs,
17126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             NULL,
17136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                             service.GetDownloaderFactory());
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    updater.Start();
17156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    updater.EnsureDownloaderCreated();
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<ManifestFetchData> fetch_data(
17181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateManifestFetchData(update_url));
1719868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const Extension* extension = tmp[0].get();
17201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    fetch_data->AddExtension(extension->id(),
17211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             extension->VersionString(),
17221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             &kNeverPingedData,
17231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             kEmptyUpdateUrlData,
17241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             std::string(),
17251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             false);
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UpdateManifest::Results results;
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    results.daystart_elapsed_seconds = 750;
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    updater.downloader_->HandleManifestResults(*fetch_data, &results);
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Time last_ping_day =
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        service.extension_prefs()->LastPingDay(extension->id());
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(last_ping_day.is_null());
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 seconds_diff = (Time::Now() - last_ping_day).InSeconds();
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_LT(seconds_diff - results.daystart_elapsed_seconds, 5);
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<TestExtensionPrefs> prefs_;
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ManifestFetchData* CreateManifestFetchData(const GURL& update_url) {
17411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return new ManifestFetchData(update_url,
17421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 0,
17431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 "",
17441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 OmahaQueryParams::Get(OmahaQueryParams::CRX),
17451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 ManifestFetchData::PING);
17461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
17471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1749a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  content::TestBrowserThreadBundle thread_bundle_;
17505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  content::InProcessUtilityThreadHelper in_process_utility_thread_helper_;
1751c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1752c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined OS_CHROMEOS
1753c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
1754c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  chromeos::ScopedTestCrosSettings test_cros_settings_;
1755c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  chromeos::ScopedTestUserManager test_user_manager_;
1756c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Because we test some private methods of ExtensionUpdater, it's easier for the
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// actual test code to live in ExtenionUpdaterTest methods instead of TEST_F
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// subclasses where friendship with ExtenionUpdater is not inherited.
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequests) {
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestExtensionUpdateCheckRequests(false);
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestExtensionUpdateCheckRequestsPending) {
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestExtensionUpdateCheckRequests(true);
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestUpdateUrlData) {
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUpdateUrlDataEmpty();
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUpdateUrlDataSimple();
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUpdateUrlDataCompound();
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestUpdateUrlDataFromGallery(
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_urls::GetWebstoreUpdateUrl().spec());
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestInstallSource) {
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestInstallSource();
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestDetermineUpdates) {
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestDetermineUpdates();
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestDetermineUpdatesPending) {
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestDetermineUpdatesPending();
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestMultipleManifestDownloading) {
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestMultipleManifestDownloading();
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloading) {
17965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSingleExtensionDownloading(false, false, false);
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPending) {
18005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSingleExtensionDownloading(true, false, false);
18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingWithRetry) {
18045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSingleExtensionDownloading(false, true, false);
18052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingPendingWithRetry) {
18085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSingleExtensionDownloading(true, true, false);
18095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
18105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailure) {
18125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSingleExtensionDownloading(false, false, true);
18135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
18145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailureWithRetry) {
18165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSingleExtensionDownloading(false, true, true);
18175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
18185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestSingleExtensionDownloadingFailurePending) {
18205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestSingleExtensionDownloading(true, false, true);
18215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
18225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieAuth) {
18246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload(
18256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "https://chrome.google.com/webstore/download",
18266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      false, false,  // No OAuth2 support
18276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      0, 0);
18286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
18296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
18306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadCookieFailure) {
18316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload(
18326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "https://chrome.google.com/webstore/download",
18336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      false, false,  // No OAuth2 support
18346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      0, -1);  // max_authuser=-1 simulates no valid authuser value.
18356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
18366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
18376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser1) {
18386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload("https://google.com", false, false, 1, 1);
18396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
18406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
18416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithNonDefaultAuthUser2) {
18426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload("https://google.com", false, false, 2, 2);
1843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
18456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadAuthUserExhaustionFailure) {
18466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload("https://google.com", false, false, 2, 5);
1847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
18496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Token) {
18506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload(
18516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "https://google.com",
18526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      true, true,
18536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      0, -1);
1854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
18566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadWithOAuth2Failure) {
18576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload(
18586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "https://google.com",
18596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      true, false,
18606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      0, -1);
18615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
18625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadNoOAuth2WithNonGoogleDomain) {
18646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload(
18656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "https://not-google.com",
18666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      true, true,
18676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      0, -1);
18685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
18695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
18706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, ProtectedDownloadFailWithoutHTTPS) {
18716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  TestProtectedDownload(
18726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      "http://google.com",
18736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      true, true,
18746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      0, 0);
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesFail) {
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestMultipleExtensionDownloading(false);
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestMultipleExtensionDownloadingUpdatesSucceed) {
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestMultipleExtensionDownloading(true);
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestManifestRetryDownloading) {
18852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TestManifestRetryDownloading();
18862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
18872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithOrganicBrand) {
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestGalleryRequestsWithBrand(true);
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestGalleryRequestsWithNonOrganicBrand) {
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestGalleryRequestsWithBrand(false);
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestHandleManifestResults) {
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestHandleManifestResults();
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestNonAutoUpdateableLocations) {
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TestURLFetcherFactory factory;
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceForManifestTests service(prefs_.get());
19036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ExtensionUpdater updater(&service,
19046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.extension_prefs(),
19056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.pref_service(),
19066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.profile(),
19076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           kUpdateFrequencySecs,
19086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           NULL,
19096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.GetDownloaderFactory());
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExtensionDownloaderDelegate delegate;
19116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  service.OverrideDownloaderDelegate(&delegate);
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-internal non-external extensions should be rejected.
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionList extensions;
19152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service.CreateTestExtensions(1, 1, &extensions, NULL,
19162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               Manifest::INVALID_LOCATION);
19172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service.CreateTestExtensions(2, 1, &extensions, NULL, Manifest::INTERNAL);
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(2u, extensions.size());
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& updateable_id = extensions[1]->id();
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These expectations fail if the delegate's methods are invoked for the
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // first extension, which has a non-matching id.
19236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_CALL(delegate,
19246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              GetUpdateUrlData(updateable_id)).WillOnce(Return(""));
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, GetPingDataForExtension(updateable_id, _));
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  service.set_extensions(extensions, ExtensionList());
19282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionUpdater::CheckParams params;
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  updater.Start();
19302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  updater.CheckNow(params);
19311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::RunAllBlockingPoolTasksUntilIdle();
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestUpdatingDisabledExtensions) {
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TestURLFetcherFactory factory;
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceForManifestTests service(prefs_.get());
19376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ExtensionUpdater updater(&service,
19386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.extension_prefs(),
19396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.pref_service(),
19406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.profile(),
19416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           kUpdateFrequencySecs,
19426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           NULL,
19436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.GetDownloaderFactory());
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExtensionDownloaderDelegate delegate;
19456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  service.OverrideDownloaderDelegate(&delegate);
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Non-internal non-external extensions should be rejected.
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionList enabled_extensions;
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionList disabled_extensions;
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.CreateTestExtensions(1, 1, &enabled_extensions, NULL,
19512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Manifest::INTERNAL);
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service.CreateTestExtensions(2, 1, &disabled_extensions, NULL,
19532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Manifest::INTERNAL);
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, enabled_extensions.size());
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, disabled_extensions.size());
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& enabled_id = enabled_extensions[0]->id();
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& disabled_id = disabled_extensions[0]->id();
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We expect that both enabled and disabled extensions are auto-updated.
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, GetUpdateUrlData(enabled_id)).WillOnce(Return(""));
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, GetPingDataForExtension(enabled_id, _));
19626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  EXPECT_CALL(delegate,
19636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)              GetUpdateUrlData(disabled_id)).WillOnce(Return(""));
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, GetPingDataForExtension(disabled_id, _));
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  service.set_extensions(enabled_extensions, disabled_extensions);
19672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ExtensionUpdater::CheckParams params;
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  updater.Start();
19692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  updater.CheckNow(params);
19701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::RunAllBlockingPoolTasksUntilIdle();
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestManifestFetchesBuilderAddExtension) {
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TestURLFetcherFactory factory;
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockService service(prefs_.get());
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExtensionDownloaderDelegate delegate;
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionDownloader> downloader(
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ExtensionDownloader(&delegate, service.request_context()));
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First, verify that adding valid extensions does invoke the callbacks on
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the delegate.
198303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string id = crx_file::id_util::GenerateId("foo");
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(
19862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      downloader->AddPendingExtension(id, GURL("http://example.com/update"),
19872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      0));
19885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  downloader->StartAllPending(NULL);
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Mock::VerifyAndClearExpectations(&delegate);
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extensions with invalid update URLs should be rejected.
199303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  id = crx_file::id_util::GenerateId("foo2");
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(
19952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      downloader->AddPendingExtension(id, GURL("http:google.com:foo"), 0));
19965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  downloader->StartAllPending(NULL);
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extensions with empty IDs should be rejected.
2000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(downloader->AddPendingExtension(std::string(), GURL(), 0));
20015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  downloader->StartAllPending(NULL);
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(akalin): Test that extensions with empty update URLs
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // converted from user scripts are rejected.
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset the ExtensionDownloader so that it drops the current fetcher.
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  downloader.reset(
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new ExtensionDownloader(&delegate, service.request_context()));
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, ManifestFetchersCount(downloader.get()));
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extensions with empty update URLs should have a default one
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // filled in.
201403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  id = crx_file::id_util::GenerateId("foo3");
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(delegate, GetPingDataForExtension(id, _)).WillOnce(Return(false));
20162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(downloader->AddPendingExtension(id, GURL(), 0));
20175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  downloader->StartAllPending(NULL);
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, ManifestFetchersCount(downloader.get()));
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TestURLFetcher* fetcher =
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      factory.GetFetcherByID(ExtensionDownloader::kManifestFetcherId);
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(fetcher);
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(fetcher->GetOriginalURL().is_empty());
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestStartUpdateCheckMemory) {
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TestURLFetcherFactory factory;
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockService service(prefs_.get());
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockExtensionDownloaderDelegate delegate;
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionDownloader downloader(&delegate, service.request_context());
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StartUpdateCheck(&downloader, CreateManifestFetchData(GURL()));
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should delete the newly-created ManifestFetchData.
20341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StartUpdateCheck(&downloader, CreateManifestFetchData(GURL()));
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should add into |manifests_pending_|.
20361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  StartUpdateCheck(&downloader,
20371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   CreateManifestFetchData(GURL("http://www.google.com")));
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The dtor of |downloader| should delete the pending fetchers.
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(ExtensionUpdaterTest, TestCheckSoon) {
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ServiceForManifestTests service(prefs_.get());
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TestURLFetcherFactory factory;
20446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ExtensionUpdater updater(&service,
20456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.extension_prefs(),
20466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.pref_service(),
20476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.profile(),
20486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           kUpdateFrequencySecs,
20496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           NULL,
20506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                           service.GetDownloaderFactory());
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(updater.WillCheckSoon());
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  updater.Start();
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(updater.WillCheckSoon());
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  updater.CheckSoon();
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(updater.WillCheckSoon());
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  updater.CheckSoon();
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(updater.WillCheckSoon());
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunUntilIdle();
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(updater.WillCheckSoon());
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  updater.CheckSoon();
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(updater.WillCheckSoon());
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  updater.Stop();
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(updater.WillCheckSoon());
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(asargent) - (http://crbug.com/12780) add tests for:
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -prodversionmin (shouldn't update if browser version too old)
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -manifests & updates arriving out of order / interleaved
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -malformed update url (empty, file://, has query, has a # fragment, etc.)
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -An extension gets uninstalled while updates are in progress (so it doesn't
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  "come back from the dead")
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -An extension gets manually updated to v3 while we're downloading v2 (ie
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  you don't get downgraded accidentally)
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -An update manifest mentions multiple updates
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
2077