// Copyright 2017 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/previews/content/previews_optimization_guide.h"

#include <memory>

#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "components/optimization_guide/hints_component_info.h"
#include "components/optimization_guide/optimization_guide_service.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/previews/content/hints_fetcher.h"
#include "components/previews/content/previews_hints.h"
#include "components/previews/content/previews_top_host_provider.h"
#include "components/previews/content/previews_user_data.h"
#include "components/previews/core/bloom_filter.h"
#include "components/previews/core/previews_experiments.h"
#include "components/previews/core/previews_features.h"
#include "components/previews/core/previews_switches.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace previews {

namespace {
// A fake default page_id for testing.
const uint64_t kDefaultPageId = 123456;

enum class HintsFetcherEndState {
  kFetchFailed = 0,
  kFetchSuccessWithHints = 1,
  kFetchSuccessWithNoHints = 2,
};

// Retry delay is 16 minutes to allow for kFetchRetryDelaySecs +
// kFetchRandomMaxDelaySecs to pass.
constexpr int kTestFetchRetryDelaySecs = 60 * 16;

constexpr int kUpdateFetchHintsTimeSecs = 24 * 60 * 60;  // 24 hours.

}  // namespace

class TestOptimizationGuideService
    : public optimization_guide::OptimizationGuideService {
 public:
  explicit TestOptimizationGuideService(
      const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner)
      : OptimizationGuideService(ui_task_runner),
        add_observer_called_(false),
        remove_observer_called_(false) {}

  void AddObserver(
      optimization_guide::OptimizationGuideServiceObserver* observer) override {
    add_observer_called_ = true;
  }

  void RemoveObserver(
      optimization_guide::OptimizationGuideServiceObserver* observer) override {
    remove_observer_called_ = true;
  }

  bool AddObserverCalled() { return add_observer_called_; }
  bool RemoveObserverCalled() { return remove_observer_called_; }

 private:
  bool add_observer_called_;
  bool remove_observer_called_;
};

// A mock class implementation for unittesting previews_optimization_guide.
class MockPreviewsTopHostProvider : public PreviewsTopHostProvider {
 public:
  MOCK_CONST_METHOD1(GetTopHosts, std::vector<std::string>(size_t max_sites));
};

std::unique_ptr<optimization_guide::proto::GetHintsResponse> BuildHintsResponse(
    std::vector<std::string> hosts) {
  std::unique_ptr<optimization_guide::proto::GetHintsResponse>
      get_hints_response =
          std::make_unique<optimization_guide::proto::GetHintsResponse>();

  for (const auto& host : hosts) {
    optimization_guide::proto::Hint* hint = get_hints_response->add_hints();
    hint->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
    hint->set_key(host);
    optimization_guide::proto::PageHint* page_hint = hint->add_page_hints();
    page_hint->set_page_pattern("page pattern");
  }
  return get_hints_response;
}

// A mock class implementation of HintsFetcher for unittesting
// previews_optimization_guide.
class TestHintsFetcher : public HintsFetcher {
  using HintsFetchedCallback = base::OnceCallback<void(
      base::Optional<
          std::unique_ptr<optimization_guide::proto::GetHintsResponse>>)>;
  using HintsFetcher::FetchOptimizationGuideServiceHints;

 public:
  TestHintsFetcher(
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      GURL optimization_guide_service_url,
      HintsFetcherEndState fetch_state)
      : HintsFetcher(url_loader_factory, optimization_guide_service_url),
        fetch_state_(fetch_state) {}

  bool FetchOptimizationGuideServiceHints(
      const std::vector<std::string>& hosts,
      HintsFetchedCallback hints_fetched_callback) override {
    switch (fetch_state_) {
      case HintsFetcherEndState::kFetchFailed:
        std::move(hints_fetched_callback).Run(base::nullopt);
        return false;
      case HintsFetcherEndState::kFetchSuccessWithHints:
        hints_fetched_ = true;
        std::move(hints_fetched_callback).Run(BuildHintsResponse({"host.com"}));
        return true;
      case HintsFetcherEndState::kFetchSuccessWithNoHints:
        hints_fetched_ = true;
        std::move(hints_fetched_callback).Run(BuildHintsResponse({}));
        return true;
    }
    return true;
  }

  bool hints_fetched() { return hints_fetched_; }

 private:
  bool hints_fetched_ = false;
  HintsFetcherEndState fetch_state_;
};

// A Test PreviewsOptimizationGuide to observe and record when callbacks
// from hints fetching and storing occur.
class TestPreviewsOptimizationGuide : public PreviewsOptimizationGuide {
 public:
  TestPreviewsOptimizationGuide(
      optimization_guide::OptimizationGuideService* optimization_guide_service,
      const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
      const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
      const base::FilePath& profile_path,
      PreviewsTopHostProvider* previews_top_host_provider,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory)
      : PreviewsOptimizationGuide(optimization_guide_service,
                                  ui_task_runner,
                                  background_task_runner,
                                  profile_path,
                                  previews_top_host_provider,
                                  url_loader_factory) {}

  bool fetched_hints_stored() { return fetched_hints_stored_; }

 private:
  void OnHintsFetched(
      base::Optional<
          std::unique_ptr<optimization_guide::proto::GetHintsResponse>>
          get_hints_response) override {
    fetched_hints_stored_ = false;
    PreviewsOptimizationGuide::OnHintsFetched(std::move(get_hints_response));
  }

  void OnFetchedHintsStored() override {
    fetched_hints_stored_ = true;
    PreviewsOptimizationGuide::OnFetchedHintsStored();
  }

  bool fetched_hints_stored_ = false;
};

