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

#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/repeating_test_future.h"
#include "base/test/test_file_util.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/download/save_package_file_picker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/download/public/common/download_item.h"
#include "components/history/core/browser/download_constants.h"
#include "components/history/core/browser/download_row.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
#include "components/security_state/core/security_state.h"
#include "components/services/quarantine/test_support.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/download_test_observer.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "net/base/filename_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/shell_dialogs/fake_select_file_dialog.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/dbus/dlp/dlp_client.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

using content::BrowserContext;
using content::BrowserThread;
using content::DownloadManager;
using content::RenderFrameHost;
using content::RenderProcessHost;
using content::WebContents;
using download::DownloadItem;
using testing::_;
using testing::ContainsRegex;
using testing::HasSubstr;
using ui::FakeSelectFileDialog;

namespace {

// Returns file contents with each continuous run of whitespace replaced by a
// single space.
std::string ReadFileAndCollapseWhitespace(const base::FilePath& file_path) {
  std::string file_contents;
  if (!base::ReadFileToString(file_path, &file_contents)) {
    ADD_FAILURE() << "Failed to read \"" << file_path.value() << "\" file.";
    return std::string();
  }

  return base::CollapseWhitespaceASCII(file_contents, false);
}

// Prepends a Mark Of The Web to `file_contents`.
std::string PrependMotw(const std::string& file_contents, const GURL& url) {
  return base::StringPrintf("<!-- saved from url=(%04d)%s --> ",
                            url.spec().size(), url.spec().c_str()) +
         file_contents;
}

// Waits for an item record in the downloads database to match |filter|. See
// DownloadStoredProperly() below for an example filter.
class DownloadPersistedObserver : public DownloadHistory::Observer {
 public:
  typedef base::RepeatingCallback<bool(DownloadItem* item,
                                       const history::DownloadRow&)>
      PersistedFilter;

  DownloadPersistedObserver(Profile* profile, const PersistedFilter& filter)
      : profile_(profile),
        filter_(filter),
        persisted_(false) {
    DownloadCoreServiceFactory::GetForBrowserContext(profile_)
        ->GetDownloadHistory()
        ->AddObserver(this);
  }

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

  ~DownloadPersistedObserver() override {
    DownloadCoreService* service =
        DownloadCoreServiceFactory::GetForBrowserContext(profile_);
    if (service && service->GetDownloadHistory())
      service->GetDownloadHistory()->RemoveObserver(this);
  }

  bool WaitForPersisted() {
    if (persisted_)
      return true;
    base::RunLoop run_loop;
    quit_waiting_callback_ = run_loop.QuitClosure();
    run_loop.Run();
    return persisted_;
  }

  void OnDownloadStored(DownloadItem* item,
                        const history::DownloadRow& info) override {
    persisted_ = persisted_ || filter_.Run(item, info);
    if (persisted_ && quit_waiting_callback_)
      std::move(quit_waiting_callback_).Run();
  }

 private:
  raw_ptr<Profile> profile_;
  PersistedFilter filter_;
  base::OnceClosure quit_waiting_callback_;
  bool persisted_;
};

// Waits for an item record to be removed from the downloads database.
class DownloadRemovedObserver : public DownloadPersistedObserver {
 public:
  DownloadRemovedObserver(Profile* profile, int32_t download_id)
      : DownloadPersistedObserver(profile, PersistedFilter()),
        removed_(false),
        download_id_(download_id) {}

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

  ~DownloadRemovedObserver() override = default;

  bool WaitForRemoved() {
    if (removed_)
      return true;
    base::RunLoop run_loop;
    quit_waiting_callback_ = run_loop.QuitClosure();
    run_loop.Run();
    return removed_;
  }

  void OnDownloadStored(DownloadItem* item,
                        const history::DownloadRow& info) override {}

  void OnDownloadsRemoved(const DownloadHistory::IdSet& ids) override {
    removed_ = ids.find(download_id_) != ids.end();
    if (removed_ && quit_waiting_callback_)
      std::move(quit_waiting_callback_).Run();
  }

 private:
  bool removed_;
  base::OnceClosure quit_waiting_callback_;
  int32_t download_id_;
};

bool DownloadStoredProperly(const GURL& expected_url,
                            const base::FilePath& expected_path,
                            int64_t num_files,
                            history::DownloadState expected_state,
                            DownloadItem* item,
                            const history::DownloadRow& info) {
  // This function may be called multiple times for a given test. Returning
  // false doesn't necessarily mean that the test has failed or will fail, it
  // might just mean that the test hasn't passed yet.
  if (!expected_path.empty() && info.target_path != expected_path) {
    DVLOG(20) << __FUNCTION__ << " " << info.target_path.value()
              << " != " << expected_path.value();
    return false;
  }
  if (info.url_chain.size() != 1u) {
    DVLOG(20) << __FUNCTION__ << " " << info.url_chain.size() << " != 1";
    return false;
  }
  if (info.url_chain[0] != expected_url) {
    DVLOG(20) << __FUNCTION__ << " " << info.url_chain[0].spec()
              << " != " << expected_url.spec();
    return false;
  }
  if ((num_files >= 0) && (info.received_bytes != num_files)) {
    DVLOG(20) << __FUNCTION__ << " " << num_files
              << " != " << info.received_bytes;
    return false;
  }
  if (info.state != expected_state) {
    DVLOG(20) << __FUNCTION__ << " " << info.state << " != " << expected_state;
    return false;
  }
  return true;
}

static const char kAppendedExtension[] = ".html";

// Loosely based on logic in DownloadTestObserver.
class DownloadItemCreatedObserver : public DownloadManager::Observer {
 public:
  explicit DownloadItemCreatedObserver(DownloadManager* manager)
      : manager_(manager) {
    manager->AddObserver(this);
  }

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

  ~DownloadItemCreatedObserver() override {
    if (manager_)
      manager_->RemoveObserver(this);
  }

  // Wait for the first download item created after object creation.
  // Note that this class provides no protection against the download
  // being destroyed between creation and return of WaitForNewDownloadItem();
  // the caller must guarantee that in some other fashion.
  void WaitForDownloadItem(
      std::vector<raw_ptr<DownloadItem, VectorExperimental>>* items_seen) {
    if (!manager_) {
      // The manager went away before we were asked to wait; return
      // what we have, even if it's null.
      *items_seen = items_seen_;
      return;
    }

    if (items_seen_.empty()) {
      base::RunLoop run_loop;
      quit_waiting_callback_ = run_loop.QuitClosure();
      run_loop.Run();
    }

    *items_seen = items_seen_;
    return;
  }

 private:
  // DownloadManager::Observer
  void OnDownloadCreated(DownloadManager* manager,
                         DownloadItem* item) override {
    DCHECK_EQ(manager, manager_);
    items_seen_.push_back(item);

    if (quit_waiting_callback_)
      std::move(quit_waiting_callback_).Run();
  }

  void ManagerGoingDown(DownloadManager* manager) override {
    manager_->RemoveObserver(this);
    manager_ = nullptr;
    if (quit_waiting_callback_)
      std::move(quit_waiting_callback_).Run();
  }

  base::OnceClosure quit_waiting_callback_;
  raw_ptr<DownloadManager> manager_;
  std::vector<raw_ptr<DownloadItem, VectorExperimental>> items_seen_;
};

class SavePageBrowserTest : public InProcessBrowserTest {
 public:
  SavePageBrowserTest() = default;

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

