// 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 <memory>
#include <utility>

#include "base/bind.h"
#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "base/test/scoped_path_override.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/values.h"
#include "base/version.h"
#include "build/build_config.h"
#include "components/crx_file/crx_verifier.h"
#include "components/prefs/testing_pref_service.h"
#include "components/update_client/component_unpacker.h"
#include "components/update_client/crx_update_item.h"
#include "components/update_client/persisted_data.h"
#include "components/update_client/ping_manager.h"
#include "components/update_client/protocol_parser.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_errors.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&));
};

}  // namespace

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

using std::string;

class MockPingManagerImpl : public PingManager {
 public:
  struct PingData {
    std::string id;
    base::Version previous_version;
    base::Version next_version;
    ErrorCategory error_category = ErrorCategory::kNone;
    int error_code = 0;
    int extra_code1 = 0;
    ErrorCategory diff_error_category = ErrorCategory::kNone;
    int diff_error_code = 0;
    bool diff_update_failed = false;
  };

  explicit MockPingManagerImpl(scoped_refptr<Configurator> config);

  void SendPing(const Component& component, Callback callback) override;

  const std::vector<PingData>& ping_data() const;

  const std::vector<base::Value>& events() const;

 protected:
  ~MockPingManagerImpl() override;

 private:
  std::vector<PingData> ping_data_;
  std::vector<base::Value> events_;
  DISALLOW_COPY_AND_ASSIGN(MockPingManagerImpl);
};

MockPingManagerImpl::MockPingManagerImpl(scoped_refptr<Configurator> config)
    : PingManager(config) {}

MockPingManagerImpl::~MockPingManagerImpl() {}

void MockPingManagerImpl::SendPing(const Component& component,
                                   Callback callback) {
  PingData ping_data;
  ping_data.id = component.id_;
  ping_data.previous_version = component.previous_version_;
  ping_data.next_version = component.next_version_;
  ping_data.error_category = component.error_category_;
  ping_data.error_code = component.error_code_;
  ping_data.extra_code1 = component.extra_code1_;
  ping_data.diff_error_category = component.diff_error_category_;
  ping_data.diff_error_code = component.diff_error_code_;
  ping_data.diff_update_failed = component.diff_update_failed();
  ping_data_.push_back(ping_data);

  events_ = component.GetEvents();

  std::move(callback).Run(0, "");
}

const std::vector<MockPingManagerImpl::PingData>&
MockPingManagerImpl::ping_data() const {
  return ping_data_;
}

const std::vector<base::Value>& MockPingManagerImpl::events() const {
  return events_;
}

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

 protected:
  void RunThreads();

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

  scoped_refptr<update_client::TestConfigurator> config() { return config_; }
  update_client::PersistedData* metadata() { return metadata_.get(); }

  base::OnceClosure quit_closure() { return runloop_.QuitClosure(); }

 private:
  static constexpr int kNumWorkerThreads_ = 2;

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  base::RunLoop runloop_;

  scoped_refptr<update_client::TestConfigurator> config_ =
      base::MakeRefCounted<TestConfigurator>();
  std::unique_ptr<TestingPrefServiceSimple> pref_ =
      std::make_unique<TestingPrefServiceSimple>();
  std::unique_ptr<update_client::PersistedData> metadata_;

  DISALLOW_COPY_AND_ASSIGN(UpdateClientTest);
};

constexpr int UpdateClientTest::kNumWorkerThreads_;

UpdateClientTest::UpdateClientTest() {
  PersistedData::RegisterPrefs(pref_->registry());
  metadata_ = std::make_unique<PersistedData>(pref_.get(), nullptr);
}

UpdateClientTest::~UpdateClientTest() {
}

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

base::FilePath UpdateClientTest::TestFilePath(const char* file) {
  base::FilePath path;
  base::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 DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx.version = base::Version("0.9");
      crx.installer = base::MakeRefCounted<TestInstaller>();
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      std::vector<base::Optional<CrxComponent>> component = {crx};
      return component;
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(1u, ids_to_check.size());
      const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
      EXPECT_EQ(id, ids_to_check.front());
      EXPECT_EQ(1u, components.count(id));

      auto& component = components.at(id);

      EXPECT_TRUE(component->is_foreground());

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "noupdate";

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

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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);

  update_client->AddObserver(&observer);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), true,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// 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 DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx1;
      crx1.name = "test_jebg";
      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx1.version = base::Version("0.9");
      crx1.installer = base::MakeRefCounted<TestInstaller>();
      crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      CrxComponent crx2;
      crx2.name = "test_abag";
      crx2.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
      crx2.version = base::Version("2.2");
      crx2.installer = base::MakeRefCounted<TestInstaller>();
      crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      return {crx1, crx2};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <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'
                         hash_sha256='6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd
                                      7c9b12cb7cc067667bde87'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
        <app appid='abagagagagagagagagagagagagagagag'>
          <updatecheck status='noupdate'/>
        </app>
      </response>
      */
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(2u, ids_to_check.size());

      ProtocolParser::Results results;
      {
        const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
        package.hash_sha256 =
            "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";

        ProtocolParser::Result result;
        result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
        result.status = "ok";
        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);

        EXPECT_FALSE(components.at(id)->is_foreground());
      }

      {
        const std::string id = "abagagagagagagagagagagagagagagag";
        EXPECT_EQ(id, ids_to_check[1]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "noupdate";
        results.list.push_back(result);

        EXPECT_FALSE(components.at(id)->is_foreground());
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(1u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(0, ping_data[0].error_code);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(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);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
                                        "abagagagagagagagagagagagagagagag"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests the scenario where two CRXs are checked for updates. One CRX has
// an update but the server ignores the second CRX and returns no response for
// it. The second component gets an |UPDATE_RESPONSE_NOT_FOUND| error and
// transitions to the error state.
TEST_F(UpdateClientTest, TwoCrxUpdateFirstServerIgnoresSecond) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx1;
      crx1.name = "test_jebg";
      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx1.version = base::Version("0.9");
      crx1.installer = base::MakeRefCounted<TestInstaller>();
      crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      CrxComponent crx2;
      crx2.name = "test_abag";
      crx2.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
      crx2.version = base::Version("2.2");
      crx2.installer = base::MakeRefCounted<TestInstaller>();
      crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      return {crx1, crx2};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <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'
                         hash_sha256='6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd
                                      7c9b12cb7cc067667bde87'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(2u, ids_to_check.size());

      ProtocolParser::Results results;
      {
        const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
        package.hash_sha256 =
            "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";

        ProtocolParser::Result result;
        result.extension_id = "jebgalgnebhfojomionfpkfelancnnkf";
        result.status = "ok";
        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);

        EXPECT_FALSE(components.at(id)->is_foreground());
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(1u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(0, ping_data[0].error_code);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(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_UPDATE_ERROR,
                                  "abagagagagagagagagagagagagagagag"))
        .Times(1)
        .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
          CrxUpdateItem item;
          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
          EXPECT_EQ(ComponentState::kUpdateError, item.state);
          EXPECT_EQ(5, static_cast<int>(item.error_category));
          EXPECT_EQ(-10004, item.error_code);
          EXPECT_EQ(0, item.extra_code1);
        }));
  }

  update_client->AddObserver(&observer);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
                                        "abagagagagagagagagagagagagagagag"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests the update check for two CRXs scenario when the second CRX does not
