// 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 "content/public/browser/btm_service.h"

#include <optional>
#include <string_view>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_file_util.h"
#include "base/time/default_clock.h"
#include "base/time/time.h"
#include "base/types/pass_key.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/browser/browser_context_impl.h"
#include "content/browser/btm/btm_bounce_detector.h"
#include "content/browser/btm/btm_service_impl.h"
#include "content/browser/btm/btm_state.h"
#include "content/browser/btm/btm_test_utils.h"
#include "content/browser/btm/btm_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/btm_redirect_info.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/btm_service_test_utils.h"
#include "content/public/test/mock_browsing_data_remover_delegate.h"
#include "content/public/test/test_browser_context.h"
#include "net/base/schemeful_site.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/http/http_status_code.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features_generated.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "url/gurl.h"

using testing::AllOf;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::Pair;

namespace content {

class BtmServiceTest : public testing::Test {
 protected:
  base::PassKey<BtmServiceTest> PassKey() { return {}; }

  void RecordBounce(
      BrowserContext* browser_context,
      std::string_view url,
      std::string_view initial_url,
      std::string_view final_url,
      base::Time time,
      bool stateful,
      BtmServiceImpl::StatefulBounceCallback stateful_bounce_callback) {
    BtmRedirectChainInfo chain(
        GURL(initial_url), ukm::AssignNewSourceId(), GURL(final_url),
        ukm::AssignNewSourceId(),
        /*length=*/3,
        /*is_partial_chain=*/false,
        btm::Are3PcsGenerallyEnabled(browser_context, nullptr));

    BtmRedirectInfoPtr redirect = BtmRedirectInfo::CreateForServer(
        GURL(url), ukm::AssignNewSourceId(),
        stateful ? BtmDataAccessType::kWrite : BtmDataAccessType::kRead, time,
        /*was_response_cached=*/false,
        /*response_code=*/net::HTTP_FOUND,
        /*server_bounce_delay=*/base::TimeDelta());

    btm::Populate3PcExceptions(browser_context,
                               /*web_contents=*/nullptr, GURL(initial_url),
                               GURL(final_url), base::span_from_ref(redirect));
    redirect->chain_index = 1;
    redirect->chain_id = chain.chain_id;

    BtmServiceImpl::Get(browser_context)
        ->RecordBounceForTesting(*redirect, chain, stateful_bounce_callback);
  }

 private:
  BrowserTaskEnvironment task_environment_;
};

TEST_F(BtmServiceTest, CreateServiceIfFeatureEnabled) {
  ScopedInitBtmFeature init_btm(true);

  TestBrowserContext profile;
  EXPECT_NE(BtmServiceImpl::Get(&profile), nullptr);
}

TEST_F(BtmServiceTest, DontCreateServiceIfFeatureDisabled) {
  ScopedInitBtmFeature init_btm(false);

  TestBrowserContext profile;
  EXPECT_EQ(BtmServiceImpl::Get(&profile), nullptr);
}

// Verifies that if the BTM feature is enabled, BTM database is created when a
// (non-OTR) profile is created.
TEST_F(BtmServiceTest, CreateBTMDatabaseIfBtmEnabled) {
  base::FilePath data_path = base::CreateUniqueTempDirectoryScopedToTest();
  BtmServiceImpl* service;
  std::unique_ptr<TestBrowserContext> profile;

  // Ensure the BTM feature is enabled.
  base::test::ScopedFeatureList feature_list(features::kBtm);

  profile = std::make_unique<TestBrowserContext>(data_path);
  service = BtmServiceImpl::Get(profile.get());
  ASSERT_NE(service, nullptr);

  // Ensure the database files have been created since the BTM feature is
  // enabled.
  WaitOnStorage(service);
  BrowserContextImpl::From(profile.get())->WaitForBtmCleanupForTesting();
#if BUILDFLAG(IS_FUCHSIA) && defined(IS_WEB_ENGINE)
  // See crbug.com/434764000, file based BTM is disabled on web engine on
  // fuchsia due to the storage constraint.
  EXPECT_FALSE(base::PathExists(GetBtmFilePath(profile.get())));
#else
  EXPECT_TRUE(base::PathExists(GetBtmFilePath(profile.get())));
#endif
}

#if BUILDFLAG(IS_FUCHSIA) && defined(IS_WEB_ENGINE)
// See crbug.com/434764000, file based BTM is disabled on web engine on fuchsia
// due to the storage constraint.
#define MAYBE_PreserveRegularProfileDbFiles \
  DISABLED_PreserveRegularProfileDbFiles
#else
#define MAYBE_PreserveRegularProfileDbFiles PreserveRegularProfileDbFiles
#endif
// Verifies that when an OTR profile is opened, the BTM database file for
// the underlying regular profile is NOT deleted.
TEST_F(BtmServiceTest, MAYBE_PreserveRegularProfileDbFiles) {
  base::FilePath data_path = base::CreateUniqueTempDirectoryScopedToTest();

  // Ensure the BTM feature is enabled.
  base::test::ScopedFeatureList feature_list(features::kBtm);

  // Build a regular profile.
  std::unique_ptr<TestBrowserContext> profile =
      std::make_unique<TestBrowserContext>(data_path);
  BtmServiceImpl* service = BtmServiceImpl::Get(profile.get());
  ASSERT_NE(service, nullptr);

  // Ensure the regular profile's database files have been created since the
  // BTM feature is enabled.
  WaitOnStorage(service);
  BrowserContextImpl::From(profile.get())->WaitForBtmCleanupForTesting();
  ASSERT_TRUE(base::PathExists(GetBtmFilePath(profile.get())));

  // Build an off-the-record profile based on `profile`.
  std::unique_ptr<TestBrowserContext> otr_profile =
      std::make_unique<TestBrowserContext>(profile->GetPath());
  otr_profile->set_is_off_the_record(true);
  BtmServiceImpl* otr_service = BtmServiceImpl::Get(otr_profile.get());
  ASSERT_NE(otr_service, nullptr);

  // Ensure the OTR profile's database has been initialized and any file
  // deletion tasks have finished (although there shouldn't be any).
  WaitOnStorage(otr_service);
  BrowserContextImpl::From(otr_profile.get())->WaitForBtmCleanupForTesting();

  // Ensure the regular profile's database files were NOT deleted.
  EXPECT_TRUE(base::PathExists(GetBtmFilePath(profile.get())));

  // Every TestBrowserContext normally deletes its folder when it's destroyed.
  // But since `otr_profile` is sharing `profile`'s directory, we don't want it
  // to delete that folder (`profile` will).
  otr_profile->TakePath();
}
#if BUILDFLAG(IS_FUCHSIA) && defined(IS_WEB_ENGINE)
// See crbug.com/434764000, file based BTM is disabled on web engine on
// fuchsia due to the storage constraint. But the leftover file previously
// created should be deleted.
TEST_F(BtmServiceTest, DeleteLeftoverDatabaseFileOnWebEngineOnFuchsia) {
  base::FilePath user_data_dir;
  base::FilePath db_path;

  // First, create a browser context and create a mock database file at the
  // correct path.
  {
    TestBrowserContext browser_context;
    db_path = GetBtmFilePath(&browser_context);
    // Ensure the BtmService (and its database) are initialized.
    BrowserContextImpl::From(&browser_context)
        ->GetBtmService()
        ->WaitForFuchsiaCleanupForTesting();

    // Create a mock database file where one would be if the platform wasn't
    // WebEngine on Fuchsia.
    ASSERT_TRUE(base::WriteFile(db_path, "test"));
    ASSERT_TRUE(base::PathExists(db_path));

    // Take ownership of the browser context's directory so we can reuse it.
    user_data_dir = browser_context.TakePath();

    // Confirm that WaitForBtmCleanupForTesting() returns and the file still
    // exists.
    BrowserContextImpl::From(&browser_context)->WaitForBtmCleanupForTesting();
    ASSERT_TRUE(base::PathExists(db_path));
  }

  // Confirm the file still exists after the browser context is destroyed.
  ASSERT_TRUE(base::PathExists(db_path));

  // Create another browser context for the same directory and confirm the
  // database file is deleted.
  {
    TestBrowserContext browser_context(user_data_dir);
    BrowserContextImpl::From(&browser_context)
        ->GetBtmService()
        ->WaitForFuchsiaCleanupForTesting();
    ASSERT_FALSE(base::PathExists(db_path));
  }
}

TEST_F(BtmServiceTest, BtmServiceCanStartWithoutDatabaseFile) {
  TestBrowserContext browser_context;
  base::FilePath db_path = GetBtmFilePath(&browser_context);
  ASSERT_FALSE(base::PathExists(db_path));
  // Wait for the database to be created.
  BrowserContextImpl::From(&browser_context)
      ->GetBtmService()
      ->storage()
      ->FlushPostedTasksForTesting();
  ASSERT_FALSE(base::PathExists(db_path));
}
#endif

#if BUILDFLAG(IS_FUCHSIA) && defined(IS_WEB_ENGINE)
// See crbug.com/434764000, file based BTM is disabled on web engine on
// fuchsia due to the storage constraint.
#define MAYBE_DatabaseFileIsDeletedIfFeatureIsDisabled \
  DISABLED_DatabaseFileIsDeletedIfFeatureIsDisabled
#else
#define MAYBE_DatabaseFileIsDeletedIfFeatureIsDisabled \
  DatabaseFileIsDeletedIfFeatureIsDisabled
#endif
TEST_F(BtmServiceTest, MAYBE_DatabaseFileIsDeletedIfFeatureIsDisabled) {
  base::FilePath user_data_dir;
  base::FilePath db_path;

  // First, create a browser context while BTM is enabled, and confirm a
  // database file is created.
  {
    TestBrowserContext browser_context;
    db_path = GetBtmFilePath(&browser_context);
    // Wait for the database to be created.
    BrowserContextImpl::From(&browser_context)
        ->GetBtmService()
        ->storage()
        ->FlushPostedTasksForTesting();
    ASSERT_TRUE(base::PathExists(db_path));

    // Take ownership of the browser context's directory so we can reuse it.
    user_data_dir = browser_context.TakePath();

    // Confirm that WaitForBtmCleanupForTesting() returns even if the file is
    // not deleted.
    BrowserContextImpl::From(&browser_context)->WaitForBtmCleanupForTesting();
    ASSERT_TRUE(base::PathExists(db_path));
  }

  // Confirm the file still exists after the browser context is destroyed.
  ASSERT_TRUE(base::PathExists(db_path));

  // Create another browser context for the same directory, while BTM is
  // disabled. Confirm the database file is deleted.
  {
    ScopedInitBtmFeature disable_btm(false);
    TestBrowserContext browser_context(user_data_dir);
    ASSERT_FALSE(BrowserContextImpl::From(&browser_context)->GetBtmService());
    BrowserContextImpl::From(&browser_context)->WaitForBtmCleanupForTesting();
    ASSERT_FALSE(base::PathExists(db_path));
  }
}

TEST_F(BtmServiceTest, EmptySiteEventsIgnored) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kBtm);
  std::unique_ptr<TestBrowserContext> profile =
      std::make_unique<TestBrowserContext>();
  BtmServiceImpl* service = BtmServiceImpl::Get(profile.get());

  // Record a bounce for an empty URL.
  GURL url;
  base::Time bounce = base::Time::FromSecondsSinceUnixEpoch(2);
  RecordBounce(profile.get(), url.spec(), "https://initial.com",
               "https://final.com", bounce, false, base::DoNothing());
  WaitOnStorage(service);

  // Verify that an entry is not returned when querying for an empty URL,
  StateForURLCallback callback = base::BindLambdaForTesting(
      [&](BtmState state) { EXPECT_FALSE(state.was_loaded()); });
  service->storage()
      ->AsyncCall(&BtmStorage::Read)
      .WithArgs(url)
      .Then(std::move(callback));
  WaitOnStorage(service);
}