class PreviewsOptimizationGuideTest : public testing::Test {
 public:
  PreviewsOptimizationGuideTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::UI_MOCK_TIME) {}

  ~PreviewsOptimizationGuideTest() override {}

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    CreateServiceAndGuide();
  }

  // Delete |guide_| if it hasn't been deleted.
  void TearDown() override { ResetGuide(); }

  PreviewsOptimizationGuide* guide() { return guide_.get(); }

  MockPreviewsTopHostProvider* top_host_provider() {
    return previews_top_host_provider_.get();
  }

  TestOptimizationGuideService* optimization_guide_service() {
    return optimization_guide_service_.get();
  }

  network::SharedURLLoaderFactory* url_loader_factory() {
    return url_loader_factory_.get();
  }

  TestHintsFetcher* hints_fetcher() {
    return static_cast<TestHintsFetcher*>(guide_->GetHintsFetcherForTesting());
  }

  void ProcessHints(const optimization_guide::proto::Configuration& config,
                    const std::string& version) {
    optimization_guide::HintsComponentInfo info(
        base::Version(version),
        temp_dir().Append(FILE_PATH_LITERAL("somefile.pb")));
    ASSERT_NO_FATAL_FAILURE(WriteConfigToFile(config, info.path));
    guide_->OnHintsComponentAvailable(info);
    RunUntilIdle();
  }

  void CreateServiceAndGuide() {
    if (guide_) {
      ResetGuide();
    }
    url_loader_factory_ =
        base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
            &test_url_loader_factory_);
    if (!previews_top_host_provider_) {
      previews_top_host_provider_ =
          std::make_unique<MockPreviewsTopHostProvider>();
    }
    optimization_guide_service_ =
        std::make_unique<TestOptimizationGuideService>(
            scoped_task_environment_.GetMainThreadTaskRunner());
    guide_ = std::make_unique<TestPreviewsOptimizationGuide>(
        optimization_guide_service_.get(),
        scoped_task_environment_.GetMainThreadTaskRunner(),
        scoped_task_environment_.GetMainThreadTaskRunner(), temp_dir(),
        previews_top_host_provider_.get(), url_loader_factory_);

    guide_->SetTimeClockForTesting(scoped_task_environment_.GetMockClock());

    base::test::ScopedFeatureList scoped_list;
    scoped_list.InitAndEnableFeature(features::kOptimizationHintsFetching);

    // Add observer is called after the HintCache is fully initialized,
    // indicating that the PreviewsOptimizationGuide is ready to process hints.
    while (!optimization_guide_service_->AddObserverCalled()) {
      RunUntilIdle();
    }
  }

  void ResetGuide() {
    guide_.reset();
    RunUntilIdle();
  }

  std::unique_ptr<TestHintsFetcher> BuildTestHintsFetcher(
      HintsFetcherEndState end_state) {
    std::unique_ptr<TestHintsFetcher> hints_fetcher =
        std::make_unique<TestHintsFetcher>(
            url_loader_factory_, GURL("https://hintsserver.com"), end_state);
    return hints_fetcher;
  }

  base::FilePath temp_dir() const { return temp_dir_.GetPath(); }

 protected:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

  void MoveClockForwardBy(base::TimeDelta time_delta) {
    scoped_task_environment_.FastForwardBy(time_delta);
    base::RunLoop().RunUntilIdle();
  }

  void RunUntilIdle() {
    scoped_task_environment_.RunUntilIdle();
    base::RunLoop().RunUntilIdle();
  }

  void DoExperimentFlagTest(base::Optional<std::string> experiment_name,
                            bool expect_enabled);

  // This is a helper function for initializing fixed number of ResourceLoading
  // hints.
  void InitializeFixedCountResourceLoadingHints();

  // This is a helper function for initializing fixed number of ResourceLoading
  // hints that contain an experiment
  void InitializeFixedCountResourceLoadingHintsWithTwoExperiments();

  // This is a helper function for initializing multiple ResourceLoading hints.
  // The generated hint proto contains hints for |key_count| keys.
  // |page_patterns_per_key| page patterns are specified per key.
  // For each page pattern, 2 resource loading hints are specified in the proto.
  void InitializeMultipleResourceLoadingHints(size_t key_count,
                                              size_t page_patterns_per_key);

  // This is a helper function for initializing with a LITE_PAGE_REDIRECT
  // server blacklist.
  void InitializeWithLitePageRedirectBlacklist();

  // This function guarantees that all of the asynchronous processing required
  // to load the specified hint has occurred prior to calling IsWhitelisted.
  // It accomplishes this by calling MaybeLoadOptimizationHints() and waiting
  // until OnLoadOptimizationHints runs before calling IsWhitelisted().
  bool MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      PreviewsUserData* previews_data,
      const GURL& url,
      PreviewsType type,
      net::EffectiveConnectionType* out_ect_threshold);

  void RunUntilFetchedHintsStored() {
    while (!guide_->fetched_hints_stored()) {
    }
  }

 private:
  void WriteConfigToFile(const optimization_guide::proto::Configuration& config,
                         const base::FilePath& filePath) {
    std::string serialized_config;
    ASSERT_TRUE(config.SerializeToString(&serialized_config));
    ASSERT_EQ(static_cast<int32_t>(serialized_config.length()),
              base::WriteFile(filePath, serialized_config.data(),
                              serialized_config.length()));
  }

  void TestOnHintsFetched(
      std::unique_ptr<optimization_guide::proto::GetHintsResponse>
          get_hints_response) {}

  std::unique_ptr<TestHintsFetcher> test_fetcher_;
  // Callback used to indicate that the asynchronous call to
  // MaybeLoadOptimizationHints() has completed its processing.
  void OnLoadOptimizationHints();

  base::ScopedTempDir temp_dir_;

  // std::unique_ptr<PreviewsOptimizationGuide> guide_;
  std::unique_ptr<TestPreviewsOptimizationGuide> guide_;
  std::unique_ptr<TestOptimizationGuideService> optimization_guide_service_;
  std::unique_ptr<MockPreviewsTopHostProvider> previews_top_host_provider_;

  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
  network::TestURLLoaderFactory test_url_loader_factory_;

  // Flag set when the OnLoadOptimizationHints callback runs. This indicates
  // that MaybeLoadOptimizationHints() has completed its processing.
  bool requested_hints_loaded_;

  GURL loaded_hints_document_gurl_;
  std::vector<std::string> loaded_hints_resource_patterns_;
  // const base::SimpleTestClock* test_clock_;

  DISALLOW_COPY_AND_ASSIGN(PreviewsOptimizationGuideTest);
};

