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.
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/notifications/notification.h"
11 #include "chrome/browser/notifications/notification_test_util.h"
12 #include "chrome/browser/notifications/notification_ui_manager.h"
13 #include "chrome/browser/notifications/sync_notifier/sync_notifier_test_utils.h"
14 #include "chrome/browser/notifications/sync_notifier/synced_notification.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/test/test_browser_thread.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "ui/message_center/message_center_util.h"
21 #include "ui/message_center/notification_types.h"
23 using syncer::SyncData;
24 using notifier::SyncedNotification;
25 using sync_pb::EntitySpecifics;
26 using sync_pb::SyncedNotificationSpecifics;
29 const int kNotificationPriority = static_cast<int>(
30 message_center::LOW_PRIORITY);
32 bool UseRichNotifications() {
33 return message_center::IsRichNotificationEnabled();
40 class SyncedNotificationTest : public testing::Test {
42 SyncedNotificationTest()
43 : ui_thread_(content::BrowserThread::UI, &message_loop_) {}
44 virtual ~SyncedNotificationTest() {}
46 // Methods from testing::Test.
48 virtual void SetUp() OVERRIDE {
49 sync_data1_ = CreateSyncData(kTitle1, kText1, kIconUrl1, kImageUrl1,
50 kAppId1, kKey1, kUnread);
51 sync_data2_ = CreateSyncData(kTitle2, kText2, kIconUrl2, kImageUrl2,
52 kAppId2, kKey2, kUnread);
53 // Notification 3 will have the same ID as notification1, but different
55 sync_data3_ = CreateSyncData(kTitle3, kText3, kIconUrl3, kImageUrl3,
56 kAppId1, kKey1, kUnread);
57 // Notification 4 will be the same as 1, but the read state will be 'read'.
58 sync_data4_ = CreateSyncData(kTitle1, kText1, kIconUrl1, kImageUrl1,
59 kAppId1, kKey1, kDismissed);
61 notification1_.reset(new SyncedNotification(sync_data1_));
62 notification2_.reset(new SyncedNotification(sync_data2_));
63 notification3_.reset(new SyncedNotification(sync_data3_));
64 notification4_.reset(new SyncedNotification(sync_data4_));
66 notification_manager_.reset(new StubNotificationUIManager(GURL(
67 kSyncedNotificationsWelcomeOrigin)));
70 virtual void TearDown() OVERRIDE {
71 notification_manager_.reset();
74 virtual void AddButtonBitmaps(SyncedNotification* notification,
75 unsigned int how_many) {
76 for (unsigned int i = 0; i < how_many; ++i) {
77 notification->button_bitmaps_.push_back(gfx::Image());
78 notification->button_bitmaps_fetch_pending_.push_back(true);
82 StubNotificationUIManager* notification_manager() {
83 return notification_manager_.get();
86 scoped_ptr<SyncedNotification> notification1_;
87 scoped_ptr<SyncedNotification> notification2_;
88 scoped_ptr<SyncedNotification> notification3_;
89 scoped_ptr<SyncedNotification> notification4_;
90 syncer::SyncData sync_data1_;
91 syncer::SyncData sync_data2_;
92 syncer::SyncData sync_data3_;
93 syncer::SyncData sync_data4_;
96 base::MessageLoopForIO message_loop_;
97 content::TestBrowserThread ui_thread_;
98 scoped_ptr<StubNotificationUIManager> notification_manager_;
100 DISALLOW_COPY_AND_ASSIGN(SyncedNotificationTest);
103 // test simple accessors
105 TEST_F(SyncedNotificationTest, GetAppIdTest) {
106 std::string found_app_id = notification1_->GetAppId();
107 std::string expected_app_id(kAppId1);
109 EXPECT_EQ(found_app_id, expected_app_id);
112 TEST_F(SyncedNotificationTest, GetKeyTest) {
113 std::string found_key = notification1_->GetKey();
114 std::string expected_key(kKey1);
116 EXPECT_EQ(expected_key, found_key);
119 TEST_F(SyncedNotificationTest, GetTitleTest) {
120 std::string found_title = notification1_->GetTitle();
121 std::string expected_title(kTitle1);
123 EXPECT_EQ(expected_title, found_title);
126 TEST_F(SyncedNotificationTest, GetIconURLTest) {
127 std::string found_icon_url = notification1_->GetAppIconUrl().spec();
128 std::string expected_icon_url(kIconUrl1);
130 EXPECT_EQ(expected_icon_url, found_icon_url);
133 TEST_F(SyncedNotificationTest, GetReadStateTest) {
134 SyncedNotification::ReadState found_state1 =
135 notification1_->GetReadState();
136 SyncedNotification::ReadState expected_state1(SyncedNotification::kUnread);
138 EXPECT_EQ(expected_state1, found_state1);
140 SyncedNotification::ReadState found_state2 =
141 notification4_->GetReadState();
142 SyncedNotification::ReadState expected_state2(SyncedNotification::kDismissed);
144 EXPECT_EQ(expected_state2, found_state2);
147 // TODO(petewil): Improve ctor to pass in an image and type so this test can
148 // pass on actual data.
149 TEST_F(SyncedNotificationTest, GetImageURLTest) {
150 GURL found_image_url = notification1_->GetImageUrl();
151 GURL expected_image_url = GURL(kImageUrl1);
153 EXPECT_EQ(expected_image_url, found_image_url);
156 // TODO(petewil): test with a multi-line message
157 TEST_F(SyncedNotificationTest, GetTextTest) {
158 std::string found_text = notification1_->GetText();
159 std::string expected_text(kText1);
161 EXPECT_EQ(expected_text, found_text);
164 TEST_F(SyncedNotificationTest, GetCreationTimeTest) {
165 uint64 found_time = notification1_->GetCreationTime();
166 EXPECT_EQ(kFakeCreationTime, found_time);
169 TEST_F(SyncedNotificationTest, GetPriorityTest) {
170 double found_priority = notification1_->GetPriority();
171 EXPECT_EQ(static_cast<double>(kNotificationPriority), found_priority);
174 TEST_F(SyncedNotificationTest, GetButtonCountTest) {
175 int found_button_count = notification1_->GetButtonCount();
176 EXPECT_EQ(2, found_button_count);
179 TEST_F(SyncedNotificationTest, GetNotificationCountTest) {
180 int found_notification_count = notification1_->GetNotificationCount();
181 EXPECT_EQ(3, found_notification_count);
184 TEST_F(SyncedNotificationTest, GetDefaultDestinationDataTest) {
185 std::string default_destination_title =
186 notification1_->GetDefaultDestinationTitle();
187 GURL default_destination_icon_url =
188 notification1_->GetDefaultDestinationIconUrl();
189 GURL default_destination_url =
190 notification1_->GetDefaultDestinationUrl();
191 EXPECT_EQ(std::string(kDefaultDestinationTitle), default_destination_title);
192 EXPECT_EQ(GURL(kDefaultDestinationIconUrl),
193 default_destination_icon_url);
194 EXPECT_EQ(GURL(kDefaultDestinationUrl), default_destination_url);
197 TEST_F(SyncedNotificationTest, GetButtonDataTest) {
198 std::string button_one_title = notification1_->GetButtonTitle(0);
199 GURL button_one_icon_url = notification1_->GetButtonIconUrl(0);
200 GURL button_one_url = notification1_->GetButtonUrl(0);
201 std::string button_two_title = notification1_->GetButtonTitle(1);
202 GURL button_two_icon_url = notification1_->GetButtonIconUrl(1);
203 GURL button_two_url = notification1_->GetButtonUrl(1);
204 EXPECT_EQ(std::string(kButtonOneTitle), button_one_title);
205 EXPECT_EQ(GURL(kButtonOneIconUrl), button_one_icon_url);
206 EXPECT_EQ(GURL(kButtonOneUrl), button_one_url);
207 EXPECT_EQ(std::string(kButtonTwoTitle), button_two_title);
208 EXPECT_EQ(GURL(kButtonTwoIconUrl), button_two_icon_url);
209 EXPECT_EQ(GURL(kButtonTwoUrl), button_two_url);
212 TEST_F(SyncedNotificationTest, ContainedNotificationTest) {
213 std::string notification_title1 =
214 notification1_->GetContainedNotificationTitle(0);
215 std::string notification_title2 =
216 notification1_->GetContainedNotificationTitle(1);
217 std::string notification_title3 =
218 notification1_->GetContainedNotificationTitle(2);
219 std::string notification_message1 =
220 notification1_->GetContainedNotificationMessage(0);
221 std::string notification_message2 =
222 notification1_->GetContainedNotificationMessage(1);
223 std::string notification_message3 =
224 notification1_->GetContainedNotificationMessage(2);
226 EXPECT_EQ(std::string(kContainedTitle1), notification_title1);
227 EXPECT_EQ(std::string(kContainedTitle2), notification_title2);
228 EXPECT_EQ(std::string(kContainedTitle3), notification_title3);
229 EXPECT_EQ(std::string(kContainedMessage1), notification_message1);
230 EXPECT_EQ(std::string(kContainedMessage2), notification_message2);
231 EXPECT_EQ(std::string(kContainedMessage3), notification_message3);
234 // test that EqualsIgnoringReadState works as we expect
235 TEST_F(SyncedNotificationTest, EqualsIgnoringReadStateTest) {
236 EXPECT_TRUE(notification1_->EqualsIgnoringReadState(*notification1_));
237 EXPECT_TRUE(notification2_->EqualsIgnoringReadState(*notification2_));
238 EXPECT_FALSE(notification1_->EqualsIgnoringReadState(*notification2_));
239 EXPECT_FALSE(notification1_->EqualsIgnoringReadState(*notification3_));
240 EXPECT_TRUE(notification1_->EqualsIgnoringReadState(*notification4_));
243 TEST_F(SyncedNotificationTest, UpdateTest) {
244 scoped_ptr<SyncedNotification> notification5;
245 notification5.reset(new SyncedNotification(sync_data1_));
247 // update with the sync data from notification2, and ensure they are equal.
248 notification5->Update(sync_data2_);
249 EXPECT_TRUE(notification5->EqualsIgnoringReadState(*notification2_));
250 EXPECT_EQ(notification5->GetReadState(), notification2_->GetReadState());
251 EXPECT_FALSE(notification5->EqualsIgnoringReadState(*notification1_));
254 TEST_F(SyncedNotificationTest, ShowTest) {
256 if (!UseRichNotifications())
259 // Call the method under test using the pre-populated data.
260 notification1_->Show(notification_manager(), NULL, NULL);
262 const Notification notification = notification_manager()->notification();
264 // Check the base fields of the notification.
265 EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE, notification.type());
266 EXPECT_EQ(std::string(kTitle1), base::UTF16ToUTF8(notification.title()));
267 EXPECT_EQ(std::string(kText1), base::UTF16ToUTF8(notification.message()));
268 EXPECT_EQ(std::string(kExpectedOriginUrl), notification.origin_url().spec());
269 EXPECT_EQ(std::string(kKey1), base::UTF16ToUTF8(notification.replace_id()));
271 EXPECT_EQ(kFakeCreationTime, notification.timestamp().ToDoubleT());
272 EXPECT_EQ(kNotificationPriority, notification.priority());
275 TEST_F(SyncedNotificationTest, DismissTest) {
277 if (!UseRichNotifications())
280 // Call the method under test using a dismissed notification.
281 notification4_->Show(notification_manager(), NULL, NULL);
283 EXPECT_EQ(std::string(kKey1), notification_manager()->dismissed_id());
286 TEST_F(SyncedNotificationTest, AddBitmapToFetchQueueTest) {
287 scoped_ptr<SyncedNotification> notification6;
288 notification6.reset(new SyncedNotification(sync_data1_));
290 // Add two bitmaps to the queue.
291 notification6->AddBitmapToFetchQueue(GURL(kIconUrl1));
292 notification6->AddBitmapToFetchQueue(GURL(kIconUrl2));
294 EXPECT_EQ(GURL(kIconUrl1), notification6->fetchers_[0]->url());
295 EXPECT_EQ(GURL(kIconUrl2), notification6->fetchers_[1]->url());
297 notification6->AddBitmapToFetchQueue(GURL(kIconUrl2));
300 TEST_F(SyncedNotificationTest, OnFetchCompleteTest) {
301 if (!UseRichNotifications())
304 // Set up the internal state that FetchBitmaps() would have set.
305 notification1_->notification_manager_ = notification_manager();
307 // Add the bitmaps to the queue for us to match up.
308 notification1_->AddBitmapToFetchQueue(GURL(kIconUrl1));
309 notification1_->AddBitmapToFetchQueue(GURL(kImageUrl1));
310 notification1_->AddBitmapToFetchQueue(GURL(kButtonOneIconUrl));
311 notification1_->AddBitmapToFetchQueue(GURL(kButtonTwoIconUrl));
313 // Put some realistic looking bitmap data into the url_fetcher.
316 // Put a real bitmap into "bitmap". 2x2 bitmap of green 32 bit pixels.
317 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
318 bitmap.allocPixels();
319 bitmap.eraseColor(SK_ColorGREEN);
321 // Allocate the button_bitmaps_ array as the calling function normally would.
322 AddButtonBitmaps(notification1_.get(), 2);
324 notification1_->OnFetchComplete(GURL(kIconUrl1), &bitmap);
326 // When we call OnFetchComplete on the last bitmap, show should be called.
327 notification1_->OnFetchComplete(GURL(kImageUrl1), &bitmap);
329 notification1_->OnFetchComplete(GURL(kButtonOneIconUrl), &bitmap);
331 notification1_->OnFetchComplete(GURL(kButtonTwoIconUrl), &bitmap);
333 // Expect that the app icon has some data in it.
334 EXPECT_FALSE(notification1_->GetAppIcon().IsEmpty());
335 EXPECT_FALSE(notification_manager()->notification().small_image().IsEmpty());
337 // Since we check Show() thoroughly in its own test, we only check cursorily.
338 EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE,
339 notification_manager()->notification().type());
340 EXPECT_EQ(std::string(kTitle1),
341 base::UTF16ToUTF8(notification_manager()->notification().title()));
344 base::UTF16ToUTF8(notification_manager()->notification().message()));
346 // TODO(petewil): Check that the bitmap in the notification is what we expect.
347 // This fails today, the type info is different.
348 // EXPECT_TRUE(gfx::BitmapsAreEqual(
349 // image, notification1_->GetAppIconBitmap()));
353 TEST_F(SyncedNotificationTest, EmptyBitmapTest) {
354 if (!UseRichNotifications())
357 // Set up the internal state that FetchBitmaps() would have set.
358 notification1_->notification_manager_ = notification_manager();
360 // Add the bitmaps to the queue for us to match up.
361 notification1_->AddBitmapToFetchQueue(GURL(kIconUrl1));
362 notification1_->AddBitmapToFetchQueue(GURL(kImageUrl1));
363 notification1_->AddBitmapToFetchQueue(GURL(kButtonOneIconUrl));
364 notification1_->AddBitmapToFetchQueue(GURL(kButtonTwoIconUrl));
366 // Put some realistic looking bitmap data into the url_fetcher.
368 SkBitmap empty_bitmap;
370 // Put a real bitmap into "bitmap". 2x2 bitmap of green 32 bit pixels.
371 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
372 bitmap.allocPixels();
373 bitmap.eraseColor(SK_ColorGREEN);
375 // Put a null bitmap into "bitmap". 2x2 bitmap of green 32 bit pixels.
376 empty_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 0, 0);
377 empty_bitmap.allocPixels();
378 empty_bitmap.eraseColor(SK_ColorGREEN);
380 // Allocate the button_bitmaps_ array as the calling function normally would.
381 AddButtonBitmaps(notification1_.get(), 2);
383 notification1_->OnFetchComplete(GURL(kIconUrl1), &bitmap);
385 // When we call OnFetchComplete on the last bitmap, show should be called.
386 notification1_->OnFetchComplete(GURL(kImageUrl1), &bitmap);
388 notification1_->OnFetchComplete(GURL(kButtonOneIconUrl), &empty_bitmap);
390 notification1_->OnFetchComplete(GURL(kButtonTwoIconUrl), NULL);
392 // Since we check Show() thoroughly in its own test, we only check cursorily.
393 EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE,
394 notification_manager()->notification().type());
395 EXPECT_EQ(std::string(kTitle1),
396 base::UTF16ToUTF8(notification_manager()->notification().title()));
399 base::UTF16ToUTF8(notification_manager()->notification().message()));
402 // TODO(petewil): Add a test for a notification being read and or deleted.
404 } // namespace notifier