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

#include <algorithm>
#include <memory>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/simple_test_clock.h"
#include "build/build_config.h"
#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/extensions/api/settings_private/generated_prefs.h"
#include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
#include "chrome/browser/preloading/scoped_prewarm_feature_list.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/chrome_security_blocking_page_factory.h"
#include "chrome/browser/ssl/generated_https_first_mode_pref.h"
#include "chrome/browser/ssl/https_first_mode_settings_tracker.h"
#include "chrome/browser/ssl/https_upgrades_interceptor.h"
#include "chrome/browser/ssl/https_upgrades_navigation_throttle.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "chrome/browser/ui/omnibox/omnibox_controller.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/captive_portal/content/captive_portal_service.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/embedder_support/pref_names.h"
#include "components/omnibox/browser/omnibox_client.h"
#include "components/prefs/pref_service.h"
#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h"
#include "components/security_interstitials/core/features.h"
#include "components/security_interstitials/core/https_only_mode_metrics.h"
#include "components/security_interstitials/core/metrics_helper.h"
#include "components/security_state/content/security_state_tab_helper.h"
#include "components/site_engagement/content/site_engagement_service.h"
#include "components/strings/grit/components_strings.h"
#include "components/ukm/test_ukm_recorder.h"
#include "components/variations/active_field_trials.h"
#include "components/variations/hashing.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/content_mock_cert_verifier.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_util.h"
#include "net/test/cert_test_util.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/request_handler_util.h"
#include "net/test/test_data_directory.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_source.h"
#include "services/network/public/cpp/ip_address_space_overrides_test_utils.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/ip_address_space.mojom.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/url_constants.h"

using chrome_browser_interstitials::HFMInterstitialType;
using security_interstitials::https_only_mode::BlockingResult;
using security_interstitials::https_only_mode::Event;
using security_interstitials::https_only_mode::InterstitialReason;
using security_interstitials::https_only_mode::kEventHistogram;
using security_interstitials::https_only_mode::
    kEventHistogramWithEngagementHeuristic;
using security_interstitials::https_only_mode::kInterstitialReasonHistogram;
using security_interstitials::https_only_mode::
    kNavigationRequestSecurityLevelHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicAccumulatedHostCountHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicEnforcementDurationHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicHostCountHistogram;
using security_interstitials::https_only_mode::
    kSiteEngagementHeuristicStateHistogram;
using security_interstitials::https_only_mode::NavigationRequestSecurityLevel;
using security_interstitials::https_only_mode::SiteEngagementHeuristicState;
using UkmEntry = ukm::builders::HttpsFirstMode_Event;

// Many of the following tests have only minor variations for HTTPS-First Mode
// vs. HTTPS-Upgrades. These get parameterized so the tests run under both
// versions on their own as well as when both HTTPS Upgrades and HTTPS-First
// Mode are enabled (to test any interactions between the two upgrade modes).
// HTTPS-Upgrades is now enabled by default, so all of these variations build
// on top of that baseline.
//
// Quick summary of all features tested here:
// * HTTPS-Upgrades:
//     Automatically upgrades main frame navigations to HTTPS. Silently falls
//     back to HTTP on failure.
// * HTTPS First Mode:
//     Automatically upgrades main frame navigations to HTTPS. Shows an
//     interstitial on failure.
// * HTTPS First Mode With Site Engagement:
//     Automatically enables HTTPS First Mode for sites that are visited mainly
//     over HTTPS.
// * HTTPS First Mode for Typically Secure Users
//     Automatically enables HTTPS First Mode for users that mainly visit HTTPS
//     sites.
// * HTTPS First Mode in Incognito:
//     Automatically enables HTTPS First Mode in Incognito windows.
// * HTTPS First Balanced Mode:
//     Enables HTTPS First Mode like full HFM, but exempt navigations that are
//     likely to fail.
//
enum class HttpsUpgradesTestType {
  // Enables the HFM pref.
  kHttpsFirstModeOnly,

  // Enables HFM with Site Engagement heuristic.
  kHttpsFirstModeWithSiteEngagement,

  // Enables HFM for Typically Secure Users.
  kHttpsFirstModeForTypicallySecureUsers,

  // Enables HFM with Site Engagement and HFM for Typically Secure Users (both
  // automatically enable HFM). Disables BalancedModeByDefault as that case is
  // already tested by kHttpsFirstBalancedMode.
  kAllAutoHFM,

  // Enables HFM in Incognito mode. Runs testcases inside an Incognito
  // window.
  kHttpsFirstModeIncognito,

  // Enables HFM in balanced mode.
  kHttpsFirstBalancedMode,

  // Enables HFM pref, HFM with Site Engagement heuristic, HFM for typically
  // secure users, HFM in incognito, and balanced HFM feature flags.
  kAll,

  // Disables HFM pref, HFM with Site Engagement heuristic, the HFM for
  // typically secure users feature, and the HFM in Incognito feature.
  kNone,

  // HttpsUpgradesBrowserTest tests don't run in these modes. They are used to
  // instantiate individual tests instead:

  // Enables HFM with Site Engagement heuristic without Balanced Mode. This
  // should be a no-op.
  kHttpsFirstModeWithSiteEngagementWithoutBalancedMode,
};

// Stores the number of times the HTTPS-First Mode interstitial is shown for the
// given reason.
struct ExpectedInterstitialReasons {
  // The number of times the interstitial was shown because the HFM pref was
  // enabled.
  size_t pref = 0;
  // The number of times the interstitial was shown because of the Typically
  // Secure User heuristic.
  size_t typically_secure_user = 0;
  // The number of times the interstitial was shown because of being in balanced
  // mode.
  size_t balanced = 0;
};

// A very low site engagement score.
constexpr int kLowSiteEngagementScore = 1;
// A very high site engagement score.
constexpr int kHighSiteEnagementScore = 99;

// Tests for HTTPS-Upgrades and the v2 implementation of HTTPS-First Mode.
class HttpsUpgradesBrowserTest
    : public testing::WithParamInterface<HttpsUpgradesTestType>,
      public InProcessBrowserTest {
 public:
  HttpsUpgradesBrowserTest() = default;
  ~HttpsUpgradesBrowserTest() override = default;

  void SetUp() override {
    // HFM heuristics are disabled on enterprise managed machines, so some of
    // the tests may fail on bots. Explicitly set management status to false.
    // Some of the tests check enterprise policies, so this configuration is
    // unusual because non-enterprise machines are unlikely to have an
    // enterprise allowlist, but it's good for test coverage.
    ChromeSecurityBlockingPageFactory::SetEnterpriseManagedForTesting(false);

    // HFM is controlled by a pref (configured in SetUpOnMainThread).
    switch (https_upgrades_test_type()) {
      case HttpsUpgradesTestType::kHttpsFirstModeOnly:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      case HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstModeV2ForEngagedSites,
                                  features::kHttpsFirstBalancedMode},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstBalancedModeAutoEnable,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      case HttpsUpgradesTestType::
          kHttpsFirstModeWithSiteEngagementWithoutBalancedMode:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstModeV2ForEngagedSites},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstBalancedMode,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      case HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::
                                      kHttpsFirstModeV2ForTypicallySecureUsers,
                                  features::kHttpsFirstBalancedMode},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstBalancedModeAutoEnable,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      case HttpsUpgradesTestType::kAllAutoHFM:
        // HFM pref is disabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::
                                      kHttpsFirstModeV2ForTypicallySecureUsers,
                                  features::kHttpsFirstModeV2ForEngagedSites,
                                  features::kHttpsFirstBalancedMode},
            /*disabled_features=*/{
                features::kHttpsFirstBalancedModeAutoEnable,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      case HttpsUpgradesTestType::kHttpsFirstModeIncognito:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstModeIncognito},
            /*disabled_features=*/{
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      case HttpsUpgradesTestType::kHttpsFirstBalancedMode:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstBalancedMode,
                                  features::kHttpsFirstBalancedModeAutoEnable},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstModeV2ForEngagedSites,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      // Enable HFM, HFM with Site Engagement heuristic, HFM for typically
      // secure users, and HFM in Incognito.
      case HttpsUpgradesTestType::kAll:
        // HFM pref is enabled in SetUpOnMainThread.
        feature_list_.InitWithFeatures(
            /*enabled_features=*/
            {
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstModeForAdvancedProtectionUsers,
                features::kHttpsFirstModeIncognito,
                features::kHttpsFirstBalancedMode,
                features::kHttpsFirstBalancedModeAutoEnable,
            },
            /*disabled_features=*/{
                security_interstitials::features::kHttpsFirstDialogUi});
        break;

      // Disable HFM, HFM with Site Engagement heuristic, HFM for Typically
      // Secure Users, and HFM in Incognito. (HFM pref is disabled in
      // SetUpOnMainThread.) This is equivalent to the baseline default of
      // HTTPS-Upgrades.
      case HttpsUpgradesTestType::kNone:
        feature_list_.InitWithFeatures(
            /*enabled_features=*/{},
            /*disabled_features=*/{
                features::kHttpsFirstModeV2ForEngagedSites,
                features::kHttpsFirstModeV2ForTypicallySecureUsers,
                features::kHttpsFirstBalancedMode,
                features::kHttpsFirstBalancedModeAutoEnable,
                security_interstitials::features::kHttpsFirstDialogUi});
        break;
    }

    InProcessBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    // By default allow all hosts on HTTPS.
    mock_cert_verifier_.mock_cert_verifier()->set_default_result(net::OK);
    host_resolver()->AddRule("*", "127.0.0.1");

    // Set up "bad-https.com", "bad-https2.com", "nonunique-hostname-bad-https"
    // and "nonunique-hostname-bad-https2" as hostnames with an SSL error.
    // HTTPS upgrades to these hosts will fail.
    scoped_refptr<net::X509Certificate> cert(https_server_.GetCertificate());
    net::CertVerifyResult verify_result;
    verify_result.is_issued_by_known_root = false;
    verify_result.verified_cert = cert;
    verify_result.cert_status = net::CERT_STATUS_COMMON_NAME_INVALID;
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "bad-https.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "www.bad-https.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "bad-https2.com", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "nonunique-hostname-bad-https", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);
    mock_cert_verifier_.mock_cert_verifier()->AddResultForCertAndHost(
        cert, "nonunique-hostname-bad-https2", verify_result,
        net::ERR_CERT_COMMON_NAME_INVALID);

    http_server_.AddDefaultHandlers(GetChromeTestDataDir());
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(http_server_.Start());
    ASSERT_TRUE(https_server_.Start());

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server()->port());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server()->port());

    // Incognito tests swap out the default Browser instance for an Incognito
    // window, and then should behave like kHttpsFirstMode type tests but
    // without enabling the full HFM pref.
    if (https_upgrades_test_type() ==
        HttpsUpgradesTestType::kHttpsFirstModeIncognito) {
      UseIncognitoBrowser();
      SetPref(false);
    }

    // Only enable the HTTPS-First Mode pref when the test config calls for it.
    // Some of the HFM heuristics check that the preference wasn't set so as
    // not to override user preference (e.g. if the user changed the pref by
    // turning it off from the UI, we don't want to override it).
    if (IsHttpsFirstModePrefEnabled()) {
      SetPref(true);
    }

    if (InBalancedMode()) {
      SetBalancedPref(true);
    }

    test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
  }

  void TearDownOnMainThread() override {
    browser()->profile()->GetPrefs()->ClearPref(prefs::kHttpsOnlyModeEnabled);
    browser()->profile()->GetPrefs()->ClearPref(
        prefs::kHttpsOnlyModeAutoEnabled);
    browser()->profile()->GetPrefs()->ClearPref(prefs::kHttpsUpgradeFallbacks);
    browser()->profile()->GetPrefs()->ClearPref(
        prefs::kHttpsUpgradeNavigations);
    browser()->profile()->GetPrefs()->ClearPref(prefs::kHttpsFirstBalancedMode);

    HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
    HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    mock_cert_verifier_.SetUpCommandLine(command_line);
  }

  void SetUpInProcessBrowserTestFixture() override {
    mock_cert_verifier_.SetUpInProcessBrowserTestFixture();
  }

  void TearDownInProcessBrowserTestFixture() override {
    mock_cert_verifier_.TearDownInProcessBrowserTestFixture();
  }

  // Incognito testing support
  //
  // Returns the active Browser for the test type being run.
  Browser* GetBrowser() const {
    return incognito_browser_ ? incognito_browser_.get() : browser();
  }
  // Call to use an Incognito browser rather than the default.
  void UseIncognitoBrowser() {
    ASSERT_EQ(nullptr, incognito_browser_.get());
    incognito_browser_ = CreateIncognitoBrowser();
  }
  bool IsIncognito() const { return incognito_browser_ != nullptr; }
  bool OnlyInBalancedMode() const {
    return https_upgrades_test_type() ==
           HttpsUpgradesTestType::kHttpsFirstBalancedMode;
  }
  bool InBalancedMode() const {
    return https_upgrades_test_type() ==
               HttpsUpgradesTestType::kHttpsFirstBalancedMode ||
           https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
  }

 protected:
  HttpsUpgradesTestType https_upgrades_test_type() const { return GetParam(); }

  void SetPref(bool enabled) {
    auto* prefs = browser()->profile()->GetPrefs();
    prefs->SetBoolean(prefs::kHttpsOnlyModeEnabled, enabled);
  }

  bool GetPref() const {
    auto* prefs = browser()->profile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled);
  }

  void SetBalancedPref(bool enabled) {
    auto* prefs = browser()->profile()->GetPrefs();
    prefs->SetBoolean(prefs::kHttpsFirstBalancedMode, enabled);
  }

  bool GetBalancedPref() const {
    auto* prefs = browser()->profile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsFirstBalancedMode);
  }

  void ProceedThroughInterstitial(content::WebContents* tab) {
    content::TestNavigationObserver nav_observer(tab, 1);
    std::string javascript = "window.certificateErrorPageController.proceed();";
    ASSERT_TRUE(content::ExecJs(tab, javascript));
    nav_observer.Wait();
  }

  void DontProceedThroughInterstitial(content::WebContents* tab) {
    content::TestNavigationObserver nav_observer(tab, 1);
    std::string javascript =
        "window.certificateErrorPageController.dontProceed();";
    ASSERT_TRUE(content::ExecJs(tab, javascript));
    nav_observer.Wait();
  }

  void NavigateAndWaitForFallback(content::WebContents* tab, const GURL& url) {
    // TODO(crbug.com/40248833): With fallback as part of the same navigation,
    // this helper is no longer particularly useful. Consider updating callers.
    content::NavigateToURLBlockUntilNavigationsComplete(tab, url, 1);
  }

  // Whether HFM is enabled by the UI setting.
  bool IsHttpsFirstModePrefEnabled() const {
    return https_upgrades_test_type() ==
               HttpsUpgradesTestType::kHttpsFirstModeOnly ||
           https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
  }

  // Whether HFM is enabled for many sites, and thus the tests should run steps
  // that assume the HTTP interstitial will trigger (i.e., for fallback HTTP
  // navigations when HTTPS-First Mode is enabled).
  bool IsHttpsFirstModeInterstitialEnabledAcrossSites() const {
    return IsHttpsFirstModePrefEnabled() || InBalancedMode() || IsIncognito();
  }

  // Whether HTTPS-First Mode with Site Engagement Heuristic is enabled. When
  // enabled, this feature will enable HFM on sites that have high Site
  // Engagement scores on their HTTPS URLs. HFM with Site Engagement requires
  // HTTPS-Upgrades to be enabled.
  bool IsSiteEngagementHeuristicEnabled() const {
    bool enabled =
        https_upgrades_test_type() ==
            HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAllAutoHFM ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
    return enabled;
  }

  // Whether automatic HTTPS-First Mode for typically secure users is enabled.
  // When enabled, this feature will enable HFM for users who would see HFM
  // warnings very rarely. HFM for typically secure users requires
  // HTTPS-Upgrades to be enabled.
  bool IsTypicallySecureUserFeatureEnabled() const {
    bool enabled =
        https_upgrades_test_type() ==
            HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAllAutoHFM ||
        https_upgrades_test_type() == HttpsUpgradesTestType::kAll;
    return enabled;
  }

  void SetSiteEngagementScore(const GURL& url, double score) {
    site_engagement::SiteEngagementService* service =
        site_engagement::SiteEngagementService::Get(browser()->profile());
    service->ResetBaseScoreForURL(url, score);
    ASSERT_EQ(score, service->GetScore(url));
  }

  // Checks that the HTTPS-First Mode interstitial has been shown for the
  // correct reasons.
  void CheckInterstitialReasonHistogram(
      const ExpectedInterstitialReasons& expected_reasons) {
    histograms()->ExpectTotalCount(kInterstitialReasonHistogram,
                                   expected_reasons.pref +
                                       expected_reasons.typically_secure_user +
                                       expected_reasons.balanced);
    histograms()->ExpectBucketCount(kInterstitialReasonHistogram,
                                    static_cast<int>(InterstitialReason::kPref),
                                    expected_reasons.pref);
    histograms()->ExpectBucketCount(
        kInterstitialReasonHistogram,
        static_cast<int>(InterstitialReason::kBalanced),
        expected_reasons.balanced);
    histograms()->ExpectBucketCount(
        kInterstitialReasonHistogram,
        static_cast<int>(InterstitialReason::kTypicallySecureUserHeuristic),
        expected_reasons.typically_secure_user);
  }

  // Verifies that an HFM interstitial is shown.
  void ExpectInterstitial(content::WebContents* contents) {
    EXPECT_EQ(HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  }

  // Verifies that an HFM interstitial is shown only if the HFM-pref is enabled
  // or we're in balanced mode.
  void ExpectInterstitialOnlyIfPrefIsSetOrInBalancedMode(
      content::WebContents* contents) {
    if (IsHttpsFirstModePrefEnabled() || InBalancedMode()) {
      ExpectInterstitial(contents);
    } else {
      EXPECT_FALSE(
          chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
              contents));
    }
  }

  // Verifies that an HFM interstitial is shown either due to prefs being
  // enabled or typically secure heuristic.
  void MaybeExpectTypicallySecureInterstitial(content::WebContents* contents) {
    if (IsHttpsFirstModePrefEnabled() || InBalancedMode() ||
        IsTypicallySecureUserFeatureEnabled()) {
      // Typically secure interstitial should only be shown iff HFM is not
      // enabled by prefs.
      if (IsTypicallySecureUserFeatureEnabled() &&
          !IsHttpsFirstModePrefEnabled() && !InBalancedMode()) {
        EXPECT_EQ(
            HFMInterstitialType::kTypicallySecure,
            chrome_browser_interstitials::GetHFMInterstitialType(contents));
      } else {
        // Otherwise, interstitial is enabled by prefs.
        EXPECT_EQ(
            HFMInterstitialType::kStandard,
            chrome_browser_interstitials::GetHFMInterstitialType(contents));
      }
      return;
    }
    // Interstitial isn't enabled by the prefs or heuristic.
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }

  base::SimpleTestClock* GetTestClock() { return &test_clock_; }

  // Prepare the profile so that HFM can be automatically enabled.
  void SatisfyTypicallySecureHeuristicRequirements() {
    base::SimpleTestClock* clock = GetTestClock();

    // The total engagement score of all sites must be over a certain threshold.
    SetSiteEngagementScore(GURL("https://google.com:12345"), 90);

    // Profile must be old enough.
    browser()->profile()->SetCreationTimeForTesting(clock->Now() -
                                                    base::Days(30));
    hfm_service()->SetClockForTesting(clock);

    // There must be a lot of recorded navigations.
    for (size_t i = 0; i < 1500; i++) {
      hfm_service()->IncrementRecentNavigationCount();
    }
    clock->Advance(base::Days(15));

    // Navigate to an HTTP URL that will upgrade and fall back to HTTP.
    // This will start Typically Secure observation.
    GURL http_url("http://bad-https2.com/simple.html");
    content::WebContents* contents =
        GetBrowser()->tab_strip_model()->GetActiveWebContents();
    content::NavigateToURLBlockUntilNavigationsComplete(
        contents, http_url, /*number_of_navigations=*/1);
    ExpectInterstitialOnlyIfPrefIsSetOrInBalancedMode(contents);

    // Advance the clock and navigate to an HTTP URL again. This will drop the
    // first fallback event.
    clock->Advance(base::Days(35));
  }

  net::EmbeddedTestServer* http_server() { return &http_server_; }
  net::EmbeddedTestServer* https_server() { return &https_server_; }
  base::HistogramTester* histograms() { return &histograms_; }
  base::test::ScopedFeatureList* feature_list() { return &feature_list_; }

  HttpsFirstModeService* hfm_service() const {
    return HttpsFirstModeServiceFactory::GetForProfile(browser()->profile());
  }

  // Checks that the interstitial UKM has an entry for `url` and `result`.
  void ExpectUKMEntry(
      const GURL& url,
      security_interstitials::https_only_mode::BlockingResult result) {
    auto entries = test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
    EXPECT_EQ(1u, entries.size());

    test_ukm_recorder_->ExpectEntrySourceHasUrl(entries[0], url);
    test_ukm_recorder_->ExpectEntryMetric(entries[0], "Result",
                                          static_cast<int>(result));
  }

  // Checks that the interstitial UKM has no entry.
  void ExpectEmptyUKM() {
    auto entries = test_ukm_recorder_->GetEntriesByName(UkmEntry::kEntryName);
    EXPECT_EQ(0u, entries.size());
  }

  void EnableCaptivePortalDetection(Browser* browser);

 private:
  // TODO(https://crbug.com/423465927): Explore a better approach to make the
  // existing tests run with the prewarm feature enabled.
  test::ScopedPrewarmFeatureList prewarm_feature_list_{
      test::ScopedPrewarmFeatureList::PrewarmState::kDisabled};
  base::test::ScopedFeatureList feature_list_;
  net::EmbeddedTestServer http_server_{net::EmbeddedTestServer::TYPE_HTTP};
  net::EmbeddedTestServer https_server_{net::EmbeddedTestServer::TYPE_HTTPS};
  content::ContentMockCertVerifier mock_cert_verifier_;
  base::HistogramTester histograms_;
  raw_ptr<Browser, AcrossTasksDanglingUntriaged> incognito_browser_ = nullptr;
  std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;

  // A clock that can be installed with
  // HttpsFirstModeService::SetClockForTesting(). This must outlive the test
  // because HttpsFirstModeService can access it from shutdown tasks that run
  // during PostRunTestOnMainThread().
  base::SimpleTestClock test_clock_;
};

