// Copyright 2013 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 <set>

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/run_loop.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/io_thread.h"
#include "chrome/browser/net/dns_probe_test_util.h"
#include "chrome/browser/net/net_error_tab_helper.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/profiles/profile.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/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/error_page/common/net_error_info.h"
#include "components/google/core/browser/google_util.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_navigation_observer.h"
#include "net/base/net_errors.h"
#include "net/dns/dns_test_util.h"
#include "net/test/url_request/url_request_failed_job.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/url_request/url_request_filter.h"
#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job.h"

using base::Bind;
using base::Callback;
using base::Closure;
using base::ConstRef;
using base::FilePath;
using base::MessageLoop;
using base::Unretained;
using chrome_common_net::DnsProbeStatus;
using content::BrowserThread;
using net::URLRequestFailedJob;
using net::URLRequestMockHTTPJob;
using content::WebContents;
using google_util::LinkDoctorBaseURL;
using net::MockDnsClientRule;
using net::NetworkDelegate;
using net::URLRequest;
using net::URLRequestFilter;
using net::URLRequestInterceptor;
using net::URLRequestJob;
using ui_test_utils::NavigateToURL;
using ui_test_utils::NavigateToURLBlockUntilNavigationsComplete;

namespace chrome_browser_net {

namespace {

// Postable function to run a Closure on the UI thread.  Since
// BrowserThread::PostTask returns a bool, it can't directly be posted to
// another thread.
void RunClosureOnUIThread(const base::Closure& closure) {
  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure);
}

// Wraps DnsProbeService and delays callbacks until someone calls
// CallDelayedCallbacks.  This allows the DnsProbeBrowserTest to enforce a
// stricter ordering of events.
class DelayingDnsProbeService : public DnsProbeService {
 public:
  DelayingDnsProbeService() {}

  ~DelayingDnsProbeService() override { EXPECT_TRUE(delayed_probes_.empty()); }

  void ProbeDns(const ProbeCallback& callback) override {
    delayed_probes_.push_back(callback);
  }

  void StartDelayedProbes() {
    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

    std::vector<ProbeCallback> probes;
    probes.swap(delayed_probes_);

    for (std::vector<ProbeCallback>::const_iterator i = probes.begin();
         i != probes.end(); ++i) {
      DnsProbeService::ProbeDns(*i);
    }
  }

  int delayed_probe_count() const {
    CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    return delayed_probes_.size();
  }

 private:
  std::vector<ProbeCallback> delayed_probes_;
};

FilePath GetMockLinkDoctorFilePath() {
  FilePath root_http;
  PathService::Get(chrome::DIR_TEST_DATA, &root_http);
  return root_http.AppendASCII("mock-link-doctor.json");
}

// A request that can be delayed until Resume() is called.  Can also run a
// callback if destroyed without being resumed.  Resume can be called either
// before or after a the request is started.
class DelayableRequest {
 public:
  // Called by a DelayableRequest if it was set to be delayed, and has been
  // destroyed without Undelay being called.
  typedef base::Callback<void(DelayableRequest* request)> DestructionCallback;

  virtual void Resume() = 0;

 protected:
  virtual ~DelayableRequest() {}
};

class DelayableURLRequestFailedJob : public URLRequestFailedJob,
                                     public DelayableRequest {
 public:
  // |destruction_callback| is only called if a delayed request is destroyed
  // without being resumed.
  DelayableURLRequestFailedJob(net::URLRequest* request,
                               net::NetworkDelegate* network_delegate,
                               int net_error,
                               bool should_delay,
                               const DestructionCallback& destruction_callback)
      : URLRequestFailedJob(request, network_delegate, net_error),
        should_delay_(should_delay),
        start_delayed_(false),
        destruction_callback_(destruction_callback) {}

  void Start() override {
    if (should_delay_) {
      DCHECK(!start_delayed_);
      start_delayed_ = true;
      return;
    }
    URLRequestFailedJob::Start();
  }

  void Resume() override {
    DCHECK(should_delay_);
    should_delay_ = false;
    if (start_delayed_) {
      start_delayed_ = false;
      Start();
    }
  }

 private:
  ~DelayableURLRequestFailedJob() override {
    if (should_delay_)
      destruction_callback_.Run(this);
  }

  bool should_delay_;
  bool start_delayed_;
  const DestructionCallback destruction_callback_;
};

class DelayableURLRequestMockHTTPJob : public URLRequestMockHTTPJob,
                                       public DelayableRequest {
 public:
  DelayableURLRequestMockHTTPJob(
      net::URLRequest* request,
      net::NetworkDelegate* network_delegate,
      const base::FilePath& file_path,
      bool should_delay,
      const DestructionCallback& destruction_callback)
      : URLRequestMockHTTPJob(
            request,
            network_delegate,
            file_path,
            BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
                base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)),
        should_delay_(should_delay),
        start_delayed_(false),
        destruction_callback_(destruction_callback) {}

