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

#include <algorithm>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/feature_list.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browsing_data/browsing_data_helper.h"
#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h"
#include "chrome/browser/net/net_error_diagnostics_dialog.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search_engines/ui_thread_search_terms_data.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.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/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/google/core/common/google_util.h"
#include "components/language/core/browser/pref_names.h"
#include "components/policy/core/browser/browser_policy_connector.h"
#include "components/policy/core/common/mock_configuration_policy_provider.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "google_apis/gaia/gaia_urls.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/base/filename_util.h"
#include "net/base/net_errors.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/failing_http_transaction_factory.h"
#include "net/http/http_cache.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 "net/test/url_request/url_request_failed_job.h"
#include "net/test/url_request/url_request_mock_data_job.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_test_job.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/features.h"
#include "ui/base/l10n/l10n_util.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/chrome_browser_main_chromeos.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chromeos/tpm/stub_install_attributes.h"
#include "components/policy/core/common/policy_types.h"
#else
#include "chrome/browser/policy/profile_policy_connector_builder.h"
#endif
#include "components/policy/core/common/mock_configuration_policy_provider.h"

using content::BrowserThread;
using content::NavigationController;
using net::URLRequestFailedJob;
using net::URLRequestTestJob;

namespace {

// Searches for first node containing |text|, and if it finds one, searches
// through all ancestors seeing if any of them is of class "hidden". Since it
// relies on the hidden class used by network error pages, not suitable for
// general use.
bool WARN_UNUSED_RESULT IsDisplayingText(Browser* browser,
                                         const std::string& text) {
  // clang-format off
  std::string command = base::StringPrintf(R"(
    function isNodeVisible(node) {
      if (!node || node.classList.contains('hidden'))
        return false;
      if (!node.parentElement)
        return true;
      // Otherwise, we must check all parent nodes
      return isNodeVisible(node.parentElement);
    }
    var node = document.evaluate("//*[contains(text(),'%s')]", document,
      null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    domAutomationController.send(isNodeVisible(node));
  )", text.c_str());
  // clang-format on
  bool result = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      browser->tab_strip_model()->GetActiveWebContents(), command, &result));
  return result;
}

// Expands the more box on the currently displayed error page.
void ToggleHelpBox(Browser* browser) {
  EXPECT_TRUE(content::ExecuteScript(
      browser->tab_strip_model()->GetActiveWebContents(),
      "document.getElementById('details-button').click();"));
}

// Returns true if the diagnostics link suggestion is displayed.
bool WARN_UNUSED_RESULT IsDisplayingDiagnosticsLink(Browser* browser) {
  std::string command = base::StringPrintf(
      "var diagnose_link = document.getElementById('diagnose-link');"
      "domAutomationController.send(diagnose_link != null);");
  bool result = false;
  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
      browser->tab_strip_model()->GetActiveWebContents(), command, &result));
  return result;
}

// Checks that the local error page is being displayed, without remotely
// retrieved navigation corrections, and with the specified error string.
void ExpectDisplayingLocalErrorPage(const std::string& url,
                                    Browser* browser,
                                    const std::string& error_string) {
  EXPECT_TRUE(IsDisplayingText(browser, error_string));

  // Locally generated error pages should not have navigation corrections.
  EXPECT_FALSE(IsDisplayingText(browser, url));

  // Locally generated error pages should not have a link with search terms.
  EXPECT_FALSE(IsDisplayingText(browser, "search query"));
}

// Checks that the local error page is being displayed, without remotely
// retrieved navigation corrections, and with the specified error code.
void ExpectDisplayingLocalErrorPage(const std::string& url,
                                    Browser* browser,
                                    net::Error error_code) {
  ExpectDisplayingLocalErrorPage(url, browser,
                                 net::ErrorToShortString(error_code));
}

// Checks that an error page with information retrieved from the navigation
// correction service is being displayed, with the specified specified error
// string.
void ExpectDisplayingNavigationCorrections(Browser* browser,
                                           const std::string& error_string) {
  EXPECT_TRUE(IsDisplayingText(browser, error_string));

  // Check that the mock navigation corrections are displayed.
  EXPECT_TRUE(IsDisplayingText(browser, "http://mock.http/title2.html"));

  // Check that the search terms are displayed as a link.
  EXPECT_TRUE(IsDisplayingText(browser, "search query"));

  // The diagnostics button isn't displayed when corrections were
  // retrieved from a remote server.
  EXPECT_FALSE(IsDisplayingDiagnosticsLink(browser));
}

// Checks that an error page with information retrieved from the navigation
// correction service is being displayed, with the specified specified error
// code.
void ExpectDisplayingNavigationCorrections(Browser* browser,
                                           net::Error error_code) {
  ExpectDisplayingNavigationCorrections(browser,
                                        net::ErrorToShortString(error_code));
}

// Returns true if the platform has support for a diagnostics tool, and it
// can be launched from |web_contents|.
bool WebContentsCanShowDiagnosticsTool(content::WebContents* web_contents) {
#if defined(OS_CHROMEOS)
  // ChromeOS uses an extension instead of a diagnostics dialog.
  return true;
#else
  return CanShowNetworkDiagnosticsDialog(web_contents);
#endif
}

class ErrorPageTest : public InProcessBrowserTest {
 public:
  enum HistoryNavigationDirection {
    HISTORY_NAVIGATE_BACK,
    HISTORY_NAVIGATE_FORWARD,
  };

  ErrorPageTest() = default;
  ~ErrorPageTest() override = default;

  // Navigates the active tab to a mock url created for the file at |path|.
  void NavigateToFileURL(const std::string& path) {
    GURL url = embedded_test_server()->GetURL(path);
    ui_test_utils::NavigateToURL(browser(), url);
  }

