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

#include "components/optimization_guide/core/hints/hints_fetcher.h"

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/optimization_guide/browser_test_util.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h"
#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h"
#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/common/features.h"
#include "components/google/core/common/google_switches.h"
#include "components/google/core/common/google_util.h"
#include "components/metrics/content/subprocess_metrics_provider.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_handle.h"
#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h"
#include "components/optimization_guide/core/filters/hints_component_info.h"
#include "components/optimization_guide/core/filters/hints_component_util.h"
#include "components/optimization_guide/core/filters/optimization_hints_component_update_listener.h"
#include "components/optimization_guide/core/filters/test_hints_component_creator.h"
#include "components/optimization_guide/core/hints/fake_hints_fetcher.h"
#include "components/optimization_guide/core/hints/hints_manager.h"
#include "components/optimization_guide/core/hints/optimization_guide_store.h"
#include "components/optimization_guide/core/hints/top_host_provider.h"
#include "components/optimization_guide/core/optimization_guide_constants.h"
#include "components/optimization_guide/core/optimization_guide_enums.h"
#include "components/optimization_guide/core/optimization_guide_features.h"
#include "components/optimization_guide/core/optimization_guide_prefs.h"
#include "components/optimization_guide/core/optimization_guide_switches.h"
#include "components/optimization_guide/proto/hints.pb.h"
#include "components/prefs/pref_service.h"
#include "components/site_engagement/content/site_engagement_service.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/variations/hashing.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_base.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/network_connection_change_simulator.h"
#include "content/public/test/prerender_test_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/network/public/cpp/network_connection_tracker.h"
#include "services/network/test/test_network_connection_tracker.h"
#include "third_party/blink/public/common/features.h"

namespace {

constexpr char kGoogleHost[] = "www.google.com";

constexpr char kGoogleSearchUrlPath[] = "/search?q=search_results_page.html";

// Modifies |relative_url|:
// Scheme of the returned URL matches the scheme of the |server|.
// Host of the returned URL matches kGoogleHost.
// Port number of the returned URL matches the port at which |server| is
// listening.
// Path of the returned URL is set to |relative_url|.
GURL GetURLWithGoogleHost(net::EmbeddedTestServer* server,
                          const std::string& relative_url) {
  GURL server_base_url = server->base_url();
  GURL base_url =
      GURL(base::StrCat({server_base_url.GetScheme(), "://", kGoogleHost, ":",
                         server_base_url.GetPort()}));
  EXPECT_TRUE(base_url.is_valid()) << base_url.possibly_invalid_spec();
  return base_url.Resolve(relative_url);
}

// Handles the server request to Google search URL.
std::unique_ptr<net::test_server::HttpResponse> HandleGoogleSearchUrlRequest(
    const net::test_server::HttpRequest& request) {
  if (base::EqualsCaseInsensitiveASCII(request.relative_url,
                                       kGoogleSearchUrlPath)) {
    // Serve the SRP file.
    std::unique_ptr<net::test_server::BasicHttpResponse> response =
        std::make_unique<net::test_server::BasicHttpResponse>();
    std::string file_contents;
    base::FilePath test_data_directory;
    base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory);
    if (base::ReadFileToString(test_data_directory.AppendASCII(
                                   "previews/search_results_page.html"),
                               &file_contents)) {
      response->set_content(file_contents);
      response->set_code(net::HTTP_OK);
      return std::move(response);
    }
  }
  return nullptr;
}

}  // namespace

// This test class sets up everything but does not enable any
// HintsFetcher-related features. The parameter selects whether the
// OptimizationGuideKeyedService is enabled (tests should pass in the same way
// for both cases).
class HintsFetcherDisabledBrowserTest : public InProcessBrowserTest {
 public:
  HintsFetcherDisabledBrowserTest() = default;

  HintsFetcherDisabledBrowserTest(const HintsFetcherDisabledBrowserTest&) =
      delete;
  HintsFetcherDisabledBrowserTest& operator=(
      const HintsFetcherDisabledBrowserTest&) = delete;

  ~HintsFetcherDisabledBrowserTest() override = default;

  void SetUpOnMainThread() override {
    content::NetworkConnectionChangeSimulator().SetConnectionType(
        network::mojom::ConnectionType::CONNECTION_2G);

    // Ensure that kGoogleHost resolves to the localhost where the embedded test
    // server is listening.
    host_resolver()->AddRule("*", "127.0.0.1");

    ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();

    InProcessBrowserTest::SetUpOnMainThread();
  }

  void SetUp() override {
    origin_server_ = std::make_unique<net::EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);
    net::EmbeddedTestServer::ServerCertificateConfig origin_server_cert_config;
    origin_server_cert_config.dns_names = {kGoogleHost};
    origin_server_cert_config.ip_addresses = {net::IPAddress::IPv4Localhost()};
    origin_server_->SetSSLConfig(origin_server_cert_config);
    origin_server_->RegisterRequestHandler(
        base::BindRepeating(&HandleGoogleSearchUrlRequest));
    origin_server_->ServeFilesFromSourceDirectory("chrome/test/data/previews");

    ASSERT_TRUE(origin_server_->Start());

    https_url_ = origin_server_->GetURL("/hint_setup.html");
    ASSERT_TRUE(https_url().SchemeIs(url::kHttpsScheme));

    search_results_page_url_ =
        GetURLWithGoogleHost(origin_server_.get(), kGoogleSearchUrlPath);

