// Copyright 2014 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 "components/update_client/update_checker.h"

#include <map>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/json/json_reader.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/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/version.h"
#include "build/build_config.h"
#include "components/prefs/testing_pref_service.h"
#include "components/update_client/activity_data_service.h"
#include "components/update_client/component.h"
#if defined(STARBOARD)
#include "components/update_client/net/url_request_post_interceptor.h"
#else
#include "components/update_client/net/url_loader_post_interceptor.h"
#endif
#include "components/update_client/persisted_data.h"
#include "components/update_client/test_configurator.h"
#include "components/update_client/update_engine.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

using std::string;

namespace update_client {

namespace {

base::FilePath test_file(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);
}

const char kUpdateItemId[] = "jebgalgnebhfojomionfpkfelancnnkf";

class ActivityDataServiceTest final : public ActivityDataService {
 public:
  bool GetActiveBit(const std::string& id) const override;
  void ClearActiveBit(const std::string& id) override;
  int GetDaysSinceLastActive(const std::string& id) const override;
  int GetDaysSinceLastRollCall(const std::string& id) const override;

  void SetActiveBit(const std::string& id, bool value);
  void SetDaysSinceLastActive(const std::string& id, int daynum);
  void SetDaysSinceLastRollCall(const std::string& id, int daynum);

 private:
  std::map<std::string, bool> actives_;
  std::map<std::string, int> days_since_last_actives_;
  std::map<std::string, int> days_since_last_rollcalls_;
};

bool ActivityDataServiceTest::GetActiveBit(const std::string& id) const {
  const auto& it = actives_.find(id);
  return it != actives_.end() ? it->second : false;
}

void ActivityDataServiceTest::ClearActiveBit(const std::string& id) {
  SetActiveBit(id, false);
}

int ActivityDataServiceTest::GetDaysSinceLastActive(
    const std::string& id) const {
  const auto& it = days_since_last_actives_.find(id);
  return it != days_since_last_actives_.end() ? it->second : -2;
}

int ActivityDataServiceTest::GetDaysSinceLastRollCall(
    const std::string& id) const {
  const auto& it = days_since_last_rollcalls_.find(id);
  return it != days_since_last_rollcalls_.end() ? it->second : -2;
}

void ActivityDataServiceTest::SetActiveBit(const std::string& id, bool value) {
  actives_[id] = value;
}

void ActivityDataServiceTest::SetDaysSinceLastActive(const std::string& id,
                                                     int daynum) {
  days_since_last_actives_[id] = daynum;
}

void ActivityDataServiceTest::SetDaysSinceLastRollCall(const std::string& id,
                                                       int daynum) {
  days_since_last_rollcalls_[id] = daynum;
}

}  // namespace

class UpdateCheckerTest : public testing::TestWithParam<bool> {
 public:
  UpdateCheckerTest();
  ~UpdateCheckerTest() override;

  // Overrides from testing::Test.
  void SetUp() override;
  void TearDown() override;

  void UpdateCheckComplete(
      const base::Optional<ProtocolParser::Results>& results,
      ErrorCategory error_category,
      int error,
      int retry_after_sec);

 protected:
  void Quit();
  void RunThreads();

  std::unique_ptr<Component> MakeComponent() const;

  scoped_refptr<TestConfigurator> config_;
  std::unique_ptr<ActivityDataServiceTest> activity_data_service_;
  std::unique_ptr<TestingPrefServiceSimple> pref_;
  std::unique_ptr<PersistedData> metadata_;

  std::unique_ptr<UpdateChecker> update_checker_;

#if defined(STARBOARD)
  std::unique_ptr<InterceptorFactory> interceptor_factory_;
  scoped_refptr<URLRequestPostInterceptor> post_interceptor_;
#else
  std::unique_ptr<URLLoaderPostInterceptor> post_interceptor_;
#endif

  base::Optional<ProtocolParser::Results> results_;
  ErrorCategory error_category_ = ErrorCategory::kNone;
  int error_ = 0;
  int retry_after_sec_ = 0;

  scoped_refptr<UpdateContext> update_context_;

  bool is_foreground_ = false;

 private:
  scoped_refptr<UpdateContext> MakeMockUpdateContext() const;

  base::test::ScopedTaskEnvironment scoped_task_environment_;
  base::OnceClosure quit_closure_;