  // Navigates to the given URL and waits for |num_navigations| to occur, and
  // the title to change to |expected_title|.
  void NavigateToURLAndWaitForTitle(const GURL& url,
                                    const std::string& expected_title,
                                    int32_t num_navigations) {
    content::TitleWatcher title_watcher(
        browser()->tab_strip_model()->GetActiveWebContents(),
        base::ASCIIToUTF16(expected_title));

    ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), url, num_navigations);

    EXPECT_EQ(base::ASCIIToUTF16(expected_title),
              title_watcher.WaitAndGetTitle());
  }

  // Navigates back in the history and waits for |num_navigations| to occur, and
  // the title to change to |expected_title|.
  void GoBackAndWaitForTitle(const std::string& expected_title,
                             int32_t num_navigations) {
    NavigateHistoryAndWaitForTitle(expected_title,
                                   num_navigations,
                                   HISTORY_NAVIGATE_BACK);
  }

  // Navigates forward in the history and waits for |num_navigations| to occur,
  // and the title to change to |expected_title|.
  void GoForwardAndWaitForTitle(const std::string& expected_title,
                                int32_t num_navigations) {
    NavigateHistoryAndWaitForTitle(expected_title,
                                   num_navigations,
                                   HISTORY_NAVIGATE_FORWARD);
  }

  void GoBackAndWaitForNavigations(int32_t num_navigations) {
    NavigateHistory(num_navigations, HISTORY_NAVIGATE_BACK);
  }

  void GoForwardAndWaitForNavigations(int32_t num_navigations) {
    NavigateHistory(num_navigations, HISTORY_NAVIGATE_FORWARD);
  }

  // Navigates the browser the indicated direction in the history and waits for
  // |num_navigations| to occur and the title to change to |expected_title|.
  void NavigateHistoryAndWaitForTitle(const std::string& expected_title,
                                      int32_t num_navigations,
                                      HistoryNavigationDirection direction) {
    content::TitleWatcher title_watcher(
        browser()->tab_strip_model()->GetActiveWebContents(),
        base::ASCIIToUTF16(expected_title));

    NavigateHistory(num_navigations, direction);

    EXPECT_EQ(title_watcher.WaitAndGetTitle(),
              base::ASCIIToUTF16(expected_title));
  }

  void NavigateHistory(int32_t num_navigations,
                       HistoryNavigationDirection direction) {
    content::TestNavigationObserver test_navigation_observer(
        browser()->tab_strip_model()->GetActiveWebContents(), num_navigations);
    if (direction == HISTORY_NAVIGATE_BACK) {
      chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB);
    } else if (direction == HISTORY_NAVIGATE_FORWARD) {
      chrome::GoForward(browser(), WindowOpenDisposition::CURRENT_TAB);
    } else {
      FAIL();
    }
    test_navigation_observer.Wait();
  }
};

class TestFailProvisionalLoadObserver : public content::WebContentsObserver {
 public:
  explicit TestFailProvisionalLoadObserver(content::WebContents* contents)
      : content::WebContentsObserver(contents) {}
  ~TestFailProvisionalLoadObserver() override {}

  void DidFinishNavigation(
      content::NavigationHandle* navigation_handle) override {
    if (navigation_handle->IsErrorPage())
      fail_url_ = navigation_handle->GetURL();
  }

  const GURL& fail_url() const { return fail_url_; }

 private:
  GURL fail_url_;

  DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver);
};

class DNSErrorPageTest : public ErrorPageTest {
 public:
  DNSErrorPageTest() {
    url_loader_interceptor_ =
        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
            [](DNSErrorPageTest* owner,
               content::URLLoaderInterceptor::RequestParams* params) {
              // Add an interceptor that serves LinkDoctor responses
              if (google_util::LinkDoctorBaseURL() == params->url_request.url) {
                // The origin header should exist and be opaque.
                std::string origin;
                bool has_origin = params->url_request.headers.GetHeader(
                    net::HttpRequestHeaders::kOrigin, &origin);
                EXPECT_TRUE(has_origin);
                EXPECT_EQ(origin, "null");
                // Send RequestCreated so that anyone blocking on
                // WaitForRequests can continue.
                base::PostTaskWithTraits(
                    FROM_HERE, {BrowserThread::UI},
                    base::BindOnce(&DNSErrorPageTest::RequestCreated,
                                   base::Unretained(owner)));
                content::URLLoaderInterceptor::WriteResponse(
                    "chrome/test/data/mock-link-doctor.json",
                    params->client.get());
                return true;
              }

              // Referenced by mock Link Doctor page.
              if (params->url_request.url.spec() ==
                  "http://mock.http/title2.html") {
                content::URLLoaderInterceptor::WriteResponse(
                    "chrome/test/data/title2.html", params->client.get());
                return true;
              }

              // Add an interceptor for the search engine the error page will
              // use.
              if (params->url_request.url.host() ==
                  owner->search_term_url_.host()) {
                content::URLLoaderInterceptor::WriteResponse(
                    "chrome/test/data/title3.html", params->client.get());
                return true;
              }

              return false;
            },
            this));
  }

  ~DNSErrorPageTest() override = default;

  // When it sees a request for |path|, returns a 500 response with a body that
  // will be sniffed as binary/octet-stream.
  static std::unique_ptr<net::test_server::HttpResponse>
  Return500WithBinaryBody(const std::string& path,
                          const net::test_server::HttpRequest& request) {
    if (path != request.relative_url)
      return nullptr;
    return std::unique_ptr<net::test_server::HttpResponse>(
        new net::test_server::RawHttpResponse("HTTP/1.1 500 Server Sad :(\n\n",
                                              "\x01"));
  }

  void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }

  void SetUpOnMainThread() override {
    // All mock.http requests get served by the embedded test server.
    host_resolver()->AddRule("mock.http", "127.0.0.1");

    ASSERT_TRUE(embedded_test_server()->Start());

    UIThreadSearchTermsData search_terms_data(browser()->profile());
    search_term_url_ = GURL(search_terms_data.GoogleBaseURLValue());
  }

  void WaitForRequests(int32_t requests_to_wait_for) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    DCHECK_EQ(-1, requests_to_wait_for_);
    DCHECK(!run_loop_);

    if (requests_to_wait_for <= num_requests_)
      return;

    requests_to_wait_for_ = requests_to_wait_for;
    run_loop_.reset(new base::RunLoop());
    run_loop_->Run();
    run_loop_.reset();
    requests_to_wait_for_ = -1;
    EXPECT_EQ(num_requests_, requests_to_wait_for);
  }

  // Returns the total number of requests handled thus far.
  int32_t num_requests() const {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    return num_requests_;
  }

  void RequestCreated() {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    num_requests_++;
    if (num_requests_ == requests_to_wait_for_)
      run_loop_->Quit();
  }

  // Returns a GURL that results in a DNS error.
  GURL GetDnsErrorURL() const {
    return URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED);
  }

 private:
  // These are only used on the UI thread.
  int32_t num_requests_ = 0;
  int32_t requests_to_wait_for_ = -1;
  GURL search_term_url_;
  std::unique_ptr<base::RunLoop> run_loop_;
  std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
};