// HttpsUpgradesBrowserTest is NOT instantiated for unusual configurations like
// kHttpsFirstModeWithSiteEngagementWithoutBalancedMode.
INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    HttpsUpgradesBrowserTest,
    ::testing::Values(
        HttpsUpgradesTestType::kHttpsFirstModeOnly,
        HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement,
        HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers,
        HttpsUpgradesTestType::kAllAutoHFM,
        HttpsUpgradesTestType::kHttpsFirstModeIncognito,
        HttpsUpgradesTestType::kHttpsFirstBalancedMode,
        HttpsUpgradesTestType::kAll,
        HttpsUpgradesTestType::kNone),
    // Map param to a human-readable string for better test output.
    [](testing::TestParamInfo<HttpsUpgradesTestType> input_type)
        -> std::string {
      switch (input_type.param) {
        case HttpsUpgradesTestType::kHttpsFirstModeOnly:
          return "HttpsFirstModeOnly";
        case HttpsUpgradesTestType::kHttpsFirstModeWithSiteEngagement:
          return "HttpsFirstModeWithSiteEngagement";
        case HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers:
          return "HttpsFirstModeForTypicallySecureUsers";
        case HttpsUpgradesTestType::kAllAutoHFM:
          return "AllAutoHFM";
        case HttpsUpgradesTestType::kHttpsFirstModeIncognito:
          return "HttpsFirstModeIncognito";
        case HttpsUpgradesTestType::kHttpsFirstBalancedMode:
          return "HttpsFirstBalancedMode";
        case HttpsUpgradesTestType::kAll:
          return "AllFeatures";
        case HttpsUpgradesTestType::kNone:
          return "None";
        case HttpsUpgradesTestType::
            kHttpsFirstModeWithSiteEngagementWithoutBalancedMode:
          return "kHttpsFirstModeWithSiteEngagementWithoutBalancedMode";
      }
    });

// If the user navigates to an HTTP URL for a site that supports HTTPS, the
// navigation should end up on the HTTPS version of the URL if upgrading is
// enabled.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpScheme_ShouldUpgrade) {
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");

  // The NavigateToURL() call returns `false` because the navigation is
  // redirected to HTTPS.
  auto* contents = browser()->tab_strip_model()->GetActiveWebContents();
  content::TestNavigationObserver nav_observer(contents, 1);
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  nav_observer.Wait();

  EXPECT_TRUE(nav_observer.last_navigation_succeeded());
  EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  histograms()->ExpectTotalCount(kEventHistogram, 2);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeSucceeded, 1);

  // Also record general request metrics.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kSecure, 1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kUpgraded, 1);

  ExpectEmptyUKM();
}

// If the user navigates to an HTTPS URL for a site that supports HTTPS, the
// navigation should end up on that exact URL.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpsScheme_ShouldLoad) {
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::NavigateToURL(contents, https_url));

  // Verify that navigation event metrics were not recorded as the navigation
  // was not upgraded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  // General navigation metrics should still be recorded.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kSecure, 1);

  ExpectEmptyUKM();
}

// If the user navigates to a localhost URL, the navigation should end up on
// that exact URL.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, Localhost_ShouldNotUpgrade) {
  GURL localhost_url = http_server()->GetURL("localhost", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::NavigateToURL(contents, localhost_url));

  // Verify that navigation event metrics were not recorded as the navigation
  // was not upgraded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  // Verify that general navigation request metrics were recorded.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kLocalhost,
                                  1);

  ExpectEmptyUKM();
}

// Test that HTTPS Upgrades are skipped for non-unique hostnames, such as
// non-publicly routable (RFC1918/4193) IP addresses, but HTTPS-First Mode
// should still apply.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NonRoutableIPAddress_ShouldNotUpgrade) {
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);

  // Set up an interceptor because the test server can't listen on private IPs.
  GURL local_ip_url("http://192.168.0.1/simple.html");
  auto url_loader_interceptor =
      content::URLLoaderInterceptor::ServeFilesFromDirectoryAtOrigin(
          GetChromeTestDataDir().MaybeAsASCII(),
          local_ip_url.GetWithEmptyPath());

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  if (IsHttpsFirstModePrefEnabled()) {
    // HFM should attempt the upgrade, fail, and fallback to the interstitial.
    EXPECT_FALSE(content::NavigateToURL(contents, local_ip_url));
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));

    // Verify that upgrade events were recorded because an upgrade was attempted
    // and failed.
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeTimedOut, 1);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // If HFM strict mode is not enabled, we should not attempt to upgrade the
    // navigation.
    EXPECT_TRUE(content::NavigateToURL(contents, local_ip_url));
    histograms()->ExpectTotalCount(kEventHistogram, 0);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kNonUniqueHostname, 1);
  }

  ExpectEmptyUKM();
}

// Test that unique single-label hostnames (e.g. gTLDs) are only upgraded and
// warned on in strict mode.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UniqueSingleLabel_NoWarnInBalancedMode) {
  // Set an HTTPS testing port that does not match the test server to have all
  // attempted upgrades fail.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);

  GURL singlelabel_url = http_server()->GetURL("cl", "/simple.html");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  if (IsHttpsFirstModePrefEnabled()) {
    // HFM should attempt the upgrade, fail, and fallback to the interstitial.
    EXPECT_FALSE(content::NavigateToURL(contents, singlelabel_url));
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  } else {
    // Otherwise, the request should not be upgraded and just navigate to HTTP.
    EXPECT_TRUE(content::NavigateToURL(contents, singlelabel_url));
    EXPECT_EQ(singlelabel_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kSingleLabelHostname, 1);
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  }

  // If in Strict Mode, verify that upgrade events were recorded because an
  // upgrade was attempted and failed.
  if (IsHttpsFirstModePrefEnabled()) {
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeTimedOut, 1);

    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
  }

  ExpectEmptyUKM();
}

// If the user navigates to a non-unique hostname, the navigation should be
// upgraded only if strict mode is enabled. If we skip upgrading we should
// record that the reason was the non-unique hostname.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, NonUniqueHost_RecordsMetrics) {
  GURL nonunique_url1 = http_server()->GetURL("test.local", "/simple.html");
  GURL nonunique_url2 = http_server()->GetURL("test", "/simple.html");
  // Note that we don't test with an RFC1918 IP because the test server
  // wouldn't receive the traffic (since it relies on DNS).

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  if (IsHttpsFirstModePrefEnabled()) {
    EXPECT_FALSE(content::NavigateToURL(contents, nonunique_url1));
    EXPECT_FALSE(content::NavigateToURL(contents, nonunique_url2));
    // Other histograms are still recorded.
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    2);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 2);
  } else {
    // When HFM strict mode is not enabled, Chrome does NOT upgrade, so other
    // histograms are not recorded.
    EXPECT_TRUE(content::NavigateToURL(contents, nonunique_url1));
    EXPECT_TRUE(content::NavigateToURL(contents, nonunique_url2));
    histograms()->ExpectUniqueSample(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kNonUniqueHostname, 2);
  }

  ExpectEmptyUKM();
}

// Test that non-default ports (e.g. not HTTP80) are only upgraded and warned on
// in strict mode and Incognito.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NonDefaultPorts_NoWarnInBalancedMode) {
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);

  // Set up an interceptor so we can test non-default (and non-testing) ports.
  GURL non_default_http_url = GURL("http://example.com:8080/simple.html");
  auto url_loader_interceptor =
      content::URLLoaderInterceptor::ServeFilesFromDirectoryAtOrigin(
          GetChromeTestDataDir().MaybeAsASCII(),
          non_default_http_url.GetWithEmptyPath());

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  if (IsHttpsFirstModePrefEnabled() || IsIncognito()) {
    // HFM should attempt the upgrade, fail, and fallback to the interstitial.
    EXPECT_FALSE(content::NavigateToURL(contents, non_default_http_url));
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  } else {
    // Otherwise, the request should not be upgraded and just navigate to HTTP.
    EXPECT_TRUE(content::NavigateToURL(contents, non_default_http_url));
    EXPECT_EQ(non_default_http_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kNonDefaultPorts, 1);
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
  }

  // If in Strict Mode or Incognito, verify that upgrade events were recorded
  // because an upgrade was attempted and failed.
  if (IsHttpsFirstModePrefEnabled() || IsIncognito()) {
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(
        kEventHistogram,
        security_interstitials::https_only_mode::Event::kUpgradeNetError, 1);

    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
  }

  ExpectEmptyUKM();
}

// If the user navigates to an HTTPS URL, the navigation should end up on that
// exact URL, even if the site has an SSL error.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpsScheme_BrokenSSL_ShouldNotFallback) {
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_FALSE(content::NavigateToURL(contents, https_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // The SSL error should show regardless of the HFM state.
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents));

  // Verify that navigation event metrics were not recorded as the navigation
  // was not upgraded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  ExpectEmptyUKM();
}

// If the user navigates to an HTTP URL for a site with broken HTTPS, the
// navigation should end up on the HTTPS URL and show the HTTPS-Only Mode
// interstitial.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       UrlWithHttpScheme_BrokenSSL_ShouldInterstitial) {
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // The user hasn't taken action yet, so this should be empty.
  ExpectEmptyUKM();
}

