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

#include <memory>

#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "chrome/browser/background_fetch/background_fetch_delegate_impl.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/download/background_download_service_factory.h"
#include "chrome/browser/download/download_request_limiter.h"
#include "chrome/browser/offline_items_collection/offline_content_aggregator_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_key.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/background_fetch/job_details.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/download/public/background_service/background_download_service.h"
#include "components/download/public/background_service/logger.h"
#include "components/offline_items_collection/core/offline_content_aggregator.h"
#include "components/offline_items_collection/core/offline_content_provider.h"
#include "components/offline_items_collection/core/offline_item.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/fenced_frame_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/http_response.h"
#include "services/metrics/public/cpp/metrics_utils.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "url/origin.h"

using offline_items_collection::ContentId;
using offline_items_collection::OfflineContentProvider;
using GetVisualsOptions =
    offline_items_collection::OfflineContentProvider::GetVisualsOptions;
using offline_items_collection::OfflineItem;
using offline_items_collection::OfflineItemFilter;
using offline_items_collection::OfflineItemProgressUnit;
using offline_items_collection::OfflineItemVisuals;

namespace {

using net::test_server::BasicHttpResponse;
using net::test_server::HttpRequest;
using net::test_server::HttpResponse;

// Scripts run by this test are defined in
// chrome/test/data/background_fetch/background_fetch.js.

// URL of the test helper page that helps drive these tests.
const char kHelperPage[] = "/background_fetch/background_fetch.html";

// Name of the Background Fetch client as known by the download service.
const char kBackgroundFetchClient[] = "BackgroundFetch";

// Stringified values of request services made to the download service.
const char kResultAccepted[] = "ACCEPTED";

// Title of a Background Fetch started by StartSingleFileDownload().
const char kSingleFileDownloadTitle[] = "Single-file Background Fetch";

// Size of the downloaded resource, used in BackgroundFetch tests.
const int kDownloadedResourceSizeInBytes = 82;

// Incorrect downloadTotal, when it's set too high in the JavaScript file
// loaded by this test.
const int kDownloadTotalBytesTooHigh = 1000;

// Incorrect downloadTotal, when it's set too low in the JavaScript file
// loaded by this test.
const int kDownloadTotalBytesTooLow = 80;

// Number of requests in the fetch() call from the JavaScript file loaded by
// this test.
const int kNumRequestsInFetch = 1;

// Number of icons in the fetch() call from the JavaScript file loaded by this
// test.
const int kNumIconsInFetch = 1;

// Exponential bucket spacing for UKM event data.
const double kUkmEventDataBucketSpacing = 2.0;

// Implementation of a download system logger that provides the ability to wait
// for certain events to happen, notably added and progressing downloads.
class WaitableDownloadLoggerObserver : public download::Logger::Observer {
 public:
  using DownloadAcceptedCallback =
      base::OnceCallback<void(const std::string& guid)>;

  WaitableDownloadLoggerObserver() = default;

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

  ~WaitableDownloadLoggerObserver() override = default;

  // Sets the |callback| to be invoked when a download has been accepted.
  void set_download_accepted_callback(DownloadAcceptedCallback callback) {
    download_accepted_callback_ = std::move(callback);
  }

  // download::Logger::Observer implementation:
  void OnServiceStatusChanged(
      const base::Value::Dict& service_status) override {}
  void OnServiceDownloadsAvailable(
      const base::Value::List& service_downloads) override {}
  void OnServiceDownloadChanged(
      const base::Value::Dict& service_download) override {}
  void OnServiceDownloadFailed(
      const base::Value::Dict& service_download) override {}
  void OnServiceRequestMade(const base::Value::Dict& service_request) override {
    const std::string* client = service_request.FindString("client");
    const std::string* guid = service_request.FindString("guid");
    const std::string* result = service_request.FindString("result");

    if (*client != kBackgroundFetchClient)
      return;  // This event is not targeted to us.

    if (*result == kResultAccepted && download_accepted_callback_)
      std::move(download_accepted_callback_).Run(*guid);
  }