void PreviewsOptimizationGuideTest::InitializeFixedCountResourceLoadingHints() {
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("somedomain.org");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);

  // Page hint for "/news/"
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("/news/");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_loading_hint1 =
      optimization1->add_resource_loading_hints();
  resource_loading_hint1->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_loading_hint1->set_resource_pattern("news_cruft.js");

  // Page hint for "football"
  optimization_guide::proto::PageHint* page_hint2 = hint1->add_page_hints();
  page_hint2->set_page_pattern("football");
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_loading_hint2 =
      optimization2->add_resource_loading_hints();
  resource_loading_hint2->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_loading_hint2->set_resource_pattern("football_cruft.js");

  optimization_guide::proto::ResourceLoadingHint* resource_loading_hint3 =
      optimization2->add_resource_loading_hints();
  resource_loading_hint3->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_loading_hint3->set_resource_pattern("barball_cruft.js");

  ProcessHints(config, "2.0.0");
}

void PreviewsOptimizationGuideTest::
    InitializeFixedCountResourceLoadingHintsWithTwoExperiments() {
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("somedomain.org");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);

  // Page hint for "/news/"
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("/news/");

  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_experiment_name("experiment_1");
  optimization1->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_loading_hint1 =
      optimization1->add_resource_loading_hints();
  resource_loading_hint1->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_loading_hint1->set_resource_pattern("news_cruft.js");

  optimization_guide::proto::Optimization* optimization2 =
      page_hint1->add_whitelisted_optimizations();
  optimization2->set_experiment_name("experiment_2");
  optimization2->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_loading_hint2 =
      optimization2->add_resource_loading_hints();
  resource_loading_hint2->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_loading_hint2->set_resource_pattern("football_cruft.js");

  ProcessHints(config, "2.0.0");
}

void PreviewsOptimizationGuideTest::InitializeMultipleResourceLoadingHints(
    size_t key_count,
    size_t page_patterns_per_key) {
  optimization_guide::proto::Configuration config;

  for (size_t key_index = 0; key_index < key_count; ++key_index) {
    optimization_guide::proto::Hint* hint = config.add_hints();
    hint->set_key("somedomain" + base::NumberToString(key_index) + ".org");
    hint->set_key_representation(optimization_guide::proto::HOST_SUFFIX);

    for (size_t page_pattern_index = 0;
         page_pattern_index < page_patterns_per_key; ++page_pattern_index) {
      // Page hint for "/news/"
      optimization_guide::proto::PageHint* page_hint = hint->add_page_hints();
      page_hint->set_page_pattern(
          "/news" + base::NumberToString(page_pattern_index) + "/");
      optimization_guide::proto::Optimization* optimization1 =
          page_hint->add_whitelisted_optimizations();
      optimization1->set_optimization_type(
          optimization_guide::proto::RESOURCE_LOADING);

      optimization_guide::proto::ResourceLoadingHint* resource_loading_hint_1 =
          optimization1->add_resource_loading_hints();
      resource_loading_hint_1->set_loading_optimization_type(
          optimization_guide::proto::LOADING_BLOCK_RESOURCE);
      resource_loading_hint_1->set_resource_pattern("news_cruft_1.js");

      optimization_guide::proto::ResourceLoadingHint* resource_loading_hint_2 =
          optimization1->add_resource_loading_hints();
      resource_loading_hint_2->set_loading_optimization_type(
          optimization_guide::proto::LOADING_BLOCK_RESOURCE);
      resource_loading_hint_2->set_resource_pattern("news_cruft_2.js");
    }
  }

  ProcessHints(config, "2.0.0");
}

void PreviewsOptimizationGuideTest::InitializeWithLitePageRedirectBlacklist() {
  previews::BloomFilter blacklist_bloom_filter(7, 511);
  blacklist_bloom_filter.Add("blacklisteddomain.com");
  blacklist_bloom_filter.Add("blacklistedsubdomain.maindomain.co.in");
  std::string blacklist_data((char*)&blacklist_bloom_filter.bytes()[0],
                             blacklist_bloom_filter.bytes().size());
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::OptimizationFilter* blacklist_proto =
      config.add_optimization_blacklists();
  blacklist_proto->set_optimization_type(
      optimization_guide::proto::LITE_PAGE_REDIRECT);
  std::unique_ptr<optimization_guide::proto::BloomFilter> bloom_filter_proto =
      std::make_unique<optimization_guide::proto::BloomFilter>();
  bloom_filter_proto->set_num_hash_functions(7);
  bloom_filter_proto->set_num_bits(511);
  bloom_filter_proto->set_data(blacklist_data);
  blacklist_proto->set_allocated_bloom_filter(bloom_filter_proto.release());
  ProcessHints(config, "2.0.0");
}

bool PreviewsOptimizationGuideTest::
    MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
        PreviewsUserData* previews_data,
        const GURL& url,
        PreviewsType type,
        net::EffectiveConnectionType* out_ect_threshold) {
  // Ensure that all asynchronous MaybeLoadOptimizationHints processing
  // finishes prior to calling IsWhitelisted. This is accomplished by waiting
  // for the OnLoadOptimizationHints callback to set |requested_hints_loaded_|
  // to true.
  requested_hints_loaded_ = false;
  if (guide()->MaybeLoadOptimizationHints(
          url, base::BindOnce(
                   &PreviewsOptimizationGuideTest::OnLoadOptimizationHints,
                   base::Unretained(this)))) {
    while (!requested_hints_loaded_) {
      RunUntilIdle();
    }
  }

  return guide()->IsWhitelisted(previews_data, url, type, out_ect_threshold);
}

void PreviewsOptimizationGuideTest::OnLoadOptimizationHints() {
  requested_hints_loaded_ = true;
}