  DISALLOW_COPY_AND_ASSIGN(UpdateCheckerTest);
};

// This test is parameterized for |is_foreground|.
INSTANTIATE_TEST_SUITE_P(Parameterized, UpdateCheckerTest, testing::Bool());

UpdateCheckerTest::UpdateCheckerTest()
    : scoped_task_environment_(
          base::test::ScopedTaskEnvironment::MainThreadType::IO) {}

UpdateCheckerTest::~UpdateCheckerTest() {
}

void UpdateCheckerTest::SetUp() {
  is_foreground_ = GetParam();

  config_ = base::MakeRefCounted<TestConfigurator>();

  pref_ = std::make_unique<TestingPrefServiceSimple>();
  activity_data_service_ = std::make_unique<ActivityDataServiceTest>();
  PersistedData::RegisterPrefs(pref_->registry());
  metadata_ = std::make_unique<PersistedData>(pref_.get(),
                                              activity_data_service_.get());

#if defined(STARBOARD)
  interceptor_factory_ =
      std::make_unique<InterceptorFactory>(base::ThreadTaskRunnerHandle::Get());
  post_interceptor_ = interceptor_factory_->CreateInterceptor();
#else
  post_interceptor_ = std::make_unique<URLLoaderPostInterceptor>(
      config_->test_url_loader_factory());
#endif
  EXPECT_TRUE(post_interceptor_);

  update_checker_ = nullptr;

  error_ = 0;
  retry_after_sec_ = 0;
  update_context_ = MakeMockUpdateContext();
  update_context_->is_foreground = is_foreground_;
}

void UpdateCheckerTest::TearDown() {
  update_checker_ = nullptr;

#if defined(STARBOARD)
  post_interceptor_ = nullptr;
  interceptor_factory_ = nullptr;
#else
  post_interceptor_.reset();
#endif

  config_ = nullptr;

  // The PostInterceptor requires the message loop to run to destruct correctly.
  // TODO(sorin): This is fragile and should be fixed.
  scoped_task_environment_.RunUntilIdle();
}

void UpdateCheckerTest::RunThreads() {
  base::RunLoop runloop;
  quit_closure_ = runloop.QuitClosure();
  runloop.Run();
}

void UpdateCheckerTest::Quit() {
  if (!quit_closure_.is_null())
    std::move(quit_closure_).Run();
}

void UpdateCheckerTest::UpdateCheckComplete(
    const base::Optional<ProtocolParser::Results>& results,
    ErrorCategory error_category,
    int error,
    int retry_after_sec) {
  results_ = results;
  error_category_ = error_category;
  error_ = error;
  retry_after_sec_ = retry_after_sec;
  Quit();
}

scoped_refptr<UpdateContext> UpdateCheckerTest::MakeMockUpdateContext() const {
  return base::MakeRefCounted<UpdateContext>(
      config_, false, std::vector<std::string>(),
      UpdateClient::CrxDataCallback(), UpdateEngine::NotifyObserversCallback(),
      UpdateEngine::Callback(), nullptr);
}

std::unique_ptr<Component> UpdateCheckerTest::MakeComponent() const {
  CrxComponent crx_component;
  crx_component.name = "test_jebg";
  crx_component.pk_hash.assign(jebg_hash, jebg_hash + base::size(jebg_hash));
  crx_component.installer = nullptr;
  crx_component.version = base::Version("0.9");
  crx_component.fingerprint = "fp1";

  auto component = std::make_unique<Component>(*update_context_, kUpdateItemId);
  component->state_ = std::make_unique<Component::StateNew>(component.get());
  component->crx_component_ = crx_component;

  return component;
}