// provide a CrxComponent instance. In this case, the update is handled as
// if only one component were provided as an argument to the |Update| call
// with the exception that the second component still fires an event such as
// |COMPONENT_UPDATE_ERROR|.
TEST_F(UpdateClientTest, TwoCrxUpdateNoCrxComponentData) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx.version = base::Version("0.9");
      crx.installer = base::MakeRefCounted<TestInstaller>();
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      return {crx, base::nullopt};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <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'
                         hash_sha256='6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd
                                      7c9b12cb7cc067667bde87'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(1u, ids_to_check.size());

      ProtocolParser::Results results;
      {
        const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
        package.hash_sha256 =
            "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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);

        EXPECT_FALSE(components.at(id)->is_foreground());
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(1u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(0, ping_data[0].error_code);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(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_UPDATE_ERROR,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc"))
        .Times(1);
  }

  update_client->AddObserver(&observer);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
                                        "ihfokbkgjpifnbbojhneepfflplebdkc"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests the update check for two CRXs scenario when no CrxComponent data is
// provided for either component. In this case, no update check occurs, and
// |COMPONENT_UPDATE_ERROR| event fires for both components.
TEST_F(UpdateClientTest, TwoCrxUpdateNoCrxComponentDataAtAll) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      return {base::nullopt, base::nullopt};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      NOTREACHED();
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    void DoStartDownload(const GURL& url) override { NOTREACHED(); }
  };

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      EXPECT_EQ(0u, MockPingManagerImpl::ping_data().size());
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "jebgalgnebhfojomionfpkfelancnnkf"))
        .Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc"))
        .Times(1);
  }

  update_client->AddObserver(&observer);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
                                        "ihfokbkgjpifnbbojhneepfflplebdkc"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// 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 DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx1;
      crx1.name = "test_jebg";
      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx1.version = base::Version("0.9");
      crx1.installer = base::MakeRefCounted<TestInstaller>();
      crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      CrxComponent crx2;
      crx2.name = "test_ihfo";
      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
      crx2.version = base::Version("0.8");
      crx2.installer = base::MakeRefCounted<TestInstaller>();
      crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      return {crx1, crx2};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <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'
                         hash_sha256='6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd
                                      7c9b12cb7cc067667bde87'/>
              </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'
                         hash_sha256='813c59747e139a608b3b5fc49633affc6db574373f
                                      309f156ea6d27229c0b3f9'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */

      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(2u, ids_to_check.size());

      ProtocolParser::Results results;
      {
        const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
        package.hash_sha256 =
            "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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);
      }

      {
        const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        EXPECT_EQ(id, ids_to_check[1]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
        package.hash_sha256 =
            "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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);
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;

        // The result must not include a file path in the case of errors.
        result.error = -118;
      } 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;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(2u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(1, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(-118, ping_data[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
      EXPECT_EQ(base::Version("0.8"), ping_data[1].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[1].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[1].error_category));
      EXPECT_EQ(0, ping_data[1].error_code);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(1));
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "jebgalgnebhfojomionfpkfelancnnkf"))
        .Times(1)
        .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
          CrxUpdateItem item;
          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
          EXPECT_EQ(ComponentState::kUpdateError, item.state);
          EXPECT_EQ(1, static_cast<int>(item.error_category));
          EXPECT_EQ(-118, item.error_code);
          EXPECT_EQ(0, item.extra_code1);
        }));
  }
  {
    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(AtLeast(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);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
                                        "ihfokbkgjpifnbbojhneepfflplebdkc"};

  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

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

      // Must use the same stateful installer object.
      static scoped_refptr<CrxInstaller> installer =
          base::MakeRefCounted<VersionedTestInstaller>();

      ++num_calls;

      CrxComponent crx;
      crx.name = "test_ihfo";
      crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
      crx.installer = installer;
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      if (num_calls == 1) {
        crx.version = base::Version("0.8");
      } else if (num_calls == 2) {
        crx.version = base::Version("1.0");
      } else {
        NOTREACHED();
      }

      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());

      static int num_call = 0;
      ++num_call;

      ProtocolParser::Results results;

      if (num_call == 1) {
        /*
        Mock the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.1'>
          <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'
                           hash_sha256='813c59747e139a608b3b5fc49633affc6db57437
                                        3f309f156ea6d27229c0b3f9'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
        package.hash_sha256 =
            "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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) {
        /*
        Mock the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.1'>
          <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'
                           hash_sha256='1af337fbd19c72db0f870753bcd7711c3ae9dcaa
                                        0ecde26c262bad942b112990'
                           fp='22'
                           hashdiff_sha256='73c6e2d4f783fc4ca5481e89e0b8bfce7aec
                                            8ead3686290c94792658ec06f2f2'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
        package.namediff = "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
        package.hash_sha256 =
            "1af337fbd19c72db0f870753bcd7711c3ae9dcaa0ecde26c262bad942b112990";
        package.hashdiff_sha256 =
            "73c6e2d4f783fc4ca5481e89e0b8bfce7aec8ead3686290c94792658ec06f2f2";
        package.fingerprint = "22";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;
      } 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;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(2u, ping_data.size());
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[0].id);
      EXPECT_EQ(base::Version("0.8"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(0, ping_data[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
      EXPECT_EQ(base::Version("1.0"), ping_data[1].previous_version);
      EXPECT_EQ(base::Version("2.0"), ping_data[1].next_version);
      EXPECT_FALSE(ping_data[1].diff_update_failed);
      EXPECT_EQ(0, static_cast<int>(ping_data[1].diff_error_category));
      EXPECT_EQ(0, ping_data[1].diff_error_code);
      EXPECT_EQ(0, static_cast<int>(ping_data[1].error_category));
      EXPECT_EQ(0, ping_data[1].error_code);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(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(AtLeast(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);

  const std::vector<std::string> ids = {"ihfokbkgjpifnbbojhneepfflplebdkc"};
  {
    base::RunLoop runloop;
    update_client->Update(ids, base::BindOnce(&DataCallbackMock::Callback),
                          false,
                          base::BindOnce(&CompletionCallbackMock::Callback,
                                         runloop.QuitClosure()));
    runloop.Run();
  }

  {
    base::RunLoop runloop;
    update_client->Update(ids, base::BindOnce(&DataCallbackMock::Callback),
                          false,
                          base::BindOnce(&CompletionCallbackMock::Callback,
                                         runloop.QuitClosure()));
    runloop.Run();
  }

  update_client->RemoveObserver(&observer);
}

// Tests the update scenario for one CRX where the CRX installer returns
// an error. Tests that the |unpack_path| argument refers to a valid path
// then |Install| is called, then tests that the |unpack| path is deleted
// by the |update_client| code before the test ends.
TEST_F(UpdateClientTest, OneCrxInstallError) {
  class MockInstaller : public CrxInstaller {
   public:
    MOCK_METHOD1(OnUpdateError, void(int error));
    MOCK_METHOD2(DoInstall,
                 void(const base::FilePath& unpack_path,
                      const Callback& callback));
    MOCK_METHOD2(GetInstalledFile,
                 bool(const std::string& file, base::FilePath* installed_file));
    MOCK_METHOD0(Uninstall, bool());

    void Install(const base::FilePath& unpack_path,
                 const std::string& public_key,
                 Callback callback) override {
      DoInstall(unpack_path, std::move(callback));

      unpack_path_ = unpack_path;
      EXPECT_TRUE(base::DirectoryExists(unpack_path_));
      base::PostTaskWithTraits(
          FROM_HERE, {base::MayBlock()},
          base::BindOnce(std::move(callback),
                         CrxInstaller::Result(InstallError::GENERIC_ERROR)));
    }

   protected:
    ~MockInstaller() override {
      // The unpack path is deleted unconditionally by the component state code,
      // which is driving this installer. Therefore, the unpack path must not
      // exist when this object is destroyed.
      if (!unpack_path_.empty())
        EXPECT_FALSE(base::DirectoryExists(unpack_path_));
    }

   private:
    // Contains the |unpack_path| argument of the Install call.
    base::FilePath unpack_path_;
  };

  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      scoped_refptr<MockInstaller> installer =
          base::MakeRefCounted<MockInstaller>();

      EXPECT_CALL(*installer, OnUpdateError(_)).Times(0);
      EXPECT_CALL(*installer, DoInstall(_, _)).Times(1);
      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 + base::size(jebg_hash));
      crx.version = base::Version("0.9");
      crx.installer = installer;
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <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'
                         hash_sha256='6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd
                                      7c9b12cb7cc067667bde87'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      EXPECT_FALSE(session_id.empty());

      const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
      EXPECT_EQ(id, ids_to_check[0]);
      EXPECT_EQ(1u, components.count(id));

      ProtocolParser::Result::Manifest::Package package;
      package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
      package.hash_sha256 =
          "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "ok";
      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);

      ProtocolParser::Results results;
      results.list.push_back(result);
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(1u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(3, static_cast<int>(ping_data[0].error_category));  // kInstall.
      EXPECT_EQ(9, ping_data[0].error_code);  // kInstallerError.
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(1));
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_READY,
                                  "jebgalgnebhfojomionfpkfelancnnkf")).Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "jebgalgnebhfojomionfpkfelancnnkf"))
        .Times(1);
  }

  update_client->AddObserver(&observer);

  std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

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

      // Must use the same stateful installer object.
      static scoped_refptr<CrxInstaller> installer =
          base::MakeRefCounted<VersionedTestInstaller>();

      ++num_calls;

      CrxComponent crx;
      crx.name = "test_ihfo";
      crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
      crx.installer = installer;
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      if (num_calls == 1) {
        crx.version = base::Version("0.8");
      } else if (num_calls == 2) {
        crx.version = base::Version("1.0");
      } else {
        NOTREACHED();
      }

      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());

      static int num_call = 0;
      ++num_call;

      ProtocolParser::Results results;

      if (num_call == 1) {
        /*
        Mock the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.1'>
          <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'
                           hash_sha256='813c59747e139a608b3b5fc49633affc6db57437
                                        3f309f156ea6d27229c0b3f9'
                           fp='1'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
        package.hash_sha256 =
            "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";
        package.fingerprint = "1";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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) {
        /*
        Mock the following response:
        <?xml version='1.0' encoding='UTF-8'?>
        <response protocol='3.1'>
          <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'
                           hash_sha256='1af337fbd19c72db0f870753bcd7711c3ae9dcaa
                                        0ecde26c262bad942b112990'
                           fp='22'
                           hashdiff_sha256='73c6e2d4f783fc4ca5481e89e0b8bfce7aec
                                            8ead3686290c94792658ec06f2f2'/>
                </packages>
              </manifest>
            </updatecheck>
          </app>
        </response>
        */
        const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_2.crx";
        package.namediff = "ihfokbkgjpifnbbojhneepfflplebdkc_1to2.crx";
        package.hash_sha256 =
            "1af337fbd19c72db0f870753bcd7711c3ae9dcaa0ecde26c262bad942b112990";
        package.hashdiff_sha256 =
            "73c6e2d4f783fc4ca5481e89e0b8bfce7aec8ead3686290c94792658ec06f2f2";
        package.fingerprint = "22";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;
      } 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;

        // The response must not include a file path in the case of errors.
        result.error = -1;
      } 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;
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(2u, ping_data.size());
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[0].id);
      EXPECT_EQ(base::Version("0.8"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(0, ping_data[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
      EXPECT_EQ(base::Version("1.0"), ping_data[1].previous_version);
      EXPECT_EQ(base::Version("2.0"), ping_data[1].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[1].error_category));
      EXPECT_EQ(0, ping_data[1].error_code);
      EXPECT_TRUE(ping_data[1].diff_update_failed);
      EXPECT_EQ(1, static_cast<int>(ping_data[1].diff_error_category));
      EXPECT_EQ(-1, ping_data[1].diff_error_code);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(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(AtLeast(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);

  const std::vector<std::string> ids = {"ihfokbkgjpifnbbojhneepfflplebdkc"};

  {
    base::RunLoop runloop;
    update_client->Update(ids, base::BindOnce(&DataCallbackMock::Callback),
                          false,
                          base::BindOnce(&CompletionCallbackMock::Callback,
                                         runloop.QuitClosure()));
    runloop.Run();
  }

  {
    base::RunLoop runloop;
    update_client->Update(ids, base::BindOnce(&DataCallbackMock::Callback),
                          false,
                          base::BindOnce(&CompletionCallbackMock::Callback,
                                         runloop.QuitClosure()));
    runloop.Run();
  }

  update_client->RemoveObserver(&observer);
}

// 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 DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx.version = base::Version("0.9");
      crx.installer = base::MakeRefCounted<TestInstaller>();
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      static int num_call = 0;
      ++num_call;

      EXPECT_EQ(Error::NONE, error);

      if (num_call == 2)
        std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(1u, ids_to_check.size());
      const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
      EXPECT_EQ(id, ids_to_check.front());
      EXPECT_EQ(1u, components.count(id));

      auto& component = components.at(id);

      EXPECT_FALSE(component->is_foreground());

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "noupdate";
      ProtocolParser::Results results;
      results.list.push_back(result);

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests the install of one CRX.
TEST_F(UpdateClientTest, OneCrxInstall) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx.version = base::Version("0.0");
      crx.installer = base::MakeRefCounted<TestInstaller>();
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <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'
                         hash_sha256='6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd
                                      7c9b12cb7cc067667bde87'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(1u, ids_to_check.size());

      const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
      EXPECT_EQ(id, ids_to_check[0]);
      EXPECT_EQ(1u, components.count(id));

      ProtocolParser::Result::Manifest::Package package;
      package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
      package.hash_sha256 =
          "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "ok";
      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);

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

      // Verify that calling Install sets ondemand.
      EXPECT_TRUE(components.at(id)->is_foreground());

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(1u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("0.0"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(0, ping_data[0].error_code);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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(AtLeast(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::BindOnce(&DataCallbackMock::Callback),
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests the install of one CRX when no component data is provided. This
// results in an install error.
TEST_F(UpdateClientTest, OneCrxInstallNoCrxComponentData) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      return {base::nullopt};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      NOTREACHED();
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    void DoStartDownload(const GURL& url) override { NOTREACHED(); }
  };

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      EXPECT_EQ(0u, MockPingManagerImpl::ping_data().size());
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  MockObserver observer;
  InSequence seq;
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                "jebgalgnebhfojomionfpkfelancnnkf"))
      .Times(1)
      .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
        // Tests that the state of the component when the CrxComponent data
        // is not provided. In this case, the optional |item.component| instance
        // is not present.
        CrxUpdateItem item;
        EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
        EXPECT_EQ(ComponentState::kUpdateError, item.state);
        EXPECT_STREQ("jebgalgnebhfojomionfpkfelancnnkf", item.id.c_str());
        EXPECT_FALSE(item.component);
        EXPECT_EQ(ErrorCategory::kService, item.error_category);
        EXPECT_EQ(static_cast<int>(Error::CRX_NOT_FOUND), item.error_code);
        EXPECT_EQ(0, item.extra_code1);
      }));

  update_client->AddObserver(&observer);

  update_client->Install(
      std::string("jebgalgnebhfojomionfpkfelancnnkf"),
      base::BindOnce(&DataCallbackMock::Callback),
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests that overlapping installs of the same CRX result in an error.
TEST_F(UpdateClientTest, ConcurrentInstallSameCRX) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx.version = base::Version("0.0");
      crx.installer = base::MakeRefCounted<TestInstaller>();
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      static int num_call = 0;
      ++num_call;

      EXPECT_LE(num_call, 2);

      if (num_call == 1) {
        EXPECT_EQ(Error::UPDATE_IN_PROGRESS, error);
        return;
      }
      if (num_call == 2) {
        EXPECT_EQ(Error::NONE, error);
        std::move(quit_closure).Run();
      }
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(1u, ids_to_check.size());
      const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
      EXPECT_EQ(id, ids_to_check.front());
      EXPECT_EQ(1u, components.count(id));

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "noupdate";

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

      // Verify that calling Install sets |is_foreground| for the component.
      EXPECT_TRUE(components.at(id)->is_foreground());

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  MockObserver observer;
  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::BindOnce(&DataCallbackMock::Callback),
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  update_client->Install(
      std::string("jebgalgnebhfojomionfpkfelancnnkf"),
      base::BindOnce(&DataCallbackMock::Callback),
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests that UpdateClient::Update returns Error::INVALID_ARGUMENT when
// the |ids| parameter is empty.
TEST_F(UpdateClientTest, EmptyIdList) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      return {};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      DCHECK_EQ(Error::INVALID_ARGUMENT, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      NOTREACHED();
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  const std::vector<std::string> empty_id_list;
  update_client->Update(
      empty_id_list, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));
  RunThreads();
}

TEST_F(UpdateClientTest, SendUninstallPing) {
  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return nullptr;
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      NOTREACHED();
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return nullptr;
    }

   private:
    MockCrxDownloader() : CrxDownloader(nullptr) {}
    ~MockCrxDownloader() override {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(1u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("1.2.3.4"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("0"), ping_data[0].next_version);
      EXPECT_EQ(10, ping_data[0].extra_code1);
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  update_client->SendUninstallPing(
      "jebgalgnebhfojomionfpkfelancnnkf", base::Version("1.2.3.4"), 10,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();
}

TEST_F(UpdateClientTest, RetryAfter) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx.version = base::Version("0.9");
      crx.installer = base::MakeRefCounted<TestInstaller>();
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      static int num_call = 0;
      ++num_call;

      EXPECT_LE(num_call, 4);

      if (num_call == 1) {
        EXPECT_EQ(Error::NONE, error);
      } else if (num_call == 2) {
        // This request is throttled since the update engine received a
        // positive |retry_after_sec| value in the update check response.
        EXPECT_EQ(Error::RETRY_LATER, error);
      } else if (num_call == 3) {
        // This request is a foreground Install, which is never throttled.
        // The update engine received a |retry_after_sec| value of 0, which
        // resets the throttling.
        EXPECT_EQ(Error::NONE, error);
      } else if (num_call == 4) {
        // This request succeeds since there is no throttling in effect.
        EXPECT_EQ(Error::NONE, error);
      }

      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());

      static int num_call = 0;
      ++num_call;

      EXPECT_LE(num_call, 3);

      int retry_after_sec(0);
      if (num_call == 1) {
        // Throttle the next call.
        retry_after_sec = 60 * 60;  // 1 hour.
      }

      EXPECT_EQ(1u, ids_to_check.size());
      const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
      EXPECT_EQ(id, ids_to_check.front());
      EXPECT_EQ(1u, components.count(id));

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "noupdate";

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

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, retry_after_sec));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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);
  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);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
  {
    // The engine handles this Update call but responds with a valid
    // |retry_after_sec|, which causes subsequent calls to fail.
    base::RunLoop runloop;
    update_client->Update(ids, base::BindOnce(&DataCallbackMock::Callback),
                          false,
                          base::BindOnce(&CompletionCallbackMock::Callback,
                                         runloop.QuitClosure()));
    runloop.Run();
  }

  {
    // This call will result in a completion callback invoked with
    // Error::ERROR_UPDATE_RETRY_LATER.
    base::RunLoop runloop;
    update_client->Update(ids, base::BindOnce(&DataCallbackMock::Callback),
                          false,
                          base::BindOnce(&CompletionCallbackMock::Callback,
                                         runloop.QuitClosure()));
    runloop.Run();
  }

  {
    // The Install call is handled, and the throttling is reset due to
    // the value of |retry_after_sec| in the completion callback.
    base::RunLoop runloop;
    update_client->Install(std::string("jebgalgnebhfojomionfpkfelancnnkf"),
                           base::BindOnce(&DataCallbackMock::Callback),
                           base::BindOnce(&CompletionCallbackMock::Callback,
                                          runloop.QuitClosure()));
    runloop.Run();
  }

  {
    // This call succeeds.
    base::RunLoop runloop;
    update_client->Update(ids, base::BindOnce(&DataCallbackMock::Callback),
                          false,
                          base::BindOnce(&CompletionCallbackMock::Callback,
                                         runloop.QuitClosure()));
    runloop.Run();
  }

  update_client->RemoveObserver(&observer);
}