// HTTPS-First Mode in Incognito should customize the interstitial.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       IncognitoInterstitialVariation) {
  // This test only applies to fully-enabled HFM and HFM-in-Incognito.
  if (!IsHttpsFirstModePrefEnabled() && !IsIncognito()) {
    return;
  }

  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModePrefEnabled()) {
    EXPECT_EQ(HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  } else if (IsIncognito()) {
    // Test that HFM-in-Incognito overrides the default interstitial text.
    EXPECT_EQ(HFMInterstitialType::kIncognito,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  }

  // The user hasn't taken action yet, so this should be empty.
  ExpectEmptyUKM();
}

void MaybeEnableHttpsFirstModeForEngagedSitesAndWait(
    HttpsFirstModeService* hfm_service) {
  base::RunLoop run_loop;
  hfm_service->MaybeEnableHttpsFirstModeForEngagedSites(run_loop.QuitClosure());
  run_loop.Run();
}

// Returns a URL loader interceptor that responds to HTTPS URLs with a cert
// error and to HTTP URLs with a good response.
std::unique_ptr<content::URLLoaderInterceptor>
MakeInterceptorForSiteEngagementHeuristic() {
  return std::make_unique<content::URLLoaderInterceptor>(
      base::BindLambdaForTesting(
          [](content::URLLoaderInterceptor::RequestParams* params) {
            if (params->url_request.url.SchemeIs("https")) {
              // Fail with an SSL error.
              network::URLLoaderCompletionStatus status;
              status.error_code = net::ERR_CERT_COMMON_NAME_INVALID;
              status.ssl_info = net::SSLInfo();
              status.ssl_info->cert_status =
                  net::CERT_STATUS_COMMON_NAME_INVALID;
              // The cert doesn't matter.
              status.ssl_info->cert = net::ImportCertFromFile(
                  net::GetTestCertsDirectory(), "ok_cert.pem");
              status.ssl_info->unverified_cert = status.ssl_info->cert;
              params->client->OnComplete(status);
              return true;
            }
            content::URLLoaderInterceptor::WriteResponse(
                "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                "<html>Done</html>", params->client.get());
            return true;
          }));
}

// TODO(crbug.com/40904694): Fails on the linux-wayland-rel bot.
#if defined(OZONE_PLATFORM_WAYLAND)
#define MAYBE_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial \
  DISABLED_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial
#else
#define MAYBE_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial \
  UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial
#endif
// Test for Site Engagement Heuristic, a feature that enables HFM on specific
// sites based on their site engagement scores.
// If the user navigates to an HTTP URL for a site with broken HTTPS, the
// navigation should end up on the HTTPS URL and show the HTTPS-Only Mode
// interstitial. It should also record a separate histogram for Site Engagement
// Heuristic if the interstitial isn't enabled.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    MAYBE_UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldInterstitial) {
  // HFM+SE is not enabled in Incognito.
  if (IsIncognito()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = GetBrowser()->profile();
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set test clock.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  GURL http_url("http://bad-https.com");
  GURL https_url("https://bad-https.com");
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);
  const bool is_interstitial_due_to_se_heuristic =
      IsSiteEngagementHeuristicEnabled() && !IsHttpsFirstModePrefEnabled() &&
      !InBalancedMode();

  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites() ||
      IsSiteEngagementHeuristicEnabled()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    EXPECT_EQ(is_interstitial_due_to_se_heuristic
                  ? HFMInterstitialType::kSiteEngagement
                  : HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  } else {
    EXPECT_EQ(HFMInterstitialType::kNone,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Check engagement heuristic metrics. These are only recorded when the
  // site engagement heuristic is enabled and the interstitial is due to this
  // heuristic and not because of prefs.
  if (is_interstitial_due_to_se_heuristic) {
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 3);
    histograms()->ExpectBucketCount(kEventHistogramWithEngagementHeuristic,
                                    Event::kUpgradeAttempted, 1);
    histograms()->ExpectBucketCount(kEventHistogramWithEngagementHeuristic,
                                    Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(kEventHistogramWithEngagementHeuristic,
                                    Event::kUpgradeCertError, 1);
    // Check the heuristic state.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicStateHistogram, 1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kDisabled, 0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kEnabled, 1);
    // Check host count.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    0,
                                    /*expected_count=*/0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    1,
                                    /*expected_count=*/1);
    // Check accumulated host count.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0,
        /*expected_count=*/0);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1,
        /*expected_count=*/1);
    // Check enforcement duration. Since the host isn't removed from HFM
    // enforcement list, no duration should be recorded yet.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 0);

    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 1);
  } else {
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 0);
  }

  // Lower HTTPS engagement score. This disables HFM on the site. Also advance
  // the clock.
  SetSiteEngagementScore(https_url, 5);
  clock_ptr->Advance(base::Hours(1));
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  // Should only show the interstitial if the HFM pref is enabled. Site
  // engagement heuristic alone will no longer cause an interstitial.
  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));

    // Proceed through the interstitial, which will add the host to the
    // allowlist and navigate to the HTTP fallback URL.
    ProceedThroughInterstitial(contents);

    // Verify that the interstitial metrics were correctly recorded. The
    // interstitial was shown twice, once clicked through and once not.
    histograms()->ExpectTotalCount("interstitial.https_first_mode.decision", 4);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::SHOW, 2);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::PROCEED, 1);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);
  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    if (IsSiteEngagementHeuristicEnabled()) {
      // Verify that the interstitial metrics were correctly recorded. The
      // interstitial was shown once and navigated away from.
      histograms()->ExpectTotalCount("interstitial.https_first_mode.decision",
                                     2);
      histograms()->ExpectBucketCount(
          "interstitial.https_first_mode.decision",
          security_interstitials::MetricsHelper::Decision::SHOW, 1);
      histograms()->ExpectBucketCount(
          "interstitial.https_first_mode.decision",
          security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);
    } else {
      histograms()->ExpectTotalCount("interstitial.https_first_mode.decision",
                                     0);
    }
  }

  // Check engagement heuristic metrics. These are only recorded when the
  // site engagement heuristic is enabled and the interstitial is due to this
  // heuristic and not because of prefs.
  if (IsSiteEngagementHeuristicEnabled() &&
      !IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Event histogram shouldn't change because Site Engagement heuristic didn't
    // kick in.
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 3);

    // Check host count.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   2);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    0,
                                    /*expected_count=*/1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    1,
                                    /*expected_count=*/1);
    // Check accumulated host count.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 2);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0,
        /*expected_count=*/0);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1,
        /*expected_count=*/2);
    // Check enforcement duration. The host is now removed from HFM
    // enforcement list, so its HFM enforcement duration should be recorded now.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 1);
    histograms()->ExpectTimeBucketCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, base::Hours(1),
        1);

    // This bucket was recorded once previously, shouldn't be recorded again.
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 1);

  } else {
    // Event histogram shouldn't change because Site Engagement heuristic didn't
    // kick in.
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

    // If HFM pref was enabled, no SE metrics should be recorded because HFM
    // won't be auto-enabled.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   0);
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0);
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 0);

    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 0);
  }
}

// Test that Site Engagement Heuristic doesn't enforce HTTPS on URLs with
// non-default ports.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristic_ShouldIgnoreUrlsWithNonDefaultPorts) {
  // HFM+SE is not enabled in Incognito.
  if (IsIncognito()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = GetBrowser()->profile();
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set test clock.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  GURL http_url("http://bad-https.com");
  GURL https_url("https://bad-https.com");
  GURL navigated_url("http://bad-https.com:8080");

  // Set engagement for the HTTP and HTTPS origins with default ports.
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  // Navigate to a non-default port version of the URL.
  NavigateAndWaitForFallback(contents, navigated_url);
  EXPECT_EQ(navigated_url, contents->GetLastCommittedURL());

  // Non-strict modes should not upgrade because `navigated_url` has a
  // non-default port, regardless of whether the hostname is on the enforcelist.
  if (IsHttpsFirstModePrefEnabled()) {
    EXPECT_EQ(HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  } else {
    EXPECT_EQ(HFMInterstitialType::kNone,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  }

  // Strict mode should have upgraded and fallen back to HTTP.
  if (IsHttpsFirstModePrefEnabled()) {
    // Verify that navigation event metrics were correctly recorded.
    histograms()->ExpectTotalCount(kEventHistogram, 3);
    histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted,
                                    1);
    histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
    histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError,
                                    1);
  } else {
    histograms()->ExpectTotalCount(kEventHistogram, 0);
  }

  // Engagement heuristic shouldn't handle any navigation events because we
  // didn't navigate to bad-https.com:80.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

  // Check engagement heuristic metrics. These are only recorded when the
  // site engagement interstitial is enabled.
  if (IsSiteEngagementHeuristicEnabled() &&
      !IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Check the heuristic state. The heuristic should enable HFM for
    // example.com
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicStateHistogram, 1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kDisabled, 0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicStateHistogram,
                                    SiteEngagementHeuristicState::kEnabled, 1);
    // Check host count.
    histograms()->ExpectTotalCount(kSiteEngagementHeuristicHostCountHistogram,
                                   1);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    0,
                                    /*expected_count=*/0);
    histograms()->ExpectBucketCount(kSiteEngagementHeuristicHostCountHistogram,
                                    1,
                                    /*expected_count=*/1);
    // Check accumulated host count.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 0,
        /*expected_count=*/0);
    histograms()->ExpectBucketCount(
        kSiteEngagementHeuristicAccumulatedHostCountHistogram, 1,
        /*expected_count=*/1);
    // Check enforcement duration. Since the host isn't removed from HFM
    // enforcement list, no duration should be recorded yet.
    histograms()->ExpectTotalCount(
        kSiteEngagementHeuristicEnforcementDurationHistogram, 0);
  } else {
    histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);
  }
}

IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    PRE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito.
  if (IsIncognito()) {
    return;
  }

  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  if (!IsHttpsFirstModePrefEnabled() && !InBalancedMode()) {
    // When HFM is not enabled via pref, these should never be set in this test.
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeEnabled));
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeAutoEnabled));
  }

  // Typically Secure User heuristic requires a minimum total site engagement
  // score.
  SetSiteEngagementScore(GURL("https://google.com"), 90);

  base::Time now;
  EXPECT_TRUE(base::Time::FromUTCString("2023-10-15T06:00:00Z", &now));
  // Start the clock at standard system time.
  GetTestClock()->SetNow(now);

  profile->SetCreationTimeForTesting(GetTestClock()->Now() - base::Days(30));

  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  hfm_service->SetClockForTesting(GetTestClock());

  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  // Visit the HTTP URL. Profile age is old enough but we haven't been observing
  // navigations for long enough, so Typically Secure Users feature won't show
  // an interstitial here.
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  ExpectedInterstitialReasons expected_reasons;

  if (IsHttpsFirstModePrefEnabled()) {
    ExpectInterstitial(contents);
    expected_reasons.pref++;
  } else if (InBalancedMode()) {
    ExpectInterstitial(contents);
    expected_reasons.balanced++;
  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  // Move the clock forward and revisit HTTP. Profile is old enough now, but
  // Typically Secure Users feature will only auto-enable HFM after a restart
  // and show an interstitial.
  GetTestClock()->Advance(base::Days(15));
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModePrefEnabled()) {
    ExpectInterstitial(contents);
    expected_reasons.pref++;
  } else if (InBalancedMode()) {
    ExpectInterstitial(contents);
    expected_reasons.balanced++;
  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  if (!IsHttpsFirstModePrefEnabled() && !InBalancedMode()) {
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeEnabled));
    EXPECT_FALSE(
        profile->GetPrefs()->HasPrefPath(prefs::kHttpsOnlyModeAutoEnabled));
  }
}

// TODO(crbug.com/40925331): Fails on the linux-wayland-rel bot.
#if defined(OZONE_PLATFORM_WAYLAND)
#define MAYBE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser \
  DISABLED_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser
#else
#define MAYBE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser \
  UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser
#endif
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    MAYBE_UrlWithHttpScheme_BrokenSSL_ShouldInterstitial_TypicallySecureUser) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito.
  if (IsIncognito()) {
    return;
  }

  // Advance the clock to one day after the last fallback event, which happened
  // on the 15th day.
  GetTestClock()->SetNow(base::Time::NowFromSystemTime() + base::Days(16));

  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  // Do lots of navigations so that Typically Secure User can kick in.
  for (size_t i = 0; i < 1500; i++) {
    hfm_service->IncrementRecentNavigationCount();
  }

  hfm_service->SetClockForTesting(GetTestClock());
  // HFM service runs this on startup, but we can't set the test clock before it
  // runs, and we need to move the clock forward for this to work. So call it
  // explicitly again here.
  hfm_service->CheckUserIsTypicallySecureAndMaybeEnableHttpsFirstBalancedMode();
  size_t initial_navigation_count = hfm_service->GetRecentNavigationCount();

  // Use a different hostname than the PRE_ test so that we don't hit the
  // allowlist.
  GURL http_url = http_server()->GetURL("bad-https2.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https2.com", "/simple.html");
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_EQ(initial_navigation_count + 1u,
            hfm_service->GetRecentNavigationCount());

  bool expect_interstitial = IsHttpsFirstModeInterstitialEnabledAcrossSites() ||
                             IsTypicallySecureUserFeatureEnabled();
  // Expect typically secure text only when HFM is auto-enabled, so exclude
  // HttpsUpgradesTestType::kAll where HFM is enabled via pref).
  bool expect_typically_secure_user_interstitial_text =
      https_upgrades_test_type() ==
          HttpsUpgradesTestType::kHttpsFirstModeForTypicallySecureUsers ||
      https_upgrades_test_type() == HttpsUpgradesTestType::kAllAutoHFM;

  ExpectedInterstitialReasons expected_reasons;
  if (expect_interstitial) {
    EXPECT_EQ(expect_typically_secure_user_interstitial_text
                  ? HFMInterstitialType::kTypicallySecure
                  : HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));

    if (expect_typically_secure_user_interstitial_text) {
      expected_reasons.typically_secure_user++;
    } else if (IsHttpsFirstModePrefEnabled()) {
      expected_reasons.pref++;
    } else if (InBalancedMode()) {
      expected_reasons.balanced++;
    } else {
      NOTREACHED();
    }
  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  // Move the clock forward a day and revisit HTTP. Should still show HFM
  // interstitial.
  GetTestClock()->Advance(base::Days(1));
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_EQ(initial_navigation_count + 2u,
            hfm_service->GetRecentNavigationCount());

  if (expect_interstitial) {
    EXPECT_EQ(expect_typically_secure_user_interstitial_text
                  ? HFMInterstitialType::kTypicallySecure
                  : HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));

    if (expect_typically_secure_user_interstitial_text) {
      expected_reasons.typically_secure_user++;
    } else if (IsHttpsFirstModePrefEnabled()) {
      expected_reasons.pref++;
    } else if (InBalancedMode()) {
      expected_reasons.balanced++;
    } else {
      NOTREACHED();
    }

  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
  CheckInterstitialReasonHistogram(expected_reasons);

  // Disable HFM and HF-balanced-mode. Should no longer auto-enable it.
  SetPref(false);
  auto* state = static_cast<StatefulSSLHostStateDelegate*>(
      profile->GetSSLHostStateDelegate());
  state->SetHttpsFirstBalancedModeSuppressedForTesting(true);
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(initial_navigation_count + 3u,
            hfm_service->GetRecentNavigationCount());
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));

  // Re-enable HFM. Should now show HFM interstitial without the auto-enabled
  // text.
  SetPref(true);
  state->SetHttpsFirstBalancedModeSuppressedForTesting(false);
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_EQ(initial_navigation_count + 4u,
            hfm_service->GetRecentNavigationCount());

  EXPECT_EQ(HFMInterstitialType::kStandard,
            chrome_browser_interstitials::GetHFMInterstitialType(contents));
  expected_reasons.pref++;

  CheckInterstitialReasonHistogram(expected_reasons);
}