// This test is parameterized for |is_foreground|.
TEST_P(UpdateCheckerTest, UpdateCheckSuccess) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_1.json")));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  auto& component = components[kUpdateItemId];
  component->crx_component_->installer_attributes["ap"] = "some_ap";

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components,
      {{"extra", "params"}, {"testrequest", "1"}}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_EQ(1, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  ASSERT_EQ(1, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

  // Sanity check the request.
  const auto root =
      base::JSONReader::Read(post_interceptor_->GetRequestBody(0));
  ASSERT_TRUE(root);
  const auto* request = root->FindKey("request");
  ASSERT_TRUE(request);
  EXPECT_TRUE(request->FindKey("@os"));
  EXPECT_EQ("fake_prodid", request->FindKey("@updater")->GetString());
  EXPECT_EQ("crx2,crx3", request->FindKey("acceptformat")->GetString());
  EXPECT_TRUE(request->FindKey("arch"));
  EXPECT_EQ("cr", request->FindKey("dedup")->GetString());
  EXPECT_EQ("params", request->FindKey("extra")->GetString());
  EXPECT_LT(0, request->FindPath({"hw", "physmemory"})->GetInt());
  EXPECT_EQ("fake_lang", request->FindKey("lang")->GetString());
  EXPECT_TRUE(request->FindKey("nacl_arch"));
  EXPECT_EQ("fake_channel_string",
            request->FindKey("prodchannel")->GetString());
  EXPECT_EQ("30.0", request->FindKey("prodversion")->GetString());
  EXPECT_EQ("3.1", request->FindKey("protocol")->GetString());
  EXPECT_TRUE(request->FindKey("requestid"));
  EXPECT_TRUE(request->FindKey("sessionid"));
  EXPECT_EQ("1", request->FindKey("testrequest")->GetString());
  EXPECT_EQ("fake_channel_string",
            request->FindKey("updaterchannel")->GetString());
  EXPECT_EQ("30.0", request->FindKey("updaterversion")->GetString());

  // No "dlpref" is sent by default.
  EXPECT_FALSE(request->FindKey("dlpref"));

  EXPECT_TRUE(request->FindPath({"os", "arch"})->is_string());
  EXPECT_EQ("Fake Operating System",
            request->FindPath({"os", "platform"})->GetString());
  EXPECT_TRUE(request->FindPath({"os", "version"})->is_string());

  const auto& app = request->FindKey("app")->GetList()[0];
  EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
  EXPECT_EQ("0.9", app.FindKey("version")->GetString());
  EXPECT_EQ("TEST", app.FindKey("brand")->GetString());
  if (is_foreground_)
    EXPECT_EQ("ondemand", app.FindKey("installsource")->GetString());
  EXPECT_EQ("some_ap", app.FindKey("ap")->GetString());
  EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
  EXPECT_TRUE(app.FindKey("updatecheck"));
  EXPECT_TRUE(app.FindKey("ping"));
  EXPECT_EQ(-2, app.FindPath({"ping", "r"})->GetInt());
  EXPECT_EQ("fp1", app.FindPath({"packages", "package"})
                       ->GetList()[0]
                       .FindKey("fp")
                       ->GetString());

#if defined(OS_WIN)
  EXPECT_TRUE(request->FindKey("domainjoined"));
#if defined(GOOGLE_CHROME_BUILD)
  const auto* updater = request->FindKey("updater");
  EXPECT_TRUE(updater);
  EXPECT_EQ("Omaha", updater->FindKey("name")->GetString());
  EXPECT_TRUE(updater->FindKey("autoupdatecheckenabled")->is_bool());
  EXPECT_TRUE(updater->FindKey("ismachine")->is_bool());
  EXPECT_TRUE(updater->FindKey("updatepolicy")->is_int());
#endif  // GOOGLE_CHROME_BUILD
#endif  // OS_WIN

  // Sanity check the arguments of the callback after parsing.
  EXPECT_EQ(ErrorCategory::kNone, error_category_);
  EXPECT_EQ(0, error_);
  EXPECT_TRUE(results_);
  EXPECT_EQ(1u, results_->list.size());
  const auto& result = results_->list.front();
  EXPECT_STREQ("jebgalgnebhfojomionfpkfelancnnkf", result.extension_id.c_str());
  EXPECT_EQ("1.0", result.manifest.version);
  EXPECT_EQ("11.0.1.0", result.manifest.browser_min_version);
  EXPECT_EQ(1u, result.manifest.packages.size());
  EXPECT_STREQ("jebgalgnebhfojomionfpkfelancnnkf.crx",
               result.manifest.packages.front().name.c_str());
  EXPECT_EQ(1u, result.crx_urls.size());
  EXPECT_EQ(GURL("http://localhost/download/"), result.crx_urls.front());
  EXPECT_STREQ("this", result.action_run.c_str());

  // Check the DDOS protection header values.
#if defined(STARBOARD)
  const auto extra_request_headers = post_interceptor_->GetRequests()[0].second;
#else
  const auto extra_request_headers =
      std::get<1>(post_interceptor_->GetRequests()[0]);
#endif
  EXPECT_TRUE(extra_request_headers.HasHeader("X-Goog-Update-Interactivity"));
  std::string header;
  extra_request_headers.GetHeader("X-Goog-Update-Interactivity", &header);
  EXPECT_STREQ(is_foreground_ ? "fg" : "bg", header.c_str());
  extra_request_headers.GetHeader("X-Goog-Update-Updater", &header);
  EXPECT_STREQ("fake_prodid-30.0", header.c_str());
  extra_request_headers.GetHeader("X-Goog-Update-AppId", &header);
  EXPECT_STREQ("jebgalgnebhfojomionfpkfelancnnkf", header.c_str());
}

// Tests that an invalid "ap" is not serialized.
TEST_P(UpdateCheckerTest, UpdateCheckInvalidAp) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_1.json")));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  // Make "ap" too long.
  auto& component = components[kUpdateItemId];
  component->crx_component_->installer_attributes["ap"] = std::string(257, 'a');

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));

  RunThreads();

  const auto request = post_interceptor_->GetRequestBody(0);
    const auto root = base::JSONReader::Read(request);
    ASSERT_TRUE(root);
    const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
    EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
    EXPECT_EQ("0.9", app.FindKey("version")->GetString());
    EXPECT_EQ("TEST", app.FindKey("brand")->GetString());
    if (is_foreground_)
      EXPECT_EQ("ondemand", app.FindKey("installsource")->GetString());
    EXPECT_FALSE(app.FindKey("ap"));
    EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
    EXPECT_TRUE(app.FindKey("updatecheck"));
    EXPECT_TRUE(app.FindKey("ping"));
    EXPECT_EQ(-2, app.FindPath({"ping", "r"})->GetInt());
    EXPECT_EQ("fp1", app.FindPath({"packages", "package"})
                         ->GetList()[0]
                         .FindKey("fp")
                         ->GetString());
}