// Tests the update check for two CRXs scenario. The first component supports
// the group policy to enable updates, and has its updates disabled. The second
// component has an update. The server does not honor the "updatedisabled"
// attribute and returns updates for both components. However, the update for
// the first component is not applied and the client responds with a
// (SERVICE_ERROR, UPDATE_DISABLED)
TEST_F(UpdateClientTest, TwoCrxUpdateOneUpdateDisabled) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx1;
      crx1.name = "test_jebg";
      crx1.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx1.version = base::Version("0.9");
      crx1.installer = base::MakeRefCounted<TestInstaller>();
      crx1.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      crx1.supports_group_policy_enable_component_updates = true;

      CrxComponent crx2;
      crx2.name = "test_ihfo";
      crx2.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
      crx2.version = base::Version("0.8");
      crx2.installer = base::MakeRefCounted<TestInstaller>();
      crx2.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;

      return {crx1, crx2};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <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'
                         hash_sha256='6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd
                                      7c9b12cb7cc067667bde87'/>
              </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'
                         hash_sha256='813c59747e139a608b3b5fc49633affc6db574373f
                                      309f156ea6d27229c0b3f9'/>
              </packages>
            </manifest>
          </updatecheck>
        </app>
      </response>
      */

      // UpdateClient reads the state of |enabled_component_updates| from the
      // configurator instance, persists its value in the corresponding
      // update context, and propagates it down to each of the update actions,
      // and further down to the UpdateChecker instance.
      EXPECT_FALSE(session_id.empty());
      EXPECT_FALSE(enabled_component_updates);
      EXPECT_EQ(2u, ids_to_check.size());

      ProtocolParser::Results results;
      {
        const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
        EXPECT_EQ(id, ids_to_check[0]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "jebgalgnebhfojomionfpkfelancnnkf.crx";
        package.hash_sha256 =
            "6fc4b93fd11134de1300c2c0bb88c12b644a4ec0fd7c9b12cb7cc067667bde87";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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);
      }

      {
        const std::string id = "ihfokbkgjpifnbbojhneepfflplebdkc";
        EXPECT_EQ(id, ids_to_check[1]);
        EXPECT_EQ(1u, components.count(id));

        ProtocolParser::Result::Manifest::Package package;
        package.name = "ihfokbkgjpifnbbojhneepfflplebdkc_1.crx";
        package.hash_sha256 =
            "813c59747e139a608b3b5fc49633affc6db574373f309f156ea6d27229c0b3f9";

        ProtocolParser::Result result;
        result.extension_id = id;
        result.status = "ok";
        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);
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    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;
      } else {
        NOTREACHED();
      }

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(&MockCrxDownloader::OnDownloadProgress,
                                    base::Unretained(this)));

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      const auto ping_data = MockPingManagerImpl::ping_data();
      EXPECT_EQ(2u, ping_data.size());
      EXPECT_EQ("jebgalgnebhfojomionfpkfelancnnkf", ping_data[0].id);
      EXPECT_EQ(base::Version("0.9"), ping_data[0].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[0].next_version);
      EXPECT_EQ(4, static_cast<int>(ping_data[0].error_category));
      EXPECT_EQ(2, ping_data[0].error_code);
      EXPECT_EQ("ihfokbkgjpifnbbojhneepfflplebdkc", ping_data[1].id);
      EXPECT_EQ(base::Version("0.8"), ping_data[1].previous_version);
      EXPECT_EQ(base::Version("1.0"), ping_data[1].next_version);
      EXPECT_EQ(0, static_cast<int>(ping_data[1].error_category));
      EXPECT_EQ(0, ping_data[1].error_code);
    }
  };

  // Disables updates for the components declaring support for the group policy.
  config()->SetEnabledComponentUpdates(false);
  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::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_ERROR,
                                  "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_UPDATE_DOWNLOADING,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc"))
        .Times(AtLeast(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);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf",
                                        "ihfokbkgjpifnbbojhneepfflplebdkc"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests the scenario where the update check fails.
TEST_F(UpdateClientTest, OneCrxUpdateCheckFails) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      CrxComponent crx;
      crx.name = "test_jebg";
      crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
      crx.version = base::Version("0.9");
      crx.installer = base::MakeRefCounted<TestInstaller>();
      crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
      return {crx};
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::UPDATE_CHECK_ERROR, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(1u, ids_to_check.size());
      const std::string id = "jebgalgnebhfojomionfpkfelancnnkf";
      EXPECT_EQ(id, ids_to_check.front());
      EXPECT_EQ(1u, components.count(id));
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::BindOnce(std::move(update_check_callback), base::nullopt,
                         ErrorCategory::kUpdateCheck, -1, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  MockObserver observer;
  InSequence seq;
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                "jebgalgnebhfojomionfpkfelancnnkf"))
      .Times(1);
  EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                "jebgalgnebhfojomionfpkfelancnnkf"))
      .Times(1)
      .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
        CrxUpdateItem item;
        EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
        EXPECT_EQ(ComponentState::kUpdateError, item.state);
        EXPECT_EQ(5, static_cast<int>(item.error_category));
        EXPECT_EQ(-1, item.error_code);
        EXPECT_EQ(0, item.extra_code1);
      }));

  update_client->AddObserver(&observer);

  const std::vector<std::string> ids = {"jebgalgnebhfojomionfpkfelancnnkf"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), false,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