class BtmServiceStateRemovalTest : public testing::Test {
 public:
  BtmServiceStateRemovalTest()
      : profile_(std::make_unique<TestBrowserContext>()),
        service_(BtmServiceImpl::Get(GetProfile())) {
    SetBrowserClientForTesting(&browser_client_);
  }

  base::TimeDelta grace_period;
  base::TimeDelta interaction_ttl;
  base::TimeDelta tiny_delta = base::Milliseconds(1);

  BrowserContext* GetProfile() { return profile_.get(); }
  BtmServiceImpl* GetService() { return service_; }

 protected:
  TpcBlockingBrowserClient browser_client_;
  BrowserTaskEnvironment task_environment_;
  MockBrowsingDataRemoverDelegate delegate_;

  // Test setup.
  void SetUp() override {
    grace_period = features::kBtmGracePeriod.Get();
    interaction_ttl = features::kBtmInteractionTtl.Get();
    ASSERT_LT(tiny_delta, grace_period);

    GetProfile()->GetBrowsingDataRemover()->SetEmbedderDelegate(&delegate_);
    browser_client_.SetBlockThirdPartyCookiesByDefault(true);
    ASSERT_FALSE(Are3PcsGenerallyEnabled());

    DCHECK(service_);
    service_->SetStorageClockForTesting(&clock_);
    WaitOnStorage(GetService());
  }

  void TearDown() override {
    profile_.reset();
    base::RunLoop().RunUntilIdle();
  }

  void AdvanceTimeTo(base::Time now) {
    ASSERT_GE(now, clock_.Now());
    clock_.SetNow(now);
  }

  base::Time Now() { return clock_.Now(); }
  void SetNow(base::Time now) { clock_.SetNow(now); }

  void AdvanceTimeBy(base::TimeDelta delta) { clock_.Advance(delta); }

  void FireBtmTimer() {
    service_->OnTimerFiredForTesting();
    WaitOnStorage(GetService());
  }

  // Add an exception to the third-party cookie blocking rule for
  // |third_party_url| embedded by |first_party_url|.
  void Add3PCException(const GURL& first_party_url,
                       const GURL& third_party_url) {
    browser_client_.GrantCookieAccessDueToHeuristic(
        profile_.get(), net::SchemefulSite(first_party_url),
        net::SchemefulSite(third_party_url), base::Days(1),
        /*ignore_schemes=*/false);

    auto* client = GetContentClientForTesting()->browser();
    EXPECT_TRUE(client->IsFullCookieAccessAllowed(
        profile_.get(), nullptr, third_party_url,
        blink::StorageKey::CreateFirstParty(
            url::Origin::Create(first_party_url)),
        /*overrides=*/{}));
    EXPECT_FALSE(client->IsFullCookieAccessAllowed(
        profile_.get(), nullptr, first_party_url,
        blink::StorageKey::CreateFirstParty(
            url::Origin::Create(third_party_url)),
        /*overrides=*/{}));
  }

