// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/sequenced_worker_pool_owner.h"
#include "base/thread_task_runner_handle.h"
#include "base/values.h"
#include "base/version.h"
#include "components/update_client/crx_update_item.h"
#include "components/update_client/ping_manager.h"
#include "components/update_client/test_configurator.h"
#include "components/update_client/test_installer.h"
#include "components/update_client/update_checker.h"
#include "components/update_client/update_client_internal.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace update_client {

namespace {

using base::FilePath;

// Makes a copy of the file specified by |from_path| in a temporary directory
// and returns the path of the copy. Returns true if successful. Cleans up if
// there was an error creating the copy.
bool MakeTestFile(const FilePath& from_path, FilePath* to_path) {
  FilePath temp_dir;
  bool result =
      CreateNewTempDirectory(FILE_PATH_LITERAL("update_client"), &temp_dir);
  if (!result)
    return false;

  FilePath temp_file;
  result = CreateTemporaryFileInDir(temp_dir, &temp_file);
  if (!result)
    return false;

  result = CopyFile(from_path, temp_file);
  if (!result) {
    DeleteFile(temp_file, false);
    return false;
  }

  *to_path = temp_file;
  return true;
}

using Events = UpdateClient::Observer::Events;

class MockObserver : public UpdateClient::Observer {
 public:
  MOCK_METHOD2(OnEvent, void(Events event, const std::string&));
};

class OnDemandTester {
 public:
  OnDemandTester(const scoped_refptr<UpdateClient>& update_client,
                 bool expected_value);

  void CheckOnDemand(Events event, const std::string&);

 private:
  const scoped_refptr<UpdateClient> update_client_;
  const bool expected_value_;
};

OnDemandTester::OnDemandTester(const scoped_refptr<UpdateClient>& update_client,
                               bool expected_value)
    : update_client_(update_client), expected_value_(expected_value) {
}

void OnDemandTester::CheckOnDemand(Events event, const std::string& id) {
  if (event == Events::COMPONENT_CHECKING_FOR_UPDATES) {
    CrxUpdateItem update_item;
    EXPECT_TRUE(update_client_->GetCrxUpdateState(id, &update_item));
    EXPECT_EQ(update_item.on_demand, expected_value_);
  }
}

class FakePingManagerImpl : public PingManager {
 public:
  explicit FakePingManagerImpl(const Configurator& config);
  ~FakePingManagerImpl() override;

  void OnUpdateComplete(const CrxUpdateItem* item) override;

  const std::vector<CrxUpdateItem>& items() const;

 private:
  std::vector<CrxUpdateItem> items_;
  DISALLOW_COPY_AND_ASSIGN(FakePingManagerImpl);
};

FakePingManagerImpl::FakePingManagerImpl(const Configurator& config)
    : PingManager(config) {
}

FakePingManagerImpl::~FakePingManagerImpl() {
}

void FakePingManagerImpl::OnUpdateComplete(const CrxUpdateItem* item) {
  items_.push_back(*item);
}

const std::vector<CrxUpdateItem>& FakePingManagerImpl::items() const {
  return items_;
}

}  // namespace

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Return;

using std::string;

class UpdateClientTest : public testing::Test {
 public:
  UpdateClientTest();
  ~UpdateClientTest() override;

 protected:
  void RunThreads();
  void StopWorkerPool();

  // Returns the full path to a test file.
  static base::FilePath TestFilePath(const char* file);

  scoped_refptr<update_client::Configurator> config() { return config_; }

  base::Closure quit_closure() { return quit_closure_; }

 private:
  static const int kNumWorkerThreads_ = 2;

  base::MessageLoopForUI message_loop_;
  base::RunLoop runloop_;
  base::Closure quit_closure_;

  scoped_ptr<base::SequencedWorkerPoolOwner> worker_pool_;

  scoped_refptr<update_client::Configurator> config_;

  DISALLOW_COPY_AND_ASSIGN(UpdateClientTest);
};