TEST_P(UpdateCheckerTest, UpdateCheckSuccessNoBrand) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_1.json")));

  config_->SetBrand("TOOLONG");   // Sets an invalid brand code.
  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));

  RunThreads();

  const auto request = post_interceptor_->GetRequestBody(0);

    const auto root = base::JSONReader::Read(request);
    ASSERT_TRUE(root);
    const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
    EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
    EXPECT_EQ("0.9", app.FindKey("version")->GetString());
    EXPECT_FALSE(app.FindKey("brand"));
    if (is_foreground_)
      EXPECT_EQ("ondemand", app.FindKey("installsource")->GetString());
    EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
    EXPECT_TRUE(app.FindKey("updatecheck"));
    EXPECT_TRUE(app.FindKey("ping"));
    EXPECT_EQ(-2, app.FindPath({"ping", "r"})->GetInt());
    EXPECT_EQ("fp1", app.FindPath({"packages", "package"})
                         ->GetList()[0]
                         .FindKey("fp")
                         ->GetString());
}

// Simulates a 403 server response error.
TEST_P(UpdateCheckerTest, UpdateCheckError) {
#if defined(STARBOARD)
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"), 403));
#else
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"), net::HTTP_FORBIDDEN));
#endif

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_EQ(1, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  EXPECT_EQ(1, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

  EXPECT_EQ(ErrorCategory::kUpdateCheck, error_category_);
  EXPECT_EQ(403, error_);
  EXPECT_FALSE(results_);
}

TEST_P(UpdateCheckerTest, UpdateCheckDownloadPreference) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_1.json")));

  config_->SetDownloadPreference(string("cacheable"));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components,
      {{"extra", "params"}}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  // The request must contain dlpref="cacheable".
  const auto request = post_interceptor_->GetRequestBody(0);
    const auto root = base::JSONReader().Read(request);
    ASSERT_TRUE(root);
    EXPECT_EQ("cacheable",
              root->FindKey("request")->FindKey("dlpref")->GetString());
}

// This test is checking that an update check signed with CUP fails, since there
// is currently no entity that can respond with a valid signed response.
// A proper CUP test requires network mocks, which are not available now.
TEST_P(UpdateCheckerTest, UpdateCheckCupError) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_1.json")));

  config_->SetEnabledCupSigning(true);
  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));

  RunThreads();

  EXPECT_EQ(1, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  ASSERT_EQ(1, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

  // Sanity check the request.
  const auto& request = post_interceptor_->GetRequestBody(0);
    const auto root = base::JSONReader::Read(request);
    ASSERT_TRUE(root);
    const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
    EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
    EXPECT_EQ("0.9", app.FindKey("version")->GetString());
    EXPECT_EQ("TEST", app.FindKey("brand")->GetString());
    if (is_foreground_)
      EXPECT_EQ("ondemand", app.FindKey("installsource")->GetString());
    EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
    EXPECT_TRUE(app.FindKey("updatecheck"));
    EXPECT_TRUE(app.FindKey("ping"));
    EXPECT_EQ(-2, app.FindPath({"ping", "r"})->GetInt());
    EXPECT_EQ("fp1", app.FindPath({"packages", "package"})
                         ->GetList()[0]
                         .FindKey("fp")
                         ->GetString());

  // Expect an error since the response is not trusted.
  EXPECT_EQ(ErrorCategory::kUpdateCheck, error_category_);
  EXPECT_EQ(-10000, error_);
  EXPECT_FALSE(results_);
}

// Tests that the UpdateCheckers will not make an update check for a
// component that requires encryption when the update check URL is unsecure.
TEST_P(UpdateCheckerTest, UpdateCheckRequiresEncryptionError) {
  config_->SetUpdateCheckUrl(GURL("http:\\foo\bar"));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  auto& component = components[kUpdateItemId];
  component->crx_component_->requires_network_encryption = true;

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_EQ(ErrorCategory::kUpdateCheck, error_category_);
  EXPECT_EQ(-10002, error_);
  EXPECT_FALSE(component->next_version_.IsValid());
}

// Tests that the PersistedData will get correctly update and reserialize
// the elapsed_days value.
TEST_P(UpdateCheckerTest, UpdateCheckLastRollCall) {
  const char* filename = "updatecheck_reply_4.json";
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"), test_file(filename)));
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"), test_file(filename)));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  // Do two update-checks.
  activity_data_service_->SetDaysSinceLastRollCall(kUpdateItemId, 5);
  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components,
      {{"extra", "params"}}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());
  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components,
      {{"extra", "params"}}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_EQ(2, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  ASSERT_EQ(2, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

    const auto root1 =
        base::JSONReader::Read(post_interceptor_->GetRequestBody(0));
    ASSERT_TRUE(root1);
    const auto& app1 = root1->FindKey("request")->FindKey("app")->GetList()[0];
    EXPECT_EQ(5, app1.FindPath({"ping", "r"})->GetInt());
    const auto root2 =
        base::JSONReader::Read(post_interceptor_->GetRequestBody(1));
    ASSERT_TRUE(root2);
    const auto& app2 = root2->FindKey("request")->FindKey("app")->GetList()[0];
    EXPECT_EQ(3383, app2.FindPath({"ping", "rd"})->GetInt());
    EXPECT_TRUE(app2.FindPath({"ping", "ping_freshness"})->is_string());
}

TEST_P(UpdateCheckerTest, UpdateCheckLastActive) {
  const char* filename = "updatecheck_reply_4.json";
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"), test_file(filename)));
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"), test_file(filename)));
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"), test_file(filename)));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  activity_data_service_->SetActiveBit(kUpdateItemId, true);
  activity_data_service_->SetDaysSinceLastActive(kUpdateItemId, 10);
  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components,
      {{"extra", "params"}}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  // The active bit should be reset.
  EXPECT_FALSE(metadata_->GetActiveBit(kUpdateItemId));

  activity_data_service_->SetActiveBit(kUpdateItemId, true);
  update_checker_ = UpdateChecker::Create(config_, metadata_.get());
  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components,
      {{"extra", "params"}}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  // The active bit should be reset.
  EXPECT_FALSE(metadata_->GetActiveBit(kUpdateItemId));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());
  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components,
      {{"extra", "params"}}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_FALSE(metadata_->GetActiveBit(kUpdateItemId));

  EXPECT_EQ(3, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  ASSERT_EQ(3, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

    {
      const auto root =
          base::JSONReader::Read(post_interceptor_->GetRequestBody(0));
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(10, app.FindPath({"ping", "a"})->GetInt());
      EXPECT_EQ(-2, app.FindPath({"ping", "r"})->GetInt());
    }
    {
      const auto root =
          base::JSONReader::Read(post_interceptor_->GetRequestBody(1));
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(3383, app.FindPath({"ping", "ad"})->GetInt());
      EXPECT_EQ(3383, app.FindPath({"ping", "rd"})->GetInt());
      EXPECT_TRUE(app.FindPath({"ping", "ping_freshness"})->is_string());
    }
    {
      const auto root =
          base::JSONReader::Read(post_interceptor_->GetRequestBody(2));
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(3383, app.FindPath({"ping", "rd"})->GetInt());
      EXPECT_TRUE(app.FindPath({"ping", "ping_freshness"})->is_string());
    }
}

TEST_P(UpdateCheckerTest, UpdateCheckInstallSource) {
  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  auto& component = components[kUpdateItemId];
  auto crx_component = component->crx_component();

  if (is_foreground_) {
    {
#if defined(STARBOARD)
      auto post_interceptor = post_interceptor_;
#else
      auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
          config_->test_url_loader_factory());
#endif
      EXPECT_TRUE(post_interceptor->ExpectRequest(
          std::make_unique<PartialMatch>("updatecheck"),
          test_file("updatecheck_reply_1.json")));
      update_checker_->CheckForUpdates(
          update_context_->session_id, {kUpdateItemId}, components, {}, false,
          base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                         base::Unretained(this)));
      RunThreads();
      const auto& request = post_interceptor->GetRequestBody(0);
        const auto root = base::JSONReader::Read(request);
        ASSERT_TRUE(root);
        const auto& app =
            root->FindKey("request")->FindKey("app")->GetList()[0];
        EXPECT_EQ("ondemand", app.FindKey("installsource")->GetString());
        EXPECT_FALSE(app.FindKey("installedby"));
    }
    {
#if defined(STARBOARD)
      auto post_interceptor = post_interceptor_;
#else
      auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
          config_->test_url_loader_factory());
#endif
      EXPECT_TRUE(post_interceptor->ExpectRequest(
          std::make_unique<PartialMatch>("updatecheck"),
          test_file("updatecheck_reply_1.json")));
      crx_component->install_source = "sideload";
      crx_component->install_location = "policy";
      component->set_crx_component(*crx_component);
      update_checker_->CheckForUpdates(
          update_context_->session_id, {kUpdateItemId}, components, {}, false,
          base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                         base::Unretained(this)));
      RunThreads();
      const auto& request = post_interceptor->GetRequestBody(0);
        const auto root = base::JSONReader::Read(request);
        ASSERT_TRUE(root);
        const auto& app =
            root->FindKey("request")->FindKey("app")->GetList()[0];
        EXPECT_EQ("sideload", app.FindKey("installsource")->GetString());
        EXPECT_EQ("policy", app.FindKey("installedby")->GetString());
    }
    return;
  }

  DCHECK(!is_foreground_);
  {
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_FALSE(app.FindKey("installsource"));
  }
  {
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    crx_component->install_source = "webstore";
    crx_component->install_location = "external";
    component->set_crx_component(*crx_component);
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ("webstore", app.FindKey("installsource")->GetString());
      EXPECT_EQ("external", app.FindKey("installedby")->GetString());
  }
}

