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. 4 5 #include "base/command_line.h" 6 #include "base/path_service.h" 7 #include "base/strings/utf_string_conversions.h" 8 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/browser_shutdown.h" 10 #include "chrome/browser/chromeos/login/enrollment/enrollment_screen.h" 11 #include "chrome/browser/chromeos/login/enrollment/mock_enrollment_screen.h" 12 #include "chrome/browser/chromeos/login/existing_user_controller.h" 13 #include "chrome/browser/chromeos/login/language_switch_menu.h" 14 #include "chrome/browser/chromeos/login/login_display_host_impl.h" 15 #include "chrome/browser/chromeos/login/mock_authenticator.h" 16 #include "chrome/browser/chromeos/login/mock_login_status_consumer.h" 17 #include "chrome/browser/chromeos/login/screens/mock_eula_screen.h" 18 #include "chrome/browser/chromeos/login/screens/mock_network_screen.h" 19 #include "chrome/browser/chromeos/login/screens/mock_update_screen.h" 20 #include "chrome/browser/chromeos/login/screens/network_screen.h" 21 #include "chrome/browser/chromeos/login/screens/reset_screen.h" 22 #include "chrome/browser/chromeos/login/screens/user_image_screen.h" 23 #include "chrome/browser/chromeos/login/screens/wrong_hwid_screen.h" 24 #include "chrome/browser/chromeos/login/startup_utils.h" 25 #include "chrome/browser/chromeos/login/test_login_utils.h" 26 #include "chrome/browser/chromeos/login/wizard_controller.h" 27 #include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h" 28 #include "chrome/common/chrome_paths.h" 29 #include "chrome/test/base/ui_test_utils.h" 30 #include "chromeos/chromeos_switches.h" 31 #include "chromeos/chromeos_test_utils.h" 32 #include "chromeos/network/network_state_handler.h" 33 #include "grit/generated_resources.h" 34 #include "testing/gmock/include/gmock/gmock.h" 35 #include "testing/gtest/include/gtest/gtest.h" 36 #include "third_party/icu/source/common/unicode/locid.h" 37 #include "ui/base/accelerators/accelerator.h" 38 #include "ui/base/l10n/l10n_util.h" 39 40 namespace chromeos { 41 42 namespace { 43 const char kUsername[] = "test_user (at) managedchrome.com"; 44 const char kPassword[] = "test_password"; 45 } // namespace 46 47 using ::testing::_; 48 49 template <class T, class H> 50 class MockOutShowHide : public T { 51 public: 52 template <class P> explicit MockOutShowHide(P p) : T(p) {} 53 template <class P> MockOutShowHide(P p, H* actor) 54 : T(p, actor), actor_(actor) {} 55 56 H* actor() const { return actor_.get(); } 57 58 MOCK_METHOD0(Show, void()); 59 MOCK_METHOD0(Hide, void()); 60 61 private: 62 scoped_ptr<H> actor_; 63 }; 64 65 #define MOCK(mock_var, screen_name, mocked_class, actor_class) \ 66 mock_var = new MockOutShowHide<mocked_class, actor_class>( \ 67 WizardController::default_controller(), new actor_class); \ 68 WizardController::default_controller()->screen_name.reset(mock_var); \ 69 EXPECT_CALL(*mock_var, Show()).Times(0); \ 70 EXPECT_CALL(*mock_var, Hide()).Times(0); 71 72 class WizardControllerTest : public WizardInProcessBrowserTest { 73 protected: 74 WizardControllerTest() : WizardInProcessBrowserTest( 75 WizardController::kTestNoScreenName) {} 76 virtual ~WizardControllerTest() {} 77 78 private: 79 DISALLOW_COPY_AND_ASSIGN(WizardControllerTest); 80 }; 81 82 IN_PROC_BROWSER_TEST_F(WizardControllerTest, SwitchLanguage) { 83 ASSERT_TRUE(WizardController::default_controller() != NULL); 84 WizardController::default_controller()->AdvanceToScreen( 85 WizardController::kNetworkScreenName); 86 87 // Checking the default locale. Provided that the profile is cleared in SetUp. 88 EXPECT_EQ("en-US", g_browser_process->GetApplicationLocale()); 89 EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); 90 EXPECT_FALSE(base::i18n::IsRTL()); 91 const std::wstring en_str = 92 UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE)); 93 94 LanguageSwitchMenu::SwitchLanguage("fr"); 95 EXPECT_EQ("fr", g_browser_process->GetApplicationLocale()); 96 EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); 97 EXPECT_FALSE(base::i18n::IsRTL()); 98 const std::wstring fr_str = 99 UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE)); 100 101 EXPECT_NE(en_str, fr_str); 102 103 LanguageSwitchMenu::SwitchLanguage("ar"); 104 EXPECT_EQ("ar", g_browser_process->GetApplicationLocale()); 105 EXPECT_STREQ("ar", icu::Locale::getDefault().getLanguage()); 106 EXPECT_TRUE(base::i18n::IsRTL()); 107 const std::wstring ar_str = 108 UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE)); 109 110 EXPECT_NE(fr_str, ar_str); 111 } 112 113 class WizardControllerFlowTest : public WizardControllerTest { 114 protected: 115 WizardControllerFlowTest() {} 116 // Overriden from InProcessBrowserTest: 117 virtual void SetUpOnMainThread() OVERRIDE { 118 WizardControllerTest::SetUpOnMainThread(); 119 120 // Make sure that OOBE is run as an "official" build. 121 WizardController::default_controller()->is_official_build_ = true; 122 123 // Clear portal list (as it is by default in OOBE). 124 NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); 125 126 // Set up the mocks for all screens. 127 MOCK(mock_network_screen_, network_screen_, 128 MockNetworkScreen, MockNetworkScreenActor); 129 MOCK(mock_update_screen_, update_screen_, 130 MockUpdateScreen, MockUpdateScreenActor); 131 MOCK(mock_eula_screen_, eula_screen_, MockEulaScreen, MockEulaScreenActor); 132 MOCK(mock_enrollment_screen_, enrollment_screen_, 133 MockEnrollmentScreen, MockEnrollmentScreenActor); 134 135 // Switch to the initial screen. 136 EXPECT_EQ(NULL, WizardController::default_controller()->current_screen()); 137 EXPECT_CALL(*mock_network_screen_, Show()).Times(1); 138 WizardController::default_controller()->AdvanceToScreen( 139 WizardController::kNetworkScreenName); 140 } 141 142 void OnExit(ScreenObserver::ExitCodes exit_code) { 143 WizardController::default_controller()->OnExit(exit_code); 144 } 145 146 MockOutShowHide<MockNetworkScreen, MockNetworkScreenActor>* 147 mock_network_screen_; 148 MockOutShowHide<MockUpdateScreen, MockUpdateScreenActor>* mock_update_screen_; 149 MockOutShowHide<MockEulaScreen, MockEulaScreenActor>* mock_eula_screen_; 150 MockOutShowHide<MockEnrollmentScreen, 151 MockEnrollmentScreenActor>* mock_enrollment_screen_; 152 153 private: 154 DISALLOW_COPY_AND_ASSIGN(WizardControllerFlowTest); 155 }; 156 157 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowMain) { 158 EXPECT_TRUE(ExistingUserController::current_controller() == NULL); 159 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 160 WizardController::default_controller()->current_screen()); 161 EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); 162 EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); 163 OnExit(ScreenObserver::NETWORK_CONNECTED); 164 165 EXPECT_EQ(WizardController::default_controller()->GetEulaScreen(), 166 WizardController::default_controller()->current_screen()); 167 EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); 168 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1); 169 EXPECT_CALL(*mock_update_screen_, Show()).Times(1); 170 OnExit(ScreenObserver::EULA_ACCEPTED); 171 // Let update screen smooth time process (time = 0ms). 172 content::RunAllPendingInMessageLoop(); 173 174 EXPECT_EQ(WizardController::default_controller()->GetUpdateScreen(), 175 WizardController::default_controller()->current_screen()); 176 EXPECT_CALL(*mock_update_screen_, Hide()).Times(0); 177 EXPECT_CALL(*mock_eula_screen_, Show()).Times(0); 178 OnExit(ScreenObserver::UPDATE_INSTALLED); 179 180 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 181 EXPECT_EQ( 182 "ethernet,wifi,cellular", 183 NetworkHandler::Get()->network_state_handler()->check_portal_list()); 184 } 185 186 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorUpdate) { 187 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 188 WizardController::default_controller()->current_screen()); 189 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); 190 EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); 191 EXPECT_CALL(*mock_update_screen_, Show()).Times(0); 192 EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); 193 OnExit(ScreenObserver::NETWORK_CONNECTED); 194 195 EXPECT_EQ(WizardController::default_controller()->GetEulaScreen(), 196 WizardController::default_controller()->current_screen()); 197 EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); 198 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1); 199 EXPECT_CALL(*mock_update_screen_, Show()).Times(1); 200 OnExit(ScreenObserver::EULA_ACCEPTED); 201 // Let update screen smooth time process (time = 0ms). 202 content::RunAllPendingInMessageLoop(); 203 204 EXPECT_EQ(WizardController::default_controller()->GetUpdateScreen(), 205 WizardController::default_controller()->current_screen()); 206 EXPECT_CALL(*mock_update_screen_, Hide()).Times(0); 207 EXPECT_CALL(*mock_eula_screen_, Show()).Times(0); 208 EXPECT_CALL(*mock_eula_screen_, Hide()).Times(0); // last transition 209 OnExit(ScreenObserver::UPDATE_ERROR_UPDATING); 210 211 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 212 } 213 214 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowSkipUpdateEnroll) { 215 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 216 WizardController::default_controller()->current_screen()); 217 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); 218 EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); 219 EXPECT_CALL(*mock_update_screen_, Show()).Times(0); 220 EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); 221 OnExit(ScreenObserver::NETWORK_CONNECTED); 222 223 EXPECT_EQ(WizardController::default_controller()->GetEulaScreen(), 224 WizardController::default_controller()->current_screen()); 225 EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); 226 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); 227 EXPECT_CALL(*mock_update_screen_, Show()).Times(0); 228 WizardController::default_controller()->SkipUpdateEnrollAfterEula(); 229 EXPECT_CALL(*mock_enrollment_screen_->actor(), 230 SetParameters(mock_enrollment_screen_, 231 false, // is_auto_enrollment 232 true, // can_exit_enrollment 233 "")) 234 .Times(1); 235 EXPECT_CALL(*mock_enrollment_screen_, Show()).Times(1); 236 EXPECT_CALL(*mock_enrollment_screen_, Hide()).Times(0); 237 OnExit(ScreenObserver::EULA_ACCEPTED); 238 content::RunAllPendingInMessageLoop(); 239 240 EXPECT_EQ(WizardController::default_controller()->GetEnrollmentScreen(), 241 WizardController::default_controller()->current_screen()); 242 EXPECT_TRUE(ExistingUserController::current_controller() == NULL); 243 EXPECT_EQ( 244 "ethernet,wifi,cellular", 245 NetworkHandler::Get()->network_state_handler()->check_portal_list()); 246 } 247 248 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEulaDeclined) { 249 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 250 WizardController::default_controller()->current_screen()); 251 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); 252 EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); 253 EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); 254 OnExit(ScreenObserver::NETWORK_CONNECTED); 255 256 EXPECT_EQ(WizardController::default_controller()->GetEulaScreen(), 257 WizardController::default_controller()->current_screen()); 258 EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); 259 EXPECT_CALL(*mock_network_screen_, Show()).Times(1); 260 EXPECT_CALL(*mock_network_screen_, Hide()).Times(0); // last transition 261 OnExit(ScreenObserver::EULA_BACK); 262 263 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 264 WizardController::default_controller()->current_screen()); 265 } 266 267 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, 268 ControlFlowEnrollmentCompleted) { 269 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 270 WizardController::default_controller()->current_screen()); 271 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); 272 EXPECT_CALL(*mock_enrollment_screen_->actor(), 273 SetParameters(mock_enrollment_screen_, 274 false, // is_auto_enrollment 275 true, // can_exit_enrollment 276 "")) 277 .Times(1); 278 EXPECT_CALL(*mock_enrollment_screen_, Show()).Times(1); 279 EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); 280 281 WizardController::default_controller()->AdvanceToScreen( 282 WizardController::kEnrollmentScreenName); 283 EnrollmentScreen* screen = 284 WizardController::default_controller()->GetEnrollmentScreen(); 285 EXPECT_EQ(screen, WizardController::default_controller()->current_screen()); 286 OnExit(ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED); 287 288 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 289 } 290 291 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, 292 ControlFlowAutoEnrollmentCompleted) { 293 WizardController::default_controller()->SkipPostLoginScreensForTesting(); 294 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 295 WizardController::default_controller()->current_screen()); 296 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(0); 297 298 LoginUtils::Set(new TestLoginUtils(kUsername, kPassword)); 299 MockConsumer mock_consumer; 300 301 // Must have a pending signin to resume after auto-enrollment: 302 LoginDisplayHostImpl::default_host()->StartSignInScreen(); 303 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 304 ExistingUserController::current_controller()->DoAutoEnrollment(); 305 ExistingUserController::current_controller()->set_login_status_consumer( 306 &mock_consumer); 307 // This calls StartWizard, destroying the current controller() and its mocks; 308 // don't set expectations on those objects. 309 ExistingUserController::current_controller()->CompleteLogin( 310 UserContext(kUsername, kPassword, "")); 311 // Run the tasks posted to complete the login: 312 base::MessageLoop::current()->RunUntilIdle(); 313 314 EnrollmentScreen* screen = 315 WizardController::default_controller()->GetEnrollmentScreen(); 316 EXPECT_EQ(screen, WizardController::default_controller()->current_screen()); 317 // This is the main expectation: after auto-enrollment, login is resumed. 318 EXPECT_CALL(mock_consumer, OnLoginSuccess(_, _, _)).Times(1); 319 OnExit(ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED); 320 // Prevent browser launch when the profile is prepared: 321 browser_shutdown::SetTryingToQuit(true); 322 // Run the tasks posted to complete the login: 323 base::MessageLoop::current()->RunUntilIdle(); 324 } 325 326 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowResetScreen) { 327 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 328 WizardController::default_controller()->current_screen()); 329 330 LoginDisplayHostImpl::default_host()->StartSignInScreen(); 331 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 332 ExistingUserController::current_controller()->OnStartDeviceReset(); 333 334 ResetScreen* screen = 335 WizardController::default_controller()->GetResetScreen(); 336 EXPECT_EQ(screen, WizardController::default_controller()->current_screen()); 337 338 // After reset screen is canceled, it returns to sign-in screen. 339 // And this destroys WizardController. 340 OnExit(ScreenObserver::RESET_CANCELED); 341 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 342 } 343 344 IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, 345 ControlFlowWrongHWIDScreenFromLogin) { 346 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 347 WizardController::default_controller()->current_screen()); 348 349 LoginDisplayHostImpl::default_host()->StartSignInScreen(); 350 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 351 ExistingUserController::current_controller()->ShowWrongHWIDScreen(); 352 353 WrongHWIDScreen* screen = 354 WizardController::default_controller()->GetWrongHWIDScreen(); 355 EXPECT_EQ(screen, WizardController::default_controller()->current_screen()); 356 357 // After warning is skipped, user returns to sign-in screen. 358 // And this destroys WizardController. 359 OnExit(ScreenObserver::WRONG_HWID_WARNING_SKIPPED); 360 EXPECT_FALSE(ExistingUserController::current_controller() == NULL); 361 } 362 363 class WizardControllerKioskFlowTest : public WizardControllerFlowTest { 364 protected: 365 WizardControllerKioskFlowTest() {} 366 367 // Overridden from InProcessBrowserTest: 368 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 369 base::FilePath test_data_dir; 370 ASSERT_TRUE(chromeos::test_utils::GetTestDataPath( 371 "app_mode", "kiosk_manifest", &test_data_dir)); 372 command_line->AppendSwitchPath( 373 switches::kAppOemManifestFile, 374 test_data_dir.AppendASCII("kiosk_manifest.json")); 375 } 376 377 private: 378 DISALLOW_COPY_AND_ASSIGN(WizardControllerKioskFlowTest); 379 }; 380 381 IN_PROC_BROWSER_TEST_F(WizardControllerKioskFlowTest, 382 ControlFlowKioskForcedEnrollment) { 383 EXPECT_CALL(*mock_enrollment_screen_->actor(), 384 SetParameters(mock_enrollment_screen_, 385 false, // is_auto_enrollment 386 false, // can_exit_enrollment 387 "")) 388 .Times(1); 389 390 EXPECT_TRUE(ExistingUserController::current_controller() == NULL); 391 EXPECT_EQ(WizardController::default_controller()->GetNetworkScreen(), 392 WizardController::default_controller()->current_screen()); 393 EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); 394 EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); 395 OnExit(ScreenObserver::NETWORK_CONNECTED); 396 397 EXPECT_EQ(WizardController::default_controller()->GetEulaScreen(), 398 WizardController::default_controller()->current_screen()); 399 EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); 400 EXPECT_CALL(*mock_update_screen_, StartNetworkCheck()).Times(1); 401 EXPECT_CALL(*mock_update_screen_, Show()).Times(1); 402 OnExit(ScreenObserver::EULA_ACCEPTED); 403 // Let update screen smooth time process (time = 0ms). 404 content::RunAllPendingInMessageLoop(); 405 406 EXPECT_EQ(WizardController::default_controller()->GetUpdateScreen(), 407 WizardController::default_controller()->current_screen()); 408 EXPECT_CALL(*mock_update_screen_, Hide()).Times(1); 409 EXPECT_CALL(*mock_enrollment_screen_, Show()).Times(1); 410 OnExit(ScreenObserver::UPDATE_INSTALLED); 411 412 EXPECT_FALSE(StartupUtils::IsOobeCompleted()); 413 414 // Make sure enterprise enrollment page shows up right after update screen. 415 EnrollmentScreen* screen = 416 WizardController::default_controller()->GetEnrollmentScreen(); 417 EXPECT_EQ(screen, WizardController::default_controller()->current_screen()); 418 OnExit(ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED); 419 420 EXPECT_TRUE(StartupUtils::IsOobeCompleted()); 421 } 422 423 // TODO(dzhioev): Add test emaulating device with wrong HWID. 424 425 // TODO(nkostylev): Add test for WebUI accelerators http://crosbug.com/22571 426 427 COMPILE_ASSERT(ScreenObserver::EXIT_CODES_COUNT == 18, 428 add_tests_for_new_control_flow_you_just_introduced); 429 430 } // namespace chromeos 431