  void Start() override {
    if (should_delay_) {
      DCHECK(!start_delayed_);
      start_delayed_ = true;
      return;
    }
    URLRequestMockHTTPJob::Start();
  }

  void Resume() override {
    DCHECK(should_delay_);
    should_delay_ = false;
    if (start_delayed_) {
      start_delayed_ = false;
      Start();
    }
  }

 private:
  ~DelayableURLRequestMockHTTPJob() override {
    if (should_delay_)
      destruction_callback_.Run(this);
  }

  bool should_delay_;
  bool start_delayed_;
  const DestructionCallback destruction_callback_;
};

// Interceptor for navigation correction requests.  Can cause requests to
// fail with an error, and/or delay a request until a test allows to continue.
// Also can run a callback when a delayed request is cancelled.
class BreakableCorrectionInterceptor : public URLRequestInterceptor {
 public:
  explicit BreakableCorrectionInterceptor(
      const FilePath& mock_corrections_file_path)
      : mock_corrections_file_path_(mock_corrections_file_path),
        net_error_(net::OK),
        delay_requests_(false),
        on_request_destroyed_callback_(
            base::Bind(&BreakableCorrectionInterceptor::OnRequestDestroyed,
                       base::Unretained(this))) {
  }

  ~BreakableCorrectionInterceptor() override {
    // All delayed requests should have been resumed or cancelled by this point.
    EXPECT_TRUE(delayed_requests_.empty());
  }

  URLRequestJob* MaybeInterceptRequest(
      URLRequest* request,
      NetworkDelegate* network_delegate) const override {
    if (net_error_ != net::OK) {
      DelayableURLRequestFailedJob* job =
          new DelayableURLRequestFailedJob(
              request, network_delegate, net_error_, delay_requests_,
              on_request_destroyed_callback_);
      if (delay_requests_)
        delayed_requests_.insert(job);
      return job;
    } else {
      DelayableURLRequestMockHTTPJob* job =
          new DelayableURLRequestMockHTTPJob(
              request, network_delegate, mock_corrections_file_path_,
              delay_requests_, on_request_destroyed_callback_);
      if (delay_requests_)
        delayed_requests_.insert(job);
      return job;
    }
  }

  void set_net_error(int net_error) { net_error_ = net_error; }

  void SetDelayRequests(bool delay_requests) {
    delay_requests_ = delay_requests;

    // Resume all delayed requests if no longer delaying requests.
    if (!delay_requests) {
      while (!delayed_requests_.empty()) {
        DelayableRequest* request = *delayed_requests_.begin();
        delayed_requests_.erase(request);
        request->Resume();
      }
    }
  }

  // Runs |callback| once all delayed requests have been destroyed.  Does not
  // wait for delayed requests that have been resumed.
  void SetRequestDestructionCallback(const base::Closure& callback) {
    ASSERT_TRUE(delayed_request_destruction_callback_.is_null());
    if (delayed_requests_.empty()) {
      callback.Run();
      return;
    }
    delayed_request_destruction_callback_ = callback;
  }

  void OnRequestDestroyed(DelayableRequest* request) {
    ASSERT_EQ(1u, delayed_requests_.count(request));
    delayed_requests_.erase(request);
    if (delayed_requests_.empty() &&
        !delayed_request_destruction_callback_.is_null()) {
      delayed_request_destruction_callback_.Run();
      delayed_request_destruction_callback_.Reset();
    }
  }

 private:
  const FilePath mock_corrections_file_path_;
  int net_error_;
  bool delay_requests_;

  // Called when a request is destroyed.  Memeber variable because
  // MaybeCreateJob is "const", so calling base::Bind in that function does
  // not work well.
  const DelayableRequest::DestructionCallback on_request_destroyed_callback_;