TEST_P(UpdateCheckerTest, ComponentDisabled) {
  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  auto& component = components[kUpdateItemId];
  auto crx_component = component->crx_component();

  {
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
      EXPECT_FALSE(app.FindKey("disabled"));
  }

  {
    crx_component->disabled_reasons = {};
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
      EXPECT_FALSE(app.FindKey("disabled"));
  }

  {
    crx_component->disabled_reasons = {0};
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
      const auto& disabled = app.FindKey("disabled")->GetList();
      EXPECT_EQ(1u, disabled.size());
      EXPECT_EQ(0, disabled[0].FindKey("reason")->GetInt());
  }
  {
    crx_component->disabled_reasons = {1};
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
      const auto& disabled = app.FindKey("disabled")->GetList();
      EXPECT_EQ(1u, disabled.size());
      EXPECT_EQ(1, disabled[0].FindKey("reason")->GetInt());
  }

  {
    crx_component->disabled_reasons = {4, 8, 16};
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
      const auto& disabled = app.FindKey("disabled")->GetList();
      EXPECT_EQ(3u, disabled.size());
      EXPECT_EQ(4, disabled[0].FindKey("reason")->GetInt());
      EXPECT_EQ(8, disabled[1].FindKey("reason")->GetInt());
      EXPECT_EQ(16, disabled[2].FindKey("reason")->GetInt());
  }

  {
    crx_component->disabled_reasons = {0, 4, 8, 16};
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(false, app.FindKey("enabled")->GetBool());
      const auto& disabled = app.FindKey("disabled")->GetList();
      EXPECT_EQ(4u, disabled.size());
      EXPECT_EQ(0, disabled[0].FindKey("reason")->GetInt());
      EXPECT_EQ(4, disabled[1].FindKey("reason")->GetInt());
      EXPECT_EQ(8, disabled[2].FindKey("reason")->GetInt());
      EXPECT_EQ(16, disabled[3].FindKey("reason")->GetInt());
  }
}