    hints_server_ = std::make_unique<net::EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);

    net::EmbeddedTestServer::ServerCertificateConfig hints_server_cert_config;
    hints_server_cert_config.dns_names = {
        GURL(optimization_guide::kOptimizationGuideServiceGetHintsDefaultURL)
            .GetHost()};
    hints_server_->SetSSLConfig(hints_server_cert_config);
    hints_server_->ServeFilesFromSourceDirectory("chrome/test/data/previews");
    hints_server_->RegisterRequestHandler(base::BindRepeating(
        &HintsFetcherDisabledBrowserTest::HandleGetHintsRequest,
        base::Unretained(this)));

    ASSERT_TRUE(hints_server_->Start());

    std::map<std::string, std::string> params;
    params["random_anchor_sampling_period"] = "1";
    params["traffic_client_enabled_percent"] = "100";
    param_feature_list_.InitAndEnableFeatureWithParameters(
        blink::features::kNavigationPredictor, params);

    InProcessBrowserTest::SetUp();
  }

  void SetUpCommandLine(base::CommandLine* cmd) override {
    cmd->AppendSwitch("purge_hint_cache_store");

    cmd->AppendSwitch(optimization_guide::switches::
                          kDisableCheckingUserPermissionsForTesting);

    // Set up OptimizationGuideServiceURL, this does not enable HintsFetching,
    // only provides the URL.
    cmd->AppendSwitchASCII(
        optimization_guide::switches::kOptimizationGuideServiceGetHintsURL,
        hints_server_
            ->GetURL(GURL(optimization_guide::
                              kOptimizationGuideServiceGetHintsDefaultURL)
                         .GetHost(),
                     "/")
            .spec());
    cmd->AppendSwitchASCII("force-variation-ids", "4");

    cmd->AppendSwitchASCII(optimization_guide::switches::kFetchHintsOverride,
                           "example1.com, example2.com");

    cmd->AppendSwitch(optimization_guide::switches::kFetchHintsOverrideTimer);

    // Ignore the port numbers for the Google Search URL check.
    cmd->AppendSwitch(switches::kIgnoreGooglePortNumbers);
  }

  // Creates hint data for the |hint_setup_url|'s so that the fetching of the
  // hints is triggered.
  void SetUpComponentUpdateHints(const GURL& hint_setup_url) {
    optimization_guide::RetryForHistogramUntilCountReached(
        GetHistogramTester(),
        "OptimizationGuide.HintsManager.HintCacheInitialized", 1);

    const optimization_guide::HintsComponentInfo& component_info =
        test_hints_component_creator_.CreateHintsComponentInfoWithPageHints(
            optimization_guide::proto::NOSCRIPT, {hint_setup_url.GetHost()},
            "*");

    base::HistogramTester histogram_tester;

    optimization_guide::OptimizationHintsComponentUpdateListener::GetInstance()
        ->MaybeUpdateHintsComponent(component_info);

    optimization_guide::RetryForHistogramUntilCountReached(
        &histogram_tester,
        optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);
  }

  void SetNetworkConnectionOffline() {
    content::NetworkConnectionChangeSimulator().SetConnectionType(
        network::mojom::ConnectionType::CONNECTION_NONE);
  }

  void SetNetworkConnectionOnline() {
    content::NetworkConnectionChangeSimulator().SetConnectionType(
        network::mojom::ConnectionType::CONNECTION_2G);
  }

  void SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType response_type) {
    response_type_ = response_type;
  }

  void LoadHintsForUrl(const GURL& url) {
    base::HistogramTester histogram_tester;

    // Navigate to |url| to prime the OptimizationGuide hints for the
    // url's host and ensure that they have been loaded from the store (via
    // histogram) prior to the navigation that tests functionality.
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

    optimization_guide::RetryForHistogramUntilCountReached(
        &histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
  }

  const GURL& https_url() const { return https_url_; }
  const base::HistogramTester* GetHistogramTester() {
    return &histogram_tester_;
  }

  const GURL& search_results_page_url() const {
    return search_results_page_url_;
  }

  void SetExpectedHintsRequestForHostsAndUrls(
      const base::flat_set<std::string>& hosts_or_urls) {
    base::AutoLock lock(lock_);
    expect_hints_request_for_hosts_and_urls_ = hosts_or_urls;
  }

  size_t count_hints_requests_received() {
    base::AutoLock lock(lock_);
    return count_hints_requests_received_;
  }

  void increase_count_hints_requests_received() {
    {
      base::AutoLock lock(lock_);
      ++count_hints_requests_received_;
    }

    if (quit_closure_) {
      content::GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
                                                   std::move(quit_closure_));
    }
  }

  void SetExpectedBearerAccessToken(
      const std::string& expected_bearer_access_token) {
    expected_bearer_access_token_ = expected_bearer_access_token;
  }

  void WaitUntilHintsFetcherRequestReceived() {
    {
      // Acquire the |lock_| inside to avoid starving other consumers of the
      // lock.
      base::AutoLock lock(lock_);
      if (count_hints_requests_received_ > 0) {
        return;
      }
    }

    base::RunLoop run_loop;
    quit_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

  void ResetCountHintsRequestsReceived() {
    base::AutoLock lock(lock_);
    count_hints_requests_received_ = 0;
  }

  // Triggers nostate prefetch of |url|.
  void TriggerNoStatePrefetch(const GURL& url) {
    prerender::NoStatePrefetchManager* no_state_prefetch_manager =
        prerender::NoStatePrefetchManagerFactory::GetForBrowserContext(
            browser()->profile());
    ASSERT_TRUE(no_state_prefetch_manager);

    prerender::test_utils::TestNoStatePrefetchContentsFactory*
        no_state_prefetch_contents_factory =
            new prerender::test_utils::TestNoStatePrefetchContentsFactory();
    no_state_prefetch_manager->SetNoStatePrefetchContentsFactoryForTest(
        no_state_prefetch_contents_factory);

    content::SessionStorageNamespace* storage_namespace =
        browser()
            ->tab_strip_model()
            ->GetActiveWebContents()
            ->GetController()
            .GetDefaultSessionStorageNamespace();
    ASSERT_TRUE(storage_namespace);

    std::unique_ptr<prerender::test_utils::TestPrerender> test_prerender =
        no_state_prefetch_contents_factory->ExpectNoStatePrefetchContents(
            prerender::FINAL_STATUS_NOSTATE_PREFETCH_FINISHED);

    std::unique_ptr<prerender::NoStatePrefetchHandle> no_state_prefetch_handle =
        no_state_prefetch_manager->AddSameOriginSpeculation(
            url, storage_namespace, gfx::Size(640, 480),
            url::Origin::Create(url));
    ASSERT_EQ(no_state_prefetch_handle->contents(), test_prerender->contents());

    // The final status may be either  FINAL_STATUS_NOSTATE_PREFETCH_FINISHED or
    // FINAL_STATUS_RECENTLY_VISITED.
    test_prerender->contents()->set_skip_final_checks(true);
  }

 protected:
  base::test::ScopedFeatureList scoped_feature_list_;
  std::unique_ptr<net::EmbeddedTestServer> origin_server_;
  std::unique_ptr<net::EmbeddedTestServer> hints_server_;
  optimization_guide::HintsFetcherRemoteResponseType response_type_ =
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful;

 private:
  std::unique_ptr<net::test_server::HttpResponse> HandleOriginRequest(
      const net::test_server::HttpRequest& request) {
    EXPECT_EQ(request.method, net::test_server::METHOD_GET);
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    response->set_code(net::HTTP_OK);

    return std::move(response);
  }

  std::unique_ptr<net::test_server::HttpResponse> HandleGetHintsRequest(
      const net::test_server::HttpRequest& request) {
    increase_count_hints_requests_received();
    auto response = std::make_unique<net::test_server::BasicHttpResponse>();
    // If the request is a GET, it corresponds to a navigation so return a
    // normal response.
    EXPECT_EQ(request.method, net::test_server::METHOD_POST);
    EXPECT_NE(request.headers.end(), request.headers.find("X-Client-Data"));

    EXPECT_EQ(expected_bearer_access_token_.empty(),
              !base::Contains(request.headers,
                              net::HttpRequestHeaders::kAuthorization));
    if (!expected_bearer_access_token_.empty()) {
      EXPECT_EQ(expected_bearer_access_token_,
                request.headers.at(net::HttpRequestHeaders::kAuthorization));
    }

    // Make sure only one of API key or access token is sent.
    EXPECT_EQ(base::Contains(request.headers, "X-Goog-Api-Key"),
              expected_bearer_access_token_.empty());

    optimization_guide::proto::GetHintsRequest hints_request;
    EXPECT_TRUE(hints_request.ParseFromString(request.content));
    EXPECT_FALSE(hints_request.hosts().empty() && hints_request.urls().empty());
    EXPECT_GE(optimization_guide::HintsFetcher::kMaxHosts,
              static_cast<size_t>(hints_request.hosts().size()));

    // Only verify the hints if there are hosts in the request.
    if (!hints_request.hosts().empty()) {
      VerifyHintsMatchExpectedHostsAndUrls(hints_request);
    }

    if (response_type_ ==
        optimization_guide::HintsFetcherRemoteResponseType::kSuccessful) {
      response->set_code(net::HTTP_OK);

      optimization_guide::proto::GetHintsResponse get_hints_response;

      optimization_guide::proto::Hint* hint = get_hints_response.add_hints();
      hint->set_key_representation(optimization_guide::proto::HOST);
      hint->set_key(search_results_page_url_.GetHost());
      hint->add_allowlisted_optimizations()->set_optimization_type(
          optimization_guide::proto::OptimizationType::NOSCRIPT);
      optimization_guide::proto::PageHint* page_hint = hint->add_page_hints();
      page_hint->set_page_pattern("page pattern");

      std::string serialized_request;
      get_hints_response.SerializeToString(&serialized_request);
      response->set_content(serialized_request);
    } else if (response_type_ ==
               optimization_guide::HintsFetcherRemoteResponseType::
                   kUnsuccessful) {
      response->set_code(net::HTTP_NOT_FOUND);

    } else if (response_type_ ==
               optimization_guide::HintsFetcherRemoteResponseType::kMalformed) {
      response->set_code(net::HTTP_OK);

      std::string serialized_request = "Not a proto";
      response->set_content(serialized_request);
    } else if (response_type_ ==
               optimization_guide::HintsFetcherRemoteResponseType::kHung) {
      return std::make_unique<net::test_server::HungResponse>();
    } else {
      NOTREACHED();
    }

    return std::move(response);
  }

  // Verifies that the hosts present in |hints_request| match the expected set
  // of hosts present in |expect_hints_request_for_hosts_|. The ordering of the
  // hosts in not matched.
  void VerifyHintsMatchExpectedHostsAndUrls(
      const optimization_guide::proto::GetHintsRequest& hints_request) const {
    if (!expect_hints_request_for_hosts_and_urls_) {
      return;
    }

    base::flat_set<std::string> hosts_and_urls_requested;
    for (const auto& host : hints_request.hosts()) {
      hosts_and_urls_requested.insert(host.host());
    }
    for (const auto& url : hints_request.urls()) {
      // TODO(crbug.com/40118423):  Remove normalization step once nav predictor
      // provides predictable URLs.
      hosts_and_urls_requested.insert(GURL(url.url()).GetAsReferrer().spec());
    }

    EXPECT_EQ(expect_hints_request_for_hosts_and_urls_.value().size(),
              hosts_and_urls_requested.size());
    for (const auto& host_or_url :
         expect_hints_request_for_hosts_and_urls_.value()) {
      hosts_and_urls_requested.erase(host_or_url);
    }
    EXPECT_EQ(0u, hosts_and_urls_requested.size());
  }

  void TearDownOnMainThread() override {
    EXPECT_TRUE(origin_server_->ShutdownAndWaitUntilComplete());
    EXPECT_TRUE(hints_server_->ShutdownAndWaitUntilComplete());

    InProcessBrowserTest::TearDownOnMainThread();
  }

  base::test::ScopedFeatureList param_feature_list_;

  GURL https_url_;

  GURL search_results_page_url_;

  base::HistogramTester histogram_tester_;

  optimization_guide::testing::TestHintsComponentCreator
      test_hints_component_creator_;

  base::Lock lock_;

  // Guarded by |lock_|.
  // Count of hints requests received so far by |hints_server_|.
  size_t count_hints_requests_received_ = 0;

  base::OnceClosure quit_closure_;

  // Guarded by |lock_|. Set of hosts and URLs for which a hints request is
  // expected to arrive. This set is verified to match with the set of hosts and
  // URLs present in the hints request. If null, then the verification is not
  // done.
  std::optional<base::flat_set<std::string>>
      expect_hints_request_for_hosts_and_urls_;

  // The expected authorization header holding the bearer access token.
  std::string expected_bearer_access_token_;

  std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;
};

