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

Side by Side 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: Sync 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
6
7 #include "base/callback.h"
8 #include "base/message_loop.h"
9 #include "chrome/browser/captive_portal/captive_portal_service.h"
10 #include "net/base/net_errors.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace captive_portal {
15
16 // Used for testing CaptivePortalTabReloader in isolation from the observer.
17 // Exposes a number of private functions and mocks out others.
18 class TestCaptivePortalTabReloader : public CaptivePortalTabReloader {
19 public:
20 TestCaptivePortalTabReloader()
21 : CaptivePortalTabReloader(NULL, NULL, base::Callback<void(void)>()) {
22 }
23
24 bool TimerRunning() {
25 return slow_ssl_load_timer_.IsRunning();
26 }
27
28 // The following methods are aliased so they can be publicly accessed by the
29 // unit tests.
30
31 State state() const {
32 return CaptivePortalTabReloader::state();
33 }
34
35 void set_slow_ssl_load_time(base::TimeDelta slow_ssl_load_time) {
36 EXPECT_FALSE(TimerRunning());
37 CaptivePortalTabReloader::set_slow_ssl_load_time(slow_ssl_load_time);
38 }
39
40 MOCK_METHOD0(ReloadTab, void());
41 MOCK_METHOD0(MaybeOpenCaptivePortalLoginTab, void());
42 MOCK_METHOD0(CheckForCaptivePortal, void());
43 };
44
45 class CaptivePortalTabReloaderTest : public testing::Test {
46 public:
47 CaptivePortalTabReloaderTest() {
48 // Most tests don't run the message loop, so don't use a timer for them.
49 tab_reloader_.set_slow_ssl_load_time(base::TimeDelta());
50 }
51
52 virtual ~CaptivePortalTabReloaderTest() {
53 }
54
55 // testing::Test
56 virtual void TearDown() OVERRIDE {
57 EXPECT_FALSE(tab_reloader().TimerRunning());
58 // Run any pending operations, so the test fails if there was a call to
59 // a mocked out function pending.
60 MessageLoop::current()->RunAllPending();
61 }
62
63 TestCaptivePortalTabReloader& tab_reloader() { return tab_reloader_; }
64
65 private:
66 MessageLoop message_loop_;
67
68 testing::StrictMock<TestCaptivePortalTabReloader> tab_reloader_;
69 };
70
71 // Simulates a slow SSL load when the Internet is connected.
72 TEST_F(CaptivePortalTabReloaderTest, InternetConnected) {
73 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
74
75 tab_reloader().OnLoadStart(true);
76 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING,
77 tab_reloader().state());
78 EXPECT_TRUE(tab_reloader().TimerRunning());
79
80 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
81 MessageLoop::current()->RunAllPending();
82 EXPECT_FALSE(tab_reloader().TimerRunning());
83 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
84 tab_reloader().state());
85
86 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED,
87 RESULT_INTERNET_CONNECTED);
88
89 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
90 EXPECT_FALSE(tab_reloader().TimerRunning());
91
92 tab_reloader().OnLoadCommitted(net::OK);
93 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
94 }
95
96 // Simulates a slow SSL load when the Internet is connected. In this case,
97 // the timeout error occurs before the timer triggers. Unlikely to happen
98 // in practice, but best if it still works.
99 TEST_F(CaptivePortalTabReloaderTest, InternetConnectedTimeout) {
100 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
101
102 tab_reloader().OnLoadStart(true);
103 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING,
104 tab_reloader().state());
105 EXPECT_TRUE(tab_reloader().TimerRunning());
106
107 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
108 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
109 EXPECT_FALSE(tab_reloader().TimerRunning());
110 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
111 tab_reloader().state());
112
113 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED,
114 RESULT_INTERNET_CONNECTED);
115
116 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
117 }
118
119 // Simulates a slow SSL load when captive portal checks return no response.
120 TEST_F(CaptivePortalTabReloaderTest, NoResponse) {
121 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
122
123 tab_reloader().OnLoadStart(true);
124 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING,
125 tab_reloader().state());
126 EXPECT_TRUE(tab_reloader().TimerRunning());
127
128 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
129 MessageLoop::current()->RunAllPending();
130 EXPECT_FALSE(tab_reloader().TimerRunning());
131 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
132 tab_reloader().state());
133
134 tab_reloader().OnCaptivePortalResults(RESULT_NO_RESPONSE, RESULT_NO_RESPONSE);
135
136 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
137 EXPECT_FALSE(tab_reloader().TimerRunning());
138
139 tab_reloader().OnLoadCommitted(net::OK);
140 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
141 }
142
143 // Simulates a slow HTTP load when behind a captive portal, that eventually.
144 // tiems out. Since it's HTTP, the TabReloader should do nothing.
145 TEST_F(CaptivePortalTabReloaderTest, DoesNothingOnHttp) {
146 tab_reloader().OnLoadStart(false);
147 EXPECT_FALSE(tab_reloader().TimerRunning());
148 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
149
150 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED,
151 RESULT_BEHIND_CAPTIVE_PORTAL);
152 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
153
154 // The user logs in.
155 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
156 RESULT_INTERNET_CONNECTED);
157 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
158
159 // The page times out.
160 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
161 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
162 }
163
164 // Simulate the normal login process. The user logs in before the error page
165 // in the original tab commits.
166 TEST_F(CaptivePortalTabReloaderTest, Login) {
167 tab_reloader().OnLoadStart(true);
168
169 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
170 MessageLoop::current()->RunAllPending();
171 EXPECT_FALSE(tab_reloader().TimerRunning());
172 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
173 tab_reloader().state());
174
175 // The captive portal service detects a captive portal. The TabReloader
176 // should try and create a new login tab in response.
177 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
178 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED,
179 RESULT_BEHIND_CAPTIVE_PORTAL);
180 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
181 tab_reloader().state());
182 EXPECT_FALSE(tab_reloader().TimerRunning());
183
184 // The user logs on from another tab, and a captive portal check is triggered.
185 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
186 RESULT_INTERNET_CONNECTED);
187 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
188 tab_reloader().state());
189
190 // The error page commits, which should start an asynchronous reload.
191 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
192 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
193 tab_reloader().state());
194
195 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
196 MessageLoop::current()->RunAllPending();
197 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
198 }
199
200 // Simulate the normal login process. The user logs in after the tab finishes
201 // loading the error page.
202 TEST_F(CaptivePortalTabReloaderTest, LoginLate) {
203 tab_reloader().OnLoadStart(true);
204
205 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
206 MessageLoop::current()->RunAllPending();
207 EXPECT_FALSE(tab_reloader().TimerRunning());
208 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
209 tab_reloader().state());
210
211 // The captive portal service detects a captive portal. The TabReloader
212 // should try and create a new login tab in response.
213 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
214 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED,
215 RESULT_BEHIND_CAPTIVE_PORTAL);
216 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
217 tab_reloader().state());
218 EXPECT_FALSE(tab_reloader().TimerRunning());
219
220 // The error page commits.
221 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
222 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
223 tab_reloader().state());
224
225 // The user logs on from another tab, and a captive portal check is triggered.
226 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
227 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
228 RESULT_INTERNET_CONNECTED);
229 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
230 }
231
232 // Simulate a login after the tab times out unexpectedly quickly.
233 TEST_F(CaptivePortalTabReloaderTest, TimeoutFast) {
234 tab_reloader().OnLoadStart(true);
235
236 // The error page commits, which should trigger a captive portal check,
237 // since the timer's still running.
238 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
239 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
240 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
241 tab_reloader().state());
242
243 // The captive portal service detects a captive portal. The TabReloader
244 // should try and create a new login tab in response.
245 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
246 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED,
247 RESULT_BEHIND_CAPTIVE_PORTAL);
248 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
249 tab_reloader().state());
250 EXPECT_FALSE(tab_reloader().TimerRunning());
251
252 // The user logs on from another tab, and a captive portal check is triggered.
253 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
254 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
255 RESULT_INTERNET_CONNECTED);
256 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
257 }
258
259 // Simulate the case that a user has already logged in before the tab receives a
260 // captive portal result, but a RESULT_BEHIND_CAPTIVE_PORTAL was received
261 // before the tab started loading.
262 TEST_F(CaptivePortalTabReloaderTest, AlreadyLoggedIn) {
263 tab_reloader().OnLoadStart(true);
264
265 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
266 MessageLoop::current()->RunAllPending();
267 EXPECT_FALSE(tab_reloader().TimerRunning());
268 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
269 tab_reloader().state());
270
271 // The user has already logged in. Since the last result found a captive
272 // portal, the tab will be reloaded if a timeout is committed.
273 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
274 RESULT_INTERNET_CONNECTED);
275 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
276 tab_reloader().state());
277
278 // The error page commits, which should start an asynchronous reload.
279 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
280 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
281 tab_reloader().state());
282
283 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
284 MessageLoop::current()->RunAllPending();
285 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
286 }
287
288 // Same as above, except the result is received even before the timer triggers,
289 // due to a captive portal test request from some external source, like a login
290 // tab.
291 TEST_F(CaptivePortalTabReloaderTest, AlreadyLoggedInBeforeTimerTriggers) {
292 tab_reloader().OnLoadStart(true);
293
294 // The user has already logged in. Since the last result indicated there is
295 // a captive portal, the tab will be reloaded if it times out.
296 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
297 RESULT_INTERNET_CONNECTED);
298 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
299 tab_reloader().state());
300 EXPECT_FALSE(tab_reloader().TimerRunning());
301
302 // The error page commits, which should start an asynchronous reload.
303 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
304 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
305 tab_reloader().state());
306
307 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
308 MessageLoop::current()->RunAllPending();
309 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
310 }
311
312 // Simulate the user logging in while the timer is still running. May happen
313 // if the tab is reloaded just before logging in on another tab.
314 TEST_F(CaptivePortalTabReloaderTest, LogInWhileTimerRunning) {
315 tab_reloader().OnLoadStart(true);
316 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING,
317 tab_reloader().state());
318 EXPECT_TRUE(tab_reloader().TimerRunning());
319
320 // The user has already logged in.
321 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
322 RESULT_INTERNET_CONNECTED);
323 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
324 tab_reloader().state());
325
326 // The error page commits, which should start an asynchronous reload.
327 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
328 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
329 tab_reloader().state());
330
331 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
332 MessageLoop::current()->RunAllPending();
333 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
334 }
335
336 // Simulate a captive portal being detected while the time is still running.
337 // The captive portal check triggered by the timer detects the captive portal
338 // again, and then the user logs in.
339 TEST_F(CaptivePortalTabReloaderTest, BehindPortalResultWhileTimerRunning) {
340 tab_reloader().OnLoadStart(true);
341 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING,
342 tab_reloader().state());
343 EXPECT_TRUE(tab_reloader().TimerRunning());
344
345 // The user is behind a captive portal, but since the tab hasn't timed out,
346 // the message is ignored.
347 tab_reloader().OnCaptivePortalResults(RESULT_INTERNET_CONNECTED,
348 RESULT_BEHIND_CAPTIVE_PORTAL);
349 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING,
350 tab_reloader().state());
351
352 // The rest proceeds as normal.
353 EXPECT_CALL(tab_reloader(), CheckForCaptivePortal()).Times(1);
354 MessageLoop::current()->RunAllPending();
355 EXPECT_EQ(CaptivePortalTabReloader::STATE_MAYBE_BROKEN_BY_PORTAL,
356 tab_reloader().state());
357
358 // The captive portal service detects a captive portal, and this time the
359 // tab tries to create a login tab.
360 EXPECT_CALL(tab_reloader(), MaybeOpenCaptivePortalLoginTab()).Times(1);
361 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
362 RESULT_BEHIND_CAPTIVE_PORTAL);
363 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
364 tab_reloader().state());
365 EXPECT_FALSE(tab_reloader().TimerRunning());
366
367 // The user logs on from another tab, and a captive portal check is triggered.
368 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
369 RESULT_INTERNET_CONNECTED);
370 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
371 tab_reloader().state());
372
373 // The error page commits, which should start an asynchronous reload.
374 tab_reloader().OnLoadCommitted(net::ERR_CONNECTION_TIMED_OUT);
375 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
376 tab_reloader().state());
377
378 EXPECT_CALL(tab_reloader(), ReloadTab()).Times(1);
379 MessageLoop::current()->RunAllPending();
380 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
381 }
382
383 // The CaptivePortalService detects the user has logged in to a captive portal
384 // while the timer is still running, but the original load succeeds, so no
385 // reload is done.
386 TEST_F(CaptivePortalTabReloaderTest, LogInWhileTimerRunningNoError) {
387 tab_reloader().OnLoadStart(true);
388 EXPECT_EQ(CaptivePortalTabReloader::STATE_TIMER_RUNNING,
389 tab_reloader().state());
390 EXPECT_TRUE(tab_reloader().TimerRunning());
391
392 // The user has already logged in.
393 tab_reloader().OnCaptivePortalResults(RESULT_BEHIND_CAPTIVE_PORTAL,
394 RESULT_INTERNET_CONNECTED);
395 EXPECT_FALSE(tab_reloader().TimerRunning());
396 EXPECT_EQ(CaptivePortalTabReloader::STATE_NEEDS_RELOAD,
397 tab_reloader().state());
398
399 // The page successfully commits, so no reload is triggered.
400 tab_reloader().OnLoadCommitted(net::OK);
401 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE, tab_reloader().state());
402 }
403
404 } // namespace captive_portal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698