TEST_P(UpdateCheckerTest, UpdateCheckUpdateDisabled) {
  config_->SetBrand("");
  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  auto& component = components[kUpdateItemId];
  auto crx_component = component->crx_component();

  // Ignore this test parameter to keep the test simple.
  update_context_->is_foreground = false;
  {
    // Tests the scenario where:
    //  * the component does not support group policies.
    //  * the component updates are disabled.
    // Expects the group policy to be ignored and the update check to not
    // include the "updatedisabled" attribute.
    EXPECT_FALSE(crx_component->supports_group_policy_enable_component_updates);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
      EXPECT_EQ("0.9", app.FindKey("version")->GetString());
      EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
      EXPECT_TRUE(app.FindKey("updatecheck")->DictEmpty());
  }
  {
    // Tests the scenario where:
    //  * the component supports group policies.
    //  * the component updates are disabled.
    // Expects the update check to include the "updatedisabled" attribute.
    crx_component->supports_group_policy_enable_component_updates = true;
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, false,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
      EXPECT_EQ("0.9", app.FindKey("version")->GetString());
      EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
      EXPECT_TRUE(app.FindPath({"updatecheck", "updatedisabled"})->GetBool());
  }
  {
    // Tests the scenario where:
    //  * the component does not support group policies.
    //  * the component updates are enabled.
    // Expects the update check to not include the "updatedisabled" attribute.
    crx_component->supports_group_policy_enable_component_updates = false;
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, true,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
      EXPECT_EQ("0.9", app.FindKey("version")->GetString());
      EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
      EXPECT_TRUE(app.FindKey("updatecheck")->DictEmpty());
  }
  {
    // Tests the scenario where:
    //  * the component supports group policies.
    //  * the component updates are enabled.
    // Expects the update check to not include the "updatedisabled" attribute.
    crx_component->supports_group_policy_enable_component_updates = true;
    component->set_crx_component(*crx_component);
#if defined(STARBOARD)
    auto post_interceptor = post_interceptor_;
#else
    auto post_interceptor = std::make_unique<URLLoaderPostInterceptor>(
        config_->test_url_loader_factory());
#endif
    EXPECT_TRUE(post_interceptor->ExpectRequest(
        std::make_unique<PartialMatch>("updatecheck"),
        test_file("updatecheck_reply_1.json")));
    update_checker_->CheckForUpdates(
        update_context_->session_id, {kUpdateItemId}, components, {}, true,
        base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                       base::Unretained(this)));
    RunThreads();
    const auto& request = post_interceptor->GetRequestBody(0);
      const auto root = base::JSONReader::Read(request);
      ASSERT_TRUE(root);
      const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
      EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
      EXPECT_EQ("0.9", app.FindKey("version")->GetString());
      EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
      EXPECT_TRUE(app.FindKey("updatecheck")->DictEmpty());
  }
}

