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 "chrome/browser/chromeos/login/screens/mock_error_screen.h"
8 #include "chrome/browser/chromeos/login/screens/mock_screen_observer.h"
9 #include "chrome/browser/chromeos/login/screens/update_screen.h"
10 #include "chrome/browser/chromeos/login/wizard_controller.h"
11 #include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h"
12 #include "chrome/browser/chromeos/net/network_portal_detector.h"
13 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h"
14 #include "chromeos/chromeos_switches.h"
15 #include "chromeos/dbus/fake_dbus_thread_manager.h"
16 #include "chromeos/dbus/fake_update_engine_client.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 using ::testing::AnyNumber
;
21 using ::testing::AtLeast
;
22 using ::testing::Exactly
;
23 using ::testing::Invoke
;
24 using ::testing::Return
;
31 const char kStubEthernetServicePath
[] = "eth0";
32 const char kStubWifiServicePath
[] = "wlan0";
36 class UpdateScreenTest
: public WizardInProcessBrowserTest
{
38 UpdateScreenTest() : WizardInProcessBrowserTest("update"),
39 fake_update_engine_client_(NULL
),
40 network_portal_detector_(NULL
) {
44 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE
{
45 FakeDBusThreadManager
* fake_dbus_thread_manager
=
46 new FakeDBusThreadManager
;
47 fake_dbus_thread_manager
->SetFakeClients();
48 fake_update_engine_client_
= new FakeUpdateEngineClient
;
49 fake_dbus_thread_manager
->SetUpdateEngineClient(
50 scoped_ptr
<UpdateEngineClient
>(fake_update_engine_client_
));
52 DBusThreadManager::SetInstanceForTesting(fake_dbus_thread_manager
);
53 WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
55 // Setup network portal detector to return online state for both
56 // ethernet and wifi networks. Ethernet is an active network by
58 network_portal_detector_
= new NetworkPortalDetectorTestImpl();
59 NetworkPortalDetector::InitializeForTesting(network_portal_detector_
);
60 NetworkPortalDetector::CaptivePortalState online_state
;
61 online_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
;
62 online_state
.response_code
= 204;
63 SetDefaultNetworkPath(kStubEthernetServicePath
);
64 SetDetectionResults(kStubEthernetServicePath
, online_state
);
65 SetDetectionResults(kStubWifiServicePath
, online_state
);
68 virtual void SetUpOnMainThread() OVERRIDE
{
69 WizardInProcessBrowserTest::SetUpOnMainThread();
71 mock_screen_observer_
.reset(new MockScreenObserver());
72 mock_error_screen_actor_
.reset(new MockErrorScreenActor());
73 mock_error_screen_
.reset(
74 new MockErrorScreen(mock_screen_observer_
.get(),
75 mock_error_screen_actor_
.get()));
76 EXPECT_CALL(*mock_screen_observer_
, ShowCurrentScreen())
78 EXPECT_CALL(*mock_screen_observer_
, GetErrorScreen())
80 .WillRepeatedly(Return(mock_error_screen_
.get()));
82 ASSERT_TRUE(WizardController::default_controller() != NULL
);
83 update_screen_
= WizardController::default_controller()->GetUpdateScreen();
84 ASSERT_TRUE(update_screen_
!= NULL
);
85 ASSERT_EQ(WizardController::default_controller()->current_screen(),
87 update_screen_
->screen_observer_
= mock_screen_observer_
.get();
90 virtual void CleanUpOnMainThread() OVERRIDE
{
91 mock_error_screen_
.reset();
92 mock_error_screen_actor_
.reset();
93 WizardInProcessBrowserTest::CleanUpOnMainThread();
96 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE
{
97 NetworkPortalDetector::Shutdown();
98 WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
101 void SetDefaultNetworkPath(const std::string
& service_path
) {
102 DCHECK(network_portal_detector_
);
103 network_portal_detector_
->SetDefaultNetworkPathForTesting(
107 void SetDetectionResults(
108 const std::string
& service_path
,
109 const NetworkPortalDetector::CaptivePortalState
& state
) {
110 DCHECK(network_portal_detector_
);
111 network_portal_detector_
->SetDetectionResultsForTesting(service_path
,
115 void NotifyPortalDetectionCompleted() {
116 DCHECK(network_portal_detector_
);
117 network_portal_detector_
->NotifyObserversForTesting();
120 FakeUpdateEngineClient
* fake_update_engine_client_
;
121 scoped_ptr
<MockScreenObserver
> mock_screen_observer_
;
122 scoped_ptr
<MockErrorScreenActor
> mock_error_screen_actor_
;
123 scoped_ptr
<MockErrorScreen
> mock_error_screen_
;
124 UpdateScreen
* update_screen_
;
125 NetworkPortalDetectorTestImpl
* network_portal_detector_
;
128 DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest
);
131 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestBasic
) {
132 ASSERT_TRUE(update_screen_
->actor_
!= NULL
);
135 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestNoUpdate
) {
136 update_screen_
->SetIgnoreIdleStatus(true);
137 UpdateEngineClient::Status status
;
138 status
.status
= UpdateEngineClient::UPDATE_STATUS_IDLE
;
139 update_screen_
->UpdateStatusChanged(status
);
140 status
.status
= UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE
;
141 update_screen_
->UpdateStatusChanged(status
);
142 status
.status
= UpdateEngineClient::UPDATE_STATUS_IDLE
;
143 // GetLastStatus() will be called via ExitUpdate() called from
144 // UpdateStatusChanged().
145 fake_update_engine_client_
->set_default_status(status
);
147 EXPECT_CALL(*mock_screen_observer_
, OnExit(ScreenObserver::UPDATE_NOUPDATE
))
149 update_screen_
->UpdateStatusChanged(status
);
152 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestUpdateAvailable
) {
153 update_screen_
->is_ignore_update_deadlines_
= true;
155 UpdateEngineClient::Status status
;
156 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE
;
157 status
.new_version
= "latest and greatest";
158 update_screen_
->UpdateStatusChanged(status
);
160 status
.status
= UpdateEngineClient::UPDATE_STATUS_DOWNLOADING
;
161 status
.download_progress
= 0.0;
162 update_screen_
->UpdateStatusChanged(status
);
164 status
.download_progress
= 0.5;
165 update_screen_
->UpdateStatusChanged(status
);
167 status
.download_progress
= 1.0;
168 update_screen_
->UpdateStatusChanged(status
);
170 status
.status
= UpdateEngineClient::UPDATE_STATUS_VERIFYING
;
171 update_screen_
->UpdateStatusChanged(status
);
173 status
.status
= UpdateEngineClient::UPDATE_STATUS_FINALIZING
;
174 update_screen_
->UpdateStatusChanged(status
);
176 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT
;
177 update_screen_
->UpdateStatusChanged(status
);
178 // UpdateStatusChanged(status) calls RebootAfterUpdate().
179 EXPECT_EQ(1, fake_update_engine_client_
->reboot_after_update_call_count());
182 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorIssuingUpdateCheck
) {
183 // First, cancel the update that is already in progress.
184 EXPECT_CALL(*mock_screen_observer_
,
185 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
187 update_screen_
->CancelUpdate();
189 fake_update_engine_client_
->set_update_check_result(
190 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
191 EXPECT_CALL(*mock_screen_observer_
,
192 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
194 update_screen_
->StartNetworkCheck();
197 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorCheckingForUpdate
) {
198 UpdateEngineClient::Status status
;
199 status
.status
= UpdateEngineClient::UPDATE_STATUS_ERROR
;
200 // GetLastStatus() will be called via ExitUpdate() called from
201 // UpdateStatusChanged().
202 fake_update_engine_client_
->set_default_status(status
);
204 EXPECT_CALL(*mock_screen_observer_
,
205 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
207 update_screen_
->UpdateStatusChanged(status
);
210 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorUpdating
) {
211 UpdateEngineClient::Status status
;
212 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE
;
213 status
.new_version
= "latest and greatest";
214 // GetLastStatus() will be called via ExitUpdate() called from
215 // UpdateStatusChanged().
216 fake_update_engine_client_
->set_default_status(status
);
218 update_screen_
->UpdateStatusChanged(status
);
220 status
.status
= UpdateEngineClient::UPDATE_STATUS_ERROR
;
221 // GetLastStatus() will be called via ExitUpdate() called from
222 // UpdateStatusChanged().
223 fake_update_engine_client_
->set_default_status(status
);
225 EXPECT_CALL(*mock_screen_observer_
,
226 OnExit(ScreenObserver::UPDATE_ERROR_UPDATING
))
228 update_screen_
->UpdateStatusChanged(status
);
231 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestTemproraryOfflineNetwork
) {
232 EXPECT_CALL(*mock_screen_observer_
,
233 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
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(kStubEthernetServicePath
, portal_state
);
243 // Update screen will show error message about portal state because
244 // ethernet is behind captive portal.
245 EXPECT_CALL(*mock_error_screen_actor_
,
246 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
248 EXPECT_CALL(*mock_error_screen_actor_
,
249 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL
, std::string()))
251 EXPECT_CALL(*mock_error_screen_actor_
, FixCaptivePortal())
253 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
256 update_screen_
->StartNetworkCheck();
258 NetworkPortalDetector::CaptivePortalState online_state
;
259 online_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
;
260 online_state
.response_code
= 204;
261 SetDetectionResults(kStubEthernetServicePath
, online_state
);
263 // Second notification from portal detector will be about online state,
264 // so update screen will hide error message and proceed to update.
265 EXPECT_CALL(*mock_screen_observer_
, HideErrorScreen(update_screen_
))
267 fake_update_engine_client_
->set_update_check_result(
268 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
270 EXPECT_CALL(*mock_screen_observer_
,
271 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
274 NotifyPortalDetectionCompleted();
277 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestTwoOfflineNetworks
) {
278 EXPECT_CALL(*mock_screen_observer_
,
279 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
281 update_screen_
->CancelUpdate();
283 // Change ethernet state to portal.
284 NetworkPortalDetector::CaptivePortalState portal_state
;
285 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
286 portal_state
.response_code
= 200;
287 SetDetectionResults(kStubEthernetServicePath
, portal_state
);
289 // Update screen will show error message about portal state because
290 // ethernet is behind captive portal.
291 EXPECT_CALL(*mock_error_screen_actor_
,
292 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
294 EXPECT_CALL(*mock_error_screen_actor_
,
295 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL
, std::string()))
297 EXPECT_CALL(*mock_error_screen_actor_
, FixCaptivePortal())
299 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
302 update_screen_
->StartNetworkCheck();
304 // Change active network to the wifi behind proxy.
305 NetworkPortalDetector::CaptivePortalState proxy_state
;
307 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED
;
308 proxy_state
.response_code
= -1;
309 SetDefaultNetworkPath(kStubWifiServicePath
);
310 SetDetectionResults(kStubWifiServicePath
, proxy_state
);
312 // Update screen will show message about proxy error because wifie
313 // network requires proxy authentication.
314 EXPECT_CALL(*mock_error_screen_actor_
,
315 SetErrorState(ErrorScreen::ERROR_STATE_PROXY
, std::string()))
318 NotifyPortalDetectionCompleted();
321 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestVoidNetwork
) {
322 SetDefaultNetworkPath("");
324 // Cancels pending update request.
325 EXPECT_CALL(*mock_screen_observer_
,
326 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
328 update_screen_
->CancelUpdate();
330 // First portal detection attempt returns NULL network and undefined
331 // results, so detection is restarted.
332 EXPECT_CALL(*mock_error_screen_actor_
,
335 EXPECT_CALL(*mock_error_screen_actor_
,
338 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
340 update_screen_
->StartNetworkCheck();
342 // Second portal detection also returns NULL network and undefined
343 // results. In this case, offline message should be displayed.
344 EXPECT_CALL(*mock_error_screen_actor_
,
345 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
347 EXPECT_CALL(*mock_error_screen_actor_
,
348 SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE
, std::string()))
350 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
352 base::MessageLoop::current()->RunUntilIdle();
353 NotifyPortalDetectionCompleted();
356 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestAPReselection
) {
357 EXPECT_CALL(*mock_screen_observer_
,
358 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
360 update_screen_
->CancelUpdate();
362 // Change ethernet state to portal.
363 NetworkPortalDetector::CaptivePortalState portal_state
;
364 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
365 portal_state
.response_code
= 200;
366 SetDetectionResults(kStubEthernetServicePath
, portal_state
);
368 // Update screen will show error message about portal state because
369 // ethernet is behind captive portal.
370 EXPECT_CALL(*mock_error_screen_actor_
,
371 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
373 EXPECT_CALL(*mock_error_screen_actor_
,
374 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL
, std::string()))
376 EXPECT_CALL(*mock_error_screen_actor_
, FixCaptivePortal())
378 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
381 update_screen_
->StartNetworkCheck();
383 // User re-selects the same network manually. In this case, hide
384 // offline message and skip network check. Since ethernet is still
385 // behind portal, update engine fails to update.
386 EXPECT_CALL(*mock_screen_observer_
, HideErrorScreen(update_screen_
))
388 fake_update_engine_client_
->set_update_check_result(
389 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
390 EXPECT_CALL(*mock_screen_observer_
,
391 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
394 update_screen_
->OnConnectToNetworkRequested(kStubEthernetServicePath
);
395 base::MessageLoop::current()->RunUntilIdle();
398 } // namespace chromeos