// Checks that navigation to a non-unique hostname doesn't display a typically
// secure interstitial.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    TypicallySecure_NonUniqueHostname_ShouldNotShowInterstitial) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito.
  if (IsIncognito()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  SatisfyTypicallySecureHeuristicRequirements();
  // This should auto-enable HFM now:
  hfm_service()
      ->CheckUserIsTypicallySecureAndMaybeEnableHttpsFirstBalancedMode();

  // Check that a bad HTTPS URL should show an interstitial due to the
  // heuristic.
  GURL http_url("http://bad-https.com/simple.html");
  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  content::NavigateToURLBlockUntilNavigationsComplete(
      contents, http_url, /*number_of_navigations=*/1);
  MaybeExpectTypicallySecureInterstitial(contents);

  // Check that a non-unique hostname shouldn't show an interstitial due to the
  // heuristic.
  GURL nonunique_url("http://nonunique-hostname-bad-https/simple.html");
  content::NavigateToURLBlockUntilNavigationsComplete(
      contents, nonunique_url, /*number_of_navigations=*/1);
  if (IsHttpsFirstModePrefEnabled()) {
    // Non-unique hostnames should only show an interstitial in strict mode.
    EXPECT_EQ(HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
}

// Same as TypicallySecure_NonUniqueHostname_ShouldNotShowInterstitial, but
// also navigates to a non-unique URL before checking the heuristic. The
// non-unique URL should not count as a fallback navigation and should not
// disable the Typically Secure heuristic.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    TypicallySecure_NonUniqueHostnameFallbackShouldNotDisableTypicallySecureHeuristic) {
  // HFM-for-Typically-Secure-Users is not enabled in Incognito.
  if (IsIncognito()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  SatisfyTypicallySecureHeuristicRequirements();

  // Before running the heuristic checks, also navigate to a non-unique
  // hostname. This will result in an interstitial iff strict mode is enabled.
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::NavigateToURLBlockUntilNavigationsComplete(
      contents, GURL("http://nonunique-hostname-bad-https2/simple.html"),
      /*number_of_navigations=*/1);
  if (IsHttpsFirstModePrefEnabled()) {
    // Non-unique hostnames should only show an interstitial in strict mode.
    EXPECT_EQ(HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }

  // This should still auto-enable HFM despite the interstitial for the
  // non-unique hostname because Typically Secure heuristic ignores fallbacks
  // for non-unique hostnames.
  hfm_service()
      ->CheckUserIsTypicallySecureAndMaybeEnableHttpsFirstBalancedMode();

  // Check that a bad HTTPS URL should show an interstitial due to the
  // heuristic.
  GURL http_url("http://bad-https.com/simple.html");
  content::NavigateToURLBlockUntilNavigationsComplete(
      contents, http_url, /*number_of_navigations=*/1);
  MaybeExpectTypicallySecureInterstitial(contents);

  // Check that a non-unique hostname shouldn't show an interstitial due to the
  // heuristic.
  GURL nonunique_url("http://nonunique-hostname-bad-https/simple.html");
  content::NavigateToURLBlockUntilNavigationsComplete(
      contents, nonunique_url, /*number_of_navigations=*/1);
  if (IsHttpsFirstModePrefEnabled()) {
    // Non-unique hostnames should only show an interstitial in strict mode.
    EXPECT_EQ(HFMInterstitialType::kStandard,
              chrome_browser_interstitials::GetHFMInterstitialType(contents));
  } else {
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
}

// Regression test for crbug.com/1441276. Sequence of events:
// 1. Loads http://example.com. This gets upgraded to https://example.com.
// 2. https://example.com has an iframe for https://nonexistentsite.com. It
//    navigates away immediately to http://example.com.
// 3. This causes a crash in
//    HttpsUpgradesInterceptor::MaybeCreateLoaderForResponse() for
//    nonexistentsite.com.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       LoadIFrameAndNavigateAway_ShouldNotCrash) {
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);

  bool navigated_once = false;
  auto url_loader_interceptor = std::make_unique<content::URLLoaderInterceptor>(
      base::BindLambdaForTesting(
          [&navigated_once](
              content::URLLoaderInterceptor::RequestParams* params) {
            if (params->url_request.url == GURL("https://example.com")) {
              if (!navigated_once) {
                // Load an iframe that will result in an error and immediately
                // navigate away.
                content::URLLoaderInterceptor::WriteResponse(
                    "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                    "<html>"
                    "<iframe src='https://nonexistentsite.com'></iframe>"
                    "<script>window.location.href = "
                    "'http://example.com';</script></html>",
                    params->client.get());
                navigated_once = true;
                return true;
              }
              // Return a normal response the second time this is called,
              // otherwise the test will timeout due to navigating back and
              // forth between http and https URLs.
              content::URLLoaderInterceptor::WriteResponse(
                  "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                  "<html>Done</html>", params->client.get());
              return true;
            }

            if (params->url_request.url == GURL("http://example.com")) {
              content::URLLoaderInterceptor::WriteResponse(
                  "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                  "<html>Test</html>", params->client.get());
              return true;
            }

            if (params->url_request.url.GetHost() == "nonexistentsite.com") {
              // This request must fail for the bug to trigger.
              params->client->OnComplete(network::URLLoaderCompletionStatus(
                  net::ERR_CONNECTION_RESET));
              return true;
            }
            return false;
          }));

  GURL http_url("http://example.com");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
}

// If the user triggers an HTTPS-Only Mode interstitial for a host and then
// clicks through the interstitial, they should end up on the HTTP URL.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       InterstitialBypassed_HttpFallbackLoaded) {
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));

    // Proceed through the interstitial, which will add the host to the
    // allowlist and navigate to the HTTP fallback URL.
    ProceedThroughInterstitial(contents);

    // Verify that the interstitial metrics were correctly recorded.
    histograms()->ExpectTotalCount("interstitial.https_first_mode.decision", 2);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::SHOW, 1);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::PROCEED, 1);

    ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
  }

  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Revisit the site. Should load without a warning, but also record another
  // UKM.
  // TODO(crbug.com/406530494): This should also record the allowlisted status.
  NavigateAndWaitForFallback(contents, http_url);
  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
  }
}

// If the upgraded HTTPS URL is not available due to a net error, it should
// trigger the HTTPS-Only Mode interstitial and offer fallback.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NetErrorOnUpgrade_ShouldInterstitial) {
  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeNetError, 1);
}

// If the upgraded HTTPS URL is not available due to a potentially-transient
// exempted net error (here a DNS resolution error), show the regular net error
// page instead of the HTTPS-First Mode interstitial. If the network conditions
// change such that the network error no longer triggers, reloading the tab
// should continue the upgraded navigation, which will fail and trigger fallback
// to HTTP. (Regression test for crbug.com/1277211.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       ExemptNetErrorOnUpgrade_ShouldNotFallback) {
  // This test is only interesting when HTTPS-First Mode is enabled.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  {
    // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED. Navigating
    // to the HTTP URL should get upgraded to HTTPS, but fail with a net error
    // page on the HTTPS URL.
    auto dns_failure_interceptor =
        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
            [](content::URLLoaderInterceptor::RequestParams* params) {
              params->client->OnComplete(network::URLLoaderCompletionStatus(
                  net::ERR_NAME_NOT_RESOLVED));
              return true;
            }));
    EXPECT_FALSE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));

    // Reload the tab. The net error should still be showing as the navigation
    // still results in ERR_NAME_NOT_RESOLVED.
    content::TestNavigationObserver nav_observer(contents, 1);
    contents->GetController().Reload(content::ReloadType::NORMAL,
                                     /*check_for_repost=*/false);
    nav_observer.Wait();
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(chrome_browser_interstitials::IsShowingInterstitial(contents));
  }

  // Interceptor is now out of scope and no longer applies. Reload the tab and
  // the upgraded navigation should continue, fail due to the bad HTTPS on the
  // server, and fall back to HTTP.
  content::TestNavigationObserver nav_observer(contents, 1);
  contents->GetController().Reload(content::ReloadType::NORMAL,
                                   /*check_for_repost=*/false);
  nav_observer.Wait();

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ASSERT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    ProceedThroughInterstitial(contents);
  }

  // Should now be on the HTTP URL and it should be allowlisted.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
}

// Test that if one site redirects to a non-existent site, that we show the
// regular net error page instead of the HTTPS-First Mode interstitial.
// (Regression test for crbug.com/1277211.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       RedirectToNonexistentSite_ShouldNotInterstitial) {
  // This test is only interesting when HTTPS-First Mode is enabled.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  std::string nonexistent_domain = "nonexistentsite.com";
  GURL nonexistent_http_url =
      http_server()->GetURL(nonexistent_domain, "/simple.html");
  GURL nonexistent_https_url =
      https_server()->GetURL(nonexistent_domain, "/simple.html");
  std::string www_redirect_path =
      base::StrCat({"/server-redirect?", nonexistent_http_url.spec()});
  GURL redirecting_https_url =
      https_server()->GetURL("foo.com", www_redirect_path);
  GURL redirecting_http_url =
      http_server()->GetURL("foo.com", www_redirect_path);

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED for
  // nonexistentsite.com.
  auto dns_failure_interceptor =
      std::make_unique<content::URLLoaderInterceptor>(
          base::BindLambdaForTesting(
              [nonexistent_domain](
                  content::URLLoaderInterceptor::RequestParams* params) {
                if (params->url_request.url.GetHost() == nonexistent_domain) {
                  params->client->OnComplete(network::URLLoaderCompletionStatus(
                      net::ERR_NAME_NOT_RESOLVED));
                  return true;
                }
                return false;
              }));

  // Navigating to the HTTP URL should get upgraded to HTTPS, but fail with a
  // net error page on the HTTPS URL.
  EXPECT_FALSE(content::NavigateToURL(contents, redirecting_http_url));
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));
  EXPECT_EQ(url::kHttpsScheme, contents->GetLastCommittedURL().GetScheme());
  EXPECT_EQ(nonexistent_domain, contents->GetLastCommittedURL().GetHost());
}

// If the upgraded HTTPS URL is not available due to a potentially-transient
// exempted net error but the hostname is non-unique, don't show the net error
// page and instead just fallback to HTTP and the HTTPS-First Mode interstitial.
// Otherwise, the user can be stuck on the net error page when the HTTP version
// of the host would have resolved, such as for corp single-label hostnames.
// (Regression test for crbug.com/1451040.)
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    ExemptNetErrorOnUpgrade_NonUniqueHostname_ShouldFallback) {
  // This test is only interesting when HTTPS-First Mode is fully enabled.
  if (!IsHttpsFirstModePrefEnabled()) {
    return;
  }

  GURL http_url = http_server()->GetURL("blorp", "/simple.html");
  GURL https_url = https_server()->GetURL("blorp", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED. Navigating
  // to the HTTP URL should get upgraded to HTTPS, and then fallback to HTTP
  // and the HFM interstitial.
  auto dns_failure_interceptor =
      std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
          [](content::URLLoaderInterceptor::RequestParams* params) {
            params->client->OnComplete(
                network::URLLoaderCompletionStatus(net::ERR_NAME_NOT_RESOLVED));
            return true;
          }));
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingInterstitial(contents));
  ProceedThroughInterstitial(contents);

  // Should now be on the HTTP URL and it should be allowlisted.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
}

// If the upgraded HTTPS URL is not available due to an exempted net error but
// is to a single-label unique hostname (i.e. a TLD) don't show the net error
// page. This is the same as
// ExemptNetErrorOnUpgrade_NonUniqueHostname_ShouldFallback except with a unique
// one-label hostname.
// (Partial regression test for impact of crrev.com/c/5507613 on b/348330182.)
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    ExemptNetErrorOnUpgrade_UniqueSingleLabelHostname_ShouldFallback) {
  // This test is only interesting when HTTPS-First Strict Mode is enabled.
  // Balanced Mode won't try to upgrade these requests at all.
  if (!IsHttpsFirstModePrefEnabled() || IsIncognito()) {
    return;
  }

  GURL http_url = http_server()->GetURL("cl", "/simple.html");
  GURL https_url = https_server()->GetURL("cl", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  // Set up an interceptor that will return ERR_NAME_NOT_RESOLVED. Navigating
  // to the HTTP URL should get upgraded to HTTPS, and then fallback to HTTP
  // and the HFM interstitial.
  auto dns_failure_interceptor =
      std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
          [](content::URLLoaderInterceptor::RequestParams* params) {
            params->client->OnComplete(
                network::URLLoaderCompletionStatus(net::ERR_NAME_NOT_RESOLVED));
            return true;
          }));
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingInterstitial(contents));
  ProceedThroughInterstitial(contents);

  // Should now be on the HTTP URL and the hostname should be allowlisted.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialProceed);
}

// Navigations in subframes should not get upgraded by HTTPS-Only Mode. They
// should be blocked as mixed content.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpsParentHttpSubframeNavigation_Blocked) {
  const GURL parent_url(
      https_server()->GetURL("foo.com", "/iframe_blank.html"));
  const GURL iframe_url(http_server()->GetURL("foo.com", "/simple.html"));

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::NavigateToURL(contents, parent_url));

  content::TestNavigationObserver nav_observer(contents, 1);
  EXPECT_TRUE(content::NavigateIframeToURL(contents, "test", iframe_url));
  nav_observer.Wait();
  EXPECT_NE(iframe_url, nav_observer.last_navigation_url());

  // Verify that no navigation event metrics were recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 0);
}

// Navigating to an HTTP URL in a subframe of an HTTP page should not upgrade
// the subframe navigation to HTTPS (even if the subframe navigation is to a
// different host than the parent frame).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpParentHttpSubframeNavigation_NotUpgraded) {
  // The parent frame will fail to upgrade to HTTPS.
  const GURL parent_url(
      http_server()->GetURL("bad-https.com", "/iframe_blank.html"));
  const GURL iframe_url(http_server()->GetURL("bar.com", "/simple.html"));

  // Navigate to `parent_url` and bypass the HTTPS-Only Mode warning.
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, parent_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    // Proceeding through the interstitial will add the hostname to the
    // allowlist.
    ProceedThroughInterstitial(contents);
  }

  // Verify that navigation event metrics were recorded for the main frame.
  histograms()->ExpectTotalCount(kEventHistogram, 3);

  // Navigate the iframe to `iframe_url`. It should successfully navigate and
  // not get upgraded to HTTPS as the hostname is now in the allowlist.
  content::TestNavigationObserver nav_observer(contents, 1);
  EXPECT_TRUE(content::NavigateIframeToURL(contents, "test", iframe_url));
  nav_observer.Wait();
  EXPECT_EQ(iframe_url, nav_observer.last_navigation_url());

  // Verify that no new navigation event metrics were recorded for the subframe.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
}

// Tests that a navigation to the HTTP version of a site with an HTTPS version
// that is slow to respond gets upgraded to HTTPS but times out and shows the
// HTTPS-Only Mode interstitial.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, SlowHttps_ShouldInterstitial) {
  // Set timeout to zero so that HTTPS upgrades immediately timeout.
  HttpsUpgradesNavigationThrottle::set_timeout_for_testing(base::TimeDelta());

  // Set up a custom HTTPS server that times out without sending a response.
  net::EmbeddedTestServer timeout_server{net::EmbeddedTestServer::TYPE_HTTPS};
  timeout_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        // Server will hang until destroyed.
        return std::make_unique<net::test_server::HungResponse>();
      }));
  ASSERT_TRUE(timeout_server.Start());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(timeout_server.port());

  const GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
}