IN_PROC_BROWSER_TEST_F(HintsFetcherDisabledBrowserTest, HintsFetcherDisabled) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Expect that the histogram for HintsFetcher to be 0 because the OnePlatform
  // is not enabled.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount", 0);
}

// This test class enables OnePlatform Hints.
class HintsFetcherBrowserTest : public HintsFetcherDisabledBrowserTest {
 public:
  HintsFetcherBrowserTest() = default;

  HintsFetcherBrowserTest(const HintsFetcherBrowserTest&) = delete;
  HintsFetcherBrowserTest& operator=(const HintsFetcherBrowserTest&) = delete;

  ~HintsFetcherBrowserTest() override = default;

  void SetUp() override {
    std::vector<base::test::FeatureRefAndParams> enabled_features = {
        {optimization_guide::features::kOptimizationHints, {}},
        {*optimization_guide::kHintsMaxConcurrentNavigationFetches.feature,
         {{optimization_guide::kHintsMaxConcurrentNavigationFetches.name,
           "2"}}},
        {optimization_guide::kHintsBatchUpdateForActiveTabsAndTopHosts, {}},
    };
    PopulateEnabledFeatures(&enabled_features);
    scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features,
                                                       disabled_features_);
    // Call to inherited class to match same set up with feature flags added.
    HintsFetcherDisabledBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // Register an optimization type, so hints will be fetched at page
    // navigation.
    OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
        ->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT});

    HintsFetcherDisabledBrowserTest::SetUpOnMainThread();
  }

  // Allows subclasses to expand on the features to enable.
  virtual void PopulateEnabledFeatures(
      std::vector<base::test::FeatureRefAndParams>* enabled_features) {}

  optimization_guide::TopHostProvider* top_host_provider() {
    OptimizationGuideKeyedService* keyed_service =
        OptimizationGuideKeyedServiceFactory::GetForProfile(
            browser()->profile());
    return keyed_service->GetTopHostProvider();
  }

  void CanApplyOptimizationOnDemand(
      const std::vector<GURL>& urls,
      const std::vector<optimization_guide::proto::OptimizationType>&
          optimization_types,
      optimization_guide::OnDemandOptimizationGuideDecisionRepeatingCallback
          callback) {
    OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
        ->CanApplyOptimizationOnDemand(
            urls, optimization_types,
            optimization_guide::proto::CONTEXT_BOOKMARKS, callback);
  }

 protected:
  std::vector<base::test::FeatureRef> disabled_features_;
};

// This test creates new browser with no profile and loads a random page with
// the feature flags for OptimizationHintsFetching. We confirm that the
// TopHostProvider is called and does not crash by checking UMA
// histograms for the total number of TopEngagementSites and
// the total number of sites returned controlled by the experiments flag
// |max_oneplatform_update_hosts|.
IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherEnabled) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherFetchedHintsLoaded) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  GURL url = https_url();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1),
            1);

  LoadHintsForUrl(https_url());

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), https_url()));

  // Verifies that the fetched hint is just used in memory and nothing is
  // loaded.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintCache.HintType.Loaded", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesSuccessful) {
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  // Wait until histograms have been updated before performing checks for
  // correct behavior based on the response.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesUnsuccessful) {
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kUnsuccessful);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  // Wait until histograms have been updated before performing checks for
  // correct behavior based on the response.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status",
      net::HTTP_NOT_FOUND, 1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesMalformed) {
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kMalformed);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  // Wait until histograms have been updated before performing checks for
  // correct behavior based on the response.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcherWithResponsesUnsuccessfulAtNavigationTime) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kUnsuccessful);

  // Set the connection online to force a fetch at navigation time.
  SetNetworkConnectionOnline();

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(),
                                           GURL("https://unsuccessful.com/")));

  // We expect that we requested hints for 1 URL.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount."
                "PageNavigation",
                1),
            1);
}