  // Mutable is needed because MaybeCreateJob is const.
  mutable std::set<DelayableRequest*> delayed_requests_;

  base::Closure delayed_request_destruction_callback_;
};

class DnsProbeBrowserTestIOThreadHelper {
 public:
  DnsProbeBrowserTestIOThreadHelper();

  void SetUpOnIOThread(IOThread* io_thread);
  void CleanUpOnIOThreadAndDeleteHelper();

  void SetMockDnsClientRules(MockDnsClientRule::Result system_good_result,
                             MockDnsClientRule::Result public_good_result);
  void SetCorrectionServiceNetError(int net_error);
  void SetCorrectionServiceDelayRequests(bool delay_requests);
  void SetRequestDestructionCallback(const base::Closure& callback);
  void StartDelayedProbes(int expected_delayed_probe_count);

 private:
  IOThread* io_thread_;
  DnsProbeService* original_dns_probe_service_;
  DelayingDnsProbeService* delaying_dns_probe_service_;
  BreakableCorrectionInterceptor* interceptor_;
  FilePath mock_corrections_file_path_;
};

DnsProbeBrowserTestIOThreadHelper::DnsProbeBrowserTestIOThreadHelper()
    : io_thread_(NULL),
      original_dns_probe_service_(NULL),
      delaying_dns_probe_service_(NULL),
      interceptor_(NULL),
      mock_corrections_file_path_(GetMockLinkDoctorFilePath()) {}

void DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread(IOThread* io_thread) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  CHECK(io_thread);
  CHECK(!io_thread_);
  CHECK(!original_dns_probe_service_);
  CHECK(!delaying_dns_probe_service_);
  CHECK(!interceptor_);

  io_thread_ = io_thread;

  delaying_dns_probe_service_ = new DelayingDnsProbeService();

  IOThread::Globals* globals = io_thread_->globals();
  original_dns_probe_service_ = globals->dns_probe_service.release();
  globals->dns_probe_service.reset(delaying_dns_probe_service_);

  URLRequestFailedJob::AddUrlHandler();

  interceptor_ =
      new BreakableCorrectionInterceptor(mock_corrections_file_path_);
  URLRequestFilter::GetInstance()->AddUrlInterceptor(
      LinkDoctorBaseURL(), scoped_ptr<URLRequestInterceptor>(interceptor_));
}

void DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper() {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  URLRequestFilter::GetInstance()->ClearHandlers();

  IOThread::Globals* globals = io_thread_->globals();
  scoped_ptr<DnsProbeService> delaying_dns_probe_service(
      globals->dns_probe_service.release());
  globals->dns_probe_service.reset(original_dns_probe_service_);

  CHECK_EQ(delaying_dns_probe_service_, delaying_dns_probe_service.get());

  delete this;
}

void DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules(
    MockDnsClientRule::Result system_result,
    MockDnsClientRule::Result public_result) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  DnsProbeService* service = io_thread_->globals()->dns_probe_service.get();
  service->SetSystemClientForTesting(
      CreateMockDnsClientForProbes(system_result));
  service->SetPublicClientForTesting(
      CreateMockDnsClientForProbes(public_result));
}

void DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceNetError(
    int net_error) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  interceptor_->set_net_error(net_error);
}

void DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceDelayRequests(
    bool delay_requests) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  interceptor_->SetDelayRequests(delay_requests);
}

void DnsProbeBrowserTestIOThreadHelper::SetRequestDestructionCallback(
    const base::Closure& callback) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  interceptor_->SetRequestDestructionCallback(callback);
}

void DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes(
    int expected_delayed_probe_count) {
  CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));

  CHECK(delaying_dns_probe_service_);

  int actual_delayed_probe_count =
      delaying_dns_probe_service_->delayed_probe_count();
  EXPECT_EQ(expected_delayed_probe_count, actual_delayed_probe_count);

  delaying_dns_probe_service_->StartDelayedProbes();
}

class DnsProbeBrowserTest : public InProcessBrowserTest {
 public:
  DnsProbeBrowserTest();
  ~DnsProbeBrowserTest() override;

  void SetUpOnMainThread() override;
  void TearDownOnMainThread() override;