// Tests that an HTTP POST form navigation to "bar.com" from an HTTP page on
// "foo.com" is not upgraded to HTTPS. (HTTP form navigations from HTTPS are
// blocked by the Mixed Forms warning.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, HttpPageHttpPost_NotUpgraded) {
  // Point the HTTP form target to "bar.com".
  base::StringPairs replacement_text;
  replacement_text.emplace_back(make_pair(
      "REPLACE_WITH_HOST_AND_PORT",
      net::HostPortPair::FromURL(http_server()->GetURL("foo.com", "/"))
          .ToString()));
  auto replacement_path = net::test_server::GetFilePathWithReplacements(
      "/ssl/page_with_form_targeting_http_url.html", replacement_text);

  // Navigate to the page hosting the form on "foo.com".
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  content::NavigateToURLBlockUntilNavigationsComplete(
      contents, http_server()->GetURL("bad-https.com", replacement_path), 1);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // The HTTPS-Only Mode interstitial should trigger.
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    // Proceed through the interstitial to add the hostname to the allowlist.
    ProceedThroughInterstitial(contents);
  }

  // Verify that navigation event metrics were recorded for the initial page.
  histograms()->ExpectTotalCount(kEventHistogram, 3);

  // Submit the form and wait for the navigation to complete.
  content::TestNavigationObserver nav_observer(contents, 1);
  ASSERT_TRUE(
      content::ExecJs(contents, "document.getElementById('submit').click();"));
  nav_observer.Wait();

  // Check that the navigation has ended up on the HTTP target.
  EXPECT_EQ("foo.com", contents->GetLastCommittedURL().GetHost());
  EXPECT_TRUE(contents->GetLastCommittedURL().SchemeIs(url::kHttpScheme));

  // Verify that no new navigation event metrics were recorded for the POST
  // navigation.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
}

// Tests that if an HTTPS navigation redirects to HTTP on a different host, it
// should upgrade to HTTPS on that new host. (A downgrade redirect on the same
// host would imply a redirect loop.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpsToHttpRedirect_ShouldUpgrade) {
  GURL target_url = http_server()->GetURL("bar.com", "/title1.html");
  GURL url = https_server()->GetURL("foo.com",
                                    "/server-redirect?" + target_url.spec());

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  // NavigateToURL() returns `false` because the final redirected URL does not
  // match `url`. Separately ensure the navigation succeeded using a navigation
  // observer.
  content::TestNavigationObserver nav_observer(contents, 1);
  EXPECT_FALSE(content::NavigateToURL(contents, url));
  nav_observer.Wait();
  EXPECT_TRUE(nav_observer.last_navigation_succeeded());

  // Verify that navigation event metrics were correctly recorded.
  EXPECT_TRUE(contents->GetLastCommittedURL().SchemeIs(url::kHttpsScheme));
  histograms()->ExpectTotalCount(kEventHistogram, 2);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeSucceeded, 1);

  EXPECT_EQ("bar.com", contents->GetLastCommittedURL().GetHost());
}

// Regression test for crbug.com/41488861.
// Tests that a slow fallback load is not cancelled with timeout.
// bad-ssl.com is configured to return a slow load over http. Navigating to
// http://bad-ssl.com should upgrade and immediately fall back, then display the
// http response without cancelling it for timeout.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       CancelTimeoutForFallbackNavigations) {
  net::EmbeddedTestServer http_server;
  net::EmbeddedTestServer https_server{net::EmbeddedTestServer::TYPE_HTTPS};

  // Make the HTTP server return a slow response.
  http_server.RegisterRequestHandler(base::BindRepeating(
      [](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        // The HTTP load needs to be slower than the 1 second timeout configured
        // by the the test.
        auto slow_http_response =
            std::make_unique<net::test_server::DelayedHttpResponse>(
                base::Seconds(2));
        slow_http_response->set_content_type("text/html");
        slow_http_response->set_content("hello from http");
        return std::move(slow_http_response);
      }));
  ASSERT_TRUE(http_server.Start());
  ASSERT_TRUE(https_server.Start());

  // Set the timeout short enough, but not zero. We can't set it to zero
  // because it'll cancel the HTTPS load with timeout instead of an error.
  HttpsUpgradesNavigationThrottle::set_timeout_for_testing(base::Seconds(1));

  HttpsUpgradesInterceptor::SetHttpPortForTesting(http_server.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(https_server.port());

  GURL http_url(http_server.GetURL("bad-https.com", "/"));
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 1);
    histograms()->ExpectBucketCount("Net.ErrorCodesForMainFrame4",
                                    -net::ERR_ABORTED, 1);
  } else {
    // Shouldn't record any net errors.
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 0);
  }

  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);
}

// Creates a redirect response.
std::unique_ptr<net::test_server::HttpResponse> RedirectResponseHandler(
    const GURL& dest_url,
    const net::test_server::HttpRequest& request) {
  std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
      new net::test_server::BasicHttpResponse);
  http_response->set_code(net::HTTP_TEMPORARY_REDIRECT);
  http_response->AddCustomHeader("Location", dest_url.spec());
  return std::move(http_response);
}

// Creates a response that causes a redirect loop over https and returns a slow
// response over http.
std::unique_ptr<net::test_server::HttpResponse> RedirectLoopResponse(
    int& http_port,
    int& https_port,
    const net::test_server::HttpRequest& request) {
  if (request.GetURL().GetPath() == "/redirect") {
    // Over https, this URL redirects to itself.
    if (request.GetURL().SchemeIs("https")) {
      GURL url(base::StringPrintf("http://a.com:%d/redirect", http_port));
      return RedirectResponseHandler(url, request);
    }
    // Over http, it prints a slow hello. This should delay longer than the
    // HTTPS upgrade timeout which is set to 1 second.
    auto slow_http_response =
        std::make_unique<net::test_server::DelayedHttpResponse>(
            base::Seconds(2));
    slow_http_response->set_content_type("text/html");
    slow_http_response->set_content("hello from http");
    return std::move(slow_http_response);
  }
  return nullptr;
}

// Another regression test for crbug.com/41488861.
// Tests that a slow load that's detected as a redirect loop will not display
// a flash of a net error page.
//
// Assume that a.com/redirect:
// - Shows a slow loading response when loaded over http
// - Redirects to http://a.com/redirect when loaded over https.
//
// The flow of the test is as follows:
// 1. Load http://a.com/redirect.
// 2. http://a.com/redirect is upgraded to http.
// 3. https://a.com/redirect redirects to http://a.com/redirect
// 4. This triggers a redirect loop (the URL was seen at step 1).
// 5. a.com is allowlisted and http://a.com/redirect is loaded as fallback.
// 6. http://a.com/redirect prints a message after a slow load.
//
// This flow should never display a net error page with ERR_TIMED_OUT to the
// user. If the interstitial is enabled, it should be displayed at the final
// step.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       RedirectLoopWithSlowRedirect_ShouldInterstitial) {
  net::EmbeddedTestServer redirect_server_http;
  net::EmbeddedTestServer redirect_server_https{
      net::EmbeddedTestServer::TYPE_HTTPS};

  // Set the timeout short enough, but not zero. We can't set it to zero
  // because it'll cancel the HTTPS load with timeout instead of an error.
  // The HTTP load in this test needs to be slower than this timeout for the
  // test to be meaningful.
  HttpsUpgradesNavigationThrottle::set_timeout_for_testing(base::Seconds(1));

  // We don't know the ports without starting the servers and we can't start
  // the servers without registering request handlers. Pass them as refs so
  // that we can change them later.
  int http_port = 0;
  int https_port = 0;
  redirect_server_http.RegisterRequestHandler(base::BindRepeating(
      &RedirectLoopResponse, std::ref(http_port), std::ref(https_port)));
  redirect_server_https.RegisterRequestHandler(base::BindRepeating(
      &RedirectLoopResponse, std::ref(http_port), std::ref(https_port)));

  ASSERT_TRUE(redirect_server_http.Start());
  ASSERT_TRUE(redirect_server_https.Start());

  http_port = redirect_server_http.port();
  https_port = redirect_server_https.port();

  HttpsUpgradesInterceptor::SetHttpPortForTesting(redirect_server_http.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(
      redirect_server_https.port());

  GURL http_url(redirect_server_http.GetURL("a.com", "/redirect"));
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 1);
    histograms()->ExpectBucketCount("Net.ErrorCodesForMainFrame4",
                                    -net::ERR_ABORTED, 1);
  } else {
    // Shouldn't record any net errors.
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    histograms()->ExpectTotalCount("Net.ErrorCodesForMainFrame4", 0);
  }

  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeRedirectLoop,
                                  1);
}

// Tests that navigating to an HTTPS page that downgrades to HTTP on the same
// host will fail and trigger the HTTPS-Only Mode interstitial (due to
// interceptor detecting a redirect loop and triggering fallback).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       RedirectLoop_ShouldInterstitial) {
  // Set up a new test server instance so it can have a custom handler.
  net::EmbeddedTestServer downgrading_server{
      net::EmbeddedTestServer::TYPE_HTTPS};
  // Downgrade by swapping the scheme for HTTP. HTTPS-Only Mode will upgrade it
  // back to HTTPS.
  downgrading_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        GURL::Replacements http_downgrade;
        http_downgrade.SetSchemeStr(url::kHttpScheme);
        // The HttpRequest will by default refer to the test server by the
        // loopback address rather than any hostname in the navigation (i.e.,
        // the EmbeddedTestServer has no notion of virtual hosts). This
        // explicitly sets the hostname back to the test host so that this
        // doesn't fail due to the exception for localhost.
        http_downgrade.SetHostStr("foo.com");
        auto redirect_url = request.GetURL().ReplaceComponents(http_downgrade);
        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
        response->set_code(net::HTTP_TEMPORARY_REDIRECT);
        response->AddCustomHeader("Location", redirect_url.spec());
        return response;
      }));
  ASSERT_TRUE(downgrading_server.Start());
  HttpsUpgradesInterceptor::SetHttpPortForTesting(downgrading_server.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(downgrading_server.port());

  GURL url = downgrading_server.GetURL("foo.com", "/");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeRedirectLoop,
                                  1);
}

// Tests that the security level is WARNING when the HTTPS-Only Mode
// interstitial is shown for a net error on HTTPS. (Without HTTPS-Only Mode, a
// net error would be a security level of NONE.)
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       NetErrorOnUpgrade_SecurityLevelWarning) {
  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  auto* helper = SecurityStateTabHelper::FromWebContents(contents);
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));

    EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel());

    // Proceed through the interstitial to navigate to the HTTP site.
    ProceedThroughInterstitial(contents);
  }

  // The HTTP site results in a net error, which should have security level NONE
  // (as no connection was made).
  // TODO(crbug.com/40248833): Uncomment once upgrades are tracked
  // per-navigation.
  // EXPECT_EQ(security_state::NONE, helper->GetSecurityLevel());
}

// Tests that the security level is WARNING when the HTTPS-Only Mode
// interstitial is shown for a cert error on HTTPS. (Without HTTPS-Only Mode, a
// a cert error would be a security level of DANGEROUS.) After clicking through
// the interstitial, the security level should still be WARNING.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       BrokenSSLOnUpgrade_SecurityLevelWarning) {
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  auto* helper = SecurityStateTabHelper::FromWebContents(contents);
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));

    EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel());

    // Proceed through the interstitial to navigate to the HTTP page.
    ProceedThroughInterstitial(contents);
  }

  // The security level should still be WARNING.
  EXPECT_EQ(security_state::WARNING, helper->GetSecurityLevel());
}

// Regression test for crbug.com/1233207.
// Tests the case where the HTTP version of a site redirects to HTTPS, but the
// HTTPS version of the site has a cert error. If the user initially navigates
// to the HTTP URL, then HTTPS-First Mode should upgrade the navigation to HTTPS
// and trigger the HTTPS-First Mode interstitial when that fails, but if the
// user clicks through the HTTPS-First Mode interstitial and falls back into the
// HTTP->HTTPS redirect back to the cert error, then the SSL interstitial should
// be shown and the user should be able to click through the SSL interstitial to
// visit the HTTPS version of the site (but in a DANGEROUS security level
// state).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       HttpsUpgradeWithBrokenSSL_ShouldTriggerSSLInterstitial) {
  // Set up a new test server instance so it can have a custom handler that
  // redirects to the HTTPS server.
  net::EmbeddedTestServer upgrading_server{net::EmbeddedTestServer::TYPE_HTTP};
  upgrading_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
        response->set_code(net::HTTP_TEMPORARY_REDIRECT);
        response->AddCustomHeader(
            "Location",
            "https://bad-https.com:" +
                base::NumberToString(
                    HttpsUpgradesInterceptor::GetHttpsPortForTesting()) +
                "/simple.html");
        return response;
      }));
  ASSERT_TRUE(upgrading_server.Start());
  HttpsUpgradesInterceptor::SetHttpPortForTesting(upgrading_server.port());

  GURL http_url = upgrading_server.GetURL("bad-https.com", "/simple.html");
  // HTTPS server will have a cert error.
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // The HTTPS-First Mode interstitial should trigger first.
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));

    // Proceeding through the HTTPS-First Mode interstitial will hit the
    // upgrading server's HTTP->HTTPS redirect. This should result in an SSL
    // interstitial (not an HTTPS-First Mode interstitial).
    ProceedThroughInterstitial(contents);
  }

  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents));

  // Proceeding through the SSL interstitial should navigate to the HTTPS
  // version of the site but with the DANGEROUS security level.
  ProceedThroughInterstitial(contents);
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  auto* helper = SecurityStateTabHelper::FromWebContents(contents);
  EXPECT_EQ(security_state::DANGEROUS, helper->GetSecurityLevel());

  // Verify that navigation event metrics were correctly recorded. They should
  // only have been recorded for the initial navigation that resulted in the
  // HTTPS-First Mode interstitial.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Verify that the interstitial metrics were correctly recorded.
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::SHOW, 1);
    histograms()->ExpectBucketCount(
        "interstitial.https_first_mode.decision",
        security_interstitials::MetricsHelper::Decision::PROCEED, 1);
  }
}

// Tests that clicking the "Learn More" link in the HTTPS-First Mode
// interstitial opens a new tab for the help center article.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, InterstitialLearnMoreLink) {
  // This test is only relevant to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));

  // Simulate clicking the learn more link (CMD_OPEN_HELP_CENTER).
  ASSERT_TRUE(content::ExecJs(
      contents, "window.certificateErrorPageController.openHelpCenter();"));

  // New tab should include the p-link "first_mode".
  EXPECT_EQ(GetBrowser()
                ->tab_strip_model()
                ->GetActiveWebContents()
                ->GetVisibleURL()
                .GetQuery(),
            "p=first_mode");

  // Verify that the interstitial metrics were correctly recorded.
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::SHOW, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.interaction",
      security_interstitials::MetricsHelper::Interaction::TOTAL_VISITS, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.interaction",
      security_interstitials::MetricsHelper::Interaction::SHOW_LEARN_MORE, 1);
}

