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 TearDownInProcessBrowserTestFixture() OVERRIDE
{
91 NetworkPortalDetector::Shutdown();
92 WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
95 void SetDefaultNetworkPath(const std::string
& service_path
) {
96 DCHECK(network_portal_detector_
);
97 network_portal_detector_
->SetDefaultNetworkPathForTesting(
101 void SetDetectionResults(
102 const std::string
& service_path
,
103 const NetworkPortalDetector::CaptivePortalState
& state
) {
104 DCHECK(network_portal_detector_
);
105 network_portal_detector_
->SetDetectionResultsForTesting(service_path
,
109 void NotifyPortalDetectionCompleted() {
110 DCHECK(network_portal_detector_
);
111 network_portal_detector_
->NotifyObserversForTesting();
114 FakeUpdateEngineClient
* fake_update_engine_client_
;
115 scoped_ptr
<MockScreenObserver
> mock_screen_observer_
;
116 scoped_ptr
<MockErrorScreenActor
> mock_error_screen_actor_
;
117 scoped_ptr
<MockErrorScreen
> mock_error_screen_
;
118 UpdateScreen
* update_screen_
;
119 NetworkPortalDetectorTestImpl
* network_portal_detector_
;
122 DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest
);
125 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestBasic
) {
126 ASSERT_TRUE(update_screen_
->actor_
!= NULL
);
129 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestNoUpdate
) {
130 update_screen_
->SetIgnoreIdleStatus(true);
131 UpdateEngineClient::Status status
;
132 status
.status
= UpdateEngineClient::UPDATE_STATUS_IDLE
;
133 update_screen_
->UpdateStatusChanged(status
);
134 status
.status
= UpdateEngineClient::UPDATE_STATUS_CHECKING_FOR_UPDATE
;
135 update_screen_
->UpdateStatusChanged(status
);
136 status
.status
= UpdateEngineClient::UPDATE_STATUS_IDLE
;
137 // GetLastStatus() will be called via ExitUpdate() called from
138 // UpdateStatusChanged().
139 fake_update_engine_client_
->set_default_status(status
);
141 EXPECT_CALL(*mock_screen_observer_
, OnExit(ScreenObserver::UPDATE_NOUPDATE
))
143 update_screen_
->UpdateStatusChanged(status
);
146 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestUpdateAvailable
) {
147 update_screen_
->is_ignore_update_deadlines_
= true;
149 UpdateEngineClient::Status status
;
150 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE
;
151 status
.new_version
= "latest and greatest";
152 update_screen_
->UpdateStatusChanged(status
);
154 status
.status
= UpdateEngineClient::UPDATE_STATUS_DOWNLOADING
;
155 status
.download_progress
= 0.0;
156 update_screen_
->UpdateStatusChanged(status
);
158 status
.download_progress
= 0.5;
159 update_screen_
->UpdateStatusChanged(status
);
161 status
.download_progress
= 1.0;
162 update_screen_
->UpdateStatusChanged(status
);
164 status
.status
= UpdateEngineClient::UPDATE_STATUS_VERIFYING
;
165 update_screen_
->UpdateStatusChanged(status
);
167 status
.status
= UpdateEngineClient::UPDATE_STATUS_FINALIZING
;
168 update_screen_
->UpdateStatusChanged(status
);
170 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATED_NEED_REBOOT
;
171 update_screen_
->UpdateStatusChanged(status
);
172 // UpdateStatusChanged(status) calls RebootAfterUpdate().
173 EXPECT_EQ(1, fake_update_engine_client_
->reboot_after_update_call_count());
176 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorIssuingUpdateCheck
) {
177 // First, cancel the update that is already in progress.
178 EXPECT_CALL(*mock_screen_observer_
,
179 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
181 update_screen_
->CancelUpdate();
183 fake_update_engine_client_
->set_update_check_result(
184 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
185 EXPECT_CALL(*mock_screen_observer_
,
186 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
188 update_screen_
->StartNetworkCheck();
191 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorCheckingForUpdate
) {
192 UpdateEngineClient::Status status
;
193 status
.status
= UpdateEngineClient::UPDATE_STATUS_ERROR
;
194 // GetLastStatus() will be called via ExitUpdate() called from
195 // UpdateStatusChanged().
196 fake_update_engine_client_
->set_default_status(status
);
198 EXPECT_CALL(*mock_screen_observer_
,
199 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
201 update_screen_
->UpdateStatusChanged(status
);
204 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestErrorUpdating
) {
205 UpdateEngineClient::Status status
;
206 status
.status
= UpdateEngineClient::UPDATE_STATUS_UPDATE_AVAILABLE
;
207 status
.new_version
= "latest and greatest";
208 // GetLastStatus() will be called via ExitUpdate() called from
209 // UpdateStatusChanged().
210 fake_update_engine_client_
->set_default_status(status
);
212 update_screen_
->UpdateStatusChanged(status
);
214 status
.status
= UpdateEngineClient::UPDATE_STATUS_ERROR
;
215 // GetLastStatus() will be called via ExitUpdate() called from
216 // UpdateStatusChanged().
217 fake_update_engine_client_
->set_default_status(status
);
219 EXPECT_CALL(*mock_screen_observer_
,
220 OnExit(ScreenObserver::UPDATE_ERROR_UPDATING
))
222 update_screen_
->UpdateStatusChanged(status
);
225 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestTemproraryOfflineNetwork
) {
226 EXPECT_CALL(*mock_screen_observer_
,
227 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
229 update_screen_
->CancelUpdate();
231 // Change ethernet state to portal.
232 NetworkPortalDetector::CaptivePortalState portal_state
;
233 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
234 portal_state
.response_code
= 200;
235 SetDetectionResults(kStubEthernetServicePath
, portal_state
);
237 // Update screen will show error message about portal state because
238 // ethernet is behind captive portal.
239 EXPECT_CALL(*mock_error_screen_actor_
,
240 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
242 EXPECT_CALL(*mock_error_screen_actor_
,
243 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL
, std::string()))
245 EXPECT_CALL(*mock_error_screen_actor_
, FixCaptivePortal())
247 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
250 update_screen_
->StartNetworkCheck();
252 NetworkPortalDetector::CaptivePortalState online_state
;
253 online_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
;
254 online_state
.response_code
= 204;
255 SetDetectionResults(kStubEthernetServicePath
, online_state
);
257 // Second notification from portal detector will be about online state,
258 // so update screen will hide error message and proceed to update.
259 EXPECT_CALL(*mock_screen_observer_
, HideErrorScreen(update_screen_
))
261 fake_update_engine_client_
->set_update_check_result(
262 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
264 EXPECT_CALL(*mock_screen_observer_
,
265 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
268 NotifyPortalDetectionCompleted();
271 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestTwoOfflineNetworks
) {
272 EXPECT_CALL(*mock_screen_observer_
,
273 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
275 update_screen_
->CancelUpdate();
277 // Change ethernet state to portal.
278 NetworkPortalDetector::CaptivePortalState portal_state
;
279 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
280 portal_state
.response_code
= 200;
281 SetDetectionResults(kStubEthernetServicePath
, portal_state
);
283 // Update screen will show error message about portal state because
284 // ethernet is behind captive portal.
285 EXPECT_CALL(*mock_error_screen_actor_
,
286 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
288 EXPECT_CALL(*mock_error_screen_actor_
,
289 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL
, std::string()))
291 EXPECT_CALL(*mock_error_screen_actor_
, FixCaptivePortal())
293 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
296 update_screen_
->StartNetworkCheck();
298 // Change active network to the wifi behind proxy.
299 NetworkPortalDetector::CaptivePortalState proxy_state
;
301 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED
;
302 proxy_state
.response_code
= -1;
303 SetDefaultNetworkPath(kStubWifiServicePath
);
304 SetDetectionResults(kStubWifiServicePath
, proxy_state
);
306 // Update screen will show message about proxy error because wifie
307 // network requires proxy authentication.
308 EXPECT_CALL(*mock_error_screen_actor_
,
309 SetErrorState(ErrorScreen::ERROR_STATE_PROXY
, std::string()))
312 NotifyPortalDetectionCompleted();
315 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestVoidNetwork
) {
316 SetDefaultNetworkPath("");
318 // Cancels pending update request.
319 EXPECT_CALL(*mock_screen_observer_
,
320 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
322 update_screen_
->CancelUpdate();
324 // First portal detection attempt returns NULL network and undefined
325 // results, so detection is restarted.
326 EXPECT_CALL(*mock_error_screen_actor_
,
329 EXPECT_CALL(*mock_error_screen_actor_
,
332 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
334 update_screen_
->StartNetworkCheck();
336 // Second portal detection also returns NULL network and undefined
337 // results. In this case, offline message should be displayed.
338 EXPECT_CALL(*mock_error_screen_actor_
,
339 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
341 EXPECT_CALL(*mock_error_screen_actor_
,
342 SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE
, std::string()))
344 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
346 base::MessageLoop::current()->RunUntilIdle();
347 NotifyPortalDetectionCompleted();
350 IN_PROC_BROWSER_TEST_F(UpdateScreenTest
, TestAPReselection
) {
351 EXPECT_CALL(*mock_screen_observer_
,
352 OnExit(ScreenObserver::UPDATE_NOUPDATE
))
354 update_screen_
->CancelUpdate();
356 // Change ethernet state to portal.
357 NetworkPortalDetector::CaptivePortalState portal_state
;
358 portal_state
.status
= NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
;
359 portal_state
.response_code
= 200;
360 SetDetectionResults(kStubEthernetServicePath
, portal_state
);
362 // Update screen will show error message about portal state because
363 // ethernet is behind captive portal.
364 EXPECT_CALL(*mock_error_screen_actor_
,
365 SetUIState(ErrorScreen::UI_STATE_UPDATE
))
367 EXPECT_CALL(*mock_error_screen_actor_
,
368 SetErrorState(ErrorScreen::ERROR_STATE_PORTAL
, std::string()))
370 EXPECT_CALL(*mock_error_screen_actor_
, FixCaptivePortal())
372 EXPECT_CALL(*mock_screen_observer_
, ShowErrorScreen())
375 update_screen_
->StartNetworkCheck();
377 // User re-selects the same network manually. In this case, hide
378 // offline message and skip network check. Since ethernet is still
379 // behind portal, update engine fails to update.
380 EXPECT_CALL(*mock_screen_observer_
, HideErrorScreen(update_screen_
))
382 fake_update_engine_client_
->set_update_check_result(
383 chromeos::UpdateEngineClient::UPDATE_RESULT_FAILED
);
384 EXPECT_CALL(*mock_screen_observer_
,
385 OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE
))
388 update_screen_
->OnConnectToNetworkRequested(kStubEthernetServicePath
);
389 base::MessageLoop::current()->RunUntilIdle();
392 } // namespace chromeos