  void RecordBounce(
      std::string_view url,
      std::string_view initial_url,
      std::string_view final_url,
      base::Time time,
      bool stateful,
      BtmServiceImpl::StatefulBounceCallback stateful_bounce_callback) {
    BtmRedirectChainInfo chain(GURL(initial_url), ukm::AssignNewSourceId(),
                               GURL(final_url), ukm::AssignNewSourceId(),
                               /*length=*/3,
                               /*is_partial_chain=*/false,
                               Are3PcsGenerallyEnabled());

    BtmRedirectInfoPtr redirect = BtmRedirectInfo::CreateForServer(
        GURL(url), ukm::AssignNewSourceId(),
        stateful ? BtmDataAccessType::kWrite : BtmDataAccessType::kRead, time,
        /*was_response_cached=*/false,
        /*response_code=*/net::HTTP_FOUND,
        /*server_bounce_delay=*/base::TimeDelta());

    btm::Populate3PcExceptions(GetProfile(),
                               /*web_contents=*/nullptr, GURL(initial_url),
                               GURL(final_url), base::span_from_ref(redirect));
    redirect->chain_index = 1;
    redirect->chain_id = chain.chain_id;

    GetService()->RecordBounceForTesting(*redirect, chain,
                                         stateful_bounce_callback);
  }

  bool Are3PcsGenerallyEnabled() {
    return btm::Are3PcsGenerallyEnabled(profile_.get(), nullptr);
  }

 private:
  base::SimpleTestClock clock_;

  std::unique_ptr<TestBrowserContext> profile_;
  raw_ptr<BtmServiceImpl, DanglingUntriaged> service_ = nullptr;
};

namespace {
class RedirectChainCounter : public BtmService::Observer {
 public:
  explicit RedirectChainCounter(BtmService* service) { obs_.Observe(service); }

  size_t count() const { return count_; }

 private:
  void OnChainHandled(const std::vector<BtmRedirectInfoPtr>& redirects,
                      const BtmRedirectChainInfoPtr& chain) override {
    count_++;
  }

  size_t count_ = 0;
  base::ScopedObservation<BtmService, Observer> obs_{this};
};
}  // namespace

TEST_F(BtmServiceStateRemovalTest,
       CompleteChain_NotifiesBtmRedirectChainObservers) {
  GetService()->SetStorageClockForTesting(base::DefaultClock::GetInstance());
  RedirectChainCounter chain_counter(GetService());

  std::vector<BtmRedirectInfoPtr> complete_redirects;
  complete_redirects.push_back(BtmRedirectInfo::CreateForServer(
      /*redirector_url=*/GURL("http://b.test/"),
      /*redirector_source_id=*/ukm::AssignNewSourceId(),
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  auto complete_chain = std::make_unique<BtmRedirectChainInfo>(
      /*initial_url=*/GURL("http://a.test/"),
      /*initial_source_id=*/ukm::AssignNewSourceId(),
      /*final_url=*/GURL("http://c.test/"),
      /*final_source_id*/ ukm::AssignNewSourceId(),
      /*length=*/1, /*is_partial_chain=*/false, Are3PcsGenerallyEnabled());

  btm::Populate3PcExceptions(GetProfile(), /*web_contents=*/nullptr,
                             complete_chain->initial_url,
                             complete_chain->final_url, complete_redirects);
  GetService()->HandleRedirectChain(std::move(complete_redirects),
                                    std::move(complete_chain),
                                    base::DoNothing());
  WaitOnStorage(GetService());
  // Expect one call to Observer.OnChainHandled when handling a complete chain.
  EXPECT_EQ(chain_counter.count(), 1u);
}

TEST_F(BtmServiceStateRemovalTest,
       PartialChain_DoesNotNotifyBtmRedirectChainObservers) {
  GetService()->SetStorageClockForTesting(base::DefaultClock::GetInstance());
  RedirectChainCounter chain_counter(GetService());

  std::vector<BtmRedirectInfoPtr> partial_redirects;
  partial_redirects.push_back(BtmRedirectInfo::CreateForServer(
      /*redirector_url=*/GURL("http://b.test/"),
      /*redirector_source_id=*/ukm::AssignNewSourceId(),
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  auto partial_chain = std::make_unique<BtmRedirectChainInfo>(
      /*initial_url=*/GURL("http://a.test/"),
      /*initial_source_id=*/ukm::AssignNewSourceId(),
      /*final_url=*/GURL("http://c.test/"),
      /*final_source_id=*/ukm::AssignNewSourceId(),
      /*length=*/1, /*is_partial_chain=*/true, Are3PcsGenerallyEnabled());

  btm::Populate3PcExceptions(GetProfile(), /*web_contents=*/nullptr,
                             partial_chain->initial_url,
                             partial_chain->final_url, partial_redirects);
  GetService()->HandleRedirectChain(std::move(partial_redirects),
                                    std::move(partial_chain),
                                    base::DoNothing());
  WaitOnStorage(GetService());
  // Expect no calls to Observer.OnChainHandled when handling a partial chain.
  EXPECT_EQ(chain_counter.count(), 0u);
}

// NOTE: The use of a MockBrowsingDataRemoverDelegate in this test fixture
// means that when BTM deletion is enabled, the row for 'url' is not actually
// removed from the BTM db since 'delegate_' doesn't actually carryout the
// removal task.
TEST_F(BtmServiceStateRemovalTest, DISABLED_BrowsingDataDeletion_Enabled) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "bounce"}});

  // Record a bounce.
  GURL url("https://example.com");
  base::Time bounce = base::Time::FromSecondsSinceUnixEpoch(2);
  RecordBounce(url.spec(), "https://initial.com", "https://final.com", bounce,
               false, base::DoNothing());
  WaitOnStorage(GetService());
  EXPECT_TRUE(GetBtmState(GetService(), url).has_value());

  // Set the current time to just after the bounce happened.
  AdvanceTimeTo(bounce + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify a removal task was not posted to the BrowsingDataRemover(Delegate).
  delegate_.VerifyAndClearExpectations();

  auto filter_builder = BrowsingDataFilterBuilder::Create(
      BrowsingDataFilterBuilder::Mode::kDelete);
  filter_builder->AddRegisterableDomain(GetSiteForBtm(url));
  filter_builder->SetCookiePartitionKeyCollection(
      net::CookiePartitionKeyCollection());
  delegate_.ExpectCall(
      base::Time::Min(), base::Time::Max(),
      (ContentBrowserClient::kDefaultBtmRemoveMask &
       ~BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX) |
          BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS,
      BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
          BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
      filter_builder.get());
  // We don't test the filter builder for partitioned cookies here because it's
  // messy. The browser tests ensure that it behaves as expected.
  delegate_.ExpectCallDontCareAboutFilterBuilder(
      base::Time::Min(), base::Time::Max(),
      BrowsingDataRemover::DATA_TYPE_COOKIES,
      BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
          BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);

  // Time-travel to after the grace period has ended for the bounce.
  AdvanceTimeTo(bounce + grace_period + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify that a removal task was posted to the BrowsingDataRemover(Delegate)
  // for 'url'.
  delegate_.VerifyAndClearExpectations();
  // Because this test fixture uses a MockBrowsingDataRemoverDelegate the BTM
  // entry should not actually be removed. However, in practice it would be.
  EXPECT_TRUE(GetBtmState(GetService(), url).has_value());

  EXPECT_THAT(ukm_recorder,
              EntryUrlsAre("DIPS.Deletion", {"http://example.com/"}));
}

TEST_F(BtmServiceStateRemovalTest,
       BrowsingDataDeletion_Respects3PExceptionsFor3PC) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "bounce"}});

  GURL excepted_3p_url("https://excepted-as-3p.com");
  GURL non_excepted_url("https://not-excepted.com");

  browser_client_.GrantCookieAccessTo3pSite(excepted_3p_url);

  int stateful_bounce_count = 0;
  BtmServiceImpl::StatefulBounceCallback increment_bounce =
      base::BindLambdaForTesting(
          [&](const GURL& final_url) { stateful_bounce_count++; });

  // Bounce through both tracking sites.
  base::Time bounce = base::Time::FromSecondsSinceUnixEpoch(2);
  RecordBounce(excepted_3p_url.spec(), "https://initial.com",
               "https://final.com", bounce, true, increment_bounce);
  RecordBounce(non_excepted_url.spec(), "https://initial.com",
               "https://final.com", bounce, true, increment_bounce);
  WaitOnStorage(GetService());

  // Verify that the bounce was not recorded for the excepted 3P URL.
  EXPECT_FALSE(GetBtmState(GetService(), excepted_3p_url).has_value());
  EXPECT_TRUE(GetBtmState(GetService(), non_excepted_url).has_value());

  // Time-travel to after the grace period has ended for the bounce.
  AdvanceTimeTo(bounce + grace_period + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Only the non-excepted site should be reported to UKM.
  EXPECT_THAT(ukm_recorder,
              EntryUrlsAre("DIPS.Deletion", {"http://not-excepted.com/"}));

  // Expect one recorded bounce, for the stateful redirect through the
  // non-excepted site.
  EXPECT_EQ(stateful_bounce_count, 1);
}