// Test an error with a file URL, and make sure it doesn't have a
// button to launch a network diagnostics tool.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, FileNotFound) {
  // Create an empty temp directory, to be sure there's no file in it.
  base::ScopedAllowBlockingForTesting allow_blocking;
  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  GURL non_existent_file_url =
      net::FilePathToFileURL(temp_dir.GetPath().AppendASCII("marmoset"));

  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), non_existent_file_url, 1);

  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      browser(), net::ERR_FILE_NOT_FOUND);
  // Should not request Link Doctor corrections for local errors.
  EXPECT_EQ(0, num_requests());
  // Only errors on HTTP/HTTPS pages should display a diagnostics button.
  EXPECT_FALSE(IsDisplayingDiagnosticsLink(browser()));
}

// Check an network error page for ERR_FAILED. In particular, this should
// not trigger a link doctor error page.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Failed) {
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), URLRequestFailedJob::GetMockHttpUrl(net::ERR_FAILED), 1);

  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      browser(), net::ERR_FAILED);
  // Should not request Link Doctor corrections for this error.
  EXPECT_EQ(0, num_requests());
}

// Test that a DNS error occuring in the main frame redirects to an error page.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_Basic) {
  // The first navigation should fail and load a blank page, while it fetches
  // the Link Doctor response.  The second navigation is the Link Doctor.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(
      browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());
}

// Test that a DNS error occuring in the main frame does not result in an
// additional session history entry.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack1) {
  NavigateToFileURL("/title2.html");
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(
      browser(), net::ERR_NAME_NOT_RESOLVED);
  GoBackAndWaitForTitle("Title Of Awesomeness", 1);
  EXPECT_EQ(1, num_requests());
}

// Test that a DNS error occuring in the main frame does not result in an
// additional session history entry.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack2) {
  NavigateToFileURL("/title2.html");

  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(
      browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());

  NavigateToFileURL("/title3.html");

  GoBackAndWaitForNavigations(2);
  ExpectDisplayingNavigationCorrections(
      browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(2, num_requests());

  GoBackAndWaitForTitle("Title Of Awesomeness", 1);
  EXPECT_EQ(2, num_requests());
}

// Test that a DNS error occuring in the main frame does not result in an
// additional session history entry.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack2AndForward) {
  NavigateToFileURL("/title2.html");

  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);

  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());

  NavigateToFileURL("/title3.html");

  GoBackAndWaitForNavigations(2);
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(2, num_requests());

  GoBackAndWaitForTitle("Title Of Awesomeness", 1);

  GoForwardAndWaitForNavigations(2);
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(3, num_requests());
}

// Test that a DNS error occuring in the main frame does not result in an
// additional session history entry.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_GoBack2Forward2) {
  NavigateToFileURL("/title3.html");

  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());

  NavigateToFileURL("/title2.html");

  GoBackAndWaitForNavigations(2);
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(2, num_requests());

  GoBackAndWaitForTitle("Title Of More Awesomeness", 1);

  GoForwardAndWaitForNavigations(2);
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(3, num_requests());

  GoForwardAndWaitForTitle("Title Of Awesomeness", 1);
  EXPECT_EQ(3, num_requests());
}

// Test that the search link on a DNS error page works.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_DoSearch) {
  // The first navigation should fail, and the second one should be the error
  // page.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(
      browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Do a search and make sure the browser ends up at the right page.
  content::TestNavigationObserver nav_observer(web_contents, 1);
  content::TitleWatcher title_watcher(
      web_contents,
      base::ASCIIToUTF16("Title Of More Awesomeness"));
  // Can't use content::ExecuteScript because it waits for scripts to send
  // notification that they've run, and scripts that trigger a navigation may
  // not send that notification.
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16("document.getElementById('search-link').click();"),
      base::NullCallback());
  nav_observer.Wait();
  EXPECT_EQ(base::ASCIIToUTF16("Title Of More Awesomeness"),
            title_watcher.WaitAndGetTitle());

  // There should have been another Link Doctor request, for tracking purposes.
  // Have to wait for it, since the search page does not depend on having
  // sent the tracking request.
  WaitForRequests(2);

  // Check the path and query string.
  std::string url;
  ASSERT_TRUE(content::ExecuteScriptAndExtractString(
                  browser()->tab_strip_model()->GetActiveWebContents(),
                  "domAutomationController.send(window.location.href);",
                  &url));
  EXPECT_EQ("/search", GURL(url).path());
  EXPECT_EQ("q=search%20query", GURL(url).query());

  // Go back to the error page, to make sure the history is correct.
  GoBackAndWaitForNavigations(2);
  ExpectDisplayingNavigationCorrections(
      browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(3, num_requests());
}

// Test that the reload button on a DNS error page works.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_DoReload) {
  // The first navigation should fail, and the second one should be the error
  // page.
  std::string url =
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec();
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Clicking the reload button should load the error page again, and there
  // should be two commits, as before.
  content::TestNavigationObserver nav_observer(web_contents, 2);
  // Can't use content::ExecuteScript because it waits for scripts to send
  // notification that they've run, and scripts that trigger a navigation may
  // not send that notification.
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16("document.getElementById('reload-button').click();"),
      base::NullCallback());
  nav_observer.Wait();
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);

  // There should have been two more requests to the correction service:  One
  // for the new error page, and one for tracking purposes.  Have to make sure
  // to wait for the tracking request, since the new error page does not depend
  // on it.
  WaitForRequests(3);
}