 private:
  DownloadAcceptedCallback download_accepted_callback_;
};

// Observes the offline item collection's content provider and then invokes the
// associated test callbacks when one has been provided.
class OfflineContentProviderObserver final
    : public OfflineContentProvider::Observer {
 public:
  using ItemsAddedCallback =
      base::OnceCallback<void(const std::vector<OfflineItem>&)>;
  using ItemUpdatedCallback = base::OnceCallback<void(const OfflineItem&)>;
  using FinishedProcessingItemCallback =
      base::OnceCallback<void(const OfflineItem&)>;

  OfflineContentProviderObserver() = default;

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

  ~OfflineContentProviderObserver() final = default;

  void set_items_added_callback(ItemsAddedCallback callback) {
    items_added_callback_ = std::move(callback);
  }

  void set_finished_processing_item_callback(
      FinishedProcessingItemCallback callback) {
    finished_processing_item_callback_ = std::move(callback);
  }

  void set_delegate(BackgroundFetchDelegateImpl* delegate) {
    delegate_ = delegate;
  }

  void PauseOnNextUpdate() {
    DCHECK(!resume_);
    pause_ = true;
  }

  void ResumeOnNextUpdate() {
    DCHECK(!pause_);
    resume_ = true;
  }

  // OfflineContentProvider::Observer implementation:
  void OnItemsAdded(
      const OfflineContentProvider::OfflineItemList& items) override {
    if (items_added_callback_)
      std::move(items_added_callback_).Run(items);
  }

  void OnItemRemoved(const ContentId& id) override {}
  void OnItemUpdated(const OfflineItem& item,
                     const std::optional<offline_items_collection::UpdateDelta>&
                         update_delta) override {
    if (item.state != offline_items_collection::OfflineItemState::IN_PROGRESS &&
        item.state != offline_items_collection::OfflineItemState::PENDING &&
        item.state != offline_items_collection::OfflineItemState::PAUSED &&
        finished_processing_item_callback_) {
      std::move(finished_processing_item_callback_).Run(item);
    }

    if (pause_) {
      if (item.state == offline_items_collection::OfflineItemState::PAUSED) {
        Resume(item.id);
        pause_ = false;
      } else {
        delegate_->PauseDownload(item.id);
      }
    }

    if (resume_ &&
        item.state == offline_items_collection::OfflineItemState::PAUSED) {
      Resume(item.id);
      resume_ = false;
    }

    // Check that the progress is always increasing and never resets.
    DCHECK_GE(item.progress.value, latest_item_.progress.value);
    latest_item_ = item;
  }
  void OnContentProviderGoingDown() override {}

  const OfflineItem& latest_item() const { return latest_item_; }

 private:
  void Resume(const ContentId& id) { delegate_->ResumeDownload(id); }

  ItemsAddedCallback items_added_callback_;
  FinishedProcessingItemCallback finished_processing_item_callback_;
  raw_ptr<BackgroundFetchDelegateImpl, AcrossTasksDanglingUntriaged> delegate_ =
      nullptr;
  bool pause_ = false;
  bool resume_ = false;

  OfflineItem latest_item_;
};

}  // namespace

class BackgroundFetchBrowserTest : public InProcessBrowserTest {
 public:
  BackgroundFetchBrowserTest()
      : offline_content_provider_observer_(
            std::make_unique<OfflineContentProviderObserver>()) {}

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

  ~BackgroundFetchBrowserTest() override = default;

  void SetUpOnMainThread() override {
    https_server_ = std::make_unique<net::EmbeddedTestServer>(
        net::EmbeddedTestServer::TYPE_HTTPS);
    https_server_->RegisterRequestHandler(base::BindRepeating(
        &BackgroundFetchBrowserTest::HandleRequest, base::Unretained(this)));
    https_server_->AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(https_server_->Start());

    Profile* profile = browser()->profile();

    download_observer_ = std::make_unique<WaitableDownloadLoggerObserver>();

    download_service_ =
        BackgroundDownloadServiceFactory::GetForKey(profile->GetProfileKey());
    download_service_->GetLogger()->AddObserver(download_observer_.get());

    // Register our observer for the offline items collection.
    OfflineContentAggregatorFactory::GetInstance()
        ->GetForKey(profile->GetProfileKey())
        ->AddObserver(offline_content_provider_observer_.get());

    SetUpBrowser(browser());

    delegate_ = static_cast<BackgroundFetchDelegateImpl*>(
        active_browser_->profile()->GetBackgroundFetchDelegate());
    DCHECK(delegate_);

    offline_content_provider_observer_->set_delegate(delegate_);
  }