 protected:
  void SetUp() override {
    ASSERT_TRUE(embedded_test_server()->InitializeAndListen());
    content::SetupCrossSiteRedirector(embedded_test_server());
    embedded_test_server()->StartAcceptingConnections();

    ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_dir_));
    InProcessBrowserTest::SetUp();
  }

  GURL NavigateToMockURL(const std::string& prefix) {
    GURL url = embedded_test_server()->GetURL("/save_page/" + prefix + ".htm");
    EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
    return url;
  }

  // Returns full paths of destination file and directory.
  void GetDestinationPaths(const std::string& prefix,
                           base::FilePath* full_file_name,
                           base::FilePath* dir,
                           content::SavePageType save_page_type =
                               content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) {
    std::string extension =
        (save_page_type == content::SAVE_PAGE_TYPE_AS_MHTML) ? ".mht" : ".htm";
    *full_file_name = GetSaveDir().AppendASCII(prefix + extension);
    *dir = GetSaveDir().AppendASCII(prefix + "_files");
  }

  WebContents* GetCurrentTab(Browser* browser) const {
    WebContents* current_tab =
        browser->tab_strip_model()->GetActiveWebContents();
    EXPECT_TRUE(current_tab);
    return current_tab;
  }

  // Returns true if and when there was a single download created, and its url
  // is |expected_url|.
  bool VerifySavePackageExpectations(
      Browser* browser,
      const GURL& expected_url) const {
    // Generally, there should only be one download item created
    // in all of these tests.  If it's already here, grab it; if not,
    // wait for it to show up.
    std::vector<raw_ptr<DownloadItem, VectorExperimental>> items;
    DownloadManager* manager = browser->profile()->GetDownloadManager();
    manager->GetAllDownloads(&items);
    if (items.empty())
      DownloadItemCreatedObserver(manager).WaitForDownloadItem(&items);

    if (items.size() != 1) {
      ADD_FAILURE();
      return false;
    }

    return items[0]->GetOriginalUrl() == expected_url;
  }

  void SaveCurrentTab(const GURL& url,
                      content::SavePageType save_page_type,
                      const std::string& prefix_for_output_files,
                      int expected_number_of_files,
                      base::FilePath* output_dir,
                      base::FilePath* main_file_name) {
    GetDestinationPaths(prefix_for_output_files, main_file_name, output_dir,
                        save_page_type);
    DownloadPersistedObserver persisted(
        browser()->profile(),
        base::BindRepeating(&DownloadStoredProperly, url, *main_file_name,
                            expected_number_of_files,
                            history::DownloadState::COMPLETE));
    base::RunLoop run_loop;
    content::SavePackageFinishedObserver observer(
        browser()->profile()->GetDownloadManager(), run_loop.QuitClosure());
    ASSERT_TRUE(GetCurrentTab(browser())
                    ->SavePage(*main_file_name, *output_dir, save_page_type));

    run_loop.Run();
    ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
    persisted.WaitForPersisted();
  }

  // Note on synchronization:
  //
  // For each Save Page As operation, we create a corresponding shell
  // DownloadItem to display progress to the user.  That DownloadItem goes
  // through its own state transitions, including being persisted out to the
  // history database, and the download shelf is not shown until after the
  // persistence occurs.  Save Package completion (and marking the DownloadItem
  // as completed) occurs asynchronously from persistence.  Thus if we want to
  // examine either UI state or DB state, we need to wait until both the save
  // package operation is complete and the relevant download item has been
  // persisted.

  DownloadManager* GetDownloadManager() const {
    auto* download_manager = browser()->profile()->GetDownloadManager();
    EXPECT_TRUE(download_manager);
    return download_manager;
  }

  // Returns full path to a file in chrome/test/data/save_page directory.
  base::FilePath GetTestDirFile(const std::string& file_name) {
    const base::FilePath::CharType kTestDir[] = FILE_PATH_LITERAL("save_page");
    return test_dir_.Append(base::FilePath(kTestDir)).AppendASCII(file_name);
  }

  base::FilePath GetSaveDir() {
    return DownloadPrefs(browser()->profile()).DownloadPath();
  }

  // Path to directory containing test data.
  base::FilePath test_dir_;
};

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLOnly) {
  GURL url = NavigateToMockURL("a");

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1, &dir,
                 &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
  EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("a.htm"), full_file_name));
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveFileURL) {
  GURL url = net::FilePathToFileURL(GetTestDirFile("text.txt"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "test", 1, &dir,
                 &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
  EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("text.txt"), full_file_name));
#if BUILDFLAG(IS_WIN)
  // Local file URL will not be quarantined.
  EXPECT_FALSE(quarantine::IsFileQuarantined(full_file_name, GURL(), GURL()));
#endif
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
                       SaveHTMLOnly_CrossOriginReadPolicy) {
  GURL url = embedded_test_server()->GetURL(
      "/downloads/cross-origin-resource-policy-resource.txt");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1, &dir,
                 &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));

  const base::FilePath::CharType kTestDir[] = FILE_PATH_LITERAL("downloads");
  const base::FilePath kTestFile =
      test_dir_.Append(base::FilePath(kTestDir))
          .AppendASCII("cross-origin-resource-policy-resource.txt");
  EXPECT_TRUE(base::ContentsEqual(kTestFile, full_file_name));
}

// TODO(crbug.com/40805571): Flaky on mac arm64.
#if BUILDFLAG(IS_MAC) && defined(ARCH_CPU_ARM64)
#define MAYBE_SaveHTMLOnlyCancel DISABLED_SaveHTMLOnlyCancel
#else
#define MAYBE_SaveHTMLOnlyCancel SaveHTMLOnlyCancel
#endif
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnlyCancel) {
  GURL url = NavigateToMockURL("a");
  DownloadManager* manager = GetDownloadManager();
  std::vector<raw_ptr<DownloadItem, VectorExperimental>> downloads;
  manager->GetAllDownloads(&downloads);
  ASSERT_EQ(0u, downloads.size());

  base::FilePath full_file_name, dir;
  GetDestinationPaths("a", &full_file_name, &dir);
  DownloadItemCreatedObserver creation_observer(manager);
  DownloadPersistedObserver persisted(
      browser()->profile(),
      base::BindRepeating(&DownloadStoredProperly, url, full_file_name, -1,
                          history::DownloadState::CANCELLED));
  // -1 to disable number of files check; we don't update after cancel, and
  // we don't know when the single file completed in relationship to
  // the cancel.

  ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
                                        content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
  std::vector<raw_ptr<DownloadItem, VectorExperimental>> items;
  creation_observer.WaitForDownloadItem(&items);
  ASSERT_EQ(1UL, items.size());
  ASSERT_EQ(url.spec(), items[0]->GetOriginalUrl().spec());
  items[0]->Cancel(true);
  // TODO(rdsmith): Fix DII::Cancel() to actually cancel the save package.
  // Currently it's ignored.

  persisted.WaitForPersisted();

  // TODO(benjhayden): Figure out how to safely wait for SavePackage's finished
  // notification, then expect the contents of the downloaded file.
}

// Test that saving an HTML file with long (i.e. > 65536 bytes) text content
// does not crash the browser despite the renderer requiring more than one
// "pass" to serialize the HTML content (see crash from crbug.com/1085721).
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLWithLongTextContent) {
  GURL url =
      embedded_test_server()->GetURL("/save_page/long-text-content.html");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
                 "long-text-content", 1, &dir, &full_file_name);

  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));

  // Besides checking that the renderer didn't crash, test also that the HTML
  // content saved is the expected one (i.e. the whole HTML, no truncation).
  EXPECT_EQ(ReadFileAndCollapseWhitespace(full_file_name),
            PrependMotw(ReadFileAndCollapseWhitespace(
                            GetTestDirFile("long-text-content.saved.html")),
                        url));
}

class DelayingDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
 public:
  explicit DelayingDownloadManagerDelegate(Profile* profile)
    : ChromeDownloadManagerDelegate(profile) {
  }

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

  ~DelayingDownloadManagerDelegate() override = default;

  bool ShouldCompleteDownload(
      download::DownloadItem* item,
      base::OnceClosure user_complete_callback) override {
    return false;
  }
};