// Tests the scenario where the server responds with different values for
// application status.
TEST_F(UpdateClientTest, OneCrxErrorUnknownApp) {
  class DataCallbackMock {
   public:
    static std::vector<base::Optional<CrxComponent>> Callback(
        const std::vector<std::string>& ids) {
      std::vector<base::Optional<CrxComponent>> component;
      {
        CrxComponent crx;
        crx.name = "test_jebg";
        crx.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
        crx.version = base::Version("0.9");
        crx.installer = base::MakeRefCounted<TestInstaller>();
        crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
        component.push_back(crx);
      }
      {
        CrxComponent crx;
        crx.name = "test_abag";
        crx.pk_hash.assign(abag_hash, abag_hash + base::size(abag_hash));
        crx.version = base::Version("0.1");
        crx.installer = base::MakeRefCounted<TestInstaller>();
        crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
        component.push_back(crx);
      }
      {
        CrxComponent crx;
        crx.name = "test_ihfo";
        crx.pk_hash.assign(ihfo_hash, ihfo_hash + base::size(ihfo_hash));
        crx.version = base::Version("0.2");
        crx.installer = base::MakeRefCounted<TestInstaller>();
        crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
        component.push_back(crx);
      }
      {
        CrxComponent crx;
        crx.name = "test_gjpm";
        crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
        crx.version = base::Version("0.3");
        crx.installer = base::MakeRefCounted<TestInstaller>();
        crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
        component.push_back(crx);
      }
      return component;
    }
  };

  class CompletionCallbackMock {
   public:
    static void Callback(base::OnceClosure quit_closure, Error error) {
      EXPECT_EQ(Error::NONE, error);
      std::move(quit_closure).Run();
    }
  };

  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(4u, ids_to_check.size());

      const std::string update_response =
          R"(<?xml version="1.0" encoding="UTF-8"?>)"
          R"(<response protocol="3.1">)"
          R"(<app appid="jebgalgnebhfojomionfpkfelancnnkf")"
          R"( status="error-unknownApplication"/>)"
          R"(<app appid="abagagagagagagagagagagagagagagag")"
          R"( status="restricted"/>)"
          R"(<app appid="ihfokbkgjpifnbbojhneepfflplebdkc")"
          R"( status="error-invalidAppId"/>)"
          R"(<app appid="gjpmebpgbhcamgdgjcmnjfhggjpgcimm")"
          R"( status="error-foobarApp"/>)"
          R"(</response>)";

      const auto parser = ProtocolParser::Create();
      EXPECT_TRUE(parser->Parse(update_response));

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::BindOnce(std::move(update_check_callback), parser->results(),
                         ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override { EXPECT_TRUE(ping_data().empty()); }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  MockObserver observer;
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "jebgalgnebhfojomionfpkfelancnnkf"))
        .Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "jebgalgnebhfojomionfpkfelancnnkf"))
        .Times(1)
        .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
          CrxUpdateItem item;
          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
          EXPECT_EQ(ComponentState::kUpdateError, item.state);
          EXPECT_EQ(5, static_cast<int>(item.error_category));
          EXPECT_EQ(-10006, item.error_code);  // UNKNOWN_APPPLICATION.
          EXPECT_EQ(0, item.extra_code1);
        }));
  }
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "abagagagagagagagagagagagagagagag"))
        .Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "abagagagagagagagagagagagagagagag"))
        .Times(1)
        .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
          CrxUpdateItem item;
          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
          EXPECT_EQ(ComponentState::kUpdateError, item.state);
          EXPECT_EQ(5, static_cast<int>(item.error_category));
          EXPECT_EQ(-10007, item.error_code);  // RESTRICTED_APPLICATION.
          EXPECT_EQ(0, item.extra_code1);
        }));
  }
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc"))
        .Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "ihfokbkgjpifnbbojhneepfflplebdkc"))
        .Times(1)
        .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
          CrxUpdateItem item;
          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
          EXPECT_EQ(ComponentState::kUpdateError, item.state);
          EXPECT_EQ(5, static_cast<int>(item.error_category));
          EXPECT_EQ(-10008, item.error_code);  // INVALID_APPID.
          EXPECT_EQ(0, item.extra_code1);
        }));
  }
  {
    InSequence seq;
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_CHECKING_FOR_UPDATES,
                                  "gjpmebpgbhcamgdgjcmnjfhggjpgcimm"))
        .Times(1);
    EXPECT_CALL(observer, OnEvent(Events::COMPONENT_UPDATE_ERROR,
                                  "gjpmebpgbhcamgdgjcmnjfhggjpgcimm"))
        .Times(1)
        .WillOnce(Invoke([&update_client](Events event, const std::string& id) {
          CrxUpdateItem item;
          EXPECT_TRUE(update_client->GetCrxUpdateState(id, &item));
          EXPECT_EQ(ComponentState::kUpdateError, item.state);
          EXPECT_EQ(5, static_cast<int>(item.error_category));
          EXPECT_EQ(-10004, item.error_code);  // UPDATE_RESPONSE_NOT_FOUND.
          EXPECT_EQ(0, item.extra_code1);
        }));
  }

  update_client->AddObserver(&observer);

  const std::vector<std::string> ids = {
      "jebgalgnebhfojomionfpkfelancnnkf", "abagagagagagagagagagagagagagagag",
      "ihfokbkgjpifnbbojhneepfflplebdkc", "gjpmebpgbhcamgdgjcmnjfhggjpgcimm"};
  update_client->Update(
      ids, base::BindOnce(&DataCallbackMock::Callback), true,
      base::BindOnce(&CompletionCallbackMock::Callback, quit_closure()));

  RunThreads();

  update_client->RemoveObserver(&observer);
}

