Index: chrome/browser/captive_portal/captive_portal_tab_reloader_unittest.cc |
=================================================================== |
--- chrome/browser/captive_portal/captive_portal_tab_reloader_unittest.cc (revision 0) |
+++ chrome/browser/captive_portal/captive_portal_tab_reloader_unittest.cc (revision 0) |
@@ -0,0 +1,404 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chrome/browser/captive_portal/captive_portal_tab_reloader.h" |
+ |
+#include "base/callback.h" |
+#include "base/message_loop.h" |
+#include "chrome/browser/captive_portal/captive_portal_service.h" |
+#include "net/base/net_errors.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace captive_portal { |
+ |
+// Used for testing CaptivePortalTabReloader in isolation from the observer. |
+// Exposes a number of private functions and mocks out others. |
+class TestCaptivePortalTabReloader : public CaptivePortalTabReloader { |
+ public: |
+ TestCaptivePortalTabReloader() |
+ : CaptivePortalTabReloader(NULL, NULL, base::Callback<void(void)>()) { |
+ } |
+ |
+ bool TimerRunning() { |
+ return slow_ssl_load_timer_.IsRunning(); |
+ } |
+ |
+ // The following methods are aliased so they can be publicly accessed by the |
+ // unit tests. |
+ |
+ State state() const { |
+ return CaptivePortalTabReloader::state(); |
+ } |
+ |
+ void set_slow_ssl_load_time(base::TimeDelta slow_ssl_load_time) { |
+ EXPECT_FALSE(TimerRunning()); |
+ CaptivePortalTabReloader::set_slow_ssl_load_time(slow_ssl_load_time); |
+ } |
+ |
+ MOCK_METHOD0(ReloadTab, void()); |
+ MOCK_METHOD0(MaybeOpenCaptivePortalLoginTab, void()); |
+ MOCK_METHOD0(CheckForCaptivePortal, void()); |
+}; |
+ |
+class CaptivePortalTabReloaderTest : public testing::Test { |
+ public: |
+ CaptivePortalTabReloaderTest() { |
+ // Most tests don't run the message loop, so don't use a timer for them. |
+ tab_reloader_.set_slow_ssl_load_time(base::TimeDelta()); |
+ } |
+ |
+ virtual ~CaptivePortalTabReloaderTest() { |
+ } |
+ |
+ // testing::Test |
+ virtual void TearDown() OVERRIDE { |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ // Run any pending operations, so the test fails if there was a call to |
+ // a mocked out function pending. |
+ MessageLoop::current()->RunAllPending(); |
+ } |
+ |
+ TestCaptivePortalTabReloader& tab_reloader() { return tab_reloader_; } |
+ |
+ private: |
+ MessageLoop message_loop_; |
+ |
+ testing::StrictMock<TestCaptivePortalTabReloader> tab_reloader_; |
+}; |
+ |
+// Simulates a slow SSL load when the Internet is connected. |
+TEST_F(CaptivePortalTabReloaderTest, InternetConnected) { |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ |
+ tab_reloader().OnLoadStart(true); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING, |
+ tab_reloader().state()); |
+ EXPECT_TRUE(tab_reloader().TimerRunning()); |
+ |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED, |
+ RESULT_INTERNET_CONNECTED); |
+ |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ |
+ tab_reloader().OnLoadCommitted(net::OK); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulates a slow SSL load when the Internet is connected. In this case, |
+// the timeout error occurs before the timer triggers. Unlikely to happen |
+// in practice, but best if it still works. |
+TEST_F(CaptivePortalTabReloaderTest, InternetConnectedTimeout) { |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ |
+ tab_reloader().OnLoadStart(true); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING, |
+ tab_reloader().state()); |
+ EXPECT_TRUE(tab_reloader().TimerRunning()); |
+ |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED, |
+ RESULT_INTERNET_CONNECTED); |
+ |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulates a slow SSL load when captive portal checks return no response. |
+TEST_F(CaptivePortalTabReloaderTest, NoResponse) { |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ |
+ tab_reloader().OnLoadStart(true); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING, |
+ tab_reloader().state()); |
+ EXPECT_TRUE(tab_reloader().TimerRunning()); |
+ |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ tab_reloader().OnCaptivePortalResults(RESULT_NO_RESPONSE, RESULT_NO_RESPONSE); |
+ |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ |
+ tab_reloader().OnLoadCommitted(net::OK); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulates a slow HTTP load when behind a captive portal, that eventually. |
+// tiems out. Since it's HTTP, the TabReloader should do nothing. |
+TEST_F(CaptivePortalTabReloaderTest, DoesNothingOnHttp) { |
+ tab_reloader().OnLoadStart(false); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ |
+ tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED, |
+ RESULT_BEHIND_CAPTIVE_PORTAL); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ |
+ // The user logs in. |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+ |
+ // The page times out. |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulate the normal login process. The user logs in before the error page |
+// in the original tab commits. |
+TEST_F(CaptivePortalTabReloaderTest, Login) { |
+ tab_reloader().OnLoadStart(true); |
+ |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ // The captive portal service detects a captive portal. The TabReloader |
+ // should try and create a new login tab in response. |
+ EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1); |
+ tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED, |
+ RESULT_BEHIND_CAPTIVE_PORTAL); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ |
+ // The user logs on from another tab, and a captive portal check is triggered. |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ // The error page commits, which should start an asynchronous reload. |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulate the normal login process. The user logs in after the tab finishes |
+// loading the error page. |
+TEST_F(CaptivePortalTabReloaderTest, LoginLate) { |
+ tab_reloader().OnLoadStart(true); |
+ |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ // The captive portal service detects a captive portal. The TabReloader |
+ // should try and create a new login tab in response. |
+ EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1); |
+ tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED, |
+ RESULT_BEHIND_CAPTIVE_PORTAL); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ |
+ // The error page commits. |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ // The user logs on from another tab, and a captive portal check is triggered. |
+ EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1); |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulate a login after the tab times out unexpectedly quickly. |
+TEST_F(CaptivePortalTabReloaderTest, TimeoutFast) { |
+ tab_reloader().OnLoadStart(true); |
+ |
+ // The error page commits, which should trigger a captive portal check, |
+ // since the timer's still running. |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ // The captive portal service detects a captive portal. The TabReloader |
+ // should try and create a new login tab in response. |
+ EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1); |
+ tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED, |
+ RESULT_BEHIND_CAPTIVE_PORTAL); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ |
+ // The user logs on from another tab, and a captive portal check is triggered. |
+ EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1); |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulate the case that a user has already logged in before the tab receives a |
+// captive portal result, but a RESULT_BEHIND_CAPTIVE_PORTAL was received |
+// before the tab started loading. |
+TEST_F(CaptivePortalTabReloaderTest, AlreadyLoggedIn) { |
+ tab_reloader().OnLoadStart(true); |
+ |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ // The user has already logged in. Since the last result found a captive |
+ // portal, the tab will be reloaded if a timeout is committed. |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ // The error page commits, which should start an asynchronous reload. |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Same as above, except the result is received even before the timer triggers, |
+// due to a captive portal test request from some external source, like a login |
+// tab. |
+TEST_F(CaptivePortalTabReloaderTest, AlreadyLoggedInBeforeTimerTriggers) { |
+ tab_reloader().OnLoadStart(true); |
+ |
+ // The user has already logged in. Since the last result indicated there is |
+ // a captive portal, the tab will be reloaded if it times out. |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ |
+ // The error page commits, which should start an asynchronous reload. |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulate the user logging in while the timer is still running. May happen |
+// if the tab is reloaded just before logging in on another tab. |
+TEST_F(CaptivePortalTabReloaderTest, LogInWhileTimerRunning) { |
+ tab_reloader().OnLoadStart(true); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING, |
+ tab_reloader().state()); |
+ EXPECT_TRUE(tab_reloader().TimerRunning()); |
+ |
+ // The user has already logged in. |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ // The error page commits, which should start an asynchronous reload. |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// Simulate a captive portal being detected while the time is still running. |
+// The captive portal check triggered by the timer detects the captive portal |
+// again, and then the user logs in. |
+TEST_F(CaptivePortalTabReloaderTest, BehindPortalResultWhileTimerRunning) { |
+ tab_reloader().OnLoadStart(true); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING, |
+ tab_reloader().state()); |
+ EXPECT_TRUE(tab_reloader().TimerRunning()); |
+ |
+ // The user is behind a captive portal, but since the tab hasn't timed out, |
+ // the message is ignored. |
+ tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED, |
+ RESULT_BEHIND_CAPTIVE_PORTAL); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING, |
+ tab_reloader().state()); |
+ |
+ // The rest proceeds as normal. |
+ EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ |
+ // The captive portal service detects a captive portal, and this time the |
+ // tab tries to create a login tab. |
+ EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1); |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_BEHIND_CAPTIVE_PORTAL); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL, |
+ tab_reloader().state()); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ |
+ // The user logs on from another tab, and a captive portal check is triggered. |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ // The error page commits, which should start an asynchronous reload. |
+ tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1); |
+ MessageLoop::current()->RunAllPending(); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+// The CaptivePortalService detects the user has logged in to a captive portal |
+// while the timer is still running, but the original load succeeds, so no |
+// reload is done. |
+TEST_F(CaptivePortalTabReloaderTest, LogInWhileTimerRunningNoError) { |
+ tab_reloader().OnLoadStart(true); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING, |
+ tab_reloader().state()); |
+ EXPECT_TRUE(tab_reloader().TimerRunning()); |
+ |
+ // The user has already logged in. |
+ tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL, |
+ RESULT_INTERNET_CONNECTED); |
+ EXPECT_FALSE(tab_reloader().TimerRunning()); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD, |
+ tab_reloader().state()); |
+ |
+ // The page successfully commits, so no reload is triggered. |
+ tab_reloader().OnLoadCommitted(net::OK); |
+ EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state()); |
+} |
+ |
+} // namespace captive_portal |
Property changes on: chrome\browser\captive_portal\captive_portal_tab_reloader_unittest.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |