tray_user_unittest.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
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/ash_switches.h" 8#include "ash/root_window_controller.h" 9#include "ash/shelf/shelf_layout_manager.h" 10#include "ash/shell.h" 11#include "ash/shell_delegate.h" 12#include "ash/system/tray/system_tray.h" 13#include "ash/system/user/tray_user.h" 14#include "ash/test/ash_test_base.h" 15#include "ash/test/test_session_state_delegate.h" 16#include "ash/test/test_shell_delegate.h" 17#include "base/command_line.h" 18#include "ui/aura/test/event_generator.h" 19#include "ui/gfx/animation/animation_container_element.h" 20#include "ui/views/view.h" 21#include "ui/views/widget/widget.h" 22 23#if defined(OS_CHROMEOS) 24#include "ash/system/tray/system_tray_notifier.h" 25#endif 26 27namespace ash { 28namespace internal { 29 30class TrayUserTest : public ash::test::AshTestBase { 31 public: 32 TrayUserTest(); 33 34 // testing::Test: 35 virtual void SetUp() OVERRIDE; 36 37 // This has to be called prior to first use with the proper configuration. 38 void InitializeParameters(int users_logged_in, bool multiprofile); 39 40 // Show the system tray menu using the provided event generator. 41 void ShowTrayMenu(aura::test::EventGenerator* generator); 42 43 // Move the mouse over the user item. 44 void MoveOverUserItem(aura::test::EventGenerator* generator, int index); 45 46 // Click on the user item. Note that the tray menu needs to be shown. 47 void ClickUserItem(aura::test::EventGenerator* generator, int index); 48 49 // Accessors to various system components. 50 ShelfLayoutManager* shelf() { return shelf_; } 51 SystemTray* tray() { return tray_; } 52 ash::test::TestSessionStateDelegate* delegate() { return delegate_; } 53 ash::internal::TrayUser* tray_user(int index) { return tray_user_[index]; } 54 55 private: 56 ShelfLayoutManager* shelf_; 57 SystemTray* tray_; 58 ash::test::TestSessionStateDelegate* delegate_; 59 // Note that the ownership of these items is on the shelf. 60 std::vector<ash::internal::TrayUser*> tray_user_; 61 62 DISALLOW_COPY_AND_ASSIGN(TrayUserTest); 63}; 64 65TrayUserTest::TrayUserTest() 66 : shelf_(NULL), 67 tray_(NULL), 68 delegate_(NULL) { 69} 70 71void TrayUserTest::SetUp() { 72 ash::test::AshTestBase::SetUp(); 73 shelf_ = Shell::GetPrimaryRootWindowController()->GetShelfLayoutManager(); 74 tray_ = Shell::GetPrimaryRootWindowController()->GetSystemTray(); 75 delegate_ = static_cast<ash::test::TestSessionStateDelegate*>( 76 ash::Shell::GetInstance()->session_state_delegate()); 77} 78 79void TrayUserTest::InitializeParameters(int users_logged_in, 80 bool multiprofile) { 81 // Show the shelf. 82 shelf()->LayoutShelf(); 83 shelf()->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 84 85 // Set our default assumptions. Note that it is sufficient to set these 86 // after everything was created. 87 delegate_->set_logged_in_users(users_logged_in); 88 ash::test::TestShellDelegate* shell_delegate = 89 static_cast<ash::test::TestShellDelegate*>( 90 ash::Shell::GetInstance()->delegate()); 91 shell_delegate->set_multi_profiles_enabled(multiprofile); 92 93 // Instead of using the existing tray panels we create new ones which makes 94 // the access easier. 95 // Note that we create one more element then there can be users to show a 96 // separator. 97 for (int i = 0; i <= delegate_->GetMaximumNumberOfLoggedInUsers(); i++) { 98 tray_user_.push_back(new ash::internal::TrayUser(tray_, i)); 99 tray_->AddTrayItem(tray_user_[i]); 100 } 101} 102 103void TrayUserTest::ShowTrayMenu(aura::test::EventGenerator* generator) { 104 gfx::Point center = tray()->GetBoundsInScreen().CenterPoint(); 105 106 generator->MoveMouseTo(center.x(), center.y()); 107 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 108 generator->ClickLeftButton(); 109} 110 111void TrayUserTest::MoveOverUserItem(aura::test::EventGenerator* generator, 112 int index) { 113 gfx::Point center = 114 tray_user(index)->GetUserPanelBoundsInScreenForTest().CenterPoint(); 115 116 generator->MoveMouseTo(center.x(), center.y()); 117} 118 119void TrayUserTest::ClickUserItem(aura::test::EventGenerator* generator, 120 int index) { 121 MoveOverUserItem(generator, index); 122 generator->ClickLeftButton(); 123} 124 125// Make sure that in single user mode the user panel cannot be activated and no 126// separators are being created. 127TEST_F(TrayUserTest, SingleUserModeDoesNotAllowAddingUser) { 128 InitializeParameters(1, false); 129 130 // Move the mouse over the status area and click to open the status menu. 131 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 132 133 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 134 135 for (int i = 0; i <= delegate()->GetMaximumNumberOfLoggedInUsers(); i++) 136 EXPECT_EQ(ash::internal::TrayUser::HIDDEN, 137 tray_user(i)->GetStateForTest()); 138 139 ShowTrayMenu(&generator); 140 141 EXPECT_TRUE(tray()->HasSystemBubble()); 142 EXPECT_TRUE(tray()->IsAnyBubbleVisible()); 143 144 for (int i = 0; i <= delegate()->GetMaximumNumberOfLoggedInUsers(); i++) 145 EXPECT_EQ(i == 0 ? ash::internal::TrayUser::SHOWN : 146 ash::internal::TrayUser::HIDDEN, 147 tray_user(i)->GetStateForTest()); 148 149 tray()->CloseSystemBubble(); 150} 151 152#if defined(OS_CHROMEOS) 153// Make sure that in multi user mode the user panel can be activated and there 154// will be one panel for each user plus a separator. 155// Note: the mouse watcher (for automatic closing upon leave) cannot be tested 156// here since it does not work with the event system in unit tests. 157TEST_F(TrayUserTest, MutiUserModeDoesNotAllowToAddUser) { 158 InitializeParameters(1, true); 159 160 // Move the mouse over the status area and click to open the status menu. 161 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 162 generator.set_async(false); 163 164 int max_users = delegate()->GetMaximumNumberOfLoggedInUsers(); 165 // Checking now for each amount of users that the correct is done. 166 for (int j = 1; j < max_users; j++) { 167 // Set the number of logged in users. 168 delegate()->set_logged_in_users(j); 169 170 // Verify that nothing is shown. 171 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 172 for (int i = 0; i <= max_users; i++) 173 EXPECT_FALSE(tray_user(i)->GetStateForTest()); 174 175 // After clicking on the tray the menu should get shown and for each logged 176 // in user we should get a visible item. In addition, the separator should 177 // show up when we reach more then one user. 178 ShowTrayMenu(&generator); 179 180 EXPECT_TRUE(tray()->HasSystemBubble()); 181 EXPECT_TRUE(tray()->IsAnyBubbleVisible()); 182 for (int i = 0; i < max_users; i++) { 183 EXPECT_EQ(i < j ? ash::internal::TrayUser::SHOWN : 184 ash::internal::TrayUser::HIDDEN, 185 tray_user(i)->GetStateForTest()); 186 } 187 188 // Check the visibility of the separator. 189 EXPECT_EQ(j > 1 ? ash::internal::TrayUser::SEPARATOR : 190 ash::internal::TrayUser::HIDDEN, 191 tray_user(max_users)->GetStateForTest()); 192 193 // Move the mouse over the user item and it should hover. 194 MoveOverUserItem(&generator, 0); 195 EXPECT_EQ(ash::internal::TrayUser::HOVERED, 196 tray_user(0)->GetStateForTest()); 197 for (int i = 1; i < max_users; i++) { 198 EXPECT_EQ(i < j ? ash::internal::TrayUser::SHOWN : 199 ash::internal::TrayUser::HIDDEN, 200 tray_user(i)->GetStateForTest()); 201 } 202 203 // Check that clicking the button allows to add item if we have still room 204 // for one more user. 205 ClickUserItem(&generator, 0); 206 EXPECT_EQ(j == max_users ? 207 ash::internal::TrayUser::ACTIVE_BUT_DISABLED : 208 ash::internal::TrayUser::ACTIVE, 209 tray_user(0)->GetStateForTest()); 210 211 // Click the button again to see that the menu goes away. 212 ClickUserItem(&generator, 0); 213 EXPECT_EQ(ash::internal::TrayUser::HOVERED, 214 tray_user(0)->GetStateForTest()); 215 216 // Close and check that everything is deleted. 217 tray()->CloseSystemBubble(); 218 EXPECT_FALSE(tray()->IsAnyBubbleVisible()); 219 for (int i = 0; i < delegate()->GetMaximumNumberOfLoggedInUsers(); i++) 220 EXPECT_EQ(ash::internal::TrayUser::HIDDEN, 221 tray_user(i)->GetStateForTest()); 222 } 223} 224 225// Make sure that user changing gets properly executed. 226TEST_F(TrayUserTest, MutiUserModeButtonClicks) { 227 // Have two users. 228 InitializeParameters(2, true); 229 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 230 ShowTrayMenu(&generator); 231 232 // Switch to a new user. 233 ClickUserItem(&generator, 1); 234 235 EXPECT_EQ(delegate()->get_activated_user(), delegate()->GetUserEmail(1)); 236 tray()->CloseSystemBubble(); 237} 238 239// Make sure that we show items for all users in the tray accordingly. 240TEST_F(TrayUserTest, CheckTrayUserItems) { 241 InitializeParameters(1, true); 242 243 int max_users = delegate()->GetMaximumNumberOfLoggedInUsers(); 244 // Checking now for each amount of users that the proper items are visible in 245 // the tray. The proper item is hereby: 246 // 3 -> User #1 247 // 2 -> User #2 248 // 1 -> User #3 249 // 0 -> Separator (never shown) 250 // Note: Tray items are required to populate system tray items as well as the 251 // system tray menu. The system tray menu changes it's appearance with the 252 // addition of more users, but the system tray does not create new items after 253 // it got created. The logic to know if an item is present, not present or 254 // even "only" a "separator" is inside the tray user items. This test tries 255 // to test as close as possible the "real thing" and as such the break is 256 // included. 257 for (int j = 1; j <= max_users; j++) { 258 // We simulate the user addition by telling the delegate the new number of 259 // users, then change all user tray items and finally tell the tray to 260 // re-layout itself. 261 delegate()->set_logged_in_users(j); 262 Shell::GetInstance()->system_tray_notifier()->NotifyUserAddedToSession(); 263 tray()->Layout(); 264 265 // Check that the tray items are being shown in the reverse order. 266 for (int i = 0; i <= max_users; i++) { 267 gfx::Rect rect = tray()-> 268 GetTrayItemViewForTest(tray_user(i))->GetBoundsInScreen(); 269 if (max_users - i < j) 270 EXPECT_FALSE(rect.IsEmpty()); 271 else 272 EXPECT_TRUE(rect.IsEmpty()); 273 } 274 } 275 276 // Click on the last item to see that the user changes. 277 aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow()); 278 generator.set_async(false); 279 280 // Switch to a new user - again, note that we have to click on the reverse 281 // item in the list (1 -> user 3). 282 gfx::Point point = 283 tray()->GetTrayItemViewForTest(tray_user(1))-> 284 GetBoundsInScreen().CenterPoint(); 285 286 generator.MoveMouseTo(point.x(), point.y()); 287 generator.ClickLeftButton(); 288 EXPECT_EQ(delegate()->get_activated_user(), delegate()->GetUserEmail(2)); 289} 290 291#endif 292 293} // namespace internal 294} // namespace ash 295