  virtual void SetUpBrowser(Browser* browser) {
    set_active_browser(browser);
    // Load the helper page that helps drive these tests.
    ASSERT_TRUE(ui_test_utils::NavigateToURL(
        browser, https_server_->GetURL(kHelperPage)));

    // Register the Service Worker that's required for Background Fetch. The
    // behaviour without an activated worker is covered by layout tests.
    ASSERT_EQ("ok - service worker registered",
              RunScript("RegisterServiceWorker()"));

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

  void TearDownOnMainThread() override {
    OfflineContentAggregatorFactory::GetInstance()
        ->GetForKey(active_browser_->profile()->GetProfileKey())
        ->RemoveObserver(offline_content_provider_observer_.get());

    download_service_->GetLogger()->RemoveObserver(download_observer_.get());
    download_service_ = nullptr;
  }

  // ---------------------------------------------------------------------------
  // Test execution functions.

  // Runs the |script| and waits for one or more items to have been added to the
  // offline items collection.
  void RunScriptAndWaitForOfflineItems(const std::string& script,
                                       std::vector<OfflineItem>* items) {
    DCHECK(items);

    base::RunLoop run_loop;
    offline_content_provider_observer_->set_items_added_callback(
        base::BindOnce(&BackgroundFetchBrowserTest::DidAddItems,
                       base::Unretained(this), run_loop.QuitClosure(), items));

    ASSERT_EQ("ok", RunScript(script));

    run_loop.Run();
  }

  // Runs the |script| and checks the result.
  void RunScriptAndCheckResultingMessage(const std::string& script,
                                         const std::string& expected_message) {
    ASSERT_EQ(expected_message, RunScript(script));
  }

  void GetVisualsForOfflineItemSync(
      const ContentId& offline_item_id,
      std::unique_ptr<OfflineItemVisuals>* out_visuals) {
    base::RunLoop run_loop;

    delegate_->GetVisualsForItem(
        offline_item_id, GetVisualsOptions::IconOnly(),
        base::BindOnce(&BackgroundFetchBrowserTest::DidGetVisuals,
                       base::Unretained(this), run_loop.QuitClosure(),
                       out_visuals));
    run_loop.Run();
  }

  // ---------------------------------------------------------------------------
  // Helper functions.

  // Runs the |script| in the current tab and writes the output to |*result|.
  content::EvalJsResult RunScript(const std::string& script) {
    return content::EvalJs(active_browser_->tab_strip_model()
                               ->GetActiveWebContents()
                               ->GetPrimaryMainFrame(),
                           script);
  }

  // Runs the given |function| and asserts that it responds with "ok".
  // Must be wrapped with ASSERT_NO_FATAL_FAILURE().
  void RunScriptFunction(const std::string& function) {
    ASSERT_EQ("ok", RunScript(function));
  }

  // Intercepts all requests.
  std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
    if (request.GetURL().path() == "/background_fetch/upload") {
      DCHECK(!request.content.empty());
      DCHECK(request_body_.empty());
      request_body_ = request.content;

      auto response = std::make_unique<BasicHttpResponse>();
      response->set_code(net::HTTP_OK);
      return response;
    }

    if (request.GetURL().query() == "clickevent")
      std::move(click_event_closure_).Run();

    // The default handlers will take care of this request.
    return nullptr;
  }

  // Gets the ideal display size.
  gfx::Size GetIconDisplaySize() {
    gfx::Size out_display_size;
    base::RunLoop run_loop;
    browser()->profile()->GetBackgroundFetchDelegate()->GetIconDisplaySize(
        base::BindOnce(&BackgroundFetchBrowserTest::DidGetIconDisplaySize,
                       base::Unretained(this), run_loop.QuitClosure(),
                       &out_display_size));
    run_loop.Run();
    return out_display_size;
  }

  // Called when we've received the ideal icon display size from
  // BackgroundFetchDelegate.
  void DidGetIconDisplaySize(base::OnceClosure quit_closure,
                             gfx::Size* out_display_size,
                             const gfx::Size& display_size) {
    DCHECK(out_display_size);
    *out_display_size = display_size;
    std::move(quit_closure).Run();
  }

  // Callback for WaitableDownloadLoggerObserver::DownloadAcceptedCallback().
  void DidAcceptDownloadCallback(base::OnceClosure quit_closure,
                                 std::string* out_guid,
                                 const std::string& guid) {
    DCHECK(out_guid);
    *out_guid = guid;

    std::move(quit_closure).Run();
  }

  // Called when the an offline item has been processed.
  void DidFinishProcessingItem(base::OnceClosure quit_closure,
                               OfflineItem* out_item,
                               const OfflineItem& processed_item) {
    DCHECK(out_item);
    *out_item = processed_item;
    std::move(quit_closure).Run();
  }

  void RevokeDownloadPermission() {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    DownloadRequestLimiter::TabDownloadState* tab_download_state =
        g_browser_process->download_request_limiter()->GetDownloadState(
            web_contents, true /* create */);
    tab_download_state->set_download_seen();
    tab_download_state->SetDownloadStatusAndNotify(
        url::Origin::Create(web_contents->GetVisibleURL()),
        DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED);
  }

  void SetPermission(ContentSettingsType content_type, ContentSetting setting) {
    auto* settings_map =
        HostContentSettingsMapFactory::GetForProfile(browser()->profile());
    DCHECK(settings_map);

    ContentSettingsPattern host_pattern =
        ContentSettingsPattern::FromURL(https_server_->base_url());

    settings_map->SetContentSettingCustomScope(
        host_pattern, ContentSettingsPattern::Wildcard(), content_type,
        setting);
  }

  void DidUpdateItem(base::OnceClosure quit_closure,
                     OfflineItem* out_item,
                     const OfflineItem& item) {
    *out_item = item;
    std::move(quit_closure).Run();
  }

  void set_active_browser(Browser* browser) { active_browser_ = browser; }

  net::EmbeddedTestServer* https_server() { return https_server_.get(); }

