- add sources.
[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/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
27 namespace ash {
28 namespace internal {
29
30 class 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
65 TrayUserTest::TrayUserTest()
66     : shelf_(NULL),
67       tray_(NULL),
68       delegate_(NULL) {
69 }
70
71 void 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
79 void 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
103 void 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
111 void 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
119 void 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.
127 TEST_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.
157 TEST_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.
226 TEST_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 - which has a capitalized name.
233   ClickUserItem(&generator, 1);
234   EXPECT_EQ(delegate()->get_activated_user(), delegate()->GetUserID(1));
235   // Since the name is capitalized, the email should be different then the
236   // user_id.
237   EXPECT_NE(delegate()->get_activated_user(), delegate()->GetUserEmail(1));
238   tray()->CloseSystemBubble();
239 }
240
241 // Make sure that we show items for all users in the tray accordingly.
242 TEST_F(TrayUserTest, CheckTrayUserItems) {
243   InitializeParameters(1, true);
244
245   int max_users = delegate()->GetMaximumNumberOfLoggedInUsers();
246   // Checking now for each amount of users that the proper items are visible in
247   // the tray. The proper item is hereby:
248   // 3 -> User #1
249   // 2 -> User #2
250   // 1 -> User #3
251   // 0 -> Separator (never shown)
252   // Note: Tray items are required to populate system tray items as well as the
253   // system tray menu. The system tray menu changes it's appearance with the
254   // addition of more users, but the system tray does not create new items after
255   // it got created. The logic to know if an item is present, not present or
256   // even "only" a "separator" is inside the tray user items. This test tries
257   // to test as close as possible the "real thing" and as such the break is
258   // included.
259   for (int j = 1; j <= max_users; j++) {
260     // We simulate the user addition by telling the delegate the new number of
261     // users, then change all user tray items and finally tell the tray to
262     // re-layout itself.
263     delegate()->set_logged_in_users(j);
264     Shell::GetInstance()->system_tray_notifier()->NotifyUserAddedToSession();
265     tray()->Layout();
266
267     // Check that the tray items are being shown in the reverse order.
268     for (int i = 0; i <= max_users; i++) {
269       gfx::Rect rect = tray()->
270           GetTrayItemViewForTest(tray_user(i))->GetBoundsInScreen();
271       if (max_users - i < j)
272         EXPECT_FALSE(rect.IsEmpty());
273       else
274         EXPECT_TRUE(rect.IsEmpty());
275     }
276   }
277
278   // Click on the last item to see that the user changes.
279   aura::test::EventGenerator generator(Shell::GetPrimaryRootWindow());
280   generator.set_async(false);
281
282   // Switch to a new user - again, note that we have to click on the reverse
283   // item in the list (1 -> user 3).
284   gfx::Point point =
285       tray()->GetTrayItemViewForTest(tray_user(1))->
286                          GetBoundsInScreen().CenterPoint();
287
288   generator.MoveMouseTo(point.x(), point.y());
289   generator.ClickLeftButton();
290   EXPECT_EQ(delegate()->get_activated_user(), delegate()->GetUserID(2));
291 }
292
293 #endif
294
295 }  // namespace internal
296 }  // namespace ash