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