 protected:
  raw_ptr<BackgroundFetchDelegateImpl, AcrossTasksDanglingUntriaged> delegate_ =
      nullptr;
  raw_ptr<download::BackgroundDownloadService, AcrossTasksDanglingUntriaged>
      download_service_ = nullptr;
  base::OnceClosure click_event_closure_;

  std::unique_ptr<WaitableDownloadLoggerObserver> download_observer_;
  std::unique_ptr<OfflineContentProviderObserver>
      offline_content_provider_observer_;
  std::unique_ptr<ukm::TestUkmRecorder> test_ukm_recorder_;
  std::string request_body_;

 private:
  // Callback for RunScriptAndWaitForOfflineItems(), called when the |items|
  // have been added to the offline items collection.
  void DidAddItems(base::OnceClosure quit_closure,
                   std::vector<OfflineItem>* out_items,
                   const std::vector<OfflineItem>& items) {
    *out_items = items;
    std::move(quit_closure).Run();
  }

  void DidGetVisuals(base::OnceClosure quit_closure,
                     std::unique_ptr<OfflineItemVisuals>* out_visuals,
                     const ContentId& offline_item_id,
                     std::unique_ptr<OfflineItemVisuals> visuals) {
    *out_visuals = std::move(visuals);
    std::move(quit_closure).Run();
  }

  std::unique_ptr<net::EmbeddedTestServer> https_server_;

  raw_ptr<Browser, AcrossTasksDanglingUntriaged> active_browser_ = nullptr;
};

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, DownloadService_Acceptance) {
  // Starts a Background Fetch for a single to-be-downloaded file and waits for
  // that request to be scheduled with the Download Service.

  std::string guid;
  {
    base::RunLoop run_loop;
    download_observer_->set_download_accepted_callback(
        base::BindOnce(&BackgroundFetchBrowserTest::DidAcceptDownloadCallback,
                       base::Unretained(this), run_loop.QuitClosure(), &guid));

    ASSERT_NO_FATAL_FAILURE(RunScriptFunction("StartSingleFileDownload()"));
    run_loop.Run();
  }

  EXPECT_FALSE(guid.empty());
}

// Flaky on linux: crbug.com/1182296
#if BUILDFLAG(IS_LINUX)
#define MAYBE_RecordBackgroundFetchUkmEvent \
  DISABLED_RecordBackgroundFetchUkmEvent
#else
#define MAYBE_RecordBackgroundFetchUkmEvent RecordBackgroundFetchUkmEvent
#endif
IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       MAYBE_RecordBackgroundFetchUkmEvent) {
  // Start a Background Fetch for a single to-be-downloaded file and  test that
  // the expected UKM data for the BackgroundFetch UKM event has been recorded.

  ASSERT_NO_FATAL_FAILURE(
      RunScriptFunction("StartSingleFileDownloadWithCorrectDownloadTotal()"));

  std::vector<raw_ptr<const ukm::mojom::UkmEntry, VectorExperimental>> entries =
      test_ukm_recorder_->GetEntriesByName(
          ukm::builders::BackgroundFetch::kEntryName);
  ASSERT_EQ(1u, entries.size());
  const auto* entry = entries[0].get();
  test_ukm_recorder_->ExpectEntryMetric(
      entry, ukm::builders::BackgroundFetch::kHasTitleName, 1);
  test_ukm_recorder_->ExpectEntryMetric(
      entry, ukm::builders::BackgroundFetch::kNumIconsName, kNumIconsInFetch);
  test_ukm_recorder_->ExpectEntryMetric(
      entry, ukm::builders::BackgroundFetch::kDownloadTotalName,
      ukm::GetExponentialBucketMin(kDownloadedResourceSizeInBytes,
                                   kUkmEventDataBucketSpacing));
  test_ukm_recorder_->ExpectEntryMetric(
      entry, ukm::builders::BackgroundFetch::kNumRequestsInFetchName,
      ukm::GetExponentialBucketMin(kNumRequestsInFetch,
                                   kUkmEventDataBucketSpacing));
  test_ukm_recorder_->ExpectEntryMetric(
      entry, ukm::builders::BackgroundFetch::kDeniedDueToPermissionsName, 0);
  // There is currently no desktop UI for BackgroundFetch, hence the icon
  // display size is set to 0,0. Once that's no longer the case, this ASSERT
  // will start failing and the unit test will have to be updated.
  ASSERT_TRUE(GetIconDisplaySize().IsEmpty());
  test_ukm_recorder_->ExpectEntryMetric(
      entry, ukm::builders::BackgroundFetch::kRatioOfIdealToChosenIconSizeName,
      -1);
}

#if BUILDFLAG(IS_MAC)
// Flaky on Mac: https://crbug.com/1259680
#define MAYBE_OfflineItemCollection_SingleFileMetadata \
  DISABLED_OfflineItemCollection_SingleFileMetadata
#else
#define MAYBE_OfflineItemCollection_SingleFileMetadata \
  OfflineItemCollection_SingleFileMetadata
