// 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);
  }

  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));
  }

  // Prepare the profile so that HFM can be automatically enabled.
  void SatisfyTypicallySecureHeuristicRequirements(
      base::SimpleTestClock* clock) {
    // 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_;
};

// 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::SimpleTestClock clock;
  base::Time now;
  EXPECT_TRUE(base::Time::FromUTCString("2023-10-15T06:00:00Z", &now));
  // Start the clock at standard system time.
  clock.SetNow(now);

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

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

  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.
  clock.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.
  base::SimpleTestClock clock;
  clock.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(&clock);
  // 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.
  clock.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();

  base::SimpleTestClock clock;
  SatisfyTypicallySecureHeuristicRequirements(&clock);
  // 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();

  base::SimpleTestClock clock;
  SatisfyTypicallySecureHeuristicRequirements(&clock);

  // 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/488043.
  // 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::Value::List 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::Value::List 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()
                                      ->GetOmniboxView()
                                      ->controller()
                                      ->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()
                                      ->GetOmniboxView()
                                      ->controller()
                                      ->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()
                                      ->GetOmniboxView()
                                      ->controller()
                                      ->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));
}
