OLD | NEW |
(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 |
OLD | NEW |