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 using captive_portal::CaptivePortalResult
;
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
,
58 void(CaptivePortalResult
, CaptivePortalResult
));
61 // Inherits from the ChromeRenderViewHostTestHarness to gain access to
62 // CreateTestWebContents. Since the tests need to micromanage order of
63 // WebContentsObserver function calls, does not actually make sure of
64 // the harness in any other way.
65 class CaptivePortalTabHelperTest
: public ChromeRenderViewHostTestHarness
{
67 CaptivePortalTabHelperTest()
69 mock_reloader_(new testing::StrictMock
<MockCaptivePortalTabReloader
>) {
70 tab_helper_
.SetTabReloaderForTest(mock_reloader_
);
72 virtual ~CaptivePortalTabHelperTest() {}
74 virtual void SetUp() OVERRIDE
{
75 ChromeRenderViewHostTestHarness::SetUp();
76 web_contents1_
.reset(CreateTestWebContents());
77 web_contents2_
.reset(CreateTestWebContents());
80 virtual void TearDown() OVERRIDE
{
81 web_contents2_
.reset(NULL
);
82 web_contents1_
.reset(NULL
);
83 ChromeRenderViewHostTestHarness::TearDown();
86 // Simulates a successful load of |url|.
87 void SimulateSuccess(const GURL
& url
,
88 content::RenderViewHost
* render_view_host
) {
89 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
90 tab_helper().DidStartProvisionalLoadForFrame(
91 1, -1, true, url
, false, false, render_view_host
);
93 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
94 tab_helper().DidCommitProvisionalLoadForFrame(
95 1, base::string16(), true, url
, content::PAGE_TRANSITION_LINK
,
99 // Simulates a connection timeout while requesting |url|.
100 void SimulateTimeout(const GURL
& url
,
101 content::RenderViewHost
* render_view_host
) {
102 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
103 tab_helper().DidStartProvisionalLoadForFrame(
104 1, -1, true, url
, false, false, render_view_host
);
106 tab_helper().DidFailProvisionalLoad(
107 1, base::string16(), true, url
, net::ERR_TIMED_OUT
, base::string16(),
110 // Provisional load starts for the error page.
111 tab_helper().DidStartProvisionalLoadForFrame(
112 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host
);
114 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
115 tab_helper().DidCommitProvisionalLoadForFrame(
116 1, base::string16(), true, GURL(kErrorPageUrl
),
117 content::PAGE_TRANSITION_LINK
, render_view_host
);
120 // Simulates an abort while requesting |url|.
121 void SimulateAbort(const GURL
& url
,
122 content::RenderViewHost
* render_view_host
,
123 NavigationType navigation_type
) {
124 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
125 tab_helper().DidStartProvisionalLoadForFrame(
126 1, -1, true, url
, false, false, render_view_host
);
128 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
129 if (navigation_type
== kSameProcess
) {
130 tab_helper().DidFailProvisionalLoad(
131 1, base::string16(), true, url
, net::ERR_ABORTED
, base::string16(),
134 // For interrupted provisional cross-process navigations, the
135 // RenderViewHost is destroyed without sending a DidFailProvisionalLoad
137 tab_helper().RenderViewDeleted(render_view_host
);
140 // Make sure that above call resulted in abort, for tests that continue
142 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
145 // Simulates an abort while loading an error page.
146 void SimulateAbortTimeout(const GURL
& url
,
147 content::RenderViewHost
* render_view_host
,
148 NavigationType navigation_type
) {
149 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
150 tab_helper().DidStartProvisionalLoadForFrame(
151 1, -1, true, url
, false, false, render_view_host
);
153 tab_helper().DidFailProvisionalLoad(
154 1, base::string16(), true, url
, net::ERR_TIMED_OUT
, base::string16(),
157 // Start event for the error page.
158 tab_helper().DidStartProvisionalLoadForFrame(
159 1, -1, true, url
, true, false, render_view_host
);
161 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
162 if (navigation_type
== kSameProcess
) {
163 tab_helper().DidFailProvisionalLoad(
164 1, base::string16(), true, url
, net::ERR_ABORTED
, base::string16(),
167 // For interrupted provisional cross-process navigations, the
168 // RenderViewHost is destroyed without sending a DidFailProvisionalLoad
170 tab_helper().RenderViewDeleted(render_view_host
);
173 // Make sure that above call resulted in abort, for tests that continue
175 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
178 CaptivePortalTabHelper
& tab_helper() {
182 // Simulates a captive portal redirect by calling the Observe method.
183 void ObservePortalResult(CaptivePortalResult previous_result
,
184 CaptivePortalResult result
) {
185 content::Source
<Profile
> source_profile(NULL
);
187 CaptivePortalService::Results results
;
188 results
.previous_result
= previous_result
;
189 results
.result
= result
;
190 content::Details
<CaptivePortalService::Results
> details_results(&results
);
192 EXPECT_CALL(mock_reloader(), OnCaptivePortalResults(previous_result
,
194 tab_helper().Observe(chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
,
199 // Simulates a redirect. Uses OnRedirect rather than Observe, for simplicity.
200 void OnRedirect(ResourceType::Type type
, const GURL
& new_url
, int child_id
) {
201 tab_helper().OnRedirect(child_id
, type
, new_url
);
204 MockCaptivePortalTabReloader
& mock_reloader() { return *mock_reloader_
; }
206 void SetIsLoginTab() {
207 tab_helper().SetIsLoginTab();
210 content::RenderViewHost
* render_view_host1() {
211 return web_contents1_
->GetRenderViewHost();
214 content::RenderViewHost
* render_view_host2() {
215 return web_contents2_
->GetRenderViewHost();
219 // Only the RenderViewHosts are used.
220 scoped_ptr
<content::WebContents
> web_contents1_
;
221 scoped_ptr
<content::WebContents
> web_contents2_
;
223 CaptivePortalTabHelper tab_helper_
;
225 // Owned by |tab_helper_|.
226 testing::StrictMock
<MockCaptivePortalTabReloader
>* mock_reloader_
;
228 DISALLOW_COPY_AND_ASSIGN(CaptivePortalTabHelperTest
);
231 TEST_F(CaptivePortalTabHelperTest
, HttpSuccess
) {
232 SimulateSuccess(GURL(kHttpUrl
), render_view_host1());
233 tab_helper().DidStopLoading(render_view_host1());
236 TEST_F(CaptivePortalTabHelperTest
, HttpTimeout
) {
237 SimulateTimeout(GURL(kHttpUrl
), render_view_host1());
238 tab_helper().DidStopLoading(render_view_host1());
241 // Same as above, but simulates what happens when the Link Doctor is enabled,
242 // which adds another provisional load/commit for the error page, after the
244 TEST_F(CaptivePortalTabHelperTest
, HttpTimeoutLinkDoctor
) {
245 SimulateTimeout(GURL(kHttpUrl
), render_view_host1());
247 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
248 // Provisional load starts for the error page.
249 tab_helper().DidStartProvisionalLoadForFrame(
250 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host1());
252 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
253 tab_helper().DidCommitProvisionalLoadForFrame(
254 1, base::string16(), true, GURL(kErrorPageUrl
),
255 content::PAGE_TRANSITION_LINK
, render_view_host1());
256 tab_helper().DidStopLoading(render_view_host1());
259 TEST_F(CaptivePortalTabHelperTest
, HttpsSuccess
) {
260 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
261 tab_helper().DidStopLoading(render_view_host1());
262 EXPECT_FALSE(tab_helper().IsLoginTab());
265 TEST_F(CaptivePortalTabHelperTest
, HttpsTimeout
) {
266 SimulateTimeout(GURL(kHttpsUrl
), render_view_host1());
267 // Make sure no state was carried over from the timeout.
268 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
269 EXPECT_FALSE(tab_helper().IsLoginTab());
272 TEST_F(CaptivePortalTabHelperTest
, HttpsAbort
) {
273 SimulateAbort(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
274 // Make sure no state was carried over from the abort.
275 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
276 EXPECT_FALSE(tab_helper().IsLoginTab());
279 // A cross-process navigation is aborted by a same-site navigation.
280 TEST_F(CaptivePortalTabHelperTest
, AbortCrossProcess
) {
281 SimulateAbort(GURL(kHttpsUrl2
), render_view_host2(), kCrossProcess
);
282 // Make sure no state was carried over from the abort.
283 SimulateSuccess(GURL(kHttpUrl
), render_view_host1());
284 EXPECT_FALSE(tab_helper().IsLoginTab());
287 // Abort while there's a provisional timeout error page loading.
288 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeout
) {
289 SimulateAbortTimeout(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
290 // Make sure no state was carried over from the timeout or the abort.
291 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
292 EXPECT_FALSE(tab_helper().IsLoginTab());
295 // Abort a cross-process navigation while there's a provisional timeout error
297 TEST_F(CaptivePortalTabHelperTest
, AbortTimeoutCrossProcess
) {
298 SimulateAbortTimeout(GURL(kHttpsUrl2
), render_view_host2(),
300 // Make sure no state was carried over from the timeout or the abort.
301 SimulateSuccess(GURL(kHttpsUrl
), render_view_host1());
302 EXPECT_FALSE(tab_helper().IsLoginTab());
305 // Opposite case from above - a same-process error page is aborted in favor of
306 // a cross-process one.
307 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeoutForCrossProcess
) {
308 SimulateAbortTimeout(GURL(kHttpsUrl
), render_view_host1(), kSameProcess
);
309 // Make sure no state was carried over from the timeout or the abort.
310 SimulateSuccess(GURL(kHttpsUrl2
), render_view_host2());
311 EXPECT_FALSE(tab_helper().IsLoginTab());
314 // A provisional same-site navigation is interrupted by a cross-process
315 // navigation without sending an abort first.
316 TEST_F(CaptivePortalTabHelperTest
, UnexpectedProvisionalLoad
) {
317 GURL same_site_url
= GURL(kHttpUrl
);
318 GURL cross_process_url
= GURL(kHttpsUrl2
);
320 // A same-site load for the original RenderViewHost starts.
321 EXPECT_CALL(mock_reloader(),
322 OnLoadStart(same_site_url
.SchemeIsSecure())).Times(1);
323 tab_helper().DidStartProvisionalLoadForFrame(
324 1, -1, true, same_site_url
, false, false, render_view_host1());
326 // It's unexpectedly interrupted by a cross-process navigation, which starts
327 // navigating before the old navigation cancels. We generate an abort message
328 // for the old navigation.
329 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
330 EXPECT_CALL(mock_reloader(),
331 OnLoadStart(cross_process_url
.SchemeIsSecure())).Times(1);
332 tab_helper().DidStartProvisionalLoadForFrame(
333 1, -1, true, cross_process_url
, false, false, render_view_host2());
335 // The cross-process navigation fails.
336 tab_helper().DidFailProvisionalLoad(
337 1, base::string16(), true, cross_process_url
, net::ERR_FAILED
,
338 base::string16(), render_view_host2());
340 // The same-site navigation finally is aborted.
341 tab_helper().DidFailProvisionalLoad(
342 1, base::string16(), true, same_site_url
, net::ERR_ABORTED
,
343 base::string16(), render_view_host1());
345 // The provisional load starts for the error page for the cross-process
347 tab_helper().DidStartProvisionalLoadForFrame(
348 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host2());
350 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_FAILED
)).Times(1);
351 tab_helper().DidCommitProvisionalLoadForFrame(
352 1, base::string16(), true, GURL(kErrorPageUrl
),
353 content::PAGE_TRANSITION_TYPED
, render_view_host2());
356 // Similar to the above test, except the original RenderViewHost manages to
357 // commit before its navigation is aborted.
358 TEST_F(CaptivePortalTabHelperTest
, UnexpectedCommit
) {
359 GURL same_site_url
= GURL(kHttpUrl
);
360 GURL cross_process_url
= GURL(kHttpsUrl2
);
362 // A same-site load for the original RenderViewHost starts.
363 EXPECT_CALL(mock_reloader(),
364 OnLoadStart(same_site_url
.SchemeIsSecure())).Times(1);
365 tab_helper().DidStartProvisionalLoadForFrame(
366 1, -1, true, same_site_url
, false, false, render_view_host1());
368 // It's unexpectedly interrupted by a cross-process navigation, which starts
369 // navigating before the old navigation cancels. We generate an abort message
370 // for the old navigation.
371 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
372 EXPECT_CALL(mock_reloader(),
373 OnLoadStart(cross_process_url
.SchemeIsSecure())).Times(1);
374 tab_helper().DidStartProvisionalLoadForFrame(
375 1, -1, true, cross_process_url
, false, false, render_view_host2());
377 // The cross-process navigation fails.
378 tab_helper().DidFailProvisionalLoad(
379 1, base::string16(), true, cross_process_url
, net::ERR_FAILED
,
381 render_view_host2());
383 // The same-site navigation succeeds.
384 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
385 EXPECT_CALL(mock_reloader(),
386 OnLoadStart(same_site_url
.SchemeIsSecure())).Times(1);
387 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
388 tab_helper().DidCommitProvisionalLoadForFrame(
389 1, base::string16(), true, same_site_url
, content::PAGE_TRANSITION_LINK
,
390 render_view_host1());
393 // Simulates navigations for a number of subframes, and makes sure no
394 // CaptivePortalTabHelper function is called.
395 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframe
) {
396 GURL url
= GURL(kHttpsUrl
);
398 tab_helper().DidStartProvisionalLoadForFrame(
399 1, -1, false, url
, false, false, render_view_host1());
400 tab_helper().DidCommitProvisionalLoadForFrame(
401 1, base::string16(), false, url
, content::PAGE_TRANSITION_LINK
,
402 render_view_host1());
405 tab_helper().DidStartProvisionalLoadForFrame(
406 2, -1, false, url
, false, false, render_view_host1());
407 tab_helper().DidFailProvisionalLoad(
408 2, base::string16(), false, url
, net::ERR_TIMED_OUT
, base::string16(),
409 render_view_host1());
410 tab_helper().DidStartProvisionalLoadForFrame(
411 2, -1, false, url
, true, false, render_view_host1());
412 tab_helper().DidFailProvisionalLoad(
413 2, base::string16(), false, url
, net::ERR_ABORTED
, base::string16(),
414 render_view_host1());
417 tab_helper().DidStartProvisionalLoadForFrame(
418 3, -1, false, url
, false, false, render_view_host1());
419 tab_helper().DidFailProvisionalLoad(
420 3, base::string16(), false, url
, net::ERR_ABORTED
, base::string16(),
421 render_view_host1());
424 // Simulates a subframe erroring out at the same time as a provisional load,
425 // but with a different error code. Make sure the TabHelper sees the correct
427 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframeParallelError
) {
428 // URL used by both frames.
429 GURL url
= GURL(kHttpsUrl
);
435 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsSecure())).Times(1);
436 tab_helper().DidStartProvisionalLoadForFrame(
437 frame_id
, -1, true, url
, false, false, render_view_host1());
438 tab_helper().DidStartProvisionalLoadForFrame(
439 subframe_id
, frame_id
, false, url
, false, false, render_view_host1());
441 // Loads return errors.
442 tab_helper().DidFailProvisionalLoad(
443 frame_id
, base::string16(), true, url
, net::ERR_UNEXPECTED
,
444 base::string16(), render_view_host1());
445 tab_helper().DidFailProvisionalLoad(
446 subframe_id
, base::string16(), false, url
, net::ERR_TIMED_OUT
,
447 base::string16(), render_view_host1());
449 // Provisional load starts for the error pages.
450 tab_helper().DidStartProvisionalLoadForFrame(
451 frame_id
, -1, true, url
, true, false, render_view_host1());
452 tab_helper().DidStartProvisionalLoadForFrame(
453 subframe_id
, frame_id
, false, url
, true, false, render_view_host1());
455 // Error page load finishes.
456 tab_helper().DidCommitProvisionalLoadForFrame(
457 subframe_id
, base::string16(), false, url
,
458 content::PAGE_TRANSITION_AUTO_SUBFRAME
, render_view_host1());
459 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_UNEXPECTED
)).Times(1);
460 tab_helper().DidCommitProvisionalLoadForFrame(
461 frame_id
, base::string16(), true, url
, content::PAGE_TRANSITION_LINK
,
462 render_view_host1());
465 // Simulates an HTTP to HTTPS redirect, which then times out.
466 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpsRedirectTimeout
) {
467 GURL
http_url(kHttpUrl
);
468 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
469 tab_helper().DidStartProvisionalLoadForFrame(
470 1, -1, true, http_url
, false, false, render_view_host1());
472 GURL
https_url(kHttpsUrl
);
473 EXPECT_CALL(mock_reloader(), OnRedirect(true)).Times(1);
474 OnRedirect(ResourceType::MAIN_FRAME
, https_url
,
475 render_view_host1()->GetProcess()->GetID());
477 tab_helper().DidFailProvisionalLoad(
478 1, base::string16(), true, https_url
, net::ERR_TIMED_OUT
,
479 base::string16(), render_view_host1());
481 // Provisional load starts for the error page.
482 tab_helper().DidStartProvisionalLoadForFrame(
483 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host1());
485 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
486 tab_helper().DidCommitProvisionalLoadForFrame(
487 1, base::string16(), true, GURL(kErrorPageUrl
),
488 content::PAGE_TRANSITION_LINK
, render_view_host1());
491 // Simulates an HTTPS to HTTP redirect.
492 TEST_F(CaptivePortalTabHelperTest
, HttpsToHttpRedirect
) {
493 GURL
https_url(kHttpsUrl
);
494 EXPECT_CALL(mock_reloader(),
495 OnLoadStart(https_url
.SchemeIsSecure())).Times(1);
496 tab_helper().DidStartProvisionalLoadForFrame(1, -1, true, https_url
, false,
497 false, render_view_host1());
499 GURL
http_url(kHttpUrl
);
500 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsSecure())).Times(1);
501 OnRedirect(ResourceType::MAIN_FRAME
, http_url
,
502 render_view_host1()->GetProcess()->GetID());
504 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
505 tab_helper().DidCommitProvisionalLoadForFrame(
506 1, base::string16(), true, http_url
, content::PAGE_TRANSITION_LINK
,
507 render_view_host1());
510 // Simulates an HTTPS to HTTPS redirect.
511 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpRedirect
) {
512 GURL
http_url(kHttpUrl
);
513 EXPECT_CALL(mock_reloader(),
514 OnLoadStart(http_url
.SchemeIsSecure())).Times(1);
515 tab_helper().DidStartProvisionalLoadForFrame(
516 1, -1, true, http_url
, false, false, render_view_host1());
518 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsSecure())).Times(1);
519 OnRedirect(ResourceType::MAIN_FRAME
, http_url
,
520 render_view_host1()->GetProcess()->GetID());
522 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
523 tab_helper().DidCommitProvisionalLoadForFrame(
524 1, base::string16(), true, http_url
, content::PAGE_TRANSITION_LINK
,
525 render_view_host1());
528 // Simulates redirect of a subframe.
529 TEST_F(CaptivePortalTabHelperTest
, SubframeRedirect
) {
530 GURL
http_url(kHttpUrl
);
531 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
532 tab_helper().DidStartProvisionalLoadForFrame(
533 1, -1, true, http_url
, false, false, render_view_host1());
535 GURL
https_url(kHttpsUrl
);
536 OnRedirect(ResourceType::SUB_FRAME
, https_url
,
537 render_view_host1()->GetProcess()->GetID());
539 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
540 tab_helper().DidCommitProvisionalLoadForFrame(
541 1, base::string16(), true, GURL(kErrorPageUrl
),
542 content::PAGE_TRANSITION_LINK
, render_view_host1());
545 // Simulates a redirect, for another RenderViewHost.
546 TEST_F(CaptivePortalTabHelperTest
, OtherRenderViewHostRedirect
) {
547 GURL
http_url(kHttpUrl
);
548 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
549 tab_helper().DidStartProvisionalLoadForFrame(
550 1, -1, true, http_url
, false, false, render_view_host1());
552 // Another RenderViewHost sees a redirect. None of the reloader's functions
554 GURL
https_url(kHttpsUrl
);
555 OnRedirect(ResourceType::MAIN_FRAME
, https_url
,
556 render_view_host2()->GetProcess()->GetID());
558 tab_helper().DidFailProvisionalLoad(
559 1, base::string16(), true, https_url
, net::ERR_TIMED_OUT
,
560 base::string16(), render_view_host1());
562 // Provisional load starts for the error page.
563 tab_helper().DidStartProvisionalLoadForFrame(
564 1, -1, true, GURL(kErrorPageUrl
), true, false, render_view_host1());
566 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
567 tab_helper().DidCommitProvisionalLoadForFrame(
568 1, base::string16(), true, GURL(kErrorPageUrl
),
569 content::PAGE_TRANSITION_LINK
, render_view_host1());
572 TEST_F(CaptivePortalTabHelperTest
, LoginTabLogin
) {
573 EXPECT_FALSE(tab_helper().IsLoginTab());
575 EXPECT_TRUE(tab_helper().IsLoginTab());
577 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
578 captive_portal::RESULT_INTERNET_CONNECTED
);
579 EXPECT_FALSE(tab_helper().IsLoginTab());
582 TEST_F(CaptivePortalTabHelperTest
, LoginTabError
) {
583 EXPECT_FALSE(tab_helper().IsLoginTab());
586 EXPECT_TRUE(tab_helper().IsLoginTab());
588 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
589 captive_portal::RESULT_NO_RESPONSE
);
590 EXPECT_FALSE(tab_helper().IsLoginTab());
593 TEST_F(CaptivePortalTabHelperTest
, LoginTabMultipleResultsBeforeLogin
) {
594 EXPECT_FALSE(tab_helper().IsLoginTab());
597 EXPECT_TRUE(tab_helper().IsLoginTab());
599 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
600 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
601 EXPECT_TRUE(tab_helper().IsLoginTab());
603 ObservePortalResult(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
604 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
605 EXPECT_TRUE(tab_helper().IsLoginTab());
607 ObservePortalResult(captive_portal::RESULT_NO_RESPONSE
,
608 captive_portal::RESULT_INTERNET_CONNECTED
);
609 EXPECT_FALSE(tab_helper().IsLoginTab());
612 TEST_F(CaptivePortalTabHelperTest
, NoLoginTab
) {
613 EXPECT_FALSE(tab_helper().IsLoginTab());
615 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
616 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
617 EXPECT_FALSE(tab_helper().IsLoginTab());
619 ObservePortalResult(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
620 captive_portal::RESULT_NO_RESPONSE
);
621 EXPECT_FALSE(tab_helper().IsLoginTab());
623 ObservePortalResult(captive_portal::RESULT_NO_RESPONSE
,
624 captive_portal::RESULT_INTERNET_CONNECTED
);
625 EXPECT_FALSE(tab_helper().IsLoginTab());