// Disabled on multiple platforms due to flakiness. crbug.com/580766
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DISABLED_SaveHTMLOnlyTabDestroy) {
  GURL url = NavigateToMockURL("a");
  auto delaying_delegate =
      std::make_unique<DelayingDownloadManagerDelegate>(browser()->profile());
  delaying_delegate->GetDownloadIdReceiverCallback().Run(
      download::DownloadItem::kInvalidId + 1);
  DownloadCoreServiceFactory::GetForBrowserContext(browser()->profile())
      ->SetDownloadManagerDelegateForTesting(std::move(delaying_delegate));
  DownloadManager* manager = GetDownloadManager();
  std::vector<raw_ptr<DownloadItem, VectorExperimental>> downloads;
  manager->GetAllDownloads(&downloads);
  ASSERT_EQ(0u, downloads.size());

  base::FilePath full_file_name, dir;
  GetDestinationPaths("a", &full_file_name, &dir);
  DownloadItemCreatedObserver creation_observer(manager);
  ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
                                        content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
  std::vector<raw_ptr<DownloadItem, VectorExperimental>> items;
  creation_observer.WaitForDownloadItem(&items);
  ASSERT_EQ(1u, items.size());

  // Close the tab; does this cancel the download?
  GetCurrentTab(browser())->Close();
  EXPECT_EQ(DownloadItem::CANCELLED, items[0]->GetState());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_FALSE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveViewSourceHTMLOnly) {
  // TODO(lukasza): https://crbug.com/971811: Disallow renderer crashes once the
  // bug is fixed.
  content::ScopedAllowRendererCrashes scoped_allow_renderer_crashes;

  GURL mock_url = embedded_test_server()->GetURL("/save_page/a.htm");
  GURL view_source_url =
      GURL(content::kViewSourceScheme + std::string(":") + mock_url.spec());
  GURL actual_page_url = embedded_test_server()->GetURL("/save_page/a.htm");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), view_source_url));

  base::FilePath full_file_name, dir;
  SaveCurrentTab(actual_page_url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1,
                 &dir, &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
  EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("a.htm"), full_file_name));
}

// Regression test for https://crbug.com/974312 (saving a page that was served
// with `Cross-Origin-Resource-Policy: same-origin` http response header).
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveCompleteHTML) {
  GURL url = NavigateToMockURL("b");

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML, "b", 3, &dir,
                 &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_TRUE(base::PathExists(dir));

  EXPECT_EQ(
      ReadFileAndCollapseWhitespace(full_file_name),
      PrependMotw(ReadFileAndCollapseWhitespace(GetTestDirFile("b.saved1.htm")),
                  url));
  EXPECT_TRUE(
      base::ContentsEqual(GetTestDirFile("1.png"), dir.AppendASCII("1.png")));
  EXPECT_EQ(ReadFileAndCollapseWhitespace(dir.AppendASCII("1.css")),
            ReadFileAndCollapseWhitespace(GetTestDirFile("1.css")));
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
                       SaveDuringInitialNavigationIncognito) {
  // Open an Incognito window.
  Browser* incognito = CreateIncognitoBrowser();  // Waits.
  ASSERT_TRUE(incognito);

  // Create a download item creation waiter on that window.
  DownloadItemCreatedObserver creation_observer(
      incognito->profile()->GetDownloadManager());

  // Navigate, unblocking with new tab.
  GURL url = embedded_test_server()->GetURL("/save_page/b.htm");
  NavigateToURLWithDisposition(incognito, url,
                               WindowOpenDisposition::NEW_FOREGROUND_TAB,
                               ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);

  // Save the page before completion.
  base::FilePath full_file_name, dir;
  GetDestinationPaths("b", &full_file_name, &dir);

  base::RunLoop run_loop;
  content::SavePackageFinishedObserver observer(
      incognito->profile()->GetDownloadManager(), run_loop.QuitClosure());
  ASSERT_TRUE(GetCurrentTab(incognito)->SavePage(
      full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));

  run_loop.Run();
  ASSERT_TRUE(VerifySavePackageExpectations(incognito, url));

  // We can't check more than this because SavePackage is racing with
  // the page load.  If the page load won the race, then SavePackage
  // might have completed. If the page load lost the race, then
  // SavePackage will cancel because there aren't any resources to
  // save.
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, NoSave) {
  ASSERT_TRUE(
      ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL)));
  EXPECT_FALSE(chrome::CanSavePage(browser()));
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, FileNameFromPageTitle) {
  GURL url = NavigateToMockURL("b");

  base::FilePath full_file_name = GetSaveDir().AppendASCII(
      std::string("Test page for saving page feature") + kAppendedExtension);
  base::FilePath dir =
      GetSaveDir().AppendASCII("Test page for saving page feature_files");
  DownloadPersistedObserver persisted(
      browser()->profile(),
      base::BindRepeating(&DownloadStoredProperly, url, full_file_name, 3,
                          history::DownloadState::COMPLETE));
  base::RunLoop run_loop;
  content::SavePackageFinishedObserver observer(
      browser()->profile()->GetDownloadManager(), run_loop.QuitClosure());
  ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
      full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));

  run_loop.Run();
  ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
  persisted.WaitForPersisted();

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_TRUE(base::PathExists(dir));

  EXPECT_EQ(
      ReadFileAndCollapseWhitespace(full_file_name),
      PrependMotw(ReadFileAndCollapseWhitespace(GetTestDirFile("b.saved2.htm")),
                  url));
  EXPECT_TRUE(
      base::ContentsEqual(GetTestDirFile("1.png"), dir.AppendASCII("1.png")));
  EXPECT_EQ(ReadFileAndCollapseWhitespace(dir.AppendASCII("1.css")),
            ReadFileAndCollapseWhitespace(GetTestDirFile("1.css")));
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, RemoveFromList) {
  GURL url = NavigateToMockURL("a");

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1, &dir,
                 &full_file_name);
  ASSERT_FALSE(HasFailure());

  DownloadManager* manager = GetDownloadManager();
  std::vector<raw_ptr<DownloadItem, VectorExperimental>> downloads;
  manager->GetAllDownloads(&downloads);
  ASSERT_EQ(1UL, downloads.size());

  DownloadRemovedObserver removed(browser()->profile(), downloads[0]->GetId());
  downloads[0]->Remove();
  removed.WaitForRemoved();

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
  EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("a.htm"), full_file_name));
}

// This tests that a webpage with the title "test.exe" is saved as
// "test.exe.htm".
// We probably don't care to handle this on Linux or Mac.
#if BUILDFLAG(IS_WIN)
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, CleanFilenameFromPageTitle) {
  base::FilePath download_dir =
      DownloadPrefs::FromDownloadManager(GetDownloadManager())->
          DownloadPath();
  base::FilePath full_file_name =
      download_dir.AppendASCII(std::string("test.exe") + kAppendedExtension);
  base::FilePath dir = download_dir.AppendASCII("test.exe_files");

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_FALSE(base::PathExists(full_file_name));
  GURL url = embedded_test_server()->GetURL("/save_page/c.htm");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  SavePackageFilePicker::SetShouldPromptUser(false);
  base::RunLoop run_loop;
  content::SavePackageFinishedObserver observer(
      browser()->profile()->GetDownloadManager(), run_loop.QuitClosure());
  chrome::SavePage(browser());
  run_loop.Run();

  EXPECT_TRUE(base::PathExists(full_file_name));

  EXPECT_TRUE(base::DieFileDie(full_file_name, false));
  EXPECT_TRUE(base::DieFileDie(dir, true));
}
#endif

// Tests that the SecurityLevel histograms are logged for save page downloads.
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SecurityLevelHistogram) {
  base::HistogramTester histogram_tester;
  GURL url = NavigateToMockURL("a");
  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1, &dir,
                 &full_file_name);
  histogram_tester.ExpectUniqueSample("Security.SecurityLevel.DownloadStarted",
                                      security_state::NONE, 1);
}