TEST_F(BtmServiceStateRemovalTest,
       BrowsingDataDeletion_Respects1PExceptionsFor3PC) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "bounce"}});

  GURL excepted_1p_url("https://excepted-as-1p.com");
  GURL scoped_excepted_1p_url("https://excepted-as-1p-with-3p.com");
  GURL non_excepted_url("https://not-excepted.com");
  GURL redirect_url_1("https://redirect-1.com");
  GURL redirect_url_2("https://redirect-2.com");
  GURL redirect_url_3("https://redirect-3.com");

  browser_client_.AllowThirdPartyCookiesOnSite(excepted_1p_url);
  Add3PCException(scoped_excepted_1p_url, redirect_url_1);

  int stateful_bounce_count = 0;
  BtmServiceImpl::StatefulBounceCallback increment_bounce =
      base::BindLambdaForTesting(
          [&](const GURL& final_url) { stateful_bounce_count++; });

  base::Time bounce = base::Time::FromSecondsSinceUnixEpoch(2);
  // Record a bounce through redirect_url_1 that starts on an excepted
  // URL.
  RecordBounce(redirect_url_1.spec(), excepted_1p_url.spec(),
               non_excepted_url.spec(), bounce, true, increment_bounce);
  // Record a bounce through redirect_url_1 that ends on an excepted
  // URL.
  RecordBounce(redirect_url_1.spec(), non_excepted_url.spec(),
               excepted_1p_url.spec(), bounce, true, increment_bounce);
  // Record a bounce through redirect_url_1 that ends on a URL with an exception
  // scoped to redirect_url_1.
  RecordBounce(redirect_url_1.spec(), non_excepted_url.spec(),
               scoped_excepted_1p_url.spec(), bounce, true, increment_bounce);
  // Record a bounce through redirect_url_2 that does not start or
  // end on an excepted URL.
  RecordBounce(redirect_url_2.spec(), non_excepted_url.spec(),
               non_excepted_url.spec(), bounce, true, increment_bounce);
  // Record a bounce through redirect_url_3 that does not start or
  // end on an excepted URL. Record an interaction on this URL as well.
  RecordBounce(redirect_url_3.spec(), non_excepted_url.spec(),
               non_excepted_url.spec(), bounce, true, increment_bounce);
  GetService()
      ->storage()
      ->AsyncCall(&BtmStorage::RecordUserActivation)
      .WithArgs(redirect_url_3, bounce);
  WaitOnStorage(GetService());

  // Expect no recorded BtmState for redirect_url_1, since every
  // recorded bounce started or ended on an excepted site.
  EXPECT_FALSE(GetBtmState(GetService(), redirect_url_1).has_value());
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_2).has_value());
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_3).has_value());

  // Record a bounce through redirect_url_2 that starts on an
  // excepted URL. This should clear the DB entry for redirect_url_2.
  RecordBounce(redirect_url_2.spec(), excepted_1p_url.spec(),
               non_excepted_url.spec(), bounce, true, increment_bounce);
  EXPECT_FALSE(GetBtmState(GetService(), redirect_url_2).has_value());

  // Record a bounce through redirect_url_3 that starts on an
  // excepted URL. This should not clear the DB entry for redirect_url_3 as it
  // has a recorded interaction.
  RecordBounce(redirect_url_3.spec(), excepted_1p_url.spec(),
               non_excepted_url.spec(), bounce, true, increment_bounce);
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_3).has_value());

  // Expect two non-excepted stateful redirects: the first bounces through
  // redirect_url_2 and redirect_url_3.
  EXPECT_EQ(stateful_bounce_count, 2);
}