// Test that the reload button on a DNS error page works after a same document
// navigation on the error page.  Error pages don't seem to do this, but some
// traces indicate this may actually happen.  This test may hang on regression.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest,
                       DNSError_DoReloadAfterSameDocumentNavigation) {
  // The first navigation should fail, and the second one should be the error
  // page.
  std::string url =
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec();
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Do a same-document navigation on the error page, which should not result
  // in a new navigation.
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16("document.location='#';"), base::NullCallback());
  content::WaitForLoadStop(web_contents);
  // Page being displayed should not change.
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);
  // No new requests should have been issued.
  EXPECT_EQ(1, num_requests());

  // Clicking the reload button should load the error page again, and there
  // should be two commits, as before.
  content::TestNavigationObserver nav_observer2(web_contents, 2);
  // Can't use content::ExecuteScript because it waits for scripts to send
  // notification that they've run, and scripts that trigger a navigation may
  // not send that notification.
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16("document.getElementById('reload-button').click();"),
      base::NullCallback());
  nav_observer2.Wait();
  ExpectDisplayingNavigationCorrections(browser(), net::ERR_NAME_NOT_RESOLVED);

  // There should have been two more requests to the correction service:  One
  // for the new error page, and one for tracking purposes.  Have to make sure
  // to wait for the tracking request, since the new error page does not depend
  // on it.
  WaitForRequests(3);
}

// Test that clicking links on a DNS error page works.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, DNSError_DoClickLink) {
  // The first navigation should fail, and the second one should be the error
  // page.
  GURL url = embedded_test_server()->GetURL("mock.http", "/title2.html");
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
       browser(), GetDnsErrorURL(), 2);
  ExpectDisplayingNavigationCorrections(
      browser(), net::ERR_NAME_NOT_RESOLVED);
  EXPECT_EQ(1, num_requests());

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Simulate a click on a link.

  content::TitleWatcher title_watcher(
      web_contents,
      base::ASCIIToUTF16("Title Of Awesomeness"));
  std::string link_selector =
      "document.querySelector('a[href=\"http://mock.http/title2.html\"]')";
  // The tracking request is triggered by onmousedown, so it catches middle
  // mouse button clicks, as well as left clicks.
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16(link_selector + ".onmousedown();"),
      base::NullCallback());
  // Can't use content::ExecuteScript because it waits for scripts to send
  // notification that they've run, and scripts that trigger a navigation may
  // not send that notification.
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16(link_selector + ".click();"), base::NullCallback());
  EXPECT_EQ(base::ASCIIToUTF16("Title Of Awesomeness"),
            title_watcher.WaitAndGetTitle());

  // There should have been a tracking request to the correction service.  Have
  // to make sure to wait the tracking request, since the new page does not
  // depend on it.
  WaitForRequests(2);
}

// Test that a DNS error occuring in an iframe does not result in showing
// navigation corrections.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, IFrameDNSError_Basic) {
  NavigateToURLAndWaitForTitle(
      embedded_test_server()->GetURL("/iframe_dns_error.html"), "Blah", 1);
  // We expect to have two history entries, since we started off with navigation
  // to "about:blank" and then navigated to "iframe_dns_error.html".
  EXPECT_EQ(2,
      browser()->tab_strip_model()->GetActiveWebContents()->
          GetController().GetEntryCount());
  EXPECT_EQ(0, num_requests());
}

// This test fails regularly on win_rel trybots. See crbug.com/121540
#if defined(OS_WIN)
#define MAYBE_IFrameDNSError_GoBack DISABLED_IFrameDNSError_GoBack
#else
#define MAYBE_IFrameDNSError_GoBack IFrameDNSError_GoBack
#endif
// Test that a DNS error occuring in an iframe does not result in an
// additional session history entry.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, MAYBE_IFrameDNSError_GoBack) {
  ui_test_utils::NavigateToURL(browser(),
                               embedded_test_server()->GetURL("/title2.html"));
  ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/iframe_dns_error.html"));
  GoBackAndWaitForTitle("Title Of Awesomeness", 1);
  EXPECT_EQ(0, num_requests());
}

// This test fails regularly on win_rel trybots. See crbug.com/121540
//
// This fails on linux_aura bringup: http://crbug.com/163931
#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
#define MAYBE_IFrameDNSError_GoBackAndForward DISABLED_IFrameDNSError_GoBackAndForward
#else
#define MAYBE_IFrameDNSError_GoBackAndForward IFrameDNSError_GoBackAndForward
#endif
// Test that a DNS error occuring in an iframe does not result in an
// additional session history entry.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest,
                       MAYBE_IFrameDNSError_GoBackAndForward) {
  NavigateToFileURL("/title2.html");
  NavigateToFileURL("/iframe_dns_error.html");
  GoBackAndWaitForTitle("Title Of Awesomeness", 1);
  GoForwardAndWaitForTitle("Blah", 1);
  EXPECT_EQ(0, num_requests());
}

// Test that a DNS error occuring in an iframe, once the main document is
// completed loading, does not result in an additional session history entry.
// To ensure that the main document has completed loading, JavaScript is used to
// inject an iframe after loading is done.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, IFrameDNSError_JavaScript) {
  content::WebContents* wc =
      browser()->tab_strip_model()->GetActiveWebContents();
  GURL fail_url =
      URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED);

  // Load a regular web page, in which we will inject an iframe.
  ui_test_utils::NavigateToURL(browser(),
                               embedded_test_server()->GetURL("/title2.html"));

  // We expect to have two history entries, since we started off with navigation
  // to "about:blank" and then navigated to "title2.html".
  EXPECT_EQ(2, wc->GetController().GetEntryCount());

  std::string script = "var frame = document.createElement('iframe');"
                       "frame.src = '" + fail_url.spec() + "';"
                       "document.body.appendChild(frame);";
  {
    TestFailProvisionalLoadObserver fail_observer(wc);
    content::WindowedNotificationObserver load_observer(
        content::NOTIFICATION_LOAD_STOP,
        content::Source<NavigationController>(&wc->GetController()));
    wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script),
                                                  base::NullCallback());
    load_observer.Wait();

    // Ensure we saw the expected failure.
    EXPECT_EQ(fail_url, fail_observer.fail_url());

    // Failed initial navigation of an iframe shouldn't be adding any history
    // entries.
    EXPECT_EQ(2, wc->GetController().GetEntryCount());
  }

  // Do the same test, but with an iframe that doesn't have initial URL
  // assigned.
  script = "var frame = document.createElement('iframe');"
           "frame.id = 'target_frame';"
           "document.body.appendChild(frame);";
  {
    content::WindowedNotificationObserver load_observer(
        content::NOTIFICATION_LOAD_STOP,
        content::Source<NavigationController>(&wc->GetController()));
    wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script),
                                                  base::NullCallback());
    load_observer.Wait();
  }

  script = "var f = document.getElementById('target_frame');"
           "f.src = '" + fail_url.spec() + "';";
  {
    TestFailProvisionalLoadObserver fail_observer(wc);
    content::WindowedNotificationObserver load_observer(
        content::NOTIFICATION_LOAD_STOP,
        content::Source<NavigationController>(&wc->GetController()));
    wc->GetMainFrame()->ExecuteJavaScriptForTests(base::ASCIIToUTF16(script),
                                                  base::NullCallback());
    load_observer.Wait();

    EXPECT_EQ(fail_url, fail_observer.fail_url());
    EXPECT_EQ(2, wc->GetController().GetEntryCount());
  }
  EXPECT_EQ(0, num_requests());
}

