Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / ash / system / tray / system_tray_unittest.cc
blob8ec6c9ee27fb059f0e5f8ffac223349d7c03638f
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.
5 #include "ash/system/tray/system_tray.h"
7 #include <vector>
9 #include "ash/root_window_controller.h"
10 #include "ash/shelf/shelf_widget.h"
11 #include "ash/system/status_area_widget.h"
12 #include "ash/system/tray/system_tray_item.h"
13 #include "ash/test/ash_test_base.h"
14 #include "base/utf_string_conversions.h"
15 #include "ui/views/controls/label.h"
16 #include "ui/views/layout/fill_layout.h"
17 #include "ui/views/view.h"
18 #include "ui/views/widget/widget.h"
20 #if defined(OS_WIN)
21 #include "base/win/windows_version.h"
22 #endif
24 namespace ash {
25 namespace test {
27 namespace {
29 SystemTray* GetSystemTray() {
30 return Shell::GetPrimaryRootWindowController()->shelf()->
31 status_area_widget()->system_tray();
34 // Trivial item implementation that tracks its views for testing.
35 class TestItem : public SystemTrayItem {
36 public:
37 TestItem() : SystemTrayItem(GetSystemTray()), tray_view_(NULL) {}
39 virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE {
40 tray_view_ = new views::View;
41 // Add a label so it has non-zero width.
42 tray_view_->SetLayoutManager(new views::FillLayout);
43 tray_view_->AddChildView(new views::Label(UTF8ToUTF16("Tray")));
44 return tray_view_;
47 virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE {
48 default_view_ = new views::View;
49 default_view_->SetLayoutManager(new views::FillLayout);
50 default_view_->AddChildView(new views::Label(UTF8ToUTF16("Default")));
51 return default_view_;
54 virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE {
55 detailed_view_ = new views::View;
56 detailed_view_->SetLayoutManager(new views::FillLayout);
57 detailed_view_->AddChildView(new views::Label(UTF8ToUTF16("Detailed")));
58 return detailed_view_;
61 virtual views::View* CreateNotificationView(
62 user::LoginStatus status) OVERRIDE {
63 notification_view_ = new views::View;
64 return notification_view_;
67 virtual void DestroyTrayView() OVERRIDE {
68 tray_view_ = NULL;
71 virtual void DestroyDefaultView() OVERRIDE {
72 default_view_ = NULL;
75 virtual void DestroyDetailedView() OVERRIDE {
76 detailed_view_ = NULL;
79 virtual void DestroyNotificationView() OVERRIDE {
80 notification_view_ = NULL;
83 virtual void UpdateAfterLoginStatusChange(
84 user::LoginStatus status) OVERRIDE {
87 views::View* tray_view() const { return tray_view_; }
88 views::View* default_view() const { return default_view_; }
89 views::View* detailed_view() const { return detailed_view_; }
90 views::View* notification_view() const { return notification_view_; }
92 private:
93 views::View* tray_view_;
94 views::View* default_view_;
95 views::View* detailed_view_;
96 views::View* notification_view_;
99 // Trivial item implementation that returns NULL from tray/default/detailed
100 // view creation methods.
101 class TestNoViewItem : public SystemTrayItem {
102 public:
103 TestNoViewItem() : SystemTrayItem(GetSystemTray()) {}
105 virtual views::View* CreateTrayView(user::LoginStatus status) OVERRIDE {
106 return NULL;
109 virtual views::View* CreateDefaultView(user::LoginStatus status) OVERRIDE {
110 return NULL;
113 virtual views::View* CreateDetailedView(user::LoginStatus status) OVERRIDE {
114 return NULL;
117 virtual views::View* CreateNotificationView(
118 user::LoginStatus status) OVERRIDE {
119 return NULL;
122 virtual void DestroyTrayView() OVERRIDE {}
123 virtual void DestroyDefaultView() OVERRIDE {}
124 virtual void DestroyDetailedView() OVERRIDE {}
125 virtual void DestroyNotificationView() OVERRIDE {}
126 virtual void UpdateAfterLoginStatusChange(
127 user::LoginStatus status) OVERRIDE {
131 } // namespace
133 typedef AshTestBase SystemTrayTest;
135 TEST_F(SystemTrayTest, SystemTrayDefaultView) {
136 SystemTray* tray = GetSystemTray();
137 ASSERT_TRUE(tray->GetWidget());
139 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
141 // Ensure that closing the bubble destroys it.
142 ASSERT_TRUE(tray->CloseSystemBubbleForTest());
143 RunAllPendingInMessageLoop();
144 ASSERT_FALSE(tray->CloseSystemBubbleForTest());
147 TEST_F(SystemTrayTest, SystemTrayTestItems) {
148 SystemTray* tray = GetSystemTray();
149 ASSERT_TRUE(tray->GetWidget());
151 TestItem* test_item = new TestItem;
152 TestItem* detailed_item = new TestItem;
153 tray->AddTrayItem(test_item);
154 tray->AddTrayItem(detailed_item);
156 // Ensure the tray views are created.
157 ASSERT_TRUE(test_item->tray_view() != NULL);
158 ASSERT_TRUE(detailed_item->tray_view() != NULL);
160 // Ensure a default views are created.
161 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
162 ASSERT_TRUE(test_item->default_view() != NULL);
163 ASSERT_TRUE(detailed_item->default_view() != NULL);
165 // Show the detailed view, ensure it's created and the default view destroyed.
166 tray->ShowDetailedView(detailed_item, 0, false, BUBBLE_CREATE_NEW);
167 RunAllPendingInMessageLoop();
168 ASSERT_TRUE(test_item->default_view() == NULL);
169 ASSERT_TRUE(detailed_item->detailed_view() != NULL);
171 // Show the default view, ensure it's created and the detailed view destroyed.
172 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
173 RunAllPendingInMessageLoop();
174 ASSERT_TRUE(test_item->default_view() != NULL);
175 ASSERT_TRUE(detailed_item->detailed_view() == NULL);
178 TEST_F(SystemTrayTest, SystemTrayNoViewItems) {
179 SystemTray* tray = GetSystemTray();
180 ASSERT_TRUE(tray->GetWidget());
182 // Verify that no crashes occur on items lacking some views.
183 TestNoViewItem* no_view_item = new TestNoViewItem;
184 tray->AddTrayItem(no_view_item);
185 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
186 tray->ShowDetailedView(no_view_item, 0, false, BUBBLE_USE_EXISTING);
187 RunAllPendingInMessageLoop();
190 TEST_F(SystemTrayTest, TrayWidgetAutoResizes) {
191 SystemTray* tray = GetSystemTray();
192 ASSERT_TRUE(tray->GetWidget());
194 // Add an initial tray item so that the tray gets laid out correctly.
195 TestItem* initial_item = new TestItem;
196 tray->AddTrayItem(initial_item);
198 gfx::Size initial_size = tray->GetWidget()->GetWindowBoundsInScreen().size();
200 TestItem* new_item = new TestItem;
201 tray->AddTrayItem(new_item);
203 gfx::Size new_size = tray->GetWidget()->GetWindowBoundsInScreen().size();
205 // Adding the new item should change the size of the tray.
206 EXPECT_NE(initial_size.ToString(), new_size.ToString());
208 // Hiding the tray view of the new item should also change the size of the
209 // tray.
210 new_item->tray_view()->SetVisible(false);
211 EXPECT_EQ(initial_size.ToString(),
212 tray->GetWidget()->GetWindowBoundsInScreen().size().ToString());
214 new_item->tray_view()->SetVisible(true);
215 EXPECT_EQ(new_size.ToString(),
216 tray->GetWidget()->GetWindowBoundsInScreen().size().ToString());
219 TEST_F(SystemTrayTest, SystemTrayNotifications) {
220 SystemTray* tray = GetSystemTray();
221 ASSERT_TRUE(tray->GetWidget());
223 TestItem* test_item = new TestItem;
224 TestItem* detailed_item = new TestItem;
225 tray->AddTrayItem(test_item);
226 tray->AddTrayItem(detailed_item);
228 // Ensure the tray views are created.
229 ASSERT_TRUE(test_item->tray_view() != NULL);
230 ASSERT_TRUE(detailed_item->tray_view() != NULL);
232 // Ensure a notification view is created.
233 tray->ShowNotificationView(test_item);
234 ASSERT_TRUE(test_item->notification_view() != NULL);
236 // Show the default view, notification view should remain.
237 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
238 RunAllPendingInMessageLoop();
239 ASSERT_TRUE(test_item->notification_view() != NULL);
241 // Show the detailed view, ensure the notificaiton view remains.
242 tray->ShowDetailedView(detailed_item, 0, false, BUBBLE_CREATE_NEW);
243 RunAllPendingInMessageLoop();
244 ASSERT_TRUE(detailed_item->detailed_view() != NULL);
245 ASSERT_TRUE(test_item->notification_view() != NULL);
247 // Hide the detailed view, ensure the notificaiton view still exists.
248 ASSERT_TRUE(tray->CloseSystemBubbleForTest());
249 RunAllPendingInMessageLoop();
250 ASSERT_TRUE(detailed_item->detailed_view() == NULL);
251 ASSERT_TRUE(test_item->notification_view() != NULL);
254 TEST_F(SystemTrayTest, BubbleCreationTypesTest) {
255 SystemTray* tray = GetSystemTray();
256 ASSERT_TRUE(tray->GetWidget());
258 TestItem* test_item = new TestItem;
259 tray->AddTrayItem(test_item);
261 // Ensure the tray views are created.
262 ASSERT_TRUE(test_item->tray_view() != NULL);
264 // Show the default view, ensure the notification view is destroyed.
265 tray->ShowDefaultView(BUBBLE_CREATE_NEW);
266 RunAllPendingInMessageLoop();
268 views::Widget* widget = test_item->default_view()->GetWidget();
269 gfx::Rect bubble_bounds = widget->GetWindowBoundsInScreen();
271 tray->ShowDetailedView(test_item, 0, true, BUBBLE_USE_EXISTING);
272 RunAllPendingInMessageLoop();
274 EXPECT_FALSE(test_item->default_view());
276 EXPECT_EQ(bubble_bounds.ToString(), test_item->detailed_view()->GetWidget()->
277 GetWindowBoundsInScreen().ToString());
278 EXPECT_EQ(widget, test_item->detailed_view()->GetWidget());
280 tray->ShowDefaultView(BUBBLE_USE_EXISTING);
281 RunAllPendingInMessageLoop();
283 EXPECT_EQ(bubble_bounds.ToString(), test_item->default_view()->GetWidget()->
284 GetWindowBoundsInScreen().ToString());
285 EXPECT_EQ(widget, test_item->default_view()->GetWidget());
288 // Tests that the tray is laid out properly in the widget to make sure that the
289 // tray extends to the correct edge of the screen.
290 TEST_F(SystemTrayTest, TrayBoundsInWidget) {
291 internal::StatusAreaWidget* widget =
292 Shell::GetPrimaryRootWindowController()->shelf()->status_area_widget();
293 SystemTray* tray = widget->system_tray();
295 // Test in bottom alignment. Bottom and right edges of the view should be
296 // aligned with the widget.
297 widget->SetShelfAlignment(SHELF_ALIGNMENT_BOTTOM);
298 gfx::Rect window_bounds = widget->GetWindowBoundsInScreen();
299 gfx::Rect tray_bounds = tray->GetBoundsInScreen();
300 EXPECT_EQ(window_bounds.bottom(), tray_bounds.bottom());
301 EXPECT_EQ(window_bounds.right(), tray_bounds.right());
303 // Test in the top alignment. Top and right edges should match.
304 widget->SetShelfAlignment(SHELF_ALIGNMENT_TOP);
305 window_bounds = widget->GetWindowBoundsInScreen();
306 tray_bounds = tray->GetBoundsInScreen();
307 EXPECT_EQ(window_bounds.y(), tray_bounds.y());
308 EXPECT_EQ(window_bounds.right(), tray_bounds.right());
310 // Test in the left alignment. Left and bottom edges should match.
311 widget->SetShelfAlignment(SHELF_ALIGNMENT_LEFT);
312 window_bounds = widget->GetWindowBoundsInScreen();
313 tray_bounds = tray->GetBoundsInScreen();
314 EXPECT_EQ(window_bounds.bottom(), tray_bounds.bottom());
315 EXPECT_EQ(window_bounds.x(), tray_bounds.x());
317 // Test in the right alignment. Right and bottom edges should match.
318 widget->SetShelfAlignment(SHELF_ALIGNMENT_LEFT);
319 window_bounds = widget->GetWindowBoundsInScreen();
320 tray_bounds = tray->GetBoundsInScreen();
321 EXPECT_EQ(window_bounds.bottom(), tray_bounds.bottom());
322 EXPECT_EQ(window_bounds.right(), tray_bounds.right());
325 } // namespace test
326 } // namespace ash