TEST_F(PreviewsOptimizationGuideTest, IsWhitelistedWithoutHints) {
  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsForNoScriptPageHintsPopulatedCorrectly) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});

  // Configure somedomain.org with 2 page patterns, different ECT thresholds.
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("somedomain.org");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("noscript_default_2g");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);
  optimization_guide::proto::PageHint* page_hint2 = hint1->add_page_hints();
  page_hint2->set_page_pattern("noscript_3g");
  page_hint2->set_max_ect_trigger(
      optimization_guide::proto::EffectiveConnectionType::
          EFFECTIVE_CONNECTION_TYPE_3G);
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  // Configure anypage.com with * page pattern.
  optimization_guide::proto::Hint* hint2 = config.add_hints();
  hint2->set_key("anypage.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint3 = hint2->add_page_hints();
  page_hint3->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization3 =
      page_hint3->add_whitelisted_optimizations();
  optimization3->set_optimization_type(optimization_guide::proto::NOSCRIPT);
  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;

  // Verify page matches and ECT thresholds.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://somedomain.org/noscript_default_2g"),
      PreviewsType::NOSCRIPT, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://somedomain.org/noscript_3g"),
      PreviewsType::NOSCRIPT, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G, ect_threshold);
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://somedomain.org/no_pattern_match"),
      PreviewsType::NOSCRIPT, &ect_threshold));

  // Verify * matches any page.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://anypage.com/noscript_for_all"),
      PreviewsType::NOSCRIPT, &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://anypage.com/"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://anypage.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsWithValidCommandLineOverride) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});

  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint = config.add_hints();
  hint->set_key("somedomain.org");
  hint->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint = hint->add_page_hints();
  page_hint->set_page_pattern("noscript_default_2g");
  optimization_guide::proto::Optimization* optimization =
      page_hint->add_whitelisted_optimizations();
  optimization->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  std::string encoded_config;
  config.SerializeToString(&encoded_config);
  base::Base64Encode(encoded_config, &encoded_config);

  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kHintsProtoOverride, encoded_config);
  CreateServiceAndGuide();

  // Verify page matches and ECT thresholds.
  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;

  EXPECT_TRUE(guide()->GetHintsForTesting());
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://somedomain.org/noscript_default_2g"),
      PreviewsType::NOSCRIPT, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsWithValidCommandLineOverrideAndPreexistingData) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});

  InitializeFixedCountResourceLoadingHints();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));

  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint = config.add_hints();
  hint->set_key("otherdomain.org");
  hint->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint = hint->add_page_hints();
  page_hint->set_page_pattern("noscript_default_2g");
  optimization_guide::proto::Optimization* optimization =
      page_hint->add_whitelisted_optimizations();
  optimization->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  std::string encoded_config;
  config.SerializeToString(&encoded_config);
  base::Base64Encode(encoded_config, &encoded_config);

  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kHintsProtoOverride, encoded_config);
  CreateServiceAndGuide();

  // Verify page matches and ECT thresholds.
  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;

  EXPECT_TRUE(guide()->GetHintsForTesting());
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://otherdomain.org/noscript_default_2g"),
      PreviewsType::NOSCRIPT, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);

  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsWithInvalidCommandLineOverride) {
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      switches::kHintsProtoOverride, "this-is-not-a-proto");
  CreateServiceAndGuide();

  EXPECT_FALSE(guide()->GetHintsForTesting());
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsWithPurgeHintCacheStoreCommandLineAndNoPreexistingData) {
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kPurgeHintCacheStore);
  CreateServiceAndGuide();

  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));

  InitializeFixedCountResourceLoadingHints();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsWithPurgeHintCacheStoreCommandLineAndPreexistingData) {
  InitializeFixedCountResourceLoadingHints();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));

  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kPurgeHintCacheStore);
  CreateServiceAndGuide();

  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));

  InitializeFixedCountResourceLoadingHints();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
}

// Test when resource loading hints are enabled.
TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsForResourceLoadingHintsPopulatedCorrectly) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  // Add first hint.
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_hint1 =
      optimization1->add_resource_loading_hints();
  resource_hint1->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_hint1->set_resource_pattern("resource.js");

  // Add an additional optimization to first hint to verify that the applicable
  // optimizations are still whitelisted.
  optimization_guide::proto::PageHint* page_hint2 = hint1->add_page_hints();
  page_hint2->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  // Add second hint.
  optimization_guide::proto::Hint* hint2 = config.add_hints();
  hint2->set_key("twitter.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint3 = hint2->add_page_hints();
  page_hint3->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization3 =
      page_hint3->add_whitelisted_optimizations();
  optimization3->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_hint2 =
      optimization3->add_resource_loading_hints();
  resource_hint2->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_hint2->set_resource_pattern("resource.js");

  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Twitter and Facebook should be whitelisted but not Google.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.twitter.com/example"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://google.com"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

// Test when both NoScript and resource loading hints are enabled.
TEST_F(
    PreviewsOptimizationGuideTest,
    ProcessHintsWhitelistForNoScriptAndResourceLoadingHintsPopulatedCorrectly) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});

  // Add first hint.
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  // Add additional optimization to second hint to verify that the applicable
  // optimizations are still whitelisted.
  optimization_guide::proto::Optimization* optimization2 =
      page_hint1->add_whitelisted_optimizations();
  optimization2->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_hint1 =
      optimization2->add_resource_loading_hints();
  resource_hint1->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_hint1->set_resource_pattern("resource.js");

  // Add second hint.
  optimization_guide::proto::Hint* hint2 = config.add_hints();
  hint2->set_key("twitter.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint2 = hint2->add_page_hints();
  page_hint2->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization3 =
      page_hint2->add_whitelisted_optimizations();
  optimization3->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_hint2 =
      optimization3->add_resource_loading_hints();
  resource_hint2->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_hint2->set_resource_pattern("resource.js");

  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Twitter and Facebook should be whitelisted but not Google.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com/example.html"),
      PreviewsType::NOSCRIPT, &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.twitter.com/example"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://google.com"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsForResourceLoadingHintsWithSlowPageTriggering) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  // Hint with 3G threshold.
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("3g.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  page_hint1->set_max_ect_trigger(
      optimization_guide::proto::EffectiveConnectionType::
          EFFECTIVE_CONNECTION_TYPE_3G);
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);

  // Hint with 4G threshold.
  optimization_guide::proto::Hint* hint2 = config.add_hints();
  hint2->set_key("4g.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint2 = hint2->add_page_hints();
  page_hint2->set_page_pattern("*");
  page_hint2->set_max_ect_trigger(
      optimization_guide::proto::EffectiveConnectionType::
          EFFECTIVE_CONNECTION_TYPE_4G);
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);

  // Hint with no threshold (default case).
  optimization_guide::proto::Hint* hint3 = config.add_hints();
  hint3->set_key("default2g.com");
  hint3->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint3 = hint3->add_page_hints();
  page_hint3->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization3 =
      page_hint3->add_whitelisted_optimizations();
  optimization3->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);

  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://3g.com"), PreviewsType::RESOURCE_LOADING_HINTS,
      &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_3G, ect_threshold);
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://4g.com/example"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_4G, ect_threshold);
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://default2g.com"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
}