#if defined(OS_WIN)  // ActionRun is only implemented on Windows.

// Tests that a run action in invoked in the CRX install scenario.
TEST_F(UpdateClientTest, ActionRun_Install) {
  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <app appid='gjpmebpgbhcamgdgjcmnjfhggjpgcimm'>
          <updatecheck status='ok'>
            <urls>
              <url codebase='http://localhost/download/'/>
            </urls>
            <manifest version='1.0' prodversionmin='11.0.1.0'>
              <packages>
                <package name='runaction_test_win.crx3'
                         hash_sha256='89290a0d2ff21ca5b45e109c6cc859ab5fe294e19c102d54acd321429c372cea'/>
              </packages>
            </manifest>
            <actions>"
             <action run='ChromeRecovery.crx3'/>"
            </actions>"
          </updatecheck>
        </app>
      </response>
      */
      EXPECT_FALSE(session_id.empty());
      EXPECT_TRUE(enabled_component_updates);
      EXPECT_EQ(1u, ids_to_check.size());

      const std::string id = "gjpmebpgbhcamgdgjcmnjfhggjpgcimm";
      EXPECT_EQ(id, ids_to_check[0]);
      EXPECT_EQ(1u, components.count(id));

      ProtocolParser::Result::Manifest::Package package;
      package.name = "runaction_test_win.crx3";
      package.hash_sha256 =
          "89290a0d2ff21ca5b45e109c6cc859ab5fe294e19c102d54acd321429c372cea";

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "ok";
      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);
      result.action_run = "ChromeRecovery.crx3";

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

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

   private:
    void DoStartDownload(const GURL& url) override {
      DownloadMetrics download_metrics;
      FilePath path;
      Result result;
      if (url.path() == "/download/runaction_test_win.crx3") {
        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("runaction_test_win.crx3"), &path));

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

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      EXPECT_EQ(3u, events().size());

      /*
      "<event eventtype="14" eventresult="1" downloader="unknown" "
      "url="http://localhost/download/runaction_test_win.crx3"
      "downloaded="1843" "
      "total="1843" download_time_ms="1000" previousversion="0.0" "
      "nextversion="1.0"/>"
      */
      const auto& event0 = events()[0];
      EXPECT_EQ(14, event0.FindKey("eventtype")->GetInt());
      EXPECT_EQ(1, event0.FindKey("eventresult")->GetInt());
      EXPECT_EQ("unknown", event0.FindKey("downloader")->GetString());
      EXPECT_EQ("http://localhost/download/runaction_test_win.crx3",
                event0.FindKey("url")->GetString());
      EXPECT_EQ("1843", event0.FindKey("downloaded")->GetString());
      EXPECT_EQ("1843", event0.FindKey("total")->GetString());
      EXPECT_EQ("1000", event0.FindKey("download_time_ms")->GetString());
      EXPECT_EQ("0.0", event0.FindKey("previousversion")->GetString());
      EXPECT_EQ("1.0", event0.FindKey("nextversion")->GetString());

      // "<event eventtype="42" eventresult="1" errorcode="1877345072"/>"
      const auto& event1 = events()[1];
      EXPECT_EQ(42, event1.FindKey("eventtype")->GetInt());
      EXPECT_EQ(1, event1.FindKey("eventresult")->GetInt());
      EXPECT_EQ(1877345072, event1.FindKey("errorcode")->GetInt());

      // "<event eventtype=\"3\" eventresult=\"1\" previousversion=\"0.0\" "
      // "nextversion=\"1.0\"/>",
      const auto& event2 = events()[2];
      EXPECT_EQ(3, event2.FindKey("eventtype")->GetInt());
      EXPECT_EQ(1, event1.FindKey("eventresult")->GetInt());
      EXPECT_EQ("0.0", event0.FindKey("previousversion")->GetString());
      EXPECT_EQ("1.0", event0.FindKey("nextversion")->GetString());
    }
  };

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  // The action is a program which returns 1877345072 as a hardcoded value.
  update_client->Install(
      std::string("gjpmebpgbhcamgdgjcmnjfhggjpgcimm"),
      base::BindOnce([](const std::vector<std::string>& ids) {
        CrxComponent crx;
        crx.name = "test_niea";
        crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
        crx.version = base::Version("0.0");
        crx.installer = base::MakeRefCounted<VersionedTestInstaller>();
        crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
        return std::vector<base::Optional<CrxComponent>>{crx};
      }),
      base::BindOnce(
          [](base::OnceClosure quit_closure, Error error) {
            EXPECT_EQ(Error::NONE, error);
            std::move(quit_closure).Run();
          },
          quit_closure()));

  RunThreads();
}