UpdateClientTest::UpdateClientTest()
    : worker_pool_(
          new base::SequencedWorkerPoolOwner(kNumWorkerThreads_, "test")) {
  quit_closure_ = runloop_.QuitClosure();

  auto pool = worker_pool_->pool();
  config_ = new TestConfigurator(
      pool->GetSequencedTaskRunner(pool->GetSequenceToken()),
      message_loop_.task_runner());
}

UpdateClientTest::~UpdateClientTest() {
}

void UpdateClientTest::RunThreads() {
  runloop_.Run();
}

void UpdateClientTest::StopWorkerPool() {
  worker_pool_->pool()->Shutdown();
}

base::FilePath UpdateClientTest::TestFilePath(const char* file) {
  base::FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  return path.AppendASCII("components")
      .AppendASCII("test")
      .AppendASCII("data")
      .AppendASCII("update_client")
      .AppendASCII(file);
}

// Tests the scenario where one update check is done for one CRX. The CRX
// has no update.
TEST_F(UpdateClientTest, OneCrxNoUpdate) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx.version = Version("0.9");
      crx.installer = new TestInstaller;
      components->push_back(crx);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "",
                                UpdateResponse::Results()));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override { EXPECT_TRUE(items().empty()); }
  };

  scoped_ptr<PingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  // Verify that calling Update does not set ondemand.
  OnDemandTester ondemand_tester(update_client, false);

  MockObserver observer;
  ON_CALL(observer, OnEvent(_, _))
      .WillByDefault(Invoke(&ondemand_tester, &OnDemandTester::CheckOnDemand));

  InSequence seq;
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));

  update_client->Update(
      ids, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the scenario where two CRXs are checked for updates. On CRX has
// an update, the other CRX does not.
TEST_F(UpdateClientTest, TwoCrxUpdateNoUpdate) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      CrxComponent crx1;
      crx1.name = "test_jebg";
      crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx1.version = Version("0.9");
      crx1.installer = new TestInstaller;

      CrxComponent crx2;
      crx2.name = "test_abag";
      crx2.pk_hash.assign(abag_hash, abag_hash + arraysize(abag_hash));
      crx2.version = Version("2.2");
      crx2.installer = new TestInstaller;

      components->push_back(crx1);
      components->push_back(crx2);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      /*
      Fake the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.0'>
        <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      UpdateResponse::Result::Manifest::Package package;
      package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";

      UpdateResponse::Result result;
      result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
      result.crx_urls.push_back(GURL("http://localhost/download/"));
      result.manifest.version = "1.0";
      result.manifest.browser_min_version = "11.0.1.0";
      result.manifest.packages.push_back(package);

      UpdateResponse::Results results;
      results.list.push_back(result);

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      download_metrics.url = url;
      download_metrics.downloader = DownloadMetrics::kNone;
      download_metrics.error = 0;
      download_metrics.downloaded_bytes = 1843;
      download_metrics.total_bytes = 1843;
      download_metrics.download_time_ms = 1000;

      FilePath path;
      EXPECT_TRUE(MakeTestFile(
          TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path));

      Result result;
      result.error = 0;
      result.response = path;
      result.downloaded_bytes = 1843;
      result.total_bytes = 1843;

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
                                base::Unretained(this), result));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&FakeCrxDownloader::OnDownloadComplete,
                     base::Unretained(this), true, result, download_metrics));
    }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override {
      const auto& ping_items = items();
      EXPECT_EQ(1U, ping_items.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
      EXPECT_TRUE(base::Version("0.9").Equals(ping_items[0].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[0].next_version));
      EXPECT_EQ(0, ping_items[0].error_category);
      EXPECT_EQ(0, ping_items[0].error_code);
    }
  };

  scoped_ptr<PingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  }
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "abagagagagagagagagagagagagagagag")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
                                  "abagagagagagagagagagagagagagagag")).Times(1);
  }

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
  ids.push_back(std::string("abagagagagagagagagagagagagagagag"));

  update_client->Update(
      ids, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the update check for two CRXs scenario. Both CRXs have updates.
TEST_F(UpdateClientTest, TwoCrxUpdate) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      CrxComponent crx1;
      crx1.name = "test_jebg";
      crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx1.version = Version("0.9");
      crx1.installer = new TestInstaller;

      CrxComponent crx2;
      crx2.name = "test_ihfo";
      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
      crx2.version = Version("0.8");
      crx2.installer = new TestInstaller;

      components->push_back(crx1);
      components->push_back(crx2);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      /*
      Fake the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.0'>
        <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
        <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      UpdateResponse::Result::Manifest::Package package1;
      package1.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";

      UpdateResponse::Result result1;
      result1.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
      result1.crx_urls.push_back(GURL("http://localhost/download/"));
      result1.manifest.version = "1.0";
      result1.manifest.browser_min_version = "11.0.1.0";
      result1.manifest.packages.push_back(package1);

      UpdateResponse::Result::Manifest::Package package2;
      package2.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";

      UpdateResponse::Result result2;
      result2.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
      result2.crx_urls.push_back(GURL("http://localhost/download/"));
      result2.manifest.version = "1.0";
      result2.manifest.browser_min_version = "11.0.1.0";
      result2.manifest.packages.push_back(package2);

      UpdateResponse::Results results;
      results.list.push_back(result1);
      results.list.push_back(result2);

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      FilePath path;
      Result result;
      if (url.path() == "/download/jebgalgnebhfojomionfpkfelancnnkf.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 1843;
        download_metrics.total_bytes = 1843;
        download_metrics.download_time_ms = 1000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 1843;
        result.total_bytes = 1843;
      } else if (url.path() ==
                 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 53638;
        download_metrics.total_bytes = 53638;
        download_metrics.download_time_ms = 2000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 53638;
        result.total_bytes = 53638;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
                                base::Unretained(this), result));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&FakeCrxDownloader::OnDownloadComplete,
                     base::Unretained(this), true, result, download_metrics));
    }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override {
      const auto& ping_items = items();
      EXPECT_EQ(2U, ping_items.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
      EXPECT_TRUE(base::Version("0.9").Equals(ping_items[0].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[0].next_version));
      EXPECT_EQ(0, ping_items[0].error_category);
      EXPECT_EQ(0, ping_items[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
      EXPECT_TRUE(base::Version("0.8").Equals(ping_items[1].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[1].next_version));
      EXPECT_EQ(0, ping_items[1].error_category);
      EXPECT_EQ(0, ping_items[1].error_code);
    }
  };

  scoped_ptr<FakePingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  }
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_WAIT,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
  }

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
  ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));

  update_client->Update(
      ids, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the scenario where there is a download timeout for the first
// CRX. The update for the first CRX fails. The update client waits before
// attempting the update for the second CRX. This update succeeds.
TEST_F(UpdateClientTest, TwoCrxUpdateDownloadTimeout) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      CrxComponent crx1;
      crx1.name = "test_jebg";
      crx1.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx1.version = Version("0.9");
      crx1.installer = new TestInstaller;

      CrxComponent crx2;
      crx2.name = "test_ihfo";
      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
      crx2.version = Version("0.8");
      crx2.installer = new TestInstaller;

      components->push_back(crx1);
      components->push_back(crx2);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      /*
      Fake the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.0'>
        <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
        <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      UpdateResponse::Result::Manifest::Package package1;
      package1.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";

      UpdateResponse::Result result1;
      result1.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
      result1.crx_urls.push_back(GURL("http://localhost/download/"));
      result1.manifest.version = "1.0";
      result1.manifest.browser_min_version = "11.0.1.0";
      result1.manifest.packages.push_back(package1);

      UpdateResponse::Result::Manifest::Package package2;
      package2.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";

      UpdateResponse::Result result2;
      result2.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
      result2.crx_urls.push_back(GURL("http://localhost/download/"));
      result2.manifest.version = "1.0";
      result2.manifest.browser_min_version = "11.0.1.0";
      result2.manifest.packages.push_back(package2);

      UpdateResponse::Results results;
      results.list.push_back(result1);
      results.list.push_back(result2);

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      FilePath path;
      Result result;
      if (url.path() == "/download/jebgalgnebhfojomionfpkfelancnnkf.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = -118;
        download_metrics.downloaded_bytes = 0;
        download_metrics.total_bytes = 0;
        download_metrics.download_time_ms = 1000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path));

        result.error = -118;
        result.response = path;
        result.downloaded_bytes = 0;
        result.total_bytes = 0;
      } else if (url.path() ==
                 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 53638;
        download_metrics.total_bytes = 53638;
        download_metrics.download_time_ms = 2000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 53638;
        result.total_bytes = 53638;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
                                base::Unretained(this), result));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&FakeCrxDownloader::OnDownloadComplete,
                     base::Unretained(this), true, result, download_metrics));
    }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override {
      const auto& ping_items = items();
      EXPECT_EQ(2U, ping_items.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
      EXPECT_TRUE(base::Version("0.9").Equals(ping_items[0].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[0].next_version));
      EXPECT_EQ(1, ping_items[0].error_category);  // Network error.
      EXPECT_EQ(-118, ping_items[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
      EXPECT_TRUE(base::Version("0.8").Equals(ping_items[1].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[1].next_version));
      EXPECT_EQ(0, ping_items[1].error_category);
      EXPECT_EQ(0, ping_items[1].error_code);
    }
  };

  scoped_ptr<FakePingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  }
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_WAIT,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
  }

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));
  ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));

  update_client->Update(
      ids, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the differential update scenario for one CRX.
TEST_F(UpdateClientTest, OneCrxDiffUpdate) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      static int num_calls = 0;

      // Must use the same stateful installer object.
      static scoped_refptr<CrxInstaller> installer(
          new VersionedTestInstaller());

      ++num_calls;

      CrxComponent crx;
      crx.name = "test_ihfo";
      crx.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
      crx.installer = installer;
      if (num_calls == 1) {
        crx.version = Version("0.8");
      } else if (num_calls == 2) {
        crx.version = Version("1.0");
      } else {
        NOTREACHED();
      }

      components->push_back(crx);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      static int num_call = 0;
      ++num_call;

      UpdateResponse::Results results;

      if (num_call == 1) {
        /*
        Fake the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.0'>
          <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
            <updatecheck status='ok'>
              <urls>
                <url codebase='http://localhost/download/'/>
              </urls>
              <manifest version='1.0' prodversionmin='11.0.1.0'>
                <packages>
                  <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        UpdateResponse::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
        package.fingerprint = "1";
        UpdateResponse::Result result;
        result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        result.crx_urls.push_back(GURL("http://localhost/download/"));
        result.manifest.version = "1.0";
        result.manifest.browser_min_version = "11.0.1.0";
        result.manifest.packages.push_back(package);
        results.list.push_back(result);
      } else if (num_call == 2) {
        /*
        Fake the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.0'>
          <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
            <updatecheck status='ok'>
              <urls>
                <url codebase='http://localhost/download/'/>
                <url codebasediff='http://localhost/download/'/>
              </urls>
              <manifest version='2.0' prodversionmin='11.0.1.0'>
                <packages>
                  <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
                           namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
                           fp='22'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        UpdateResponse::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
        package.namediff = "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
        package.fingerprint = "22";
        UpdateResponse::Result result;
        result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        result.crx_urls.push_back(GURL("http://localhost/download/"));
        result.crx_diffurls.push_back(GURL("http://localhost/download/"));
        result.manifest.version = "2.0";
        result.manifest.browser_min_version = "11.0.1.0";
        result.manifest.packages.push_back(package);
        results.list.push_back(result);
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      FilePath path;
      Result result;
      if (url.path() == "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 53638;
        download_metrics.total_bytes = 53638;
        download_metrics.download_time_ms = 2000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 53638;
        result.total_bytes = 53638;
      } else if (url.path() ==
                 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 2105;
        download_metrics.total_bytes = 2105;
        download_metrics.download_time_ms = 1000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 2105;
        result.total_bytes = 2105;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
                                base::Unretained(this), result));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&FakeCrxDownloader::OnDownloadComplete,
                     base::Unretained(this), true, result, download_metrics));
    }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override {
      const auto& ping_items = items();
      EXPECT_EQ(2U, ping_items.size());
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[0].id);
      EXPECT_TRUE(base::Version("0.8").Equals(ping_items[0].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[0].next_version));
      EXPECT_EQ(0, ping_items[0].error_category);
      EXPECT_EQ(0, ping_items[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[1].previous_version));
      EXPECT_TRUE(base::Version("2.0").Equals(ping_items[1].next_version));
      EXPECT_EQ(0, ping_items[1].diff_error_category);
      EXPECT_EQ(0, ping_items[1].diff_error_code);
    }
  };

  scoped_ptr<FakePingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
  }

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));

  {
    base::RunLoop runloop;
    update_client->Update(
        ids, base::Bind(&DataCallbackFake::Callback),
        base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
    runloop.Run();
  }

  {
    base::RunLoop runloop;
    update_client->Update(
        ids, base::Bind(&DataCallbackFake::Callback),
        base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
    runloop.Run();
  }

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the update scenario for one CRX where the CRX installer returns
// an error.
TEST_F(UpdateClientTest, OneCrxInstallError) {
  class MockInstaller : public CrxInstaller {
   public:
    MOCK_METHOD1(OnUpdateError, void(int error));
    MOCK_METHOD2(Install,
                 bool(const base::DictionaryValue& manifest,
                      const base::FilePath& unpack_path));
    MOCK_METHOD2(GetInstalledFile,
                 bool(const std::string& file, base::FilePath* installed_file));
    MOCK_METHOD0(Uninstall, bool());

    static void OnInstall(const base::DictionaryValue& manifest,
                          const base::FilePath& unpack_path) {
      base::DeleteFile(unpack_path, true);
    }

   protected:
    ~MockInstaller() override {}
  };

  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      scoped_refptr<MockInstaller> installer(new MockInstaller());

      EXPECT_CALL(*installer, OnUpdateError(_)).Times(0);
      EXPECT_CALL(*installer, Install(_, _))
          .WillOnce(DoAll(Invoke(MockInstaller::OnInstall), Return(false)));
      EXPECT_CALL(*installer, GetInstalledFile(_, _)).Times(0);
      EXPECT_CALL(*installer, Uninstall()).Times(0);

      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx.version = Version("0.9");
      crx.installer = installer;
      components->push_back(crx);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      /*
      Fake the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.0'>
        <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      UpdateResponse::Result::Manifest::Package package;
      package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";

      UpdateResponse::Result result;
      result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
      result.crx_urls.push_back(GURL("http://localhost/download/"));
      result.manifest.version = "1.0";
      result.manifest.browser_min_version = "11.0.1.0";
      result.manifest.packages.push_back(package);

      UpdateResponse::Results results;
      results.list.push_back(result);

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      download_metrics.url = url;
      download_metrics.downloader = DownloadMetrics::kNone;
      download_metrics.error = 0;
      download_metrics.downloaded_bytes = 1843;
      download_metrics.total_bytes = 1843;
      download_metrics.download_time_ms = 1000;

      FilePath path;
      EXPECT_TRUE(MakeTestFile(
          TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path));

      Result result;
      result.error = 0;
      result.response = path;
      result.downloaded_bytes = 1843;
      result.total_bytes = 1843;

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
                                base::Unretained(this), result));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&FakeCrxDownloader::OnDownloadComplete,
                     base::Unretained(this), true, result, download_metrics));
    }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override {
      const auto& ping_items = items();
      EXPECT_EQ(1U, ping_items.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
      EXPECT_TRUE(base::Version("0.9").Equals(ping_items[0].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[0].next_version));
      EXPECT_EQ(3, ping_items[0].error_category);  // kInstallError.
      EXPECT_EQ(9, ping_items[0].error_code);      // kInstallerError.
    }
  };

  scoped_ptr<PingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  }

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));

  update_client->Update(
      ids, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the fallback from differential to full update scenario for one CRX.
TEST_F(UpdateClientTest, OneCrxDiffUpdateFailsFullUpdateSucceeds) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      static int num_calls = 0;

      // Must use the same stateful installer object.
      static scoped_refptr<CrxInstaller> installer(
          new VersionedTestInstaller());

      ++num_calls;

      CrxComponent crx;
      crx.name = "test_ihfo";
      crx.pk_hash.assign(ihfo_hash, ihfo_hash + arraysize(ihfo_hash));
      crx.installer = installer;
      if (num_calls == 1) {
        crx.version = Version("0.8");
      } else if (num_calls == 2) {
        crx.version = Version("1.0");
      } else {
        NOTREACHED();
      }

      components->push_back(crx);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      static int num_call = 0;
      ++num_call;

      UpdateResponse::Results results;

      if (num_call == 1) {
        /*
        Fake the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.0'>
          <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
            <updatecheck status='ok'>
              <urls>
                <url codebase='http://localhost/download/'/>
              </urls>
              <manifest version='1.0' prodversionmin='11.0.1.0'>
                <packages>
                  <package name='ihfokbkgjpifnbbojhneepfflplebdkc_1.crx'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        UpdateResponse::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
        package.fingerprint = "1";
        UpdateResponse::Result result;
        result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        result.crx_urls.push_back(GURL("http://localhost/download/"));
        result.manifest.version = "1.0";
        result.manifest.browser_min_version = "11.0.1.0";
        result.manifest.packages.push_back(package);
        results.list.push_back(result);
      } else if (num_call == 2) {
        /*
        Fake the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.0'>
          <app appid='ihfokbkgjpifnbbojhneepfflplebdkc'>
            <updatecheck status='ok'>
              <urls>
                <url codebase='http://localhost/download/'/>
                <url codebasediff='http://localhost/download/'/>
              </urls>
              <manifest version='2.0' prodversionmin='11.0.1.0'>
                <packages>
                  <package name='ihfokbkgjpifnbbojhneepfflplebdkc_2.crx'
                           namediff='ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx'
                           fp='22'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        UpdateResponse::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
        package.namediff = "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
        package.fingerprint = "22";
        UpdateResponse::Result result;
        result.extension_id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        result.crx_urls.push_back(GURL("http://localhost/download/"));
        result.crx_diffurls.push_back(GURL("http://localhost/download/"));
        result.manifest.version = "2.0";
        result.manifest.browser_min_version = "11.0.1.0";
        result.manifest.packages.push_back(package);
        results.list.push_back(result);
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      FilePath path;
      Result result;
      if (url.path() == "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 53638;
        download_metrics.total_bytes = 53638;
        download_metrics.download_time_ms = 2000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 53638;
        result.total_bytes = 53638;
      } else if (url.path() ==
                 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx") {
        // A download error is injected on this execution path.
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = -1;
        download_metrics.downloaded_bytes = 0;
        download_metrics.total_bytes = 2105;
        download_metrics.download_time_ms = 1000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx"), &path));

        result.error = -1;
        result.response = path;
        result.downloaded_bytes = 0;
        result.total_bytes = 2105;
      } else if (url.path() ==
                 "/download/ihfokbkgjpifnbbojhneepfflplebdkc_2.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 53855;
        download_metrics.total_bytes = 53855;
        download_metrics.download_time_ms = 1000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("ihfokbkgjpifnbbojhneepfflplebdkc_2.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 53855;
        result.total_bytes = 53855;
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
                                base::Unretained(this), result));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&FakeCrxDownloader::OnDownloadComplete,
                     base::Unretained(this), true, result, download_metrics));
    }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override {
      const auto& ping_items = items();
      EXPECT_EQ(2U, ping_items.size());
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[0].id);
      EXPECT_TRUE(base::Version("0.8").Equals(ping_items[0].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[0].next_version));
      EXPECT_EQ(0, ping_items[0].error_category);
      EXPECT_EQ(0, ping_items[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_items[1].id);
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[1].previous_version));
      EXPECT_TRUE(base::Version("2.0").Equals(ping_items[1].next_version));
      EXPECT_TRUE(ping_items[1].diff_update_failed);
      EXPECT_EQ(1, ping_items[1].diff_error_category);  // kNetworkError.
      EXPECT_EQ(-1, ping_items[1].diff_error_code);
    }
  };

  scoped_ptr<FakePingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);

    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc")).Times(1);
  }

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("ihfokbkgjpifnbbojhneepfflplebdkc"));

  {
    base::RunLoop runloop;
    update_client->Update(
        ids, base::Bind(&DataCallbackFake::Callback),
        base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
    runloop.Run();
  }

  {
    base::RunLoop runloop;
    update_client->Update(
        ids, base::Bind(&DataCallbackFake::Callback),
        base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
    runloop.Run();
  }

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the queuing of update checks. In this scenario, two update checks are
// done for one CRX. The second update check call is queued up and will run
// after the first check has completed. The CRX has no updates.
TEST_F(UpdateClientTest, OneCrxNoUpdateQueuedCall) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx.version = Version("0.9");
      crx.installer = new TestInstaller;
      components->push_back(crx);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      static int num_call = 0;
      ++num_call;

      EXPECT_EQ(0, error);

      if (num_call == 2)
        quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "",
                                UpdateResponse::Results()));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override { EXPECT_TRUE(items().empty()); }
  };

  scoped_ptr<PingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  MockObserver observer;
  InSequence seq;
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);

  update_client->AddObserver(&observer);

  std::vector<std::string> ids;
  ids.push_back(std::string("jebgalgnebhfojomionfpkfelancnnkf"));

  update_client->Update(
      ids, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));
  update_client->Update(
      ids, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests the install of one CRX.
TEST_F(UpdateClientTest, OneCrxInstall) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx.version = Version("0.0");
      crx.installer = new TestInstaller;

      components->push_back(crx);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      EXPECT_EQ(0, error);
      quit_closure.Run();
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      /*
      Fake the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.0'>
        <app appid='jebgalgnebhfojomionfpkfelancnnkf'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='jebgalgnebhfojomionfpkfelancnnkf.crx'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      UpdateResponse::Result::Manifest::Package package;
      package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";

      UpdateResponse::Result result;
      result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
      result.crx_urls.push_back(GURL("http://localhost/download/"));
      result.manifest.version = "1.0";
      result.manifest.browser_min_version = "11.0.1.0";
      result.manifest.packages.push_back(package);

      UpdateResponse::Results results;
      results.list.push_back(result);

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "", results));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      FilePath path;
      Result result;
      if (url.path() == "/download/jebgalgnebhfojomionfpkfelancnnkf.crx") {
        download_metrics.url = url;
        download_metrics.downloader = DownloadMetrics::kNone;
        download_metrics.error = 0;
        download_metrics.downloaded_bytes = 1843;
        download_metrics.total_bytes = 1843;
        download_metrics.download_time_ms = 1000;

        EXPECT_TRUE(MakeTestFile(
            TestFilePath("jebgalgnebhfojomionfpkfelancnnkf.crx"), &path));

        result.error = 0;
        result.response = path;
        result.downloaded_bytes = 1843;
        result.total_bytes = 1843;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(&FakeCrxDownloader::OnDownloadProgress,
                                base::Unretained(this), result));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(&FakeCrxDownloader::OnDownloadComplete,
                     base::Unretained(this), true, result, download_metrics));
    }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override {
      const auto& ping_items = items();
      EXPECT_EQ(1U, ping_items.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_items[0].id);
      EXPECT_TRUE(base::Version("0.0").Equals(ping_items[0].previous_version));
      EXPECT_TRUE(base::Version("1.0").Equals(ping_items[0].next_version));
      EXPECT_EQ(0, ping_items[0].error_category);
      EXPECT_EQ(0, ping_items[0].error_code);
    }
  };

  scoped_ptr<FakePingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  // Verify that calling Install sets ondemand.
  OnDemandTester ondemand_tester(update_client, true);

  MockObserver observer;
  ON_CALL(observer, OnEvent(_, _))
      .WillByDefault(Invoke(&ondemand_tester, &OnDemandTester::CheckOnDemand));

  InSequence seq;
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_FOUND,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_DOWNLOADING,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATED,
                                "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);

  update_client->AddObserver(&observer);

  update_client->Install(
      std::string("jebgalgnebhfojomionfpkfelancnnkf"),
      base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Tests that overlapping installs of the same CRX result in an error.
TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + arraysize(jebg_hash));
      crx.version = Version("0.0");
      crx.installer = new TestInstaller;

      components->push_back(crx);
    }
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      static int num_call = 0;
      ++num_call;

      EXPECT_LE(num_call, 2);

      if (num_call == 1) {
        EXPECT_EQ(Error::ERROR_UPDATE_IN_PROGRESS, error);
        return;
      }
      if (num_call == 2) {
        EXPECT_EQ(0, error);
        quit_closure.Run();
      }
    }
  };

  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::Bind(update_check_callback, GURL(), 0, "",
                                UpdateResponse::Results()));
      return true;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
  };

  class FakePingManager : public FakePingManagerImpl {
   public:
    explicit FakePingManager(const Configurator& config)
        : FakePingManagerImpl(config) {}
    ~FakePingManager() override { EXPECT_TRUE(items().empty()); }
  };

  scoped_ptr<FakePingManager> ping_manager(new FakePingManager(*config()));
  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), ping_manager.Pass(), &FakeUpdateChecker::Create,
      &FakeCrxDownloader::Create));

  // Verify that calling Install sets ondemand.
  OnDemandTester ondemand_tester(update_client, true);

  MockObserver observer;
  ON_CALL(observer, OnEvent(_, _))
      .WillByDefault(Invoke(&ondemand_tester, &OnDemandTester::CheckOnDemand));

  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                "jebgalgnebhfojomionfpkfelancnnkf"))
      .Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_NOT_UPDATED,
                                "jebgalgnebhfojomionfpkfelancnnkf"))
      .Times(1);

  update_client->AddObserver(&observer);

  update_client->Install(
      std::string("jebgalgnebhfojomionfpkfelancnnkf"),
      base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  update_client->Install(
      std::string("jebgalgnebhfojomionfpkfelancnnkf"),
      base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);

  StopWorkerPool();
}

// Make sure that we don't get any crashes when trying to update an empty list
// of ids.
TEST_F(UpdateClientTest, EmptyIdList) {
  class DataCallbackFake {
   public:
    static void Callback(const std::vector<std::string>& ids,
                         std::vector<CrxComponent>* components) {}
  };

  class CompletionCallbackFake {
   public:
    static void Callback(const base::Closure& quit_closure, int error) {
      quit_closure.Run();
    }
  };
  class FakeUpdateChecker : public UpdateChecker {
   public:
    static scoped_ptr<UpdateChecker> Create(const Configurator& config) {
      return scoped_ptr<UpdateChecker>(new FakeUpdateChecker());
    }

    bool CheckForUpdates(
        const std::vector<CrxUpdateItem*>& items_to_check,
        const std::string& additional_attributes,
        const UpdateCheckCallback& update_check_callback) override {
      return false;
    }
  };

  class FakeCrxDownloader : public CrxDownloader {
   public:
    static scoped_ptr<CrxDownloader> Create(
        bool is_background_download,
        net::URLRequestContextGetter* context_getter,
        const scoped_refptr<base::SequencedTaskRunner>&
            url_fetcher_task_runner) {
      return scoped_ptr<CrxDownloader>(new FakeCrxDownloader());
    }

   private:
    FakeCrxDownloader() : CrxDownloader(scoped_ptr<CrxDownloader>().Pass()) {}
    ~FakeCrxDownloader() override {}

    void DoStartDownload(const GURL& url) override { EXPECT_TRUE(false); }
  };

  scoped_refptr<UpdateClient> update_client(new UpdateClientImpl(
      config(), make_scoped_ptr(new FakePingManagerImpl(*config())),
      &FakeUpdateChecker::Create, &FakeCrxDownloader::Create));

  std::vector<std::string> empty_id_list;
  base::RunLoop runloop;
  update_client->Update(
      empty_id_list, base::Bind(&DataCallbackFake::Callback),
      base::Bind(&CompletionCallbackFake::Callback, runloop.QuitClosure()));
  runloop.Run();

  StopWorkerPool();
}

}  // namespace update_client