// TODO: crbug.com/376625002 - temporarily disabled for the move to //content,
// where there's no HostContentSettingsMap. Find an appropriate way to implement
// this test in //content or move it back to //chrome.
TEST_F(BtmServiceStateRemovalTest,
       DISABLED_BrowsingDataDeletion_RespectsStorageAccessGrantExceptions) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  std::vector<base::test::FeatureRefAndParams> enabled_features;
  enabled_features.push_back(
      {features::kBtm, {{"triggering_action", "bounce"}}});
  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeaturesAndParameters(enabled_features, {});

  GURL storage_access_grant_url("https://storage-access-granted.com");
  GURL top_level_storage_access_grant_url(
      "https://top-level-storage-access-granted.com");
  GURL no_grant_url("https://no-storage-access-grant.com");
  GURL redirect_url_1("https://redirect-1.com");
  GURL redirect_url_2("https://redirect-2.com");
  GURL redirect_url_3("https://redirect-3.com");

  // Create Storage Access grants for the required sites.
  /*
  HostContentSettingsMap* map =
      HostContentSettingsMapFactory::GetForProfile(GetProfile());
  map->SetContentSettingCustomScope(
      ContentSettingsPattern::Wildcard(),
      ContentSettingsPattern::FromString("[*.]" +
                                         storage_access_grant_url.host()),
      ContentSettingsType::STORAGE_ACCESS, CONTENT_SETTING_ALLOW);
  map->SetContentSettingCustomScope(
      ContentSettingsPattern::Wildcard(),
      ContentSettingsPattern::FromString(
          "[*.]" + top_level_storage_access_grant_url.host()),
      ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS, CONTENT_SETTING_ALLOW);
  */
  int stateful_bounce_count = 0;
  BtmServiceImpl::StatefulBounceCallback increment_bounce =
      base::BindLambdaForTesting(
          [&](const GURL& final_url) { stateful_bounce_count++; });

  base::Time bounce = base::Time::FromSecondsSinceUnixEpoch(2);
  // Record a bounce through redirect_url_1 that starts on a URL with an SA
  // grant.
  RecordBounce(redirect_url_1.spec(), storage_access_grant_url.spec(),
               no_grant_url.spec(), bounce, true, increment_bounce);
  // Record a bounce through redirect_url_1 that ends on a URL with a top-level
  // SA grant.
  RecordBounce(redirect_url_1.spec(), no_grant_url.spec(),
               top_level_storage_access_grant_url.spec(), bounce, true,
               increment_bounce);
  // Record a bounce through redirect_url_2 that does not start or
  // end on a URL with an SA grant.
  RecordBounce(redirect_url_2.spec(), no_grant_url.spec(), no_grant_url.spec(),
               bounce, true, increment_bounce);
  // Record a bounce through redirect_url_3 that does not start or
  // end on a URL with an SA grant. Record an interaction on this URL as well.
  RecordBounce(redirect_url_3.spec(), no_grant_url.spec(), no_grant_url.spec(),
               bounce, true, increment_bounce);
  GetService()
      ->storage()
      ->AsyncCall(&BtmStorage::RecordUserActivation)
      .WithArgs(redirect_url_3, bounce);
  WaitOnStorage(GetService());

  // Expect no recorded BtmState for redirect_url_1, since every
  // recorded bounce started or ended on a site with an SA grant.
  EXPECT_FALSE(GetBtmState(GetService(), redirect_url_1).has_value());
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_2).has_value());
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_3).has_value());

  // Record a bounce through redirect_url_2 that starts on a URL with an SA
  // grant. This should clear the DB entry for redirect_url_2.
  RecordBounce(redirect_url_2.spec(), storage_access_grant_url.spec(),
               no_grant_url.spec(), bounce, true, increment_bounce);
  EXPECT_FALSE(GetBtmState(GetService(), redirect_url_2).has_value());

  // Record a bounce through redirect_url_3 that starts on a URL with an SA
  // grant. This should not clear the DB entry for redirect_url_3 as it has a
  // recorded interaction.
  RecordBounce(redirect_url_3.spec(), storage_access_grant_url.spec(),
               no_grant_url.spec(), bounce, true, increment_bounce);
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_3).has_value());

  // Expect two non-SA stateful redirects: the first bounces through
  // redirect_url_2 and redirect_url_3.
  EXPECT_EQ(stateful_bounce_count, 2);
}

// When third-party cookies are globally allowed, bounces should be recorded for
// sites which have an exception to block 3PC, but not by default.
TEST_F(
    BtmServiceStateRemovalTest,
    BrowsingDataDeletion_Respects1PExceptionsForBlocking3PCWhenDefaultAllowed) {
  browser_client_.SetBlockThirdPartyCookiesByDefault(false);
  ASSERT_TRUE(Are3PcsGenerallyEnabled());

  ukm::TestAutoSetUkmRecorder ukm_recorder;
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "bounce"}});

  GURL blocked_1p_url("https://excepted-as-1p.com");
  GURL scoped_blocked_1p_url("https://excepted-as-1p-with-3p.com");
  GURL non_blocked_url("https://not-excepted.com");
  GURL redirect_url_1("https://redirect-1.com");
  GURL redirect_url_2("https://redirect-2.com");
  GURL redirect_url_3("https://redirect-3.com");
  GURL redirect_url_4("https://redirect-4.com");

  // Exceptions to block third-party cookies.
  browser_client_.BlockThirdPartyCookiesOnSite(blocked_1p_url);
  browser_client_.BlockThirdPartyCookies(redirect_url_1, scoped_blocked_1p_url);

  int stateful_bounce_count = 0;
  BtmServiceImpl::StatefulBounceCallback increment_bounce =
      base::BindLambdaForTesting(
          [&](const GURL& final_url) { stateful_bounce_count++; });

  base::Time bounce = base::Time::FromSecondsSinceUnixEpoch(2);
  // Record a bounce through redirect_url_1 that starts and ends on blocked
  // URLs.
  RecordBounce(redirect_url_1.spec(), blocked_1p_url.spec(),
               scoped_blocked_1p_url.spec(), bounce, true, increment_bounce);
  // Record a bounce through redirect_url_2 that starts and ends on blocked
  // URLs. Record an interaction on this URL as well.
  RecordBounce(redirect_url_2.spec(), blocked_1p_url.spec(),
               blocked_1p_url.spec(), bounce, true, increment_bounce);
  GetService()
      ->storage()
      ->AsyncCall(&BtmStorage::RecordUserActivation)
      .WithArgs(redirect_url_2, bounce);
  WaitOnStorage(GetService());
  // Record a bounce through redirect_url_3 that starts on a non-blocked URL.
  RecordBounce(redirect_url_3.spec(), non_blocked_url.spec(),
               blocked_1p_url.spec(), bounce, true, increment_bounce);
  // Record a bounce through redirect_url_4 that ends on a non-blocked URL.
  RecordBounce(redirect_url_4.spec(), blocked_1p_url.spec(),
               non_blocked_url.spec(), bounce, true, increment_bounce);

  // Expect a recorded BtmState for redirect_url_1 and redirect_url_2, since
  // they were bounced through with blocking exceptions on both the initial and
  // final URL. The other two trackers were only bounced through from
  // default-allowed sites.
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_1).has_value());
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_2).has_value());
  EXPECT_FALSE(GetBtmState(GetService(), redirect_url_3).has_value());
  EXPECT_FALSE(GetBtmState(GetService(), redirect_url_4).has_value());

  // Record a bounce through redirect_url_1 that starts on a non-blocked URL.
  // This should clear the DB entry for redirect_url_1.
  RecordBounce(redirect_url_1.spec(), non_blocked_url.spec(),
               blocked_1p_url.spec(), bounce, true, increment_bounce);
  EXPECT_FALSE(GetBtmState(GetService(), redirect_url_1).has_value());

  // Record a bounce through redirect_url_2 that starts on a
  // blocked URL. This should not clear the DB entry for redirect_url_2 as it
  // has a recorded interaction.
  RecordBounce(redirect_url_2.spec(), non_blocked_url.spec(),
               blocked_1p_url.spec(), bounce, true, increment_bounce);
  EXPECT_TRUE(GetBtmState(GetService(), redirect_url_2).has_value());

  // Expect two recorded stateful redirects: the first bounces through
  // redirect_url_1 and redirect_url_2.
  EXPECT_EQ(stateful_bounce_count, 2);
}

