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 "base/utf_string_conversions.h"
6#include "chrome/browser/browser_process.h"
7#include "chrome/browser/chromeos/login/account_screen.h"
8#include "chrome/browser/chromeos/login/enterprise_enrollment_screen.h"
9#include "chrome/browser/chromeos/login/eula_view.h"
10#include "chrome/browser/chromeos/login/existing_user_controller.h"
11#include "chrome/browser/chromeos/login/language_switch_menu.h"
12#include "chrome/browser/chromeos/login/mock_update_screen.h"
13#include "chrome/browser/chromeos/login/network_screen.h"
14#include "chrome/browser/chromeos/login/network_selection_view.h"
15#include "chrome/browser/chromeos/login/user_image_screen.h"
16#include "chrome/browser/chromeos/login/wizard_controller.h"
17#include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h"
18#include "chrome/test/ui_test_utils.h"
19#include "grit/generated_resources.h"
20#include "testing/gmock/include/gmock/gmock.h"
21#include "testing/gtest/include/gtest/gtest.h"
22#include "ui/base/l10n/l10n_util.h"
23#include "unicode/locid.h"
24#include "views/accelerator.h"
25
26namespace {
27
28template <class T>
29class MockOutShowHide : public T {
30 public:
31  template <class P> MockOutShowHide(P p) : T(p) {}
32  template <class P1, class P2> MockOutShowHide(P1 p1, P2 p2) : T(p1, p2) {}
33  MOCK_METHOD0(Show, void());
34  MOCK_METHOD0(Hide, void());
35};
36
37template <class T>
38struct CreateMockWizardScreenHelper {
39  static MockOutShowHide<T>* Create(WizardController* wizard);
40};
41
42template <class T> MockOutShowHide<T>*
43CreateMockWizardScreenHelper<T>::Create(WizardController* wizard) {
44  return new MockOutShowHide<T>(wizard);
45}
46
47template <> MockOutShowHide<chromeos::NetworkScreen>*
48CreateMockWizardScreenHelper<chromeos::NetworkScreen>::Create(
49    WizardController* wizard) {
50  return new MockOutShowHide<chromeos::NetworkScreen>(wizard);
51}
52
53#define MOCK(mock_var, screen_name, mocked_class)                              \
54  mock_var = CreateMockWizardScreenHelper<mocked_class>::Create(controller()); \
55  controller()->screen_name.reset(mock_var);                                   \
56  EXPECT_CALL(*mock_var, Show()).Times(0);                                     \
57  EXPECT_CALL(*mock_var, Hide()).Times(0);
58
59}  // namespace
60
61using chromeos::ExistingUserController;
62
63class WizardControllerTest : public chromeos::WizardInProcessBrowserTest {
64 protected:
65  WizardControllerTest() : chromeos::WizardInProcessBrowserTest(
66      WizardController::kTestNoScreenName) {}
67  virtual ~WizardControllerTest() {}
68
69 private:
70  DISALLOW_COPY_AND_ASSIGN(WizardControllerTest);
71};
72
73IN_PROC_BROWSER_TEST_F(WizardControllerTest, SwitchLanguage) {
74  WizardController* const wizard = controller();
75  ASSERT_TRUE(wizard != NULL);
76  wizard->ShowFirstScreen(WizardController::kNetworkScreenName);
77  views::View* current_screen = wizard->contents();
78  ASSERT_TRUE(current_screen != NULL);
79
80  // Checking the default locale. Provided that the profile is cleared in SetUp.
81  EXPECT_EQ("en-US", g_browser_process->GetApplicationLocale());
82  EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage());
83  EXPECT_FALSE(base::i18n::IsRTL());
84  const std::wstring en_str =
85      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));
86
87  chromeos::LanguageSwitchMenu::SwitchLanguage("fr");
88  EXPECT_EQ("fr", g_browser_process->GetApplicationLocale());
89  EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage());
90  EXPECT_FALSE(base::i18n::IsRTL());
91  const std::wstring fr_str =
92      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));
93
94  EXPECT_NE(en_str, fr_str);
95
96  chromeos::LanguageSwitchMenu::SwitchLanguage("ar");
97  EXPECT_EQ("ar", g_browser_process->GetApplicationLocale());
98  EXPECT_STREQ("ar", icu::Locale::getDefault().getLanguage());
99  EXPECT_TRUE(base::i18n::IsRTL());
100  const std::wstring ar_str =
101      UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE));
102
103  EXPECT_NE(fr_str, ar_str);
104}
105
106class WizardControllerFlowTest : public WizardControllerTest {
107 protected:
108  WizardControllerFlowTest() {}
109  // Overriden from InProcessBrowserTest:
110  virtual Browser* CreateBrowser(Profile* profile) {
111    Browser* ret = WizardControllerTest::CreateBrowser(profile);
112
113    // Make sure that OOBE is run as an "official" build.
114    WizardController::default_controller()->is_official_build_ = true;
115
116    // Set up the mocks for all screens.
117    MOCK(mock_account_screen_, account_screen_, chromeos::AccountScreen);
118    MOCK(mock_network_screen_, network_screen_, chromeos::NetworkScreen);
119    MOCK(mock_update_screen_, update_screen_, MockUpdateScreen);
120    MOCK(mock_eula_screen_, eula_screen_, chromeos::EulaScreen);
121    MOCK(mock_enterprise_enrollment_screen_,
122         enterprise_enrollment_screen_,
123         chromeos::EnterpriseEnrollmentScreen);
124
125    // Switch to the initial screen.
126    EXPECT_EQ(NULL, controller()->current_screen());
127    EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
128    controller()->ShowFirstScreen(WizardController::kNetworkScreenName);
129
130    return ret;
131  }
132
133  void OnExit(chromeos::ScreenObserver::ExitCodes exit_code) {
134    controller()->OnExit(exit_code);
135  }
136
137  MockOutShowHide<chromeos::AccountScreen>* mock_account_screen_;
138  MockOutShowHide<chromeos::NetworkScreen>* mock_network_screen_;
139  MockOutShowHide<MockUpdateScreen>* mock_update_screen_;
140  MockOutShowHide<chromeos::EulaScreen>* mock_eula_screen_;
141  MockOutShowHide<chromeos::EnterpriseEnrollmentScreen>*
142      mock_enterprise_enrollment_screen_;
143
144 private:
145  DISALLOW_COPY_AND_ASSIGN(WizardControllerFlowTest);
146};
147
148IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowMain) {
149  EXPECT_TRUE(ExistingUserController::current_controller() == NULL);
150  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
151  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
152  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
153  OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED);
154
155  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
156  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
157  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1);
158  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
159  OnExit(chromeos::ScreenObserver::EULA_ACCEPTED);
160  // Let update screen smooth time process (time = 0ms).
161  ui_test_utils::RunAllPendingInMessageLoop();
162
163  EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen());
164  EXPECT_CALL(*mock_update_screen_, Hide()).Times(0);
165  EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
166  OnExit(chromeos::ScreenObserver::UPDATE_INSTALLED);
167
168  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
169  set_controller(NULL);
170}
171
172IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorUpdate) {
173  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
174  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
175  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
176  EXPECT_CALL(*mock_update_screen_, Show()).Times(0);
177  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
178  OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED);
179
180  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
181  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
182  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1);
183  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
184  OnExit(chromeos::ScreenObserver::EULA_ACCEPTED);
185  // Let update screen smooth time process (time = 0ms).
186  ui_test_utils::RunAllPendingInMessageLoop();
187
188  EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen());
189  EXPECT_CALL(*mock_update_screen_, Hide()).Times(0);
190  EXPECT_CALL(*mock_eula_screen_, Show()).Times(0);
191  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(0);  // last transition
192  OnExit(chromeos::ScreenObserver::UPDATE_ERROR_UPDATING);
193
194  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
195  set_controller(NULL);
196}
197
198IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEulaDeclined) {
199  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
200  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
201  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
202  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
203  OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED);
204
205  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
206  EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1);
207  EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
208  EXPECT_CALL(*mock_network_screen_, Hide()).Times(0);  // last transition
209  OnExit(chromeos::ScreenObserver::EULA_BACK);
210
211  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
212}
213
214IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorNetwork) {
215  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
216  OnExit(chromeos::ScreenObserver::NETWORK_OFFLINE);
217
218  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
219  set_controller(NULL);
220}
221
222#if !defined(OFFICIAL_BUILD)
223// TODO(mnissler): These tests are not yet enabled for official builds. Remove
224// the guards once we enable the enrollment feature for official builds.
225
226IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest,
227                       ControlFlowEnterpriseEnrollmentCompleted) {
228  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
229  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
230  EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1);
231  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
232  EXPECT_TRUE(controller()->contents()->GetFocusManager()->ProcessAccelerator(
233      views::Accelerator(ui::VKEY_P, false, true, true)));
234
235  EXPECT_EQ(controller()->GetEnterpriseEnrollmentScreen(),
236            controller()->current_screen());
237  OnExit(chromeos::ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED);
238
239  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
240  set_controller(NULL);
241}
242
243IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest,
244                       ControlFlowEnterpriseEnrollmentCancelled) {
245  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
246  EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0);
247  EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1);
248  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
249  EXPECT_TRUE(controller()->contents()->GetFocusManager()->ProcessAccelerator(
250      views::Accelerator(ui::VKEY_P, false, true, true)));
251
252  EXPECT_EQ(controller()->GetEnterpriseEnrollmentScreen(),
253            controller()->current_screen());
254  OnExit(chromeos::ScreenObserver::ENTERPRISE_ENROLLMENT_CANCELLED);
255
256  EXPECT_FALSE(ExistingUserController::current_controller() == NULL);
257  set_controller(NULL);
258}
259#endif
260
261#if defined(OFFICIAL_BUILD)
262// This test is supposed to fail on official build.
263#define MAYBE_Accelerators DISABLED_Accelerators
264#else
265#define MAYBE_Accelerators Accelerators
266#endif
267
268IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, MAYBE_Accelerators) {
269  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
270
271  views::FocusManager* focus_manager = NULL;
272  views::Accelerator accel_account_screen(ui::VKEY_A, false, true, true);
273  views::Accelerator accel_network_screen(ui::VKEY_N, false, true, true);
274  views::Accelerator accel_update_screen(ui::VKEY_U, false, true, true);
275  views::Accelerator accel_image_screen(ui::VKEY_I, false, true, true);
276  views::Accelerator accel_eula_screen(ui::VKEY_E, false, true, true);
277  views::Accelerator accel_enterprise_enrollment_screen(
278      ui::VKEY_P, false, true, true);
279
280  focus_manager = controller()->contents()->GetFocusManager();
281  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
282  EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1);
283  EXPECT_TRUE(
284      focus_manager->ProcessAccelerator(accel_enterprise_enrollment_screen));
285  EXPECT_EQ(controller()->GetEnterpriseEnrollmentScreen(),
286            controller()->current_screen());
287
288  focus_manager = controller()->contents()->GetFocusManager();
289  EXPECT_CALL(*mock_enterprise_enrollment_screen_, Hide()).Times(1);
290  EXPECT_CALL(*mock_account_screen_, Show()).Times(1);
291  EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_account_screen));
292  EXPECT_EQ(controller()->GetAccountScreen(), controller()->current_screen());
293
294  focus_manager = controller()->contents()->GetFocusManager();
295  EXPECT_CALL(*mock_account_screen_, Hide()).Times(1);
296  EXPECT_CALL(*mock_network_screen_, Show()).Times(1);
297  EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_network_screen));
298  EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen());
299
300  focus_manager = controller()->contents()->GetFocusManager();
301  EXPECT_CALL(*mock_network_screen_, Hide()).Times(1);
302  EXPECT_CALL(*mock_update_screen_, Show()).Times(1);
303  EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_update_screen));
304  EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen());
305
306  focus_manager = controller()->contents()->GetFocusManager();
307  EXPECT_CALL(*mock_update_screen_, Hide()).Times(1);
308  EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_image_screen));
309  EXPECT_EQ(controller()->GetUserImageScreen(), controller()->current_screen());
310
311  focus_manager = controller()->contents()->GetFocusManager();
312  EXPECT_CALL(*mock_eula_screen_, Show()).Times(1);
313  EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_eula_screen));
314  EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen());
315}
316
317COMPILE_ASSERT(chromeos::ScreenObserver::EXIT_CODES_COUNT == 17,
318               add_tests_for_new_control_flow_you_just_introduced);
319