// Tests that if the user bypasses the HTTPS-First Mode interstitial, and then
// later the server fixes their HTTPS support and the user successfully connects
// over HTTPS, the allowlist entry is cleared (so HFM will kick in again for
// that site).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, BadHttpsFollowedByGoodHttps) {
  // TODO(crbug.com/40248833): This test is flakey when only HTTPS Upgrades are
  // enabled.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL bad_https_url = https_server()->GetURL("foo.com", "/close-socket");
  GURL good_https_url = https_server()->GetURL("foo.com", "/ssl/google.html");

  ASSERT_EQ(http_url.GetHost(), bad_https_url.GetHost());
  ASSERT_EQ(bad_https_url.GetHost(), good_https_url.GetHost());

  auto* tab = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  auto* profile = Profile::FromBrowserContext(tab->GetBrowserContext());
  auto* state = static_cast<StatefulSSLHostStateDelegate*>(
      profile->GetSSLHostStateDelegate());

  // First check that main frame requests revoke the decision.

  // Navigate to `http_url`, which will get upgraded to `bad_https_url`.
  NavigateAndWaitForFallback(tab, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ASSERT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(tab));
    ProceedThroughInterstitial(tab);
  }

  EXPECT_TRUE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));

  EXPECT_TRUE(content::NavigateToURL(tab, good_https_url));
  EXPECT_FALSE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));

  // Rarely, an open connection with the bad cert might be reused for the next
  // navigation, which is supposed to show an interstitial. Close open
  // connections to ensure a fresh connection (and certificate validation) for
  // the next navigation. See https://crbug.com/1150592. A deeper fix for this
  // issue would be to unify certificate bypass logic which is currently split
  // between the net stack and content layer; see https://crbug.com/40418163.
  // See also: SSLUITest.BadCertFollowedByGoodCert.
  state->RevokeUserAllowExceptionsHard(http_url.GetHost());

  // Now check that subresource requests revoke the decision.

  // Navigate to `http_url`, which will get upgraded to `bad_https_url`.
  NavigateAndWaitForFallback(tab, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    ASSERT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(tab));
    ProceedThroughInterstitial(tab);
  }

  EXPECT_TRUE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));

  // Load "logo.gif" as an image on the page.
  GURL image = https_server()->GetURL("foo.com", "/ssl/google_files/logo.gif");

  // TODO(crbug.com/422956041): this fetch generates an LNA request, its unclear
  // why. Investigation is required to see if this is an LNA bug or not.
  EXPECT_EQ(
      true,
      EvalJs(tab,
             std::string("var img = document.createElement('img');img.src ='") +
                 image.spec() +
                 "';"
                 "new Promise(resolve => {"
                 "  img.onload=function() { "
                 "    resolve(true); };"
                 "  document.body.appendChild(img);"
                 "});"));

  EXPECT_FALSE(state->HasAllowException(
      http_url.GetHost(), tab->GetPrimaryMainFrame()->GetStoragePartition()));
}

// Tests that clicking the "Go back" button in the HTTPS-First Mode interstitial
// navigates back to the previous page (about:blank in this case).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, InterstitialGoBack) {
  // This test is only relevant to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));

  // Simulate clicking the "Go back" button.
  DontProceedThroughInterstitial(contents);

  EXPECT_EQ(GURL("about:blank"), contents->GetLastCommittedURL());

  // Verify that the interstitial metrics were correctly recorded.
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::SHOW, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialDontProceed);
}

// Tests that closing the tab of the HTTPS-First Mode interstitial counts as
// not proceeding through the interstitial for metrics.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, CloseInterstitialTab) {
  // This test is only relevant to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL http_url = http_server()->GetURL("foo.com", "/close-socket");
  GURL https_url = https_server()->GetURL("foo.com", "/close-socket");

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));

  // Leave the interstitial by closing the tab.
  chrome::CloseWebContents(GetBrowser(), contents, false);

  // Verify that the interstitial metrics were correctly recorded.
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::SHOW, 1);
  histograms()->ExpectBucketCount(
      "interstitial.https_first_mode.decision",
      security_interstitials::MetricsHelper::Decision::DONT_PROCEED, 1);

  ExpectUKMEntry(http_url, BlockingResult::kInterstitialDontProceed);
}

// Tests that if a user allowlists a host and then does not visit it again for
// seven days (the expiration period), then the interstitial will be shown again
// the next time they visit the host.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, AllowlistEntryExpires) {
  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set a testing clock on the StatefulSSLHostStateDelegate, keeping a pointer
  // to the clock object around so the test can manipulate time. `chrome_state`
  // takes ownership of `clock`.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  // Visit a host that doesn't support HTTPS for the first time, and click
  // through the HTTPS-First Mode interstitial to allowlist the host.
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    ProceedThroughInterstitial(contents);
  }

  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  // Simulate the clock advancing by 16 days, which is past the expiration
  // point.
  clock_ptr->Advance(base::Days(16));

  // The host should no longer be allowlisted, and the interstitial should
  // trigger again.
  EXPECT_FALSE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
}

// Tests that re-visiting an allowlisted host bumps the expiration time to a new
// seven days in the future from now.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, RevisitingBumpsExpiration) {
  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set a testing clock on the StatefulSSLHostStateDelegate, keeping a pointer
  // to the clock object around so the test can manipulate time. `chrome_state`
  // takes ownership of `clock`.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  // Visit a host that doesn't support HTTPS for the first time, and click
  // through the HTTPS-First Mode interstitial to allowlist the host.
  GURL http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  NavigateAndWaitForFallback(contents, http_url);

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
    ProceedThroughInterstitial(contents);
  }

  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  // Simulate the clock advancing by ten days.
  clock_ptr->Advance(base::Days(10));

  // Navigate to the host again; this will reset the allowlist expiration to
  // now + 7 days.
  EXPECT_TRUE(content::NavigateToURL(contents, http_url));

  // Simulate the clock advancing another ten days. This will be _after_ the
  // initial expiration date of the allowlist entry, but _before_ the bumped
  // expiration date from the second navigation.
  clock_ptr->Advance(base::Days(10));
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
  EXPECT_TRUE(content::NavigateToURL(contents, http_url));
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));
}

// Tests that if a hostname has an HSTS entry registered, then HTTPS-First Mode
// should not try to upgrade it (instead allowing HSTS to handle the upgrade as
// it is more strict).
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, PreferHstsOverHttpsFirstMode) {
  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  // URL for HTTPS server that will result in a certificate error.
  GURL https_url = https_server()->GetURL("bad-https.com", "/simple.html");

  // HTTP version of that URL that will get upgraded to HTTPS (but with the
  // correct port for the HTTPS server -- the test code can configure
  // HTTPS-First Mode to be aware of the different ports, but can't do that for
  // HSTS).
  GURL::Replacements downgrade_scheme_to_http;
  downgrade_scheme_to_http.SetSchemeStr(url::kHttpScheme);
  GURL http_url = https_url.ReplaceComponents(downgrade_scheme_to_http);

  // Set HTTP testing port to match `http_url`.
  HttpsUpgradesInterceptor::SetHttpPortForTesting(http_url.EffectiveIntPort());

  // Add hostname to the TransportSecurityState.
  base::Time expiry = base::Time::Now() + base::Days(100);
  bool include_subdomains = false;
  auto* network_context =
      profile->GetDefaultStoragePartition()->GetNetworkContext();
  base::RunLoop run_loop;
  network_context->AddHSTS(http_url.GetHost(), expiry, include_subdomains,
                           run_loop.QuitClosure());
  run_loop.Run();

  // Navigate to the HTTP URL. It should get upgraded to HTTPS and trigger a
  // fatal certificate error (because of HTTPS) instead of falling back to the
  // HTTPS-First Mode interstitial.
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingSSLInterstitial(contents));

  // Verify that no HFM event histograms were emitted (to check that HFM did not
  // trigger for this navigation at all).
  histograms()->ExpectTotalCount(kEventHistogram, 0);

  // Verify that general navigation request metrics were recorded.
  histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kHstsUpgraded,
                                  1);
  histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                  NavigationRequestSecurityLevel::kSecure, 1);
}

// Regression test for crbug.com/1272781. Previously, performing back/forward
// navigations around the HTTPS-First Mode interstitial could cause history
// entries to dropped.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       InterstitialFallbackMaintainsHistory) {
  // This test only applies to HTTPS-First Mode.
  if (!IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }

  GURL good_https_url = https_server()->GetURL("site1.com", "/defaultresponse");

  // Set up a new test server instance so it can have a custom handler.
  net::EmbeddedTestServer downgrading_server{
      net::EmbeddedTestServer::TYPE_HTTPS};
  // Downgrade by swapping the scheme for HTTP. HTTPS-First Mode will upgrade it
  // back to HTTPS.
  downgrading_server.RegisterRequestHandler(base::BindLambdaForTesting(
      [&](const net::test_server::HttpRequest& request)
          -> std::unique_ptr<net::test_server::HttpResponse> {
        GURL::Replacements http_downgrade;
        http_downgrade.SetSchemeStr(url::kHttpScheme);
        // The HttpRequest will by default refer to the test server by the
        // loopback address rather than any hostname in the navigation (i.e.,
        // the EmbeddedTestServer has no notion of virtual hosts). This
        // explicitly sets the hostname back to the test host so that this
        // doesn't fail due to the exception for localhost.
        http_downgrade.SetHostStr("site2.com");
        auto redirect_url = request.GetURL().ReplaceComponents(http_downgrade);
        auto response = std::make_unique<net::test_server::BasicHttpResponse>();
        response->set_code(net::HTTP_TEMPORARY_REDIRECT);
        response->AddCustomHeader("Location", redirect_url.spec());
        return response;
      }));
  ASSERT_TRUE(downgrading_server.Start());
  HttpsUpgradesInterceptor::SetHttpPortForTesting(downgrading_server.port());
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(downgrading_server.port());

  GURL downgrading_https_url = downgrading_server.GetURL("site2.com", "/");
  GURL::Replacements swap_http_scheme;
  swap_http_scheme.SetSchemeStr(url::kHttpScheme);
  GURL downgrading_http_url =
      downgrading_https_url.ReplaceComponents(swap_http_scheme);

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  // Navigate to a "good" HTTPS site.
  EXPECT_TRUE(content::NavigateToURL(contents, good_https_url));

  // Navigate to the HTTP version of `downgrading_https_url`, which will get
  // upgraded to HTTPS and fail, triggering the HTTPS-First Mode
  // interstitial.
  content::NavigateToURLBlockUntilNavigationsComplete(contents,
                                                      downgrading_http_url, 1);
  EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));

  // Simulate clicking the browser "back" button.
  EXPECT_TRUE(content::HistoryGoBack(contents));
  EXPECT_EQ(good_https_url, contents->GetLastCommittedURL());
  auto* helper = SecurityStateTabHelper::FromWebContents(contents);
  EXPECT_EQ(security_state::SECURE, helper->GetSecurityLevel());

  // Simulate clicking the browser "forward" button. The HistoryGoForward()
  // call returns `false` because it is an error page.
  EXPECT_FALSE(content::HistoryGoForward(contents));
  EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));

  // No forward entry should be present.
  EXPECT_FALSE(contents->GetController().CanGoForward());

  // Simulate clicking the browser "back" button again. Previously this would
  // result in `about:blank` being shown.
  EXPECT_TRUE(content::HistoryGoBack(contents));
  EXPECT_EQ(good_https_url, contents->GetLastCommittedURL());

  // Repeat forward one last time. (Previously the user would no longer be able
  // to go back any more as the history entries were lost.)
  EXPECT_FALSE(content::HistoryGoForward(contents));  // error page -> false
  EXPECT_EQ(downgrading_http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));
  EXPECT_TRUE(contents->GetController().CanGoBack());
}

// Tests that if the HttpAllowlist enterprise policy is set, then HTTPS upgrades
// are skipped for hosts in the allowlist. Includes simple hostname, wildcard
// hostname pattern, and bare IP address cases.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       EnterpriseAllowlistDisablesUpgrades) {
  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();

  // Without any policy allowlist, navigate to HTTP URL on foo.com. It *should*
  // get upgraded to HTTPS.
  auto http_url = http_server()->GetURL("foo.com", "/simple.html");
  auto https_url = https_server()->GetURL("foo.com", "/simple.html");
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // Artificially add the pref that gets mapped from the enterprise policy.
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  auto* prefs = profile->GetPrefs();
  base::ListValue allowlist;
  allowlist.Append("foo.com");
  allowlist.Append("[*.]bar.com");
  allowlist.Append(http_server()->GetIPLiteralString());
  // These cases should not work, but the policy->pref mapping won't immediately
  // reject them.
  allowlist.Append("[*]");
  allowlist.Append("*");
  prefs->SetList(prefs::kHttpAllowlist, std::move(allowlist));

  // Navigate to HTTP URL on foo.com. It should not get upgraded to HTTPS and
  // no interstitial should be shown.
  http_url = http_server()->GetURL("foo.com", "/simple.html");
  https_url = https_server()->GetURL("foo.com", "/simple.html");
  EXPECT_TRUE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));

  // Navigate to HTTP URL on bar.com. Same result.
  http_url = http_server()->GetURL("bar.com", "/simple.html");
  https_url = https_server()->GetURL("bar.com", "/simple.html");
  EXPECT_TRUE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));

  // Navigate to HTTP URL on bar.bar.com. Same result as subdomain wildcard
  // was specified.
  http_url = http_server()->GetURL("bar.bar.com", "/simple.html");
  https_url = https_server()->GetURL("bar.bar.com", "/simple.html");
  EXPECT_TRUE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));

  // Navigate to HTTP URL on foo.foo.com. Subdomains of foo.com should not be
  // considered as being in the allowlist as no wildcard was specified. This
  // should get upgraded to HTTPS.
  http_url = http_server()->GetURL("foo.foo.com", "/simple.html");
  https_url = https_server()->GetURL("foo.foo.com", "/simple.html");
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // Navigate to HTTP URL on baz.com, which is not on the allowlist. Should get
  // upgraded to HTTPS.
  http_url = http_server()->GetURL("baz.com", "/simple.html");
  https_url = https_server()->GetURL("baz.com", "/simple.html");
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(https_url, contents->GetLastCommittedURL());

  // Navigate to HTTP URL on the HTTP test server's IP address. It should not
  // get upgraded to HTTPS and no interstitial should be shown.
  http_url = http_server()->GetURL("/simple.html");
  https_url = https_server()->GetURL("/simple.html");
  EXPECT_TRUE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));
}

// Tests that if the HttpAllowlist enterprise policy is set, then HTTPS upgrades
// and HTTPS-First Mode For Site Engagement checks are skipped for hosts in the
// allowlist.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    EnterpriseAllowlistDisablesHttpsFirstModeForSiteEngagament) {
  // Skip this test when HTTPS-First Mode for Site Engagement isn't enabled.
  if (!IsSiteEngagementHeuristicEnabled()) {
    return;
  }
  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());

  // Without any policy allowlist, navigate to an HTTP URL. It should show the
  // HFM+SE interstitial.
  GURL http_url("http://bad-https.com");
  GURL https_url("https://bad-https.com");
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);

  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));

  // Artificially add the pref that gets mapped from the enterprise policy.
  auto* prefs = profile->GetPrefs();
  base::ListValue allowlist;
  allowlist.Append("bad-https.com");
  prefs->SetList(prefs::kHttpAllowlist, std::move(allowlist));

  // Navigate to the same URL. It should not get upgraded to HTTPS and
  // no interstitial should be shown.
  EXPECT_TRUE(content::NavigateToURL(contents, http_url));
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));
}

IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       EnterprisePolicyDisablesUpgrades) {
  // Disable HTTPS-Upgrades via enterprise policy.
  auto* prefs = browser()->profile()->GetPrefs();
  prefs->SetBoolean(prefs::kHttpsUpgradesEnabled, false);

  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // HTTPS-First Mode should supercede HTTPS-Upgrades and upgrade the
    // navigation despite the HttpsUpgradeMode policy setting.
    EXPECT_FALSE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // If HTTPS-First Mode is not enabled but upgrading is, then the policy
    // should prevent the upgrade.
    EXPECT_TRUE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 1);
  }
}

// Test that HTTPS Upgrades are skipped if the "Insecure content" site setting
// is set to "allow".
// MIXED_SCRIPT isn't enabled as a content setting on Android.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_InsecureContentSettingDisablesUpgrades \
  DISABLED_InsecureContentSettingDisablesUpgrades