 protected:
  // Sets the browser object that other methods apply to, and that has the
  // DnsProbeStatus messages of its currently active tab monitored.
  void SetActiveBrowser(Browser* browser);

  void SetCorrectionServiceBroken(bool broken);
  void SetCorrectionServiceDelayRequests(bool delay_requests);
  void WaitForDelayedRequestDestruction();
  void SetMockDnsClientRules(MockDnsClientRule::Result system_result,
                             MockDnsClientRule::Result public_result);

  // These functions are often used to wait for two navigations because two
  // pages are loaded when navigation corrections are enabled: a blank page, so
  // the user stops seeing the previous page, and then the error page, either
  // with navigation corrections or without them (If the request failed).
  void NavigateToDnsError(int num_navigations);
  void NavigateToOtherError(int num_navigations);

  void StartDelayedProbes(int expected_delayed_probe_count);
  DnsProbeStatus WaitForSentStatus();
  int pending_status_count() const { return dns_probe_status_queue_.size(); }

  std::string Title();
  bool PageContains(const std::string& expected);

  // Checks that the local error page is being displayed, without navigation
  // corrections, and with the specified status text.  The status text should be
  // either a network error or DNS probe status.
  void ExpectDisplayingLocalErrorPage(const std::string& status_text);

  // Checks that an error page with mock navigation corrections is being
  // displayed, with the specified status text. The status text should be either
  // a network error or DNS probe status.
  void ExpectDisplayingCorrections(const std::string& status_text);

 private:
  void OnDnsProbeStatusSent(DnsProbeStatus dns_probe_status);

  DnsProbeBrowserTestIOThreadHelper* helper_;

  // Browser that methods apply to.
  Browser* active_browser_;
  // Helper that current has its DnsProbeStatus messages monitored.
  NetErrorTabHelper* monitored_tab_helper_;

  bool awaiting_dns_probe_status_;
  // Queue of statuses received but not yet consumed by WaitForSentStatus().
  std::list<DnsProbeStatus> dns_probe_status_queue_;
};

DnsProbeBrowserTest::DnsProbeBrowserTest()
    : helper_(new DnsProbeBrowserTestIOThreadHelper()),
      active_browser_(NULL),
      monitored_tab_helper_(NULL),
      awaiting_dns_probe_status_(false) {
}

DnsProbeBrowserTest::~DnsProbeBrowserTest() {
  // No tests should have any unconsumed probe statuses.
  EXPECT_EQ(0, pending_status_count());
}

void DnsProbeBrowserTest::SetUpOnMainThread() {
  NetErrorTabHelper::set_state_for_testing(
      NetErrorTabHelper::TESTING_DEFAULT);

  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kAlternateErrorPagesEnabled, true);

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      Bind(&DnsProbeBrowserTestIOThreadHelper::SetUpOnIOThread,
           Unretained(helper_),
           g_browser_process->io_thread()));

  SetActiveBrowser(browser());
}

void DnsProbeBrowserTest::TearDownOnMainThread() {
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      Bind(&DnsProbeBrowserTestIOThreadHelper::CleanUpOnIOThreadAndDeleteHelper,
           Unretained(helper_)));

  NetErrorTabHelper::set_state_for_testing(
      NetErrorTabHelper::TESTING_DEFAULT);
}

void DnsProbeBrowserTest::SetActiveBrowser(Browser* browser) {
  // If currently watching a NetErrorTabHelper, stop doing so before start
  // watching another.
  if (monitored_tab_helper_) {
    monitored_tab_helper_->set_dns_probe_status_snoop_callback_for_testing(
        NetErrorTabHelper::DnsProbeStatusSnoopCallback());
  }
  active_browser_ = browser;
  monitored_tab_helper_ = NetErrorTabHelper::FromWebContents(
      active_browser_->tab_strip_model()->GetActiveWebContents());
  monitored_tab_helper_->set_dns_probe_status_snoop_callback_for_testing(
      Bind(&DnsProbeBrowserTest::OnDnsProbeStatusSent, Unretained(this)));
}

void DnsProbeBrowserTest::SetCorrectionServiceBroken(bool broken) {
  int net_error = broken ? net::ERR_NAME_NOT_RESOLVED : net::OK;

  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      Bind(&DnsProbeBrowserTestIOThreadHelper::SetCorrectionServiceNetError,
           Unretained(helper_),
           net_error));
}

