15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_service.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_service_factory.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/url_request_mock_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_types.h"
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/render_frame_host.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/transport_security_state.h"
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/test/url_request/url_request_failed_job.h"
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/test/url_request/url_request_mock_http_job.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_filter.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuusing captive_portal::CaptivePortalResult;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::WebContents;
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing net::URLRequestFailedJob;
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing net::URLRequestMockHTTPJob;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Path of the fake login page, when using the TestServer.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kTestServerLoginPath = "files/captive_portal/login.html";
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Path of a page with an iframe that has a mock SSL timeout, when using the
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TestServer.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kTestServerIframeTimeoutPath =
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "files/captive_portal/iframe_timeout.html";
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following URLs each have two different behaviors, depending on whether
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLRequestMockCaptivePortalJobFactory is currently simulating the presence
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of a captive portal or not.  They use different domains so that HSTS can be
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// applied to them independently.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A mock URL for the CaptivePortalService's |test_url|.  When behind a captive
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// portal, this URL returns a mock login page.  When connected to the Internet,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it returns a 204 response.  Uses the name of the login file so that reloading
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it will not request a different URL.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kMockCaptivePortalTestUrl =
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://mock.captive.portal.test/login.html";
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Another mock URL for the CaptivePortalService's |test_url|.  When behind a
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// captive portal, this URL returns a 511 status code and an HTML page that
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// redirect to the above URL.  When connected to the Internet, it returns a 204
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// response.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kMockCaptivePortal511Url =
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "http://mock.captive.portal.511/page511.html";
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When behind a captive portal, this URL hangs without committing until a call
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to URLRequestTimeoutOnDemandJob::FailJobs.  When that function is called,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the request will time out.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When connected to the Internet, this URL returns a non-error page.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kMockHttpsUrl =
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "https://mock.captive.portal.long.timeout/title2.html";
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as above, but different domain, so can be used to trigger cross-site
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigations.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kMockHttpsUrl2 =
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "https://mock.captive.portal.long.timeout2/title2.html";
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as kMockHttpsUrl, except the timeout happens instantly.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kMockHttpsQuickTimeoutUrl =
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "https://mock.captive.portal.quick.timeout/title2.html";
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Expected title of a tab once an HTTPS load completes, when not behind a
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// captive portal.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kInternetConnectedTitle = "Title Of Awesomeness";
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A URL request job that hangs until FailJobs() is called.  Started jobs
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are stored in a static class variable containing a linked list so that
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FailJobs() can locate them.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestTimeoutOnDemandJob : public net::URLRequestJob,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     public base::NonThreadSafe {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // net::URLRequestJob:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Start() OVERRIDE;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All the public static methods below can be called on any thread.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Waits for exactly |num_jobs|.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WaitForJobs(int num_jobs);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fails all active URLRequestTimeoutOnDemandJobs with connection timeouts.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are expected to be exactly |expected_num_jobs| waiting for
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // failure.  The only way to gaurantee this is with an earlier call to
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WaitForJobs, so makes sure there has been a matching WaitForJobs call.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void FailJobs(int expected_num_jobs);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Abandon all active URLRequestTimeoutOnDemandJobs.  |expected_num_jobs|
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // behaves just as in FailJobs.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AbandonJobs(int expected_num_jobs);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class URLRequestMockCaptivePortalJobFactory;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Operation to perform on jobs when removing them from |job_list_|.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum EndJobOperation {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FAIL_JOBS,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ABANDON_JOBS,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob(net::URLRequest* request,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               net::NetworkDelegate* network_delegate);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~URLRequestTimeoutOnDemandJob();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Attempts to removes |this| from |jobs_|.  Returns true if it was removed
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the list.
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool RemoveFromList();
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void WaitForJobsOnIOThread(int num_jobs);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void FailOrAbandonJobsOnIOThread(
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int expected_num_jobs,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EndJobOperation end_job_operation);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks if there are at least |num_jobs_to_wait_for_| jobs in
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |job_list_|.  If so, exits the message loop on the UI thread, which
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be spinning in a call to WaitForJobs.  Does nothing when
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |num_jobs_to_wait_for_| is 0.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void MaybeStopWaitingForJobsOnIOThread();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All class variables are only accessed on the IO thread.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of jobs currently being waited for, or 0 if not currently
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // waiting for jobs.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int num_jobs_to_wait_for_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The last number of jobs that were waited for.  When FailJobs or
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AbandonJobs is called, this should match |expected_num_jobs|.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int last_num_jobs_to_wait_for_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of jobs that have been started, but not yet waited for.  If jobs
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are deleted unexpectedly, they're still included in this count, even though
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // they've been removed from |job_list_|.  Intended to reduce chance of stalls
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on regressions.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int num_jobs_started_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Head of linked list of jobs that have been started and are now waiting to
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be timed out.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static URLRequestTimeoutOnDemandJob* job_list_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The next job that had been started but not yet timed out.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob* next_job_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(URLRequestTimeoutOnDemandJob);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestTimeoutOnDemandJob::num_jobs_to_wait_for_ = 0;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestTimeoutOnDemandJob::last_num_jobs_to_wait_for_ = 0;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int URLRequestTimeoutOnDemandJob::num_jobs_started_ = 0;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestTimeoutOnDemandJob* URLRequestTimeoutOnDemandJob::job_list_ = NULL;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestTimeoutOnDemandJob::Start() {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(CalledOnValidThread());
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Insert at start of the list.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  next_job_ = job_list_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  job_list_ = this;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_jobs_started_;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks if there are at least |num_jobs_to_wait_for_| jobs in
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |job_list_|.  If so, exits the message loop on the UI thread, which
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be spinning in a call to WaitForJobs.  Does nothing if
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |num_jobs_to_wait_for_| is 0.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MaybeStopWaitingForJobsOnIOThread();
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestTimeoutOnDemandJob::WaitForJobs(int num_jobs) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 num_jobs));
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RunMessageLoop();
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 expected_num_jobs,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 FAIL_JOBS));
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 expected_num_jobs,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ABANDON_JOBS));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request, net::NetworkDelegate* network_delegate)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : net::URLRequestJob(request, network_delegate),
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_job_(NULL) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestTimeoutOnDemandJob::~URLRequestTimeoutOnDemandJob() {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All hanging jobs should have failed or been abandoned before being
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // destroyed.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RemoveFromList());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestTimeoutOnDemandJob::RemoveFromList() {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob** job = &job_list_;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (*job) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (*job == this) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *job = next_job_;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      next_job_ = NULL;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    job = &next_job_;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the job wasn't in this list, |next_job_| should be NULL.
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(next_job_);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread(int num_jobs) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, num_jobs_to_wait_for_);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LT(0, num_jobs);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of tabs being waited on should be strictly increasing.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LE(last_num_jobs_to_wait_for_, num_jobs);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  num_jobs_to_wait_for_ = num_jobs;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MaybeStopWaitingForJobsOnIOThread();
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestTimeoutOnDemandJob::MaybeStopWaitingForJobsOnIOThread() {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_jobs_to_wait_for_ == 0)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There shouldn't be any extra jobs.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(num_jobs_started_, num_jobs_to_wait_for_);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should never be greater, but if it is, go ahead and exit the message loop
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to try and avoid hanging.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_jobs_started_ >= num_jobs_to_wait_for_) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_num_jobs_to_wait_for_ = num_jobs_to_wait_for_;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    num_jobs_to_wait_for_ = 0;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                            base::MessageLoop::QuitClosure());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread(
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_num_jobs,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EndJobOperation end_job_operation) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_LT(0, expected_num_jobs);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(last_num_jobs_to_wait_for_, expected_num_jobs);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_num_jobs_to_wait_for_ = 0;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_jobs = 0;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (job_list_) {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++num_jobs;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLRequestTimeoutOnDemandJob* job = job_list_;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Since the error notification may result in the job's destruction, remove
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it from the job list before the error.
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(job->RemoveFromList());
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end_job_operation == FAIL_JOBS) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      job->NotifyStartError(net::URLRequestStatus(
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                net::URLRequestStatus::FAILED,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                net::ERR_CONNECTION_TIMED_OUT));
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_num_jobs, num_jobs_started_);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_num_jobs, num_jobs);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  num_jobs_started_ -= expected_num_jobs;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLRequestCaptivePortalJobFactory emulates captive portal behavior.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initially, it emulates being behind a captive portal.  When
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SetBehindCaptivePortal(false) is called, it emulates behavior when not behind
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a captive portal.  The class itself is never instantiated.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It handles requests for kMockCaptivePortalTestUrl, kMockHttpsUrl, and
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// kMockHttpsQuickTimeoutUrl.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestMockCaptivePortalJobFactory {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The public static methods below can be called on any thread.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adds the testing URLs to the net::URLRequestFilter.  Should only be called
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // once.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddUrlHandlers();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets whether or not there is a captive portal.  Outstanding requests are
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not affected.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetBehindCaptivePortal(bool behind_captive_portal);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These do all the work of the corresponding public functions, with the only
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // difference being that they must be called on the IO thread.
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void AddUrlHandlersOnIOThread();
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetBehindCaptivePortalOnIOThread(bool behind_captive_portal);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns a URLRequestJob that reflects the current captive portal state
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for the URLs: kMockCaptivePortalTestUrl, kMockHttpsUrl, and
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kMockHttpsQuickTimeoutUrl.  See documentation of individual URLs for
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // actual behavior.
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static net::URLRequestJob* Factory(net::URLRequest* request,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     net::NetworkDelegate* network_delegate,
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const std::string& scheme);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool behind_captive_portal_;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_IMPLICIT_CONSTRUCTORS(URLRequestMockCaptivePortalJobFactory);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestMockCaptivePortalJobFactory::behind_captive_portal_ = true;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestMockCaptivePortalJobFactory::AddUrlHandlers() {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool behind_captive_portal) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &URLRequestMockCaptivePortalJobFactory::
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              SetBehindCaptivePortalOnIOThread,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          behind_captive_portal));
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handle only exact matches, so any related requests, such as those for
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // favicons, are not handled by the factory.
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter->AddUrlHandler(GURL(kMockCaptivePortalTestUrl),
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        URLRequestMockCaptivePortalJobFactory::Factory);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter->AddUrlHandler(GURL(kMockCaptivePortal511Url),
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        URLRequestMockCaptivePortalJobFactory::Factory);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter->AddUrlHandler(GURL(kMockHttpsUrl),
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        URLRequestMockCaptivePortalJobFactory::Factory);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter->AddUrlHandler(GURL(kMockHttpsUrl2),
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        URLRequestMockCaptivePortalJobFactory::Factory);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  filter->AddUrlHandler(GURL(kMockHttpsQuickTimeoutUrl),
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        URLRequestMockCaptivePortalJobFactory::Factory);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool behind_captive_portal) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  behind_captive_portal_ = behind_captive_portal;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJob* URLRequestMockCaptivePortalJobFactory::Factory(
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::URLRequest* request,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::NetworkDelegate* network_delegate,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& scheme) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The PathService is threadsafe.
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath root_http;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::DIR_TEST_DATA, &root_http);
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (request->url() == GURL(kMockHttpsUrl) ||
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      request->url() == GURL(kMockHttpsUrl2)) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (behind_captive_portal_)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return new URLRequestTimeoutOnDemandJob(request, network_delegate);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once logged in to the portal, HTTPS requests return the page that was
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // actually requested.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new URLRequestMockHTTPJob(
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request,
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        network_delegate,
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        root_http.Append(FILE_PATH_LITERAL("title2.html")),
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (request->url() == GURL(kMockHttpsQuickTimeoutUrl)) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (behind_captive_portal_)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return new URLRequestFailedJob(
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          request, network_delegate, net::ERR_CONNECTION_TIMED_OUT);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Once logged in to the portal, HTTPS requests return the page that was
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // actually requested.
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new URLRequestMockHTTPJob(
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        network_delegate,
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        root_http.Append(FILE_PATH_LITERAL("title2.html")),
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The URL should be the captive portal test URL.
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(GURL(kMockCaptivePortalTestUrl) == request->url() ||
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                GURL(kMockCaptivePortal511Url) == request->url());
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (behind_captive_portal_) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Prior to logging in to the portal, the HTTP test URLs are intercepted
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // by the captive portal.
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (GURL(kMockCaptivePortal511Url) == request->url()) {
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return new URLRequestMockHTTPJob(
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            network_delegate,
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            root_http.Append(FILE_PATH_LITERAL("captive_portal/page511.html")),
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return new URLRequestMockHTTPJob(
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          request,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          network_delegate,
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          root_http.Append(FILE_PATH_LITERAL("captive_portal/login.html")),
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // After logging in to the portal, the test URLs return a 204 response.
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new URLRequestMockHTTPJob(
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        request,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        network_delegate,
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        root_http.Append(FILE_PATH_LITERAL("captive_portal/page204.html")),
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a server-side redirect for use with the TestServer.
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string CreateServerRedirect(const std::string& dest_url) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* const kServerRedirectBase = "server-redirect?";
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kServerRedirectBase + dest_url;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the total number of loading tabs across all Browsers, for all
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Profiles.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int NumLoadingTabs() {
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_loading_tabs = 0;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (TabContentsIterator it; !it.done(); it.Next()) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->IsLoading())
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++num_loading_tabs;
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_loading_tabs;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsLoginTab(WebContents* web_contents) {
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CaptivePortalTabHelper::FromWebContents(web_contents)->IsLoginTab();
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tracks how many times each tab has been navigated since the Observer was
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// created.  The standard TestNavigationObserver can only watch specific
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pre-existing tabs or loads in serial for all tabs.
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultiNavigationObserver : public content::NotificationObserver {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver();
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MultiNavigationObserver();
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Waits for exactly |num_navigations_to_wait_for| LOAD_STOP
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // notifications to have occurred since the construction of |this|.  More
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigations than expected occuring will trigger a expect failure.
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WaitForNavigations(int num_navigations_to_wait_for);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of LOAD_STOP events that have occurred for
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |web_contents| since this was constructed.
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int NumNavigationsForTab(WebContents* web_contents) const;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The number of LOAD_STOP events since |this| was created.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_navigations() const { return num_navigations_; }
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::map<const WebContents*, int> TabNavigationMap;
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // content::NotificationObserver:
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type, const content::NotificationSource& source,
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_navigations_;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map of how many times each tab has navigated since |this| was created.
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabNavigationMap tab_navigation_map_;
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Total number of navigations to wait for.  Value only matters when
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |waiting_for_navigation_| is true.
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_navigations_to_wait_for_;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if WaitForNavigations has been called, until
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |num_navigations_to_wait_for_| have been observed.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool waiting_for_navigation_;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MultiNavigationObserver);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MultiNavigationObserver::MultiNavigationObserver()
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : num_navigations_(0),
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_navigations_to_wait_for_(0),
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      waiting_for_navigation_(false) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::NotificationService::AllSources());
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MultiNavigationObserver::~MultiNavigationObserver() {
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MultiNavigationObserver::WaitForNavigations(
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int num_navigations_to_wait_for) {
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shouldn't already be waiting for navigations.
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(waiting_for_navigation_);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(0, num_navigations_to_wait_for);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_navigations_ < num_navigations_to_wait_for) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    num_navigations_to_wait_for_ = num_navigations_to_wait_for;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    waiting_for_navigation_ = true;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(waiting_for_navigation_);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_navigations_, num_navigations_to_wait_for);
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int MultiNavigationObserver::NumNavigationsForTab(
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* web_contents) const {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabNavigationMap::const_iterator tab_navigations =
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_navigation_map_.find(web_contents);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tab_navigations == tab_navigation_map_.end())
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tab_navigations->second;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MultiNavigationObserver::Observe(
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(type, content::NOTIFICATION_LOAD_STOP);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NavigationController* controller =
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<content::NavigationController>(source).ptr();
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_navigations_;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++tab_navigation_map_[controller->GetWebContents()];
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (waiting_for_navigation_ &&
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_navigations_to_wait_for_ == num_navigations_) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    waiting_for_navigation_ = false;
59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoopForUI::current()->Quit();
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This observer creates a list of loading tabs, and then waits for them all
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to stop loading and have the kInternetConnectedTitle.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is for the specific purpose of observing tabs time out after logging in
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to a captive portal, which will then cause them to reload.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MultiNavigationObserver is insufficient for this because there may or may not
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be a LOAD_STOP event between the timeout and the reload.
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See bug http://crbug.com/133227
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FailLoadsAfterLoginObserver : public content::NotificationObserver {
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLoginObserver();
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FailLoadsAfterLoginObserver();
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WaitForNavigations();
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::set<const WebContents*> TabSet;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // content::NotificationObserver:
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type, const content::NotificationSource& source,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The set of tabs that need to be navigated.  This is the set of loading
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tabs when the observer is created.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabSet tabs_needing_navigation_;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of tabs that have stopped navigating with the expected title.  These
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are expected not to be navigated again.
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TabSet tabs_navigated_to_final_destination_;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // True if WaitForNavigations has been called, until
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |tabs_navigated_to_final_destination_| equals |tabs_needing_navigation_|.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool waiting_for_navigation_;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FailLoadsAfterLoginObserver);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FailLoadsAfterLoginObserver::FailLoadsAfterLoginObserver()
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : waiting_for_navigation_(false) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::NotificationService::AllSources());
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (TabContentsIterator it; !it.done(); it.Next()) {
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->IsLoading())
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tabs_needing_navigation_.insert(*it);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FailLoadsAfterLoginObserver::~FailLoadsAfterLoginObserver() {
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FailLoadsAfterLoginObserver::WaitForNavigations() {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shouldn't already be waiting for navigations.
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(waiting_for_navigation_);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (tabs_needing_navigation_.size() !=
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          tabs_navigated_to_final_destination_.size()) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    waiting_for_navigation_ = true;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(waiting_for_navigation_);
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(tabs_needing_navigation_.size(),
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tabs_navigated_to_final_destination_.size());
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FailLoadsAfterLoginObserver::Observe(
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(type, content::NOTIFICATION_LOAD_STOP);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NavigationController* controller =
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<content::NavigationController>(source).ptr();
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* contents = controller->GetWebContents();
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1u, tabs_needing_navigation_.count(contents));
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0u, tabs_navigated_to_final_destination_.count(contents));
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (contents->GetTitle() != base::ASCIIToUTF16(kInternetConnectedTitle))
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tabs_navigated_to_final_destination_.insert(contents);
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (waiting_for_navigation_ &&
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tabs_needing_navigation_.size() ==
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          tabs_navigated_to_final_destination_.size()) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    waiting_for_navigation_ = false;
68090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoopForUI::current()->Quit();
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An observer for watching the CaptivePortalService.  It tracks the last
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// received result and the total number of received results.
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CaptivePortalObserver : public content::NotificationObserver {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit CaptivePortalObserver(Profile* profile);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs the message loop until until at exactly |update_count| capitive portal
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // results have been received, since this creation of |this|.  Expects no
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // additional captive portal results.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WaitForResults(int num_results_to_wait_for);
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_results_received() const { return num_results_received_; }
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CaptivePortalResult captive_portal_result() const {
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return captive_portal_result_;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Records results and exits the message loop, if needed.
7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Observe(int type,
7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const content::NotificationSource& source,
7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of times OnPortalResult has been called since construction.
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_results_received_;
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If WaitForResults was called, the total number of updates for which to
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // wait.  Value doesn't matter when |waiting_for_result_| is false.
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_results_to_wait_for_;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool waiting_for_result_;
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalService* captive_portal_service_;
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Last result received.
7215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  CaptivePortalResult captive_portal_result_;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CaptivePortalObserver);
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalObserver::CaptivePortalObserver(Profile* profile)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : num_results_received_(0),
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_results_to_wait_for_(0),
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      waiting_for_result_(false),
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_(profile),
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      captive_portal_service_(
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          CaptivePortalServiceFactory::GetForProfile(profile)),
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      captive_portal_result_(
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          captive_portal_service_->last_detection_result()) {
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this,
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<Profile>(profile_));
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalObserver::WaitForResults(int num_results_to_wait_for) {
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(0, num_results_to_wait_for);
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(waiting_for_result_);
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (num_results_received_ < num_results_to_wait_for) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    num_results_to_wait_for_ = num_results_to_wait_for;
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    waiting_for_result_ = true;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RunMessageLoop();
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(waiting_for_result_);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_results_to_wait_for, num_results_received_);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalObserver::Observe(
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(type, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(profile_, content::Source<Profile>(source).ptr());
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalService::Results* results =
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<CaptivePortalService::Results>(details).ptr();
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(captive_portal_result_, results->previous_result);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(captive_portal_service_->last_detection_result(),
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            results->result);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  captive_portal_result_ = results->result;
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ++num_results_received_;
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (waiting_for_result_ &&
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      num_results_to_wait_for_ == num_results_received_) {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    waiting_for_result_ = false;
77490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    base::MessageLoop::current()->Quit();
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds an HSTS rule for |host|, so that all HTTP requests sent to it will
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be switched to HTTPS requests.
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddHstsHost(net::URLRequestContextGetter* context_getter,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const std::string& host) {
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::TransportSecurityState* transport_security_state =
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_getter->GetURLRequestContext()->transport_security_state();
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!transport_security_state) {
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FAIL();
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time expiry = base::Time::Now() + base::TimeDelta::FromDays(1000);
7912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool include_subdomains = false;
7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  transport_security_state->AddHSTS(host, expiry, include_subdomains);
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CaptivePortalBrowserTest : public InProcessBrowserTest {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalBrowserTest();
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // InProcessBrowserTest:
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE;
8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void TearDownOnMainThread() OVERRIDE;
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the captive portal checking preference.  Does not affect the command
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // line flag, which is set in SetUpCommandLine.
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void EnableCaptivePortalDetection(Profile* profile, bool enabled);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets up the captive portal service for the given profile so that
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all checks go to |test_url|.  Also disables all timers.
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetUpCaptivePortalService(Profile* profile, const GURL& test_url);
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |browser|'s profile is currently running a captive portal
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // check.
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool CheckPending(Browser* browser);
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the CaptivePortalTabReloader::State of |web_contents|.
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader::State GetStateOfTabReloader(
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      WebContents* web_contents) const;
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the CaptivePortalTabReloader::State of the indicated tab.
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser,
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                          int index) const;
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of tabs with the given state, across all profiles.
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NumTabsWithState(CaptivePortalTabReloader::State state) const;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of tabs broken by captive portals, across all profiles.
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NumBrokenTabs() const;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the number of tabs that need to be reloaded due to having logged
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in to a captive portal, across all profiles.
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NumNeedReloadTabs() const;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigates |browser|'s active tab to |url| and expects no captive portal
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // test to be triggered.  |expected_navigations| is the number of times the
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // active tab will end up being navigated.  It should be 1, except for the
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Link Doctor page, which acts like two navigations.
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NavigateToPageExpectNoTest(Browser* browser,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const GURL& url,
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  int expected_navigations);
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigates |browser|'s active tab to an SSL tab that takes a while to load,
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // triggering a captive portal check, which is expected to give the result
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |expected_result|.  The page finishes loading, with a timeout, after the
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // captive portal check.
8475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void SlowLoadNoCaptivePortal(Browser* browser,
8485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                               CaptivePortalResult expected_result);
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigates |browser|'s active tab to an SSL timeout, expecting a captive
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // portal check to be triggered and return a result which will indicates
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // there's no detected captive portal.
8535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void FastTimeoutNoCaptivePortal(Browser* browser,
8545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                  CaptivePortalResult expected_result);
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigates the active tab to a slow loading SSL page, which will then
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // trigger a captive portal test.  The test is expected to find a captive
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // portal.  The slow loading page will continue to load after the function
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // returns, until URLRequestTimeoutOnDemandJob::FailJobs() is called,
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at which point it will timeout.
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When |expect_login_tab| is false, no login tab is expected to be opened,
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // because one already exists, and the function returns once the captive
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // portal test is complete.
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |expect_login_tab| is true, a login tab is then expected to be opened.
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It waits until both the login tab has finished loading, and two captive
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // portal tests complete.  The second test is triggered by the load of the
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // captive portal tab completing.
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function must not be called when the active tab is currently loading.
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Waits for the hanging request to be issued, so other functions can rely
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on URLRequestTimeoutOnDemandJob::WaitForJobs having been called.
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SlowLoadBehindCaptivePortal(Browser* browser, bool expect_login_tab);
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same as above, but takes extra parameters.
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |hanging_url| should either be kMockHttpsUrl or redirect to kMockHttpsUrl.
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |expected_portal_checks| and |expected_login_tab_navigations| allow
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // client-side redirects to be tested.  |expected_login_tab_navigations| is
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ignored when |expect_open_login_tab| is false.
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SlowLoadBehindCaptivePortal(Browser* browser,
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   bool expect_open_login_tab,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const GURL& hanging_url,
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int expected_portal_checks,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int expected_login_tab_navigations);
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Just like SlowLoadBehindCaptivePortal, except the navigated tab has
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a connection timeout rather having its time trigger, and the function
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // waits until that timeout occurs.
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FastTimeoutBehindCaptivePortal(Browser* browser,
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      bool expect_open_login_tab);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Much as above, but accepts a URL parameter and can be used for errors that
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // trigger captive portal checks other than timeouts.  |error_url| should
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // result in an error rather than hanging.
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FastErrorBehindCaptivePortal(Browser* browser,
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool expect_open_login_tab,
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const GURL& error_url);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigates the login tab without logging in.  The login tab must be the
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // specified browser's active tab.  Expects no other tab to change state.
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that nothing has gone wrong prior to the function call.
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void NavigateLoginTab(Browser* browser,
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int num_loading_tabs,
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int num_timed_out_tabs);
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulates a login by updating the URLRequestMockCaptivePortalJob's
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // behind captive portal state, and navigating the login tab.  Waits for
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // all broken but not loading tabs to be reloaded.
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that nothing has gone wrong prior to the function call.
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes the slow SSL loads of all active tabs time out at once, and waits for
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // them to finish both that load and the automatic reload it should trigger.
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should be no timed out tabs when this is called.
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Makes the slow SSL loads of all active tabs time out at once, and waits for
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // them to finish displaying their error pages.  The login tab should be the
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // active tab.  There should be no timed out tabs when this is called.
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs);
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigates |browser|'s active tab to |starting_url| while not behind a
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // captive portal.  Then navigates to |interrupted_url|, which should create
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a URLRequestTimeoutOnDemandJob, which is then abandoned.  The load should
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // trigger a captive portal check, which finds a captive portal and opens a
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab.
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then the navigation is interrupted by a navigation to |timeout_url|, which
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should trigger a captive portal check, and finally the test simulates
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // logging in.
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The purpose of this test is to make sure the TabHelper triggers a captive
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // portal check when a load is interrupted by another load, particularly in
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the case of cross-process navigations.
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunNavigateLoadingTabToTimeoutTest(Browser* browser,
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const GURL& starting_url,
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const GURL& interrupted_url,
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const GURL& timeout_url);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets the timeout used by a CaptivePortalTabReloader on slow SSL loads
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before a captive portal check.
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetSlowSSLLoadTime(CaptivePortalTabReloader* tab_reloader,
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          base::TimeDelta slow_ssl_load_time);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CaptivePortalTabReloader* GetTabReloader(WebContents* web_contents) const;
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest);
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalBrowserTest::CaptivePortalBrowserTest() {
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::SetUpOnMainThread() {
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enable mock requests.
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestMockCaptivePortalJobFactory::AddUrlHandlers();
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Double-check that the captive portal service isn't enabled by default for
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser tests.
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalService::DISABLED_FOR_TESTING,
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            CaptivePortalService::get_state_for_testing());
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalService::set_state_for_testing(
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableCaptivePortalDetection(browser()->profile(), true);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the captive portal service to use URLRequestMockCaptivePortalJob's
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mock URL, by default.
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpCaptivePortalService(browser()->profile(),
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GURL(kMockCaptivePortalTestUrl));
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void CaptivePortalBrowserTest::TearDownOnMainThread() {
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No test should have a captive portal check pending on quit.
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser()));
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile, bool enabled) {
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile,
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                         const GURL& test_url) {
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalService* captive_portal_service =
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CaptivePortalServiceFactory::GetForProfile(profile);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  captive_portal_service->set_test_url(test_url);
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't use any non-zero timers.  Timers are checked in unit tests.
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalService::RecheckPolicy* recheck_policy =
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &captive_portal_service->recheck_policy();
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  recheck_policy->initial_backoff_no_portal_ms = 0;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  recheck_policy->initial_backoff_portal_ms = 0;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  recheck_policy->backoff_policy.maximum_backoff_ms = 0;
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CaptivePortalBrowserTest::CheckPending(Browser* browser) {
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalService* captive_portal_service =
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CaptivePortalServiceFactory::GetForProfile(browser->profile());
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return captive_portal_service->DetectionInProgress() ||
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      captive_portal_service->TimerRunning();
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalTabReloader::State CaptivePortalBrowserTest::GetStateOfTabReloader(
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* web_contents) const {
10152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetTabReloader(web_contents)->state();
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalTabReloader::State
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser* browser,
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  int index) const {
10212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return GetStateOfTabReloader(
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetWebContentsAt(index));
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CaptivePortalBrowserTest::NumTabsWithState(
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptivePortalTabReloader::State state) const {
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_tabs = 0;
10282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (TabContentsIterator it; !it.done(); it.Next()) {
10292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (GetStateOfTabReloader(*it) == state)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++num_tabs;
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return num_tabs;
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CaptivePortalBrowserTest::NumBrokenTabs() const {
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NumTabsWithState(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL);
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CaptivePortalBrowserTest::NumNeedReloadTabs() const {
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NumTabsWithState(CaptivePortalTabReloader::STATE_NEEDS_RELOAD);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::NavigateToPageExpectNoTest(
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_navigations) {
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser, url, expected_navigations);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No captive portal checks should have ocurred or be pending, and there
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be no new tabs.
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, portal_observer.num_results_received());
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
10572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, browser->tab_strip_model()->count());
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_navigations, navigation_observer.num_navigations());
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumLoadingTabs());
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser, 0));
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::SlowLoadNoCaptivePortal(
10655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Browser* browser,
10665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CaptivePortalResult expected_result) {
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader* tab_reloader =
10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloader(browser->tab_strip_model()->GetActiveWebContents());
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_reloader);
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(browser,
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              GURL(kMockHttpsUrl),
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              CURRENT_TAB,
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              ui_test_utils::BROWSER_TEST_NONE);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1, browser->tab_strip_model()->count());
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_result, portal_observer.captive_portal_result());
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, navigation_observer.num_navigations());
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First tab should still be loading.
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, NumLoadingTabs());
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the request to be issued, then time it out.
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(1);
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::FailJobs(1);
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1, browser->tab_strip_model()->count());
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumLoadingTabs());
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a slow SSL load time to prevent the timer from triggering.
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::FastTimeoutNoCaptivePortal(
11055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Browser* browser,
11065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    CaptivePortalResult expected_result) {
11075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_NE(expected_result, captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL);
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the load time to be large, so the timer won't trigger.  The value is
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not restored at the end of the function.
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader* tab_reloader =
11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloader(browser->tab_strip_model()->GetActiveWebContents());
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_reloader);
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Neither of these should be changed by the navigation.
11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int active_index = browser->tab_strip_model()->active_index();
11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int expected_tab_count = browser->tab_strip_model()->count();
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser,
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestFailedJob::GetMockHttpsUrl(net::ERR_CONNECTION_TIMED_OUT));
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // An attempt to detect a captive portal should have started by now.  If not,
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // abort early to prevent hanging.
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(portal_observer.num_results_received() > 0 ||
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              CheckPending(browser));
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1);
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the result.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_result, portal_observer.captive_portal_result());
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the right tab was navigated, and there were no extra
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigations.
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
11422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   browser->tab_strip_model()->GetWebContentsAt(active_index)));
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumLoadingTabs());
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the tab's state, and verify no captive portal check is pending.
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser, 0));
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure no login tab was opened.
11512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(expected_tab_count, browser->tab_strip_model()->count());
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expect_open_login_tab) {
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser,
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              expect_open_login_tab,
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              GURL(kMockHttpsUrl),
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              1,
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              1);
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expect_open_login_tab,
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& hanging_url,
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_portal_checks,
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int expected_login_tab_navigations) {
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_GE(expected_portal_checks, 1);
11712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser->tab_strip_model();
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling this on a tab that's waiting for a load to manually be timed out
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will result in a hang.
11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading());
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger a captive portal check quickly.
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader* tab_reloader =
11782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloader(tab_strip_model->GetActiveWebContents());
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_reloader);
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of tabs expected to be open after the captive portal checks
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have completed.
11842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_tab_count = tab_strip_model->count();
11852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_active_index = tab_strip_model->active_index();
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int initial_loading_tabs = NumLoadingTabs();
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_broken_tabs = NumBrokenTabs();
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) {
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++expected_broken_tabs;
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(browser,
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              hanging_url,
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              CURRENT_TAB,
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              ui_test_utils::BROWSER_TEST_NONE);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(expected_portal_checks);
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expect_open_login_tab) {
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_GE(expected_login_tab_navigations, 1);
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    navigation_observer.WaitForNavigations(expected_login_tab_navigations);
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count());
12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(initial_tab_count, tab_strip_model->active_index());
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_login_tab_navigations,
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              navigation_observer.NumNavigationsForTab(
12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  tab_strip_model->GetWebContentsAt(initial_tab_count)));
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetStateOfTabReloaderAt(browser, 1));
12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, navigation_observer.num_navigations());
12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(initial_tab_count, tab_strip_model->count());
12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for all the expect resource loads to actually start, so subsequent
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // functions can rely on them having started.
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(initial_loading_tabs + 1);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(initial_loading_tabs + 1, NumLoadingTabs());
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_broken_tabs, NumBrokenTabs());
12285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            portal_observer.captive_portal_result());
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_portal_checks, portal_observer.num_results_received());
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser, initial_active_index));
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reset the load time to be large, so the timer won't trigger on a reload.
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expect_open_login_tab) {
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastErrorBehindCaptivePortal(browser,
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               expect_open_login_tab,
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GURL(kMockHttpsQuickTimeoutUrl));
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool expect_open_login_tab,
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& error_url) {
12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser->tab_strip_model();
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calling this on a tab that's waiting for a load to manually be timed out
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will result in a hang.
12552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_FALSE(tab_strip_model->GetActiveWebContents()->IsLoading());
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the load time to be large, so the timer won't trigger.  The value is
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not restored at the end of the function.
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader* tab_reloader =
12602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloader(tab_strip_model->GetActiveWebContents());
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_reloader);
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of tabs expected to be open after the captive portal checks
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have completed.
12662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_tab_count = tab_strip_model->count();
12672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_active_index = tab_strip_model->active_index();
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int initial_loading_tabs = NumLoadingTabs();
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected_broken_tabs = NumBrokenTabs();
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
12712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          GetStateOfTabReloader(tab_strip_model->GetActiveWebContents())) {
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++expected_broken_tabs;
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(browser,
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              error_url,
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              CURRENT_TAB,
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              ui_test_utils::BROWSER_TEST_NONE);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expect_open_login_tab) {
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    navigation_observer.WaitForNavigations(2);
12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(initial_tab_count + 1, tab_strip_model->count());
12862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(initial_tab_count, tab_strip_model->active_index());
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Make sure that the originally active tab and the captive portal tab have
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // each loaded once.
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     tab_strip_model->GetWebContentsAt(initial_active_index)));
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     tab_strip_model->GetWebContentsAt(initial_tab_count)));
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
12942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              GetStateOfTabReloaderAt(browser, 1));
12952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    navigation_observer.WaitForNavigations(1);
12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
13002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     tab_strip_model->GetWebContentsAt(initial_active_index)));
13012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_EQ(initial_tab_count, tab_strip_model->count());
13022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(initial_active_index, tab_strip_model->active_index());
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(initial_loading_tabs, NumLoadingTabs());
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_broken_tabs, NumBrokenTabs());
13075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            portal_observer.captive_portal_result());
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser, initial_active_index));
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::NavigateLoginTab(Browser* browser,
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                int num_loading_tabs,
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                int num_timed_out_tabs) {
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser->tab_strip_model();
13232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_tab_count = tab_strip_model->count();
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int login_tab_index = tab_strip_model->active_index();
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloader(tab_strip_model->GetActiveWebContents()));
13302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(IsLoginTab(browser->tab_strip_model()->GetActiveWebContents()));
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do the navigation.
1333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::RenderFrameHost* render_frame_host =
1334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tab_strip_model->GetActiveWebContents()->GetMainFrame();
1335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1);
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the captive portal result.
13415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            portal_observer.captive_portal_result());
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure not much has changed.
13472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(initial_tab_count, tab_strip_model->count());
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_loading_tabs + num_timed_out_tabs, NumBrokenTabs());
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
13512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser, login_tab_index));
13522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure there were no unexpected navigations.
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(login_tab_index)));
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::Login(Browser* browser,
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int num_loading_tabs,
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     int num_timed_out_tabs) {
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate logging in.
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser->tab_strip_model();
13692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_tab_count = tab_strip_model->count();
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the login page is on top.
13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int login_tab_index = tab_strip_model->active_index();
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
13762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser, login_tab_index));
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Trigger a navigation.
1380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::RenderFrameHost* render_frame_host =
1381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tab_strip_model->GetActiveWebContents()->GetMainFrame();
1382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for all the timed out tabs to reload.
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1 + num_timed_out_tabs);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The tabs that were loading before should still be loading, and now be in
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // STATE_NEEDS_RELOAD.
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumBrokenTabs());
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_loading_tabs, NumNeedReloadTabs());
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that the broken tabs have reloaded, and there's no more
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // captive portal tab.
13982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(initial_tab_count, tab_strip_model->count());
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser, login_tab_index));
14012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(login_tab_index)));
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure there were no unexpected navigations of the login tab.
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(login_tab_index)));
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser,
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   int num_loading_tabs) {
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs());
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumBrokenTabs());
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser->tab_strip_model();
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_num_tabs = tab_strip_model->count();
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_active_tab = tab_strip_model->active_index();
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLoginObserver fail_loads_observer;
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connection(s) finally time out.  There should have already been a call
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to wait for the requests to be issued before logging on.
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(num_loading_tabs);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs);
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fail_loads_observer.WaitForNavigations();
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No captive portal checks should have ocurred or be pending, and there
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be no new tabs.
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, portal_observer.num_results_received());
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(initial_num_tabs, tab_strip_model->count());
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(initial_active_tab, tab_strip_model->active_index());
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumNeedReloadTabs());
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumLoadingTabs());
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::FailLoadsWithoutLogin(Browser* browser,
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     int num_loading_tabs) {
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, NumNeedReloadTabs());
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_loading_tabs, NumBrokenTabs());
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser->tab_strip_model();
14462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int initial_num_tabs = tab_strip_model->count();
14472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int login_tab = tab_strip_model->active_index();
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
14492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloader(tab_strip_model->GetActiveWebContents()));
14502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(IsLoginTab(tab_strip_model->GetActiveWebContents()));
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connection(s) finally time out.  There should have already been a call
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to wait for the requests to be issued.
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(num_loading_tabs);
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No captive portal checks should have ocurred or be pending, and there
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should be no new tabs.
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, portal_observer.num_results_received());
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
14642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(initial_num_tabs, tab_strip_model->count());
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumNeedReloadTabs());
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumLoadingTabs());
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(num_loading_tabs, NumBrokenTabs());
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloader(tab_strip_model->GetActiveWebContents()));
14712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IsLoginTab(tab_strip_model->GetActiveWebContents()));
14722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(login_tab, tab_strip_model->active_index());
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, navigation_observer.NumNavigationsForTab(
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(login_tab)));
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::RunNavigateLoadingTabToTimeoutTest(
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& starting_url,
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& hanging_url,
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& timeout_url) {
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Temporarily disable the captive portal and navigate to the starting
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URL, which may be a URL that will hang when behind a captive portal.
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToPageExpectNoTest(browser, starting_url, 1);
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go to the first hanging url.
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser, true, hanging_url, 1, 1);
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Abandon the request.
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(1);
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::AbandonJobs(1);
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser->tab_strip_model();
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader* tab_reloader =
14982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloader(tab_strip_model->GetWebContentsAt(0));
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_reloader);
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A non-zero delay makes it more likely that CaptivePortalTabHelper will
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be confused by events relating to canceling the old navigation.
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromSeconds(2));
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser->profile());
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate the error tab to another slow loading page.  Can't have
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ui_test_utils do the navigation because it will wait for loading tabs to
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stop loading before navigating.
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This may result in either 0 or 1 DidStopLoading events.  If there is one,
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it must happen before the CaptivePortalService sends out its test request,
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so waiting for PortalObserver to see that request prevents it from
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // confusing the MultiNavigationObservers used later.
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(0, true);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->OpenURL(content::OpenURLParams(timeout_url,
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          content::Referrer(),
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          CURRENT_TAB,
15181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          ui::PAGE_TRANSITION_TYPED,
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          false));
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser));
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, NumLoadingTabs());
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser, 0));
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
15262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser, 1));
15272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to make sure the request has been issued before logging in.
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(1);
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate logging in.
15332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(1, true);
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser, 1, 0);
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timeout occurs, and page is automatically reloaded.
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser, 1);
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CaptivePortalBrowserTest::SetSlowSSLLoadTime(
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CaptivePortalTabReloader* tab_reloader,
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta slow_ssl_load_time) {
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab_reloader->set_slow_ssl_load_time(slow_ssl_load_time);
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CaptivePortalTabReloader* CaptivePortalBrowserTest::GetTabReloader(
15482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WebContents* web_contents) const {
15492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CaptivePortalTabHelper::FromWebContents(web_contents)->
15502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloaderForTest();
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure there's no test for a captive portal on HTTP timeouts.  This will
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// also trigger the link doctor page, which results in the load of a second
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error page.
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpTimeout) {
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToPageExpectNoTest(browser(), url, 2);
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure there's no check for a captive portal on HTTPS errors other than
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// timeouts, when they preempt the slow load timer.
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsNonTimeoutError) {
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = URLRequestFailedJob::GetMockHttpsUrl(net::ERR_UNEXPECTED);
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToPageExpectNoTest(browser(), url, 1);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure no captive portal test triggers on HTTPS timeouts of iframes.
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsIframeTimeout) {
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use an HTTPS server for the top level page.
1571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer https_server(
1572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
15732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = https_server.GetURL(kTestServerIframeTimeoutPath);
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToPageExpectNoTest(browser(), url, 1);
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check the captive portal result when the test request reports a network
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error.  The check is triggered by a slow loading page, and the page
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// errors out only after getting a captive portal result.
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFails) {
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpCaptivePortalService(
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser()->profile(),
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED));
15875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_NO_RESPONSE);
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as above, but for the rather unlikely case that the connection times out
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// before the timer triggers.
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFailsFastTimout) {
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpCaptivePortalService(
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser()->profile(),
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED));
15965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  FastTimeoutNoCaptivePortal(browser(), captive_portal::RESULT_NO_RESPONSE);
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks the case that captive portal detection is disabled.
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Disabled) {
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableCaptivePortalDetection(browser()->profile(), false);
16025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_INTERNET_CONNECTED);
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that we look for a captive portal on HTTPS timeouts and don't reload
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the error tab when the captive portal probe gets a 204 response, indicating
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there is no captive portal.
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, InternetConnected) {
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can't just use SetBehindCaptivePortal(false), since then there wouldn't
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be a timeout.
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpCaptivePortalService(browser()->profile(),
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            test_server()->GetURL("nocontent"));
16145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_INTERNET_CONNECTED);
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that no login page is opened when the HTTP test URL redirects to an
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SSL certificate error.
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RedirectSSLCertError) {
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need an HTTP TestServer to handle a dynamically created server redirect.
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer::SSLOptions ssl_options;
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_options.server_certificate =
1625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
1626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer https_server(
1627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS, ssl_options,
16282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL ssl_login_url = https_server.GetURL(kTestServerLoginPath);
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalService* captive_portal_service =
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CaptivePortalServiceFactory::GetForProfile(browser()->profile());
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(captive_portal_service);
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpCaptivePortalService(
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser()->profile(),
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_server()->GetURL(CreateServerRedirect(ssl_login_url.spec())));
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_NO_RESPONSE);
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A slow SSL load triggers a captive portal check.  The user logs on before
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the SSL page times out.  We wait for the timeout and subsequent reload.
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Login) {
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load starts, detect captive portal and open up a login tab.
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Log in.  One loading tab, no timed out ones.
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 1, 0);
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timeout occurs, and page is automatically reloaded.
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 1);
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Same as above, except we make sure everything works with an incognito
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// profile.  Main issues it tests for are that the incognito has its own
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// non-NULL captive portal service, and we open the tab in the correct
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// window.
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginIncognito) {
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will watch tabs for both profiles, but only used to make sure no
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // navigations occur for the non-incognito profile.
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver non_incognito_portal_observer(browser()->profile());
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* incognito_browser = CreateIncognitoBrowser();
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableCaptivePortalDetection(incognito_browser->profile(), true);
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpCaptivePortalService(incognito_browser->profile(),
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GURL(kMockCaptivePortalTestUrl));
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(incognito_browser, true);
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
16742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, tab_strip_model->count());
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(incognito_browser, 1, 0);
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(incognito_browser, 1);
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, tab_strip_model->count());
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, navigation_observer.NumNavigationsForTab(
16862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(0)));
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, non_incognito_portal_observer.num_results_received());
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The captive portal page is opened before the SSL page times out,
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but the user logs in only after the page times out.
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginSlow) {
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsWithoutLogin(browser(), 1);
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 0, 1);
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks the unlikely case that the tab times out before the timer triggers.
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This most likely won't happen, but should still work:
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) {
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastTimeoutBehindCaptivePortal(browser(), true);
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 0, 1);
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A cert error triggers a captive portal check and results in opening a login
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tab.  The user then logs in and the page with the error is reloaded.
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, SSLCertErrorLogin) {
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need an HTTP TestServer to handle a dynamically created server redirect.
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer::SSLOptions https_options;
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  https_options.server_certificate =
1713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME;
1714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer https_server(
1715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS, https_options,
17162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The path does not matter.
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL cert_error_url = https_server.GetURL(kTestServerLoginPath);
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The interstitial should trigger a captive portal check when it opens, just
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // like navigating to kMockHttpsQuickTimeoutUrl.
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastErrorBehindCaptivePortal(browser(), true, cert_error_url);
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate logging in.  Can't use Login() because the interstitial tab looks
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // like a cross between a hung tab (Load was never committed) and a tab at an
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error page (The load was stopped).
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser()->profile());
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
1733a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  content::RenderFrameHost* render_frame_host =
1734a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      tab_strip_model->GetActiveWebContents()->GetMainFrame();
1735a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The captive portal tab navigation will trigger a captive portal check,
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and reloading the original tab will bring up the interstitial page again,
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // triggering a second captive portal check.
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(2);
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for both tabs to finish loading.
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(2);
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, portal_observer.num_results_received());
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser()));
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED,
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            portal_observer.captive_portal_result());
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check state of tabs.  While the first tab is still displaying an
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // interstitial page, since no portal was found, it should be in STATE_NONE,
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as should the login tab.
17522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2, tab_strip_model->count());
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
17552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 1));
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure only one navigation was for the login tab.
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
17612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(1)));
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tries navigating both the tab that encounters an SSL timeout and the
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// login tab twice, only logging in the second time.
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) {
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastTimeoutBehindCaptivePortal(browser(), true);
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Activate the timed out tab and navigate it to a timeout again.
17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
17712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(0, true);
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FastTimeoutBehindCaptivePortal(browser(), false);
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Activate and navigate the captive portal tab.  This should not trigger a
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // reload of the tab with the error.
17762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(1, true);
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateLoginTab(browser(), 0, 1);
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate logging in.
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 0, 1);
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After the first SSL timeout, closes the login tab and makes sure it's opened
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it again on a second timeout.
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, CloseLoginTab) {
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First load starts, opens a login tab, and then times out.
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsWithoutLogin(browser(), 1);
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close login tab.
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::CloseTab(browser());
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go through the standard slow load login, and make sure it still works.
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 1, 0);
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 1);
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that two tabs with SSL timeouts in the same window work.  Both
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tabs only timeout after logging in.
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, TwoBrokenTabs) {
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Can't set the TabReloader HTTPS timeout on a new tab without doing some
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // acrobatics, so open a new tab at a normal page, and then navigate it to a
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // timeout.
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser()->profile());
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURLWithDisposition(
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestMockHTTPJob::GetMockUrl(
18122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::FilePath(FILE_PATH_LITERAL("title2.html"))),
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NEW_FOREGROUND_TAB,
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
18172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(3, tab_strip_model->count());
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser()));
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, portal_observer.num_results_received());
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, NumLoadingTabs());
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.num_navigations());
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
18232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(2)));
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
18272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 1));
18282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE,
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 2));
18312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2, tab_strip_model->active_index());
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), false);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(1, true);
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 2, 0);
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 2);
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, AbortLoad) {
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Abandon the request.
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(1);
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::AbandonJobs(1);
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser()->profile());
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Switch back to the hung tab from the login tab, and abort the navigation.
18512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(0, true);
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Stop(browser());
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1);
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumBrokenTabs());
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, portal_observer.num_results_received());
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(CheckPending(browser()));
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(1, true);
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 0, 0);
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks the case where the timed out tab is successfully navigated before
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// logging in.
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, NavigateBrokenTab) {
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go to the error page.
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsWithoutLogin(browser(), 1);
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate the error tab to a non-error page.
18742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
18752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(0, true);
18762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(
18772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser(), URLRequestMockHTTPJob::GetMockUrl(
18782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     base::FilePath(FILE_PATH_LITERAL("title2.html"))));
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate logging in.
18832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(1, true);
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 0, 0);
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that captive portal detection triggers correctly when a same-site
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation is cancelled by a navigation to the same site.
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NavigateLoadingTabToTimeoutSingleSite) {
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunNavigateLoadingTabToTimeoutTest(
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl),
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl),
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl));
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Fails on Windows only, mostly on Win7. http://crbug.com/170033
18992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
19002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
19012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DISABLED_NavigateLoadingTabToTimeoutTwoSites
19022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
19042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NavigateLoadingTabToTimeoutTwoSites
19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that captive portal detection triggers correctly when a same-site
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation is cancelled by a navigation to another site.
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
19102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       MAYBE_NavigateLoadingTabToTimeoutTwoSites) {
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunNavigateLoadingTabToTimeoutTest(
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl),
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl),
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl2));
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that captive portal detection triggers correctly when a cross-site
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// navigation is cancelled by a navigation to yet another site.
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       NavigateLoadingTabToTimeoutThreeSites) {
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunNavigateLoadingTabToTimeoutTest(
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestMockHTTPJob::GetMockUrl(
19252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::FilePath(FILE_PATH_LITERAL("title.html"))),
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl),
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GURL(kMockHttpsUrl2));
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that navigating a timed out tab back clears its state.
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBack) {
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a working page.
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestMockHTTPJob::GetMockUrl(
19362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::FilePath(FILE_PATH_LITERAL("title2.html"))));
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go to the error page.
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true);
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsWithoutLogin(browser(), 1);
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser()->profile());
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Activate the error page tab again and go back.
19462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
19472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->ActivateTabAt(0, true);
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::GoBack(browser(), CURRENT_TAB);
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1);
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
19522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(0)));
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, portal_observer.num_results_received());
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that navigating back to a timeout triggers captive portal detection.
19592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBackToTimeout) {
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Disable captive portal detection so the first navigation doesn't open a
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // login tab.
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableCaptivePortalDetection(browser()->profile(), false);
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_INTERNET_CONNECTED);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate to a working page.
19672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui_test_utils::NavigateToURL(
19682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser(), URLRequestMockHTTPJob::GetMockUrl(
19692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     base::FilePath(FILE_PATH_LITERAL("title2.html"))));
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE,
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EnableCaptivePortalDetection(browser()->profile(), true);
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader* tab_reloader =
19772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloader(tab_strip_model->GetActiveWebContents());
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_reloader);
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Go to the error page.
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser()->profile());
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::GoBack(browser(), CURRENT_TAB);
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the check triggered by the broken tab and for the login tab to
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stop loading.
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1);
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the request has been issued.
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(1);
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CheckPending(browser()));
19955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            portal_observer.captive_portal_result());
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
19992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
20012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 1));
20022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(IsLoginTab(browser()->tab_strip_model()->GetWebContentsAt(1)));
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2, tab_strip_model->count());
20052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, tab_strip_model->active_index());
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
20072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(1)));
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, NumLoadingTabs());
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 1, 0);
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 1);
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks that reloading a timeout triggers captive portal detection.
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Much like the last test, though the captive portal is disabled before
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the inital navigation, rather than captive portal detection.
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, ReloadTimeout) {
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do the first navigation while not behind a captive portal.
20222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip_model = browser()->tab_strip_model();
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser()->profile());
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), GURL(kMockHttpsUrl));
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(0, portal_observer.num_results_received());
20262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1, tab_strip_model->count());
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A captive portal spontaneously appears.
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalTabReloader* tab_reloader =
20322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetTabReloader(tab_strip_model->GetActiveWebContents());
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_reloader);
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
20372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab_strip_model->GetActiveWebContents()->GetController().Reload(true);
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait for the check triggered by the broken tab and for the login tab to
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // stop loading.
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(1);
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the request has been issued.
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestTimeoutOnDemandJob::WaitForJobs(1);
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, portal_observer.num_results_received());
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(CheckPending(browser()));
20485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            portal_observer.captive_portal_result());
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
20522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 0));
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
20542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            GetStateOfTabReloaderAt(browser(), 1));
20552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(IsLoginTab(tab_strip_model->GetWebContentsAt(1)));
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2, tab_strip_model->count());
20582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, tab_strip_model->active_index());
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
20602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   tab_strip_model->GetWebContentsAt(1)));
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, NumLoadingTabs());
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 1, 0);
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 1);
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks the case where there are two windows, and there's an SSL timeout in
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the background one.
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Disabled:  http://crbug.com/134357
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, DISABLED_TwoWindows) {
20722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* browser2 =
20732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new Browser(Browser::CreateParams(browser()->profile(),
20742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        browser()->host_desktop_type()));
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate the new browser window so it'll be shown and we can pick the
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // active window.
2077f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser2, GURL(url::kAboutBlankURL));
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Generally, |browser2| will be the active window.  However, if the
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // original browser window lost focus before creating the new one, such as
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when running multiple tests at once, the original browser window may
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // remain the profile's active window.
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* active_browser =
20842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chrome::FindTabbedBrowser(browser()->profile(), true,
20852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                browser()->host_desktop_type());
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* inactive_browser;
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (active_browser == browser2) {
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When only one test is running at a time, the new browser will probably be
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // on top, but when multiple tests are running at once, this is not
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // guaranteed.
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inactive_browser = browser();
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_EQ(active_browser, browser());
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    inactive_browser = browser2;
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CaptivePortalObserver portal_observer(browser()->profile());
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MultiNavigationObserver navigation_observer;
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigate the tab in the inactive browser to an SSL timeout.  Have to use
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome::NavigateParams and NEW_BACKGROUND_TAB to avoid activating the
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // window.
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::NavigateParams params(inactive_browser,
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                GURL(kMockHttpsQuickTimeoutUrl),
21051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                ui::PAGE_TRANSITION_TYPED);
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.disposition = NEW_BACKGROUND_TAB;
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.window_action = chrome::NavigateParams::NO_ACTION;
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(&params);
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  navigation_observer.WaitForNavigations(2);
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the active window hasn't changed, and its new tab is
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // active.
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(active_browser,
21142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            chrome::FindTabbedBrowser(browser()->profile(), true,
21152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      browser()->host_desktop_type()));
21162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(1, active_browser->tab_strip_model()->active_index());
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check that the only two navigated tabs were the new error tab in the
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backround windows, and the login tab in the active window.
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   inactive_browser->tab_strip_model()->GetWebContentsAt(1)));
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   active_browser->tab_strip_model()->GetWebContentsAt(1)));
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, NumLoadingTabs());
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check captive portal test results.
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  portal_observer.WaitForResults(1);
21285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ASSERT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL,
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            portal_observer.captive_portal_result());
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1, portal_observer.num_results_received());
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the inactive browser.
21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, inactive_browser->tab_strip_model()->count());
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(inactive_browser, 0));
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(inactive_browser, 1));
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the active browser.
21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(2, active_browser->tab_strip_model()->count());
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(active_browser, 0));
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetStateOfTabReloaderAt(active_browser, 1));
21452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(
21462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IsLoginTab(active_browser->tab_strip_model()->GetWebContentsAt(1)));
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Simulate logging in.
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(active_browser, 0, 1);
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An HTTP page redirects to an HTTPS page loads slowly before timing out.  A
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// captive portal is found, and then the user logs in before the original page
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// times out.
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpToHttpsRedirectLogin) {
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server()->Start());
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      test_server()->GetURL(CreateServerRedirect(kMockHttpsUrl)),
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1);
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 1, 0);
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 1);
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An HTTPS page redirects to an HTTP page.
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsToHttpRedirect) {
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use an HTTPS server for the top level page.
2170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer https_server(
2171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
21722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(https_server.Start());
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL http_timeout_url =
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2 navigations due to the Link Doctor.
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToPageExpectNoTest(
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser(),
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      https_server.GetURL(CreateServerRedirect(http_timeout_url.spec())),
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      2);
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests the 511 response code, along with an HTML redirect to a login page.
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Status511) {
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetUpCaptivePortalService(browser()->profile(),
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            GURL(kMockCaptivePortal511Url));
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true, GURL(kMockHttpsUrl), 2, 2);
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 1, 0);
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 1);
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HSTS redirects an HTTP request to HTTPS, and the request then times out.
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A captive portal is then detected, and a login tab opened, before logging
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in.
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HstsLogin) {
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL::Replacements replacements;
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string scheme = "http";
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  replacements.SetSchemeStr(scheme);
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL http_timeout_url = GURL(kMockHttpsUrl).ReplaceComponents(replacements);
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::BrowserThread::PostTask(
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserThread::IO, FROM_HERE,
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&AddHstsHost,
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 make_scoped_refptr(browser()->profile()->GetRequestContext()),
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 http_timeout_url.host()));
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url, 1, 1);
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Login(browser(), 1, 0);
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FailLoadsAfterLogin(browser(), 1);
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2214