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/interstitial_page.h"
12 #include "content/public/browser/interstitial_page_delegate.h"
13 #include "content/public/browser/web_contents.h"
14 #include "net/base/net_errors.h"
15 #include "net/cert/cert_status_flags.h"
16 #include "net/ssl/ssl_info.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
21 using captive_portal::CaptivePortalResult
;
23 // Used for testing CaptivePortalTabReloader in isolation from the observer.
24 // Exposes a number of private functions and mocks out others.
25 class TestCaptivePortalTabReloader
: public CaptivePortalTabReloader
{
27 explicit TestCaptivePortalTabReloader(content::WebContents
* web_contents
)
28 : CaptivePortalTabReloader(NULL
,
30 base::Callback
<void(void)>()) {
33 virtual ~TestCaptivePortalTabReloader() {
37 return slow_ssl_load_timer_
.IsRunning();
40 // The following methods are aliased so they can be publicly accessed by the
44 return CaptivePortalTabReloader::state();
47 void set_slow_ssl_load_time(base::TimeDelta slow_ssl_load_time
) {
48 EXPECT_FALSE(TimerRunning());
49 CaptivePortalTabReloader::set_slow_ssl_load_time(slow_ssl_load_time
);
52 // CaptivePortalTabReloader:
53 MOCK_METHOD0(ReloadTab
, void());
54 MOCK_METHOD0(MaybeOpenCaptivePortalLoginTab
, void());
55 MOCK_METHOD0(CheckForCaptivePortal
, void());
58 DISALLOW_COPY_AND_ASSIGN(TestCaptivePortalTabReloader
);
61 // Used to test behavior when a WebContents is showing an interstitial page.
62 class MockInterstitialPageDelegate
: public content::InterstitialPageDelegate
{
64 // The newly created MockInterstitialPageDelegate will be owned by the
65 // WebContents' InterstitialPage, and cleaned up when the WebContents
67 explicit MockInterstitialPageDelegate(
68 content::WebContents
* web_contents
) {
69 content::InterstitialPage
* interstitial_page
=
70 content::InterstitialPage::Create(
71 web_contents
, true, GURL("http://blah"), this);
72 interstitial_page
->DontCreateViewForTesting();
73 interstitial_page
->Show();
76 virtual ~MockInterstitialPageDelegate() {
80 // InterstitialPageDelegate implementation:
81 virtual std::string
GetHTMLContents() OVERRIDE
{
82 return "HTML Contents";
85 DISALLOW_COPY_AND_ASSIGN(MockInterstitialPageDelegate
);
88 class CaptivePortalTabReloaderTest
: public ChromeRenderViewHostTestHarness
{
91 virtual void SetUp() OVERRIDE
{
92 ChromeRenderViewHostTestHarness::SetUp();
93 tab_reloader_
.reset(new testing::StrictMock
<TestCaptivePortalTabReloader
>(
96 // Most tests don't run the message loop, so don't use a timer for them.
97 tab_reloader_
->set_slow_ssl_load_time(base::TimeDelta());
100 virtual void TearDown() OVERRIDE
{
101 EXPECT_FALSE(tab_reloader().TimerRunning());
102 tab_reloader_
.reset(NULL
);
103 ChromeRenderViewHostTestHarness::TearDown();
106 TestCaptivePortalTabReloader
& tab_reloader() { return *tab_reloader_
.get(); }
109 scoped_ptr
<TestCaptivePortalTabReloader
> tab_reloader_
;
112 // Simulates a slow SSL load when the Internet is connected.
113 TEST_F(CaptivePortalTabReloaderTest
, InternetConnected
) {
114 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
116 tab_reloader().OnLoadStart(true);
117 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
118 tab_reloader().state());
119 EXPECT_TRUE(tab_reloader().TimerRunning());
121 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
122 base::MessageLoop::current()->RunUntilIdle();
123 EXPECT_FALSE(tab_reloader().TimerRunning());
124 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
125 tab_reloader().state());
127 tab_reloader().OnCaptivePortalResults(
128 captive_portal::RESULT_INTERNET_CONNECTED
,
129 captive_portal::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(
156 captive_portal::RESULT_INTERNET_CONNECTED
,
157 captive_portal::RESULT_INTERNET_CONNECTED
);
159 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
162 // Simulates a slow SSL load when captive portal checks return no response.
163 TEST_F(CaptivePortalTabReloaderTest
, NoResponse
) {
164 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
166 tab_reloader().OnLoadStart(true);
167 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
168 tab_reloader().state());
169 EXPECT_TRUE(tab_reloader().TimerRunning());
171 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
172 base::MessageLoop::current()->RunUntilIdle();
173 EXPECT_FALSE(tab_reloader().TimerRunning());
174 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
175 tab_reloader().state());
177 tab_reloader().OnCaptivePortalResults(captive_portal::RESULT_NO_RESPONSE
,
178 captive_portal::RESULT_NO_RESPONSE
);
180 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
181 EXPECT_FALSE(tab_reloader().TimerRunning());
183 tab_reloader().OnLoadCommitted(net::OK
);
184 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
187 // Simulates a slow HTTP load when behind a captive portal, that eventually.
188 // tiems out. Since it's HTTP, the TabReloader should do nothing.
189 TEST_F(CaptivePortalTabReloaderTest
, DoesNothingOnHttp
) {
190 tab_reloader().OnLoadStart(false);
191 EXPECT_FALSE(tab_reloader().TimerRunning());
192 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
194 tab_reloader().OnCaptivePortalResults(
195 captive_portal::RESULT_INTERNET_CONNECTED
,
196 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
197 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
200 tab_reloader().OnCaptivePortalResults(
201 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
202 captive_portal::RESULT_INTERNET_CONNECTED
);
203 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
205 // The page times out.
206 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
207 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
210 // Simulate the normal login process. The user logs in before the error page
211 // in the original tab commits.
212 TEST_F(CaptivePortalTabReloaderTest
, Login
) {
213 tab_reloader().OnLoadStart(true);
215 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
216 base::MessageLoop::current()->RunUntilIdle();
217 EXPECT_FALSE(tab_reloader().TimerRunning());
218 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
219 tab_reloader().state());
221 // The captive portal service detects a captive portal. The TabReloader
222 // should try and create a new login tab in response.
223 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
224 tab_reloader().OnCaptivePortalResults(
225 captive_portal::RESULT_INTERNET_CONNECTED
,
226 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
227 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
228 tab_reloader().state());
229 EXPECT_FALSE(tab_reloader().TimerRunning());
231 // The user logs on from another tab, and a captive portal check is triggered.
232 tab_reloader().OnCaptivePortalResults(
233 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
234 captive_portal::RESULT_INTERNET_CONNECTED
);
235 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
236 tab_reloader().state());
238 // The error page commits, which should start an asynchronous reload.
239 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
240 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
241 tab_reloader().state());
243 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
244 base::MessageLoop::current()->RunUntilIdle();
245 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
248 // Simulate the normal login process. The user logs in after the tab finishes
249 // loading the error page.
250 TEST_F(CaptivePortalTabReloaderTest
, LoginLate
) {
251 tab_reloader().OnLoadStart(true);
253 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
254 base::MessageLoop::current()->RunUntilIdle();
255 EXPECT_FALSE(tab_reloader().TimerRunning());
256 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
257 tab_reloader().state());
259 // The captive portal service detects a captive portal. The TabReloader
260 // should try and create a new login tab in response.
261 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
262 tab_reloader().OnCaptivePortalResults(
263 captive_portal::RESULT_INTERNET_CONNECTED
,
264 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
265 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
266 tab_reloader().state());
267 EXPECT_FALSE(tab_reloader().TimerRunning());
269 // The error page commits.
270 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
271 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
272 tab_reloader().state());
274 // The user logs on from another tab, and a captive portal check is triggered.
275 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
276 tab_reloader().OnCaptivePortalResults(
277 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
278 captive_portal::RESULT_INTERNET_CONNECTED
);
279 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
282 // Simulate a login after the tab times out unexpectedly quickly.
283 TEST_F(CaptivePortalTabReloaderTest
, TimeoutFast
) {
284 tab_reloader().OnLoadStart(true);
286 // The error page commits, which should trigger a captive portal check,
287 // since the timer's still running.
288 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
289 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
290 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
291 tab_reloader().state());
293 // The captive portal service detects a captive portal. The TabReloader
294 // should try and create a new login tab in response.
295 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
296 tab_reloader().OnCaptivePortalResults(
297 captive_portal::RESULT_INTERNET_CONNECTED
,
298 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
299 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
300 tab_reloader().state());
301 EXPECT_FALSE(tab_reloader().TimerRunning());
303 // The user logs on from another tab, and a captive portal check is triggered.
304 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
305 tab_reloader().OnCaptivePortalResults(
306 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
307 captive_portal::RESULT_INTERNET_CONNECTED
);
308 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
311 // An SSL protocol error triggers a captive portal check behind a captive
312 // portal. The user then logs in.
313 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolError
) {
314 tab_reloader().OnLoadStart(true);
316 // The error page commits, which should trigger a captive portal check,
317 // since the timer's still running.
318 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
319 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
320 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
321 tab_reloader().state());
323 // The captive portal service detects a captive portal. The TabReloader
324 // should try and create a new login tab in response.
325 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
326 tab_reloader().OnCaptivePortalResults(
327 captive_portal::RESULT_INTERNET_CONNECTED
,
328 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
329 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
330 tab_reloader().state());
331 EXPECT_FALSE(tab_reloader().TimerRunning());
333 // The user logs on from another tab, and a captive portal check is triggered.
334 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
335 tab_reloader().OnCaptivePortalResults(
336 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
337 captive_portal::RESULT_INTERNET_CONNECTED
);
338 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
341 // An SSL protocol error triggers a captive portal check behind a captive
342 // portal. The user logs in before the results from the captive portal check
344 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolErrorFastLogin
) {
345 tab_reloader().OnLoadStart(true);
347 // The error page commits, which should trigger a captive portal check,
348 // since the timer's still running.
349 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
350 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
351 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
352 tab_reloader().state());
354 // The user has logged in from another tab. The tab automatically reloads.
355 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
356 tab_reloader().OnCaptivePortalResults(
357 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
358 captive_portal::RESULT_INTERNET_CONNECTED
);
359 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
362 // An SSL protocol error triggers a captive portal check behind a captive
363 // portal. The user logs in before the results from the captive portal check
364 // completes. This case is probably not too likely, but should be handled.
365 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolErrorAlreadyLoggedIn
) {
366 tab_reloader().OnLoadStart(true);
368 // The user logs in from another tab before the tab errors out.
369 tab_reloader().OnCaptivePortalResults(
370 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
371 captive_portal::RESULT_INTERNET_CONNECTED
);
372 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
373 tab_reloader().state());
375 // The error page commits, which should trigger a reload.
376 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
377 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
378 base::MessageLoop::current()->RunUntilIdle();
379 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
382 // Simulate the case that a user has already logged in before the tab receives a
383 // captive portal result, but a RESULT_BEHIND_CAPTIVE_PORTAL was received
384 // before the tab started loading.
385 TEST_F(CaptivePortalTabReloaderTest
, AlreadyLoggedIn
) {
386 tab_reloader().OnLoadStart(true);
388 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
389 base::MessageLoop::current()->RunUntilIdle();
390 EXPECT_FALSE(tab_reloader().TimerRunning());
391 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
392 tab_reloader().state());
394 // The user has already logged in. Since the last result found a captive
395 // portal, the tab will be reloaded if a timeout is committed.
396 tab_reloader().OnCaptivePortalResults(
397 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
398 captive_portal::RESULT_INTERNET_CONNECTED
);
399 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
400 tab_reloader().state());
402 // The error page commits, which should start an asynchronous reload.
403 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
404 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
405 tab_reloader().state());
407 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
408 base::MessageLoop::current()->RunUntilIdle();
409 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
412 // Same as above, except the result is received even before the timer triggers,
413 // due to a captive portal test request from some external source, like a login
415 TEST_F(CaptivePortalTabReloaderTest
, AlreadyLoggedInBeforeTimerTriggers
) {
416 tab_reloader().OnLoadStart(true);
418 // The user has already logged in. Since the last result indicated there is
419 // a captive portal, the tab will be reloaded if it times out.
420 tab_reloader().OnCaptivePortalResults(
421 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
422 captive_portal::RESULT_INTERNET_CONNECTED
);
423 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
424 tab_reloader().state());
425 EXPECT_FALSE(tab_reloader().TimerRunning());
427 // The error page commits, which should start an asynchronous reload.
428 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
429 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
430 tab_reloader().state());
432 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
433 base::MessageLoop::current()->RunUntilIdle();
434 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
437 // Simulate the user logging in while the timer is still running. May happen
438 // if the tab is reloaded just before logging in on another tab.
439 TEST_F(CaptivePortalTabReloaderTest
, LoginWhileTimerRunning
) {
440 tab_reloader().OnLoadStart(true);
441 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
442 tab_reloader().state());
443 EXPECT_TRUE(tab_reloader().TimerRunning());
445 // The user has already logged in.
446 tab_reloader().OnCaptivePortalResults(
447 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
448 captive_portal::RESULT_INTERNET_CONNECTED
);
449 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
450 tab_reloader().state());
452 // The error page commits, which should start an asynchronous reload.
453 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
454 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
455 tab_reloader().state());
457 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
458 base::MessageLoop::current()->RunUntilIdle();
459 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
462 // Simulate a captive portal being detected while the time is still running.
463 // The captive portal check triggered by the timer detects the captive portal
464 // again, and then the user logs in.
465 TEST_F(CaptivePortalTabReloaderTest
, BehindPortalResultWhileTimerRunning
) {
466 tab_reloader().OnLoadStart(true);
467 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
468 tab_reloader().state());
469 EXPECT_TRUE(tab_reloader().TimerRunning());
471 // The user is behind a captive portal, but since the tab hasn't timed out,
472 // the message is ignored.
473 tab_reloader().OnCaptivePortalResults(
474 captive_portal::RESULT_INTERNET_CONNECTED
,
475 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
476 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
477 tab_reloader().state());
479 // The rest proceeds as normal.
480 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
481 base::MessageLoop::current()->RunUntilIdle();
482 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
483 tab_reloader().state());
485 // The captive portal service detects a captive portal, and this time the
486 // tab tries to create a login tab.
487 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
488 tab_reloader().OnCaptivePortalResults(
489 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
490 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
491 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
492 tab_reloader().state());
493 EXPECT_FALSE(tab_reloader().TimerRunning());
495 // The user logs on from another tab, and a captive portal check is triggered.
496 tab_reloader().OnCaptivePortalResults(
497 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
498 captive_portal::RESULT_INTERNET_CONNECTED
);
499 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
500 tab_reloader().state());
502 // The error page commits, which should start an asynchronous reload.
503 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
504 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
505 tab_reloader().state());
507 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
508 base::MessageLoop::current()->RunUntilIdle();
509 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
512 // The CaptivePortalService detects the user has logged in to a captive portal
513 // while the timer is still running, but the original load succeeds, so no
515 TEST_F(CaptivePortalTabReloaderTest
, LogInWhileTimerRunningNoError
) {
516 tab_reloader().OnLoadStart(true);
517 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
518 tab_reloader().state());
519 EXPECT_TRUE(tab_reloader().TimerRunning());
521 // The user has already logged in.
522 tab_reloader().OnCaptivePortalResults(
523 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
524 captive_portal::RESULT_INTERNET_CONNECTED
);
525 EXPECT_FALSE(tab_reloader().TimerRunning());
526 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
527 tab_reloader().state());
529 // The page successfully commits, so no reload is triggered.
530 tab_reloader().OnLoadCommitted(net::OK
);
531 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
534 // Simulate the login process when there's an SSL certificate error.
535 TEST_F(CaptivePortalTabReloaderTest
, SSLCertErrorLogin
) {
536 tab_reloader().OnLoadStart(true);
537 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
538 tab_reloader().state());
540 // The load is interrupted by an interstitial page. The interstitial page
541 // is created after the TabReloader is notified.
542 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal());
543 net::SSLInfo ssl_info
;
544 ssl_info
.SetCertError(net::CERT_STATUS_COMMON_NAME_INVALID
);
545 tab_reloader().OnSSLCertError(ssl_info
);
546 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
547 tab_reloader().state());
548 EXPECT_FALSE(tab_reloader().TimerRunning());
549 // The MockInterstitialPageDelegate will cleaned up by the WebContents.
550 new MockInterstitialPageDelegate(web_contents());
552 // Captive portal probe finds a captive portal.
553 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
554 tab_reloader().OnCaptivePortalResults(
555 captive_portal::RESULT_INTERNET_CONNECTED
,
556 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
558 // The user logs in. Since the interstitial is showing, the page should
559 // be reloaded, despite still having a provisional load.
560 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
561 tab_reloader().OnCaptivePortalResults(
562 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
563 captive_portal::RESULT_INTERNET_CONNECTED
);
566 // Simulate an HTTP redirect to HTTPS, when the Internet is connected.
567 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpsRedirectInternetConnected
) {
568 tab_reloader().OnLoadStart(false);
569 // There should be no captive portal check pending.
570 base::MessageLoop::current()->RunUntilIdle();
572 // HTTP to HTTPS redirect.
573 tab_reloader().OnRedirect(true);
574 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
575 tab_reloader().state());
576 EXPECT_TRUE(tab_reloader().TimerRunning());
578 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
579 base::MessageLoop::current()->RunUntilIdle();
580 EXPECT_FALSE(tab_reloader().TimerRunning());
581 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
582 tab_reloader().state());
584 tab_reloader().OnCaptivePortalResults(
585 captive_portal::RESULT_INTERNET_CONNECTED
,
586 captive_portal::RESULT_INTERNET_CONNECTED
);
588 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
589 EXPECT_FALSE(tab_reloader().TimerRunning());
591 tab_reloader().OnLoadCommitted(net::OK
);
592 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
595 // Simulate an HTTP redirect to HTTPS and subsequent Login, when the user logs
596 // in before the original page commits.
597 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpsRedirectLogin
) {
598 tab_reloader().OnLoadStart(false);
599 // There should be no captive portal check pending.
600 base::MessageLoop::current()->RunUntilIdle();
602 // HTTP to HTTPS redirect.
603 tab_reloader().OnRedirect(true);
604 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
605 tab_reloader().state());
607 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
608 base::MessageLoop::current()->RunUntilIdle();
609 EXPECT_FALSE(tab_reloader().TimerRunning());
610 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
611 tab_reloader().state());
613 // The captive portal service detects a captive portal. The TabReloader
614 // should try and create a new login tab in response.
615 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
616 tab_reloader().OnCaptivePortalResults(
617 captive_portal::RESULT_INTERNET_CONNECTED
,
618 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
619 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
620 tab_reloader().state());
621 EXPECT_FALSE(tab_reloader().TimerRunning());
623 // The user logs on from another tab, and a captive portal check is triggered.
624 tab_reloader().OnCaptivePortalResults(
625 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
626 captive_portal::RESULT_INTERNET_CONNECTED
);
627 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
628 tab_reloader().state());
630 // The error page commits, which should start an asynchronous reload.
631 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
632 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
633 tab_reloader().state());
635 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
636 base::MessageLoop::current()->RunUntilIdle();
637 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
640 // Simulate the case where an HTTPs page redirects to an HTTPS page, before
641 // the timer triggers.
642 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpRedirect
) {
643 tab_reloader().OnLoadStart(true);
644 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
645 tab_reloader().state());
647 tab_reloader().OnRedirect(false);
648 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
649 EXPECT_FALSE(tab_reloader().TimerRunning());
651 // There should be no captive portal check pending after the redirect.
652 base::MessageLoop::current()->RunUntilIdle();
654 // Logging in shouldn't do anything.
655 tab_reloader().OnCaptivePortalResults(
656 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
657 captive_portal::RESULT_INTERNET_CONNECTED
);
658 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
661 // Check that an HTTPS to HTTPS redirect results in no timer running.
662 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpsRedirect
) {
663 tab_reloader().OnLoadStart(true);
664 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
665 tab_reloader().state());
667 tab_reloader().OnRedirect(true);
668 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
669 EXPECT_FALSE(tab_reloader().TimerRunning());
670 // Nothing should happen.
671 base::MessageLoop::current()->RunUntilIdle();
674 // Check that an HTTPS to HTTP to HTTPS redirect results in no timer running.
675 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpToHttpsRedirect
) {
676 tab_reloader().OnLoadStart(true);
677 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
678 tab_reloader().state());
680 tab_reloader().OnRedirect(false);
681 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
682 EXPECT_FALSE(tab_reloader().TimerRunning());
684 tab_reloader().OnRedirect(true);
685 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
686 EXPECT_FALSE(tab_reloader().TimerRunning());
687 // Nothing should happen.
688 base::MessageLoop::current()->RunUntilIdle();
691 // Check that an HTTP to HTTP redirect results in the timer not running.
692 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpRedirect
) {
693 tab_reloader().OnLoadStart(false);
694 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
696 tab_reloader().OnRedirect(false);
697 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
698 EXPECT_FALSE(tab_reloader().TimerRunning());
700 // There should be no captive portal check pending after the redirect.
701 base::MessageLoop::current()->RunUntilIdle();
703 // Logging in shouldn't do anything.
704 tab_reloader().OnCaptivePortalResults(
705 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
706 captive_portal::RESULT_INTERNET_CONNECTED
);
707 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());