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

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

Powered by Google App Engine
This is Rietveld 408576698