Home | History | Annotate | Download | only in login
      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