// Tests that a run action is invoked in an update scenario when there was
// no update.
TEST_F(UpdateClientTest, ActionRun_NoUpdate) {
  class MockUpdateChecker : public UpdateChecker {
   public:
    static std::unique_ptr<UpdateChecker> Create(
        scoped_refptr<Configurator> config,
        PersistedData* metadata) {
      return std::make_unique<MockUpdateChecker>();
    }

    void CheckForUpdates(
        const std::string& session_id,
        const std::vector<std::string>& ids_to_check,
        const IdToComponentPtrMap& components,
        const base::flat_map<std::string, std::string>& additional_attributes,
        bool enabled_component_updates,
        UpdateCheckCallback update_check_callback) override {
      /*
      Mock the following response:

      <?xml version='1.0' encoding='UTF-8'?>
      <response protocol='3.1'>
        <app appid='gjpmebpgbhcamgdgjcmnjfhggjpgcimm'>
          <updatecheck status='noupdate'>
            <actions>"
             <action run=ChromeRecovery.crx3'/>"
            </actions>"
          </updatecheck>
        </app>
      </response>
      */
      EXPECT_FALSE(session_id.empty());
      EXPECT_EQ(1u, ids_to_check.size());
      const std::string id = "gjpmebpgbhcamgdgjcmnjfhggjpgcimm";
      EXPECT_EQ(id, ids_to_check[0]);
      EXPECT_EQ(1u, components.count(id));

      ProtocolParser::Result result;
      result.extension_id = id;
      result.status = "noupdate";
      result.action_run = "ChromeRecovery.crx3";

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

      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE, base::BindOnce(std::move(update_check_callback), results,
                                    ErrorCategory::kNone, 0, 0));
    }
  };

  class MockCrxDownloader : public CrxDownloader {
   public:
    static std::unique_ptr<CrxDownloader> Create(
        bool is_background_download,
        scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
      return std::make_unique<MockCrxDownloader>();
    }

    MockCrxDownloader() : CrxDownloader(nullptr) {}

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

  class MockPingManager : public MockPingManagerImpl {
   public:
    explicit MockPingManager(scoped_refptr<Configurator> config)
        : MockPingManagerImpl(config) {}

   protected:
    ~MockPingManager() override {
      EXPECT_EQ(1u, events().size());

      // "<event eventtype="42" eventresult="1" errorcode="1877345072"/>"
      const auto& event = events()[0];
      EXPECT_EQ(42, event.FindKey("eventtype")->GetInt());
      EXPECT_EQ(1, event.FindKey("eventresult")->GetInt());
      EXPECT_EQ(1877345072, event.FindKey("errorcode")->GetInt());
    }
  };

  // Unpack the CRX to mock an existing install to be updated. The payload to
  // run is going to be picked up from this directory.
  base::FilePath unpack_path;
  {
    base::RunLoop runloop;
    base::OnceClosure quit_closure = runloop.QuitClosure();

    auto config = base::MakeRefCounted<TestConfigurator>();
    auto component_unpacker = base::MakeRefCounted<ComponentUnpacker>(
        std::vector<uint8_t>(std::begin(gjpm_hash), std::end(gjpm_hash)),
        TestFilePath("runaction_test_win.crx3"), nullptr,
        config->CreateServiceManagerConnector(),
        crx_file::VerifierFormat::CRX2_OR_CRX3);

    component_unpacker->Unpack(base::BindOnce(
        [](base::FilePath* unpack_path, base::OnceClosure quit_closure,
           const ComponentUnpacker::Result& result) {
          EXPECT_EQ(UnpackerError::kNone, result.error);
          EXPECT_EQ(0, result.extended_error);
          *unpack_path = result.unpack_path;
          std::move(quit_closure).Run();
        },
        &unpack_path, runloop.QuitClosure()));

    runloop.Run();
  }

  EXPECT_FALSE(unpack_path.empty());
  EXPECT_TRUE(base::DirectoryExists(unpack_path));
  int64_t file_size = 0;
  EXPECT_TRUE(base::GetFileSize(unpack_path.AppendASCII("ChromeRecovery.crx3"),
                                &file_size));
  EXPECT_EQ(44582, file_size);

  base::ScopedTempDir unpack_path_owner;
  EXPECT_TRUE(unpack_path_owner.Set(unpack_path));

  scoped_refptr<UpdateClient> update_client =
      base::MakeRefCounted<UpdateClientImpl>(
          config(), base::MakeRefCounted<MockPingManager>(config()),
          &MockUpdateChecker::Create, &MockCrxDownloader::Create);

  // The action is a program which returns 1877345072 as a hardcoded value.
  const std::vector<std::string> ids = {"gjpmebpgbhcamgdgjcmnjfhggjpgcimm"};
  update_client->Update(
      ids,
      base::BindOnce(
          [](const base::FilePath& unpack_path,
             const std::vector<std::string>& ids) {
            CrxComponent crx;
            crx.name = "test_niea";
            crx.pk_hash.assign(gjpm_hash, gjpm_hash + base::size(gjpm_hash));
            crx.version = base::Version("1.0");
            crx.installer =
                base::MakeRefCounted<ReadOnlyTestInstaller>(unpack_path);
            crx.crx_format_requirement = crx_file::VerifierFormat::CRX2_OR_CRX3;
            return std::vector<base::Optional<CrxComponent>>{crx};
          },
          unpack_path),
      false,
      base::BindOnce(
          [](base::OnceClosure quit_closure, Error error) {
            EXPECT_EQ(Error::NONE, error);
            std::move(quit_closure).Run();
          },
          quit_closure()));

  RunThreads();
}

#endif  // OS_WIN

}  // namespace update_client