TEST_F(BtmServiceStateRemovalTest, ImmediateEnforcement) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "bounce"}});
  SetNow(base::Time::FromSecondsSinceUnixEpoch(2));
  ASSERT_FALSE(Are3PcsGenerallyEnabled());

  // Record a bounce.
  GURL url("https://example.com");
  base::Time bounce = Now();
  RecordBounce(url.spec(), "https://initial.com", "https://final.com", bounce,
               false, base::DoNothing());
  WaitOnStorage(GetService());
  EXPECT_TRUE(GetBtmState(GetService(), url).has_value());

  // Set the current time to just after the bounce happened and simulate firing
  // the BTM timer.
  AdvanceTimeTo(bounce + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify a removal task was not posted to the BrowsingDataRemover(Delegate).
  delegate_.VerifyAndClearExpectations();

  auto filter_builder = BrowsingDataFilterBuilder::Create(
      BrowsingDataFilterBuilder::Mode::kDelete);
  filter_builder->AddRegisterableDomain(GetSiteForBtm(url));
  filter_builder->SetCookiePartitionKeyCollection(
      net::CookiePartitionKeyCollection());
  delegate_.ExpectCall(
      base::Time::Min(), base::Time::Max(),
      (ContentBrowserClient::kDefaultBtmRemoveMask &
       ~BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX) |
          BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS,
      BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
          BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB,
      filter_builder.get());
  // We don't test the filter builder for partitioned cookies here because it's
  // messy. The browser tests ensure that it behaves as expected.
  delegate_.ExpectCallDontCareAboutFilterBuilder(
      base::Time::Min(), base::Time::Max(),
      BrowsingDataRemover::DATA_TYPE_COOKIES,
      BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
          BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB);

  // Perform immediate enforcement of deletion, without regard for grace period
  // and verify `url` is returned the `DeletedSitesCallback`.
  base::RunLoop run_loop;
  base::OnceCallback<void(const std::vector<std::string>& sites)> callback =
      base::BindLambdaForTesting(
          [&](const std::vector<std::string>& deleted_sites) {
            EXPECT_THAT(deleted_sites,
                        testing::UnorderedElementsAre(GetSiteForBtm(url)));
            run_loop.Quit();
          });
  GetService()->DeleteEligibleSitesImmediately(std::move(callback));
  task_environment_.RunUntilIdle();
  run_loop.Run();

  // Verify that a removal task was posted to the BrowsingDataRemover(Delegate)
  // for 'url'.
  delegate_.VerifyAndClearExpectations();
}

// A test class that verifies BtmService state deletion metrics collection
// behavior.
class BtmServiceHistogramTest : public BtmServiceStateRemovalTest {
 public:
  BtmServiceHistogramTest() = default;

  const base::HistogramTester& histograms() const { return histogram_tester_; }

 protected:
  const std::string kBlock3PC = "Block3PC";
  const std::string kUmaHistogramDeletionPrefix = "Privacy.DIPS.Deletion.";
  const std::string kServerRedirectsDelayHist =
      "Privacy.DIPS.ServerBounceDelay";
  const std::string kServerRedirectsChainDelayHist =
      "Privacy.DIPS.ServerBounceChainDelay";
  const std::string kServerRedirectsStatusCodePrefix =
      "Privacy.DIPS.BounceStatusCode.";
  const std::string kNoCache = "NoCache";
  const std::string kCached = "Cached";

  base::HistogramTester histogram_tester_;
};

TEST_F(BtmServiceHistogramTest, DeletionLatency) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "bounce"}});

  // Verify the histogram starts empty
  histograms().ExpectTotalCount("Privacy.DIPS.DeletionLatency2", 0);

  // Record a bounce.
  GURL url("https://example.com");
  base::Time bounce = base::Time::FromSecondsSinceUnixEpoch(2);
  RecordBounce(url.spec(), "https://initial.com", "https://final.com", bounce,
               false, base::DoNothing());
  WaitOnStorage(GetService());

  // Set the current time to just after the bounce happened.
  AdvanceTimeTo(bounce + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify deletion latency metrics were NOT emitted and the BTM entry was NOT
  // removed.
  histograms().ExpectTotalCount("Privacy.DIPS.DeletionLatency2", 0);
  EXPECT_TRUE(GetBtmState(GetService(), url).has_value());

  // Time-travel to after the grace period has ended for the bounce.
  AdvanceTimeTo(bounce + grace_period + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify a deletion latency metric was emitted and the BTM entry was
  // removed.
  histograms().ExpectTotalCount("Privacy.DIPS.DeletionLatency2", 1);
  EXPECT_FALSE(GetBtmState(GetService(), url).has_value());
}

TEST_F(BtmServiceHistogramTest, Deletion_ExceptedAs1P) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "stateful_bounce"}});

  // Verify the histogram is initially empty.
  EXPECT_TRUE(histograms()
                  .GetTotalCountsForPrefix(kUmaHistogramDeletionPrefix)
                  .empty());

  // Record a bounce.
  GURL url("https://example.com");
  GURL excepted_1p_url("https://initial.com");
  browser_client_.AllowThirdPartyCookiesOnSite(excepted_1p_url);
  base::Time bounce_time = base::Time::FromSecondsSinceUnixEpoch(2);
  RecordBounce(url.spec(), excepted_1p_url.spec(), "https://final.com",
               bounce_time, true, base::DoNothing());
  WaitOnStorage(GetService());

  // Time-travel to after the grace period has ended for the bounce.
  AdvanceTimeTo(bounce_time + grace_period + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify a deletion metric was emitted and the BTM entry was removed.
  base::HistogramTester::CountsMap expected_counts;
  expected_counts[kUmaHistogramDeletionPrefix + kBlock3PC] = 1;
  EXPECT_THAT(histograms().GetTotalCountsForPrefix(kUmaHistogramDeletionPrefix),
              testing::ContainerEq(expected_counts));
  histograms().ExpectUniqueSample(kUmaHistogramDeletionPrefix + kBlock3PC,
                                  BtmDeletionAction::kExcepted, 1);
  EXPECT_FALSE(GetBtmState(GetService(), url).has_value());
}

TEST_F(BtmServiceHistogramTest, Deletion_ExceptedAs3P) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "stateful_bounce"}});

  // Verify the histogram is initially empty.
  EXPECT_TRUE(histograms()
                  .GetTotalCountsForPrefix(kUmaHistogramDeletionPrefix)
                  .empty());

  // Record a bounce.
  GURL excepted_3p_url("https://example.com");
  browser_client_.GrantCookieAccessTo3pSite(excepted_3p_url);
  base::Time bounce_time = base::Time::FromSecondsSinceUnixEpoch(2);
  RecordBounce(excepted_3p_url.spec(), "https://initial.com",
               "https://final.com", bounce_time, true, base::DoNothing());
  WaitOnStorage(GetService());

  // Time-travel to after the grace period has ended for the bounce.
  AdvanceTimeTo(bounce_time + grace_period + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify a deletion metric was emitted and the BTM entry was removed.
  base::HistogramTester::CountsMap expected_counts;
  expected_counts[kUmaHistogramDeletionPrefix + kBlock3PC] = 1;
  EXPECT_THAT(histograms().GetTotalCountsForPrefix(kUmaHistogramDeletionPrefix),
              testing::ContainerEq(expected_counts));
  histograms().ExpectUniqueSample(kUmaHistogramDeletionPrefix + kBlock3PC,
                                  BtmDeletionAction::kExcepted, 1);
  EXPECT_FALSE(GetBtmState(GetService(), excepted_3p_url).has_value());
}

TEST_F(BtmServiceHistogramTest, DISABLED_Deletion_Enforced) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "stateful_bounce"}});

  // Verify the histogram is initially empty.
  EXPECT_TRUE(histograms()
                  .GetTotalCountsForPrefix(kUmaHistogramDeletionPrefix)
                  .empty());

  // Record a bounce.
  GURL url("https://example.com");
  base::Time bounce_time = base::Time::FromSecondsSinceUnixEpoch(2);
  RecordBounce(url.spec(), "https://initial.com", "https://final.com",
               bounce_time, true, base::DoNothing());
  WaitOnStorage(GetService());

  // Time-travel to after the grace period has ended for the bounce.
  AdvanceTimeTo(bounce_time + grace_period + tiny_delta);
  FireBtmTimer();
  task_environment_.RunUntilIdle();

  // Verify a deletion metric was emitted and the BTM entry was not removed.
  base::HistogramTester::CountsMap expected_counts;
  expected_counts[kUmaHistogramDeletionPrefix + kBlock3PC] = 1;
  EXPECT_THAT(histograms().GetTotalCountsForPrefix(kUmaHistogramDeletionPrefix),
              testing::ContainerEq(expected_counts));
  histograms().ExpectUniqueSample(kUmaHistogramDeletionPrefix + kBlock3PC,
                                  BtmDeletionAction::kEnforced, 1);
  EXPECT_TRUE(GetBtmState(GetService(), url).has_value());
}

