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_helper.h"
7 #include "base/callback.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "chrome/browser/captive_portal/captive_portal_service.h"
10 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
13 #include "content/public/browser/notification_details.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_source.h"
16 #include "content/public/browser/notification_types.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/test_renderer_host.h"
21 #include "net/base/net_errors.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using captive_portal::CaptivePortalResult
;
26 using content::ResourceType
;
30 const char* const kHttpUrl
= "http://whatever.com/";
31 const char* const kHttpsUrl
= "https://whatever.com/";
33 // Used for cross-process navigations. Shouldn't actually matter whether this
34 // is different from kHttpsUrl, but best to keep things consistent.
35 const char* const kHttpsUrl2
= "https://cross_process.com/";
37 // Error pages use a "data:" URL. Shouldn't actually matter what this is.
38 const char* const kErrorPageUrl
= "data:blah";
40 // Some navigations behave differently depending on if they're cross-process
49 class MockCaptivePortalTabReloader
: public CaptivePortalTabReloader
{
51 MockCaptivePortalTabReloader()
52 : CaptivePortalTabReloader(NULL
, NULL
, base::Callback
<void()>()) {
55 MOCK_METHOD1(OnLoadStart
, void(bool));
56 MOCK_METHOD1(OnLoadCommitted
, void(int));
57 MOCK_METHOD0(OnAbort
, void());
58 MOCK_METHOD1(OnRedirect
, void(bool));
59 MOCK_METHOD2(OnCaptivePortalResults
,
60 void(CaptivePortalResult
, CaptivePortalResult
));
63 // Inherits from the ChromeRenderViewHostTestHarness to gain access to
64 // CreateTestWebContents. Since the tests need to micromanage order of
65 // WebContentsObserver function calls, does not actually make sure of
66 // the harness in any other way.
67 class CaptivePortalTabHelperTest
: public ChromeRenderViewHostTestHarness
{
69 CaptivePortalTabHelperTest()
71 mock_reloader_(new testing::StrictMock
<MockCaptivePortalTabReloader
>) {
72 tab_helper_
.SetTabReloaderForTest(mock_reloader_
);
74 ~CaptivePortalTabHelperTest() override
{}
76 void SetUp() override
{
77 ChromeRenderViewHostTestHarness::SetUp();
78 web_contents1_
.reset(CreateTestWebContents());
79 web_contents2_
.reset(CreateTestWebContents());
81 // This will simulate the initialization of the RenderFrame in the renderer
82 // process. This is needed because WebContents does not initialize a
83 // RenderFrame on construction, and the tests expect one to exist.
84 content::RenderFrameHostTester::For(main_render_frame1())
85 ->InitializeRenderFrameIfNeeded();
86 content::RenderFrameHostTester::For(main_render_frame2())
87 ->InitializeRenderFrameIfNeeded();
90 void TearDown() override
{
91 web_contents2_
.reset(NULL
);
92 web_contents1_
.reset(NULL
);
93 ChromeRenderViewHostTestHarness::TearDown();
96 // Simulates a successful load of |url|.
97 void SimulateSuccess(const GURL
& url
,
98 content::RenderViewHost
* render_view_host
) {
99 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
101 tab_helper().DidStartProvisionalLoadForFrame(
102 render_view_host
->GetMainFrame(), url
, false, false);
104 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
105 tab_helper().DidCommitProvisionalLoadForFrame(
106 render_view_host
->GetMainFrame(),
108 ui::PAGE_TRANSITION_LINK
);
111 // Simulates a connection timeout while requesting |url|.
112 void SimulateTimeout(const GURL
& url
,
113 content::RenderViewHost
* render_view_host
) {
114 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
116 tab_helper().DidStartProvisionalLoadForFrame(
117 render_view_host
->GetMainFrame(), url
, false, false);
119 tab_helper().DidFailProvisionalLoad(render_view_host
->GetMainFrame(),
125 // Provisional load starts for the error page.
126 tab_helper().DidStartProvisionalLoadForFrame(
127 render_view_host
->GetMainFrame(), GURL(kErrorPageUrl
), true, false);
129 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
130 tab_helper().DidCommitProvisionalLoadForFrame(
131 render_view_host
->GetMainFrame(),
133 ui::PAGE_TRANSITION_LINK
);
136 // Simulates an abort while requesting |url|.
137 void SimulateAbort(const GURL
& url
,
138 content::RenderViewHost
* render_view_host
,
139 NavigationType navigation_type
) {
140 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
142 tab_helper().DidStartProvisionalLoadForFrame(
143 render_view_host
->GetMainFrame(), url
, false, false);
145 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
146 if (navigation_type
== kSameProcess
) {
147 tab_helper().DidFailProvisionalLoad(render_view_host
->GetMainFrame(),
153 // For interrupted provisional cross-process navigations, the
154 // RenderViewHost is destroyed without sending a DidFailProvisionalLoad
156 tab_helper().RenderViewDeleted(render_view_host
);
159 // Make sure that above call resulted in abort, for tests that continue
161 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
164 // Simulates an abort while loading an error page.
165 void SimulateAbortTimeout(const GURL
& url
,
166 content::RenderViewHost
* render_view_host
,
167 NavigationType navigation_type
) {
168 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
170 tab_helper().DidStartProvisionalLoadForFrame(
171 render_view_host
->GetMainFrame(), url
, false, false);
173 tab_helper().DidFailProvisionalLoad(render_view_host
->GetMainFrame(),
179 // Start event for the error page.
180 tab_helper().DidStartProvisionalLoadForFrame(
181 render_view_host
->GetMainFrame(), url
, true, false);
183 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
184 if (navigation_type
== kSameProcess
) {
185 tab_helper().DidFailProvisionalLoad(render_view_host
->GetMainFrame(),
191 // For interrupted provisional cross-process navigations, the
192 // RenderViewHost is destroyed without sending a DidFailProvisionalLoad
194 tab_helper().RenderViewDeleted(render_view_host
);
197 // Make sure that above call resulted in abort, for tests that continue
199 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
202 CaptivePortalTabHelper
& tab_helper() {
206 // Simulates a captive portal redirect by calling the Observe method.
207 void ObservePortalResult(CaptivePortalResult previous_result
,
208 CaptivePortalResult result
) {
209 content::Source
<Profile
> source_profile(NULL
);
211 CaptivePortalService::Results results
;
212 results
.previous_result
= previous_result
;
213 results
.result
= result
;
214 content::Details
<CaptivePortalService::Results
> details_results(&results
);
216 EXPECT_CALL(mock_reloader(), OnCaptivePortalResults(previous_result
,
218 tab_helper().Observe(chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
,
223 // Simulates a redirect. Uses OnRedirect rather than Observe, for simplicity.
224 void OnRedirect(ResourceType type
, const GURL
& new_url
, int child_id
) {
225 tab_helper().OnRedirect(child_id
, type
, new_url
);
228 MockCaptivePortalTabReloader
& mock_reloader() { return *mock_reloader_
; }
230 void SetIsLoginTab() {
231 tab_helper().SetIsLoginTab();
234 content::RenderViewHost
* render_view_host1() {
235 return web_contents1_
->GetRenderViewHost();
238 content::RenderViewHost
* render_view_host2() {
239 return web_contents2_
->GetRenderViewHost();
242 content::RenderFrameHost
* main_render_frame1() {
243 return web_contents1_
->GetMainFrame();
246 content::RenderFrameHost
* main_render_frame2() {
247 return web_contents2_
->GetMainFrame();
251 // Only the RenderViewHosts are used.
252 scoped_ptr
<content::WebContents
> web_contents1_
;
253 scoped_ptr
<content::WebContents
> web_contents2_
;
255 CaptivePortalTabHelper tab_helper_
;
257 // Owned by |tab_helper_|.
258 testing::StrictMock
<MockCaptivePortalTabReloader
>* mock_reloader_
;
260 DISALLOW_COPY_AND_ASSIGN(CaptivePortalTabHelperTest
);
263 TEST_F(CaptivePortalTabHelperTest
, HttpSuccess
) {
264 SimulateSuccess(GURL(kHttpUrl
), render_view_host1());
265 tab_helper().DidStopLoading();
268 TEST_F(CaptivePortalTabHelperTest
, HttpTimeout
) {
269 SimulateTimeout(GURL(kHttpUrl
), render_view_host1());
270 tab_helper().DidStopLoading();
273 // Same as above, but simulates what happens when the Link Doctor is enabled,
274 // which adds another provisional load/commit for the error page, after the
276 TEST_F(CaptivePortalTabHelperTest
, HttpTimeoutLinkDoctor
) {
277 SimulateTimeout(GURL(kHttpUrl
), render_view_host1());
279 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
280 // Provisional load starts for the error page.
281 tab_helper().DidStartProvisionalLoadForFrame(
282 main_render_frame1(), GURL(kErrorPageUrl
), true, false);
284 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
285 tab_helper().DidCommitProvisionalLoadForFrame(main_render_frame1(),
287 ui::PAGE_TRANSITION_LINK
);
288 tab_helper().DidStopLoading();
291 TEST_F(CaptivePortalTabHelperTest
, HttpsSuccess
) {
292 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
293 tab_helper().DidStopLoading();
294 EXPECT_FALSE(tab_helper().IsLoginTab());
297 TEST_F(CaptivePortalTabHelperTest
, HttpsTimeout
) {
298 SimulateTimeout(GURL(kHttpsUrl
), render_view_host1());
299 // Make sure no state was carried over from the timeout.
300 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
301 EXPECT_FALSE(tab_helper().IsLoginTab());
304 TEST_F(CaptivePortalTabHelperTest
, HttpsAbort
) {
305 SimulateAbort(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
306 // Make sure no state was carried over from the abort.
307 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
308 EXPECT_FALSE(tab_helper().IsLoginTab());
311 // A cross-process navigation is aborted by a same-site navigation.
312 TEST_F(CaptivePortalTabHelperTest
, AbortCrossProcess
) {
313 SimulateAbort(GURL(kHttpsUrl2
), render_view_host2(), kCrossProcess
);
314 // Make sure no state was carried over from the abort.
315 SimulateSuccess(GURL(kHttpUrl
), render_view_host1());
316 EXPECT_FALSE(tab_helper().IsLoginTab());
319 // Abort while there's a provisional timeout error page loading.
320 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeout
) {
321 SimulateAbortTimeout(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
322 // Make sure no state was carried over from the timeout or the abort.
323 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
324 EXPECT_FALSE(tab_helper().IsLoginTab());
327 // Abort a cross-process navigation while there's a provisional timeout error
329 TEST_F(CaptivePortalTabHelperTest
, AbortTimeoutCrossProcess
) {
330 SimulateAbortTimeout(GURL(kHttpsUrl2
), render_view_host2(),
332 // Make sure no state was carried over from the timeout or the abort.
333 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
334 EXPECT_FALSE(tab_helper().IsLoginTab());
337 // Opposite case from above - a same-process error page is aborted in favor of
338 // a cross-process one.
339 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeoutForCrossProcess
) {
340 SimulateAbortTimeout(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
341 // Make sure no state was carried over from the timeout or the abort.
342 SimulateSuccess(GURL(kHttpsUrl2
), render_view_host2());
343 EXPECT_FALSE(tab_helper().IsLoginTab());
346 // A provisional same-site navigation is interrupted by a cross-process
347 // navigation without sending an abort first.
348 TEST_F(CaptivePortalTabHelperTest
, UnexpectedProvisionalLoad
) {
349 GURL same_site_url
= GURL(kHttpUrl
);
350 GURL cross_process_url
= GURL(kHttpsUrl2
);
352 // A same-site load for the original RenderViewHost starts.
353 EXPECT_CALL(mock_reloader(),
354 OnLoadStart(same_site_url
.SchemeIsCryptographic())).Times(1);
355 tab_helper().DidStartProvisionalLoadForFrame(
356 main_render_frame1(), same_site_url
, false, false);
358 // It's unexpectedly interrupted by a cross-process navigation, which starts
359 // navigating before the old navigation cancels. We generate an abort message
360 // for the old navigation.
361 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
362 EXPECT_CALL(mock_reloader(),
363 OnLoadStart(cross_process_url
.SchemeIsCryptographic())).Times(1);
364 tab_helper().DidStartProvisionalLoadForFrame(
365 main_render_frame2(), cross_process_url
, false, false);
367 // The cross-process navigation fails.
368 tab_helper().DidFailProvisionalLoad(main_render_frame2(),
374 // The same-site navigation finally is aborted.
375 tab_helper().DidFailProvisionalLoad(main_render_frame1(),
381 // The provisional load starts for the error page for the cross-process
383 tab_helper().DidStartProvisionalLoadForFrame(
384 main_render_frame2(), GURL(kErrorPageUrl
), true, false);
386 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_FAILED
)).Times(1);
387 tab_helper().DidCommitProvisionalLoadForFrame(main_render_frame2(),
389 ui::PAGE_TRANSITION_TYPED
);
392 // Similar to the above test, except the original RenderViewHost manages to
393 // commit before its navigation is aborted.
394 TEST_F(CaptivePortalTabHelperTest
, UnexpectedCommit
) {
395 GURL same_site_url
= GURL(kHttpUrl
);
396 GURL cross_process_url
= GURL(kHttpsUrl2
);
398 // A same-site load for the original RenderViewHost starts.
399 EXPECT_CALL(mock_reloader(),
400 OnLoadStart(same_site_url
.SchemeIsCryptographic())).Times(1);
401 tab_helper().DidStartProvisionalLoadForFrame(
402 main_render_frame1(), same_site_url
, false, false);
404 // It's unexpectedly interrupted by a cross-process navigation, which starts
405 // navigating before the old navigation cancels. We generate an abort message
406 // for the old navigation.
407 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
408 EXPECT_CALL(mock_reloader(),
409 OnLoadStart(cross_process_url
.SchemeIsCryptographic())).Times(1);
410 tab_helper().DidStartProvisionalLoadForFrame(
411 main_render_frame2(), cross_process_url
, false, false);
413 // The cross-process navigation fails.
414 tab_helper().DidFailProvisionalLoad(main_render_frame2(),
420 // The same-site navigation succeeds.
421 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
422 EXPECT_CALL(mock_reloader(),
423 OnLoadStart(same_site_url
.SchemeIsCryptographic())).Times(1);
424 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
425 tab_helper().DidCommitProvisionalLoadForFrame(
426 main_render_frame1(), same_site_url
, ui::PAGE_TRANSITION_LINK
);
429 // Simulates navigations for a number of subframes, and makes sure no
430 // CaptivePortalTabHelper function is called.
431 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframe
) {
432 GURL url
= GURL(kHttpsUrl
);
434 content::RenderFrameHostTester
* render_frame_host_tester
=
435 content::RenderFrameHostTester::For(main_render_frame1());
436 content::RenderFrameHost
* subframe1
=
437 render_frame_host_tester
->AppendChild("subframe1");
440 tab_helper().DidStartProvisionalLoadForFrame(subframe1
, url
, false, false);
441 tab_helper().DidCommitProvisionalLoadForFrame(
442 subframe1
, url
, ui::PAGE_TRANSITION_LINK
);
445 content::RenderFrameHost
* subframe2
=
446 render_frame_host_tester
->AppendChild("subframe2");
447 tab_helper().DidStartProvisionalLoadForFrame(subframe2
, url
, false, false);
448 tab_helper().DidFailProvisionalLoad(
449 subframe2
, url
, net::ERR_TIMED_OUT
, base::string16(), false);
450 tab_helper().DidStartProvisionalLoadForFrame(subframe2
, url
, true, false);
451 tab_helper().DidFailProvisionalLoad(
452 subframe2
, url
, net::ERR_ABORTED
, base::string16(), false);
455 content::RenderFrameHost
* subframe3
=
456 render_frame_host_tester
->AppendChild("subframe3");
457 tab_helper().DidStartProvisionalLoadForFrame(subframe3
, url
, false, false);
458 tab_helper().DidFailProvisionalLoad(
459 subframe3
, url
, net::ERR_ABORTED
, base::string16(), false);
462 // Simulates a subframe erroring out at the same time as a provisional load,
463 // but with a different error code. Make sure the TabHelper sees the correct
465 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframeParallelError
) {
466 // URL used by both frames.
467 GURL url
= GURL(kHttpsUrl
);
468 content::RenderFrameHost
* subframe
=
469 content::RenderFrameHostTester::For(main_render_frame1())
470 ->AppendChild("subframe");
473 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
475 tab_helper().DidStartProvisionalLoadForFrame(
476 main_render_frame1(), url
, false, false);
477 tab_helper().DidStartProvisionalLoadForFrame(subframe
, url
, false, false);
479 // Loads return errors.
480 tab_helper().DidFailProvisionalLoad(
481 main_render_frame1(), url
, net::ERR_UNEXPECTED
, base::string16(), false);
482 tab_helper().DidFailProvisionalLoad(
483 subframe
, url
, net::ERR_TIMED_OUT
, base::string16(), false);
485 // Provisional load starts for the error pages.
486 tab_helper().DidStartProvisionalLoadForFrame(
487 main_render_frame1(), url
, true, false);
488 tab_helper().DidStartProvisionalLoadForFrame(subframe
, url
, true, false);
490 // Error page load finishes.
491 tab_helper().DidCommitProvisionalLoadForFrame(
492 subframe
, url
, ui::PAGE_TRANSITION_AUTO_SUBFRAME
);
493 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_UNEXPECTED
)).Times(1);
494 tab_helper().DidCommitProvisionalLoadForFrame(
495 main_render_frame1(), url
, ui::PAGE_TRANSITION_LINK
);
498 // Simulates an HTTP to HTTPS redirect, which then times out.
499 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpsRedirectTimeout
) {
500 GURL
http_url(kHttpUrl
);
501 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
502 tab_helper().DidStartProvisionalLoadForFrame(
503 main_render_frame1(), http_url
, false, false);
505 GURL
https_url(kHttpsUrl
);
506 EXPECT_CALL(mock_reloader(), OnRedirect(true)).Times(1);
507 OnRedirect(content::RESOURCE_TYPE_MAIN_FRAME
,
509 render_view_host1()->GetProcess()->GetID());
511 tab_helper().DidFailProvisionalLoad(main_render_frame1(),
517 // Provisional load starts for the error page.
518 tab_helper().DidStartProvisionalLoadForFrame(
519 main_render_frame1(), GURL(kErrorPageUrl
), true, false);
521 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
522 tab_helper().DidCommitProvisionalLoadForFrame(main_render_frame1(),
524 ui::PAGE_TRANSITION_LINK
);
527 // Simulates an HTTPS to HTTP redirect.
528 TEST_F(CaptivePortalTabHelperTest
, HttpsToHttpRedirect
) {
529 GURL
https_url(kHttpsUrl
);
530 EXPECT_CALL(mock_reloader(), OnLoadStart(https_url
.SchemeIsCryptographic()))
532 tab_helper().DidStartProvisionalLoadForFrame(
533 main_render_frame1(), https_url
, false, false);
535 GURL
http_url(kHttpUrl
);
536 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsCryptographic()))
538 OnRedirect(content::RESOURCE_TYPE_MAIN_FRAME
, http_url
,
539 render_view_host1()->GetProcess()->GetID());
541 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
542 tab_helper().DidCommitProvisionalLoadForFrame(
543 main_render_frame1(), http_url
, ui::PAGE_TRANSITION_LINK
);
546 // Simulates an HTTPS to HTTPS redirect.
547 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpRedirect
) {
548 GURL
http_url(kHttpUrl
);
549 EXPECT_CALL(mock_reloader(), OnLoadStart(http_url
.SchemeIsCryptographic()))
551 tab_helper().DidStartProvisionalLoadForFrame(
552 main_render_frame1(), http_url
, false, false);
554 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsCryptographic()))
556 OnRedirect(content::RESOURCE_TYPE_MAIN_FRAME
, http_url
,
557 render_view_host1()->GetProcess()->GetID());
559 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
560 tab_helper().DidCommitProvisionalLoadForFrame(
561 main_render_frame1(), http_url
, ui::PAGE_TRANSITION_LINK
);
564 // Tests that a subframe redirect doesn't reset the timer to kick off a captive
565 // portal probe for the main frame if the main frame request is taking too long.
566 TEST_F(CaptivePortalTabHelperTest
, SubframeRedirect
) {
567 GURL
http_url(kHttpUrl
);
568 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
569 tab_helper().DidStartProvisionalLoadForFrame(
570 main_render_frame1(), http_url
, false, false);
572 GURL
https_url(kHttpsUrl
);
573 OnRedirect(content::RESOURCE_TYPE_SUB_FRAME
,
575 render_view_host1()->GetProcess()->GetID());
577 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
578 tab_helper().DidCommitProvisionalLoadForFrame(
579 main_render_frame1(), GURL(kErrorPageUrl
), ui::PAGE_TRANSITION_LINK
);
582 // Simulates a redirect, for another RenderViewHost.
583 TEST_F(CaptivePortalTabHelperTest
, OtherRenderViewHostRedirect
) {
584 GURL
http_url(kHttpUrl
);
585 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
586 tab_helper().DidStartProvisionalLoadForFrame(
587 main_render_frame1(), http_url
, false, false);
589 // Another RenderViewHost sees a redirect. None of the reloader's functions
591 GURL
https_url(kHttpsUrl
);
592 OnRedirect(content::RESOURCE_TYPE_MAIN_FRAME
,
594 render_view_host2()->GetProcess()->GetID());
596 tab_helper().DidFailProvisionalLoad(main_render_frame1(),
602 // Provisional load starts for the error page.
603 tab_helper().DidStartProvisionalLoadForFrame(
604 main_render_frame1(), GURL(kErrorPageUrl
), true, false);
606 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
607 tab_helper().DidCommitProvisionalLoadForFrame(main_render_frame1(),
609 ui::PAGE_TRANSITION_LINK
);
612 TEST_F(CaptivePortalTabHelperTest
, LoginTabLogin
) {
613 EXPECT_FALSE(tab_helper().IsLoginTab());
615 EXPECT_TRUE(tab_helper().IsLoginTab());
617 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
618 captive_portal::RESULT_INTERNET_CONNECTED
);
619 EXPECT_FALSE(tab_helper().IsLoginTab());
622 TEST_F(CaptivePortalTabHelperTest
, LoginTabError
) {
623 EXPECT_FALSE(tab_helper().IsLoginTab());
626 EXPECT_TRUE(tab_helper().IsLoginTab());
628 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
629 captive_portal::RESULT_NO_RESPONSE
);
630 EXPECT_FALSE(tab_helper().IsLoginTab());
633 TEST_F(CaptivePortalTabHelperTest
, LoginTabMultipleResultsBeforeLogin
) {
634 EXPECT_FALSE(tab_helper().IsLoginTab());
637 EXPECT_TRUE(tab_helper().IsLoginTab());
639 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
640 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
641 EXPECT_TRUE(tab_helper().IsLoginTab());
643 ObservePortalResult(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
644 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
645 EXPECT_TRUE(tab_helper().IsLoginTab());
647 ObservePortalResult(captive_portal::RESULT_NO_RESPONSE
,
648 captive_portal::RESULT_INTERNET_CONNECTED
);
649 EXPECT_FALSE(tab_helper().IsLoginTab());
652 TEST_F(CaptivePortalTabHelperTest
, NoLoginTab
) {
653 EXPECT_FALSE(tab_helper().IsLoginTab());
655 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
656 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
657 EXPECT_FALSE(tab_helper().IsLoginTab());
659 ObservePortalResult(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
660 captive_portal::RESULT_NO_RESPONSE
);
661 EXPECT_FALSE(tab_helper().IsLoginTab());
663 ObservePortalResult(captive_portal::RESULT_NO_RESPONSE
,
664 captive_portal::RESULT_INTERNET_CONNECTED
);
665 EXPECT_FALSE(tab_helper().IsLoginTab());