// Tests that a page can be saved as MHTML.
// Flaky on Windows, crbug.com/1048100
#if BUILDFLAG(IS_WIN)
#define MAYBE_SavePageAsMHTML DISABLED_SavePageAsMHTML
#else
#define MAYBE_SavePageAsMHTML SavePageAsMHTML
#endif
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SavePageAsMHTML) {
  static const int64_t kFileSizeMin = 2758;
  GURL url = NavigateToMockURL("b");
  base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
      GetDownloadManager())->DownloadPath();
  base::FilePath full_file_name =
      download_dir.AppendASCII("Test page for saving page feature.mhtml");

  SavePackageFilePicker::SetShouldPromptUser(true);
  DownloadPersistedObserver persisted(
      browser()->profile(),
      base::BindRepeating(&DownloadStoredProperly, url, full_file_name, -1,
                          history::DownloadState::COMPLETE));

  FakeSelectFileDialog::Factory* select_file_dialog_factory =
      FakeSelectFileDialog::RegisterFactory();
  // Save page and run until the fake select file dialog opens.
  {
    base::RunLoop run_loop;
    select_file_dialog_factory->SetOpenCallback(run_loop.QuitClosure());
    chrome::SavePage(browser());
    run_loop.Run();
  }

// On ChromeOS, the default should be MHTML.
#if BUILDFLAG(IS_CHROMEOS)
  ASSERT_EQ("mhtml",
            select_file_dialog_factory->GetLastDialog()->default_extension());
#else
  ASSERT_EQ("html",
            select_file_dialog_factory->GetLastDialog()->default_extension());
#endif

  // Save the file as MHTML. Run until save completes.
  base::RunLoop run_loop;
  content::SavePackageFinishedObserver observer(
      browser()->profile()->GetDownloadManager(), run_loop.QuitClosure());
  ASSERT_TRUE(select_file_dialog_factory->GetLastDialog()->CallFileSelected(
      full_file_name, "mhtml"));
  run_loop.Run();

  ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
  persisted.WaitForPersisted();

  base::ScopedAllowBlockingForTesting allow_blocking;
  std::optional<int64_t> actual_file_size = base::GetFileSize(full_file_name);
  ASSERT_TRUE(actual_file_size.has_value());
  EXPECT_LE(kFileSizeMin, actual_file_size.value());

  std::string contents;
  EXPECT_TRUE(base::ReadFileToString(full_file_name, &contents));
  // Test for a CSS encoded character.  This used to use HTML encoding.
  EXPECT_THAT(contents, HasSubstr("content: \"\\e003 \\e004 b\""));
}

// Tests that if we default our file picker to MHTML due to user preference we
// update the suggested file name to end with .mhtml.
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
                       SavePageAsMHTMLByPrefUpdatesExtension) {
  SavePackageFilePicker::SetShouldPromptUser(false);
  DownloadPrefs* download_prefs =
      DownloadPrefs::FromDownloadManager(GetDownloadManager());
  base::FilePath download_dir = download_prefs->DownloadPath();
  base::FilePath full_file_name = download_dir.AppendASCII("test_page");
  download_prefs->SetSaveFileType(content::SAVE_PAGE_TYPE_AS_MHTML);

  content::SavePackagePathPickedParams received_params;
  content::SavePackagePathPickedCallback callback = base::BindOnce(
      [](content::SavePackagePathPickedParams* received_params,
         content::SavePackagePathPickedParams params,
         content::SavePackageDownloadCreatedCallback cb) {
        *received_params = params;
      },
      &received_params);

  // Deletes itself.
  new SavePackageFilePicker(
      /*web_contents=*/GetCurrentTab(browser()),
      /*suggested_path=*/full_file_name,
      /*default_extension=*/FILE_PATH_LITERAL(".html"),
      /*can_save_as_complete=*/true,
      /*download_prefs=*/download_prefs,
      /*callback=*/std::move(callback));

  EXPECT_TRUE(
      received_params.file_path.MatchesExtension(FILE_PATH_LITERAL(".mhtml")));
  EXPECT_EQ(received_params.save_type, content::SAVE_PAGE_TYPE_AS_MHTML);
}

// Flaky on Windows: https://crbug.com/1247404.
#if BUILDFLAG(IS_WIN)
#define MAYBE_SavePageBrowserTest_NonMHTML DISABLED_SavePageBrowserTest_NonMHTML
#else
#define MAYBE_SavePageBrowserTest_NonMHTML SavePageBrowserTest_NonMHTML
#endif
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
                       MAYBE_SavePageBrowserTest_NonMHTML) {
  SavePackageFilePicker::SetShouldPromptUser(false);
  GURL url("data:text/plain,foo");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  base::RunLoop run_loop;
  content::SavePackageFinishedObserver observer(
      browser()->profile()->GetDownloadManager(), run_loop.QuitClosure());
  chrome::SavePage(browser());
  run_loop.Run();
  base::FilePath download_dir = DownloadPrefs::FromDownloadManager(
      GetDownloadManager())->DownloadPath();
  base::FilePath filename = download_dir.AppendASCII("dataurl.txt");
  base::ScopedAllowBlockingForTesting allow_blocking;
  ASSERT_TRUE(base::PathExists(filename));
  std::string contents;
  EXPECT_TRUE(base::ReadFileToString(filename, &contents));
  EXPECT_EQ("foo", contents);
}

// If a save-page-complete operation results in creating subresources that would
// otherwise be considered dangerous, such files should get a .download
// extension appended so that they won't be accidentally executed by the user.
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, DangerousSubresources) {
  GURL url =
      embedded_test_server()->GetURL("/save_page/dubious-subresources.html");

  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
                 "dubious-subresources", 2, &dir, &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("not-a-crx.crx.download")));
}

// Test that we don't crash when the page contains an iframe that
// was handled as a download (http://crbug.com/42212).
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveDownloadableIFrame) {
  GURL url =
      embedded_test_server()->GetURL("/downloads/iframe-src-is-a-download.htm");

  // Wait for and then dismiss the non-save-page-as-related download item
  // (the one associated with downloading of "thisdayinhistory.xls" file).
  {
    GURL download_url =
        embedded_test_server()->GetURL("/downloads/thisdayinhistory.xls");
    DownloadPersistedObserver persisted(
        browser()->profile(),
        base::BindRepeating(&DownloadStoredProperly, download_url,
                            base::FilePath(), -1,
                            history::DownloadState::COMPLETE));

    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

    ASSERT_TRUE(VerifySavePackageExpectations(browser(), download_url));
    persisted.WaitForPersisted();
    std::vector<raw_ptr<download::DownloadItem, VectorExperimental>> downloads;
    GetDownloadManager()->GetAllDownloads(&downloads);
    for (download::DownloadItem* download : downloads) {
      download->Remove();
    }
  }

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
                 "iframe-src-is-a-download", 3, &dir, &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("thisdayinhistory.html")));
  EXPECT_TRUE(base::PathExists(dir.AppendASCII("no-such-file.html")));
}

// Test that file: URI won't be saved when referred to from an HTTP page.
// See also https://crbug.com/616429.
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveUnauthorizedResource) {
  GURL url = NavigateToMockURL("unauthorized-access");

  // Create a test file (that the web page should not have access to).
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temp_dir2;
  ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
  base::FilePath file_path =
      temp_dir2.GetPath().Append(FILE_PATH_LITERAL("should-not-save.jpg"));
  std::string file_content("fake-jpg");
  ASSERT_TRUE(base::WriteFile(file_path, file_content));

  // Refer to the test file from the test page.
  GURL file_url = net::FilePathToFileURL(file_path);
  ASSERT_TRUE(ExecJs(
      browser()->tab_strip_model()->GetWebContentsAt(0),
      base::StringPrintf("document.getElementById('resource1').src = '%s';",
                         file_url.spec().data())));

  // Save the current page.
  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
                 "unauthorized-access", 2, &dir, &full_file_name);

  // We should not save resource that the web page didn't have access to.
  // (because executing a resource request can have side effects - for example
  // after https://crbug.com/590714 a website from the internet should not be
  // able to issue a resource request to an intranet website and trigger
  // server-side actions in the internet;  this test uses a file: URI as a
  // canary for detecting whether a website can access restricted resources).
  EXPECT_FALSE(base::PathExists(dir.AppendASCII("should-not-save.jpg")));
}

#if BUILDFLAG(IS_WIN)
// Save a file and confirm that the file is correctly quarantined.
IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveURLQuarantine) {
  GURL url = embedded_test_server()->GetURL("/save_page/text.txt");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "test", 1, &dir,
                 &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
  EXPECT_TRUE(base::ContentsEqual(GetTestDirFile("text.txt"), full_file_name));
  EXPECT_TRUE(quarantine::IsFileQuarantined(full_file_name, url, GURL()));
}
#endif