// Checks that navigation corrections are not loaded when we receive an actual
// 404 page.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Page404) {
  NavigateToURLAndWaitForTitle(embedded_test_server()->GetURL("/page404.html"),
                               "SUCCESS", 1);
  EXPECT_EQ(0, num_requests());
}

// Checks that navigation corrections are loaded in response to a 404 page with
// no body.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Empty404) {
  // The first navigation should fail and load a blank page, while it fetches
  // the Link Doctor response.  The second navigation is the Link Doctor.
  GURL url = embedded_test_server()->GetURL("/errorpage/empty404.html");
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 2);
  // This depends on the non-internationalized error ID string in
  // localized_error.cc.
  ExpectDisplayingNavigationCorrections(
      browser(), "HTTP ERROR 404");
  EXPECT_EQ(1, num_requests());
}

// Checks that a local error page is shown in response to a 500 error page
// without a body.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Empty500) {
  ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/errorpage/empty500.html"));
  // This depends on the non-internationalized error ID string in
  // localized_error.cc.
  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      browser(), "HTTP ERROR 500");
  EXPECT_EQ(0, num_requests());
}

// Check that the easter egg is present and initialised and is not disabled.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, CheckEasterEggIsNotDisabled) {
  ui_test_utils::NavigateToURL(browser(),
      URLRequestFailedJob::GetMockHttpUrl(net::ERR_INTERNET_DISCONNECTED));

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Check for no disabled message container.
  std::string command = base::StringPrintf(
      "var hasDisableContainer = document.querySelectorAll('.snackbar').length;"
      "domAutomationController.send(hasDisableContainer);");
  int32_t result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
               web_contents, command, &result));
  EXPECT_EQ(0, result);

  // Presence of the canvas container.
  command = base::StringPrintf(
    "var runnerCanvas = document.querySelectorAll('.runner-canvas').length;"
    "domAutomationController.send(runnerCanvas);");
  EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
               web_contents, command, &result));
  EXPECT_EQ(1, result);
}

// Test error page in incognito mode. The two major things are that navigation
// corrections are not fetched (Only one navigation, display local error page),
// and that no network diagnostic link is included, except on ChromeOS.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Incognito) {
  Browser* incognito_browser = CreateIncognitoBrowser();

  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
      incognito_browser,
      URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED), 1);

  // Verify that the expected error page is being displayed.
  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      incognito_browser, net::ERR_NAME_NOT_RESOLVED);

#if !defined(OS_CHROMEOS)
  // Can't currently show the diagnostics in incognito on any platform but
  // ChromeOS.
  EXPECT_FALSE(WebContentsCanShowDiagnosticsTool(
      incognito_browser->tab_strip_model()->GetActiveWebContents()));
#endif

  // Diagnostics button should be displayed, if available.
  EXPECT_EQ(WebContentsCanShowDiagnosticsTool(
                incognito_browser->tab_strip_model()->GetActiveWebContents()),
            IsDisplayingDiagnosticsLink(incognito_browser));
}

class ErrorPageAutoReloadTest : public InProcessBrowserTest {
 public:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    command_line->AppendSwitch(switches::kEnableAutoReload);
  }

  void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }

  void InstallInterceptor(const GURL& url, int32_t requests_to_fail) {
    requests_ = failures_ = 0;

    url_loader_interceptor_ =
        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
            [](int32_t requests_to_fail, int32_t* requests, int32_t* failures,
               content::URLLoaderInterceptor::RequestParams* params) {
              if (params->url_request.url.path() == "/searchdomaincheck")
                return false;
              if (params->url_request.url.path() == "/favicon.ico")
                return false;
              if (params->url_request.url.GetOrigin() ==
                  GaiaUrls::GetInstance()->gaia_url())
                return false;
              (*requests)++;
              if (*failures < requests_to_fail) {
                (*failures)++;
                network::URLLoaderCompletionStatus status;
                status.error_code = net::ERR_CONNECTION_RESET;
                params->client->OnComplete(status);
                return true;
              }

              std::string body = URLRequestTestJob::test_data_1();
              content::URLLoaderInterceptor::WriteResponse(
                  URLRequestTestJob::test_headers(), body,
                  params->client.get());
              return true;
            },
            requests_to_fail, &requests_, &failures_));
  }

  void NavigateToURLAndWaitForTitle(const GURL& url,
                                    const std::string& expected_title,
                                    int32_t num_navigations) {
    content::TitleWatcher title_watcher(
        browser()->tab_strip_model()->GetActiveWebContents(),
        base::ASCIIToUTF16(expected_title));

    ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
        browser(), url, num_navigations);

    EXPECT_EQ(base::ASCIIToUTF16(expected_title),
              title_watcher.WaitAndGetTitle());
  }

  int32_t interceptor_requests() const { return requests_; }
  int32_t interceptor_failures() const { return failures_; }

 private:
  std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
  int32_t requests_;
  int32_t failures_;
};

