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 "net/base/net_errors.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 namespace captive_portal
{
28 const char* const kHttpUrl
= "http://whatever.com/";
29 const char* const kHttpsUrl
= "https://whatever.com/";
31 // Used for cross-process navigations. Shouldn't actually matter whether this
32 // is different from kHttpsUrl, but best to keep things consistent.
33 const char* const kHttpsUrl2
= "https://cross_process.com/";
35 // Error pages use a "data:" URL. Shouldn't actually matter what this is.
36 const char* const kErrorPageUrl
= "data:blah";
38 // Some navigations behave differently depending on if they're cross-process
47 class MockCaptivePortalTabReloader
: public CaptivePortalTabReloader
{
49 MockCaptivePortalTabReloader()
50 : CaptivePortalTabReloader(NULL
, NULL
, base::Callback
<void()>()) {
53 MOCK_METHOD1(OnLoadStart
, void(bool));
54 MOCK_METHOD1(OnLoadCommitted
, void(int));
55 MOCK_METHOD0(OnAbort
, void());
56 MOCK_METHOD1(OnRedirect
, void(bool));
57 MOCK_METHOD2(OnCaptivePortalResults
, void(Result
, Result
));
60 // Inherits from the ChromeRenderViewHostTestHarness to gain access to
61 // CreateTestWebContents. Since the tests need to micromanage order of
62 // WebContentsObserver function calls, does not actually make sure of
63 // the harness in any other way.
64 class CaptivePortalTabHelperTest
: public ChromeRenderViewHostTestHarness
{
66 CaptivePortalTabHelperTest()
68 mock_reloader_(new testing::StrictMock
<MockCaptivePortalTabReloader
>) {
69 tab_helper_
.SetTabReloaderForTest(mock_reloader_
);
71 virtual ~CaptivePortalTabHelperTest() {}
73 virtual void SetUp() OVERRIDE
{
74 ChromeRenderViewHostTestHarness::SetUp();
75 web_contents1_
.reset(CreateTestWebContents());
76 web_contents2_
.reset(CreateTestWebContents());
79 virtual void TearDown() OVERRIDE
{
80 web_contents2_
.reset(NULL
);
81 web_contents1_
.reset(NULL
);
82 ChromeRenderViewHostTestHarness::TearDown();
85 // Simulates a successful load of |url|.
86 void SimulateSuccess(const GURL
& url
,
87 content::RenderViewHost
* render_view_host
) {
88 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
89 tab_helper().DidStartProvisionalLoadForFrame(
90 1, -1, true, url
, false, false, render_view_host
);
92 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
93 tab_helper().DidCommitProvisionalLoadForFrame(
94 1, base::string16(), true, url
, content::PAGE_TRANSITION_LINK
,
98 // Simulates a connection timeout while requesting |url|.
99 void SimulateTimeout(const GURL
& url
,
100 content::RenderViewHost
* render_view_host
) {
101 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
102 tab_helper().DidStartProvisionalLoadForFrame(
103 1, -1, true, url
, false, false, render_view_host
);
105 tab_helper().DidFailProvisionalLoad(
106 1, base::string16(), true, url
, net::ERR_TIMED_OUT
, base::string16(),
109 // Provisional load starts for the error page.
110 tab_helper().DidStartProvisionalLoadForFrame(
111 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host
);
113 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
114 tab_helper().DidCommitProvisionalLoadForFrame(
115 1, base::string16(), true, GURL(kErrorPageUrl
),
116 content::PAGE_TRANSITION_LINK
, render_view_host
);
119 // Simulates an abort while requesting |url|.
120 void SimulateAbort(const GURL
& url
,
121 content::RenderViewHost
* render_view_host
,
122 NavigationType navigation_type
) {
123 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
124 tab_helper().DidStartProvisionalLoadForFrame(
125 1, -1, true, url
, false, false, render_view_host
);
127 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
128 if (navigation_type
== kSameProcess
) {
129 tab_helper().DidFailProvisionalLoad(
130 1, base::string16(), true, url
, net::ERR_ABORTED
, base::string16(),
133 // For interrupted provisional cross-process navigations, the
134 // RenderViewHost is destroyed without sending a DidFailProvisionalLoad
136 tab_helper().RenderViewDeleted(render_view_host
);
139 // Make sure that above call resulted in abort, for tests that continue
141 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
144 // Simulates an abort while loading an error page.
145 void SimulateAbortTimeout(const GURL
& url
,
146 content::RenderViewHost
* render_view_host
,
147 NavigationType navigation_type
) {
148 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
149 tab_helper().DidStartProvisionalLoadForFrame(
150 1, -1, true, url
, false, false, render_view_host
);
152 tab_helper().DidFailProvisionalLoad(
153 1, base::string16(), true, url
, net::ERR_TIMED_OUT
, base::string16(),
156 // Start event for the error page.
157 tab_helper().DidStartProvisionalLoadForFrame(
158 1, -1, true, url
, true, false, render_view_host
);
160 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
161 if (navigation_type
== kSameProcess
) {
162 tab_helper().DidFailProvisionalLoad(
163 1, base::string16(), true, url
, net::ERR_ABORTED
, base::string16(),
166 // For interrupted provisional cross-process navigations, the
167 // RenderViewHost is destroyed without sending a DidFailProvisionalLoad
169 tab_helper().RenderViewDeleted(render_view_host
);
172 // Make sure that above call resulted in abort, for tests that continue
174 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
177 CaptivePortalTabHelper
& tab_helper() {
181 // Simulates a captive portal redirect by calling the Observe method.
182 void ObservePortalResult(Result previous_result
, Result result
) {
183 content::Source
<Profile
> source_profile(NULL
);
185 CaptivePortalService::Results results
;
186 results
.previous_result
= previous_result
;
187 results
.result
= result
;
188 content::Details
<CaptivePortalService::Results
> details_results(&results
);
190 EXPECT_CALL(mock_reloader(), OnCaptivePortalResults(previous_result
,
192 tab_helper().Observe(chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
,
197 // Simulates a redirect. Uses OnRedirect rather than Observe, for simplicity.
198 void OnRedirect(ResourceType::Type type
, const GURL
& new_url
, int child_id
) {
199 tab_helper().OnRedirect(child_id
, type
, new_url
);
202 MockCaptivePortalTabReloader
& mock_reloader() { return *mock_reloader_
; }
204 void SetIsLoginTab() {
205 tab_helper().SetIsLoginTab();
208 content::RenderViewHost
* render_view_host1() {
209 return web_contents1_
->GetRenderViewHost();
212 content::RenderViewHost
* render_view_host2() {
213 return web_contents2_
->GetRenderViewHost();
217 // Only the RenderViewHosts are used.
218 scoped_ptr
<content::WebContents
> web_contents1_
;
219 scoped_ptr
<content::WebContents
> web_contents2_
;
221 CaptivePortalTabHelper tab_helper_
;
223 // Owned by |tab_helper_|.
224 testing::StrictMock
<MockCaptivePortalTabReloader
>* mock_reloader_
;
226 DISALLOW_COPY_AND_ASSIGN(CaptivePortalTabHelperTest
);
229 TEST_F(CaptivePortalTabHelperTest
, HttpSuccess
) {
230 SimulateSuccess(GURL(kHttpUrl
), render_view_host1());
231 tab_helper().DidStopLoading(render_view_host1());
234 TEST_F(CaptivePortalTabHelperTest
, HttpTimeout
) {
235 SimulateTimeout(GURL(kHttpUrl
), render_view_host1());
236 tab_helper().DidStopLoading(render_view_host1());
239 // Same as above, but simulates what happens when the Link Doctor is enabled,
240 // which adds another provisional load/commit for the error page, after the
242 TEST_F(CaptivePortalTabHelperTest
, HttpTimeoutLinkDoctor
) {
243 SimulateTimeout(GURL(kHttpUrl
), render_view_host1());
245 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
246 // Provisional load starts for the error page.
247 tab_helper().DidStartProvisionalLoadForFrame(
248 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host1());
250 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
251 tab_helper().DidCommitProvisionalLoadForFrame(
252 1, base::string16(), true, GURL(kErrorPageUrl
),
253 content::PAGE_TRANSITION_LINK
, render_view_host1());
254 tab_helper().DidStopLoading(render_view_host1());
257 TEST_F(CaptivePortalTabHelperTest
, HttpsSuccess
) {
258 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
259 tab_helper().DidStopLoading(render_view_host1());
260 EXPECT_FALSE(tab_helper().IsLoginTab());
263 TEST_F(CaptivePortalTabHelperTest
, HttpsTimeout
) {
264 SimulateTimeout(GURL(kHttpsUrl
), render_view_host1());
265 // Make sure no state was carried over from the timeout.
266 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
267 EXPECT_FALSE(tab_helper().IsLoginTab());
270 TEST_F(CaptivePortalTabHelperTest
, HttpsAbort
) {
271 SimulateAbort(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
272 // Make sure no state was carried over from the abort.
273 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
274 EXPECT_FALSE(tab_helper().IsLoginTab());
277 // A cross-process navigation is aborted by a same-site navigation.
278 TEST_F(CaptivePortalTabHelperTest
, AbortCrossProcess
) {
279 SimulateAbort(GURL(kHttpsUrl2
), render_view_host2(), kCrossProcess
);
280 // Make sure no state was carried over from the abort.
281 SimulateSuccess(GURL(kHttpUrl
), render_view_host1());
282 EXPECT_FALSE(tab_helper().IsLoginTab());
285 // Abort while there's a provisional timeout error page loading.
286 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeout
) {
287 SimulateAbortTimeout(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
288 // Make sure no state was carried over from the timeout or the abort.
289 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
290 EXPECT_FALSE(tab_helper().IsLoginTab());
293 // Abort a cross-process navigation while there's a provisional timeout error
295 TEST_F(CaptivePortalTabHelperTest
, AbortTimeoutCrossProcess
) {
296 SimulateAbortTimeout(GURL(kHttpsUrl2
), render_view_host2(),
298 // Make sure no state was carried over from the timeout or the abort.
299 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
300 EXPECT_FALSE(tab_helper().IsLoginTab());
303 // Opposite case from above - a same-process error page is aborted in favor of
304 // a cross-process one.
305 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeoutForCrossProcess
) {
306 SimulateAbortTimeout(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
307 // Make sure no state was carried over from the timeout or the abort.
308 SimulateSuccess(GURL(kHttpsUrl2
), render_view_host2());
309 EXPECT_FALSE(tab_helper().IsLoginTab());
312 // A provisional same-site navigation is interrupted by a cross-process
313 // navigation without sending an abort first.
314 TEST_F(CaptivePortalTabHelperTest
, UnexpectedProvisionalLoad
) {
315 GURL same_site_url
= GURL(kHttpUrl
);
316 GURL cross_process_url
= GURL(kHttpsUrl2
);
318 // A same-site load for the original RenderViewHost starts.
319 EXPECT_CALL(mock_reloader(),
320 OnLoadStart(same_site_url
.SchemeIsSecure())).Times(1);
321 tab_helper().DidStartProvisionalLoadForFrame(
322 1, -1, true, same_site_url
, false, false, render_view_host1());
324 // It's unexpectedly interrupted by a cross-process navigation, which starts
325 // navigating before the old navigation cancels. We generate an abort message
326 // for the old navigation.
327 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
328 EXPECT_CALL(mock_reloader(),
329 OnLoadStart(cross_process_url
.SchemeIsSecure())).Times(1);
330 tab_helper().DidStartProvisionalLoadForFrame(
331 1, -1, true, cross_process_url
, false, false, render_view_host2());
333 // The cross-process navigation fails.
334 tab_helper().DidFailProvisionalLoad(
335 1, base::string16(), true, cross_process_url
, net::ERR_FAILED
,
336 base::string16(), render_view_host2());
338 // The same-site navigation finally is aborted.
339 tab_helper().DidFailProvisionalLoad(
340 1, base::string16(), true, same_site_url
, net::ERR_ABORTED
,
341 base::string16(), render_view_host1());
343 // The provisional load starts for the error page for the cross-process
345 tab_helper().DidStartProvisionalLoadForFrame(
346 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host2());
348 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_FAILED
)).Times(1);
349 tab_helper().DidCommitProvisionalLoadForFrame(
350 1, base::string16(), true, GURL(kErrorPageUrl
),
351 content::PAGE_TRANSITION_TYPED
, render_view_host2());
354 // Similar to the above test, except the original RenderViewHost manages to
355 // commit before its navigation is aborted.
356 TEST_F(CaptivePortalTabHelperTest
, UnexpectedCommit
) {
357 GURL same_site_url
= GURL(kHttpUrl
);
358 GURL cross_process_url
= GURL(kHttpsUrl2
);
360 // A same-site load for the original RenderViewHost starts.
361 EXPECT_CALL(mock_reloader(),
362 OnLoadStart(same_site_url
.SchemeIsSecure())).Times(1);
363 tab_helper().DidStartProvisionalLoadForFrame(
364 1, -1, true, same_site_url
, false, false, render_view_host1());
366 // It's unexpectedly interrupted by a cross-process navigation, which starts
367 // navigating before the old navigation cancels. We generate an abort message
368 // for the old navigation.
369 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
370 EXPECT_CALL(mock_reloader(),
371 OnLoadStart(cross_process_url
.SchemeIsSecure())).Times(1);
372 tab_helper().DidStartProvisionalLoadForFrame(
373 1, -1, true, cross_process_url
, false, false, render_view_host2());
375 // The cross-process navigation fails.
376 tab_helper().DidFailProvisionalLoad(
377 1, base::string16(), true, cross_process_url
, net::ERR_FAILED
,
379 render_view_host2());
381 // The same-site navigation succeeds.
382 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
383 EXPECT_CALL(mock_reloader(),
384 OnLoadStart(same_site_url
.SchemeIsSecure())).Times(1);
385 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
386 tab_helper().DidCommitProvisionalLoadForFrame(
387 1, base::string16(), true, same_site_url
, content::PAGE_TRANSITION_LINK
,
388 render_view_host1());
391 // Simulates navigations for a number of subframes, and makes sure no
392 // CaptivePortalTabHelper function is called.
393 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframe
) {
394 GURL url
= GURL(kHttpsUrl
);
396 tab_helper().DidStartProvisionalLoadForFrame(
397 1, -1, false, url
, false, false, render_view_host1());
398 tab_helper().DidCommitProvisionalLoadForFrame(
399 1, base::string16(), false, url
, content::PAGE_TRANSITION_LINK
,
400 render_view_host1());
403 tab_helper().DidStartProvisionalLoadForFrame(
404 2, -1, false, url
, false, false, render_view_host1());
405 tab_helper().DidFailProvisionalLoad(
406 2, base::string16(), false, url
, net::ERR_TIMED_OUT
, base::string16(),
407 render_view_host1());
408 tab_helper().DidStartProvisionalLoadForFrame(
409 2, -1, false, url
, true, false, render_view_host1());
410 tab_helper().DidFailProvisionalLoad(
411 2, base::string16(), false, url
, net::ERR_ABORTED
, base::string16(),
412 render_view_host1());
415 tab_helper().DidStartProvisionalLoadForFrame(
416 3, -1, false, url
, false, false, render_view_host1());
417 tab_helper().DidFailProvisionalLoad(
418 3, base::string16(), false, url
, net::ERR_ABORTED
, base::string16(),
419 render_view_host1());
422 // Simulates a subframe erroring out at the same time as a provisional load,
423 // but with a different error code. Make sure the TabHelper sees the correct
425 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframeParallelError
) {
426 // URL used by both frames.
427 GURL url
= GURL(kHttpsUrl
);
433 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
434 tab_helper().DidStartProvisionalLoadForFrame(
435 frame_id
, -1, true, url
, false, false, render_view_host1());
436 tab_helper().DidStartProvisionalLoadForFrame(
437 subframe_id
, frame_id
, false, url
, false, false, render_view_host1());
439 // Loads return errors.
440 tab_helper().DidFailProvisionalLoad(
441 frame_id
, base::string16(), true, url
, net::ERR_UNEXPECTED
,
442 base::string16(), render_view_host1());
443 tab_helper().DidFailProvisionalLoad(
444 subframe_id
, base::string16(), false, url
, net::ERR_TIMED_OUT
,
445 base::string16(), render_view_host1());
447 // Provisional load starts for the error pages.
448 tab_helper().DidStartProvisionalLoadForFrame(
449 frame_id
, -1, true, url
, true, false, render_view_host1());
450 tab_helper().DidStartProvisionalLoadForFrame(
451 subframe_id
, frame_id
, false, url
, true, false, render_view_host1());
453 // Error page load finishes.
454 tab_helper().DidCommitProvisionalLoadForFrame(
455 subframe_id
, base::string16(), false, url
,
456 content::PAGE_TRANSITION_AUTO_SUBFRAME
, render_view_host1());
457 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_UNEXPECTED
)).Times(1);
458 tab_helper().DidCommitProvisionalLoadForFrame(
459 frame_id
, base::string16(), true, url
, content::PAGE_TRANSITION_LINK
,
460 render_view_host1());
463 // Simulates an HTTP to HTTPS redirect, which then times out.
464 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpsRedirectTimeout
) {
465 GURL
http_url(kHttpUrl
);
466 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
467 tab_helper().DidStartProvisionalLoadForFrame(
468 1, -1, true, http_url
, false, false, render_view_host1());
470 GURL
https_url(kHttpsUrl
);
471 EXPECT_CALL(mock_reloader(), OnRedirect(true)).Times(1);
472 OnRedirect(ResourceType::MAIN_FRAME
, https_url
,
473 render_view_host1()->GetProcess()->GetID());
475 tab_helper().DidFailProvisionalLoad(
476 1, base::string16(), true, https_url
, net::ERR_TIMED_OUT
,
477 base::string16(), render_view_host1());
479 // Provisional load starts for the error page.
480 tab_helper().DidStartProvisionalLoadForFrame(
481 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host1());
483 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
484 tab_helper().DidCommitProvisionalLoadForFrame(
485 1, base::string16(), true, GURL(kErrorPageUrl
),
486 content::PAGE_TRANSITION_LINK
, render_view_host1());
489 // Simulates an HTTPS to HTTP redirect.
490 TEST_F(CaptivePortalTabHelperTest
, HttpsToHttpRedirect
) {
491 GURL
https_url(kHttpsUrl
);
492 EXPECT_CALL(mock_reloader(),
493 OnLoadStart(https_url
.SchemeIsSecure())).Times(1);
494 tab_helper().DidStartProvisionalLoadForFrame(1, -1, true, https_url
, false,
495 false, render_view_host1());
497 GURL
http_url(kHttpUrl
);
498 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsSecure())).Times(1);
499 OnRedirect(ResourceType::MAIN_FRAME
, http_url
,
500 render_view_host1()->GetProcess()->GetID());
502 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
503 tab_helper().DidCommitProvisionalLoadForFrame(
504 1, base::string16(), true, http_url
, content::PAGE_TRANSITION_LINK
,
505 render_view_host1());
508 // Simulates an HTTPS to HTTPS redirect.
509 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpRedirect
) {
510 GURL
http_url(kHttpUrl
);
511 EXPECT_CALL(mock_reloader(),
512 OnLoadStart(http_url
.SchemeIsSecure())).Times(1);
513 tab_helper().DidStartProvisionalLoadForFrame(
514 1, -1, true, http_url
, false, false, render_view_host1());
516 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsSecure())).Times(1);
517 OnRedirect(ResourceType::MAIN_FRAME
, http_url
,
518 render_view_host1()->GetProcess()->GetID());
520 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
521 tab_helper().DidCommitProvisionalLoadForFrame(
522 1, base::string16(), true, http_url
, content::PAGE_TRANSITION_LINK
,
523 render_view_host1());
526 // Simulates redirect of a subframe.
527 TEST_F(CaptivePortalTabHelperTest
, SubframeRedirect
) {
528 GURL
http_url(kHttpUrl
);
529 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
530 tab_helper().DidStartProvisionalLoadForFrame(
531 1, -1, true, http_url
, false, false, render_view_host1());
533 GURL
https_url(kHttpsUrl
);
534 OnRedirect(ResourceType::SUB_FRAME
, https_url
,
535 render_view_host1()->GetProcess()->GetID());
537 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
538 tab_helper().DidCommitProvisionalLoadForFrame(
539 1, base::string16(), true, GURL(kErrorPageUrl
),
540 content::PAGE_TRANSITION_LINK
, render_view_host1());
543 // Simulates a redirect, for another RenderViewHost.
544 TEST_F(CaptivePortalTabHelperTest
, OtherRenderViewHostRedirect
) {
545 GURL
http_url(kHttpUrl
);
546 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
547 tab_helper().DidStartProvisionalLoadForFrame(
548 1, -1, true, http_url
, false, false, render_view_host1());
550 // Another RenderViewHost sees a redirect. None of the reloader's functions
552 GURL
https_url(kHttpsUrl
);
553 OnRedirect(ResourceType::MAIN_FRAME
, https_url
,
554 render_view_host2()->GetProcess()->GetID());
556 tab_helper().DidFailProvisionalLoad(
557 1, base::string16(), true, https_url
, net::ERR_TIMED_OUT
,
558 base::string16(), render_view_host1());
560 // Provisional load starts for the error page.
561 tab_helper().DidStartProvisionalLoadForFrame(
562 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host1());
564 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
565 tab_helper().DidCommitProvisionalLoadForFrame(
566 1, base::string16(), true, GURL(kErrorPageUrl
),
567 content::PAGE_TRANSITION_LINK
, render_view_host1());
570 TEST_F(CaptivePortalTabHelperTest
, LoginTabLogin
) {
571 EXPECT_FALSE(tab_helper().IsLoginTab());
573 EXPECT_TRUE(tab_helper().IsLoginTab());
575 ObservePortalResult(RESULT_INTERNET_CONNECTED
, RESULT_INTERNET_CONNECTED
);
576 EXPECT_FALSE(tab_helper().IsLoginTab());
579 TEST_F(CaptivePortalTabHelperTest
, LoginTabError
) {
580 EXPECT_FALSE(tab_helper().IsLoginTab());
583 EXPECT_TRUE(tab_helper().IsLoginTab());
585 ObservePortalResult(RESULT_INTERNET_CONNECTED
, RESULT_NO_RESPONSE
);
586 EXPECT_FALSE(tab_helper().IsLoginTab());
589 TEST_F(CaptivePortalTabHelperTest
, LoginTabMultipleResultsBeforeLogin
) {
590 EXPECT_FALSE(tab_helper().IsLoginTab());
593 EXPECT_TRUE(tab_helper().IsLoginTab());
595 ObservePortalResult(RESULT_INTERNET_CONNECTED
, RESULT_BEHIND_CAPTIVE_PORTAL
);
596 EXPECT_TRUE(tab_helper().IsLoginTab());
598 ObservePortalResult(RESULT_BEHIND_CAPTIVE_PORTAL
,
599 RESULT_BEHIND_CAPTIVE_PORTAL
);
600 EXPECT_TRUE(tab_helper().IsLoginTab());
602 ObservePortalResult(RESULT_NO_RESPONSE
, RESULT_INTERNET_CONNECTED
);
603 EXPECT_FALSE(tab_helper().IsLoginTab());
606 TEST_F(CaptivePortalTabHelperTest
, NoLoginTab
) {
607 EXPECT_FALSE(tab_helper().IsLoginTab());
609 ObservePortalResult(RESULT_INTERNET_CONNECTED
, RESULT_BEHIND_CAPTIVE_PORTAL
);
610 EXPECT_FALSE(tab_helper().IsLoginTab());
612 ObservePortalResult(RESULT_BEHIND_CAPTIVE_PORTAL
, RESULT_NO_RESPONSE
);
613 EXPECT_FALSE(tab_helper().IsLoginTab());
615 ObservePortalResult(RESULT_NO_RESPONSE
, RESULT_INTERNET_CONNECTED
);
616 EXPECT_FALSE(tab_helper().IsLoginTab());
619 } // namespace captive_portal