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 ~MockInterstitialPageDelegate() override
{}
79 // InterstitialPageDelegate implementation:
80 std::string
GetHTMLContents() override
{ return "HTML Contents"; }
82 DISALLOW_COPY_AND_ASSIGN(MockInterstitialPageDelegate
);
85 class CaptivePortalTabReloaderTest
: public ChromeRenderViewHostTestHarness
{
88 void SetUp() override
{
89 ChromeRenderViewHostTestHarness::SetUp();
90 tab_reloader_
.reset(new testing::StrictMock
<TestCaptivePortalTabReloader
>(
93 // Most tests don't run the message loop, so don't use a timer for them.
94 tab_reloader_
->set_slow_ssl_load_time(base::TimeDelta());
97 void TearDown() override
{
98 EXPECT_FALSE(tab_reloader().TimerRunning());
99 tab_reloader_
.reset(NULL
);
100 ChromeRenderViewHostTestHarness::TearDown();
103 TestCaptivePortalTabReloader
& tab_reloader() { return *tab_reloader_
.get(); }
106 scoped_ptr
<TestCaptivePortalTabReloader
> tab_reloader_
;
109 // Simulates a slow SSL load when the Internet is connected.
110 TEST_F(CaptivePortalTabReloaderTest
, InternetConnected
) {
111 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
113 tab_reloader().OnLoadStart(true);
114 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
115 tab_reloader().state());
116 EXPECT_TRUE(tab_reloader().TimerRunning());
118 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
119 base::MessageLoop::current()->RunUntilIdle();
120 EXPECT_FALSE(tab_reloader().TimerRunning());
121 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
122 tab_reloader().state());
124 tab_reloader().OnCaptivePortalResults(
125 captive_portal::RESULT_INTERNET_CONNECTED
,
126 captive_portal::RESULT_INTERNET_CONNECTED
);
128 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
129 EXPECT_FALSE(tab_reloader().TimerRunning());
131 tab_reloader().OnLoadCommitted(net::OK
);
132 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
135 // Simulates a slow SSL load when the Internet is connected. In this case,
136 // the timeout error occurs before the timer triggers. Unlikely to happen
137 // in practice, but best if it still works.
138 TEST_F(CaptivePortalTabReloaderTest
, InternetConnectedTimeout
) {
139 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
141 tab_reloader().OnLoadStart(true);
142 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
143 tab_reloader().state());
144 EXPECT_TRUE(tab_reloader().TimerRunning());
146 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
147 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
148 EXPECT_FALSE(tab_reloader().TimerRunning());
149 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
150 tab_reloader().state());
152 tab_reloader().OnCaptivePortalResults(
153 captive_portal::RESULT_INTERNET_CONNECTED
,
154 captive_portal::RESULT_INTERNET_CONNECTED
);
156 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
159 // Simulates a slow SSL load when captive portal checks return no response.
160 TEST_F(CaptivePortalTabReloaderTest
, NoResponse
) {
161 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
163 tab_reloader().OnLoadStart(true);
164 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
165 tab_reloader().state());
166 EXPECT_TRUE(tab_reloader().TimerRunning());
168 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
169 base::MessageLoop::current()->RunUntilIdle();
170 EXPECT_FALSE(tab_reloader().TimerRunning());
171 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
172 tab_reloader().state());
174 tab_reloader().OnCaptivePortalResults(captive_portal::RESULT_NO_RESPONSE
,
175 captive_portal::RESULT_NO_RESPONSE
);
177 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
178 EXPECT_FALSE(tab_reloader().TimerRunning());
180 tab_reloader().OnLoadCommitted(net::OK
);
181 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
184 // Simulates a slow HTTP load when behind a captive portal, that eventually.
185 // tiems out. Since it's HTTP, the TabReloader should do nothing.
186 TEST_F(CaptivePortalTabReloaderTest
, DoesNothingOnHttp
) {
187 tab_reloader().OnLoadStart(false);
188 EXPECT_FALSE(tab_reloader().TimerRunning());
189 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
191 tab_reloader().OnCaptivePortalResults(
192 captive_portal::RESULT_INTERNET_CONNECTED
,
193 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
194 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
197 tab_reloader().OnCaptivePortalResults(
198 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
199 captive_portal::RESULT_INTERNET_CONNECTED
);
200 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
202 // The page times out.
203 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
204 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
207 // Simulate the normal login process. The user logs in before the error page
208 // in the original tab commits.
209 TEST_F(CaptivePortalTabReloaderTest
, Login
) {
210 tab_reloader().OnLoadStart(true);
212 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
213 base::MessageLoop::current()->RunUntilIdle();
214 EXPECT_FALSE(tab_reloader().TimerRunning());
215 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
216 tab_reloader().state());
218 // The captive portal service detects a captive portal. The TabReloader
219 // should try and create a new login tab in response.
220 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
221 tab_reloader().OnCaptivePortalResults(
222 captive_portal::RESULT_INTERNET_CONNECTED
,
223 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
224 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
225 tab_reloader().state());
226 EXPECT_FALSE(tab_reloader().TimerRunning());
228 // The user logs on from another tab, and a captive portal check is triggered.
229 tab_reloader().OnCaptivePortalResults(
230 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
231 captive_portal::RESULT_INTERNET_CONNECTED
);
232 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
233 tab_reloader().state());
235 // The error page commits, which should start an asynchronous reload.
236 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
237 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
238 tab_reloader().state());
240 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
241 base::MessageLoop::current()->RunUntilIdle();
242 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
245 // Simulate the normal login process. The user logs in after the tab finishes
246 // loading the error page.
247 TEST_F(CaptivePortalTabReloaderTest
, LoginLate
) {
248 tab_reloader().OnLoadStart(true);
250 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
251 base::MessageLoop::current()->RunUntilIdle();
252 EXPECT_FALSE(tab_reloader().TimerRunning());
253 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
254 tab_reloader().state());
256 // The captive portal service detects a captive portal. The TabReloader
257 // should try and create a new login tab in response.
258 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
259 tab_reloader().OnCaptivePortalResults(
260 captive_portal::RESULT_INTERNET_CONNECTED
,
261 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
262 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
263 tab_reloader().state());
264 EXPECT_FALSE(tab_reloader().TimerRunning());
266 // The error page commits.
267 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
268 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
269 tab_reloader().state());
271 // The user logs on from another tab, and a captive portal check is triggered.
272 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
273 tab_reloader().OnCaptivePortalResults(
274 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
275 captive_portal::RESULT_INTERNET_CONNECTED
);
276 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
279 // Simulate a login after the tab times out unexpectedly quickly.
280 TEST_F(CaptivePortalTabReloaderTest
, TimeoutFast
) {
281 tab_reloader().OnLoadStart(true);
283 // The error page commits, which should trigger a captive portal check,
284 // since the timer's still running.
285 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
286 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
287 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
288 tab_reloader().state());
290 // The captive portal service detects a captive portal. The TabReloader
291 // should try and create a new login tab in response.
292 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
293 tab_reloader().OnCaptivePortalResults(
294 captive_portal::RESULT_INTERNET_CONNECTED
,
295 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
296 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
297 tab_reloader().state());
298 EXPECT_FALSE(tab_reloader().TimerRunning());
300 // The user logs on from another tab, and a captive portal check is triggered.
301 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
302 tab_reloader().OnCaptivePortalResults(
303 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
304 captive_portal::RESULT_INTERNET_CONNECTED
);
305 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
308 // An SSL protocol error triggers a captive portal check behind a captive
309 // portal. The user then logs in.
310 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolError
) {
311 tab_reloader().OnLoadStart(true);
313 // The error page commits, which should trigger a captive portal check,
314 // since the timer's still running.
315 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
316 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
317 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
318 tab_reloader().state());
320 // The captive portal service detects a captive portal. The TabReloader
321 // should try and create a new login tab in response.
322 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
323 tab_reloader().OnCaptivePortalResults(
324 captive_portal::RESULT_INTERNET_CONNECTED
,
325 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
326 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
327 tab_reloader().state());
328 EXPECT_FALSE(tab_reloader().TimerRunning());
330 // The user logs on from another tab, and a captive portal check is triggered.
331 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
332 tab_reloader().OnCaptivePortalResults(
333 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
334 captive_portal::RESULT_INTERNET_CONNECTED
);
335 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
338 // An SSL protocol error triggers a captive portal check behind a captive
339 // portal. The user logs in before the results from the captive portal check
341 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolErrorFastLogin
) {
342 tab_reloader().OnLoadStart(true);
344 // The error page commits, which should trigger a captive portal check,
345 // since the timer's still running.
346 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
347 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
348 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
349 tab_reloader().state());
351 // The user has logged in from another tab. The tab automatically reloads.
352 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
353 tab_reloader().OnCaptivePortalResults(
354 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
355 captive_portal::RESULT_INTERNET_CONNECTED
);
356 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
359 // An SSL protocol error triggers a captive portal check behind a captive
360 // portal. The user logs in before the results from the captive portal check
361 // completes. This case is probably not too likely, but should be handled.
362 TEST_F(CaptivePortalTabReloaderTest
, SSLProtocolErrorAlreadyLoggedIn
) {
363 tab_reloader().OnLoadStart(true);
365 // The user logs in from another tab before the tab errors out.
366 tab_reloader().OnCaptivePortalResults(
367 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
368 captive_portal::RESULT_INTERNET_CONNECTED
);
369 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
370 tab_reloader().state());
372 // The error page commits, which should trigger a reload.
373 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
374 tab_reloader().OnLoadCommitted(net::ERR_SSL_PROTOCOL_ERROR
);
375 base::MessageLoop::current()->RunUntilIdle();
376 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
379 // Simulate the case that a user has already logged in before the tab receives a
380 // captive portal result, but a RESULT_BEHIND_CAPTIVE_PORTAL was received
381 // before the tab started loading.
382 TEST_F(CaptivePortalTabReloaderTest
, AlreadyLoggedIn
) {
383 tab_reloader().OnLoadStart(true);
385 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
386 base::MessageLoop::current()->RunUntilIdle();
387 EXPECT_FALSE(tab_reloader().TimerRunning());
388 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
389 tab_reloader().state());
391 // The user has already logged in. Since the last result found a captive
392 // portal, the tab will be reloaded if a timeout is committed.
393 tab_reloader().OnCaptivePortalResults(
394 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
395 captive_portal::RESULT_INTERNET_CONNECTED
);
396 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
397 tab_reloader().state());
399 // The error page commits, which should start an asynchronous reload.
400 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
401 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
402 tab_reloader().state());
404 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
405 base::MessageLoop::current()->RunUntilIdle();
406 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
409 // Same as above, except the result is received even before the timer triggers,
410 // due to a captive portal test request from some external source, like a login
412 TEST_F(CaptivePortalTabReloaderTest
, AlreadyLoggedInBeforeTimerTriggers
) {
413 tab_reloader().OnLoadStart(true);
415 // The user has already logged in. Since the last result indicated there is
416 // a captive portal, the tab will be reloaded if it times out.
417 tab_reloader().OnCaptivePortalResults(
418 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
419 captive_portal::RESULT_INTERNET_CONNECTED
);
420 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
421 tab_reloader().state());
422 EXPECT_FALSE(tab_reloader().TimerRunning());
424 // The error page commits, which should start an asynchronous reload.
425 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
426 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
427 tab_reloader().state());
429 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
430 base::MessageLoop::current()->RunUntilIdle();
431 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
434 // Simulate the user logging in while the timer is still running. May happen
435 // if the tab is reloaded just before logging in on another tab.
436 TEST_F(CaptivePortalTabReloaderTest
, LoginWhileTimerRunning
) {
437 tab_reloader().OnLoadStart(true);
438 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
439 tab_reloader().state());
440 EXPECT_TRUE(tab_reloader().TimerRunning());
442 // The user has already logged in.
443 tab_reloader().OnCaptivePortalResults(
444 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
445 captive_portal::RESULT_INTERNET_CONNECTED
);
446 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
447 tab_reloader().state());
449 // The error page commits, which should start an asynchronous reload.
450 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
451 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
452 tab_reloader().state());
454 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
455 base::MessageLoop::current()->RunUntilIdle();
456 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
459 // Simulate a captive portal being detected while the time is still running.
460 // The captive portal check triggered by the timer detects the captive portal
461 // again, and then the user logs in.
462 TEST_F(CaptivePortalTabReloaderTest
, BehindPortalResultWhileTimerRunning
) {
463 tab_reloader().OnLoadStart(true);
464 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
465 tab_reloader().state());
466 EXPECT_TRUE(tab_reloader().TimerRunning());
468 // The user is behind a captive portal, but since the tab hasn't timed out,
469 // the message is ignored.
470 tab_reloader().OnCaptivePortalResults(
471 captive_portal::RESULT_INTERNET_CONNECTED
,
472 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
473 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
474 tab_reloader().state());
476 // The rest proceeds as normal.
477 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
478 base::MessageLoop::current()->RunUntilIdle();
479 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
480 tab_reloader().state());
482 // The captive portal service detects a captive portal, and this time the
483 // tab tries to create a login tab.
484 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
485 tab_reloader().OnCaptivePortalResults(
486 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
487 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
488 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
489 tab_reloader().state());
490 EXPECT_FALSE(tab_reloader().TimerRunning());
492 // The user logs on from another tab, and a captive portal check is triggered.
493 tab_reloader().OnCaptivePortalResults(
494 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
495 captive_portal::RESULT_INTERNET_CONNECTED
);
496 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
497 tab_reloader().state());
499 // The error page commits, which should start an asynchronous reload.
500 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
501 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
502 tab_reloader().state());
504 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
505 base::MessageLoop::current()->RunUntilIdle();
506 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
509 // The CaptivePortalService detects the user has logged in to a captive portal
510 // while the timer is still running, but the original load succeeds, so no
512 TEST_F(CaptivePortalTabReloaderTest
, LogInWhileTimerRunningNoError
) {
513 tab_reloader().OnLoadStart(true);
514 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
515 tab_reloader().state());
516 EXPECT_TRUE(tab_reloader().TimerRunning());
518 // The user has already logged in.
519 tab_reloader().OnCaptivePortalResults(
520 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
521 captive_portal::RESULT_INTERNET_CONNECTED
);
522 EXPECT_FALSE(tab_reloader().TimerRunning());
523 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
524 tab_reloader().state());
526 // The page successfully commits, so no reload is triggered.
527 tab_reloader().OnLoadCommitted(net::OK
);
528 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
531 // Simulate the login process when there's an SSL certificate error.
532 TEST_F(CaptivePortalTabReloaderTest
, SSLCertErrorLogin
) {
533 tab_reloader().OnLoadStart(true);
534 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
535 tab_reloader().state());
537 // The load is interrupted by an interstitial page. The interstitial page
538 // is created after the TabReloader is notified.
539 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal());
540 net::SSLInfo ssl_info
;
541 ssl_info
.SetCertError(net::CERT_STATUS_COMMON_NAME_INVALID
);
542 tab_reloader().OnSSLCertError(ssl_info
);
543 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
544 tab_reloader().state());
545 EXPECT_FALSE(tab_reloader().TimerRunning());
546 // The MockInterstitialPageDelegate will cleaned up by the WebContents.
547 new MockInterstitialPageDelegate(web_contents());
549 // Captive portal probe finds a captive portal.
550 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
551 tab_reloader().OnCaptivePortalResults(
552 captive_portal::RESULT_INTERNET_CONNECTED
,
553 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
555 // The user logs in. Since the interstitial is showing, the page should
556 // be reloaded, despite still having a provisional load.
557 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
558 tab_reloader().OnCaptivePortalResults(
559 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
560 captive_portal::RESULT_INTERNET_CONNECTED
);
563 // Simulate an HTTP redirect to HTTPS, when the Internet is connected.
564 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpsRedirectInternetConnected
) {
565 tab_reloader().OnLoadStart(false);
566 // There should be no captive portal check pending.
567 base::MessageLoop::current()->RunUntilIdle();
569 // HTTP to HTTPS redirect.
570 tab_reloader().OnRedirect(true);
571 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
572 tab_reloader().state());
573 EXPECT_TRUE(tab_reloader().TimerRunning());
575 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
576 base::MessageLoop::current()->RunUntilIdle();
577 EXPECT_FALSE(tab_reloader().TimerRunning());
578 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
579 tab_reloader().state());
581 tab_reloader().OnCaptivePortalResults(
582 captive_portal::RESULT_INTERNET_CONNECTED
,
583 captive_portal::RESULT_INTERNET_CONNECTED
);
585 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
586 EXPECT_FALSE(tab_reloader().TimerRunning());
588 tab_reloader().OnLoadCommitted(net::OK
);
589 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
592 // Simulate an HTTP redirect to HTTPS and subsequent Login, when the user logs
593 // in before the original page commits.
594 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpsRedirectLogin
) {
595 tab_reloader().OnLoadStart(false);
596 // There should be no captive portal check pending.
597 base::MessageLoop::current()->RunUntilIdle();
599 // HTTP to HTTPS redirect.
600 tab_reloader().OnRedirect(true);
601 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
602 tab_reloader().state());
604 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
605 base::MessageLoop::current()->RunUntilIdle();
606 EXPECT_FALSE(tab_reloader().TimerRunning());
607 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL
,
608 tab_reloader().state());
610 // The captive portal service detects a captive portal. The TabReloader
611 // should try and create a new login tab in response.
612 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
613 tab_reloader().OnCaptivePortalResults(
614 captive_portal::RESULT_INTERNET_CONNECTED
,
615 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
616 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
617 tab_reloader().state());
618 EXPECT_FALSE(tab_reloader().TimerRunning());
620 // The user logs on from another tab, and a captive portal check is triggered.
621 tab_reloader().OnCaptivePortalResults(
622 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
623 captive_portal::RESULT_INTERNET_CONNECTED
);
624 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
625 tab_reloader().state());
627 // The error page commits, which should start an asynchronous reload.
628 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT
);
629 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
,
630 tab_reloader().state());
632 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
633 base::MessageLoop::current()->RunUntilIdle();
634 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
637 // Simulate the case where an HTTPs page redirects to an HTTPS page, before
638 // the timer triggers.
639 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpRedirect
) {
640 tab_reloader().OnLoadStart(true);
641 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
642 tab_reloader().state());
644 tab_reloader().OnRedirect(false);
645 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
646 EXPECT_FALSE(tab_reloader().TimerRunning());
648 // There should be no captive portal check pending after the redirect.
649 base::MessageLoop::current()->RunUntilIdle();
651 // Logging in shouldn't do anything.
652 tab_reloader().OnCaptivePortalResults(
653 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
654 captive_portal::RESULT_INTERNET_CONNECTED
);
655 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
658 // Check that an HTTPS to HTTPS redirect results in no timer running.
659 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpsRedirect
) {
660 tab_reloader().OnLoadStart(true);
661 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
662 tab_reloader().state());
664 tab_reloader().OnRedirect(true);
665 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
666 EXPECT_FALSE(tab_reloader().TimerRunning());
667 // Nothing should happen.
668 base::MessageLoop::current()->RunUntilIdle();
671 // Check that an HTTPS to HTTP to HTTPS redirect results in no timer running.
672 TEST_F(CaptivePortalTabReloaderTest
, HttpsToHttpToHttpsRedirect
) {
673 tab_reloader().OnLoadStart(true);
674 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING
,
675 tab_reloader().state());
677 tab_reloader().OnRedirect(false);
678 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
679 EXPECT_FALSE(tab_reloader().TimerRunning());
681 tab_reloader().OnRedirect(true);
682 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
683 EXPECT_FALSE(tab_reloader().TimerRunning());
684 // Nothing should happen.
685 base::MessageLoop::current()->RunUntilIdle();
688 // Check that an HTTP to HTTP redirect results in the timer not running.
689 TEST_F(CaptivePortalTabReloaderTest
, HttpToHttpRedirect
) {
690 tab_reloader().OnLoadStart(false);
691 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
693 tab_reloader().OnRedirect(false);
694 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());
695 EXPECT_FALSE(tab_reloader().TimerRunning());
697 // There should be no captive portal check pending after the redirect.
698 base::MessageLoop::current()->RunUntilIdle();
700 // Logging in shouldn't do anything.
701 tab_reloader().OnCaptivePortalResults(
702 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
703 captive_portal::RESULT_INTERNET_CONNECTED
);
704 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
, tab_reloader().state());