// Test suite that allows testing --site-per-process against cross-site frames.
// See http://dev.chromium.org/developers/design-documents/site-isolation.
class SavePageSitePerProcessBrowserTest : public SavePageBrowserTest {
 public:
  SavePageSitePerProcessBrowserTest() = default;

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

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    SavePageBrowserTest::SetUpCommandLine(command_line);

    // Append --site-per-process flag.
    content::IsolateAllSitesForTesting(command_line);
  }

  void SetUpOnMainThread() override {
    SavePageBrowserTest::SetUpOnMainThread();

    // Used by the BrokenImage test which depends on *.no.such.host not
    // resolving to 127.0.0.1
    host_resolver()->AddRule("no.such.host", "128.0.0.1");
    host_resolver()->AddRule("*", "127.0.0.1");
  }
};

// Test for crbug.com/526786.
IN_PROC_BROWSER_TEST_F(SavePageSitePerProcessBrowserTest, SaveAsCompleteHtml) {
  GURL url(
      embedded_test_server()->GetURL("a.com", "/save_page/frames-xsite.htm"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
                 "frames-xsite-complete-html", 5, &dir, &full_file_name);
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::DirectoryExists(dir));
  base::FilePath expected_files[] = {
      full_file_name,
      dir.AppendASCII("a.html"),  // From iframes.htm
      dir.AppendASCII("b.html"),  // From iframes.htm
      dir.AppendASCII("1.css"),   // From b.htm
      dir.AppendASCII("1.png"),   // Deduplicated from iframes.htm and b.htm.
  };
  for (auto file_path : expected_files) {
    EXPECT_TRUE(base::PathExists(file_path)) << "Does " << file_path.value()
                                             << " exist?";
    std::optional<int64_t> actual_file_size = base::GetFileSize(file_path);
    ASSERT_TRUE(actual_file_size.has_value());
    EXPECT_NE(0, actual_file_size.value())
        << "Is " << file_path.value() << " non-empty?";
  }

  // Verify that local links got correctly replaced with local paths
  // (most importantly for iframe elements, which are only exercised
  // by this particular test).
  std::string main_contents;
  ASSERT_TRUE(base::ReadFileToString(full_file_name, &main_contents));
  EXPECT_THAT(
      main_contents,
      HasSubstr("<iframe "
                "src=\"./frames-xsite-complete-html_files/a.html\"></iframe>"));
  EXPECT_THAT(
      main_contents,
      HasSubstr("<iframe "
                "src=\"./frames-xsite-complete-html_files/b.html\"></iframe>"));
  EXPECT_THAT(
      main_contents,
      HasSubstr("<img src=\"./frames-xsite-complete-html_files/1.png\">"));

  // Verification of html contents.
  EXPECT_THAT(
      main_contents,
      HasSubstr("frames-xsite.htm: 896fd88d-a77a-4f46-afd8-24db7d5af9c2"));
  std::string a_contents;
  ASSERT_TRUE(base::ReadFileToString(dir.AppendASCII("a.html"), &a_contents));
  EXPECT_THAT(a_contents,
              HasSubstr("a.htm: 1b8aae2b-e164-462f-bd5b-98aa366205f2"));
  std::string b_contents;
  ASSERT_TRUE(base::ReadFileToString(dir.AppendASCII("b.html"), &b_contents));
  EXPECT_THAT(b_contents,
              HasSubstr("b.htm: 3a35f7fa-96a9-4487-9f18-4470263907fa"));
}