#endif

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       MAYBE_OfflineItemCollection_SingleFileMetadata) {
  // Starts a Background Fetch for a single to-be-downloaded file and waits for
  // the fetch to be registered with the offline items collection. We then
  // verify that all the appropriate values have been set.

  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(
      RunScriptAndWaitForOfflineItems("StartSingleFileDownload()", &items));
  ASSERT_EQ(items.size(), 1u);

  const OfflineItem& offline_item = items[0];

  // Verify that the appropriate data is being set.
  EXPECT_EQ(offline_item.title, kSingleFileDownloadTitle);
  EXPECT_EQ(offline_item.filter, OfflineItemFilter::FILTER_OTHER);
  EXPECT_TRUE(offline_item.is_transient);
  EXPECT_TRUE(offline_item.is_resumable);
  EXPECT_FALSE(offline_item.is_suggested);
  EXPECT_FALSE(offline_item.is_off_the_record);

  // When downloadTotal isn't specified, we report progress by parts.
  EXPECT_EQ(offline_item.progress.value, 0);
  EXPECT_EQ(offline_item.progress.max.value(), 1);
  EXPECT_EQ(offline_item.progress.unit, OfflineItemProgressUnit::PERCENTAGE);

  // Change-detector tests for values we might want to provide or change.
  EXPECT_TRUE(offline_item.description.empty());
  EXPECT_TRUE(offline_item.url.is_empty());
  EXPECT_FALSE(offline_item.is_off_the_record);
}

// Flaky on multiple platforms (b/323879025)/
IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       DISABLED_OfflineItemCollection_VerifyIconReceived) {
  // Starts a Background Fetch for a single to-be-downloaded file and waits for
  // the fetch to be registered with the offline items collection. We then
  // verify that the expected icon is associated with the newly added offline
  // item.

  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(
      RunScriptAndWaitForOfflineItems("StartSingleFileDownload()", &items));
  ASSERT_EQ(items.size(), 1u);

  const OfflineItem& offline_item = items[0];

  // Verify that the appropriate data is being set.
  EXPECT_EQ(offline_item.progress.value, 0);
  EXPECT_EQ(offline_item.progress.max.value(), 1);
  EXPECT_EQ(offline_item.progress.unit, OfflineItemProgressUnit::PERCENTAGE);
  EXPECT_FALSE(offline_item.creation_time.is_null());

  // Get visuals associated with the newly added offline item.
  std::unique_ptr<OfflineItemVisuals> out_visuals;
  GetVisualsForOfflineItemSync(offline_item.id, &out_visuals);
#if BUILDFLAG(IS_ANDROID)
  EXPECT_FALSE(out_visuals->icon.IsEmpty());
  EXPECT_EQ(out_visuals->icon.Size().width(), 100);
  EXPECT_EQ(out_visuals->icon.Size().height(), 100);
#else
  EXPECT_TRUE(out_visuals->icon.IsEmpty());
#endif
}

IN_PROC_BROWSER_TEST_F(
    BackgroundFetchBrowserTest,
    DISABLED_OfflineItemCollection_VerifyResourceDownloadedWhenDownloadTotalLargerThanActualSize) {
  // Starts a Background Fetch for a single to-be-downloaded file and waits for
  // the fetch to be registered with the offline items collection.
  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(RunScriptAndWaitForOfflineItems(
      "StartSingleFileDownloadWithBiggerThanActualDownloadTotal()", &items));
  ASSERT_EQ(items.size(), 1u);

  OfflineItem offline_item = items[0];

  // Verify that the appropriate data is being set when we start downloading.
  EXPECT_EQ(offline_item.progress.value, 0);
  EXPECT_EQ(offline_item.progress.max.value(), kDownloadTotalBytesTooHigh);
  EXPECT_EQ(offline_item.progress.unit, OfflineItemProgressUnit::PERCENTAGE);

  // Wait for the download to be completed.
  {
    base::RunLoop run_loop;
    offline_content_provider_observer_->set_finished_processing_item_callback(
        base::BindOnce(&BackgroundFetchBrowserTest::DidFinishProcessingItem,
                       base::Unretained(this), run_loop.QuitClosure(),
                       &offline_item));
    run_loop.Run();
  }

  // Download total is too high; check that we're still reporting by size,
  // but have set the max value of the progress bar to the actual download size.
  EXPECT_EQ(offline_item.state,
            offline_items_collection::OfflineItemState::COMPLETE);
  EXPECT_EQ(offline_item.progress.max.value(), offline_item.progress.value);
  EXPECT_EQ(offline_item.progress.max.value(), kDownloadedResourceSizeInBytes);
}

