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.
5 #include "base/command_line.h"
6 #include "base/memory/scoped_ptr.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/chromeos/login/screens/mock_base_screen_delegate.h"
10 #include "chrome/browser/chromeos/login/screens/mock_error_screen.h"
11 #include "chrome/browser/chromeos/login/screens/network_error.h"
12 #include "chrome/browser/chromeos/login/screens/update_screen.h"
13 #include "chrome/browser/chromeos/login/startup_utils.h"
14 #include "chrome/browser/chromeos/login/test/wizard_in_process_browser_test.h"
15 #include "chrome/browser/chromeos/login/wizard_controller.h"
16 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
17 #include "chrome/common/pref_names.h"
18 #include "chromeos/chromeos_switches.h"
19 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/fake_update_engine_client.h"
21 #include "chromeos/network/portal_detector/network_portal_detector.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 using ::testing::AnyNumber
;
26 using ::testing::AtLeast
;
27 using ::testing::Exactly
;
28 using ::testing::Invoke
;
29 using ::testing::Return
;
36 const char kStubEthernetGuid
[] = "eth0";
37 const char kStubWifiGuid
[] = "wlan0";
41 class UpdateScreenTest
: public WizardInProcessBrowserTest
{
43 UpdateScreenTest() : WizardInProcessBrowserTest("update"),
44 fake_update_engine_client_(NULL
),
45 network_portal_detector_(NULL
) {
49 void SetUpInProcessBrowserTestFixture() override
{
50 fake_update_engine_client_
= new FakeUpdateEngineClient
;
51 chromeos::DBusThreadManager::GetSetterForTesting()->SetUpdateEngineClient(
52 scoped_ptr
<UpdateEngineClient
>(fake_update_engine_client_
));
54 WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
56 // Setup network portal detector to return online state for both
57 // ethernet and wifi networks. Ethernet is an active network by
59 network_portal_detector_
= new NetworkPortalDetectorTestImpl();
60 NetworkPortalDetector::InitializeForTesting(network_portal_detector_
);
61 NetworkPortalDetector::CaptivePortalState online_state
;
62 online_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
;
63 online_state
.response_code
= 204;
64 SetDefaultNetwork(kStubEthernetGuid
);
65 SetDetectionResults(kStubEthernetGuid
, online_state
);
66 SetDetectionResults(kStubWifiGuid
, online_state
);
69 void SetUpOnMainThread() override
{
70 mock_base_screen_delegate_
.reset(new MockBaseScreenDelegate());
71 mock_network_error_view_
.reset(new MockNetworkErrorView());
72 mock_error_screen_
.reset(new MockErrorScreen(
73 mock_base_screen_delegate_
.get(), mock_network_error_view_
.get()));
74 EXPECT_CALL(*mock_base_screen_delegate_
, ShowCurrentScreen())
76 EXPECT_CALL(*mock_base_screen_delegate_
, GetErrorScreen())
78 .WillRepeatedly(Return(mock_error_screen_
.get()));
80 WizardInProcessBrowserTest::SetUpOnMainThread();
82 ASSERT_TRUE(WizardController::default_controller() != NULL
);
83 update_screen_
= UpdateScreen::Get(WizardController::default_controller());
84 ASSERT_TRUE(update_screen_
!= NULL
);
85 ASSERT_EQ(WizardController::default_controller()->current_screen(),
87 update_screen_
->base_screen_delegate_
= mock_base_screen_delegate_
.get();
90 void TearDownOnMainThread() override
{
91 WizardInProcessBrowserTest::TearDownOnMainThread();
92 mock_error_screen_
.reset();
93 mock_network_error_view_
.reset();
96 void TearDownInProcessBrowserTestFixture() override
{
97 NetworkPortalDetector::Shutdown();
98 WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
101 void SetDefaultNetwork(const std::string
& guid
) {
102 DCHECK(network_portal_detector_
);
103 network_portal_detector_
->SetDefaultNetworkForTesting(guid
);
106 void SetDetectionResults(
107 const std::string
& guid
,
108 const NetworkPortalDetector::CaptivePortalState
& state
) {
109 DCHECK(network_portal_detector_
);
110 network_portal_detector_
->SetDetectionResultsForTesting(guid
, state
);
113 void NotifyPortalDetectionCompleted() {
114 DCHECK(network_portal_detector_
);
115 network_portal_detector_
->NotifyObserversForTesting();
118 FakeUpdateEngineClient
* fake_update_engine_client_
;
119 scoped_ptr
<MockBaseScreenDelegate
> mock_base_screen_delegate_
;
120 scoped_ptr
<MockNetworkErrorView
> mock_network_error_view_
;
121 scoped_ptr
<MockErrorScreen
> mock_error_screen_
;
122 UpdateScreen
* update_screen_
;
123 NetworkPortalDetectorTestImpl
* network_portal_detector_
;
126 DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest
);
129 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestBasic
) {
130 ASSERT_TRUE(update_screen_
->view_
!= NULL
);
133 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestNoUpdate
) {
134 update_screen_
->SetIgnoreIdleStatus(true);
135 UpdateEngineClient::Status status
;
136 status
.status
= UpdateEngineClient::UPDATE_STATUS_IDLE
;
137 update_screen_
->UpdateStatusChanged(status
);
138 status
.status
= UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE
;
139 update_screen_
->UpdateStatusChanged(status
);
140 status
.status
= UpdateEngineClient::UPDATE_STATUS_IDLE
;
141 // GetLastStatus() will be called via ExitUpdate() called from
142 // UpdateStatusChanged().
143 fake_update_engine_client_
->set_default_status(status
);
145 EXPECT_CALL(*mock_base_screen_delegate_
,
146 OnExit(_
, BaseScreenDelegate::UPDATE_NOUPDATE
, _
)).Times(1);
147 update_screen_
->UpdateStatusChanged(status
);
150 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestUpdateAvailable
) {
151 update_screen_
->is_ignore_update_deadlines_
= true;
153 UpdateEngineClient::Status status
;
154 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE
;
155 status
.new_version
= "latest and greatest";
156 update_screen_
->UpdateStatusChanged(status
);
158 status
.status
= UpdateEngineClient::UPDATE_STATUS_DOWNLOADING
;
159 status
.download_progress
= 0.0;
160 update_screen_
->UpdateStatusChanged(status
);
162 status
.download_progress
= 0.5;
163 update_screen_
->UpdateStatusChanged(status
);
165 status
.download_progress
= 1.0;
166 update_screen_
->UpdateStatusChanged(status
);
168 status
.status
= UpdateEngineClient::UPDATE_STATUS_VERIFYING
;
169 update_screen_
->UpdateStatusChanged(status
);
171 status
.status
= UpdateEngineClient::UPDATE_STATUS_FINALIZING
;
172 update_screen_
->UpdateStatusChanged(status
);
174 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT
;
175 update_screen_
->UpdateStatusChanged(status
);
176 // UpdateStatusChanged(status) calls RebootAfterUpdate().
177 EXPECT_EQ(1, fake_update_engine_client_
->reboot_after_update_call_count());
178 // Check that OOBE will resume back at this screen.
179 base::MessageLoop::current()->RunUntilIdle();
180 EXPECT_FALSE(StartupUtils::IsOobeCompleted());
181 EXPECT_EQ(update_screen_
->GetName(),
182 g_browser_process
->local_state()->GetString(prefs::kOobeScreenPending
));
185 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorIssuingUpdateCheck
) {
186 // First, cancel the update that is already in progress.
187 EXPECT_CALL(*mock_base_screen_delegate_
,
188 OnExit(_
, BaseScreenDelegate::UPDATE_NOUPDATE
, _
)).Times(1);
189 update_screen_
->CancelUpdate();
191 fake_update_engine_client_
->set_update_check_result(
192 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
193 EXPECT_CALL(*mock_base_screen_delegate_
,
194 OnExit(_
, BaseScreenDelegate::UPDATE_ERROR_CHECKING_FOR_UPDATE
,
196 update_screen_
->StartNetworkCheck();
199 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorCheckingForUpdate
) {
200 UpdateEngineClient::Status status
;
201 status
.status
= UpdateEngineClient::UPDATE_STATUS_ERROR
;
202 // GetLastStatus() will be called via ExitUpdate() called from
203 // UpdateStatusChanged().
204 fake_update_engine_client_
->set_default_status(status
);
206 EXPECT_CALL(*mock_base_screen_delegate_
,
207 OnExit(_
, BaseScreenDelegate::UPDATE_ERROR_CHECKING_FOR_UPDATE
,
209 update_screen_
->UpdateStatusChanged(status
);
212 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorUpdating
) {
213 UpdateEngineClient::Status status
;
214 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE
;
215 status
.new_version
= "latest and greatest";
216 // GetLastStatus() will be called via ExitUpdate() called from
217 // UpdateStatusChanged().
218 fake_update_engine_client_
->set_default_status(status
);
220 update_screen_
->UpdateStatusChanged(status
);
222 status
.status
= UpdateEngineClient::UPDATE_STATUS_ERROR
;
223 // GetLastStatus() will be called via ExitUpdate() called from
224 // UpdateStatusChanged().
225 fake_update_engine_client_
->set_default_status(status
);
227 EXPECT_CALL(*mock_base_screen_delegate_
,
228 OnExit(_
, BaseScreenDelegate::UPDATE_ERROR_UPDATING
, _
)).Times(1);
229 update_screen_
->UpdateStatusChanged(status
);
232 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestTemproraryOfflineNetwork
) {
233 EXPECT_CALL(*mock_base_screen_delegate_
,
234 OnExit(_
, BaseScreenDelegate::UPDATE_NOUPDATE
, _
)).Times(1);
235 update_screen_
->CancelUpdate();
237 // Change ethernet state to portal.
238 NetworkPortalDetector::CaptivePortalState portal_state
;
239 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
240 portal_state
.response_code
= 200;
241 SetDetectionResults(kStubEthernetGuid
, portal_state
);
243 // Update screen will delay error message about portal state because
244 // ethernet is behind captive portal.
245 EXPECT_CALL(*mock_error_screen_
,
246 MockSetUIState(NetworkError::UI_STATE_UPDATE
)).Times(1);
247 EXPECT_CALL(*mock_error_screen_
,
248 MockSetErrorState(NetworkError::ERROR_STATE_PORTAL
,
249 std::string())).Times(1);
250 EXPECT_CALL(*mock_error_screen_
, MockFixCaptivePortal()).Times(1);
251 EXPECT_CALL(*mock_base_screen_delegate_
, ShowErrorScreen()).Times(1);
253 update_screen_
->StartNetworkCheck();
255 // Force timer expiration.
257 base::Closure timed_callback
=
258 update_screen_
->GetErrorMessageTimerForTesting().user_task();
259 ASSERT_FALSE(timed_callback
.is_null());
260 update_screen_
->GetErrorMessageTimerForTesting().Reset();
261 timed_callback
.Run();
264 NetworkPortalDetector::CaptivePortalState online_state
;
265 online_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
;
266 online_state
.response_code
= 204;
267 SetDetectionResults(kStubEthernetGuid
, online_state
);
269 // Second notification from portal detector will be about online state,
270 // so update screen will hide error message and proceed to update.
271 EXPECT_CALL(*mock_base_screen_delegate_
, HideErrorScreen(update_screen_
))
273 fake_update_engine_client_
->set_update_check_result(
274 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
276 EXPECT_CALL(*mock_base_screen_delegate_
,
277 OnExit(_
, BaseScreenDelegate::UPDATE_ERROR_CHECKING_FOR_UPDATE
,
280 NotifyPortalDetectionCompleted();
283 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestTwoOfflineNetworks
) {
284 EXPECT_CALL(*mock_base_screen_delegate_
,
285 OnExit(_
, BaseScreenDelegate::UPDATE_NOUPDATE
, _
)).Times(1);
286 update_screen_
->CancelUpdate();
288 // Change ethernet state to portal.
289 NetworkPortalDetector::CaptivePortalState portal_state
;
290 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
291 portal_state
.response_code
= 200;
292 SetDetectionResults(kStubEthernetGuid
, portal_state
);
294 // Update screen will delay error message about portal state because
295 // ethernet is behind captive portal.
296 EXPECT_CALL(*mock_error_screen_
,
297 MockSetUIState(NetworkError::UI_STATE_UPDATE
)).Times(1);
298 EXPECT_CALL(*mock_error_screen_
,
299 MockSetErrorState(NetworkError::ERROR_STATE_PORTAL
,
300 std::string())).Times(1);
301 EXPECT_CALL(*mock_error_screen_
, MockFixCaptivePortal()).Times(1);
302 EXPECT_CALL(*mock_base_screen_delegate_
, ShowErrorScreen()).Times(1);
304 update_screen_
->StartNetworkCheck();
306 // Force timer expiration.
308 base::Closure timed_callback
=
309 update_screen_
->GetErrorMessageTimerForTesting().user_task();
310 ASSERT_FALSE(timed_callback
.is_null());
311 update_screen_
->GetErrorMessageTimerForTesting().Reset();
312 timed_callback
.Run();
315 // Change active network to the wifi behind proxy.
316 NetworkPortalDetector::CaptivePortalState proxy_state
;
318 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED
;
319 proxy_state
.response_code
= -1;
320 SetDefaultNetwork(kStubWifiGuid
);
321 SetDetectionResults(kStubWifiGuid
, proxy_state
);
323 // Update screen will show message about proxy error because wifie
324 // network requires proxy authentication.
325 EXPECT_CALL(*mock_error_screen_
,
326 MockSetErrorState(NetworkError::ERROR_STATE_PROXY
, std::string()))
329 NotifyPortalDetectionCompleted();
332 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestVoidNetwork
) {
333 SetDefaultNetwork(std::string());
335 // Cancels pending update request.
336 EXPECT_CALL(*mock_base_screen_delegate_
,
337 OnExit(_
, BaseScreenDelegate::UPDATE_NOUPDATE
, _
)).Times(1);
338 update_screen_
->CancelUpdate();
340 // First portal detection attempt returns NULL network and undefined
341 // results, so detection is restarted.
342 EXPECT_CALL(*mock_error_screen_
, MockSetUIState(_
)).Times(Exactly(0));
343 EXPECT_CALL(*mock_error_screen_
, MockSetErrorState(_
, _
)).Times(Exactly(0));
344 EXPECT_CALL(*mock_base_screen_delegate_
, ShowErrorScreen()).Times(Exactly(0));
345 update_screen_
->StartNetworkCheck();
347 // Second portal detection also returns NULL network and undefined
348 // results. In this case, offline message should be displayed.
349 EXPECT_CALL(*mock_error_screen_
,
350 MockSetUIState(NetworkError::UI_STATE_UPDATE
)).Times(1);
351 EXPECT_CALL(*mock_error_screen_
,
352 MockSetErrorState(NetworkError::ERROR_STATE_OFFLINE
,
353 std::string())).Times(1);
354 EXPECT_CALL(*mock_base_screen_delegate_
, ShowErrorScreen()).Times(1);
355 base::MessageLoop::current()->RunUntilIdle();
356 NotifyPortalDetectionCompleted();
359 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestAPReselection
) {
360 EXPECT_CALL(*mock_base_screen_delegate_
,
361 OnExit(_
, BaseScreenDelegate::UPDATE_NOUPDATE
, _
)).Times(1);
362 update_screen_
->CancelUpdate();
364 // Change ethernet state to portal.
365 NetworkPortalDetector::CaptivePortalState portal_state
;
366 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
367 portal_state
.response_code
= 200;
368 SetDetectionResults(kStubEthernetGuid
, portal_state
);
370 // Update screen will delay error message about portal state because
371 // ethernet is behind captive portal.
372 EXPECT_CALL(*mock_error_screen_
,
373 MockSetUIState(NetworkError::UI_STATE_UPDATE
)).Times(1);
374 EXPECT_CALL(*mock_error_screen_
,
375 MockSetErrorState(NetworkError::ERROR_STATE_PORTAL
,
376 std::string())).Times(1);
377 EXPECT_CALL(*mock_error_screen_
, MockFixCaptivePortal()).Times(1);
378 EXPECT_CALL(*mock_base_screen_delegate_
, ShowErrorScreen()).Times(1);
380 update_screen_
->StartNetworkCheck();
382 // Force timer expiration.
384 base::Closure timed_callback
=
385 update_screen_
->GetErrorMessageTimerForTesting().user_task();
386 ASSERT_FALSE(timed_callback
.is_null());
387 update_screen_
->GetErrorMessageTimerForTesting().Reset();
388 timed_callback
.Run();
391 // User re-selects the same network manually. In this case, hide
392 // offline message and skip network check. Since ethernet is still
393 // behind portal, update engine fails to update.
394 EXPECT_CALL(*mock_base_screen_delegate_
, HideErrorScreen(update_screen_
))
396 fake_update_engine_client_
->set_update_check_result(
397 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
398 EXPECT_CALL(*mock_base_screen_delegate_
,
399 OnExit(_
, BaseScreenDelegate::UPDATE_ERROR_CHECKING_FOR_UPDATE
,
402 update_screen_
->OnConnectRequested();
403 base::MessageLoop::current()->RunUntilIdle();
406 } // namespace chromeos