Home | History | Annotate | Download | only in user
      1 // Copyright 2013 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 <vector>
      6 
      7 #include "ash/root_window_controller.h"
      8 #include "ash/shelf/shelf_layout_manager.h"
      9 #include "ash/shell.h"
     10 #include "ash/shell_delegate.h"
     11 #include "ash/system/tray/system_tray.h"
     12 #include "ash/system/user/tray_user.h"
     13 #include "ash/test/ash_test_base.h"
     14 #include "ash/test/test_session_state_delegate.h"
     15 #include "ash/test/test_shell_delegate.h"
     16 #include "ui/aura/test/event_generator.h"
     17 #include "ui/base/animation/animation_container_element.h"
     18 #include "ui/views/view.h"
     19 #include "ui/views/widget/widget.h"
     20 
     21 namespace ash {
     22 namespace internal {
     23 
     24 class TrayUserTest : public ash::test::AshTestBase {
     25  public:
     26   TrayUserTest();
     27 
     28   // testing::Test:
     29   virtual void SetUp() OVERRIDE;
     30 
     31   // This has to be called prior to first use with the proper configuration.
     32   void InitializeParameters(int users_logged_in, bool multiprofile);
     33 
     34   // Show the system tray menu using the provided event generator.
     35   void ShowTrayMenu(aura::test::EventGenerator* generator);
     36 
     37   // Move the mouse over the user item.
     38   void MoveOverUserItem(aura::test::EventGenerator* generator, int index);
     39 
     40   // Click on the user item. Note that the tray menu needs to be shown.
     41   void ClickUserItem(aura::test::EventGenerator* generator, int index);
     42 
     43   // Accessors to various system components.
     44   ShelfLayoutManager* shelf() { return shelf_; }
     45   SystemTray* tray() { return tray_; }
     46   ash::test::TestSessionStateDelegate* delegate() { return delegate_; }
     47   ash::internal::TrayUser* tray_user(int index) { return tray_user_[index]; }
     48 
     49  private:
     50   ShelfLayoutManager* shelf_;
     51   SystemTray* tray_;
     52   ash::test::TestSessionStateDelegate* delegate_;
     53   // Note that the ownership of these items is on the shelf.
     54   std::vector<ash::internal::TrayUser*> tray_user_;
     55 
     56   DISALLOW_COPY_AND_ASSIGN(TrayUserTest);
     57 };
     58 
     59 TrayUserTest::TrayUserTest()
     60     : shelf_(NULL),
     61       tray_(NULL),
     62       delegate_(NULL) {
     63 }
     64 
     65 void TrayUserTest::SetUp() {
     66   ash::test::AshTestBase::SetUp();
     67   shelf_ = Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager();
     68   tray_ = Shell::GetPrimaryRootWindowController()->GetSystemTray();
     69   delegate_ = static_cast<ash::test::TestSessionStateDelegate*>(
     70       ash::Shell::GetInstance()->session_state_delegate());
     71 }
     72 
     73 void TrayUserTest::InitializeParameters(int users_logged_in,
     74                                         bool multiprofile) {
     75   // Show the shelf.
     76   shelf()->LayoutShelf();
     77   shelf()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
     78 
     79   // Set our default assumptions. Note that it is sufficient to set these
     80   // after everything was created.
     81   delegate_->set_logged_in_users(users_logged_in);
     82   ash::test::TestShellDelegate* shell_delegate =
     83       static_cast<ash::test::TestShellDelegate*>(
     84           ash::Shell::GetInstance()->delegate());
     85   shell_delegate->set_multi_profiles_enabled(multiprofile);
     86 
     87   // Instead of using the existing tray panels we create new ones which makes
     88   // the access easier.
     89   // Note that we create one more element then there can be users to show a
     90   // separator.
     91   for (int i = 0; i <= delegate_->GetMaximumNumberOfLoggedInUsers(); i++) {
     92     tray_user_.push_back(new ash::internal::TrayUser(tray_, i));
     93     tray_->AddTrayItem(tray_user_[i]);
     94   }
     95 }
     96 
     97 void TrayUserTest::ShowTrayMenu(aura::test::EventGenerator* generator) {
     98   gfx::Point center = tray()->GetBoundsInScreen().CenterPoint();
     99 
    100   generator->MoveMouseTo(center.x(), center.y());
    101   EXPECT_FALSE(tray()->IsAnyBubbleVisible());
    102   generator->ClickLeftButton();
    103 }
    104 
    105 void TrayUserTest::MoveOverUserItem(aura::test::EventGenerator* generator,
    106     int index) {
    107   gfx::Point center =
    108       tray_user(index)->GetUserPanelBoundsInScreenForTest().CenterPoint();
    109 
    110   generator->MoveMouseTo(center.x(), center.y());
    111 }
    112 
    113 void TrayUserTest::ClickUserItem(aura::test::EventGenerator* generator,
    114                                  int index) {
    115   MoveOverUserItem(generator, index);
    116   generator->ClickLeftButton();
    117 }
    118 
    119 // Make sure that in single user mode the user panel cannot be activated and no
    120 // separators are being created.
    121 TEST_F(TrayUserTest, SingleUserModeDoesNotAllowAddingUser) {
    122   InitializeParameters(1, false);
    123 
    124   // Move the mouse over the status area and click to open the status menu.
    125   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    126 
    127   EXPECT_FALSE(tray()->IsAnyBubbleVisible());
    128 
    129   for (int i = 0; i <= delegate()->GetMaximumNumberOfLoggedInUsers(); i++)
    130     EXPECT_EQ(ash::internal::TrayUser::HIDDEN,
    131               tray_user(i)->GetStateForTest());
    132 
    133   ShowTrayMenu(&generator);
    134 
    135   EXPECT_TRUE(tray()->HasSystemBubble());
    136   EXPECT_TRUE(tray()->IsAnyBubbleVisible());
    137 
    138   for (int i = 0; i <= delegate()->GetMaximumNumberOfLoggedInUsers(); i++)
    139     EXPECT_EQ(i == 0 ? ash::internal::TrayUser::SHOWN :
    140                        ash::internal::TrayUser::HIDDEN,
    141               tray_user(i)->GetStateForTest());
    142 
    143   tray()->CloseSystemBubble();
    144 }
    145 
    146 // Make sure that in multi user mode the user panel can be activated and there
    147 // will be one panel for each user plus a separator.
    148 // Note: the mouse watcher (for automatic closing upon leave) cannot be tested
    149 // here since it does not work with the event system in unit tests.
    150 TEST_F(TrayUserTest, MutiUserModeDoesNotAllowToAddUser) {
    151   InitializeParameters(1, true);
    152 
    153   // Move the mouse over the status area and click to open the status menu.
    154   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    155   generator.set_async(false);
    156 
    157   int max_users = delegate()->GetMaximumNumberOfLoggedInUsers();
    158   // Checking now for each amount of users that the correct is done.
    159   for (int j = 1; j < max_users; j++) {
    160     // Set the number of logged in users.
    161     delegate()->set_logged_in_users(j);
    162 
    163     // Verify that nothing is shown.
    164     EXPECT_FALSE(tray()->IsAnyBubbleVisible());
    165     for (int i = 0; i <= max_users; i++)
    166       EXPECT_FALSE(tray_user(i)->GetStateForTest());
    167 
    168     // After clicking on the tray the menu should get shown and for each logged
    169     // in user we should get a visible item. In addition, the separator should
    170     // show up when we reach more then one user.
    171     ShowTrayMenu(&generator);
    172 
    173     EXPECT_TRUE(tray()->HasSystemBubble());
    174     EXPECT_TRUE(tray()->IsAnyBubbleVisible());
    175     for (int i = 0; i < max_users; i++) {
    176       EXPECT_EQ(i < j ? ash::internal::TrayUser::SHOWN :
    177                         ash::internal::TrayUser::HIDDEN,
    178                 tray_user(i)->GetStateForTest());
    179     }
    180 
    181     // Check the visibility of the separator.
    182     EXPECT_EQ(j > 1 ? ash::internal::TrayUser::SEPARATOR :
    183                       ash::internal::TrayUser::HIDDEN,
    184               tray_user(max_users)->GetStateForTest());
    185 
    186     // Move the mouse over the user item and it should hover.
    187     MoveOverUserItem(&generator, 0);
    188     EXPECT_EQ(ash::internal::TrayUser::HOVERED,
    189               tray_user(0)->GetStateForTest());
    190     for (int i = 1; i < max_users; i++) {
    191       EXPECT_EQ(i < j ? ash::internal::TrayUser::SHOWN :
    192                         ash::internal::TrayUser::HIDDEN,
    193                 tray_user(i)->GetStateForTest());
    194     }
    195 
    196     // Check that clicking the button allows to add item if we have still room
    197     // for one more user.
    198     ClickUserItem(&generator, 0);
    199     EXPECT_EQ(j == max_users ?
    200                   ash::internal::TrayUser::ACTIVE_BUT_DISABLED :
    201                   ash::internal::TrayUser::ACTIVE,
    202               tray_user(0)->GetStateForTest());
    203 
    204     // Click the button again to see that the menu goes away.
    205     ClickUserItem(&generator, 0);
    206     EXPECT_EQ(ash::internal::TrayUser::HOVERED,
    207               tray_user(0)->GetStateForTest());
    208 
    209     // Close and check that everything is deleted.
    210     tray()->CloseSystemBubble();
    211     EXPECT_FALSE(tray()->IsAnyBubbleVisible());
    212     for (int i = 0; i < delegate()->GetMaximumNumberOfLoggedInUsers(); i++)
    213       EXPECT_EQ(ash::internal::TrayUser::HIDDEN,
    214                 tray_user(i)->GetStateForTest());
    215   }
    216 }
    217 
    218 // Make sure that user changing gets properly executed.
    219 TEST_F(TrayUserTest, MutiUserModeButtonClicks) {
    220   // Have two users.
    221   InitializeParameters(2, true);
    222   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
    223   ShowTrayMenu(&generator);
    224 
    225   // Switch to a new user.
    226   ClickUserItem(&generator, 1);
    227 
    228   EXPECT_EQ(delegate()->get_activated_user(), delegate()->GetUserEmail(1));
    229   tray()->CloseSystemBubble();
    230 }
    231 
    232 }  // namespace internal
    233 }  // namespace ash
    234