IN_PROC_BROWSER_TEST_F(
    HintsFetcherBrowserTest,
    HintsFetcherWithResponsesHungShouldRecordWhenActiveRequestCanceled) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  SetResponseType(optimization_guide::HintsFetcherRemoteResponseType::kHung);

  // Set the connection online to force a fetch at navigation time.
  SetNetworkConnectionOnline();

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL("https://hung.com/1")));
  WaitUntilHintsFetcherRequestReceived();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL("https://hung.com/2")));
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL("https://hung.com/3")));

  // We expect that one request was canceled.
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "PageNavigation",
      optimization_guide::FetcherRequestStatus::kRequestCanceled, 1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       DISABLED_HintsFetcherClearFetchedHints) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  GURL url = https_url();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as OnePlatform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "PageNavigation",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1),
            1);

  LoadHintsForUrl(https_url());

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), https_url()));

  // Verifies that the fetched hint is used in-memory and no hint is loaded
  // from store.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintCache.HintType.Loaded", 0);

  // Wipe the browser history - clear all the fetched hints.
  browser()->profile()->Wipe();

  // Wait until hint cache stabilizes and clears all the fetched hints.
  base::ThreadPoolInstance::Get()->FlushForTesting();
  base::RunLoop().RunUntilIdle();

  // Try to load the same hint to confirm fetched hints are no longer there.
  LoadHintsForUrl(https_url());

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), https_url()));

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintCache.HintType.Loaded",
      static_cast<int>(optimization_guide::OptimizationGuideStore::
                           StoreEntryType::kComponentHint),
      1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherOverrideTimer) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  GURL url = https_url();
  base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
      optimization_guide::switches::kFetchHintsOverride, "whatever.com");
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      optimization_guide::switches::kFetchHintsOverrideTimer);

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as OnePlatform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  // There should be 2 sites in the engagement service.
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
      "BatchUpdateActiveTabs",
      2, 1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  // There should have been 1 hint returned in the response.
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);

  LoadHintsForUrl(https_url());

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), https_url()));

  // Verifies that the fetched hint is used from memory and no hints are loaded.
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintCache.HintType.Loaded", 0);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest, HintsFetcherFetches) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as hints fetching is enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
}

IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       OnDemandFetchRepeatedlyNoCache) {
  SetNetworkConnectionOnline();

  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  OptimizationGuideKeyedService* ogks =
      OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile());
  ogks->RegisterOptimizationTypes(
      {optimization_guide::proto::OptimizationType::NOSCRIPT});

  GURL url_with_no_hints("https://urlwithnohints.com/notcached");

  {
    base::HistogramTester histogram_tester;
    std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>();
    CanApplyOptimizationOnDemand(
        {url_with_no_hints},
        {optimization_guide::proto::OptimizationType::NOSCRIPT},
        base::BindRepeating(
            [](base::RunLoop* run_loop, const GURL& url,
               const base::flat_map<
                   optimization_guide::proto::OptimizationType,
                   optimization_guide::OptimizationGuideDecisionWithMetadata>&
                   decisions) {
              // Expect one decision per requested type.
              EXPECT_EQ(decisions.size(), 1u);
              auto it = decisions.find(
                  optimization_guide::proto::OptimizationType::NOSCRIPT);
              EXPECT_NE(it, decisions.end());
              EXPECT_EQ(it->second.decision,
                        optimization_guide::OptimizationGuideDecision::kFalse);

              run_loop->Quit();
            },
            run_loop.get()));
    run_loop->Run();

    histogram_tester.ExpectUniqueSample(
        "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
        "Bookmarks",
        optimization_guide::FetcherRequestStatus::kSuccess, 1);
  }

  {
    base::HistogramTester histogram_tester;
    std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>();
    CanApplyOptimizationOnDemand(
        {url_with_no_hints},
        {optimization_guide::proto::OptimizationType::NOSCRIPT},
        base::BindRepeating(
            [](base::RunLoop* run_loop, const GURL& url,
               const base::flat_map<
                   optimization_guide::proto::OptimizationType,
                   optimization_guide::OptimizationGuideDecisionWithMetadata>&
                   decisions) {
              // Expect one decision per requested type.
              EXPECT_EQ(decisions.size(), 1u);
              auto it = decisions.find(
                  optimization_guide::proto::OptimizationType::NOSCRIPT);
              EXPECT_NE(it, decisions.end());
              EXPECT_EQ(it->second.decision,
                        optimization_guide::OptimizationGuideDecision::kFalse);

              run_loop->Quit();
            },
            run_loop.get()));
    run_loop->Run();

    // Second time should refetch since on-demand always fetches.
    histogram_tester.ExpectUniqueSample(
        "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
        "Bookmarks",
        optimization_guide::FetcherRequestStatus::kSuccess, 1);
  }
}

// Test that the hints are fetched at the time of the navigation.
IN_PROC_BROWSER_TEST_F(HintsFetcherBrowserTest,
                       HintsFetcher_NavigationFetch_URLKeyedNotRefetched) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  optimization_guide::RetryForHistogramUntilCountReached(
      histogram_tester,
      optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
  EXPECT_EQ(1u, count_hints_requests_received());

  // Enable the connection so the page navigation race fetch is initiated.
  SetNetworkConnectionOnline();
  std::string full_url("https://foo.com/test/");
  {
    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as a race for both the host and the URL.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).GetHost());
    expected_request.insert(GURL(full_url).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(full_url)));

    EXPECT_EQ(2u, count_hints_requests_received());
    optimization_guide::RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    histogram_tester->ExpectUniqueSample(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHostAndURL,
        1);
  }

  // Navigate again to the same webpage, no race should occur.
  {
    // Navigate to a host that was recently fetched. It
    // should be recorded as covered by the hints fetcher.
    base::flat_set<std::string> expected_request;
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(full_url)));

    // With URL-keyed Hints, every unique URL navigated to will result in a
    // hints fetch if racing is enabled and allowed.
    EXPECT_EQ(2u, count_hints_requests_received());
    optimization_guide::RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        2);

    // Only the host will be attempted to race, the fetcher should block the
    // host from being fetched.
    histogram_tester->ExpectBucketCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchNotAttempted,
        1);
  }

  // Incognito page loads should not initiate any fetches.
  {
    base::HistogramTester incognito_histogram_tester;
    // Instantiate off the record Optimization Guide Service.
    OptimizationGuideKeyedServiceFactory::GetForProfile(
        browser()->profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true))
        ->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT});

    Browser* otr_browser = CreateIncognitoBrowser(browser()->profile());
    ASSERT_TRUE(ui_test_utils::NavigateToURL(otr_browser, GURL(full_url)));

    // Make sure no additional hints requests were received.
    optimization_guide::RetryForHistogramUntilCountReached(
        &incognito_histogram_tester,
        optimization_guide::kLoadedHintLocalHistogramString, 1);
    EXPECT_EQ(2u, count_hints_requests_received());

    incognito_histogram_tester.ExpectTotalCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus", 0);
  }
}