// This is a helper function for testing the experiment flags on the config for
// the optimization guide. It creates a test config with a hint containing
// multiple optimizations. The optimization under test will be marked with an
// experiment name if one is provided in |experiment_name|. It will then be
// tested to see if it's enabled, the expectation found in |expect_enabled|.
void PreviewsOptimizationGuideTest::DoExperimentFlagTest(
    base::Optional<std::string> experiment_name,
    bool expect_enabled) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});

  // Create a hint with two optimizations. One may be marked experimental
  // depending on test configuration. The other is never marked experimental.
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  // NOSCRIPT is the optimization under test and may be marked experimental.
  if (experiment_name.has_value()) {
    optimization1->set_experiment_name(experiment_name.value());
  }
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  // RESOURCE_LOADING is not marked experimental.
  optimization_guide::proto::Optimization* optimization2 =
      page_hint1->add_whitelisted_optimizations();
  optimization2->set_optimization_type(
      optimization_guide::proto::RESOURCE_LOADING);
  optimization_guide::proto::ResourceLoadingHint* resource_hint1 =
      optimization2->add_resource_loading_hints();
  resource_hint1->set_loading_optimization_type(
      optimization_guide::proto::LOADING_BLOCK_RESOURCE);
  resource_hint1->set_resource_pattern("resource.js");

  // Add a second, non-experimental hint.
  optimization_guide::proto::Hint* hint2 = config.add_hints();
  hint2->set_key("twitter.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint3 = hint2->add_page_hints();
  page_hint3->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization3 =
      page_hint3->add_whitelisted_optimizations();
  optimization3->set_optimization_type(optimization_guide::proto::NOSCRIPT);
  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Check to ensure the optimization under test (facebook noscript) is either
  // enabled or disabled, depending on what the caller told us to expect.
  EXPECT_EQ(expect_enabled, MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
                                &user_data, GURL("https://m.facebook.com"),
                                PreviewsType::NOSCRIPT, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);

  // RESOURCE_LOADING_HINTS for facebook should always be enabled.
  ect_threshold = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
  EXPECT_EQ(!expect_enabled,
            MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
                &user_data, GURL("https://m.facebook.com"),
                PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
  // Twitter's NOSCRIPT should always be enabled; RESOURCE_LOADING_HINTS is not
  // configured and should be disabled.
  ect_threshold = net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.twitter.com/example"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
  // Google (which is not configured at all) should always have both NOSCRIPT
  // and RESOURCE_LOADING_HINTS disabled.
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://google.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       HandlesExperimentalFlagWithNoExperimentFlaggedOrEnabled) {
  // With the optimization NOT flagged as experimental and no experiment
  // enabled, the optimization should be enabled.
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndDisableFeature(features::kOptimizationHintsExperiments);
  DoExperimentFlagTest(base::nullopt, true);
}

TEST_F(PreviewsOptimizationGuideTest,
       HandlesExperimentalFlagWithEmptyExperimentName) {
  // Empty experiment names should be equivalent to no experiment flag set.
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndDisableFeature(features::kOptimizationHintsExperiments);
  DoExperimentFlagTest("", true);
}

TEST_F(PreviewsOptimizationGuideTest,
       HandlesExperimentalFlagWithExperimentConfiguredAndNotRunning) {
  // With the optimization flagged as experimental and no experiment
  // enabled, the optimization should be disabled.
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndDisableFeature(features::kOptimizationHintsExperiments);
  DoExperimentFlagTest("foo_experiment", false);
}

TEST_F(PreviewsOptimizationGuideTest,
       HandlesExperimentalFlagWithExperimentConfiguredAndSameOneRunning) {
  // With the optimization flagged as experimental and an experiment with that
  // name running, the optimization should be enabled.
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeatureWithParameters(
      features::kOptimizationHintsExperiments,
      {{"experiment_name", "foo_experiment"}});
  DoExperimentFlagTest("foo_experiment", true);
}

TEST_F(PreviewsOptimizationGuideTest,
       HandlesExperimentalFlagWithExperimentConfiguredAndDifferentOneRunning) {
  // With the optimization flagged as experimental and a *different* experiment
  // enabled, the optimization should be disabled.
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeatureWithParameters(
      features::kOptimizationHintsExperiments,
      {{"experiment_name", "bar_experiment"}});
  DoExperimentFlagTest("foo_experiment", false);
}

TEST_F(PreviewsOptimizationGuideTest, EnsureExperimentsDisabledByDefault) {
  // Mark an optimization as experiment, and ensure it's disabled even though we
  // don't explicitly enable or disable the feature as part of the test. This
  // ensures the experiments feature is disabled by default.
  DoExperimentFlagTest("foo_experiment", false);
}

TEST_F(PreviewsOptimizationGuideTest, ProcessHintsUnsupportedKeyRepIsIgnored) {
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint = config.add_hints();
  hint->set_key("facebook.com");
  hint->set_key_representation(
      optimization_guide::proto::REPRESENTATION_UNSPECIFIED);
  optimization_guide::proto::PageHint* page_hint = hint->add_page_hints();
  page_hint->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization =
      page_hint->add_whitelisted_optimizations();
  optimization->set_optimization_type(optimization_guide::proto::NOSCRIPT);
  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsUnsupportedOptimizationIsIgnored) {
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint = config.add_hints();
  hint->set_key("facebook.com");
  hint->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(
      optimization_guide::proto::TYPE_UNSPECIFIED);

  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest, ProcessHintsWithExistingSentinel) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
  base::HistogramTester histogram_tester;

  // Create valid config.
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  // Create sentinel file for version 2.0.0.
  const base::FilePath sentinel_path =
      temp_dir().Append(FILE_PATH_LITERAL("previews_config_sentinel.txt"));
  base::WriteFile(sentinel_path, "2.0.0", 5);

  // Verify config not processed for version 2.0.0 (same as sentinel).
  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_TRUE(base::PathExists(sentinel_path));
  histogram_tester.ExpectUniqueSample("Previews.ProcessHintsResult",
                                      2 /* kFailedFinishProcessing */, 1);

  // Now verify config is processed for different version and sentinel cleared.
  ProcessHints(config, "3.0.0");

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_EQ(net::EFFECTIVE_CONNECTION_TYPE_2G, ect_threshold);
  EXPECT_FALSE(base::PathExists(sentinel_path));
  histogram_tester.ExpectBucketCount("Previews.ProcessHintsResult",
                                     1 /* kProcessedPreviewsHints */, 1);
}

