• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 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#import "ui/message_center/cocoa/tray_view_controller.h"
6
7#include "base/mac/scoped_nsobject.h"
8#include "base/message_loop/message_loop.h"
9#include "base/run_loop.h"
10#include "base/strings/utf_string_conversions.h"
11#import "ui/gfx/test/ui_cocoa_test_helper.h"
12#include "ui/message_center/fake_notifier_settings_provider.h"
13#include "ui/message_center/message_center.h"
14#include "ui/message_center/message_center_impl.h"
15#include "ui/message_center/message_center_style.h"
16#include "ui/message_center/notification.h"
17#include "ui/message_center/notifier_settings.h"
18
19using base::ASCIIToUTF16;
20
21namespace message_center {
22
23class TrayViewControllerTest : public ui::CocoaTest {
24 public:
25  TrayViewControllerTest()
26    : center_(NULL) {
27  }
28
29  virtual void SetUp() OVERRIDE {
30    ui::CocoaTest::SetUp();
31    message_center::MessageCenter::Initialize();
32    center_ = message_center::MessageCenter::Get();
33    center_->DisableTimersForTest();
34    tray_.reset([[MCTrayViewController alloc] initWithMessageCenter:center_]);
35    [tray_ setAnimationDuration:0.002];
36    [tray_ setAnimateClearingNextNotificationDelay:0.001];
37    [tray_ setAnimationEndedCallback:^{
38        if (nested_run_loop_.get())
39          nested_run_loop_->Quit();
40    }];
41    [tray_ view];  // Create the view.
42  }
43
44  virtual void TearDown() OVERRIDE {
45    tray_.reset();
46    message_center::MessageCenter::Shutdown();
47    ui::CocoaTest::TearDown();
48  }
49
50  void WaitForAnimationEnded() {
51    if (![tray_ isAnimating])
52      return;
53    nested_run_loop_.reset(new base::RunLoop());
54    nested_run_loop_->Run();
55    nested_run_loop_.reset();
56  }
57
58 protected:
59  message_center::NotifierId DummyNotifierId() {
60    return message_center::NotifierId();
61  }
62
63  message_center::MessageCenter* center_;  // Weak, global.
64
65  base::MessageLoopForUI message_loop_;
66  scoped_ptr<base::RunLoop> nested_run_loop_;
67  base::scoped_nsobject<MCTrayViewController> tray_;
68};
69
70TEST_F(TrayViewControllerTest, AddRemoveOne) {
71  NSScrollView* view = [[tray_ scrollView] documentView];
72  EXPECT_EQ(0u, [[view subviews] count]);
73  scoped_ptr<message_center::Notification> notification_data;
74  notification_data.reset(new message_center::Notification(
75      message_center::NOTIFICATION_TYPE_SIMPLE,
76      "1",
77      ASCIIToUTF16("First notification"),
78      ASCIIToUTF16("This is a simple test."),
79      gfx::Image(),
80      base::string16(),
81      DummyNotifierId(),
82      message_center::RichNotificationData(),
83      NULL));
84  center_->AddNotification(notification_data.Pass());
85  [tray_ onMessageCenterTrayChanged];
86  ASSERT_EQ(1u, [[view subviews] count]);
87
88  // The view should have padding around it.
89  NSView* notification = [[view subviews] objectAtIndex:0];
90  NSRect notification_frame = [notification frame];
91  EXPECT_CGFLOAT_EQ(2 * message_center::kMarginBetweenItems,
92                    NSHeight([view frame]) - NSHeight(notification_frame));
93  EXPECT_CGFLOAT_EQ(2 * message_center::kMarginBetweenItems,
94                    NSWidth([view frame]) - NSWidth(notification_frame));
95  EXPECT_GT(NSHeight([[tray_ view] frame]),
96            NSHeight([[tray_ scrollView] frame]));
97
98  center_->RemoveNotification("1", true);
99  [tray_ onMessageCenterTrayChanged];
100  EXPECT_EQ(0u, [[view subviews] count]);
101  // The empty tray is now 100px tall to accommodate
102  // the empty message.
103  EXPECT_CGFLOAT_EQ(message_center::kMinScrollViewHeight,
104                    NSHeight([view frame]));
105}
106
107TEST_F(TrayViewControllerTest, AddThreeClearAll) {
108  NSScrollView* view = [[tray_ scrollView] documentView];
109  EXPECT_EQ(0u, [[view subviews] count]);
110  scoped_ptr<message_center::Notification> notification;
111  notification.reset(new message_center::Notification(
112      message_center::NOTIFICATION_TYPE_SIMPLE,
113      "1",
114      ASCIIToUTF16("First notification"),
115      ASCIIToUTF16("This is a simple test."),
116      gfx::Image(),
117      base::string16(),
118      DummyNotifierId(),
119      message_center::RichNotificationData(),
120      NULL));
121  center_->AddNotification(notification.Pass());
122  notification.reset(new message_center::Notification(
123      message_center::NOTIFICATION_TYPE_SIMPLE,
124      "2",
125      ASCIIToUTF16("Second notification"),
126      ASCIIToUTF16("This is a simple test."),
127      gfx::Image(),
128      base::string16(),
129      DummyNotifierId(),
130      message_center::RichNotificationData(),
131      NULL));
132  center_->AddNotification(notification.Pass());
133  notification.reset(new message_center::Notification(
134      message_center::NOTIFICATION_TYPE_SIMPLE,
135      "3",
136      ASCIIToUTF16("Third notification"),
137      ASCIIToUTF16("This is a simple test."),
138      gfx::Image(),
139      base::string16(),
140      DummyNotifierId(),
141      message_center::RichNotificationData(),
142      NULL));
143  center_->AddNotification(notification.Pass());
144  [tray_ onMessageCenterTrayChanged];
145  ASSERT_EQ(3u, [[view subviews] count]);
146
147  [tray_ clearAllNotifications:nil];
148  WaitForAnimationEnded();
149  [tray_ onMessageCenterTrayChanged];
150
151  EXPECT_EQ(0u, [[view subviews] count]);
152  // The empty tray is now 100px tall to accommodate
153  // the empty message.
154  EXPECT_CGFLOAT_EQ(message_center::kMinScrollViewHeight,
155                    NSHeight([view frame]));
156}
157
158TEST_F(TrayViewControllerTest, NoClearAllWhenNoNotifications) {
159  EXPECT_TRUE([tray_ pauseButton]);
160  EXPECT_TRUE([tray_ clearAllButton]);
161
162  // With no notifications, the clear all button should be hidden.
163  EXPECT_TRUE([[tray_ clearAllButton] isHidden]);
164  EXPECT_LT(NSMinX([[tray_ clearAllButton] frame]),
165            NSMinX([[tray_ pauseButton] frame]));
166
167  // Add a notification.
168  scoped_ptr<message_center::Notification> notification;
169  notification.reset(new message_center::Notification(
170      message_center::NOTIFICATION_TYPE_SIMPLE,
171      "1",
172      ASCIIToUTF16("First notification"),
173      ASCIIToUTF16("This is a simple test."),
174      gfx::Image(),
175      base::string16(),
176      DummyNotifierId(),
177      message_center::RichNotificationData(),
178      NULL));
179  center_->AddNotification(notification.Pass());
180  [tray_ onMessageCenterTrayChanged];
181
182  // Clear all should now be visible.
183  EXPECT_FALSE([[tray_ clearAllButton] isHidden]);
184  EXPECT_GT(NSMinX([[tray_ clearAllButton] frame]),
185            NSMinX([[tray_ pauseButton] frame]));
186
187  // Adding a second notification should keep things still visible.
188  notification.reset(new message_center::Notification(
189      message_center::NOTIFICATION_TYPE_SIMPLE,
190      "2",
191      ASCIIToUTF16("Second notification"),
192      ASCIIToUTF16("This is a simple test."),
193      gfx::Image(),
194      base::string16(),
195      DummyNotifierId(),
196      message_center::RichNotificationData(),
197      NULL));
198  center_->AddNotification(notification.Pass());
199  [tray_ onMessageCenterTrayChanged];
200  EXPECT_FALSE([[tray_ clearAllButton] isHidden]);
201  EXPECT_GT(NSMinX([[tray_ clearAllButton] frame]),
202            NSMinX([[tray_ pauseButton] frame]));
203
204  // Clear all notifications.
205  [tray_ clearAllNotifications:nil];
206  WaitForAnimationEnded();
207  [tray_ onMessageCenterTrayChanged];
208
209  // The button should be hidden again.
210  EXPECT_TRUE([[tray_ clearAllButton] isHidden]);
211  EXPECT_LT(NSMinX([[tray_ clearAllButton] frame]),
212            NSMinX([[tray_ pauseButton] frame]));
213}
214
215namespace {
216
217Notifier* NewNotifier(const std::string& id,
218                      const std::string& title,
219                      bool enabled) {
220  NotifierId notifier_id(NotifierId::APPLICATION, id);
221  return new Notifier(notifier_id, base::UTF8ToUTF16(title), enabled);
222}
223
224}  // namespace
225
226
227TEST_F(TrayViewControllerTest, Settings) {
228  std::vector<Notifier*> notifiers;
229  notifiers.push_back(NewNotifier("id", "title", /*enabled=*/true));
230  notifiers.push_back(NewNotifier("id2", "other title", /*enabled=*/false));
231
232  FakeNotifierSettingsProvider provider(notifiers);
233  center_->SetNotifierSettingsProvider(&provider);
234
235  CGFloat trayHeight = NSHeight([[tray_ view] frame]);
236  EXPECT_EQ(0, provider.closed_called_count());
237
238  [tray_ showSettings:nil];
239  EXPECT_FALSE(center_->IsMessageCenterVisible());
240
241  // There are 0 notifications, but 2 notifiers. The settings pane should be
242  // higher than the empty tray bubble.
243  EXPECT_LT(trayHeight, NSHeight([[tray_ view] frame]));
244
245  [tray_ showMessages:nil];
246  EXPECT_EQ(1, provider.closed_called_count());
247  EXPECT_TRUE(center_->IsMessageCenterVisible());
248
249  // The tray should be back at its previous height now.
250  EXPECT_EQ(trayHeight, NSHeight([[tray_ view] frame]));
251
252  // Clean up since this frame owns FakeNotifierSettingsProvider.
253  center_->SetNotifierSettingsProvider(NULL);
254}
255
256TEST_F(TrayViewControllerTest, EmptyCenter) {
257  EXPECT_FALSE([[tray_ emptyDescription] isHidden]);
258
259  // With no notifications, the divider should be hidden.
260  EXPECT_TRUE([[tray_ divider] isHidden]);
261  EXPECT_TRUE([[tray_ scrollView] isHidden]);
262
263  scoped_ptr<message_center::Notification> notification;
264  notification.reset(new message_center::Notification(
265      message_center::NOTIFICATION_TYPE_SIMPLE,
266      "1",
267      ASCIIToUTF16("First notification"),
268      ASCIIToUTF16("This is a simple test."),
269      gfx::Image(),
270      base::string16(),
271      DummyNotifierId(),
272      message_center::RichNotificationData(),
273      NULL));
274  center_->AddNotification(notification.Pass());
275  [tray_ onMessageCenterTrayChanged];
276
277  EXPECT_FALSE([[tray_ divider] isHidden]);
278  EXPECT_FALSE([[tray_ scrollView] isHidden]);
279  EXPECT_TRUE([[tray_ emptyDescription] isHidden]);
280}
281
282}  // namespace message_center
283