void DnsProbeBrowserTest::SetCorrectionServiceDelayRequests(
    bool delay_requests) {
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      Bind(&DnsProbeBrowserTestIOThreadHelper::
               SetCorrectionServiceDelayRequests,
           Unretained(helper_),
           delay_requests));
}

void DnsProbeBrowserTest::WaitForDelayedRequestDestruction() {
  base::RunLoop run_loop;
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      Bind(&DnsProbeBrowserTestIOThreadHelper::SetRequestDestructionCallback,
           Unretained(helper_),
           base::Bind(&RunClosureOnUIThread,
                      run_loop.QuitClosure())));
  run_loop.Run();
}

void DnsProbeBrowserTest::NavigateToDnsError(int num_navigations) {
  NavigateToURLBlockUntilNavigationsComplete(
      active_browser_,
      URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED),
      num_navigations);
}

void DnsProbeBrowserTest::NavigateToOtherError(int num_navigations) {
  NavigateToURLBlockUntilNavigationsComplete(
      active_browser_,
      URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_REFUSED),
      num_navigations);
}

void DnsProbeBrowserTest::SetMockDnsClientRules(
    MockDnsClientRule::Result system_result,
    MockDnsClientRule::Result public_result) {
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      Bind(&DnsProbeBrowserTestIOThreadHelper::SetMockDnsClientRules,
           Unretained(helper_),
           system_result,
           public_result));
}

void DnsProbeBrowserTest::StartDelayedProbes(
    int expected_delayed_probe_count) {
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      Bind(&DnsProbeBrowserTestIOThreadHelper::StartDelayedProbes,
           Unretained(helper_),
           expected_delayed_probe_count));
}

DnsProbeStatus DnsProbeBrowserTest::WaitForSentStatus() {
  CHECK(!awaiting_dns_probe_status_);
  while (dns_probe_status_queue_.empty()) {
    awaiting_dns_probe_status_ = true;
    MessageLoop::current()->Run();
    awaiting_dns_probe_status_ = false;
  }

  CHECK(!dns_probe_status_queue_.empty());
  DnsProbeStatus status = dns_probe_status_queue_.front();
  dns_probe_status_queue_.pop_front();
  return status;
}

// Check title by roundtripping to renderer, to make sure any probe results
// sent before this have been applied.
std::string DnsProbeBrowserTest::Title() {
  std::string title;

  WebContents* contents =
      active_browser_->tab_strip_model()->GetActiveWebContents();

  bool rv = content::ExecuteScriptAndExtractString(
      contents,
      "domAutomationController.send(document.title);",
      &title);
  if (!rv)
    return "";

  return title;
}

// Check text by roundtripping to renderer, to make sure any probe results
// sent before this have been applied.
bool DnsProbeBrowserTest::PageContains(const std::string& expected) {
  std::string text_content;

  bool rv = content::ExecuteScriptAndExtractString(
      active_browser_->tab_strip_model()->GetActiveWebContents(),
      "domAutomationController.send(document.body.textContent);",
      &text_content);
  if (!rv)
    return false;

  return text_content.find(expected) != std::string::npos;
}

void DnsProbeBrowserTest::ExpectDisplayingLocalErrorPage(
    const std::string& status_text) {
  EXPECT_FALSE(PageContains("http://correction1/"));
  EXPECT_FALSE(PageContains("http://correction2/"));
  EXPECT_TRUE(PageContains(status_text));
}

void DnsProbeBrowserTest::ExpectDisplayingCorrections(
    const std::string& status_text) {
  EXPECT_TRUE(PageContains("http://correction1/"));
  EXPECT_TRUE(PageContains("http://correction2/"));
  EXPECT_TRUE(PageContains(status_text));
}

void DnsProbeBrowserTest::OnDnsProbeStatusSent(
    DnsProbeStatus dns_probe_status) {
  dns_probe_status_queue_.push_back(dns_probe_status);
  if (awaiting_dns_probe_status_)
    MessageLoop::current()->Quit();
}

// Make sure probes don't break non-DNS error pages when corrections load.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, OtherErrorWithCorrectionsSuccess) {
  SetCorrectionServiceBroken(false);

  NavigateToOtherError(2);
  ExpectDisplayingCorrections("ERR_CONNECTION_REFUSED");
}