TEST_F(PreviewsOptimizationGuideTest, ProcessHintsWithInvalidSentinelFile) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
  base::HistogramTester histogram_tester;

  // Create valid config.
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  // Create sentinel file with invalid contents.
  const base::FilePath sentinel_path =
      temp_dir().Append(FILE_PATH_LITERAL("previews_config_sentinel.txt"));
  base::WriteFile(sentinel_path, "bad-2.0.0", 5);

  // Verify config not processed for existing sentinel with bad value but
  // that the existinel sentinel file is deleted.
  ProcessHints(config, "2.0.0");

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_FALSE(base::PathExists(sentinel_path));
  histogram_tester.ExpectUniqueSample("Previews.ProcessHintsResult",
                                      2 /* kFailedFinishProcessing */, 1);

  // Now verify config is processed with sentinel cleared.
  ProcessHints(config, "2.0.0");

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_FALSE(base::PathExists(sentinel_path));
  histogram_tester.ExpectBucketCount("Previews.ProcessHintsResult",
                                     1 /* kProcessedPreviewsHints */, 1);
}

TEST_F(PreviewsOptimizationGuideTest, SkipHintProcessingForSameConfigVersion) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
  base::HistogramTester histogram_tester;

  optimization_guide::proto::Configuration config1;
  optimization_guide::proto::Hint* hint1 = config1.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  optimization_guide::proto::Configuration config2;
  optimization_guide::proto::Hint* hint2 = config2.add_hints();
  hint2->set_key("google.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint2 = hint2->add_page_hints();
  page_hint2->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;

  // Process the new hints config and verify that they are available.
  ProcessHints(config1, "2.0.0");

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.google.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  histogram_tester.ExpectUniqueSample("Previews.ProcessHintsResult",
                                      1 /* kProcessedPreviewsHints */, 1);

  // Verify hint config with the same version as the previously processed config
  // is skipped.
  ProcessHints(config2, "2.0.0");

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.google.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  histogram_tester.ExpectBucketCount("Previews.ProcessHintsResult",
                                     3 /* kSkippedProcessingPreviewsHints */,
                                     1);
}

TEST_F(PreviewsOptimizationGuideTest,
       SkipHintProcessingForEarlierConfigVersion) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});
  base::HistogramTester histogram_tester;

  optimization_guide::proto::Configuration config1;
  optimization_guide::proto::Hint* hint1 = config1.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  optimization_guide::proto::Configuration config2;
  optimization_guide::proto::Hint* hint2 = config2.add_hints();
  hint2->set_key("google.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint2 = hint2->add_page_hints();
  page_hint2->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;

  // Process the new hints config and verify that they are available.
  ProcessHints(config1, "2.0.0");

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.google.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  histogram_tester.ExpectUniqueSample("Previews.ProcessHintsResult",
                                      1 /* kProcessedPreviewsHints */, 1);

  // Verify hint config with an earlier version than the previously processed
  // one is skipped.
  ProcessHints(config2, "1.0.0");

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.google.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  histogram_tester.ExpectBucketCount("Previews.ProcessHintsResult",
                                     3 /* kSkippedProcessingPreviewsHints */,
                                     1);
}

TEST_F(PreviewsOptimizationGuideTest, ProcessMultipleNewConfigs) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitWithFeatures(
      {features::kNoScriptPreviews, features::kResourceLoadingHints}, {});

  optimization_guide::proto::Configuration config1;
  optimization_guide::proto::Hint* hint1 = config1.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  optimization_guide::proto::Configuration config2;
  optimization_guide::proto::Hint* hint2 = config2.add_hints();
  hint2->set_key("google.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint2 = hint2->add_page_hints();
  page_hint2->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;

  // Process the new hints config and verify that they are available.
  ProcessHints(config1, "2.0.0");

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.google.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  histogram_tester.ExpectUniqueSample("Previews.ProcessHintsResult",
                                      1 /* kProcessedPreviewsHints */, 1);

  // Verify hint config with a newer version then the previously processed one
  // is processed.
  ProcessHints(config2, "3.0.0");

  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.facebook.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://m.google.com"), PreviewsType::NOSCRIPT,
      &ect_threshold));
  histogram_tester.ExpectBucketCount("Previews.ProcessHintsResult",
                                     1 /* kProcessedPreviewsHints */, 2);
}

TEST_F(PreviewsOptimizationGuideTest, ProcessHintConfigWithNoKeyFailsDcheck) {
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint = config.add_hints();
  hint->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  EXPECT_DCHECK_DEATH({
    ProcessHints(config, "2.0.0");
  });
}

TEST_F(PreviewsOptimizationGuideTest,
       ProcessHintsConfigWithDuplicateKeysFailsDcheck) {
  optimization_guide::proto::Configuration config;
  optimization_guide::proto::Hint* hint1 = config.add_hints();
  hint1->set_key("facebook.com");
  hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints();
  page_hint1->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization1 =
      page_hint1->add_whitelisted_optimizations();
  optimization1->set_optimization_type(optimization_guide::proto::NOSCRIPT);
  optimization_guide::proto::Hint* hint2 = config.add_hints();
  hint2->set_key("facebook.com");
  hint2->set_key_representation(optimization_guide::proto::HOST_SUFFIX);
  optimization_guide::proto::PageHint* page_hint2 = hint1->add_page_hints();
  page_hint2->set_page_pattern("*");
  optimization_guide::proto::Optimization* optimization2 =
      page_hint2->add_whitelisted_optimizations();
  optimization2->set_optimization_type(optimization_guide::proto::NOSCRIPT);

  EXPECT_DCHECK_DEATH({
    ProcessHints(config, "2.0.0");
  });
}