// Test for crbug.com/538766.
// Disabled on Mac due to excessive flakiness. https://crbug.com/1271741
#if BUILDFLAG(IS_MAC)
#define MAYBE_SaveAsMHTML DISABLED_SaveAsMHTML
#else
#define MAYBE_SaveAsMHTML SaveAsMHTML
#endif
IN_PROC_BROWSER_TEST_F(SavePageSitePerProcessBrowserTest,
                       MAYBE_SaveAsMHTML) {
  GURL url(
      embedded_test_server()->GetURL("a.com", "/save_page/frames-xsite.htm"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_MHTML, "frames-xsite-mhtml",
                 -1, &dir, &full_file_name);
  ASSERT_FALSE(HasFailure());

  std::string mhtml;
  {
    base::ScopedAllowBlockingForTesting allow_blocking;
    ASSERT_TRUE(base::ReadFileToString(full_file_name, &mhtml));
  }

  // Verify content of main frame, subframes and some savable resources.
  EXPECT_THAT(
      mhtml,
      HasSubstr("frames-xsite.htm: 896fd88d-a77a-4f46-afd8-24db7d5af9c2"));
  EXPECT_THAT(mhtml, HasSubstr("a.htm: 1b8aae2b-e164-462f-bd5b-98aa366205f2"));
  EXPECT_THAT(mhtml, HasSubstr("b.htm: 3a35f7fa-96a9-4487-9f18-4470263907fa"));
  EXPECT_THAT(mhtml, HasSubstr("font-size: 20px;"))
      << "Verifying if content from 1.css is present";

  // Verify presence of URLs associated with main frame, subframes and some
  // savable resources.
  // (note that these are single-line regexes).
  EXPECT_THAT(mhtml,
              ContainsRegex("Content-Location.*/save_page/frames-xsite.htm"));
  EXPECT_THAT(mhtml, ContainsRegex("Content-Location.*/save_page/a.htm"));
  EXPECT_THAT(mhtml, ContainsRegex("Content-Location.*/save_page/b.htm"));
  EXPECT_THAT(mhtml, ContainsRegex("Content-Location.*/save_page/1.css"));
  EXPECT_THAT(mhtml, ContainsRegex("Content-Location.*/save_page/1.png"));

  // Verify that 1.png appears in the output only once (despite being referred
  // to twice - from iframes.htm and from b.htm).
  int count = 0;
  size_t pos = 0;
  for (;;) {
    pos = mhtml.find("Content-Type: image/png", pos);
    if (pos == std::string::npos)
      break;
    count++;
    pos++;
  }
  EXPECT_EQ(1, count) << "Verify number of image/png parts in the mhtml output";
}

// Test for crbug.com/541342 - handling of dead renderer processes.
IN_PROC_BROWSER_TEST_F(SavePageSitePerProcessBrowserTest,
                       CompleteHtmlWhenRendererIsDead) {
  GURL url(
      embedded_test_server()->GetURL("a.com", "/save_page/frames-xsite.htm"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  // Kill one of renderer processes (this is the essence of this test).
  WebContents* web_contents = GetCurrentTab(browser());
  bool did_kill_a_process = false;
  web_contents->GetPrimaryMainFrame()
      ->ForEachRenderFrameHostWithAction(
          [web_contents, &did_kill_a_process](RenderFrameHost* frame) {
            if (frame->GetLastCommittedURL().host() == "bar.com") {
              RenderProcessHost* process_to_kill = frame->GetProcess();
              EXPECT_NE(web_contents->GetPrimaryMainFrame()
                            ->GetProcess()
                            ->GetDeprecatedID(),
                        process_to_kill->GetDeprecatedID())
                  << "a.com and bar.com should be in different processes.";

              EXPECT_TRUE(process_to_kill->FastShutdownIfPossible());
              EXPECT_FALSE(process_to_kill->IsInitializedAndNotDead());
              did_kill_a_process = true;
              return content::RenderFrameHost::FrameIterationAction::kStop;
            }
            return content::RenderFrameHost::FrameIterationAction::kContinue;
          });
  EXPECT_TRUE(did_kill_a_process);

  // Main verification is that we don't hang and time out when saving.
  base::FilePath full_file_name, dir;
  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML,
                 "frames-xsite-complete-html", 5, &dir, &full_file_name);
  ASSERT_FALSE(HasFailure());
  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::DirectoryExists(dir));
  EXPECT_TRUE(base::PathExists(full_file_name));
}

// Test suite that verifies that the frame tree "looks" the same before
// and after a save-page-as.
class SavePageOriginalVsSavedComparisonTest
    : public SavePageSitePerProcessBrowserTest,
      public ::testing::WithParamInterface<content::SavePageType> {
 protected:
  void TestOriginalVsSavedPage(
      content::SavePageType save_page_type,
      const GURL& url,
      size_t expected_number_of_frames_in_original_page,
      size_t expected_number_of_frames_in_mhtml_page,
      const std::vector<std::string>& expected_substrings) {
    // Navigate to the test page and verify if test expectations
    // are met (this is mostly a sanity check - a failure to meet
    // expectations would probably mean that there is a test bug
    // (i.e. that we got called with wrong expected_foo argument).
    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
    DLOG(INFO) << "Verifying test expectations for original page... : "
               << GetCurrentTab(browser())->GetLastCommittedURL();
    AssertExpectationsAboutCurrentTab(
        expected_number_of_frames_in_original_page, expected_substrings,
        save_page_type);

    // Save the page.
    base::FilePath full_file_name, dir;
    SaveCurrentTab(url, save_page_type, "save_result", -1, &dir,
                   &full_file_name);
    ASSERT_FALSE(HasFailure());

    // Stop the test server (to make sure the locally saved page
    // is self-contained / won't try to open original resources).
    ASSERT_TRUE(embedded_test_server()->ShutdownAndWaitUntilComplete());

    // Open the saved page and verify if test expectations are
    // met (i.e. if the same expectations are met for "after"
    // [saved version of the page] as for the "before"
    // [the original version of the page].
    ASSERT_TRUE(ui_test_utils::NavigateToURL(
        browser(), GURL(net::FilePathToFileURL(full_file_name))));
    DLOG(INFO) << "Verifying test expectations for saved page... : "
               << GetCurrentTab(browser())->GetLastCommittedURL();
    // Hidden elements, i.e., hidden frames, will be removed only from MHTML
    // page. They're still kept in other types of serialization, like saving
    // as a complete html page.
    size_t expected_number_of_frames_in_saved_page =
        (save_page_type == content::SAVE_PAGE_TYPE_AS_MHTML)
            ? expected_number_of_frames_in_mhtml_page
            : expected_number_of_frames_in_original_page;
    AssertExpectationsAboutCurrentTab(expected_number_of_frames_in_saved_page,
                                      expected_substrings, save_page_type);

    if (GetParam() == content::SAVE_PAGE_TYPE_AS_MHTML) {
      std::set<url::Origin> origins;
      GetCurrentTab(browser())->GetPrimaryMainFrame()->ForEachRenderFrameHost(
          [&origins](content::RenderFrameHost* host) {
            CheckFrameForMHTML(host, origins);
          });
      EXPECT_EQ(expected_number_of_frames_in_saved_page, origins.size())
          << "All origins should be unique";
    }

    // Check that we're able to navigate away and come back, as well.
    // See https://crbug.com/948246.
    ASSERT_TRUE(
        ui_test_utils::NavigateToURL(browser(), GURL("data:text/html,foo")));
    chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
    EXPECT_TRUE(content::WaitForLoadStop(GetCurrentTab(browser())));
    DLOG(INFO) << "Verifying test expectations after history navigation...";
    AssertExpectationsAboutCurrentTab(expected_number_of_frames_in_saved_page,
                                      expected_substrings, save_page_type);
  }

  // Helper method to deduplicate some code across 2 tests.
  void RunObjectElementsTest(GURL url) {
    content::SavePageType save_page_type = GetParam();

    // The `kExpectedNumberOfFrames` comes from:
    // - main frame (frames-objects.htm)
    // - object with frame-nested.htm + 2 subframes (frames-nested2.htm + b.htm)
    // - iframe with a.htm
    // - object with svg.svg
    // - object with text.txt
    // - object with pdf.pdf is responsible for presence of 2 extra frames
    //   (about:blank + one frame for the actual pdf.pdf).  These frames are an
    //   implementation detail and are not web-exposed (e.g. via window.frames).
    static constexpr size_t kExpectedNumberOfFrames = 9;

    std::vector<std::string> expected_substrings = {
        "frames-objects.htm: 8da13db4-a512-4d9b-b1c5-dc1c134234b9",
        "a.htm: 1b8aae2b-e164-462f-bd5b-98aa366205f2",
        "b.htm: 3a35f7fa-96a9-4487-9f18-4470263907fa",
        "frames-nested.htm: 4388232f-8d45-4d2e-9807-721b381be153",
        "frames-nested2.htm: 6d23dc47-f283-4977-96ec-66bcf72301a4",
        "text-object.txt: ae52dd09-9746-4b7e-86a6-6ada5e2680c2",
        "svg: 0875fd06-131d-4708-95e1-861853c6b8dc",

        // TODO(lukasza): Consider also verifying presence of "PDF test file"
        // from <object data="pdf.pdf">.  This requires ensuring that the PDF is
        // loaded before continuing with the test.
    };

    // TODO(lukasza): crbug.com/553478: Enable <object> testing of MHTML.
    if (save_page_type == content::SAVE_PAGE_TYPE_AS_MHTML)
      return;

    TestOriginalVsSavedPage(save_page_type, url, kExpectedNumberOfFrames,
                            kExpectedNumberOfFrames, expected_substrings);
  }

 private:
  void AssertExpectationsAboutCurrentTab(
      size_t expected_number_of_frames,
      const std::vector<std::string>& expected_substrings,
      content::SavePageType save_page_type) {
    size_t actual_number_of_frames =
        CollectAllRenderFrameHosts(GetCurrentTab(browser())->GetPrimaryPage())
            .size();
    EXPECT_EQ(expected_number_of_frames, actual_number_of_frames);

    for (const auto& expected_substring : expected_substrings) {
      int actual_number_of_matches = ui_test_utils::FindInPage(
          GetCurrentTab(browser()), base::UTF8ToUTF16(expected_substring),
          true,   // |forward|
          false,  // |case_sensitive|
          nullptr, nullptr);

      EXPECT_EQ(1, actual_number_of_matches)
          << "Verifying that \"" << expected_substring << "\" appears "
          << "exactly once in the text of web contents";

      // TODO(lukasza): https://crbug.com/1070597 and https://crbug.com/1070886:
      // Remove the extra test assertions below (and maybe also the
      // |save_page_type| parameter) after we get a better understanding of the
      // root cause of test flakiness.
      if (expected_substring == "a.htm: 1b8aae2b-e164-462f-bd5b-98aa366205f2" &&
          save_page_type == content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML) {
        DLOG(INFO) << "Verifying that a.htm frame has fully loaded...";
        std::vector<std::string> frame_names;
        GetCurrentTab(browser())->GetPrimaryMainFrame()->ForEachRenderFrameHost(
            [&frame_names](content::RenderFrameHost* frame) {
              frame_names.push_back(frame->GetFrameName());
            });

        EXPECT_THAT(frame_names, testing::Contains("Frame name of a.htm"));
      }
    }

    std::string forbidden_substrings[] = {
        "head",  // Html markup should not be visible.
        "err",   // "err" is a prefix of error messages + is strategically
                 // included in some tests in contents that should not render
                 // (i.e. inside of an object element and/or inside of a frame
                 // that should be hidden).
    };
    for (const auto& forbidden_substring : forbidden_substrings) {
      int actual_number_of_matches = ui_test_utils::FindInPage(
          GetCurrentTab(browser()), base::UTF8ToUTF16(forbidden_substring),
          true,   // |forward|
          false,  // |case_sensitive|
          nullptr, nullptr);
      EXPECT_EQ(0, actual_number_of_matches)
          << "Verifying that \"" << forbidden_substring << "\" doesn't "
          << "appear in the text of web contents";
    }
  }

  static void CheckFrameForMHTML(content::RenderFrameHost* host,
                                 std::set<url::Origin>& origins) {
    // See RFC n°2557, section-8.3: "Use of the Content-ID header and CID URLs".
    const char kContentIdScheme[] = "cid";
    origins.insert(host->GetLastCommittedOrigin());
    EXPECT_TRUE(host->GetLastCommittedOrigin().opaque());
    if (!host->GetParent())
      EXPECT_TRUE(host->GetLastCommittedURL().SchemeIsFile());
    else
      EXPECT_TRUE(host->GetLastCommittedURL().SchemeIs(kContentIdScheme));
  }
};

// Test coverage for:
// - crbug.com/526786: OOPIFs support for CompleteHtml
// - crbug.com/538766: OOPIFs support for MHTML
// - crbug.com/539936: Subframe gets redirected.
// Test compares original-vs-saved for a page with cross-site frames
// (subframes get redirected to a different domain - see frames-xsite.htm).
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest, CrossSite) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "frames-xsite.htm: 896fd88d-a77a-4f46-afd8-24db7d5af9c2",
      "a.htm: 1b8aae2b-e164-462f-bd5b-98aa366205f2",
      "b.htm: 3a35f7fa-96a9-4487-9f18-4470263907fa",
  };

  GURL url(
      embedded_test_server()->GetURL("a.com", "/save_page/frames-xsite.htm"));

  TestOriginalVsSavedPage(save_page_type, url, 3, 3, expected_substrings);
}