TEST_P(UpdateCheckerTest, NoUpdateActionRun) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_noupdate.json")));
  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_EQ(1, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  ASSERT_EQ(1, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

  // Sanity check the arguments of the callback after parsing.
  EXPECT_EQ(ErrorCategory::kNone, error_category_);
  EXPECT_EQ(0, error_);
  EXPECT_TRUE(results_);
  EXPECT_EQ(1u, results_->list.size());
  const auto& result = results_->list.front();
  EXPECT_STREQ("jebgalgnebhfojomionfpkfelancnnkf", result.extension_id.c_str());
  EXPECT_STREQ("noupdate", result.status.c_str());
  EXPECT_STREQ("this", result.action_run.c_str());
}

TEST_P(UpdateCheckerTest, UpdatePauseResume) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_noupdate.json")));
#if defined(STARBOARD)
  post_interceptor_->url_job_request_ready_callback(base::BindOnce(
      [](scoped_refptr<URLRequestPostInterceptor> post_interceptor) {
        post_interceptor->Resume();
      },
      post_interceptor_));
#else
  post_interceptor_->url_job_request_ready_callback(base::BindOnce(
      [](URLLoaderPostInterceptor* post_interceptor) {
        post_interceptor->Resume();
      },
      post_interceptor_.get()));
#endif
  post_interceptor_->Pause();

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  // Ignore this test parameter to keep the test simple.
  update_context_->is_foreground = false;

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  const auto& request = post_interceptor_->GetRequestBody(0);
    const auto root = base::JSONReader::Read(request);
    ASSERT_TRUE(root);
    const auto& app = root->FindKey("request")->FindKey("app")->GetList()[0];
    EXPECT_EQ(kUpdateItemId, app.FindKey("appid")->GetString());
    EXPECT_EQ("0.9", app.FindKey("version")->GetString());
    EXPECT_EQ("TEST", app.FindKey("brand")->GetString());
    EXPECT_EQ(true, app.FindKey("enabled")->GetBool());
    EXPECT_TRUE(app.FindKey("updatecheck")->DictEmpty());
    EXPECT_EQ(-2, app.FindPath({"ping", "r"})->GetInt());
    EXPECT_EQ("fp1", app.FindKey("packages")
                         ->FindKey("package")
                         ->GetList()[0]
                         .FindKey("fp")
                         ->GetString());
}