// Make sure probes don't break non-DNS error pages when corrections failed to
// load.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, OtherErrorWithCorrectionsFailure) {
  SetCorrectionServiceBroken(true);

  NavigateToOtherError(2);
  ExpectDisplayingLocalErrorPage("ERR_CONNECTION_REFUSED");
}

// Make sure probes don't break DNS error pages when corrections load.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
                       NxdomainProbeResultWithWorkingCorrections) {
  SetCorrectionServiceBroken(false);
  SetMockDnsClientRules(MockDnsClientRule::OK, MockDnsClientRule::OK);

  NavigateToDnsError(2);
  ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");

  // One status for committing a blank page before the corrections, and one for
  // when the error page with corrections is committed.
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");

  StartDelayedProbes(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN,
            WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");
}

// Make sure probes don't break corrections when probes complete before the
// corrections load.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
                       NxdomainProbeResultWithWorkingSlowCorrections) {
  SetCorrectionServiceBroken(false);
  SetCorrectionServiceDelayRequests(true);
  SetMockDnsClientRules(MockDnsClientRule::OK, MockDnsClientRule::OK);

  NavigateToDnsError(1);
  // A blank page should be displayed while the corrections are loaded.
  EXPECT_EQ("", Title());

  // A single probe should be triggered by the error page load, and it should
  // be ignored.
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  EXPECT_EQ("", Title());

  StartDelayedProbes(1);
  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN,
            WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  EXPECT_EQ("", Title());

  content::TestNavigationObserver observer(
      browser()->tab_strip_model()->GetActiveWebContents(), 1);
  // The corrections finish loading.
  SetCorrectionServiceDelayRequests(false);
  // Wait for it to commit.
  observer.Wait();
  ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");

  // Committing the corections page should trigger sending the probe result
  // again.
  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NXDOMAIN,
            WaitForSentStatus());
  ExpectDisplayingCorrections("ERR_NAME_NOT_RESOLVED");
}

// Make sure probes update DNS error page properly when they're supposed to.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
                       NoInternetProbeResultWithBrokenCorrections) {
  SetCorrectionServiceBroken(true);
  SetMockDnsClientRules(MockDnsClientRule::TIMEOUT,
                        MockDnsClientRule::TIMEOUT);

  NavigateToDnsError(2);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
            WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("DNS_PROBE_FINISHED_NO_INTERNET");
}

// Make sure probes don't break corrections when probes complete before the
// corrections request returns an error.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest,
                       NoInternetProbeResultWithSlowBrokenCorrections) {
  SetCorrectionServiceBroken(true);
  SetCorrectionServiceDelayRequests(true);
  SetMockDnsClientRules(MockDnsClientRule::TIMEOUT,
                        MockDnsClientRule::TIMEOUT);

  NavigateToDnsError(1);
  // A blank page should be displayed while the corrections load.
  EXPECT_EQ("", Title());

  // A single probe should be triggered by the error page load, and it should
  // be ignored.
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  EXPECT_EQ("", Title());

  StartDelayedProbes(1);
  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
            WaitForSentStatus());
  EXPECT_EQ("", Title());
  EXPECT_EQ(0, pending_status_count());

  content::TestNavigationObserver observer(
      browser()->tab_strip_model()->GetActiveWebContents(), 1);
  // The corrections request fails.
  SetCorrectionServiceDelayRequests(false);
  // Wait for the DNS error page to load instead.
  observer.Wait();
  // The page committing should result in sending the probe results again.
  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
            WaitForSentStatus());

  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("DNS_PROBE_FINISHED_NO_INTERNET");
}

// Double-check to make sure sync failures don't explode.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, SyncFailureWithBrokenCorrections) {
  SetCorrectionServiceBroken(true);
  SetMockDnsClientRules(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL);

  NavigateToDnsError(2);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE,
            WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
  EXPECT_EQ(0, pending_status_count());
}

// Test that pressing the stop button cancels loading corrections.
// TODO(mmenke):  Add a test for the cross process navigation case.
// TODO(mmenke):  This test could flakily pass due to the timeout on downloading
//                the corrections.  Disable that timeout for browser tests.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, CorrectionsLoadStopped) {
  SetCorrectionServiceDelayRequests(true);
  SetCorrectionServiceBroken(true);
  SetMockDnsClientRules(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT);

  NavigateToDnsError(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());
  StartDelayedProbes(1);
  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
            WaitForSentStatus());

  EXPECT_EQ("", Title());
  EXPECT_EQ(0, pending_status_count());

  chrome::Stop(browser());
  WaitForDelayedRequestDestruction();

  // End up displaying a blank page.
  EXPECT_EQ("", Title());
}

