// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/login/account_screen.h" #include "chrome/browser/chromeos/login/enterprise_enrollment_screen.h" #include "chrome/browser/chromeos/login/eula_view.h" #include "chrome/browser/chromeos/login/existing_user_controller.h" #include "chrome/browser/chromeos/login/language_switch_menu.h" #include "chrome/browser/chromeos/login/mock_update_screen.h" #include "chrome/browser/chromeos/login/network_screen.h" #include "chrome/browser/chromeos/login/network_selection_view.h" #include "chrome/browser/chromeos/login/user_image_screen.h" #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/login/wizard_in_process_browser_test.h" #include "chrome/test/ui_test_utils.h" #include "grit/generated_resources.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" #include "unicode/locid.h" #include "views/accelerator.h" namespace { template <class T> class MockOutShowHide : public T { public: template <class P> MockOutShowHide(P p) : T(p) {} template <class P1, class P2> MockOutShowHide(P1 p1, P2 p2) : T(p1, p2) {} MOCK_METHOD0(Show, void()); MOCK_METHOD0(Hide, void()); }; template <class T> struct CreateMockWizardScreenHelper { static MockOutShowHide<T>* Create(WizardController* wizard); }; template <class T> MockOutShowHide<T>* CreateMockWizardScreenHelper<T>::Create(WizardController* wizard) { return new MockOutShowHide<T>(wizard); } template <> MockOutShowHide<chromeos::NetworkScreen>* CreateMockWizardScreenHelper<chromeos::NetworkScreen>::Create( WizardController* wizard) { return new MockOutShowHide<chromeos::NetworkScreen>(wizard); } #define MOCK(mock_var, screen_name, mocked_class) \ mock_var = CreateMockWizardScreenHelper<mocked_class>::Create(controller()); \ controller()->screen_name.reset(mock_var); \ EXPECT_CALL(*mock_var, Show()).Times(0); \ EXPECT_CALL(*mock_var, Hide()).Times(0); } // namespace using chromeos::ExistingUserController; class WizardControllerTest : public chromeos::WizardInProcessBrowserTest { protected: WizardControllerTest() : chromeos::WizardInProcessBrowserTest( WizardController::kTestNoScreenName) {} virtual ~WizardControllerTest() {} private: DISALLOW_COPY_AND_ASSIGN(WizardControllerTest); }; IN_PROC_BROWSER_TEST_F(WizardControllerTest, SwitchLanguage) { WizardController* const wizard = controller(); ASSERT_TRUE(wizard != NULL); wizard->ShowFirstScreen(WizardController::kNetworkScreenName); views::View* current_screen = wizard->contents(); ASSERT_TRUE(current_screen != NULL); // Checking the default locale. Provided that the profile is cleared in SetUp. EXPECT_EQ("en-US", g_browser_process->GetApplicationLocale()); EXPECT_STREQ("en", icu::Locale::getDefault().getLanguage()); EXPECT_FALSE(base::i18n::IsRTL()); const std::wstring en_str = UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE)); chromeos::LanguageSwitchMenu::SwitchLanguage("fr"); EXPECT_EQ("fr", g_browser_process->GetApplicationLocale()); EXPECT_STREQ("fr", icu::Locale::getDefault().getLanguage()); EXPECT_FALSE(base::i18n::IsRTL()); const std::wstring fr_str = UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE)); EXPECT_NE(en_str, fr_str); chromeos::LanguageSwitchMenu::SwitchLanguage("ar"); EXPECT_EQ("ar", g_browser_process->GetApplicationLocale()); EXPECT_STREQ("ar", icu::Locale::getDefault().getLanguage()); EXPECT_TRUE(base::i18n::IsRTL()); const std::wstring ar_str = UTF16ToWide(l10n_util::GetStringUTF16(IDS_NETWORK_SELECTION_TITLE)); EXPECT_NE(fr_str, ar_str); } class WizardControllerFlowTest : public WizardControllerTest { protected: WizardControllerFlowTest() {} // Overriden from InProcessBrowserTest: virtual Browser* CreateBrowser(Profile* profile) { Browser* ret = WizardControllerTest::CreateBrowser(profile); // Make sure that OOBE is run as an "official" build. WizardController::default_controller()->is_official_build_ = true; // Set up the mocks for all screens. MOCK(mock_account_screen_, account_screen_, chromeos::AccountScreen); MOCK(mock_network_screen_, network_screen_, chromeos::NetworkScreen); MOCK(mock_update_screen_, update_screen_, MockUpdateScreen); MOCK(mock_eula_screen_, eula_screen_, chromeos::EulaScreen); MOCK(mock_enterprise_enrollment_screen_, enterprise_enrollment_screen_, chromeos::EnterpriseEnrollmentScreen); // Switch to the initial screen. EXPECT_EQ(NULL, controller()->current_screen()); EXPECT_CALL(*mock_network_screen_, Show()).Times(1); controller()->ShowFirstScreen(WizardController::kNetworkScreenName); return ret; } void OnExit(chromeos::ScreenObserver::ExitCodes exit_code) { controller()->OnExit(exit_code); } MockOutShowHide<chromeos::AccountScreen>* mock_account_screen_; MockOutShowHide<chromeos::NetworkScreen>* mock_network_screen_; MockOutShowHide<MockUpdateScreen>* mock_update_screen_; MockOutShowHide<chromeos::EulaScreen>* mock_eula_screen_; MockOutShowHide<chromeos::EnterpriseEnrollmentScreen>* mock_enterprise_enrollment_screen_; private: DISALLOW_COPY_AND_ASSIGN(WizardControllerFlowTest); }; IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowMain) { EXPECT_TRUE(ExistingUserController::current_controller() == NULL); EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED); EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen()); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(1); OnExit(chromeos::ScreenObserver::EULA_ACCEPTED); // Let update screen smooth time process (time = 0ms). ui_test_utils::RunAllPendingInMessageLoop(); EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen()); EXPECT_CALL(*mock_update_screen_, Hide()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(0); OnExit(chromeos::ScreenObserver::UPDATE_INSTALLED); EXPECT_FALSE(ExistingUserController::current_controller() == NULL); set_controller(NULL); } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorUpdate) { EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(0); EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED); EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen()); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(1); OnExit(chromeos::ScreenObserver::EULA_ACCEPTED); // Let update screen smooth time process (time = 0ms). ui_test_utils::RunAllPendingInMessageLoop(); EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen()); EXPECT_CALL(*mock_update_screen_, Hide()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(0); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(0); // last transition OnExit(chromeos::ScreenObserver::UPDATE_ERROR_UPDATING); EXPECT_FALSE(ExistingUserController::current_controller() == NULL); set_controller(NULL); } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEulaDeclined) { EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); OnExit(chromeos::ScreenObserver::NETWORK_CONNECTED); EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen()); EXPECT_CALL(*mock_eula_screen_, Hide()).Times(1); EXPECT_CALL(*mock_network_screen_, Show()).Times(1); EXPECT_CALL(*mock_network_screen_, Hide()).Times(0); // last transition OnExit(chromeos::ScreenObserver::EULA_BACK); EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowErrorNetwork) { EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); OnExit(chromeos::ScreenObserver::NETWORK_OFFLINE); EXPECT_FALSE(ExistingUserController::current_controller() == NULL); set_controller(NULL); } #if !defined(OFFICIAL_BUILD) // TODO(mnissler): These tests are not yet enabled for official builds. Remove // the guards once we enable the enrollment feature for official builds. IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEnterpriseEnrollmentCompleted) { EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0); EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1); EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); EXPECT_TRUE(controller()->contents()->GetFocusManager()->ProcessAccelerator( views::Accelerator(ui::VKEY_P, false, true, true))); EXPECT_EQ(controller()->GetEnterpriseEnrollmentScreen(), controller()->current_screen()); OnExit(chromeos::ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED); EXPECT_FALSE(ExistingUserController::current_controller() == NULL); set_controller(NULL); } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, ControlFlowEnterpriseEnrollmentCancelled) { EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); EXPECT_CALL(*mock_update_screen_, StartUpdate()).Times(0); EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1); EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); EXPECT_TRUE(controller()->contents()->GetFocusManager()->ProcessAccelerator( views::Accelerator(ui::VKEY_P, false, true, true))); EXPECT_EQ(controller()->GetEnterpriseEnrollmentScreen(), controller()->current_screen()); OnExit(chromeos::ScreenObserver::ENTERPRISE_ENROLLMENT_CANCELLED); EXPECT_FALSE(ExistingUserController::current_controller() == NULL); set_controller(NULL); } #endif #if defined(OFFICIAL_BUILD) // This test is supposed to fail on official build. #define MAYBE_Accelerators DISABLED_Accelerators #else #define MAYBE_Accelerators Accelerators #endif IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, MAYBE_Accelerators) { EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); views::FocusManager* focus_manager = NULL; views::Accelerator accel_account_screen(ui::VKEY_A, false, true, true); views::Accelerator accel_network_screen(ui::VKEY_N, false, true, true); views::Accelerator accel_update_screen(ui::VKEY_U, false, true, true); views::Accelerator accel_image_screen(ui::VKEY_I, false, true, true); views::Accelerator accel_eula_screen(ui::VKEY_E, false, true, true); views::Accelerator accel_enterprise_enrollment_screen( ui::VKEY_P, false, true, true); focus_manager = controller()->contents()->GetFocusManager(); EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); EXPECT_CALL(*mock_enterprise_enrollment_screen_, Show()).Times(1); EXPECT_TRUE( focus_manager->ProcessAccelerator(accel_enterprise_enrollment_screen)); EXPECT_EQ(controller()->GetEnterpriseEnrollmentScreen(), controller()->current_screen()); focus_manager = controller()->contents()->GetFocusManager(); EXPECT_CALL(*mock_enterprise_enrollment_screen_, Hide()).Times(1); EXPECT_CALL(*mock_account_screen_, Show()).Times(1); EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_account_screen)); EXPECT_EQ(controller()->GetAccountScreen(), controller()->current_screen()); focus_manager = controller()->contents()->GetFocusManager(); EXPECT_CALL(*mock_account_screen_, Hide()).Times(1); EXPECT_CALL(*mock_network_screen_, Show()).Times(1); EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_network_screen)); EXPECT_EQ(controller()->GetNetworkScreen(), controller()->current_screen()); focus_manager = controller()->contents()->GetFocusManager(); EXPECT_CALL(*mock_network_screen_, Hide()).Times(1); EXPECT_CALL(*mock_update_screen_, Show()).Times(1); EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_update_screen)); EXPECT_EQ(controller()->GetUpdateScreen(), controller()->current_screen()); focus_manager = controller()->contents()->GetFocusManager(); EXPECT_CALL(*mock_update_screen_, Hide()).Times(1); EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_image_screen)); EXPECT_EQ(controller()->GetUserImageScreen(), controller()->current_screen()); focus_manager = controller()->contents()->GetFocusManager(); EXPECT_CALL(*mock_eula_screen_, Show()).Times(1); EXPECT_TRUE(focus_manager->ProcessAccelerator(accel_eula_screen)); EXPECT_EQ(controller()->GetEulaScreen(), controller()->current_screen()); } COMPILE_ASSERT(chromeos::ScreenObserver::EXIT_CODES_COUNT == 17, add_tests_for_new_control_flow_you_just_introduced);