// The test is flaky on all platforms. https://crbug.com/1161385.
IN_PROC_BROWSER_TEST_F(
    BackgroundFetchBrowserTest,
    DISABLED_OfflineItemCollection_VerifyResourceDownloadedWhenDownloadTotalSmallerThanActualSize) {
  // Starts a Background Fetch for a single to-be-downloaded file and waits for
  // the fetch to be registered with the offline items collection.
  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(RunScriptAndWaitForOfflineItems(
      "StartSingleFileDownloadWithSmallerThanActualDownloadTotal()", &items));
  ASSERT_EQ(items.size(), 1u);

  OfflineItem offline_item = items[0];

  // Verify that the appropriate data is being set when we start downloading.
  EXPECT_EQ(offline_item.progress.value, 0);
  EXPECT_EQ(offline_item.progress.max.value(), kDownloadTotalBytesTooLow);
  EXPECT_EQ(offline_item.progress.unit, OfflineItemProgressUnit::PERCENTAGE);

  // Wait for the offline_item to be processed.
  {
    base::RunLoop run_loop;
    offline_content_provider_observer_->set_finished_processing_item_callback(
        base::BindOnce(&BackgroundFetchBrowserTest::DidFinishProcessingItem,
                       base::Unretained(this), run_loop.QuitClosure(),
                       &offline_item));
    run_loop.Run();
  }

  // Download total is too low; check that we cancel the download when the
  // bytes downloaded exceed downloadTotal.
  EXPECT_EQ(offline_item.state,
            offline_items_collection::OfflineItemState::CANCELLED);
}

// TODO(crbug.com/40842751): Fix flaky timeouts and re-enable.
IN_PROC_BROWSER_TEST_F(
    BackgroundFetchBrowserTest,
    DISABLED_OfflineItemCollection_VerifyResourceDownloadedWhenCorrectDownloadTotalSpecified) {
  // Starts a Background Fetch for a single to-be-downloaded file and waits for
  // the fetch to be registered with the offline items collection.

  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(RunScriptAndWaitForOfflineItems(
      "StartSingleFileDownloadWithCorrectDownloadTotal()", &items));
  ASSERT_EQ(items.size(), 1u);

  const OfflineItem& offline_item = items[0];

  // Verify that the appropriate data is being set when downloadTotal is
  // correctly set.
  EXPECT_EQ(offline_item.progress.value, 0);
  EXPECT_EQ(offline_item.progress.max.value(), kDownloadedResourceSizeInBytes);
  EXPECT_EQ(offline_item.progress.unit, OfflineItemProgressUnit::PERCENTAGE);
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       OfflineItemCollection_IncognitoPropagated) {
  // Starts a fetch from an incognito profile, and makes sure that the
  // OfflineItem has the appropriate fields set.
  SetUpBrowser(CreateIncognitoBrowser());

  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(
      RunScriptAndWaitForOfflineItems("StartSingleFileDownload()", &items));
  ASSERT_EQ(items.size(), 1u);
  ASSERT_TRUE(items[0].is_off_the_record);
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       FetchesRunToCompletionAndUpdateTitle_Fetched) {
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "RunFetchTillCompletion()", "backgroundfetchsuccess"));
  EXPECT_EQ(offline_content_provider_observer_->latest_item().state,
            offline_items_collection::OfflineItemState::COMPLETE);

  base::RunLoop().RunUntilIdle();  // Give `updateUI` a chance to propagate.
  EXPECT_TRUE(
      base::StartsWith(offline_content_provider_observer_->latest_item().title,
                       "New Fetched Title!", base::CompareCase::SENSITIVE));
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       FetchesRunToCompletionAndUpdateTitle_Failed) {
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "RunFetchTillCompletionWithMissingResource()", "backgroundfetchfail"));
  EXPECT_EQ(offline_content_provider_observer_->latest_item().state,
            offline_items_collection::OfflineItemState::COMPLETE);

  base::RunLoop().RunUntilIdle();  // Give `updateUI` a chance to propagate.
  EXPECT_TRUE(
      base::StartsWith(offline_content_provider_observer_->latest_item().title,
                       "New Failed Title!", base::CompareCase::SENSITIVE));
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       FetchesRunToCompletion_Upload) {
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "RunFetchTillCompletionWithUpload()", "backgroundfetchsuccess"));

  EXPECT_EQ(request_body_, "upload!");
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, ClickEventIsDispatched) {
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "RunFetchTillCompletion()", "backgroundfetchsuccess"));
  EXPECT_EQ(offline_content_provider_observer_->latest_item().state,
            offline_items_collection::OfflineItemState::COMPLETE);

  base::RunLoop().RunUntilIdle();  // Give updates a chance to propagate.

  ASSERT_EQ(delegate_->ui_state_map_.size(), 1u);
  auto entry = delegate_->ui_state_map_.begin();
  std::string job_id = entry->first;
  auto& offline_item = entry->second.offline_item;
  EXPECT_EQ(offline_items_collection::OfflineItemState::COMPLETE,
            offline_item.state);
  background_fetch::JobDetails* job_details =
      delegate_->GetJobDetails(job_id, /*allow_null=*/true);
  ASSERT_TRUE(!!job_details);
  EXPECT_EQ(job_details->job_state,
            background_fetch::JobDetails::State::kJobComplete);

  // Simulate notification click.
  delegate_->OpenItem(
      offline_items_collection::OpenParams(
          offline_items_collection::LaunchLocation::NOTIFICATION),
      offline_item.id);

  // The offline item and JobDetails should both be deleted at this point.
  EXPECT_TRUE(delegate_->ui_state_map_.empty());
  EXPECT_FALSE(delegate_->GetJobDetails(job_id, /*allow_null=*/true));

  // Wait for click event.
  {
    base::RunLoop run_loop;
    click_event_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }
}

