// 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().GetPath() == "/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().GetQuery() == "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());
}