// Test that the hints are fetched at the time of the navigation.
IN_PROC_BROWSER_TEST_F(
    HintsFetcherBrowserTest,
    HintsFetcher_NavigationFetch_FetchWithNewlyRegisteredOptType) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  optimization_guide::RetryForHistogramUntilCountReached(
      histogram_tester,
      optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
  EXPECT_EQ(1u, count_hints_requests_received());

  // Enable the network connection so the page navigation race fetch is
  // initiated.
  SetNetworkConnectionOnline();
  std::string full_url("https://foo.com/test/");
  {
    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as a race for both the host and the URL.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).GetHost());
    expected_request.insert(GURL(full_url).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(full_url)));

    EXPECT_EQ(2u, count_hints_requests_received());
    optimization_guide::RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    histogram_tester->ExpectUniqueSample(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHostAndURL,
        1);
  }

  OptimizationGuideKeyedServiceFactory::GetForProfile(
      Profile::FromBrowserContext(browser()
                                      ->tab_strip_model()
                                      ->GetActiveWebContents()
                                      ->GetBrowserContext()))
      ->RegisterOptimizationTypes(
          {optimization_guide::proto::COMPRESS_PUBLIC_IMAGES});

  // Navigate again to the same webpage, the race should occur because the
  // hints have been cleared.
  {
    // Navigate to a host that was recently fetched. It
    // should be recorded as covered by the hints fetcher.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).GetHost());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(full_url)));

    // With URL-keyed Hints, every unique URL navigated to will result in a
    // hints fetch if racing is enabled and allowed.
    EXPECT_EQ(3u, count_hints_requests_received());
    optimization_guide::RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        2);

    histogram_tester->ExpectBucketCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHost,
        1);
  }
}

// Test that the hints are fetched at the time of the navigation.
IN_PROC_BROWSER_TEST_F(
    HintsFetcherBrowserTest,
    HintsFetcher_NavigationFetch_CacheNotClearedOnLaunchedOptTypes) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  optimization_guide::RetryForHistogramUntilCountReached(
      histogram_tester,
      optimization_guide::kComponentHintsUpdatedResultHistogramString, 1);

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
  EXPECT_EQ(1u, count_hints_requests_received());

  // Enable the network connection so the page navigation race fetch is
  // initiated.
  std::string full_url("https://foo.com/test/");
  {
    // Navigate to a host not in the seeded site engagement service; it
    // should be recorded as a race for both the host and the URL.
    base::flat_set<std::string> expected_request;
    expected_request.insert(GURL(full_url).GetHost());
    expected_request.insert(GURL(full_url).spec());
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(full_url)));

    EXPECT_EQ(2u, count_hints_requests_received());
    optimization_guide::RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        1);
    histogram_tester->ExpectUniqueSample(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchHostAndURL,
        1);
  }

  OptimizationGuideKeyedServiceFactory::GetForProfile(
      Profile::FromBrowserContext(browser()
                                      ->tab_strip_model()
                                      ->GetActiveWebContents()
                                      ->GetBrowserContext()))
      ->RegisterOptimizationTypes(
          {optimization_guide::proto::DEFER_ALL_SCRIPT});

  // Navigate again to the same webpage, no race should occur.
  {
    // Navigate to a host that was recently fetched. It
    // should be recorded as covered by the hints fetcher.
    base::flat_set<std::string> expected_request;
    SetExpectedHintsRequestForHostsAndUrls(expected_request);
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(full_url)));

    // With URL-keyed Hints, every unique URL navigated to will result in a
    // hints fetch if racing is enabled and allowed.
    EXPECT_EQ(2u, count_hints_requests_received());
    optimization_guide::RetryForHistogramUntilCountReached(
        histogram_tester, optimization_guide::kLoadedHintLocalHistogramString,
        2);

    // Only the host will be attempted to race, the fetcher should block the
    // host from being fetched.
    histogram_tester->ExpectBucketCount(
        "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus",
        optimization_guide::RaceNavigationFetchAttemptStatus::
            kRaceNavigationFetchNotAttempted,
        1);
  }
}

class HintsFetcherPre3pcdBrowserTest : public HintsFetcherBrowserTest {
 public:
  HintsFetcherPre3pcdBrowserTest() {
    disabled_features_.push_back(
        content_settings::features::kTrackingProtection3pcd);
  }
};

IN_PROC_BROWSER_TEST_F(HintsFetcherPre3pcdBrowserTest,
                       HintsFetcherDoesntFetchOnNSP) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as hints fetching is enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);

  // Initiate a NSP.
  SetNetworkConnectionOnline();
  ResetCountHintsRequestsReceived();
  TriggerNoStatePrefetch(GURL("https://someotherurl.com/"));

  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsManager.RaceNavigationFetchAttemptStatus", 0);
}

class HintsFetcherSearchPageBrowserTest : public HintsFetcherBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* cmd) override {
    cmd->AppendSwitch(optimization_guide::switches::
                          kDisableFetchingHintsAtNavigationStartForTesting);
    HintsFetcherBrowserTest::SetUpCommandLine(cmd);
  }
};

// TODO(crbug.com/40919396): De-leakify and re-enable.
#if BUILDFLAG(IS_LINUX) && defined(LEAK_SANITIZER)
#define MAYBE_HintsFetcher_SRP_Slow_Connection \
  DISABLED_HintsFetcher_SRP_Slow_Connection
#else
#define MAYBE_HintsFetcher_SRP_Slow_Connection HintsFetcher_SRP_Slow_Connection
#endif
IN_PROC_BROWSER_TEST_F(HintsFetcherSearchPageBrowserTest,
                       MAYBE_HintsFetcher_SRP_Slow_Connection) {
  SetNetworkConnectionOnline();

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);

  // Populate expected hosts with hosts contained in the html response of
  // search_results_page_url(). example2.com is contained in the HTML
  // response, but hints for example2.com must not be fetched since they
  // were pushed via kFetchHintsOverride switch above.
  base::flat_set<std::string> expected_hosts_and_urls;
  // Unique hosts.
  expected_hosts_and_urls.insert(GURL("https://foo.com").GetHost());
  expected_hosts_and_urls.insert(GURL("https://example.com").GetHost());
  expected_hosts_and_urls.insert(GURL("https://example3.com").GetHost());
  // Unique URLs.
  expected_hosts_and_urls.insert("https://foo.com/");
  expected_hosts_and_urls.insert(
      "https://foo.com/simple_page_with_anchors.html");
  expected_hosts_and_urls.insert("https://example.com/foo.html");
  expected_hosts_and_urls.insert("https://example.com/bar.html");
  expected_hosts_and_urls.insert("https://example.com/baz.html");
  expected_hosts_and_urls.insert("https://example2.com/foo.html");
  expected_hosts_and_urls.insert("https://example3.com/foo.html");
  SetExpectedHintsRequestForHostsAndUrls(expected_hosts_and_urls);

  histogram_tester->ExpectTotalCount(
      optimization_guide::kLoadedHintLocalHistogramString, 0);

  // Navigate to a host not in the seeded site engagement service; it
  // should be recorded as not covered by the hints fetcher.
  ResetCountHintsRequestsReceived();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), search_results_page_url()));

  WaitUntilHintsFetcherRequestReceived();
  EXPECT_EQ(1u, count_hints_requests_received());
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
      "BatchUpdateGoogleSRP",
      3, 1);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount."
      "BatchUpdateGoogleSRP",
      7, 1);
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
                "BatchUpdateGoogleSRP",
                1),
            1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "BatchUpdateGoogleSRP",
      1);
}

