Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(598)

Unified Diff: chrome/browser/captive_portal/captive_portal_tab_reloader_unittest.cc

Issue 10020051: Open a login tab on captive portal detection on SSL loads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Fix typo in comment, forward declare CaptivePortalTabReloader in the TabHelper Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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
« no previous file with comments | « chrome/browser/captive_portal/captive_portal_tab_reloader.cc ('k') | chrome/browser/profiles/profile_dependency_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698