// Fails on official mac_trunk build. See crbug.com/465789.
#if defined(OFFICIAL_BUILD) && defined(OS_MACOSX)
#define MAYBE_AutoReload DISABLED_AutoReload
#else
#define MAYBE_AutoReload AutoReload
#endif
IN_PROC_BROWSER_TEST_F(ErrorPageAutoReloadTest, MAYBE_AutoReload) {
  GURL test_url("http://error.page.auto.reload");
  const int32_t kRequestsToFail = 2;
  InstallInterceptor(test_url, kRequestsToFail);
  NavigateToURLAndWaitForTitle(test_url, "Test One", kRequestsToFail + 1);
  // Note that the interceptor updates these variables on the IO thread,
  // but this function reads them on the main thread. The requests have to be
  // created (on the IO thread) before NavigateToURLAndWaitForTitle returns or
  // this becomes racey.
  EXPECT_EQ(kRequestsToFail, interceptor_failures());
  EXPECT_EQ(kRequestsToFail + 1, interceptor_requests());
}

IN_PROC_BROWSER_TEST_F(ErrorPageAutoReloadTest, ManualReloadNotSuppressed) {
  GURL test_url("http://error.page.auto.reload");
  const int32_t kRequestsToFail = 3;
  InstallInterceptor(test_url, kRequestsToFail);
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
      browser(), test_url, 2);

  EXPECT_EQ(2, interceptor_failures());
  EXPECT_EQ(2, interceptor_requests());

  ToggleHelpBox(browser());
  EXPECT_TRUE(IsDisplayingText(
      browser(), l10n_util::GetStringUTF8(
                     IDS_ERRORPAGES_SUGGESTION_CHECK_CONNECTION_HEADER)));

  content::WebContents* web_contents =
    browser()->tab_strip_model()->GetActiveWebContents();
  content::TestNavigationObserver nav_observer(web_contents, 1);
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16("document.getElementById('reload-button').click();"),
      base::NullCallback());
  nav_observer.Wait();
  EXPECT_FALSE(IsDisplayingText(
      browser(), l10n_util::GetStringUTF8(
                     IDS_ERRORPAGES_SUGGESTION_CHECK_CONNECTION_HEADER)));
}

// Make sure that a same document navigation does not cause issues with the
// auto-reload timer.  Note that this test was added due to this case causing
// a crash.  On regression, this test may hang due to a crashed renderer.
IN_PROC_BROWSER_TEST_F(ErrorPageAutoReloadTest, IgnoresSameDocumentNavigation) {
  GURL test_url("http://error.page.auto.reload");
  InstallInterceptor(test_url, 2);

  // Wait for the error page and first autoreload, which happens immediately.
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
      browser(), test_url, 2);

  EXPECT_EQ(2, interceptor_failures());
  EXPECT_EQ(2, interceptor_requests());

  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  web_contents->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16("document.location='#';"), base::NullCallback());
  content::WaitForLoadStop(web_contents);

  // Same-document navigation on an error page should not have resulted in a
  // new navigation, so no new requests should have been issued.
  EXPECT_EQ(2, interceptor_failures());
  EXPECT_EQ(2, interceptor_requests());

  // Wait for the second auto reload, which succeeds.
  content::TestNavigationObserver observer2(web_contents, 1);
  observer2.Wait();

  EXPECT_EQ(2, interceptor_failures());
  EXPECT_EQ(3, interceptor_requests());
}

// A test fixture that returns ERR_ADDRESS_UNREACHABLE for all navigation
// correction requests.  ERR_NAME_NOT_RESOLVED is more typical, but need to use
// a different error for the correction service and the original page to
// validate the right page is being displayed.
class ErrorPageNavigationCorrectionsFailTest : public ErrorPageTest {
 public:
  // InProcessBrowserTest:
  void SetUpOnMainThread() override {
    url_loader_interceptor_ =
        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
            [](content::URLLoaderInterceptor::RequestParams* params) {
              if (params->url_request.url != google_util::LinkDoctorBaseURL())
                return false;

              network::URLLoaderCompletionStatus status;
              status.error_code = net::ERR_ADDRESS_UNREACHABLE;
              params->client->OnComplete(status);
              return true;
            }));
  }

  void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }

 private:
  std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
};

// Make sure that when corrections fail to load, the network error page is
// successfully loaded and shows a link to the diagnostics too, if appropriate.
IN_PROC_BROWSER_TEST_F(ErrorPageNavigationCorrectionsFailTest,
                       FetchCorrectionsFails) {
  ASSERT_TRUE(embedded_test_server()->Start());
  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
      browser(),
      URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED),
      2);

  // Verify that the expected error page is being displayed.
  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      browser(), net::ERR_NAME_NOT_RESOLVED);

  // Diagnostics button should be displayed, if available.
  EXPECT_EQ(WebContentsCanShowDiagnosticsTool(
                browser()->tab_strip_model()->GetActiveWebContents()),
            IsDisplayingDiagnosticsLink(browser()));
}

class ErrorPageOfflineTest : public ErrorPageTest {
  void SetUpOnMainThread() override {
    url_loader_interceptor_ =
        std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
            [](content::URLLoaderInterceptor::RequestParams* params) {
              return false;
            }));
  }

  void TearDownOnMainThread() override { url_loader_interceptor_.reset(); }

 protected:
  void SetUpInProcessBrowserTestFixture() override {
#if defined(OS_CHROMEOS)
    if (enroll_) {
      // Set up fake install attributes.
      test_install_attributes_ =
          std::make_unique<chromeos::ScopedStubInstallAttributes>(
              chromeos::StubInstallAttributes::CreateCloudManaged("example.com",
                                                                  "fake-id"));
    }
#endif

    // Sets up a mock policy provider for user and device policies.
    EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_))
        .WillRepeatedly(testing::Return(true));

    policy::PolicyMap policy_map;
#if defined(OS_CHROMEOS)
    if (enroll_)
      SetEnterpriseUsersDefaults(&policy_map);