class HintsFetcherSearchPagePrerenderingBrowserTest
    : public HintsFetcherSearchPageBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    HintsFetcherSearchPageBrowserTest::SetUpCommandLine(command_line);
    // |prerender_helper_| has a ScopedFeatureList so we needed to delay its
    // creation until now because HintsFetcherDisabledBrowserTest also uses a
    // ScopedFeatureList and initialization order matters.
    prerender_helper_ = std::make_unique<content::test::PrerenderTestHelper>(
        base::BindRepeating(
            &HintsFetcherSearchPagePrerenderingBrowserTest::web_contents,
            base::Unretained(this)));
  }

 protected:
  content::test::PrerenderTestHelper* prerender_helper() {
    return prerender_helper_.get();
  }

  content::WebContents* web_contents() {
    return browser()->tab_strip_model()->GetActiveWebContents();
  }

 private:
  std::unique_ptr<content::test::PrerenderTestHelper> prerender_helper_;
};

// Tests that fetching the hints for a prerendered page is deferred until the
// page gets activated.
IN_PROC_BROWSER_TEST_F(HintsFetcherSearchPagePrerenderingBrowserTest,
                       HintsFetcherFetchedHintsLoadedAfterActivate) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Allowlist NoScript for https_url()'s' host.
  SetUpComponentUpdateHints(https_url());

  // Expect that the browser initialization will record at least one sample
  // in each of the following histograms as One Platform Hints are enabled.
  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
                "BatchUpdateActiveTabs",
                1),
            1);

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", 1),
            1);
  GURL initial_url =
      GetURLWithGoogleHost(origin_server_.get(), "/iframe_blank.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.Status", net::HTTP_OK, 1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.NetErrorCode", net::OK,
      1);
  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);

  histogram_tester->ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HintCount", 1, 1);
  histogram_tester->ExpectTotalCount(
      optimization_guide::kLoadedHintLocalHistogramString, 1);

  // Load a page in the prerender.
  GURL prerender_url = search_results_page_url();
  ResetCountHintsRequestsReceived();
  content::FrameTreeNodeId host_id =
      prerender_helper()->AddPrerender(prerender_url);
  EXPECT_EQ(0u, count_hints_requests_received());
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
      "BatchUpdateGoogleSRP",
      0, 0);
  histogram_tester->ExpectTotalCount(
      optimization_guide::kLoadedHintLocalHistogramString, 1);

  // Activate the page from the prerendering.
  content::test::PrerenderHostObserver host_observer(*web_contents(), host_id);
  prerender_helper()->NavigatePrimaryPage(prerender_url);
  EXPECT_TRUE(host_observer.was_activated());
  WaitUntilHintsFetcherRequestReceived();
  EXPECT_EQ(1u, count_hints_requests_received());
  optimization_guide::RetryForHistogramUntilCountReached(
      histogram_tester, optimization_guide::kLoadedHintLocalHistogramString, 2);

  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
      "BatchUpdateGoogleSRP",
      3, 1);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount."
      "BatchUpdateGoogleSRP",
      7, 1);
}

class HintsFetcherSearchPageDisabledBrowserTest
    : public HintsFetcherDisabledBrowserTest {
 public:
  HintsFetcherSearchPageDisabledBrowserTest() = default;
  void SetUp() override {
    std::vector<base::test::FeatureRefAndParams> enabled_features = {
        {optimization_guide::features::kOptimizationHints, {}},
        {blink::features::kNavigationPredictor,
         {{"random_anchor_sampling_period", "1"},
          {"traffic_client_enabled_percent", "100"}}},
        {*optimization_guide::kHintsMaxConcurrentNavigationFetches.feature,
         {{optimization_guide::kHintsMaxConcurrentNavigationFetches.name,
           "2"}}},
        {optimization_guide::kHintsBatchUpdateForActiveTabsAndTopHosts, {}},
    };
    scoped_feature_list_.InitWithFeaturesAndParameters(
        enabled_features,
        // Disabled.
        {optimization_guide::features::kOptimizationGuideFetchingForSRP});
    HintsFetcherDisabledBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // Register an optimization type, so hints will be fetched at page
    // navigation.
    OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
        ->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT});

    HintsFetcherDisabledBrowserTest::SetUpOnMainThread();
  }
};

IN_PROC_BROWSER_TEST_F(HintsFetcherSearchPageDisabledBrowserTest,
                       HintsFetcherStillFetchesNavigations) {
  SetNetworkConnectionOnline();
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Navigate to a search results page - should not result in a request with
  // more than 1 url.
  ResetCountHintsRequestsReceived();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), search_results_page_url()));

  // Technically the results page counts as a navigation URL.
  base::flat_set<std::string> srp_request;
  srp_request.insert(GURL(search_results_page_url()).GetHost());
  srp_request.insert(GURL(search_results_page_url()).spec());
  SetExpectedHintsRequestForHostsAndUrls(srp_request);
  EXPECT_EQ(1u, count_hints_requests_received());
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
      "PageNavigation",
      1, 1);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount."
      "PageNavigation",
      1, 1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "PageNavigation",
      1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "BatchUpdateGoogleSRP",
      0);

  // Now go to a regular URL.
  ResetCountHintsRequestsReceived();
  std::string full_url = "https://foo.com/test/";
  base::flat_set<std::string> expected_request;
  expected_request.insert(GURL(full_url).GetHost());
  expected_request.insert(GURL(full_url).spec());
  SetExpectedHintsRequestForHostsAndUrls(expected_request);
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(full_url)));

  optimization_guide::RetryForHistogramUntilCountReached(
      histogram_tester, optimization_guide::kLoadedHintLocalHistogramString, 1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "PageNavigation",
      2);
  EXPECT_EQ(1u, count_hints_requests_received());
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
      "PageNavigation",
      1, 2);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount."
      "PageNavigation",
      1, 2);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "PageNavigation",
      2);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "BatchUpdateGoogleSRP",
      0);
}