// Test compares original-vs-saved for a page with <object> elements.
// (see crbug.com/553478).
// crbug.com/1070886: disabled because of flakiness.
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest,
                       DISABLED_ObjectElementsViaHttp) {
  GURL url(
      embedded_test_server()->GetURL("a.com", "/save_page/frames-objects.htm"));

  RunObjectElementsTest(url);
}

// Tests that saving a page from file: URI works.
// TODO(lukasza): https://crbug.com/964364: Re-enable the test.
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest,
                       DISABLED_ObjectElementsViaFile) {
  base::FilePath test_data_dir;
  ASSERT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir));
  GURL url(net::FilePathToFileURL(
      test_data_dir.Append(FILE_PATH_LITERAL("save_page/frames-objects.htm"))));
  EXPECT_TRUE(url.SchemeIsFile());

  RunObjectElementsTest(url);
}

// Test compares original-vs-saved for a page with frames at about:blank uri.
// This tests handling of iframe elements without src attribute (only with
// srcdoc attribute) and how they get saved / cross-referenced.
#if BUILDFLAG(IS_MAC)
// TODO(crbug.com/40202613): Fails on dcheck-enabled builds on 11.0.
#define MAYBE_AboutBlank DISABLED_AboutBlank
#else
#define MAYBE_AboutBlank AboutBlank
#endif
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest,
                       MAYBE_AboutBlank) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "main: acb0609d-eb10-4c26-83e2-ad8afb7b0ff3",
      "sub1: b124df3a-d39f-47a1-ae04-5bb5d0bf549e",
      "sub2: 07014068-604d-45ae-884f-a068cfe7bc0a",
      "sub3: 06cc8fcc-c692-4a1a-a10f-1645b746e8f4",
  };

  GURL url(embedded_test_server()->GetURL("a.com",
                                          "/save_page/frames-about-blank.htm"));

  TestOriginalVsSavedPage(save_page_type, url, 4, 4, expected_substrings);
}

// Test compares original-vs-saved for a page with nested frames.
// Two levels of nesting are especially good for verifying correct
// link rewriting for subframes-vs-main-frame (see crbug.com/554666).
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest, NestedFrames) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "frames-nested.htm: 4388232f-8d45-4d2e-9807-721b381be153",
      "frames-nested2.htm: 6d23dc47-f283-4977-96ec-66bcf72301a4",
      "b.htm: 3a35f7fa-96a9-4487-9f18-4470263907fa",
  };

  GURL url(
      embedded_test_server()->GetURL("a.com", "/save_page/frames-nested.htm"));

  TestOriginalVsSavedPage(save_page_type, url, 3, 3, expected_substrings);
}

// Test for crbug.com/106364 and crbug.com/538188.
// Test frames have the same uri ...
//   subframe1 and subframe2 - both have src=b.htm
//   subframe3 and subframe4 - about:blank (no src, only srcdoc attribute).
// ... but different content (generated by main frame's javascript).
#if BUILDFLAG(IS_MAC)
// TODO(crbug.com/40202613): Fails on dcheck-enabled builds on 11.0.
#define MAYBE_RuntimeChanges DISABLED_RuntimeChanges
#else
#define MAYBE_RuntimeChanges RuntimeChanges
#endif
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest,
                       MAYBE_RuntimeChanges) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "frames-runtime-changes.htm: 4388232f-8d45-4d2e-9807-721b381be153",
      "subframe1: 21595339-61fc-4854-b6df-0668328ea263",
      "subframe2: adf55719-15e7-45be-9eda-d12fe782a1bd",
      "subframe3: 50e294bf-3a5b-499d-8772-651ead26952f",
      "subframe4: e0ea9289-7467-4d32-ba5c-c604e8d84cb7",
  };

  GURL url(embedded_test_server()->GetURL(
      "a.com", "/save_page/frames-runtime-changes.htm?do_runtime_changes=1"));

  TestOriginalVsSavedPage(save_page_type, url, 5, 5, expected_substrings);
}

// Test for saving frames with various encodings:
// - iso-8859-2: encoding declared via <meta> element
// - utf16-le-bom.htm, utf16-be-bom.htm: encoding detected via BOM
// - utf16-le-nobom.htm, utf16-le-nobom.htm - encoding declared via
//                                            mocked http headers
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest, Encoding) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "frames-encodings.htm: f53295dd-a95b-4b32-85f5-b6e15377fb20",
      "iso-8859-2.htm: Za\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87 "
      "g\xc4\x99\xc5\x9bl\xc4\x85 ja\xc5\xba\xc5\x84",
      "utf16-le-nobom.htm: Za\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87 "
      "g\xc4\x99\xc5\x9bl\xc4\x85 ja\xc5\xba\xc5\x84",
      "utf16-le-bom.htm: Za\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87 "
      "g\xc4\x99\xc5\x9bl\xc4\x85 ja\xc5\xba\xc5\x84",
      "utf16-be-nobom.htm: Za\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87 "
      "g\xc4\x99\xc5\x9bl\xc4\x85 ja\xc5\xba\xc5\x84",
      "utf16-be-bom.htm: Za\xc5\xbc\xc3\xb3\xc5\x82\xc4\x87 "
      "g\xc4\x99\xc5\x9bl\xc4\x85 ja\xc5\xba\xc5\x84"};

  GURL url(embedded_test_server()->GetURL("a.com",
                                          "/save_page/frames-encodings.htm"));

  // TODO(lukasza): crbug.com/541699: MHTML needs to handle multi-byte encodings
  // by either:
  // 1. Continuing to preserve the original encoding, but starting to round-trip
  //    the encoding declaration (in Content-Type MIME/MHTML header?)
  // 2. Saving html docs in UTF8.
  // 3. Saving the BOM (not sure if this will help for all cases though).
  if (save_page_type == content::SAVE_PAGE_TYPE_AS_MHTML)
    return;

  TestOriginalVsSavedPage(save_page_type, url, 6, 6, expected_substrings);
}

// Test for saving style element and attribute (see also crbug.com/568293).
#if BUILDFLAG(IS_MAC)
// TODO(crbug.com/40202613): Fails on dcheck-enabled builds on 11.0.
#define MAYBE_Style DISABLED_Style
#else
#define MAYBE_Style Style
#endif
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest, MAYBE_Style) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "style.htm: af84c3ca-0fc6-4b0d-bf7a-5ac18a4dab62",
      "frameF: c9539ccd-47b0-47cf-a03b-734614865872",
  };

  GURL url(embedded_test_server()->GetURL("a.com", "/save_page/style.htm"));

  // The original page has 7 iframes. One of them that contains hidden attribute
  // will be excluded from the saved page.
  TestOriginalVsSavedPage(save_page_type, url, 7, 6, expected_substrings);
}