// Tests that an update checker object and its underlying SimpleURLLoader can
// be safely destroyed while it is paused.
TEST_P(UpdateCheckerTest, UpdateResetUpdateChecker) {
  base::RunLoop runloop;
  auto quit_closure = runloop.QuitClosure();

  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_1.json")));
  post_interceptor_->url_job_request_ready_callback(base::BindOnce(
      [](base::OnceClosure quit_closure) { std::move(quit_closure).Run(); },
      std::move(quit_closure)));
  post_interceptor_->Pause();

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());
  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  runloop.Run();
}

// The update response contains a protocol version which does not match the
// expected protocol version.
TEST_P(UpdateCheckerTest, ParseErrorProtocolVersionMismatch) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_parse_error.json")));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_EQ(1, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  ASSERT_EQ(1, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

  EXPECT_EQ(ErrorCategory::kUpdateCheck, error_category_);
  EXPECT_EQ(-10003, error_);
  EXPECT_FALSE(results_);
}

// The update response contains a status |error-unknownApplication| for the
// app. The response is succesfully parsed and a result is extracted to
// indicate this status.
TEST_P(UpdateCheckerTest, ParseErrorAppStatusErrorUnknownApplication) {
  EXPECT_TRUE(post_interceptor_->ExpectRequest(
      std::make_unique<PartialMatch>("updatecheck"),
      test_file("updatecheck_reply_unknownapp.json")));

  update_checker_ = UpdateChecker::Create(config_, metadata_.get());

  IdToComponentPtrMap components;
  components[kUpdateItemId] = MakeComponent();

  update_checker_->CheckForUpdates(
      update_context_->session_id, {kUpdateItemId}, components, {}, true,
      base::BindOnce(&UpdateCheckerTest::UpdateCheckComplete,
                     base::Unretained(this)));
  RunThreads();

  EXPECT_EQ(1, post_interceptor_->GetHitCount())
      << post_interceptor_->GetRequestsAsString();
  ASSERT_EQ(1, post_interceptor_->GetCount())
      << post_interceptor_->GetRequestsAsString();

  EXPECT_EQ(ErrorCategory::kNone, error_category_);
  EXPECT_EQ(0, error_);
  EXPECT_TRUE(results_);
  EXPECT_EQ(1u, results_->list.size());
  const auto& result = results_->list.front();
  EXPECT_STREQ("error-unknownApplication", result.status.c_str());
}

}  // namespace update_client