// Tests that OptimizationGuideWebContentsObserver limits the results for SRP.
//
// Note that `OptimizationGuideWebContentsObserver::FetchHintsUsingManager`
// limits the urls to `optimization_guide::features::MaxResultsForSRPFetch()`.
// In this test, this method is called with the following URLs but the order
// varies:
//
// - https://example.com/bar.html
// - https://example.com/baz.html
// - https://example.com/foo.html
// - https://example2.com/foo.html
// - https://example3.com/foo.html
// - https://foo.com/
// - https://foo.com/simple_page_with_anchors.html
//
// If we use `max_urls_for_srp_fetch > 1`, the result of
// `OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount` varies. So, we use
// `max_urls_for_srp_fetch = 1`.
class HintsFetcherSearchPageLimitedURLsBrowserTest
    : public HintsFetcherDisabledBrowserTest {
 public:
  HintsFetcherSearchPageLimitedURLsBrowserTest() = default;

  void SetUp() override {
    std::vector<base::test::FeatureRefAndParams> enabled_features = {
        {optimization_guide::features::kOptimizationHints, {}},
        {
            optimization_guide::features::kOptimizationGuideFetchingForSRP,
            {{"max_urls_for_srp_fetch", "1"}},
        },
        {*optimization_guide::kHintsMaxConcurrentNavigationFetches.feature,
         {{optimization_guide::kHintsMaxConcurrentNavigationFetches.name,
           "2"}}},
        {optimization_guide::kHintsBatchUpdateForActiveTabsAndTopHosts, {}},
    };
    scoped_feature_list_.InitWithFeaturesAndParameters(enabled_features, {});

    HintsFetcherDisabledBrowserTest::SetUp();
  }

  void SetUpCommandLine(base::CommandLine* cmd) override {
    cmd->AppendSwitch(optimization_guide::switches::
                          kDisableFetchingHintsAtNavigationStartForTesting);
    HintsFetcherDisabledBrowserTest::SetUpCommandLine(cmd);
  }

  void SetUpOnMainThread() override {
    // Register an optimization type, so hints will be fetched at page
    // navigation.
    OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
        ->RegisterOptimizationTypes({optimization_guide::proto::NOSCRIPT});

    HintsFetcherDisabledBrowserTest::SetUpOnMainThread();
  }
};

// TODO(crbug.com/40067071): Disable limited SRP test on Windows/CrOS for now.
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS)
#define MAYBE_HintsFetcherLimitedResults DISABLED_HintsFetcherLimitedResults
#else
#define MAYBE_HintsFetcherLimitedResults HintsFetcherLimitedResults
#endif
IN_PROC_BROWSER_TEST_F(HintsFetcherSearchPageLimitedURLsBrowserTest,
                       MAYBE_HintsFetcherLimitedResults) {
  SetNetworkConnectionOnline();
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  const base::HistogramTester* histogram_tester = GetHistogramTester();

  // Navigate to a search results page - should result a batch request with up
  // to 2 urls.
  ResetCountHintsRequestsReceived();
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), search_results_page_url()));
  WaitUntilHintsFetcherRequestReceived();

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
                "BatchUpdateGoogleSRP",
                1),
            1);
  EXPECT_EQ(1u, count_hints_requests_received());
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.HostCount."
      "BatchUpdateGoogleSRP",
      1, 1);
  histogram_tester->ExpectBucketCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.UrlCount."
      "BatchUpdateGoogleSRP",
      1, 1);
  histogram_tester->ExpectTotalCount(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "BatchUpdateGoogleSRP",
      1);
}

class PersonalizedHintsFetcherBrowserTest : public HintsFetcherBrowserTest {
 public:
  PersonalizedHintsFetcherBrowserTest() = default;

  PersonalizedHintsFetcherBrowserTest(
      const PersonalizedHintsFetcherBrowserTest&) = delete;
  PersonalizedHintsFetcherBrowserTest& operator=(
      const HintsFetcherBrowserTest&) = delete;

  ~PersonalizedHintsFetcherBrowserTest() override = default;

  void SetUpBrowserContextKeyedServices(
      content::BrowserContext* context) override {
    HintsFetcherBrowserTest::SetUpBrowserContextKeyedServices(context);
    IdentityTestEnvironmentProfileAdaptor::
        SetIdentityTestEnvironmentFactoriesOnBrowserContext(context);
  }

  void SetUpOnMainThread() override {
    HintsFetcherBrowserTest::SetUpOnMainThread();
    identity_test_env_adaptor_ =
        std::make_unique<IdentityTestEnvironmentProfileAdaptor>(
            browser()->profile());
  }

  void EnableSignin() {
    identity_test_env_adaptor_->identity_test_env()
        ->MakePrimaryAccountAvailable("user@gmail.com",
                                      signin::ConsentLevel::kSignin);
    identity_test_env_adaptor_->identity_test_env()
        ->SetAutomaticIssueOfAccessTokens(true);
  }

  void CanApplyOptimizationOnDemand(
      optimization_guide::proto::OptimizationType optimization_type,
      optimization_guide::proto::RequestContext request_context) {
    std::unique_ptr<base::RunLoop> run_loop = std::make_unique<base::RunLoop>();
    OptimizationGuideKeyedServiceFactory::GetForProfile(browser()->profile())
        ->CanApplyOptimizationOnDemand(
            {GURL("https://example.com")}, {optimization_type}, request_context,
            base::BindRepeating(
                [](optimization_guide::proto::OptimizationType
                       optimization_type,
                   base::RunLoop* run_loop, const GURL& url,
                   const base::flat_map<
                       optimization_guide::proto::OptimizationType,
                       optimization_guide::
                           OptimizationGuideDecisionWithMetadata>& decisions) {
                  // Expect one decision per requested type.
                  EXPECT_EQ(decisions.size(), 1u);
                  auto it = decisions.find(optimization_type);
                  EXPECT_NE(it, decisions.end());
                  EXPECT_EQ(
                      it->second.decision,
                      optimization_guide::OptimizationGuideDecision::kFalse);

                  run_loop->Quit();
                },
                optimization_type, run_loop.get()));
    run_loop->Run();
  }

 private:
  // Identity test support.
  std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
      identity_test_env_adaptor_;
};

IN_PROC_BROWSER_TEST_F(PersonalizedHintsFetcherBrowserTest, NoUserSignIn) {
  base::HistogramTester histogram_tester;
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  // No access token set when user is not signed in.
  SetExpectedBearerAccessToken(std::string());
  CanApplyOptimizationOnDemand(
      optimization_guide::proto::OptimizationType::NOSCRIPT,
      optimization_guide::proto::CONTEXT_PAGE_INSIGHTS_HUB);
  histogram_tester.ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "PageInsightsHub",
      optimization_guide::FetcherRequestStatus::kSuccess, 1);
}

IN_PROC_BROWSER_TEST_F(PersonalizedHintsFetcherBrowserTest, UserSignedIn) {
  base::HistogramTester histogram_tester;
  EnableSignin();
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  SetExpectedBearerAccessToken("Bearer access_token");
  CanApplyOptimizationOnDemand(
      optimization_guide::proto::OptimizationType::NOSCRIPT,
      optimization_guide::proto::CONTEXT_PAGE_INSIGHTS_HUB);
  histogram_tester.ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
      "PageInsightsHub",
      optimization_guide::FetcherRequestStatus::kSuccess, 1);

  // Only the enabled RequestContext will have access token enabled.
  SetExpectedBearerAccessToken(std::string());
  CanApplyOptimizationOnDemand(
      optimization_guide::proto::OptimizationType::NOSCRIPT,
      optimization_guide::proto::CONTEXT_JOURNEYS);
  histogram_tester.ExpectUniqueSample(
      "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus.Journeys",
      optimization_guide::FetcherRequestStatus::kSuccess, 1);
}