#endif
    if (set_allow_dinosaur_easter_egg_) {
      policy_map.Set(
          policy::key::kAllowDinosaurEasterEgg, policy::POLICY_LEVEL_MANDATORY,
          policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
          std::make_unique<base::Value>(value_of_allow_dinosaur_easter_egg_),
          nullptr);
    }
    policy_provider_.UpdateChromePolicy(policy_map);

#if defined(OS_CHROMEOS)
    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
        &policy_provider_);
#else
    policy::PushProfilePolicyConnectorProviderForTesting(&policy_provider_);
#endif

    ErrorPageTest::SetUpInProcessBrowserTestFixture();
  }

  std::string NavigateToPageAndReadText() {
#if defined(OS_CHROMEOS)
    // Check enterprise enrollment
    policy::BrowserPolicyConnectorChromeOS* connector =
        g_browser_process->platform_part()
        ->browser_policy_connector_chromeos();
    EXPECT_EQ(enroll_, connector->IsEnterpriseManaged());
#endif

    ui_test_utils::NavigateToURL(
        browser(),
        URLRequestFailedJob::GetMockHttpUrl(net::ERR_INTERNET_DISCONNECTED));

    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();

    std::string command = base::StringPrintf(
        "var hasText = document.querySelector('.snackbar');"
        "domAutomationController.send(hasText ? hasText.innerText : '');");

    std::string result;
    EXPECT_TRUE(
        content::ExecuteScriptAndExtractString(web_contents, command, &result));

    return result;
  }

  // Whether to set AllowDinosaurEasterEgg policy
  bool set_allow_dinosaur_easter_egg_ = false;

  // The value of AllowDinosaurEasterEgg policy we want to set
  bool value_of_allow_dinosaur_easter_egg_;

#if defined(OS_CHROMEOS)
  // Whether to enroll this CrOS device
  bool enroll_ = true;

  std::unique_ptr<chromeos::ScopedStubInstallAttributes>
      test_install_attributes_;
#endif

  // Mock policy provider for both user and device policies.
  policy::MockConfigurationPolicyProvider policy_provider_;
  std::unique_ptr<content::URLLoaderInterceptor> url_loader_interceptor_;
};

class ErrorPageOfflineTestWithAllowDinosaurTrue : public ErrorPageOfflineTest {
 protected:
  void SetUpInProcessBrowserTestFixture() override {
    set_allow_dinosaur_easter_egg_ = true;
    value_of_allow_dinosaur_easter_egg_ = true;
    ErrorPageOfflineTest::SetUpInProcessBrowserTestFixture();
  }
};

class ErrorPageOfflineTestWithAllowDinosaurFalse : public ErrorPageOfflineTest {
 protected:
  void SetUpInProcessBrowserTestFixture() override {
    set_allow_dinosaur_easter_egg_ = true;
    value_of_allow_dinosaur_easter_egg_ = false;
    ErrorPageOfflineTest::SetUpInProcessBrowserTestFixture();
  }
};

#if defined(OS_CHROMEOS)
class ErrorPageOfflineTestUnEnrolledChromeOS : public ErrorPageOfflineTest {
 protected:
  void SetUpInProcessBrowserTestFixture() override {
    set_allow_dinosaur_easter_egg_ = false;
    enroll_ = false;
    ErrorPageOfflineTest::SetUpInProcessBrowserTestFixture();
  }
};
#endif

IN_PROC_BROWSER_TEST_F(ErrorPageOfflineTestWithAllowDinosaurTrue,
                       CheckEasterEggIsAllowed) {
  std::string result = NavigateToPageAndReadText();
  EXPECT_EQ("", result);
}

IN_PROC_BROWSER_TEST_F(ErrorPageOfflineTestWithAllowDinosaurFalse,
                       CheckEasterEggIsDisabled) {
  std::string result = NavigateToPageAndReadText();
  std::string disabled_text =
      l10n_util::GetStringUTF8(IDS_ERRORPAGE_FUN_DISABLED);
  EXPECT_EQ(disabled_text, result);
}

#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(ErrorPageOfflineTest, CheckEasterEggIsDisabled) {
  std::string result = NavigateToPageAndReadText();
  std::string disabled_text =
      l10n_util::GetStringUTF8(IDS_ERRORPAGE_FUN_DISABLED);
  EXPECT_EQ(disabled_text, result);
}
#else
IN_PROC_BROWSER_TEST_F(ErrorPageOfflineTest, CheckEasterEggIsAllowed) {
  std::string result = NavigateToPageAndReadText();
  EXPECT_EQ("", result);
}
#endif

#if defined(OS_CHROMEOS)
IN_PROC_BROWSER_TEST_F(ErrorPageOfflineTestUnEnrolledChromeOS,
                       CheckEasterEggIsAllowed) {
  std::string result = NavigateToPageAndReadText();
  std::string disabled_text =
      l10n_util::GetStringUTF8(IDS_ERRORPAGE_FUN_DISABLED);
  EXPECT_EQ("", result);
}
#endif

IN_PROC_BROWSER_TEST_F(ErrorPageOfflineTestWithAllowDinosaurTrue,
                       CheckEasterEggHighScoreLoaded) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::BrowserContext* browser_context = web_contents->GetBrowserContext();
  Profile* profile = Profile::FromBrowserContext(browser_context);

  IntegerPrefMember easter_egg_high_score;
  easter_egg_high_score.Init(prefs::kNetworkEasterEggHighScore,
                             profile->GetPrefs());

  // Set a high score in the user's profile.
  int high_score = 1000;
  easter_egg_high_score.SetValue(high_score);

  std::string result = NavigateToPageAndReadText();
  EXPECT_EQ("", result);

  content::EvalJsResult actual_high_score = content::EvalJs(
      web_contents,
      "new Promise((resolve) => {"
      "  window.initializeEasterEggHighScore = function(highscore) { "
      "    resolve(highscore);"
      "  };"
      "  /* Request the initial highscore from the browser. */"
      "  errorPageController.trackEasterEgg();"
      "});");

  EXPECT_EQ(high_score, actual_high_score);
}

