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.
5 #import "ui/message_center/cocoa/notification_controller.h"
7 #include "base/mac/foundation_util.h"
8 #include "base/mac/scoped_nsobject.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #import "ui/base/cocoa/hover_image_button.h"
13 #import "ui/base/test/ui_cocoa_test_helper.h"
14 #include "ui/message_center/fake_message_center.h"
15 #include "ui/message_center/message_center_style.h"
16 #include "ui/message_center/notification.h"
17 #include "ui/message_center/notification_types.h"
19 using base::ASCIIToUTF16;
20 using base::UTF8ToUTF16;
24 class MockMessageCenter : public message_center::FakeMessageCenter {
27 : last_removed_by_user_(false),
29 last_clicked_index_(-1) {}
31 virtual void RemoveNotification(const std::string& id,
32 bool by_user) OVERRIDE {
33 last_removed_id_ = id;
34 last_removed_by_user_ = by_user;
38 virtual void ClickOnNotificationButton(const std::string& id,
39 int button_index) OVERRIDE {
40 last_clicked_id_ = id;
41 last_clicked_index_ = button_index;
44 const std::string& last_removed_id() const { return last_removed_id_; }
45 bool last_removed_by_user() const { return last_removed_by_user_; }
46 int remove_count() const { return remove_count_; }
47 const std::string& last_clicked_id() const { return last_clicked_id_; }
48 int last_clicked_index() const { return last_clicked_index_; }
51 std::string last_removed_id_;
52 bool last_removed_by_user_;
55 std::string last_clicked_id_;
56 int last_clicked_index_;
58 DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
63 @implementation MCNotificationController (TestingInterface)
64 - (NSButton*)closeButton {
65 return closeButton_.get();
68 - (NSButton*)secondButton {
69 // The buttons are in Cocoa-y-order, so the 2nd button is first.
70 NSView* view = [[bottomView_ subviews] objectAtIndex:0];
71 return base::mac::ObjCCastStrict<NSButton>(view);
74 - (NSArray*)bottomSubviews {
75 return [bottomView_ subviews];
78 - (NSImageView*)iconView {
82 - (NSTextView*)titleView {
86 - (NSTextView*)messageView {
87 return message_.get();
90 - (NSTextView*)contextMessageView {
91 return contextMessage_.get();
95 return listView_.get();
99 namespace message_center {
101 class NotificationControllerTest : public ui::CocoaTest {
103 NSImage* TestIcon() {
104 return [NSImage imageNamed:NSImageNameUser];
108 message_center::NotifierId DummyNotifierId() {
109 return message_center::NotifierId();
113 TEST_F(NotificationControllerTest, BasicLayout) {
114 scoped_ptr<message_center::Notification> notification(
115 new message_center::Notification(
116 message_center::NOTIFICATION_TYPE_SIMPLE,
118 ASCIIToUTF16("Added to circles"),
119 ASCIIToUTF16("Jonathan and 5 others"),
123 message_center::RichNotificationData(),
125 notification->set_icon(gfx::Image([TestIcon() retain]));
127 base::scoped_nsobject<MCNotificationController> controller(
128 [[MCNotificationController alloc] initWithNotification:notification.get()
129 messageCenter:NULL]);
132 EXPECT_EQ(TestIcon(), [[controller iconView] image]);
133 EXPECT_EQ(base::SysNSStringToUTF16([[controller titleView] string]),
134 notification->title());
135 EXPECT_EQ(base::SysNSStringToUTF16([[controller messageView] string]),
136 notification->message());
137 EXPECT_EQ(controller.get(), [[controller closeButton] target]);
140 TEST_F(NotificationControllerTest, OverflowText) {
141 scoped_ptr<message_center::Notification> notification(
142 new message_center::Notification(
143 message_center::NOTIFICATION_TYPE_SIMPLE,
145 ASCIIToUTF16("This is a much longer title that should wrap "
147 ASCIIToUTF16("And even the message is long. This sure is a wordy "
148 "notification. Are you really going to read this "
153 message_center::RichNotificationData(),
155 base::scoped_nsobject<MCNotificationController> controller(
156 [[MCNotificationController alloc] initWithNotification:notification.get()
157 messageCenter:NULL]);
160 EXPECT_GT(NSHeight([[controller view] frame]),
161 message_center::kNotificationIconSize);
164 TEST_F(NotificationControllerTest, Close) {
165 scoped_ptr<message_center::Notification> notification(
166 new message_center::Notification(
167 message_center::NOTIFICATION_TYPE_SIMPLE,
174 message_center::RichNotificationData(),
176 MockMessageCenter message_center;
178 base::scoped_nsobject<MCNotificationController> controller(
179 [[MCNotificationController alloc] initWithNotification:notification.get()
180 messageCenter:&message_center]);
183 [[controller closeButton] performClick:nil];
185 EXPECT_EQ(1, message_center.remove_count());
186 EXPECT_EQ("an_id", message_center.last_removed_id());
187 EXPECT_TRUE(message_center.last_removed_by_user());
190 TEST_F(NotificationControllerTest, Update) {
191 scoped_ptr<message_center::Notification> notification(
192 new message_center::Notification(
193 message_center::NOTIFICATION_TYPE_SIMPLE,
195 ASCIIToUTF16("A simple title"),
196 ASCIIToUTF16("This message isn't too long and should fit in the"
201 message_center::RichNotificationData(),
203 base::scoped_nsobject<MCNotificationController> controller(
204 [[MCNotificationController alloc] initWithNotification:notification.get()
205 messageCenter:NULL]);
207 // Set up the default layout.
209 EXPECT_EQ(NSHeight([[controller view] frame]),
210 message_center::kNotificationIconSize);
211 EXPECT_FALSE([[controller iconView] image]);
214 notification->set_icon(gfx::Image([TestIcon() retain]));
215 [controller updateNotification:notification.get()];
216 EXPECT_EQ(TestIcon(), [[controller iconView] image]);
217 EXPECT_EQ(NSHeight([[controller view] frame]),
218 message_center::kNotificationIconSize);
221 TEST_F(NotificationControllerTest, Buttons) {
222 message_center::RichNotificationData optional;
223 message_center::ButtonInfo button1(UTF8ToUTF16("button1"));
224 optional.buttons.push_back(button1);
225 message_center::ButtonInfo button2(UTF8ToUTF16("button2"));
226 optional.buttons.push_back(button2);
228 scoped_ptr<message_center::Notification> notification(
229 new message_center::Notification(
230 message_center::NOTIFICATION_TYPE_BASE_FORMAT,
239 MockMessageCenter message_center;
241 base::scoped_nsobject<MCNotificationController> controller(
242 [[MCNotificationController alloc] initWithNotification:notification.get()
243 messageCenter:&message_center]);
246 [[controller secondButton] performClick:nil];
248 EXPECT_EQ("an_id", message_center.last_clicked_id());
249 EXPECT_EQ(1, message_center.last_clicked_index());
252 TEST_F(NotificationControllerTest, Image) {
253 scoped_ptr<message_center::Notification> notification(
254 new message_center::Notification(
255 message_center::NOTIFICATION_TYPE_BASE_FORMAT,
262 message_center::RichNotificationData(),
264 NSImage* image = [NSImage imageNamed:NSImageNameFolder];
265 notification->set_image(gfx::Image([image retain]));
267 MockMessageCenter message_center;
269 base::scoped_nsobject<MCNotificationController> controller(
270 [[MCNotificationController alloc] initWithNotification:notification.get()
271 messageCenter:&message_center]);
274 ASSERT_EQ(1u, [[controller bottomSubviews] count]);
275 ASSERT_TRUE([[[[controller bottomSubviews] lastObject] contentView]
276 isKindOfClass:[NSImageView class]]);
278 [[[[controller bottomSubviews] lastObject] contentView] image]);
281 TEST_F(NotificationControllerTest, List) {
282 message_center::RichNotificationData optional;
283 message_center::NotificationItem item1(
284 UTF8ToUTF16("First title"), UTF8ToUTF16("first message"));
285 optional.items.push_back(item1);
286 message_center::NotificationItem item2(
287 UTF8ToUTF16("Second title"),
288 UTF8ToUTF16("second slightly longer message"));
289 optional.items.push_back(item2);
290 message_center::NotificationItem item3(
291 UTF8ToUTF16(""), // Test for empty string.
292 UTF8ToUTF16(" ")); // Test for string containing only spaces.
293 optional.items.push_back(item3);
294 optional.context_message = UTF8ToUTF16("Context Message");
296 scoped_ptr<message_center::Notification> notification(
297 new message_center::Notification(
298 message_center::NOTIFICATION_TYPE_BASE_FORMAT,
300 UTF8ToUTF16("Notification Title"),
301 UTF8ToUTF16("Notification Message - should be hidden"),
308 MockMessageCenter message_center;
309 base::scoped_nsobject<MCNotificationController> controller(
310 [[MCNotificationController alloc] initWithNotification:notification.get()
311 messageCenter:&message_center]);
314 EXPECT_FALSE([[controller titleView] isHidden]);
315 EXPECT_TRUE([[controller messageView] isHidden]);
316 EXPECT_FALSE([[controller contextMessageView] isHidden]);
318 EXPECT_EQ(3u, [[[controller listView] subviews] count]);
319 EXPECT_LT(NSMaxY([[controller listView] frame]),
320 NSMinY([[controller titleView] frame]));
323 } // namespace message_center