// TODO(crbug.com/425936619): Add checks for url, hint counts, context.
class ProactivePersonalizationHintsFetcherBrowserTest
    : public HintsFetcherBrowserTest {
 public:
  ProactivePersonalizationHintsFetcherBrowserTest() = default;

  ProactivePersonalizationHintsFetcherBrowserTest(
      const ProactivePersonalizationHintsFetcherBrowserTest&) = delete;
  ProactivePersonalizationHintsFetcherBrowserTest& operator=(
      const ProactivePersonalizationHintsFetcherBrowserTest&) = delete;

  ~ProactivePersonalizationHintsFetcherBrowserTest() override = default;

  void SetUpBrowserContextKeyedServices(
      content::BrowserContext* context) override {
    HintsFetcherBrowserTest::SetUpBrowserContextKeyedServices(context);
    IdentityTestEnvironmentProfileAdaptor::
        SetIdentityTestEnvironmentFactoriesOnBrowserContext(context);
  }

  void SetUpOnMainThread() override {
    HintsFetcherBrowserTest::SetUpOnMainThread();
    identity_test_env_adaptor_ =
        std::make_unique<IdentityTestEnvironmentProfileAdaptor>(
            browser()->profile());
  }

  void PopulateEnabledFeatures(
      std::vector<base::test::FeatureRefAndParams>* enabled_features) override {
    base::FieldTrialParams personalized_fetching_params = GetFieldTrialParams();
    enabled_features->emplace_back(
        optimization_guide::features::
            kOptimizationGuideProactivePersonalizedHintsFetching,
        personalized_fetching_params);
  }

  virtual base::FieldTrialParams GetFieldTrialParams() {
    return {
        {"allowed_optimization_types", "NOSCRIPT"},
    };
  }

  void EnableSignin() {
    identity_test_env_adaptor_->identity_test_env()
        ->MakePrimaryAccountAvailable("user@gmail.com",
                                      signin::ConsentLevel::kSignin);
    identity_test_env_adaptor_->identity_test_env()
        ->SetAutomaticIssueOfAccessTokens(true);
  }

 private:
  // Identity test support.
  std::unique_ptr<IdentityTestEnvironmentProfileAdaptor>
      identity_test_env_adaptor_;
};

// Verify access token is attached during navigation fetching if a
// personalizable optimization type is requested.
IN_PROC_BROWSER_TEST_F(ProactivePersonalizationHintsFetcherBrowserTest,
                       OnNavigationFetchesWithAccessToken) {
  SetNetworkConnectionOnline();
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  ResetCountHintsRequestsReceived();
  EnableSignin();
  SetExpectedBearerAccessToken("Bearer access_token");

  GURL full_url = GURL("https://foo.com/test/");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), full_url));

  base::flat_set<std::string> expected_request;
  expected_request.insert(full_url.GetHost());
  expected_request.insert(full_url.spec());
  SetExpectedHintsRequestForHostsAndUrls(expected_request);
  EXPECT_EQ(1u, count_hints_requests_received());
}

// Verify access token is attached during active tab fetching if a
// personalizable optimization type is requested.
IN_PROC_BROWSER_TEST_F(ProactivePersonalizationHintsFetcherBrowserTest,
                       ActiveTabFetchesWithAccessToken) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  EnableSignin();
  SetExpectedBearerAccessToken("Bearer access_token");

  SetUpComponentUpdateHints(https_url());

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
                "BatchUpdateActiveTabs",
                1),
            1);
}

// Verify access token is attached during url fetching if a
// personalizable optimization type is requested.
// TODO(crbug.com/40919396): De-leakify and re-enable.
#if BUILDFLAG(IS_LINUX) && defined(LEAK_SANITIZER)
#define MAYBE_FetchingUrlFetchesWithAccessToken \
  DISABLED_FetchingUrlFetchesWithAccessToken
#else
#define MAYBE_FetchingUrlFetchesWithAccessToken \
  FetchingUrlFetchesWithAccessToken
#endif
IN_PROC_BROWSER_TEST_F(ProactivePersonalizationHintsFetcherBrowserTest,
                       MAYBE_FetchingUrlFetchesWithAccessToken) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  EnableSignin();
  SetExpectedBearerAccessToken("Bearer access_token");

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), search_results_page_url()));

  WaitUntilHintsFetcherRequestReceived();

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
                "BatchUpdateGoogleSRP",
                1),
            1);
}

class ProactivePersonalizationNoAllowedTypesHintsFetcherBrowserTest
    : public ProactivePersonalizationHintsFetcherBrowserTest {
 public:
  base::FieldTrialParams GetFieldTrialParams() override {
    return {
        {"allowed_optimization_types", "PERFORMANCE_HINTS"},
    };
  }
};

// Verify access token is not attached during navigation fetching if no
// personalizable optimization type is requested.
IN_PROC_BROWSER_TEST_F(
    ProactivePersonalizationNoAllowedTypesHintsFetcherBrowserTest,
    OnNavigationDoesNotFetchAccessToken) {
  SetNetworkConnectionOnline();
  SetResponseType(
      optimization_guide::HintsFetcherRemoteResponseType::kSuccessful);

  ResetCountHintsRequestsReceived();
  EnableSignin();
  SetExpectedBearerAccessToken(std::string());

  GURL full_url = GURL("https://foo.com/test/");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), full_url));

  base::flat_set<std::string> expected_request;
  expected_request.insert(full_url.GetHost());
  expected_request.insert(full_url.spec());
  SetExpectedHintsRequestForHostsAndUrls(expected_request);
  EXPECT_EQ(1u, count_hints_requests_received());
}

// Verify access token is not attached during active tab fetching if no
// personalizable optimization type is requested.
IN_PROC_BROWSER_TEST_F(
    ProactivePersonalizationNoAllowedTypesHintsFetcherBrowserTest,
    ActiveTabDoesNotFetchWithAccessToken) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();
  EnableSignin();
  SetExpectedBearerAccessToken(std::string());

  SetUpComponentUpdateHints(https_url());

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
                "BatchUpdateActiveTabs",
                1),
            1);
}

// Verify access token is not attached during url fetching if no personalizable
// optimization type is requested.
// TODO(crbug.com/40919396): De-leakify and re-enable.
#if BUILDFLAG(IS_LINUX) && defined(LEAK_SANITIZER)
#define MAYBE_FetchingUrlDoesNotFetchWithAccessToken \
  DISABLED_FetchingUrlDoesNotFetchWithAccessToken
#else
#define MAYBE_FetchingUrlDoesNotFetchWithAccessToken \
  FetchingUrlDoesNotFetchWithAccessToken
#endif
IN_PROC_BROWSER_TEST_F(
    ProactivePersonalizationNoAllowedTypesHintsFetcherBrowserTest,
    MAYBE_FetchingUrlDoesNotFetchWithAccessToken) {
  const base::HistogramTester* histogram_tester = GetHistogramTester();

  EnableSignin();
  SetExpectedBearerAccessToken(std::string());

  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), search_results_page_url()));

  WaitUntilHintsFetcherRequestReceived();

  EXPECT_GE(optimization_guide::RetryForHistogramUntilCountReached(
                histogram_tester,
                "OptimizationGuide.HintsFetcher.GetHintsRequest.RequestStatus."
                "BatchUpdateGoogleSRP",
                1),
            1);
}
