1// Copyright (c) 2011 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/chromeos/cros/mock_login_library.h"
6#include "chrome/browser/chromeos/cros/mock_network_library.h"
7#include "chrome/browser/chromeos/cros/mock_update_library.h"
8#include "chrome/browser/chromeos/login/mock_screen_observer.h"
9#include "chrome/browser/chromeos/login/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 "testing/gtest/include/gtest/gtest.h"
13
14namespace chromeos {
15using ::testing::_;
16using ::testing::AnyNumber;
17using ::testing::AtLeast;
18using ::testing::Return;
19using ::testing::ReturnRef;
20using ::testing::Invoke;
21
22static void RequestUpdateCheckSuccess(UpdateCallback callback, void* userdata) {
23  callback(userdata, chromeos::UPDATE_RESULT_SUCCESS, NULL);
24}
25
26class UpdateScreenTest : public WizardInProcessBrowserTest {
27 public:
28  UpdateScreenTest() : WizardInProcessBrowserTest("update"),
29                       mock_login_library_(NULL),
30                       mock_update_library_(NULL),
31                       mock_network_library_(NULL) {}
32
33 protected:
34  virtual void SetUpInProcessBrowserTestFixture() {
35    WizardInProcessBrowserTest::SetUpInProcessBrowserTestFixture();
36    cros_mock_->InitStatusAreaMocks();
37    cros_mock_->SetStatusAreaMocksExpectations();
38    ASSERT_TRUE(CrosLibrary::Get()->EnsureLoaded());
39
40    mock_login_library_ = new MockLoginLibrary();
41    cros_mock_->test_api()->SetLoginLibrary(mock_login_library_, true);
42    EXPECT_CALL(*mock_login_library_, EmitLoginPromptReady())
43        .Times(1);
44
45    mock_update_library_ = new MockUpdateLibrary();
46    cros_mock_->test_api()->SetUpdateLibrary(mock_update_library_, true);
47
48    // UpdateScreen::StartUpdate() will be called by the WizardController
49    // just after creating the update screen, so the expectations for that
50    // should be set up here.
51    EXPECT_CALL(*mock_update_library_, AddObserver(_))
52        .Times(1);
53    EXPECT_CALL(*mock_update_library_, RemoveObserver(_))
54        .Times(AtLeast(1));
55    EXPECT_CALL(*mock_update_library_, RequestUpdateCheck(_,_))
56        .Times(1)
57        .WillOnce(Invoke(RequestUpdateCheckSuccess));
58
59    mock_network_library_ = cros_mock_->mock_network_library();
60    EXPECT_CALL(*mock_network_library_, Connected())
61        .Times(1)  // also called by NetworkMenu::InitMenuItems()
62        .WillRepeatedly((Return(false)))
63        .RetiresOnSaturation();
64    EXPECT_CALL(*mock_network_library_, AddNetworkManagerObserver(_))
65        .Times(1)
66        .RetiresOnSaturation();
67    EXPECT_CALL(*mock_network_library_, FindWifiDevice())
68        .Times(AnyNumber());
69    EXPECT_CALL(*mock_network_library_, FindEthernetDevice())
70        .Times(AnyNumber());
71  }
72
73  virtual void TearDownInProcessBrowserTestFixture() {
74    cros_mock_->test_api()->SetUpdateLibrary(NULL, true);
75    WizardInProcessBrowserTest::TearDownInProcessBrowserTestFixture();
76  }
77
78  MockLoginLibrary* mock_login_library_;
79  MockUpdateLibrary* mock_update_library_;
80  MockNetworkLibrary* mock_network_library_;
81
82 private:
83  DISALLOW_COPY_AND_ASSIGN(UpdateScreenTest);
84};
85
86IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestBasic) {
87  ASSERT_TRUE(controller() != NULL);
88  scoped_ptr<MockScreenObserver> mock_screen_observer(new MockScreenObserver());
89  controller()->set_observer(mock_screen_observer.get());
90  UpdateScreen* update_screen = controller()->GetUpdateScreen();
91  ASSERT_TRUE(update_screen != NULL);
92  ASSERT_EQ(controller()->current_screen(), update_screen);
93  UpdateView* update_view = update_screen->view();
94  ASSERT_TRUE(update_view != NULL);
95  controller()->set_observer(NULL);
96}
97
98IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestNoUpdate) {
99  ASSERT_TRUE(controller() != NULL);
100  scoped_ptr<MockScreenObserver> mock_screen_observer(new MockScreenObserver());
101  controller()->set_observer(mock_screen_observer.get());
102  UpdateScreen* update_screen = controller()->GetUpdateScreen();
103  ASSERT_TRUE(update_screen != NULL);
104  ASSERT_EQ(controller()->current_screen(), update_screen);
105
106  UpdateLibrary::Status status;
107  status.status = UPDATE_STATUS_IDLE;
108  EXPECT_CALL(*mock_update_library_, status())
109      .Times(AtLeast(1))
110      .WillRepeatedly(ReturnRef(status));
111  EXPECT_CALL(*mock_screen_observer, OnExit(ScreenObserver::UPDATE_NOUPDATE))
112      .Times(1);
113  update_screen->UpdateStatusChanged(mock_update_library_);
114
115  controller()->set_observer(NULL);
116}
117
118IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestUpdateAvailable) {
119  ASSERT_TRUE(controller() != NULL);
120  scoped_ptr<MockScreenObserver> mock_screen_observer(new MockScreenObserver());
121  controller()->set_observer(mock_screen_observer.get());
122  UpdateScreen* update_screen = controller()->GetUpdateScreen();
123  ASSERT_TRUE(update_screen != NULL);
124  ASSERT_EQ(controller()->current_screen(), update_screen);
125  update_screen->SetAllUpdatesCritical(true);
126
127  UpdateLibrary::Status status;
128
129  status.status = UPDATE_STATUS_UPDATE_AVAILABLE;
130  status.new_version = "latest and greatest";
131  EXPECT_CALL(*mock_update_library_, status())
132      .Times(AtLeast(1))
133      .WillRepeatedly(ReturnRef(status));
134  update_screen->UpdateStatusChanged(mock_update_library_);
135
136  status.status = UPDATE_STATUS_DOWNLOADING;
137  status.download_progress = 0.0;
138  EXPECT_CALL(*mock_update_library_, status())
139      .Times(AtLeast(1))
140      .WillRepeatedly(ReturnRef(status));
141  update_screen->UpdateStatusChanged(mock_update_library_);
142
143  status.download_progress = 0.5;
144  EXPECT_CALL(*mock_update_library_, status())
145      .Times(AtLeast(1))
146      .WillRepeatedly(ReturnRef(status));
147  update_screen->UpdateStatusChanged(mock_update_library_);
148
149  status.download_progress = 1.0;
150  EXPECT_CALL(*mock_update_library_, status())
151      .Times(AtLeast(1))
152      .WillRepeatedly(ReturnRef(status));
153  update_screen->UpdateStatusChanged(mock_update_library_);
154
155  status.status = UPDATE_STATUS_VERIFYING;
156  EXPECT_CALL(*mock_update_library_, status())
157      .Times(AtLeast(1))
158      .WillRepeatedly(ReturnRef(status));
159  update_screen->UpdateStatusChanged(mock_update_library_);
160
161  status.status = UPDATE_STATUS_FINALIZING;
162  EXPECT_CALL(*mock_update_library_, status())
163      .Times(AtLeast(1))
164      .WillRepeatedly(ReturnRef(status));
165  update_screen->UpdateStatusChanged(mock_update_library_);
166
167  status.status = UPDATE_STATUS_UPDATED_NEED_REBOOT;
168  EXPECT_CALL(*mock_update_library_, status())
169      .Times(AtLeast(1))
170      .WillRepeatedly(ReturnRef(status));
171  EXPECT_CALL(*mock_update_library_, RebootAfterUpdate())
172      .Times(1);
173  update_screen->UpdateStatusChanged(mock_update_library_);
174
175  controller()->set_observer(NULL);
176}
177
178static void RequestUpdateCheckFail(UpdateCallback callback, void* userdata) {
179  callback(userdata, chromeos::UPDATE_RESULT_FAILED, NULL);
180}
181
182IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorIssuingUpdateCheck) {
183  ASSERT_TRUE(controller() != NULL);
184  scoped_ptr<MockScreenObserver> mock_screen_observer(new MockScreenObserver());
185  controller()->set_observer(mock_screen_observer.get());
186  UpdateScreen* update_screen = controller()->GetUpdateScreen();
187  ASSERT_TRUE(update_screen != NULL);
188  ASSERT_EQ(controller()->current_screen(), update_screen);
189
190  // First, cancel the update that is already in progress.
191  EXPECT_CALL(*mock_screen_observer,
192              OnExit(ScreenObserver::UPDATE_NOUPDATE))
193      .Times(1);
194  update_screen->CancelUpdate();
195
196  // Run UpdateScreen::StartUpdate() again, but CheckForUpdate() will fail
197  // issuing the update check this time.
198  EXPECT_CALL(*mock_update_library_, AddObserver(_))
199      .Times(1);
200  EXPECT_CALL(*mock_update_library_, RemoveObserver(_))
201      .Times(AtLeast(1));
202  EXPECT_CALL(*mock_update_library_, RequestUpdateCheck(_,_))
203      .Times(1)
204      .WillOnce(Invoke(RequestUpdateCheckFail));
205  EXPECT_CALL(*mock_screen_observer,
206              OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE))
207      .Times(1);
208  update_screen->StartUpdate();
209
210  controller()->set_observer(NULL);
211}
212
213IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorCheckingForUpdate) {
214  ASSERT_TRUE(controller() != NULL);
215  scoped_ptr<MockScreenObserver> mock_screen_observer(new MockScreenObserver());
216  controller()->set_observer(mock_screen_observer.get());
217  UpdateScreen* update_screen = controller()->GetUpdateScreen();
218  ASSERT_TRUE(update_screen != NULL);
219  ASSERT_EQ(controller()->current_screen(), update_screen);
220
221  UpdateLibrary::Status status;
222  status.status = UPDATE_STATUS_ERROR;
223  EXPECT_CALL(*mock_update_library_, status())
224      .Times(AtLeast(1))
225      .WillRepeatedly(ReturnRef(status));
226  EXPECT_CALL(*mock_screen_observer,
227              OnExit(ScreenObserver::UPDATE_ERROR_CHECKING_FOR_UPDATE))
228      .Times(1);
229  update_screen->UpdateStatusChanged(mock_update_library_);
230
231  controller()->set_observer(NULL);
232}
233
234IN_PROC_BROWSER_TEST_F(UpdateScreenTest, TestErrorUpdating) {
235  ASSERT_TRUE(controller() != NULL);
236  scoped_ptr<MockScreenObserver> mock_screen_observer(new MockScreenObserver());
237  controller()->set_observer(mock_screen_observer.get());
238  UpdateScreen* update_screen = controller()->GetUpdateScreen();
239  ASSERT_TRUE(update_screen != NULL);
240  ASSERT_EQ(controller()->current_screen(), update_screen);
241
242  UpdateLibrary::Status status;
243
244  status.status = UPDATE_STATUS_UPDATE_AVAILABLE;
245  status.new_version = "latest and greatest";
246  EXPECT_CALL(*mock_update_library_, status())
247      .Times(AtLeast(1))
248      .WillRepeatedly(ReturnRef(status));
249  update_screen->UpdateStatusChanged(mock_update_library_);
250
251  status.status = UPDATE_STATUS_ERROR;
252  EXPECT_CALL(*mock_update_library_, status())
253      .Times(AtLeast(1))
254      .WillRepeatedly(ReturnRef(status));
255  EXPECT_CALL(*mock_screen_observer,
256              OnExit(ScreenObserver::UPDATE_ERROR_UPDATING))
257      .Times(1);
258  update_screen->UpdateStatusChanged(mock_update_library_);
259
260  controller()->set_observer(NULL);
261}
262
263}  // namespace chromeos
264