IN_PROC_BROWSER_TEST_F(ErrorPageOfflineTestWithAllowDinosaurTrue,
                       CheckEasterEggHighScoreSaved) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  content::BrowserContext* browser_context = web_contents->GetBrowserContext();
  Profile* profile = Profile::FromBrowserContext(browser_context);

  IntegerPrefMember easter_egg_high_score;
  easter_egg_high_score.Init(prefs::kNetworkEasterEggHighScore,
                             profile->GetPrefs());

  // The high score should be initialized to 0.
  EXPECT_EQ(0, easter_egg_high_score.GetValue());

  std::string result = NavigateToPageAndReadText();
  EXPECT_EQ("", result);

  {
    base::RunLoop run_loop;
    PrefChangeRegistrar change_observer;
    change_observer.Init(profile->GetPrefs());
    change_observer.Add(prefs::kNetworkEasterEggHighScore,
                        run_loop.QuitClosure());

    // Save a new high score.
    EXPECT_TRUE(content::ExecJs(
        web_contents, "errorPageController.updateEasterEggHighScore(2000);"));

    // Wait for preference change.
    run_loop.Run();
    EXPECT_EQ(2000, easter_egg_high_score.GetValue());
  }

  {
    base::RunLoop run_loop;
    PrefChangeRegistrar change_observer;
    change_observer.Init(profile->GetPrefs());
    change_observer.Add(prefs::kNetworkEasterEggHighScore,
                        run_loop.QuitClosure());

    // Reset high score back to 0.
    EXPECT_TRUE(content::ExecJs(
        web_contents, "errorPageController.resetEasterEggHighScore();"));

    // Wait for preference change.
    run_loop.Run();
    EXPECT_EQ(0, easter_egg_high_score.GetValue());
  }
}

// A test fixture that simulates failing requests for an IDN domain name.
class ErrorPageForIDNTest : public InProcessBrowserTest {
 public:
  // Target hostname in different forms.
  static const char kHostname[];
  static const char kHostnameJSUnicode[];

  // InProcessBrowserTest:
  void SetUpOnMainThread() override {
    // Clear AcceptLanguages to force punycode decoding.
    browser()->profile()->GetPrefs()->SetString(
        language::prefs::kAcceptLanguages, std::string());
  }
};

const char ErrorPageForIDNTest::kHostname[] =
    "xn--d1abbgf6aiiy.xn--p1ai";
const char ErrorPageForIDNTest::kHostnameJSUnicode[] =
    "\\u043f\\u0440\\u0435\\u0437\\u0438\\u0434\\u0435\\u043d\\u0442."
    "\\u0440\\u0444";

// Make sure error page shows correct unicode for IDN.
IN_PROC_BROWSER_TEST_F(ErrorPageForIDNTest, IDN) {
  // ERR_UNSAFE_PORT will not trigger navigation corrections.
  ui_test_utils::NavigateToURL(
      browser(),
      URLRequestFailedJob::GetMockHttpUrlForHostname(net::ERR_UNSAFE_PORT,
                                                     kHostname));
  EXPECT_TRUE(IsDisplayingText(browser(), kHostnameJSUnicode));
}

// Make sure HTTP/0.9 is disabled on non-default ports by default.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, Http09WeirdPort) {
  ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL("/echo-raw?spam"));
  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      browser(), net::ERR_INVALID_HTTP_RESPONSE);
}

// Test that redirects to invalid URLs show an error. See
// https://crbug.com/462272.
IN_PROC_BROWSER_TEST_F(DNSErrorPageTest, RedirectToInvalidURL) {
  GURL url = embedded_test_server()->GetURL("/server-redirect?https://:");
  ui_test_utils::NavigateToURL(browser(), url);
  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      browser(), net::ERR_INVALID_REDIRECT);
  // The error page should commit before the redirect, not after.
  EXPECT_EQ(url, browser()
                     ->tab_strip_model()
                     ->GetActiveWebContents()
                     ->GetLastCommittedURL());
}

class ErrorPageWithHttp09OnNonDefaultPortsTest : public InProcessBrowserTest {
 public:
  // InProcessBrowserTest:
  void SetUp() override {
    EXPECT_CALL(policy_provider_, IsInitializationComplete(testing::_))
        .WillRepeatedly(testing::Return(true));
    policy::PolicyMap values;
    values.Set(policy::key::kHttp09OnNonDefaultPortsEnabled,
               policy::POLICY_LEVEL_MANDATORY, policy::POLICY_SCOPE_MACHINE,
               policy::POLICY_SOURCE_CLOUD,
               base::WrapUnique(new base::Value(true)), nullptr);
    policy_provider_.UpdateChromePolicy(values);
    policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
        &policy_provider_);

    InProcessBrowserTest::SetUp();
  }

 private:
  policy::MockConfigurationPolicyProvider policy_provider_;
};

// Make sure HTTP/0.9 works on non-default ports when enabled by policy.
IN_PROC_BROWSER_TEST_F(ErrorPageWithHttp09OnNonDefaultPortsTest,
                       Http09WeirdPortEnabled) {
  const char kHttp09Response[] = "JumboShrimp";
  ASSERT_TRUE(embedded_test_server()->Start());
  ui_test_utils::NavigateToURL(
      browser(), embedded_test_server()->GetURL(std::string("/echo-raw?") +
                                                kHttp09Response));
  EXPECT_TRUE(IsDisplayingText(browser(), kHttp09Response));
}

// Checks that when an HTTP error page is sniffed as a download, an error page
// is displayed. This tests the particular case in which the response body
// is small enough that the entire response must be read before its MIME type
// can be determined.
class ErrorPageSniffTest : public InProcessBrowserTest {};

IN_PROC_BROWSER_TEST_F(ErrorPageSniffTest,
                       SniffSmallHttpErrorResponseAsDownload) {
  const char kErrorPath[] = "/foo";
  embedded_test_server()->RegisterRequestHandler(base::BindRepeating(
      &DNSErrorPageTest::Return500WithBinaryBody, kErrorPath));
  ASSERT_TRUE(embedded_test_server()->Start());

  ui_test_utils::NavigateToURL(browser(),
                               embedded_test_server()->GetURL(kErrorPath));

  ExpectDisplayingLocalErrorPage(
      embedded_test_server()->GetURL("mock.http", "/title2.html").spec(),
      browser(), net::ERR_INVALID_RESPONSE);
}

}  // namespace