// Test for saving a page with broken subresources:
// - Broken, undecodable image (see also https://crbug.com/586680)
// - Broken link, to unresolvable host (see also https://crbug.com/594219)
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest, BrokenImage) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "broken-image.htm: 1e846775-b3ed-4d9c-a124-029554a1eb9d",
  };

  GURL url(embedded_test_server()->GetURL("127.0.0.1",
                                          "/save_page/broken-image.htm"));

  TestOriginalVsSavedPage(save_page_type, url, 1, 1, expected_substrings);
}

// Test for saving a page with a cross-site <object> element.
// Disabled on Windows due to flakiness. crbug.com/1070597.
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC)
#define MAYBE_CrossSiteObject DISABLED_CrossSiteObject
#else
#define MAYBE_CrossSiteObject CrossSiteObject
#endif
IN_PROC_BROWSER_TEST_P(SavePageOriginalVsSavedComparisonTest,
                       MAYBE_CrossSiteObject) {
  content::SavePageType save_page_type = GetParam();

  std::vector<std::string> expected_substrings = {
      "cross-site-object.htm: f727dd87-2048-44cf-beee-19fa9863f046",
      "a.htm: 1b8aae2b-e164-462f-bd5b-98aa366205f2",
      "svg: 0875fd06-131d-4708-95e1-861853c6b8dc",
  };

  GURL url(embedded_test_server()->GetURL("a.com",
                                          "/save_page/cross-site-object.htm"));

  TestOriginalVsSavedPage(save_page_type, url, 4, 4, expected_substrings);
}

INSTANTIATE_TEST_SUITE_P(
    SaveAsCompleteHtml,
    SavePageOriginalVsSavedComparisonTest,
    ::testing::Values(content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
INSTANTIATE_TEST_SUITE_P(SaveAsMhtml,
                         SavePageOriginalVsSavedComparisonTest,
                         ::testing::Values(content::SAVE_PAGE_TYPE_AS_MHTML));

class BlockingDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
 public:
  explicit BlockingDownloadManagerDelegate(Profile* profile)
      : ChromeDownloadManagerDelegate(profile) {}
  ~BlockingDownloadManagerDelegate() override = default;

  void CheckSavePackageAllowed(
      download::DownloadItem* download_item,
      base::flat_map<base::FilePath, base::FilePath> save_package_files,
      content::SavePackageAllowedCallback callback) override {
    {
      base::ScopedAllowBlockingForTesting allow_blocking;
      for (const auto& tmp_path_and_final_path : save_package_files) {
        // Every intermediate path in `save_package_files` should exist when
        // this function is called.
        EXPECT_TRUE(base::PathExists(tmp_path_and_final_path.first));

        // We don't know what exact temporary path the file has, but it
        // shouldn't be the same as its final one.
        EXPECT_NE(tmp_path_and_final_path.first,
                  tmp_path_and_final_path.second);

        save_package_final_paths_.insert(tmp_path_and_final_path.second);
      }
    }

    std::move(callback).Run(false);
  }

  void ValidateSavePackageFiles(
      const base::flat_set<base::FilePath>& expected_paths) {
    EXPECT_EQ(expected_paths.size(), save_package_final_paths_.size());
    for (const base::FilePath& expected_path : expected_paths) {
      EXPECT_TRUE(save_package_final_paths_.contains(expected_path));
    }
  }

 private:
  base::flat_set<base::FilePath> save_package_final_paths_;
};

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveOnlyHTMLBlocked) {
  GURL url = NavigateToMockURL("a");

  auto blocking_delegate =
      std::make_unique<BlockingDownloadManagerDelegate>(browser()->profile());
  blocking_delegate->GetDownloadIdReceiverCallback().Run(
      download::DownloadItem::kInvalidId + 1);
  DownloadCoreServiceFactory::GetForBrowserContext(browser()->profile())
      ->SetDownloadManagerDelegateForTesting(std::move(blocking_delegate));
  auto* delegate = static_cast<BlockingDownloadManagerDelegate*>(
      DownloadCoreServiceFactory::GetForBrowserContext(browser()->profile())
          ->GetDownloadManagerDelegate());

  base::FilePath full_file_name, dir;
  GetDestinationPaths("a", &full_file_name, &dir,
                      content::SAVE_PAGE_TYPE_AS_ONLY_HTML);
  base::RunLoop run_loop;
  content::SavePackageFinishedObserver observer(
      browser()->profile()->GetDownloadManager(), run_loop.QuitClosure());
  ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
      full_file_name, dir, content::SAVE_PAGE_TYPE_AS_ONLY_HTML));

  run_loop.Run();
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_FALSE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));

  delegate->ValidateSavePackageFiles({full_file_name});
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveCompleteHTMLBlocked) {
  GURL url = NavigateToMockURL("b");

  auto blocking_delegate =
      std::make_unique<BlockingDownloadManagerDelegate>(browser()->profile());
  blocking_delegate->GetDownloadIdReceiverCallback().Run(
      download::DownloadItem::kInvalidId + 1);
  DownloadCoreServiceFactory::GetForBrowserContext(browser()->profile())
      ->SetDownloadManagerDelegateForTesting(std::move(blocking_delegate));
  auto* delegate = static_cast<BlockingDownloadManagerDelegate*>(
      DownloadCoreServiceFactory::GetForBrowserContext(browser()->profile())
          ->GetDownloadManagerDelegate());

  base::FilePath full_file_name, dir;
  GetDestinationPaths("b", &full_file_name, &dir,
                      content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML);
  base::RunLoop run_loop;
  content::SavePackageFinishedObserver observer(
      browser()->profile()->GetDownloadManager(), run_loop.QuitClosure());
  ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
      full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));

  run_loop.Run();
  ASSERT_FALSE(HasFailure());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_FALSE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));

  delegate->ValidateSavePackageFiles({
      full_file_name,
      dir.AppendASCII("1.png"),
      dir.AppendASCII("1.css"),
  });
}

#if BUILDFLAG(IS_CHROMEOS)

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveHTMLWithDlp) {
  base::FilePath full_file_name, dir;
  GURL url;

  chromeos::DlpClient::Shutdown();
  chromeos::DlpClient::InitializeFake();
  base::test::RepeatingTestFuture<
      dlp::AddFilesRequest, base::OnceCallback<void(dlp::AddFilesResponse)>>
      add_file_cb;
  chromeos::DlpClient::Get()->GetTestInterface()->SetAddFilesMock(
      add_file_cb.GetCallback());

  url = NavigateToMockURL("a");

  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML, "a", 1, &dir,
                 &full_file_name);

  ASSERT_FALSE(HasFailure());

  auto request = std::get<0>(add_file_cb.Take());
  ASSERT_EQ(1, request.add_file_requests().size());
  EXPECT_EQ(full_file_name.value(), request.add_file_requests(0).file_path());
  EXPECT_EQ(request.add_file_requests(0).source_url(), url.spec());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
}

IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SaveMHTMLWithDlp) {
  base::FilePath full_file_name, dir;
  GURL url;

  chromeos::DlpClient::Shutdown();
  chromeos::DlpClient::InitializeFake();
  base::test::RepeatingTestFuture<
      dlp::AddFilesRequest, base::OnceCallback<void(dlp::AddFilesResponse)>>
      add_file_cb;
  chromeos::DlpClient::Get()->GetTestInterface()->SetAddFilesMock(
      add_file_cb.GetCallback());

  url = NavigateToMockURL("a");

  SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_MHTML, "a", -1, &dir,
                 &full_file_name);

  ASSERT_FALSE(HasFailure());

  auto request = std::get<0>(add_file_cb.Take());
  ASSERT_EQ(1, request.add_file_requests().size());
  EXPECT_EQ(full_file_name.value(), request.add_file_requests(0).file_path());
  EXPECT_EQ(request.add_file_requests(0).source_url(), url.spec());

  base::ScopedAllowBlockingForTesting allow_blocking;
  EXPECT_TRUE(base::PathExists(full_file_name));
  EXPECT_FALSE(base::PathExists(dir));
}

#endif  // BUILDFLAG(IS_CHROMEOS)

}  // namespace
