1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
7 #include "base/callback.h"
8 #include "base/message_loop/message_loop.h"
9 #include "chrome/browser/captive_portal/captive_portal_service.h"
10 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/interstitial_page.h"
13 #include "content/public/browser/interstitial_page_delegate.h"
14 #include "content/public/browser/web_contents.h"
15 #include "net/base/net_errors.h"
16 #include "net/cert/cert_status_flags.h"
17 #include "net/ssl/ssl_info.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
22 namespace captive_portal
{
24 // Used for testing CaptivePortalTabReloader in isolation from the observer.
25 // Exposes a number of private functions and mocks out others.
26 class TestCaptivePortalTabReloader
: public CaptivePortalTabReloader
{
28 explicit TestCaptivePortalTabReloader(content::WebContents
* web_contents
)
29 : CaptivePortalTabReloader(NULL
,
31 base::Callback
<void(void)>()) {
34 virtual ~TestCaptivePortalTabReloader() {
38 return slow_ssl_load_timer_
.IsRunning();
41 // The following methods are aliased so they can be publicly accessed by the
45 return CaptivePortalTabReloader::state();
48 void set_slow_ssl_load_time(base::TimeDelta slow_ssl_load_time
) {
49 EXPECT_FALSE(TimerRunning());
50 CaptivePortalTabReloader::set_slow_ssl_load_time(slow_ssl_load_time
);
53 // CaptivePortalTabReloader:
54 MOCK_METHOD0(ReloadTab
, void());
55 MOCK_METHOD0(MaybeOpenCaptivePortalLoginTab
, void());
56 MOCK_METHOD0(CheckForCaptivePortal
, void());
59 DISALLOW_COPY_AND_ASSIGN(TestCaptivePortalTabReloader
);
62 // Used to test behavior when a WebContents is showing an interstitial page.
63 class MockInterstitialPageDelegate
: public content::InterstitialPageDelegate
{
65 // The newly created MockInterstitialPageDelegate will be owned by the
66 // WebContents' InterstitialPage, and cleaned up when the WebContents
68 explicit MockInterstitialPageDelegate(
69 content::WebContents
* web_contents
) {
70 content::InterstitialPage
* interstitial_page
=
71 content::InterstitialPage::Create(
72 web_contents
, true, GURL("http://blah"), this);
73 interstitial_page
->DontCreateViewForTesting();
74 interstitial_page
->Show();
77 virtual ~MockInterstitialPageDelegate() {
81 // InterstitialPageDelegate implementation:
82 virtual std::string
GetHTMLContents() OVERRIDE
{
83 return "HTML Contents";
86 DISALLOW_COPY_AND_ASSIGN(MockInterstitialPageDelegate
);
89 class CaptivePortalTabReloaderTest
: public ChromeRenderViewHostTestHarness
{
92 virtual void SetUp() OVERRIDE
{
93 ChromeRenderViewHostTestHarness::SetUp();
94 tab_reloader_
.reset(new testing::StrictMock
<TestCaptivePortalTabReloader
>(
97 // Most tests don't run the message loop, so don't use a timer for them.
98 tab_reloader_
->set_slow_ssl_load_time(base::TimeDelta());
101 virtual void TearDown() OVERRIDE
{
102 EXPECT_FALSE(tab_reloader().TimerRunning());
103 tab_reloader_
.reset(NULL
);
104 ChromeRenderViewHostTestHarness::TearDown();
107 TestCaptivePortalTabReloader
& tab_reloader() { return *tab_reloader_
.get(); }
110 scoped_ptr
<TestCaptivePortalTabReloader
> tab_reloader_
;
113 // Simulates a slow SSL load when the Internet is connected.
114 TEST_F(CaptivePortalTabReloaderTest
, InternetConnected
) {
115 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
117 tab_reloader().OnLoadStart(true);
118 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
119 tab_reloader().state());
120 EXPECT_TRUE(tab_reloader().TimerRunning());
122 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
123 base::MessageLoop::current()->RunUntilIdle();
124 EXPECT_FALSE(tab_reloader().TimerRunning());
125 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
126 tab_reloader().state());
128 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
129 RESULT_INTERNET_CONNECTED
);
131 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
132 EXPECT_FALSE(tab_reloader().TimerRunning());
134 tab_reloader().OnLoadCommitted(net::OK
);
135 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
138 // Simulates a slow SSL load when the Internet is connected. In this case,
139 // the timeout error occurs before the timer triggers. Unlikely to happen
140 // in practice, but best if it still works.
141 TEST_F(CaptivePortalTabReloaderTest
, InternetConnectedTimeout
) {
142 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
144 tab_reloader().OnLoadStart(true);
145 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
146 tab_reloader().state());
147 EXPECT_TRUE(tab_reloader().TimerRunning());
149 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
150 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
151 EXPECT_FALSE(tab_reloader().TimerRunning());
152 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
153 tab_reloader().state());
155 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
156 RESULT_INTERNET_CONNECTED
);
158 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
161 // Simulates a slow SSL load when captive portal checks return no response.
162 TEST_F(CaptivePortalTabReloaderTest
, NoResponse
) {
163 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
165 tab_reloader().OnLoadStart(true);
166 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
167 tab_reloader().state());
168 EXPECT_TRUE(tab_reloader().TimerRunning());
170 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
171 base::MessageLoop::current()->RunUntilIdle();
172 EXPECT_FALSE(tab_reloader().TimerRunning());
173 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
174 tab_reloader().state());
176 tab_reloader().OnCaptivePortalResults(RESULT_NO_RESPONSE
, RESULT_NO_RESPONSE
);
178 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
179 EXPECT_FALSE(tab_reloader().TimerRunning());
181 tab_reloader().OnLoadCommitted(net::OK
);
182 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
185 // Simulates a slow HTTP load when behind a captive portal, that eventually.
186 // tiems out. Since it's HTTP, the TabReloader should do nothing.
187 TEST_F(CaptivePortalTabReloaderTest
, DoesNothingOnHttp
) {
188 tab_reloader().OnLoadStart(false);
189 EXPECT_FALSE(tab_reloader().TimerRunning());
190 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
192 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
193 RESULT_BEHIND_CAPTIVE_PORTAL
);
194 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
197 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
198 RESULT_INTERNET_CONNECTED
);
199 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
201 // The page times out.
202 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
203 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
206 // Simulate the normal login process. The user logs in before the error page
207 // in the original tab commits.
208 TEST_F(CaptivePortalTabReloaderTest
, Login
) {
209 tab_reloader().OnLoadStart(true);
211 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
212 base::MessageLoop::current()->RunUntilIdle();
213 EXPECT_FALSE(tab_reloader().TimerRunning());
214 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
215 tab_reloader().state());
217 // The captive portal service detects a captive portal. The TabReloader
218 // should try and create a new login tab in response.
219 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
220 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
221 RESULT_BEHIND_CAPTIVE_PORTAL
);
222 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
223 tab_reloader().state());
224 EXPECT_FALSE(tab_reloader().TimerRunning());
226 // The user logs on from another tab, and a captive portal check is triggered.
227 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
228 RESULT_INTERNET_CONNECTED
);
229 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
230 tab_reloader().state());
232 // The error page commits, which should start an asynchronous reload.
233 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
234 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
235 tab_reloader().state());
237 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
238 base::MessageLoop::current()->RunUntilIdle();
239 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
242 // Simulate the normal login process. The user logs in after the tab finishes
243 // loading the error page.
244 TEST_F(CaptivePortalTabReloaderTest
, LoginLate
) {
245 tab_reloader().OnLoadStart(true);
247 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
248 base::MessageLoop::current()->RunUntilIdle();
249 EXPECT_FALSE(tab_reloader().TimerRunning());
250 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
251 tab_reloader().state());
253 // The captive portal service detects a captive portal. The TabReloader
254 // should try and create a new login tab in response.
255 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
256 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
257 RESULT_BEHIND_CAPTIVE_PORTAL
);
258 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
259 tab_reloader().state());
260 EXPECT_FALSE(tab_reloader().TimerRunning());
262 // The error page commits.
263 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
264 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
265 tab_reloader().state());
267 // The user logs on from another tab, and a captive portal check is triggered.
268 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
269 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
270 RESULT_INTERNET_CONNECTED
);
271 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
274 // Simulate a login after the tab times out unexpectedly quickly.
275 TEST_F(CaptivePortalTabReloaderTest
, TimeoutFast
) {
276 tab_reloader().OnLoadStart(true);
278 // The error page commits, which should trigger a captive portal check,
279 // since the timer's still running.
280 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
281 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
282 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
283 tab_reloader().state());
285 // The captive portal service detects a captive portal. The TabReloader
286 // should try and create a new login tab in response.
287 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
288 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
289 RESULT_BEHIND_CAPTIVE_PORTAL
);
290 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
291 tab_reloader().state());
292 EXPECT_FALSE(tab_reloader().TimerRunning());
294 // The user logs on from another tab, and a captive portal check is triggered.
295 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
296 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
297 RESULT_INTERNET_CONNECTED
);
298 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
301 // An SSL protocol error triggers a captive portal check behind a captive
302 // portal. The user then logs in.
303 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolError
) {
304 tab_reloader().OnLoadStart(true);
306 // The error page commits, which should trigger a captive portal check,
307 // since the timer's still running.
308 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
309 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
310 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
311 tab_reloader().state());
313 // The captive portal service detects a captive portal. The TabReloader
314 // should try and create a new login tab in response.
315 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
316 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
317 RESULT_BEHIND_CAPTIVE_PORTAL
);
318 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
319 tab_reloader().state());
320 EXPECT_FALSE(tab_reloader().TimerRunning());
322 // The user logs on from another tab, and a captive portal check is triggered.
323 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
324 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
325 RESULT_INTERNET_CONNECTED
);
326 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
329 // An SSL protocol error triggers a captive portal check behind a captive
330 // portal. The user logs in before the results from the captive portal check
332 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolErrorFastLogin
) {
333 tab_reloader().OnLoadStart(true);
335 // The error page commits, which should trigger a captive portal check,
336 // since the timer's still running.
337 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
338 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
339 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
340 tab_reloader().state());
342 // The user has logged in from another tab. The tab automatically reloads.
343 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
344 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
345 RESULT_INTERNET_CONNECTED
);
346 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
349 // An SSL protocol error triggers a captive portal check behind a captive
350 // portal. The user logs in before the results from the captive portal check
351 // completes. This case is probably not too likely, but should be handled.
352 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolErrorAlreadyLoggedIn
) {
353 tab_reloader().OnLoadStart(true);
355 // The user logs in from another tab before the tab errors out.
356 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
357 RESULT_INTERNET_CONNECTED
);
358 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
359 tab_reloader().state());
361 // The error page commits, which should trigger a reload.
362 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
363 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
364 base::MessageLoop::current()->RunUntilIdle();
365 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
368 // Simulate the case that a user has already logged in before the tab receives a
369 // captive portal result, but a RESULT_BEHIND_CAPTIVE_PORTAL was received
370 // before the tab started loading.
371 TEST_F(CaptivePortalTabReloaderTest
, AlreadyLoggedIn
) {
372 tab_reloader().OnLoadStart(true);
374 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
375 base::MessageLoop::current()->RunUntilIdle();
376 EXPECT_FALSE(tab_reloader().TimerRunning());
377 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
378 tab_reloader().state());
380 // The user has already logged in. Since the last result found a captive
381 // portal, the tab will be reloaded if a timeout is committed.
382 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
383 RESULT_INTERNET_CONNECTED
);
384 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
385 tab_reloader().state());
387 // The error page commits, which should start an asynchronous reload.
388 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
389 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
390 tab_reloader().state());
392 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
393 base::MessageLoop::current()->RunUntilIdle();
394 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
397 // Same as above, except the result is received even before the timer triggers,
398 // due to a captive portal test request from some external source, like a login
400 TEST_F(CaptivePortalTabReloaderTest
, AlreadyLoggedInBeforeTimerTriggers
) {
401 tab_reloader().OnLoadStart(true);
403 // The user has already logged in. Since the last result indicated there is
404 // a captive portal, the tab will be reloaded if it times out.
405 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
406 RESULT_INTERNET_CONNECTED
);
407 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
408 tab_reloader().state());
409 EXPECT_FALSE(tab_reloader().TimerRunning());
411 // The error page commits, which should start an asynchronous reload.
412 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
413 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
414 tab_reloader().state());
416 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
417 base::MessageLoop::current()->RunUntilIdle();
418 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
421 // Simulate the user logging in while the timer is still running. May happen
422 // if the tab is reloaded just before logging in on another tab.
423 TEST_F(CaptivePortalTabReloaderTest
, LoginWhileTimerRunning
) {
424 tab_reloader().OnLoadStart(true);
425 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
426 tab_reloader().state());
427 EXPECT_TRUE(tab_reloader().TimerRunning());
429 // The user has already logged in.
430 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
431 RESULT_INTERNET_CONNECTED
);
432 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
433 tab_reloader().state());
435 // The error page commits, which should start an asynchronous reload.
436 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
437 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
438 tab_reloader().state());
440 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
441 base::MessageLoop::current()->RunUntilIdle();
442 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
445 // Simulate a captive portal being detected while the time is still running.
446 // The captive portal check triggered by the timer detects the captive portal
447 // again, and then the user logs in.
448 TEST_F(CaptivePortalTabReloaderTest
, BehindPortalResultWhileTimerRunning
) {
449 tab_reloader().OnLoadStart(true);
450 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
451 tab_reloader().state());
452 EXPECT_TRUE(tab_reloader().TimerRunning());
454 // The user is behind a captive portal, but since the tab hasn't timed out,
455 // the message is ignored.
456 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
457 RESULT_BEHIND_CAPTIVE_PORTAL
);
458 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
459 tab_reloader().state());
461 // The rest proceeds as normal.
462 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
463 base::MessageLoop::current()->RunUntilIdle();
464 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
465 tab_reloader().state());
467 // The captive portal service detects a captive portal, and this time the
468 // tab tries to create a login tab.
469 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
470 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
471 RESULT_BEHIND_CAPTIVE_PORTAL
);
472 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
473 tab_reloader().state());
474 EXPECT_FALSE(tab_reloader().TimerRunning());
476 // The user logs on from another tab, and a captive portal check is triggered.
477 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
478 RESULT_INTERNET_CONNECTED
);
479 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
480 tab_reloader().state());
482 // The error page commits, which should start an asynchronous reload.
483 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
484 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
485 tab_reloader().state());
487 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
488 base::MessageLoop::current()->RunUntilIdle();
489 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
492 // The CaptivePortalService detects the user has logged in to a captive portal
493 // while the timer is still running, but the original load succeeds, so no
495 TEST_F(CaptivePortalTabReloaderTest
, LogInWhileTimerRunningNoError
) {
496 tab_reloader().OnLoadStart(true);
497 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
498 tab_reloader().state());
499 EXPECT_TRUE(tab_reloader().TimerRunning());
501 // The user has already logged in.
502 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
503 RESULT_INTERNET_CONNECTED
);
504 EXPECT_FALSE(tab_reloader().TimerRunning());
505 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
506 tab_reloader().state());
508 // The page successfully commits, so no reload is triggered.
509 tab_reloader().OnLoadCommitted(net::OK
);
510 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
513 // Simulate the login process when there's an SSL certificate error.
514 TEST_F(CaptivePortalTabReloaderTest
, SSLCertErrorLogin
) {
515 tab_reloader().OnLoadStart(true);
516 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
517 tab_reloader().state());
519 // The load is interrupted by an interstitial page. The interstitial page
520 // is created after the TabReloader is notified.
521 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal());
522 net::SSLInfo ssl_info
;
523 ssl_info
.SetCertError(net::CERT_STATUS_COMMON_NAME_INVALID
);
524 tab_reloader().OnSSLCertError(ssl_info
);
525 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
526 tab_reloader().state());
527 EXPECT_FALSE(tab_reloader().TimerRunning());
528 // The MockInterstitialPageDelegate will cleaned up by the WebContents.
529 new MockInterstitialPageDelegate(web_contents());
531 // Captive portal probe finds a captive portal.
532 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
533 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
534 RESULT_BEHIND_CAPTIVE_PORTAL
);
536 // The user logs in. Since the interstitial is showing, the page should
537 // be reloaded, despite still having a provisional load.
538 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
539 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
540 RESULT_INTERNET_CONNECTED
);
543 // Simulate an HTTP redirect to HTTPS, when the Internet is connected.
544 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpsRedirectInternetConnected
) {
545 tab_reloader().OnLoadStart(false);
546 // There should be no captive portal check pending.
547 base::MessageLoop::current()->RunUntilIdle();
549 // HTTP to HTTPS redirect.
550 tab_reloader().OnRedirect(true);
551 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
552 tab_reloader().state());
553 EXPECT_TRUE(tab_reloader().TimerRunning());
555 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
556 base::MessageLoop::current()->RunUntilIdle();
557 EXPECT_FALSE(tab_reloader().TimerRunning());
558 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
559 tab_reloader().state());
561 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
562 RESULT_INTERNET_CONNECTED
);
564 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
565 EXPECT_FALSE(tab_reloader().TimerRunning());
567 tab_reloader().OnLoadCommitted(net::OK
);
568 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
571 // Simulate an HTTP redirect to HTTPS and subsequent Login, when the user logs
572 // in before the original page commits.
573 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpsRedirectLogin
) {
574 tab_reloader().OnLoadStart(false);
575 // There should be no captive portal check pending.
576 base::MessageLoop::current()->RunUntilIdle();
578 // HTTP to HTTPS redirect.
579 tab_reloader().OnRedirect(true);
580 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
581 tab_reloader().state());
583 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
584 base::MessageLoop::current()->RunUntilIdle();
585 EXPECT_FALSE(tab_reloader().TimerRunning());
586 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
587 tab_reloader().state());
589 // The captive portal service detects a captive portal. The TabReloader
590 // should try and create a new login tab in response.
591 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
592 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED
,
593 RESULT_BEHIND_CAPTIVE_PORTAL
);
594 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
595 tab_reloader().state());
596 EXPECT_FALSE(tab_reloader().TimerRunning());
598 // The user logs on from another tab, and a captive portal check is triggered.
599 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
600 RESULT_INTERNET_CONNECTED
);
601 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
602 tab_reloader().state());
604 // The error page commits, which should start an asynchronous reload.
605 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
606 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
607 tab_reloader().state());
609 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
610 base::MessageLoop::current()->RunUntilIdle();
611 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
614 // Simulate the case where an HTTPs page redirects to an HTTPS page, before
615 // the timer triggers.
616 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpRedirect
) {
617 tab_reloader().OnLoadStart(true);
618 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
619 tab_reloader().state());
621 tab_reloader().OnRedirect(false);
622 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
623 EXPECT_FALSE(tab_reloader().TimerRunning());
625 // There should be no captive portal check pending after the redirect.
626 base::MessageLoop::current()->RunUntilIdle();
628 // Logging in shouldn't do anything.
629 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
630 RESULT_INTERNET_CONNECTED
);
631 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
634 // Check that an HTTPS to HTTPS redirect results in no timer running.
635 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpsRedirect
) {
636 tab_reloader().OnLoadStart(true);
637 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
638 tab_reloader().state());
640 tab_reloader().OnRedirect(true);
641 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
642 tab_reloader().state());
643 EXPECT_FALSE(tab_reloader().TimerRunning());
644 // Nothing should happen.
645 base::MessageLoop::current()->RunUntilIdle();
648 // Check that an HTTPS to HTTP to HTTPS redirect results in no timer running.
649 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpToHttpsRedirect
) {
650 tab_reloader().OnLoadStart(true);
651 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
652 tab_reloader().state());
654 tab_reloader().OnRedirect(false);
655 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
656 EXPECT_FALSE(tab_reloader().TimerRunning());
658 tab_reloader().OnRedirect(true);
659 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
660 tab_reloader().state());
661 EXPECT_FALSE(tab_reloader().TimerRunning());
662 // Nothing should happen.
663 base::MessageLoop::current()->RunUntilIdle();
666 // Check that an HTTP to HTTP redirect results in the timer not running.
667 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpRedirect
) {
668 tab_reloader().OnLoadStart(false);
669 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
671 tab_reloader().OnRedirect(false);
672 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
673 EXPECT_FALSE(tab_reloader().TimerRunning());
675 // There should be no captive portal check pending after the redirect.
676 base::MessageLoop::current()->RunUntilIdle();
678 // Logging in shouldn't do anything.
679 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL
,
680 RESULT_INTERNET_CONNECTED
);
681 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
684 } // namespace captive_portal