TEST_F(BtmServiceHistogramTest, ServerBounceDelay) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeatureWithParameters(
      features::kBtm, {{"triggering_action", "bounce"}});

  // Verify that the histograms start empty.
  histograms().ExpectTotalCount(kServerRedirectsDelayHist, 0);
  histograms().ExpectTotalCount(kServerRedirectsChainDelayHist, 0);
  EXPECT_TRUE(histograms()
                  .GetTotalCountsForPrefix(kServerRedirectsStatusCodePrefix)
                  .empty());

  TestBrowserContext profile;
  BtmServiceImpl* service = BtmServiceImpl::Get(&profile);

  GURL initial_url = GURL("http://a.test/");
  ukm::SourceId initial_source_id = ukm::AssignNewSourceId();
  GURL first_redirect_url = GURL("http://b.test/");
  ukm::SourceId first_redirect_source_id = ukm::AssignNewSourceId();
  GURL second_redirect_url = GURL("http://c.test/");
  ukm::SourceId second_redirect_source_id = ukm::AssignNewSourceId();

  BtmRedirectChainObserver observer(service, GURL());
  std::vector<BtmRedirectInfoPtr> redirects;
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      first_redirect_url, first_redirect_source_id,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/true,
      /*response_code=*/net::HTTP_MOVED_PERMANENTLY,
      /*server_bounce_delay=*/base::Milliseconds(100)));
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      second_redirect_url, second_redirect_source_id,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::Milliseconds(100)));
  BtmRedirectChainInfoPtr chain = std::make_unique<BtmRedirectChainInfo>(
      initial_url, initial_source_id, GURL(), ukm::kInvalidSourceId,
      redirects.size(),
      /*is_partial_chain=*/false, Are3PcsGenerallyEnabled());
  btm::Populate3PcExceptions(&profile, /*web_contents=*/nullptr,
                             chain->initial_url, chain->final_url, redirects);
  service->HandleRedirectChain(std::move(redirects), std::move(chain),
                               base::DoNothing());
  observer.Wait();

  histograms().ExpectTotalCount(kServerRedirectsDelayHist, 2);
  histograms().ExpectTotalCount(kServerRedirectsChainDelayHist, 1);
  base::HistogramTester::CountsMap expected_counts = {
      {kServerRedirectsStatusCodePrefix + kNoCache, 1},
      {kServerRedirectsStatusCodePrefix + kCached, 1},
  };
  EXPECT_THAT(
      histograms().GetTotalCountsForPrefix(kServerRedirectsStatusCodePrefix),
      testing::ContainerEq(expected_counts));

  histograms().ExpectUniqueSample(kServerRedirectsStatusCodePrefix + kNoCache,
                                  net::HTTP_FOUND, 1);
  histograms().ExpectUniqueSample(kServerRedirectsStatusCodePrefix + kCached,
                                  net::HTTP_MOVED_PERMANENTLY, 1);
  histograms().ExpectUniqueSample(kServerRedirectsDelayHist, 100, 2);
  histograms().ExpectUniqueSample(kServerRedirectsChainDelayHist, 200, 1);
}

MATCHER_P(HasSourceId, id, "") {
  *result_listener << "where the source id is " << arg.source_id;
  return arg.source_id == id;
}

MATCHER_P(HasMetrics, matcher, "") {
  return ExplainMatchResult(matcher, arg.metrics, result_listener);
}

using BtmServiceUkmTest = BtmServiceTest;

TEST_F(BtmServiceUkmTest, BothChainBeginAndChainEnd) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  TestBrowserContext profile;
  BtmServiceImpl* service = BtmServiceImpl::Get(&profile);

  GURL initial_url = GURL("http://a.test/");
  ukm::SourceId initial_source_id = ukm::AssignNewSourceId();
  GURL redirect_url1 = GURL("http://b.test/");
  ukm::SourceId redirect_source_id1 = ukm::AssignNewSourceId();
  GURL redirect_url2 = GURL("http://c.test/first");
  ukm::SourceId redirect_source_id2 = ukm::AssignNewSourceId();
  GURL final_url = GURL("http://c.test/second");
  ukm::SourceId final_source_id = ukm::AssignNewSourceId();

  BtmRedirectChainObserver observer(service, final_url);
  std::vector<BtmRedirectInfoPtr> redirects;
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      redirect_url1, redirect_source_id1,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      redirect_url2, redirect_source_id2,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  BtmRedirectChainInfoPtr chain = std::make_unique<BtmRedirectChainInfo>(
      initial_url, initial_source_id, final_url, final_source_id,
      /*length=*/2, /*is_partial_chain=*/false,
      /*are_3pcs_generally_enabled=*/false);
  const int32_t chain_id = chain->chain_id;
  btm::Populate3PcExceptions(&profile, /*web_contents=*/nullptr, initial_url,
                             final_url, redirects);
  service->HandleRedirectChain(std::move(redirects), std::move(chain),
                               base::DoNothing());
  observer.Wait();

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainBegin",
                                      {"ChainId", "InitialAndFinalSitesSame"}),
              ElementsAre(AllOf(HasSourceId(initial_source_id),
                                HasMetrics(ElementsAre(
                                    Pair("ChainId", chain_id),
                                    Pair("InitialAndFinalSitesSame", 0))))));

  EXPECT_THAT(
      ukm_recorder.GetEntries("BTM.Redirect",
                              {"ChainId", "InitialAndFinalSitesSame"}),
      ElementsAre(
          AllOf(HasSourceId(redirect_source_id1),
                HasMetrics(ElementsAre(Pair("ChainId", chain_id),
                                       Pair("InitialAndFinalSitesSame", 0)))),
          AllOf(HasSourceId(redirect_source_id2),
                HasMetrics(ElementsAre(Pair("ChainId", chain_id),
                                       Pair("InitialAndFinalSitesSame", 0))))));

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainEnd",
                                      {"ChainId", "InitialAndFinalSitesSame"}),
              ElementsAre(AllOf(HasSourceId(final_source_id),
                                HasMetrics(ElementsAre(
                                    Pair("ChainId", chain_id),
                                    Pair("InitialAndFinalSitesSame", 0))))));
}