// TODO(crbug.com/40120187): Re-enable this test.
IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, DISABLED_AbortFromUI) {
  std::vector<OfflineItem> items;
  // Creates a registration with more than one request.
  ASSERT_NO_FATAL_FAILURE(
      RunScriptAndWaitForOfflineItems("StartFetchWithMultipleFiles()", &items));
  ASSERT_EQ(items.size(), 1u);

  // Simulate an abort from the UI.
  delegate_->CancelDownload(items[0].id);

  // Wait for an abort event to be dispatched. This is safe because there are
  // more requests to process than the scheduler will handle, and every request
  // needs to contact the delegate. Since the abort originates from the
  // delegate, this fetch will be aborted before the fetch completes.
  // Pass in a no-op function since we only want to wait for a message at this
  // point.
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "(() => {})()", "backgroundfetchabort"));
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, FetchCanBePausedAndResumed) {
  offline_content_provider_observer_->PauseOnNextUpdate();
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "RunFetchTillCompletion()", "backgroundfetchsuccess"));
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       FetchRejectedWithoutPermission) {
  RevokeDownloadPermission();
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "RunFetchAnExpectAnException()",
      "This origin does not have permission to start a fetch."));
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest, FetchFromServiceWorker) {
  auto* settings_map =
      HostContentSettingsMapFactory::GetForProfile(browser()->profile());
  DCHECK(settings_map);

  // Give the needed permissions.
  SetPermission(ContentSettingsType::AUTOMATIC_DOWNLOADS,
                CONTENT_SETTING_ALLOW);

  // The fetch should succeed.
  offline_content_provider_observer_->ResumeOnNextUpdate();
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "StartFetchFromServiceWorker()", "backgroundfetchsuccess"));

  // Revoke Automatic Downloads permission.
  SetPermission(ContentSettingsType::AUTOMATIC_DOWNLOADS,
                CONTENT_SETTING_BLOCK);

  // This should fail without the Automatic Downloads permission.
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "StartFetchFromServiceWorker()", "permissionerror"));
}

// TODO(crbug.com/40805915): Flaky on many platforms.
IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       DISABLED_FetchFromServiceWorkerWithAsk) {
  auto* settings_map =
      HostContentSettingsMapFactory::GetForProfile(browser()->profile());
  DCHECK(settings_map);

  SetPermission(ContentSettingsType::AUTOMATIC_DOWNLOADS, CONTENT_SETTING_ASK);

  // The fetch starts in a paused state.
  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(RunScriptAndWaitForOfflineItems(
      "StartFetchFromServiceWorkerNoWait()", &items));
  ASSERT_EQ(items.size(), 1u);
  EXPECT_EQ(items[0].state,
            offline_items_collection::OfflineItemState::PAUSED);
}

// TODO(crbug.com/40805915): Flaky on many platforms.
IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       DISABLED_FetchFromChildFrameWithPermissions) {
  // Give the needed permissions. The fetch should still start in a paused
  // state.
  SetPermission(ContentSettingsType::AUTOMATIC_DOWNLOADS,
                CONTENT_SETTING_ALLOW);

  // The fetch starts in a paused state.
  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(
      RunScriptAndWaitForOfflineItems("StartFetchFromIframeNoWait()", &items));
  ASSERT_EQ(items.size(), 1u);
  EXPECT_EQ(items[0].state,
            offline_items_collection::OfflineItemState::PAUSED);
}

// TODO(crbug.com/40805915): Flaky on many platforms.
IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       DISABLED_FetchFromChildFrameWithAsk) {
  SetPermission(ContentSettingsType::AUTOMATIC_DOWNLOADS, CONTENT_SETTING_ASK);

  // The fetch starts in a paused state.
  std::vector<OfflineItem> items;
  ASSERT_NO_FATAL_FAILURE(
      RunScriptAndWaitForOfflineItems("StartFetchFromIframeNoWait()", &items));
  ASSERT_EQ(items.size(), 1u);
  EXPECT_EQ(items[0].state,
            offline_items_collection::OfflineItemState::PAUSED);
}

IN_PROC_BROWSER_TEST_F(BackgroundFetchBrowserTest,
                       FetchFromChildFrameWithMissingPermissions) {
  SetPermission(ContentSettingsType::AUTOMATIC_DOWNLOADS,
                CONTENT_SETTING_BLOCK);
  ASSERT_NO_FATAL_FAILURE(RunScriptAndCheckResultingMessage(
      "StartFetchFromIframe()", "permissionerror"));
}