// Test that pressing the stop button cancels the load of corrections, and
// receiving a probe result afterwards does not swap in a DNS error page.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, CorrectionsLoadStoppedSlowProbe) {
  SetCorrectionServiceDelayRequests(true);
  SetCorrectionServiceBroken(true);
  SetMockDnsClientRules(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT);

  NavigateToDnsError(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());

  EXPECT_EQ("", Title());
  EXPECT_EQ(0, pending_status_count());

  chrome::Stop(browser());
  WaitForDelayedRequestDestruction();

  EXPECT_EQ("", Title());
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);
  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_NO_INTERNET,
            WaitForSentStatus());

  EXPECT_EQ("", Title());
}

// Make sure probes don't run for subframe DNS errors.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, NoProbeInSubframe) {
  SetCorrectionServiceBroken(false);

  const FilePath::CharType kIframeDnsErrorHtmlName[] =
      FILE_PATH_LITERAL("iframe_dns_error.html");

  NavigateToURL(
      browser(),
      URLRequestMockHTTPJob::GetMockUrl(FilePath(kIframeDnsErrorHtmlName)));

  // By the time NavigateToURL returns, the browser will have seen the failed
  // provisional load.  If a probe was started (or considered but not run),
  // then the NetErrorTabHelper would have sent a NetErrorInfo message.  Thus,
  // if one hasn't been sent by now, the NetErrorTabHelper has not (and won't)
  // start a probe for this DNS error.
  EXPECT_EQ(0, pending_status_count());
}

// Make sure browser sends NOT_RUN properly when probes are disabled.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, ProbesDisabled) {
  // Disable probes (And corrections).
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kAlternateErrorPagesEnabled, false);

  SetCorrectionServiceBroken(true);
  SetMockDnsClientRules(MockDnsClientRule::TIMEOUT, MockDnsClientRule::TIMEOUT);

  NavigateToDnsError(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_NOT_RUN, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
}

// Test the case that corrections are disabled, but DNS probes are enabled.
// This is the case with Chromium builds.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, CorrectionsDisabled) {
  // Disable corrections.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kAlternateErrorPagesEnabled, false);
  // Requests to the correction service should work if any are made, so the test
  // fails if that happens unexpectedly.
  SetCorrectionServiceBroken(false);
  // Normally disabling corrections disables DNS probes, so force DNS probes
  // to be enabled.
  NetErrorTabHelper::set_state_for_testing(
      NetErrorTabHelper::TESTING_FORCE_ENABLED);

  SetMockDnsClientRules(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL);

  // Just one commit and one sent status, since corrections are disabled.
  NavigateToDnsError(1);
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE,
            WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
}

// Test incognito mode.  Corrections should be disabled, but DNS probes are
// still enabled.
IN_PROC_BROWSER_TEST_F(DnsProbeBrowserTest, Incognito) {
  // Requests to the correction service should work if any are made, so the test
  // will fail if one is requested unexpectedly.
  SetCorrectionServiceBroken(false);

  Browser* incognito = CreateIncognitoBrowser();
  SetActiveBrowser(incognito);

  SetMockDnsClientRules(MockDnsClientRule::FAIL, MockDnsClientRule::FAIL);

  // Just one commit and one sent status, since the corrections are disabled.
  NavigateToDnsError(1);
  EXPECT_EQ(chrome_common_net::DNS_PROBE_STARTED, WaitForSentStatus());

  // Checking the page runs the RunLoop, so make sure nothing hairy happens.
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("DNS_PROBE_STARTED");
  EXPECT_EQ(0, pending_status_count());

  StartDelayedProbes(1);

  EXPECT_EQ(chrome_common_net::DNS_PROBE_FINISHED_INCONCLUSIVE,
            WaitForSentStatus());
  EXPECT_EQ(0, pending_status_count());
  ExpectDisplayingLocalErrorPage("ERR_NAME_NOT_RESOLVED");
}

}  // namespace

}  // namespace chrome_browser_net