#else
#define MAYBE_InsecureContentSettingDisablesUpgrades \
  InsecureContentSettingDisablesUpgrades
#endif
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       MAYBE_InsecureContentSettingDisablesUpgrades) {
  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  auto* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile);

  // Set insecure content setting to allowed for `http_url`.
  host_content_settings_map->SetContentSettingDefaultScope(
      http_url, GURL(), ContentSettingsType::MIXEDSCRIPT,
      CONTENT_SETTING_ALLOW);

  if (IsHttpsFirstModePrefEnabled()) {
    // If HTTPS-First Mode is enabled, upgrades should still be applied.
    EXPECT_FALSE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 1);
  }

  // Unset the content settings.
  host_content_settings_map->ClearSettingsForOneType(
      ContentSettingsType::MIXEDSCRIPT);

  // Set insecure content setting to allowed for `https_url`.
  HostContentSettingsMapFactory::GetForProfile(profile)
      ->SetContentSettingDefaultScope(https_url, GURL(),
                                      ContentSettingsType::MIXEDSCRIPT,
                                      CONTENT_SETTING_ALLOW);
  if (IsHttpsFirstModePrefEnabled()) {
    // If HTTPS-First Mode is enabled, upgrades should still be applied.
    EXPECT_FALSE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    2);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 2);
  }
}

// Test that HTTPS Upgrades are skipped if the "Insecure content" site setting
// is set to "allow".
// MIXED_SCRIPT isn't enabled as a content setting on Android.
// This test is identical to InsecureContentSettingDisablesUpgrades except it
// sets a high site engagement score for the https URL and checks an additional
// histogram.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_InsecureContentSettingDisablesHFMForEngagedSites \
  DISABLED_InsecureContentSettingDisablesHFMForEngagedSites
#else
#define MAYBE_InsecureContentSettingDisablesHFMForEngagedSites \
  InsecureContentSettingDisablesHFMForEngagedSites
#endif
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       MAYBE_InsecureContentSettingDisablesHFMForEngagedSites) {
  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  auto* host_content_settings_map =
      HostContentSettingsMapFactory::GetForProfile(profile);

  // Setting a high engagement score on the HTTPS URL enables HFM on the site
  // if the HFM+SE feature is enabled, but an Insecure Content entry disables
  // HFM+SE on the site.
  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);

  // Set insecure content setting to allowed for `http_url`.
  host_content_settings_map->SetContentSettingDefaultScope(
      http_url, GURL(), ContentSettingsType::MIXEDSCRIPT,
      CONTENT_SETTING_ALLOW);

  if (IsHttpsFirstModePrefEnabled()) {
    // If HTTPS-First Mode is fully enabled, upgrades should still be applied.
    EXPECT_FALSE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 1);
  }
  // In both cases, HFM+SE events shouldn't be recorded because of the Insecure
  // content setting.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

  // Unset the content settings.
  host_content_settings_map->ClearSettingsForOneType(
      ContentSettingsType::MIXEDSCRIPT);

  // Set insecure content setting to allowed for `https_url`.
  HostContentSettingsMapFactory::GetForProfile(profile)
      ->SetContentSettingDefaultScope(https_url, GURL(),
                                      ContentSettingsType::MIXEDSCRIPT,
                                      CONTENT_SETTING_ALLOW);
  if (IsHttpsFirstModePrefEnabled()) {
    // If HTTPS-First Mode is enabled, upgrades should still be applied.
    EXPECT_FALSE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    2);
  } else {
    // Otherwise, the upgrades should be skipped.
    EXPECT_TRUE(content::NavigateToURL(contents, http_url));
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kAllowlisted, 2);
  }
  // In both cases, HFM+SE events shouldn't be recorded because of the Insecure
  // content setting.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);
}

// Regression test for crbug.com/1431026. Triggers a navigation where HTTPS
// upgrades applied multiple times across redirects to different sites.
// Should not crash when DCHECKS are enabled.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest, crbug1431026) {
  GURL www_bad_https_url =
      https_server()->GetURL("www.bad-https.com", "/simple.html");
  GURL www_http_url =
      http_server()->GetURL("www.bad-https.com", "/simple.html");

  // Configure HTTP and bad-HTTPS URLs which redirect to www. subdomain.
  std::string www_redirect_path =
      base::StrCat({"/server-redirect?", www_http_url.spec()});
  GURL redirecting_bad_https_url =
      https_server()->GetURL("bad-https.com", www_redirect_path);
  GURL redirecting_http_url =
      http_server()->GetURL("bad-https.com", www_redirect_path);

  // A good HTTPS URL which redirects to an HTTP URL, which also redirects.
  GURL initial_redirecting_good_https_url = https_server()->GetURL(
      "good-https.com",
      base::StrCat({"/server-redirect-301?", redirecting_http_url.spec()}));

  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_FALSE(
      content::NavigateToURL(contents, initial_redirecting_good_https_url));

  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    // Should be showing interstitial on http://bad-https.com/.
    EXPECT_EQ(redirecting_http_url, contents->GetLastCommittedURL());
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  } else {
    // Either due to no upgrades, or due to fast fallback to HTTP, this should
    // end up on http://www.bad-https.com.
    EXPECT_EQ(www_http_url, contents->GetLastCommittedURL());
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }
}

// Tests that when the HTTPS-First Mode setting is toggled on or off, the
// HTTP allowlist is cleared.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       TogglingSettingClearsAllowlist) {
  // The allowlist in an Incognito window is in-memory only, and is not cleared
  // when the main profile's pref changes.
  // TODO(crbug.com/40937027): Add a test to cover the Incognito allowlisting
  // behavior explicitly.
  if (IsIncognito()) {
    return;
  }

  auto http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();

  // Start by enabling HTTPS-First Mode.
  SetPref(true);

  // Navigate to a URL that will fail upgrades, and click through the
  // interstitial to add it to the allowlist.
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));
  ProceedThroughInterstitial(contents);

  // Disable the HTTPS-First Mode pref. This should clear the allowlist.
  SetPref(false);

  if (InBalancedMode()) {
    EXPECT_FALSE(content::NavigateToURL(contents, http_url));
    EXPECT_TRUE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));

    // Proceed through the interstitial and add the host to the allowlist.
    ProceedThroughInterstitial(contents);
  } else {
    // With HTTPS-Upgrades enabled, navigating again should cause the site to
    // get added back to the allowlist.
    EXPECT_TRUE(content::NavigateToURL(contents, http_url));
    EXPECT_FALSE(
        chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
            contents));
  }

  // Re-enable the HTTPS-First Mode pref. The allowlist should be cleared again.
  SetPref(true);

  // Navigate to a URL that will fail upgrades, and the interstitial should be
  // shown again as the allowlist was cleared.
  EXPECT_FALSE(content::NavigateToURL(contents, http_url));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));
}

// Main window HTTP allowlist should not apply to Incognito window.
// Regression test for crbug.com/40949400.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       IncognitoHasSeparateAllowlist) {
  // This test only covers the case of HFM-in-Incognito.
  if (!IsIncognito()) {
    return;
  }
  // In a regular window, add a host to the HTTP allowlist.
  // Note: This is explicitly done with HTTPS-First Mode disabled as that is the
  // specific regression case for crbug.com/40949400, but HTTPS-First Mode and
  // HTTPS-Upgrades may eventually have separate allowlists.
  SetPref(false);
  auto http_url = http_server()->GetURL("bad-https.com", "/simple.html");
  auto* normal_tab = browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::NavigateToURL(normal_tab, http_url));
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          normal_tab));

  // In an Incognito window, navigating to that same host should still trigger
  // the HTTP interstitial, as the allowlist is not inherited.
  auto* incognito_tab = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_FALSE(content::NavigateToURL(incognito_tab, http_url));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      incognito_tab));
}

// Tests that URLs typed with an explicit http:// scheme are opted out from
// upgrades.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       URLsTypedWithHttpSchemeNoUpgrades) {
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  OmniboxClient* omnibox_client = GetBrowser()
                                      ->window()
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate the full URL was typed with an http scheme.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::URL_WHAT_YOU_TYPED,
      base::TimeTicks(), false, true, std::u16string(), AutocompleteMatch(),
      AutocompleteMatch());
  nav_observer.Wait();

  if (IsHttpsFirstModePrefEnabled() || IsIncognito()) {
    // Typed http URLs don't opt out of upgrades in HFM.
    EXPECT_EQ(https_url, contents->GetLastCommittedURL());
  } else {
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 1);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kExplicitHttpScheme, 1);
    EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  }
}

// Tests that URLs with an explicit http:// scheme are upgraded if they were
// autocompleted.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       URLsAutocompletedWithHttpSchemeAreUpgraded) {
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  OmniboxClient* omnibox_client = GetBrowser()
                                      ->window()
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  // Simulate the full URL was autocompleted with an http scheme.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::NAVSUGGEST,
      base::TimeTicks(), false, false, std::u16string(), AutocompleteMatch(),
      AutocompleteMatch());
  nav_observer.Wait();

  EXPECT_EQ(https_url, contents->GetLastCommittedURL());
}

// Tests that URLs typed with an explicit http:// scheme that result in an
// opt-out cause the url to be added to the allowlist.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBrowserTest,
                       URLsTypedWithHttpSchemeNoUpgradesAllowlist) {
  if (IsHttpsFirstModeInterstitialEnabledAcrossSites()) {
    return;
  }
  GURL http_url = http_server()->GetURL("foo.com", "/simple.html");
  GURL https_url = https_server()->GetURL("foo.com", "/simple.html");
  auto* contents = GetBrowser()->tab_strip_model()->GetActiveWebContents();
  OmniboxClient* omnibox_client = GetBrowser()
                                      ->window()
                                      ->GetLocationBar()
                                      ->GetOmniboxController()
                                      ->client();

  Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Site should not yet be in the allowlist.
  EXPECT_FALSE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));

  // Simulate the full URL was typed with an http scheme.
  content::TestNavigationObserver nav_observer(contents, 1);
  omnibox_client->OnAutocompleteAccept(
      http_url, nullptr, WindowOpenDisposition::CURRENT_TAB,
      ui::PAGE_TRANSITION_TYPED, AutocompleteMatchType::URL_WHAT_YOU_TYPED,
      base::TimeTicks(), false, true, std::u16string(), AutocompleteMatch(),
      AutocompleteMatch());
  nav_observer.Wait();

  // URL should not have been upgraded, and site should now be in the allowlist.
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());
  EXPECT_TRUE(state->IsHttpAllowedForHost(
      http_url.GetHost(),
      contents->GetPrimaryMainFrame()->GetStoragePartition()));
}

// Url used to detect the presence of a captive portal.
constexpr char kCaptivePortalPingUrl[] = "http://captive-portal-ping-url.com/";
// HTTPS version of the same URL.
constexpr char kCaptivePortalPingUrlHttps[] =
    "https://captive-portal-ping-url.com/";

// Returns a URL loader interceptor that responds to HTTPS URLs with a cert
// error and to HTTP URLs with a good response.
std::unique_ptr<content::URLLoaderInterceptor> MakeCaptivePortalInterceptor(
    bool login_page_has_valid_https) {
  return std::make_unique<content::URLLoaderInterceptor>(
      base::BindLambdaForTesting(
          [login_page_has_valid_https](
              content::URLLoaderInterceptor::RequestParams* params) {
            if (params->url_request.url == GURL(kCaptivePortalPingUrl) ||
                (login_page_has_valid_https &&
                 params->url_request.url == GURL(kCaptivePortalPingUrlHttps))) {
              // Return a non-204 response for the captive portal ping URL
              // so that the portal is detected.
              content::URLLoaderInterceptor::WriteResponse(
                  "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                  "<html>Non-204 response to trigger captive portal "
                  "detection</html>",
                  params->client.get());
              return true;
            }

            if (params->url_request.url.SchemeIs("https")) {
              // Fail with an SSL error so that a fallback is triggered.
              network::URLLoaderCompletionStatus status;
              status.error_code = net::ERR_CERT_COMMON_NAME_INVALID;
              status.ssl_info = net::SSLInfo();
              status.ssl_info->cert_status =
                  net::CERT_STATUS_COMMON_NAME_INVALID;
              // The cert doesn't matter.
              status.ssl_info->cert = net::ImportCertFromFile(
                  net::GetTestCertsDirectory(), "ok_cert.pem");
              status.ssl_info->unverified_cert = status.ssl_info->cert;
              params->client->OnComplete(status);
              return true;
            }
            content::URLLoaderInterceptor::WriteResponse(
                "HTTP/1.1 200 OK\nContent-type: text/html\n\n",
                "<html>Done</html>", params->client.get());
            return true;
          }));
}

void HttpsUpgradesBrowserTest::EnableCaptivePortalDetection(Browser* browser) {
  captive_portal::CaptivePortalService* captive_portal_service =
      CaptivePortalServiceFactory::GetForProfile(browser->profile());
  captive_portal_service->set_test_url(GURL(kCaptivePortalPingUrl));

  captive_portal::CaptivePortalService::set_state_for_testing(
      captive_portal::CaptivePortalService::NOT_TESTING);
  browser->profile()->GetPrefs()->SetBoolean(
      embedder_support::kAlternateErrorPagesEnabled, true);
}

// Checks that an automatically opened captive portal login page is not upgraded
// to HTTPS unless the interstitial is enabled. The captive portal's login
// page supports https.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    CaptivePortal_LoginPageWithValidSSL_ShouldNotUpgradeUnlessInterstitialEnabled) {
  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeIncognito) {
    return;
  }
  auto interceptor =
      MakeCaptivePortalInterceptor(/*login_page_has_valid_https=*/true);

  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  EnableCaptivePortalDetection(browser());

  auto* tab_strip = GetBrowser()->tab_strip_model();
  auto* contents = tab_strip->GetActiveWebContents();
  size_t tab_count = tab_strip->count();

  // Go to an HTTPS URL. The navigation will fail and trigger a captive portal
  // detection.
  ui_test_utils::TabAddedWaiter waiter(browser());
  NavigateAndWaitForFallback(contents,
                             GURL("https://ssl-error-for-captive-portal.com/"));
  waiter.Wait();

  // Captive portal login page should not be upgraded.
  content::WebContents* login_page = tab_strip->GetWebContentsAt(tab_count);
  content::WaitForLoadStop(login_page);
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          login_page));

  if (IsHttpsFirstModePrefEnabled()) {
    // If the interstitial is enabled, captive portal login page should also be
    // upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrlHttps),
              login_page->GetLastCommittedURL());

    // Should only attempt an upgrade for the original page.
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 3);
    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram. Captive portal login page is valid HTTPS, so
    // it's also counted here.
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 2);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Captive portal login page should not be upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrl), login_page->GetLastCommittedURL());

    // Should only attempt an upgrade for the original page.
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 2);
    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram:
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kCaptivePortalLogin, 1);
  }
}