class BackgroundFetchFencedFrameBrowserTest
    : public BackgroundFetchBrowserTest {
 public:
  BackgroundFetchFencedFrameBrowserTest() = default;
  ~BackgroundFetchFencedFrameBrowserTest() override = default;

  void SetUpBrowser(Browser* browser) override {
    set_active_browser(browser);
    GURL url = https_server()->GetURL("/empty.html");
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser, url));

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

  content::test::FencedFrameTestHelper& fenced_frame_test_helper() {
    return fenced_frame_test_helper_;
  }

  void RegisterServiceWorker(content::RenderFrameHost* render_frame_host) {
    ASSERT_EQ("ok - service worker registered",
              content::EvalJs(render_frame_host, "RegisterServiceWorker()"));
  }

  void StartSingleFileDownload(content::RenderFrameHost* render_frame_host,
                               std::string expected_result) {
    ASSERT_EQ(expected_result,
              content::EvalJs(render_frame_host, "StartSingleFileDownload()"));
  }

 private:
  content::test::FencedFrameTestHelper fenced_frame_test_helper_;
};

// Tests that background fetch UKM is not recorded in a fenced frame. The
// renderer should have checked and disallowed the request for fenced frames.
IN_PROC_BROWSER_TEST_F(BackgroundFetchFencedFrameBrowserTest,
                       NoRecordBackgroundFetchUkmEvent) {
  // Load a fenced frame.
  GURL fenced_frame_url(https_server()->GetURL("/fenced_frames/title1.html"));
  content::RenderFrameHost* fenced_frame =
      fenced_frame_test_helper().CreateFencedFrame(browser()
                                                       ->tab_strip_model()
                                                       ->GetActiveWebContents()
                                                       ->GetPrimaryMainFrame(),
                                                   fenced_frame_url);

  GURL fenced_frame_test_url(
      https_server()->GetURL("/fenced_frames/background_fetch.html"));

  // Navigate the fenced frame again.
  fenced_frame = fenced_frame_test_helper().NavigateFrameInFencedFrameTree(
      fenced_frame, fenced_frame_test_url);

  // Register the Service Worker that's required for Background Fetch.
  RegisterServiceWorker(fenced_frame);

  constexpr char kExpectedError[] =
      "NotAllowedError - Failed to execute 'fetch' on "
      "'BackgroundFetchManager': backgroundFetch is not allowed in fenced "
      "frames.";
  StartSingleFileDownload(fenced_frame, kExpectedError);

  std::vector<raw_ptr<const ukm::mojom::UkmEntry, VectorExperimental>> entries =
      test_ukm_recorder_->GetEntriesByName(
          ukm::builders::BackgroundFetch::kEntryName);
  ASSERT_EQ(0u, entries.size());
}

// Tests that UKM record works based on the outer most main frame. This test is
// to check non-same origin case, but actually the background fetch UKM is not
// recorded in a fenced frame regardless of origin difference because the
// renderer should have checked and disallowed the request for fenced frames.
IN_PROC_BROWSER_TEST_F(BackgroundFetchFencedFrameBrowserTest,
                       NoRecordBackgroundFetchUkmEventNotInSameOrigin) {
  net::EmbeddedTestServer cross_origin_server(
      net::EmbeddedTestServer::TYPE_HTTPS);
  cross_origin_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK);
  cross_origin_server.ServeFilesFromSourceDirectory("chrome/test/data");
  ASSERT_TRUE(cross_origin_server.Start());

  // Load a fenced frame.
  GURL fenced_frame_url(
      cross_origin_server.GetURL("/fenced_frames/title1.html"));
  content::RenderFrameHost* fenced_frame =
      fenced_frame_test_helper().CreateFencedFrame(browser()
                                                       ->tab_strip_model()
                                                       ->GetActiveWebContents()
                                                       ->GetPrimaryMainFrame(),
                                                   fenced_frame_url);

  GURL fenced_frame_test_url(
      cross_origin_server.GetURL("/fenced_frames/background_fetch.html"));
  // Navigate the fenced frame again.
  fenced_frame = fenced_frame_test_helper().NavigateFrameInFencedFrameTree(
      fenced_frame, fenced_frame_test_url);

  // Register the Service Worker that's required for Background Fetch.
  RegisterServiceWorker(fenced_frame);

  constexpr char kExpectedError[] =
      "NotAllowedError - Failed to execute 'fetch' on "
      "'BackgroundFetchManager': backgroundFetch is not allowed in fenced "
      "frames.";
  StartSingleFileDownload(fenced_frame, kExpectedError);

  std::vector<raw_ptr<const ukm::mojom::UkmEntry, VectorExperimental>> entries =
      test_ukm_recorder_->GetEntriesByName(
          ukm::builders::BackgroundFetch::kEntryName);
  ASSERT_EQ(0u, entries.size());
}