TEST_F(PreviewsOptimizationGuideTest, MaybeLoadOptimizationHints) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  InitializeFixedCountResourceLoadingHints();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.unknown.com"), base::DoNothing()));

  RunUntilIdle();

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Verify whitelisting from loaded page hints.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/news/weather/raininginseattle"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/football/seahawksrebuildingyear"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain.org/unhinted"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       MaybeLoadPageHintsWithTwoExperimentsDisabled) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  InitializeFixedCountResourceLoadingHintsWithTwoExperiments();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.unknown.com"), base::DoNothing()));

  RunUntilIdle();

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Verify whitelisting from loaded page hints.
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/news/weather/raininginseattle"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/football/seahawksrebuildingyear"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain.org/unhinted"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       MaybeLoadPageHintsWithFirstExperimentEnabled) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  base::test::ScopedFeatureList scoped_list2;
  scoped_list2.InitAndEnableFeatureWithParameters(
      features::kOptimizationHintsExperiments,
      {{"experiment_name", "experiment_1"}});

  InitializeFixedCountResourceLoadingHintsWithTwoExperiments();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.unknown.com"), base::DoNothing()));

  RunUntilIdle();

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Verify whitelisting from loaded page hints.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/news/weather/raininginseattle"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/football/seahawksrebuildingyear"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain.org/unhinted"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       MaybeLoadPageHintsWithSecondExperimentEnabled) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  base::test::ScopedFeatureList scoped_list2;
  scoped_list2.InitAndEnableFeatureWithParameters(
      features::kOptimizationHintsExperiments,
      {{"experiment_name", "experiment_2"}});

  InitializeFixedCountResourceLoadingHintsWithTwoExperiments();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.unknown.com"), base::DoNothing()));

  RunUntilIdle();

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Verify whitelisting from loaded page hints.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/news/weather/raininginseattle"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/football/seahawksrebuildingyear"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain.org/unhinted"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest,
       MaybeLoadPageHintsWithBothExperimentEnabled) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  base::test::ScopedFeatureList scoped_list2;
  scoped_list2.InitAndEnableFeatureWithParameters(
      features::kOptimizationHintsExperiments,
      {{"experiment_name", "experiment_1"},
       {"experiment_name", "experiment_2"}});

  InitializeFixedCountResourceLoadingHintsWithTwoExperiments();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org/news/football"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.unknown.com"), base::DoNothing()));

  RunUntilIdle();

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  // Verify whitelisting from loaded page hints.
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/news/weather/raininginseattle"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/football/seahawksrebuildingyear"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain.org/unhinted"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

// Test that optimization hints with multiple page patterns is processed
// correctly.
TEST_F(PreviewsOptimizationGuideTest,
       LoadManyResourceLoadingOptimizationHints) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kResourceLoadingHints);

  const size_t key_count = 50;
  const size_t page_patterns_per_key = 25;

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;

  InitializeMultipleResourceLoadingHints(key_count, page_patterns_per_key);

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain0.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain0.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain0.org/news0/football"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain49.org/"), base::DoNothing()));
  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain49.org/news0/football"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain50.org/"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://somedomain50.org/news0/football"), base::DoNothing()));
  EXPECT_FALSE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.unknown.com"), base::DoNothing()));

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain0.org/news0/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain0.org/news24/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain0.org/news25/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));

  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain49.org/news0/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_TRUE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain49.org/news24/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain49.org/news25/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));

  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain50.org/news0/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain50.org/news24/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data, GURL("https://www.somedomain50.org/news25/football"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));

  RunUntilIdle();
}

TEST_F(PreviewsOptimizationGuideTest,
       MaybeLoadOptimizationHintsWithoutEnabledPageHintsFeature) {
  // Without PageHints-oriented feature enabled, never see
  // enabled, the optimization should be disabled.
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndDisableFeature(features::kResourceLoadingHints);

  InitializeFixedCountResourceLoadingHints();

  EXPECT_TRUE(guide()->MaybeLoadOptimizationHints(
      GURL("https://www.somedomain.org"), base::DoNothing()));

  RunUntilIdle();

  PreviewsUserData user_data(kDefaultPageId);
  net::EffectiveConnectionType ect_threshold;
  EXPECT_FALSE(MaybeLoadOptimizationHintsAndCheckIsWhitelisted(
      &user_data,
      GURL("https://www.somedomain.org/news/weather/raininginseattle"),
      PreviewsType::RESOURCE_LOADING_HINTS, &ect_threshold));
}

TEST_F(PreviewsOptimizationGuideTest, IsBlacklisted) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kLitePageServerPreviews);

  EXPECT_TRUE(
      guide()->IsBlacklisted(GURL("https://m.blacklisteddomain.com/path"),
                             PreviewsType::LITE_PAGE_REDIRECT));

  InitializeWithLitePageRedirectBlacklist();

  EXPECT_TRUE(
      guide()->IsBlacklisted(GURL("https://m.blacklisteddomain.com/path"),
                             PreviewsType::LITE_PAGE_REDIRECT));
  EXPECT_DCHECK_DEATH(guide()->IsBlacklisted(
      GURL("https://m.blacklisteddomain.com/path"), PreviewsType::NOSCRIPT));

  EXPECT_TRUE(guide()->IsBlacklisted(
      GURL("https://blacklistedsubdomain.maindomain.co.in"),
      PreviewsType::LITE_PAGE_REDIRECT));

  EXPECT_FALSE(guide()->IsBlacklisted(GURL("https://maindomain.co.in"),
                                      PreviewsType::LITE_PAGE_REDIRECT));
}

TEST_F(PreviewsOptimizationGuideTest, LitePageRedirectSkipIsBlacklistedCheck) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kLitePageServerPreviews);
  InitializeWithLitePageRedirectBlacklist();

  EXPECT_TRUE(
      guide()->IsBlacklisted(GURL("https://m.blacklisteddomain.com/path"),
                             PreviewsType::LITE_PAGE_REDIRECT));
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kIgnoreLitePageRedirectOptimizationBlacklist);

  EXPECT_FALSE(
      guide()->IsBlacklisted(GURL("https://m.blacklisteddomain.com/path"),
                             PreviewsType::LITE_PAGE_REDIRECT));
}