// Same as
// CaptivePortal_LoginPageWithValidSSL_ShouldNotUpgradeUnlessInterstitialEnabled
// but the captive portal's login page serves bad SSL.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesBrowserTest,
    CaptivePortal_LoginPageWithoutValidSSL_ShouldNotUpgradeUnlessInterstitialEnabled) {
  if (https_upgrades_test_type() ==
      HttpsUpgradesTestType::kHttpsFirstModeIncognito) {
    return;
  }
  auto interceptor =
      MakeCaptivePortalInterceptor(/*login_page_has_valid_https=*/true);

  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  EnableCaptivePortalDetection(browser());

  auto* tab_strip = GetBrowser()->tab_strip_model();
  auto* contents = tab_strip->GetActiveWebContents();
  size_t tab_count = tab_strip->count();

  // Go to an HTTPS URL. The navigation will fail and trigger a captive portal
  // detection.
  ui_test_utils::TabAddedWaiter waiter(browser());
  NavigateAndWaitForFallback(contents,
                             GURL("https://ssl-error-for-captive-portal.com/"));
  waiter.Wait();

  content::WebContents* login_page = tab_strip->GetWebContentsAt(tab_count);
  content::WaitForLoadStop(login_page);

  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          login_page));

  if (IsHttpsFirstModePrefEnabled()) {
    // If the interstitial is enabled, captive portal login page should also be
    // upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrlHttps),
              login_page->GetLastCommittedURL());

    // Should only attempt an upgrade for the original page.
    histograms()->ExpectTotalCount(kNavigationRequestSecurityLevelHistogram, 3);
    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram. Captive portal login page is valid HTTPS, so
    // it's also counted here.
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 2);
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kUpgraded,
                                    1);
  } else {
    // Captive portal login page should not be upgraded to HTTPS.
    EXPECT_EQ(GURL(kCaptivePortalPingUrl), login_page->GetLastCommittedURL());

    // The original page serves bad HTTPS, but any HTTPS URL is counted as
    // secure in this histogram:
    histograms()->ExpectBucketCount(kNavigationRequestSecurityLevelHistogram,
                                    NavigationRequestSecurityLevel::kSecure, 1);
    histograms()->ExpectBucketCount(
        kNavigationRequestSecurityLevelHistogram,
        NavigationRequestSecurityLevel::kCaptivePortalLogin, 1);
  }
}

// A simple test fixture that constructs a HistogramTester (so that it gets
// initialized before browser startup). Used for testing pref tracking logic.
class HttpsUpgradesPrefsBrowserTest : public InProcessBrowserTest {
 public:
  HttpsUpgradesPrefsBrowserTest() {
    feature_list_.InitWithFeatures(
        /*enabled_features=*/{},
        /*disabled_features=*/{features::kHttpsFirstModeIncognito,
                               features::kHttpsFirstBalancedMode});
  }
  ~HttpsUpgradesPrefsBrowserTest() override = default;

 protected:
  void SetUISetting(HttpsFirstModeSetting setting) {
    extensions::settings_private::GeneratedPrefs prefs(browser()->profile());
    prefs.SetPref(
        kGeneratedHttpsFirstModePref,
        std::make_unique<base::Value>(static_cast<int>(setting)).get());
  }

  bool GetPref() const {
    auto* prefs = browser()->profile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsOnlyModeEnabled);
  }

  base::HistogramTester* histograms() { return &histograms_; }

 private:
  base::test::ScopedFeatureList feature_list_;
  base::HistogramTester histograms_;
};

// Tests that the HTTPS-First Mode state is recorded at startup and when
// changed. This test requires restarting the browser to test the "at startup"
// metric in order for the preference state to be set up before the
// HttpsFirstModeService is created.
IN_PROC_BROWSER_TEST_F(HttpsUpgradesPrefsBrowserTest, PRE_PrefStatesRecorded) {
  // The default pref state is `false`, which should get recorded when the
  // initial browser instance is started here.
  histograms()->ExpectUniqueSample(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2",
      HttpsFirstModeSetting::kDisabled, 1);

  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Disabled"));

  // Emulate changing the UI setting to Enabled. This should get recorded
  // in the histogram.
  SetUISetting(HttpsFirstModeSetting::kEnabledFull);
  histograms()->ExpectUniqueSample("Security.HttpsFirstMode.SettingChanged",
                                   true, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Enabled"));
}

IN_PROC_BROWSER_TEST_F(HttpsUpgradesPrefsBrowserTest, PrefStatesRecorded) {
  // Restarting the browser from the PRE_ test should record the startup setting
  // histogram. Checking the unique count also ensures that other profile
  // types (e.g. the ChromeOS sign-in profile) don't cause double-counting.
  EXPECT_TRUE(GetPref());
  histograms()->ExpectUniqueSample(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2",
      HttpsFirstModeSetting::kEnabledFull, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Enabled"));

  // Open an Incognito window. Startup metrics should not get recorded.
  CreateIncognitoBrowser();
  histograms()->ExpectTotalCount(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2", 1);
}

enum class BalancedModeParam {
  kNotAutoEnabled,
  kAutoEnabled,
};

// A simple test fixture that constructs a HistogramTester (so that it gets
// initialized before browser startup). Used for testing pref tracking logic.
// Variant of HttpsUpgradesPrefsBrowserTest but with the
// HttpsFirstBalancedMode feature enabled.
class HttpsUpgradesBalancedModePrefsBrowserTest
    : public testing::WithParamInterface<BalancedModeParam>,
      public InProcessBrowserTest {
 protected:
  void SetUp() override {
    // Feature flag must be enabled before SetUp() continues.
    switch (GetParam()) {
      case BalancedModeParam::kNotAutoEnabled:
        feature_list()->InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstBalancedMode},
            /*disabled_features=*/{
                features::kHttpsFirstBalancedModeAutoEnable});
        break;

      case BalancedModeParam::kAutoEnabled:
        feature_list()->InitWithFeatures(
            /*enabled_features=*/{features::kHttpsFirstBalancedMode,
                                  features::kHttpsFirstBalancedModeAutoEnable},
            /*disabled_features=*/{});
        break;
    }
    InProcessBrowserTest::SetUp();
  }

  void SetUISetting(HttpsFirstModeSetting setting) {
    extensions::settings_private::GeneratedPrefs prefs(browser()->profile());
    prefs.SetPref(
        kGeneratedHttpsFirstModePref,
        std::make_unique<base::Value>(static_cast<int>(setting)).get());
  }

  bool GetPref() const {
    auto* prefs = browser()->profile()->GetPrefs();
    return prefs->GetBoolean(prefs::kHttpsFirstBalancedMode);
  }

  base::test::ScopedFeatureList* feature_list() { return &feature_list_; }
  base::HistogramTester* histograms() { return &histograms_; }

 private:
  base::test::ScopedFeatureList feature_list_;
  base::HistogramTester histograms_;
};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    HttpsUpgradesBalancedModePrefsBrowserTest,
    ::testing::Values(BalancedModeParam::kNotAutoEnabled,
                      BalancedModeParam::kAutoEnabled),
    // Map param to a human-readable string for better test output.
    [](testing::TestParamInfo<BalancedModeParam> input_type) -> std::string {
      switch (input_type.param) {
        case BalancedModeParam::kNotAutoEnabled:
          return "BalancedModeNotAutoEnabled";
        case BalancedModeParam::kAutoEnabled:
          return "BalancedModeAutoEnabled";
      }
    });

// Tests that the HTTPS-First Mode setting is recorded at startup and when
// changed, when the HFM-Balanced-Mode feature flag is enabled. This test
// requires restarting the browser to test the "at startup" metric in order
// for the preference state to be set up before the HttpsFirstModeService is
// created.
IN_PROC_BROWSER_TEST_P(HttpsUpgradesBalancedModePrefsBrowserTest,
                       PRE_PrefStatesRecorded) {
  if (GetParam() == BalancedModeParam::kNotAutoEnabled) {
    // The default Balanced Mode pref state is false, which should get recorded
    // when the initial browser instance is started here.
    histograms()->ExpectUniqueSample(
        "Security.HttpsFirstMode.SettingEnabledAtStartup2",
        HttpsFirstModeSetting::kDisabled, 1);

    EXPECT_TRUE(variations::IsInSyntheticTrialGroup(
        "HttpsFirstModeClientSetting", "Disabled"));
  } else if (GetParam() == BalancedModeParam::kAutoEnabled) {
    // The default Balanced Mode pref state is false, but Balanced Mode is auto
    // enabled.
    histograms()->ExpectUniqueSample(
        "Security.HttpsFirstMode.SettingEnabledAtStartup2",
        HttpsFirstModeSetting::kEnabledBalanced, 1);

    EXPECT_TRUE(variations::IsInSyntheticTrialGroup(
        "HttpsFirstModeClientSetting", "Balanced"));
  }

  // Emulate changing the UI setting to Balanced Mode. This should get recorded
  // in the histogram.
  SetUISetting(HttpsFirstModeSetting::kEnabledBalanced);
  EXPECT_TRUE(GetPref());
  histograms()->ExpectUniqueSample("Security.HttpsFirstMode.SettingChanged2",
                                   HttpsFirstModeSetting::kEnabledBalanced, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Balanced"));
}

IN_PROC_BROWSER_TEST_P(HttpsUpgradesBalancedModePrefsBrowserTest,
                       PrefStatesRecorded) {
  // Restarting the browser from the PRE_ test should record the startup setting
  // histogram. Checking the unique count also ensures that other profile
  // types (e.g. the ChromeOS sign-in profile) don't cause double-counting.
  EXPECT_TRUE(GetPref());
  histograms()->ExpectUniqueSample(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2",
      HttpsFirstModeSetting::kEnabledBalanced, 1);
  EXPECT_TRUE(variations::IsInSyntheticTrialGroup("HttpsFirstModeClientSetting",
                                                  "Balanced"));

  // Open an Incognito window. Startup metrics should not get recorded.
  CreateIncognitoBrowser();
  histograms()->ExpectTotalCount(
      "Security.HttpsFirstMode.SettingEnabledAtStartup2", 1);
}

using TypicallySecureUserBrowserTest = InProcessBrowserTest;

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       PRE_RestoreCountsOnStartup_OneNavigation) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->profile());
  hfm_service->IncrementRecentNavigationCount();
}

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       RestoreCountsOnStartup_OneNavigation) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->profile());
  // A single navigation will not be persisted to the pref and won't be
  // restored on startup because navigations are persisted in batches of 10.
  EXPECT_EQ(0u, hfm_service->GetRecentNavigationCount());
}

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       PRE_RestoreCountsOnStartup_TenNavigations) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->profile());
  // Increment repeatedly to force the counts to be persisted to the pref.
  for (size_t i = 0; i < 10; i++) {
    hfm_service->IncrementRecentNavigationCount();
  }
}

IN_PROC_BROWSER_TEST_F(TypicallySecureUserBrowserTest,
                       RestoreCountsOnStartup_TenNavigations) {
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(browser()->profile());
  EXPECT_EQ(10u, hfm_service->GetRecentNavigationCount());
}

// Tests for HFM heuristics without Balanced Mode enabled. These are unusual
// configurations and shouldn't appear in production.
// TODO(crbug.com/349860796): Remove after balanced mode is fully launched.
using HttpsUpgradesHeuristicsWithoutBalancedModeBrowserTest =
    HttpsUpgradesBrowserTest;

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    HttpsUpgradesHeuristicsWithoutBalancedModeBrowserTest,
    ::testing::Values(
        HttpsUpgradesTestType::
            kHttpsFirstModeWithSiteEngagementWithoutBalancedMode));

// Test that Site Engagement Heuristic without Balanced Mode is a no-op.
IN_PROC_BROWSER_TEST_P(
    HttpsUpgradesHeuristicsWithoutBalancedModeBrowserTest,
    UrlWithHttpScheme_BrokenSSL_SiteEngagementHeuristicWithoutBalancedMode_ShouldIgnore) {
  ASSERT_FALSE(IsIncognito() || IsHttpsFirstModePrefEnabled());

  // Disable the testing port configuration, as this test doesn't use the
  // EmbeddedTestServer.
  HttpsUpgradesInterceptor::SetHttpsPortForTesting(0);
  HttpsUpgradesInterceptor::SetHttpPortForTesting(0);
  auto url_loader_interceptor = MakeInterceptorForSiteEngagementHeuristic();

  content::WebContents* contents =
      GetBrowser()->tab_strip_model()->GetActiveWebContents();
  Profile* profile = GetBrowser()->profile();
  content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate();

  // Set test clock.
  auto clock = std::make_unique<base::SimpleTestClock>();
  auto* clock_ptr = clock.get();
  StatefulSSLHostStateDelegate* chrome_state =
      static_cast<StatefulSSLHostStateDelegate*>(state);
  chrome_state->SetClockForTesting(std::move(clock));

  // Start the clock at standard system time.
  clock_ptr->SetNow(base::Time::NowFromSystemTime());

  // Set site engagement scores so that this site would have HFM enabled if
  // HFM+SE kicked in.
  GURL http_url("http://example.com");
  GURL https_url("https://example.com");

  SetSiteEngagementScore(http_url, kLowSiteEngagementScore);
  SetSiteEngagementScore(https_url, kHighSiteEnagementScore);
  HttpsFirstModeService* hfm_service =
      HttpsFirstModeServiceFactory::GetForProfile(profile);
  MaybeEnableHttpsFirstModeForEngagedSitesAndWait(hfm_service);

  // This URL should be upgraded by HTTPS-Upgrades and should fall back to HTTP,
  // but not have HFM auto-enabled on it because balanced mode isn't enabled.
  NavigateAndWaitForFallback(contents, http_url);
  EXPECT_EQ(http_url, contents->GetLastCommittedURL());

  EXPECT_EQ(HFMInterstitialType::kNone,
            chrome_browser_interstitials::GetHFMInterstitialType(contents));

  // Verify that navigation event metrics were correctly recorded.
  histograms()->ExpectTotalCount(kEventHistogram, 3);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeAttempted, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeFailed, 1);
  histograms()->ExpectBucketCount(kEventHistogram, Event::kUpgradeCertError, 1);

  // Engagement heuristic shouldn't handle any navigation events.
  histograms()->ExpectTotalCount(kEventHistogramWithEngagementHeuristic, 0);

  // Security level histogram should not record kHttpsEnforcedOnHostname.
  histograms()->ExpectBucketCount(
      kNavigationRequestSecurityLevelHistogram,
      NavigationRequestSecurityLevel::kHttpsEnforcedOnHostname, 0);
}

// Minimal test fixture for testing the interaction between the
// SecureOriginAllowlist (set via the command-line switch
// `switches::kUnsafelyTreatInsecureOriginAsSecure`) and HTTPS-First Balanced
// Mode.
class HttpsUpgradesSecureOriginAllowlistBrowserTest
    : public InProcessBrowserTest {
 public:
  HttpsUpgradesSecureOriginAllowlistBrowserTest() {
    feature_list_.InitWithFeatures(
        {features::kHttpsFirstBalancedModeAutoEnable},
        // TODO(crbug.com/351990829): Update these tests to work with the new
        // native dialog UI, and then re-enable this feature.
        {security_interstitials::features::kHttpsFirstDialogUi});
  }
  ~HttpsUpgradesSecureOriginAllowlistBrowserTest() override = default;

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    embedded_test_server()->AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(embedded_test_server()->Start());
    HttpsUpgradesInterceptor::SetHttpPortForTesting(
        embedded_test_server()->port());
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // This sets a wildcard entry in the allowlist, because we can't specify
    // an exact origin as we don't yet have the embedded test server's port
    // (it isn't started until later).
    command_line->AppendSwitchASCII(
        network::switches::kUnsafelyTreatInsecureOriginAsSecure,
        "*.example.com");
  }

 private:
  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(HttpsUpgradesSecureOriginAllowlistBrowserTest,
                       HostInAllowlistExemptedFromHttpsFirstMode) {
  GURL url_in_allowlist =
      embedded_test_server()->GetURL("test.example.com", "/simple.html");
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::NavigateToURL(contents, url_in_allowlist));
  EXPECT_FALSE(
      chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
          contents));
}

IN_PROC_BROWSER_TEST_F(HttpsUpgradesSecureOriginAllowlistBrowserTest,
                       HostNotInAllowlistShowWarning) {
  GURL url_not_in_allowlist =
      embedded_test_server()->GetURL("not-example.com", "/simple.html");
  content::WebContents* contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_FALSE(content::NavigateToURL(contents, url_not_in_allowlist));
  EXPECT_TRUE(chrome_browser_interstitials::IsShowingHttpsFirstModeInterstitial(
      contents));
}