TEST_F(BtmServiceUkmTest, InitialAndFinalSitesSame_True) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  TestBrowserContext profile;
  BtmServiceImpl* service = BtmServiceImpl::Get(&profile);

  GURL initial_url = GURL("http://a.test/");
  ukm::SourceId initial_source_id = ukm::AssignNewSourceId();
  GURL redirect_url = GURL("http://b.test/");
  ukm::SourceId redirect_source_id = ukm::AssignNewSourceId();
  GURL final_url = GURL("http://a.test/different-path");
  ukm::SourceId final_source_id = ukm::AssignNewSourceId();

  BtmRedirectChainObserver observer(service, final_url);
  std::vector<BtmRedirectInfoPtr> redirects;
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      redirect_url, redirect_source_id,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  BtmRedirectChainInfoPtr chain = std::make_unique<BtmRedirectChainInfo>(
      initial_url, initial_source_id, final_url, final_source_id,
      /*length=*/1, /*is_partial_chain=*/false,
      /*are_3pcs_generally_enabled=*/false);
  btm::Populate3PcExceptions(&profile, /*web_contents=*/nullptr,
                             chain->initial_url, chain->final_url, redirects);
  service->HandleRedirectChain(std::move(redirects), std::move(chain),
                               base::DoNothing());
  observer.Wait();

  EXPECT_THAT(
      ukm_recorder.GetEntries("BTM.ChainBegin", {"InitialAndFinalSitesSame"}),
      ElementsAre(
          AllOf(HasSourceId(initial_source_id),
                HasMetrics(ElementsAre(Pair("InitialAndFinalSitesSame", 1))))));

  EXPECT_THAT(
      ukm_recorder.GetEntries("BTM.Redirect", {"InitialAndFinalSitesSame"}),
      ElementsAre(
          AllOf(HasSourceId(redirect_source_id),
                HasMetrics(ElementsAre(Pair("InitialAndFinalSitesSame", 1))))));

  EXPECT_THAT(
      ukm_recorder.GetEntries("BTM.ChainEnd", {"InitialAndFinalSitesSame"}),
      ElementsAre(
          AllOf(HasSourceId(final_source_id),
                HasMetrics(ElementsAre(Pair("InitialAndFinalSitesSame", 1))))));
}

TEST_F(BtmServiceUkmTest, DontReportEmptyChainsAtAll) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  TestBrowserContext profile;
  BtmServiceImpl* service = BtmServiceImpl::Get(&profile);

  GURL initial_url = GURL("http://a.test/");
  ukm::SourceId initial_source_id = ukm::AssignNewSourceId();
  GURL final_url = GURL("http://b.test/");
  ukm::SourceId final_source_id = ukm::AssignNewSourceId();

  BtmRedirectChainObserver observer(service, final_url);
  BtmRedirectChainInfoPtr chain = std::make_unique<BtmRedirectChainInfo>(
      initial_url, initial_source_id, final_url, final_source_id,
      /*length=*/0, /*is_partial_chain=*/false,
      /*are_3pcs_generally_enabled*/ false);

  service->HandleRedirectChain({}, std::move(chain), base::DoNothing());
  observer.Wait();

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainBegin", {}), IsEmpty());
  EXPECT_THAT(ukm_recorder.GetEntries("BTM.Redirect", {}), IsEmpty());
  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainEnd", {}), IsEmpty());
}

TEST_F(BtmServiceUkmTest, DontReportChainBeginIfInvalidSourceId) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  TestBrowserContext profile;
  BtmServiceImpl* service = BtmServiceImpl::Get(&profile);

  GURL redirect_url = GURL("http://b.test/");
  ukm::SourceId redirect_source_id = ukm::AssignNewSourceId();
  GURL final_url = GURL("http://c.test/");
  ukm::SourceId final_source_id = ukm::AssignNewSourceId();

  BtmRedirectChainObserver observer(service, final_url);
  std::vector<BtmRedirectInfoPtr> redirects;
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      redirect_url, redirect_source_id,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  BtmRedirectChainInfoPtr chain = std::make_unique<BtmRedirectChainInfo>(
      GURL(), ukm::kInvalidSourceId, final_url, final_source_id,
      /*length=*/1, /*is_partial_chain=*/false,
      /*are_3pcs_generally_enabled=*/false);
  btm::Populate3PcExceptions(&profile, /*web_contents=*/nullptr,
                             chain->initial_url, chain->final_url, redirects);
  service->HandleRedirectChain(std::move(redirects), std::move(chain),
                               base::DoNothing());
  observer.Wait();

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainBegin", {}), IsEmpty());

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.Redirect", {}),
              ElementsAre(AllOf(HasSourceId(redirect_source_id))));

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainEnd", {}),
              ElementsAre(AllOf(HasSourceId(final_source_id))));
}

TEST_F(BtmServiceUkmTest, DontReportChainEndIfInvalidSourceId) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  TestBrowserContext profile;
  BtmServiceImpl* service = BtmServiceImpl::Get(&profile);

  GURL initial_url = GURL("http://a.test/");
  ukm::SourceId initial_source_id = ukm::AssignNewSourceId();
  GURL redirect_url = GURL("http://b.test/");
  ukm::SourceId redirect_source_id = ukm::AssignNewSourceId();

  BtmRedirectChainObserver observer(service, GURL());
  std::vector<BtmRedirectInfoPtr> redirects;
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      redirect_url, redirect_source_id,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  BtmRedirectChainInfoPtr chain = std::make_unique<BtmRedirectChainInfo>(
      initial_url, initial_source_id, GURL(), ukm::kInvalidSourceId,
      /*length=*/1, /*is_partial_chain=*/false,
      /*are_3pcs_generally_enabled=*/false);
  btm::Populate3PcExceptions(&profile, /*web_contents=*/nullptr,
                             chain->initial_url, chain->final_url, redirects);
  service->HandleRedirectChain(std::move(redirects), std::move(chain),
                               base::DoNothing());
  observer.Wait();

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainBegin", {}),
              ElementsAre(AllOf(HasSourceId(initial_source_id))));

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.Redirect", {}),
              ElementsAre(AllOf(HasSourceId(redirect_source_id))));

  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainEnd", {}), IsEmpty());
}

TEST_F(BtmServiceUkmTest, DontReportChainIfTpcsEnabled) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  TestBrowserContext profile;
  BtmServiceImpl* service = BtmServiceImpl::Get(&profile);

  GURL initial_url = GURL("http://a.test/");
  ukm::SourceId initial_source_id = ukm::AssignNewSourceId();
  GURL redirect_url = GURL("http://b.test/");
  ukm::SourceId redirect_source_id = ukm::AssignNewSourceId();
  GURL final_url = GURL("http://c.test/");
  ukm::SourceId final_source_id = ukm::AssignNewSourceId();

  BtmRedirectChainObserver observer(service, final_url);
  std::vector<BtmRedirectInfoPtr> redirects;
  redirects.push_back(BtmRedirectInfo::CreateForServer(
      redirect_url, redirect_source_id,
      /*access_type=*/BtmDataAccessType::kNone,
      /*time=*/base::Time::Now(),
      /*was_response_cached=*/false,
      /*response_code=*/net::HTTP_FOUND,
      /*server_bounce_delay=*/base::TimeDelta()));
  BtmRedirectChainInfoPtr chain = std::make_unique<BtmRedirectChainInfo>(
      initial_url, initial_source_id, final_url, final_source_id,
      redirects.size(), /*is_partial_chain=*/false,
      /*are_3pcs_generally_enabled=*/true);
  btm::Populate3PcExceptions(&profile, /*web_contents=*/nullptr, initial_url,
                             final_url, redirects);
  service->HandleRedirectChain(std::move(redirects), std::move(chain),
                               base::DoNothing());
  observer.Wait();

  // There should be no BTM chain UKMs, as processing gets short-circuited when
  // third-party cookies are enabled.
  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainBegin", {"ChainId"}),
              IsEmpty());
  EXPECT_THAT(ukm_recorder.GetEntries("BTM.Redirect", {"ChainId"}), IsEmpty());
  EXPECT_THAT(ukm_recorder.GetEntries("BTM.ChainEnd", {"ChainId"}), IsEmpty());
}

}  // namespace content