TEST_F(PreviewsOptimizationGuideTest,
       IsBlacklistedWithLitePageServerPreviewsDisabled) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndDisableFeature(features::kLitePageServerPreviews);

  InitializeWithLitePageRedirectBlacklist();

  EXPECT_TRUE(
      guide()->IsBlacklisted(GURL("https://m.blacklisteddomain.com/path"),
                             PreviewsType::LITE_PAGE_REDIRECT));
}

TEST_F(PreviewsOptimizationGuideTest, RemoveObserverCalledAtDestruction) {
  EXPECT_FALSE(optimization_guide_service()->RemoveObserverCalled());

  ResetGuide();

  EXPECT_TRUE(optimization_guide_service()->RemoveObserverCalled());
}

TEST_F(PreviewsOptimizationGuideTest, HintsFetcherEnabledNoHosts) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kOptimizationHintsFetching);
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  command_line->AppendSwitchASCII("optimization_guide_service_url",
                                  "https://hintsserver.com");

  guide()->SetHintsFetcherForTesting(
      BuildTestHintsFetcher(HintsFetcherEndState::kFetchSuccessWithHints));

  EXPECT_CALL(*top_host_provider(), GetTopHosts(testing::_)).Times(1);

  // Load hints so that OnHintsUpdated is called. This will force FetchHints to
  // be triggered if OptimizationHintsFetching is enabled.
  InitializeFixedCountResourceLoadingHints();
  // Cause the timer to fire the fetch event.
  MoveClockForwardBy(base::TimeDelta::FromSeconds(kTestFetchRetryDelaySecs));
  EXPECT_FALSE(hints_fetcher()->hints_fetched());
}

TEST_F(PreviewsOptimizationGuideTest, HintsFetcherEnabledWithHosts) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kOptimizationHintsFetching);
  std::string opt_guide_url = "https://hintsserver.com";

  guide()->SetHintsFetcherForTesting(
      BuildTestHintsFetcher(HintsFetcherEndState::kFetchSuccessWithHints));

  std::vector<std::string> hosts = {"example1.com", "example2.com"};
  EXPECT_CALL(*top_host_provider(), GetTopHosts(testing::_))
      .Times(1)
      .WillRepeatedly(testing::Return(hosts));

  // Load hints so that OnHintsUpdated is called. This will force FetchHints to
  // be triggered if OptimizationHintsFetching is enabled.
  InitializeFixedCountResourceLoadingHints();

  // Force timer to expire and schedule a hints fetch.
  MoveClockForwardBy(base::TimeDelta::FromSeconds(kTestFetchRetryDelaySecs));
  EXPECT_TRUE(hints_fetcher()->hints_fetched());
}

TEST_F(PreviewsOptimizationGuideTest, HintsFetcherTimerRetryDelay) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kOptimizationHintsFetching);
  std::string opt_guide_url = "https://hintsserver.com";

  guide()->SetHintsFetcherForTesting(
      BuildTestHintsFetcher(HintsFetcherEndState::kFetchFailed));

  std::vector<std::string> hosts = {"example1.com", "example2.com"};
  EXPECT_CALL(*top_host_provider(), GetTopHosts(testing::_))
      .Times(2)
      .WillRepeatedly(testing::Return(hosts));

  // Force hints fetch scheduling.
  guide()->ScheduleHintsFetch();

  // Force timer to expire and schedule a hints fetch - first time.
  MoveClockForwardBy(base::TimeDelta::FromSeconds(kTestFetchRetryDelaySecs));
  EXPECT_FALSE(hints_fetcher()->hints_fetched());

  // Force speculative timer to expire after fetch fails first time, update
  // hints fetcher so it succeeds this time.
  guide()->SetHintsFetcherForTesting(
      BuildTestHintsFetcher(HintsFetcherEndState::kFetchSuccessWithHints));
  MoveClockForwardBy(base::TimeDelta::FromSeconds(kTestFetchRetryDelaySecs));
  EXPECT_TRUE(hints_fetcher()->hints_fetched());
}

TEST_F(PreviewsOptimizationGuideTest, HintsFetcherTimerFetchSucceeds) {
  base::HistogramTester histogram_tester;
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndEnableFeature(features::kOptimizationHintsFetching);
  std::string opt_guide_url = "https://hintsserver.com";

  guide()->SetHintsFetcherForTesting(
      BuildTestHintsFetcher(HintsFetcherEndState::kFetchSuccessWithHints));

  std::vector<std::string> hosts = {"example1.com", "example2.com"};
  EXPECT_CALL(*top_host_provider(), GetTopHosts(testing::_))
      .WillRepeatedly(testing::Return(hosts));

  // Force hints fetch scheduling.
  guide()->ScheduleHintsFetch();

  // Force timer to expire and schedule a hints fetch that succeeds.
  MoveClockForwardBy(base::TimeDelta::FromSeconds(kTestFetchRetryDelaySecs));
  EXPECT_TRUE(hints_fetcher()->hints_fetched());

  // TODO(mcrouse): Make sure timer is triggered by metadata entry,
  // |hint_cache| control needed.
  guide()->SetHintsFetcherForTesting(
      BuildTestHintsFetcher(HintsFetcherEndState::kFetchSuccessWithHints));

  MoveClockForwardBy(base::TimeDelta::FromSeconds(kTestFetchRetryDelaySecs));
  EXPECT_FALSE(hints_fetcher()->hints_fetched());
  MoveClockForwardBy(base::TimeDelta::FromSeconds(kUpdateFetchHintsTimeSecs));

  RunUntilFetchedHintsStored();
  EXPECT_TRUE(hints_fetcher()->hints_fetched());
}

TEST_F(PreviewsOptimizationGuideTest, HintsFetcherDisabled) {
  base::test::ScopedFeatureList scoped_list;
  scoped_list.InitAndDisableFeature(features::kOptimizationHintsFetching);

  EXPECT_CALL(*top_host_provider(), GetTopHosts(testing::_)).Times(0);
  CreateServiceAndGuide();
  // Load hints so that OnHintsUpdated is called. This will
  // check that FetcHints is not triggered by making sure that top_host_provider
  // is not called.
  InitializeFixedCountResourceLoadingHints();
}

}  // namespace previews
