#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/message_center/message_center_util.h"
#include "ui/message_center/notification_types.h"
using syncer::SyncData;
const int kNotificationPriority = static_cast<int>(
message_center::LOW_PRIORITY);
-bool UseRichNotifications() {
- return message_center::IsRichNotificationEnabled();
-}
-
} // namespace
namespace notifier {
-// Stub out the NotificationUIManager for unit testing.
-class StubNotificationUIManager : public NotificationUIManager {
- public:
- StubNotificationUIManager()
- : notification_(GURL(),
- GURL(),
- string16(),
- string16(),
- new MockNotificationDelegate("stub")) {}
- virtual ~StubNotificationUIManager() {}
-
- // Adds a notification to be displayed. Virtual for unit test override.
- virtual void Add(const Notification& notification, Profile* profile)
- OVERRIDE {
- // Make a deep copy of the notification that we can inspect.
- notification_ = notification;
- profile_ = profile;
- }
-
- virtual bool Update(const Notification& notification, Profile* profile)
- OVERRIDE {
- // Make a deep copy of the notification that we can inspect.
- notification_ = notification;
- profile_ = profile;
- return true;
- }
-
- // Returns true if any notifications match the supplied ID, either currently
- // displayed or in the queue.
- virtual const Notification* FindById(const std::string& id) const OVERRIDE {
- return (notification_.id() == id) ? ¬ification_ : NULL;
- }
-
- // Removes any notifications matching the supplied ID, either currently
- // displayed or in the queue. Returns true if anything was removed.
- virtual bool CancelById(const std::string& notification_id) OVERRIDE {
- dismissed_id_ = notification_id;
- return true;
- }
-
- virtual std::set<std::string> GetAllIdsByProfileAndSourceOrigin(
- Profile* profile,
- const GURL& source) OVERRIDE {
- std::set<std::string> notification_ids;
- if (source == notification_.origin_url() &&
- profile->IsSameProfile(profile_))
- notification_ids.insert(notification_.notification_id());
- return notification_ids;
- }
-
- // Removes notifications matching the |source_origin| (which could be an
- // extension ID). Returns true if anything was removed.
- virtual bool CancelAllBySourceOrigin(const GURL& source_origin) OVERRIDE {
- return false;
- }
-
- // Removes notifications matching |profile|. Returns true if any were removed.
- virtual bool CancelAllByProfile(Profile* profile) OVERRIDE {
- return false;
- }
-
- // Cancels all pending notifications and closes anything currently showing.
- // Used when the app is terminating.
- virtual void CancelAll() OVERRIDE {}
-
- // Test hook to get the notification so we can check it
- const Notification& notification() const { return notification_; }
-
- // Test hook to check the ID of the last notification cancelled.
- std::string& dismissed_id() { return dismissed_id_; }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(StubNotificationUIManager);
- Notification notification_;
- Profile* profile_;
- std::string dismissed_id_;
-};
-
class SyncedNotificationTest : public testing::Test {
public:
SyncedNotificationTest()
// Methods from testing::Test.
virtual void SetUp() OVERRIDE {
+ notification_manager_.reset(new StubNotificationUIManager(GURL(
+ kSyncedNotificationsWelcomeOrigin)));
+
sync_data1_ = CreateSyncData(kTitle1, kText1, kIconUrl1, kImageUrl1,
kAppId1, kKey1, kUnread);
sync_data2_ = CreateSyncData(kTitle2, kText2, kIconUrl2, kImageUrl2,
sync_data4_ = CreateSyncData(kTitle1, kText1, kIconUrl1, kImageUrl1,
kAppId1, kKey1, kDismissed);
- notification1_.reset(new SyncedNotification(sync_data1_));
- notification2_.reset(new SyncedNotification(sync_data2_));
- notification3_.reset(new SyncedNotification(sync_data3_));
- notification4_.reset(new SyncedNotification(sync_data4_));
+ notification1_.reset(new SyncedNotification(
+ sync_data1_, NULL, notification_manager_.get()));
+ notification2_.reset(new SyncedNotification(
+ sync_data2_, NULL, notification_manager_.get()));
+ notification3_.reset(new SyncedNotification(
+ sync_data3_, NULL, notification_manager_.get()));
+ notification4_.reset(new SyncedNotification(
+ sync_data4_, NULL, notification_manager_.get()));
+
}
virtual void TearDown() OVERRIDE {
+ notification_manager_.reset();
}
virtual void AddButtonBitmaps(SyncedNotification* notification,
unsigned int how_many) {
for (unsigned int i = 0; i < how_many; ++i) {
notification->button_bitmaps_.push_back(gfx::Image());
+ notification->button_bitmaps_fetch_pending_.push_back(true);
}
}
+ StubNotificationUIManager* notification_manager() {
+ return notification_manager_.get();
+ }
+
scoped_ptr<SyncedNotification> notification1_;
scoped_ptr<SyncedNotification> notification2_;
scoped_ptr<SyncedNotification> notification3_;
private:
base::MessageLoopForIO message_loop_;
content::TestBrowserThread ui_thread_;
+ scoped_ptr<StubNotificationUIManager> notification_manager_;
DISALLOW_COPY_AND_ASSIGN(SyncedNotificationTest);
};
EXPECT_EQ(expected_image_url, found_image_url);
}
-// TODO(petewil): test with a multi-line message
TEST_F(SyncedNotificationTest, GetTextTest) {
std::string found_text = notification1_->GetText();
std::string expected_text(kText1);
TEST_F(SyncedNotificationTest, UpdateTest) {
scoped_ptr<SyncedNotification> notification5;
- notification5.reset(new SyncedNotification(sync_data1_));
+ notification5.reset(new SyncedNotification(
+ sync_data1_, NULL, notification_manager()));
// update with the sync data from notification2, and ensure they are equal.
notification5->Update(sync_data2_);
}
TEST_F(SyncedNotificationTest, ShowTest) {
-
- if (!UseRichNotifications())
- return;
-
- StubNotificationUIManager notification_manager;
-
// Call the method under test using the pre-populated data.
- notification1_->Show(¬ification_manager, NULL, NULL);
+ notification1_->Show(NULL);
- const Notification notification = notification_manager.notification();
+ const Notification notification = notification_manager()->notification();
// Check the base fields of the notification.
EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE, notification.type());
- EXPECT_EQ(std::string(kTitle1), UTF16ToUTF8(notification.title()));
- EXPECT_EQ(std::string(kText1), UTF16ToUTF8(notification.message()));
+ EXPECT_EQ(std::string(kTitle1), base::UTF16ToUTF8(notification.title()));
+ EXPECT_EQ(std::string(kText1), base::UTF16ToUTF8(notification.message()));
EXPECT_EQ(std::string(kExpectedOriginUrl), notification.origin_url().spec());
- EXPECT_EQ(std::string(kKey1), UTF16ToUTF8(notification.replace_id()));
+ EXPECT_EQ(std::string(kKey1), base::UTF16ToUTF8(notification.replace_id()));
EXPECT_EQ(kFakeCreationTime, notification.timestamp().ToDoubleT());
EXPECT_EQ(kNotificationPriority, notification.priority());
TEST_F(SyncedNotificationTest, DismissTest) {
- if (!UseRichNotifications())
- return;
-
- StubNotificationUIManager notification_manager;
-
// Call the method under test using a dismissed notification.
- notification4_->Show(¬ification_manager, NULL, NULL);
+ notification4_->Show(NULL);
- EXPECT_EQ(std::string(kKey1), notification_manager.dismissed_id());
+ EXPECT_EQ(std::string(kKey1), notification_manager()->dismissed_id());
}
-TEST_F(SyncedNotificationTest, AddBitmapToFetchQueueTest) {
+TEST_F(SyncedNotificationTest, CreateBitmapFetcherTest) {
scoped_ptr<SyncedNotification> notification6;
- notification6.reset(new SyncedNotification(sync_data1_));
+ notification6.reset(new SyncedNotification(
+ sync_data1_, NULL, notification_manager()));
// Add two bitmaps to the queue.
- notification6->AddBitmapToFetchQueue(GURL(kIconUrl1));
- notification6->AddBitmapToFetchQueue(GURL(kIconUrl2));
+ notification6->CreateBitmapFetcher(GURL(kIconUrl1));
+ notification6->CreateBitmapFetcher(GURL(kIconUrl2));
- EXPECT_EQ(2, notification6->active_fetcher_count_);
EXPECT_EQ(GURL(kIconUrl1), notification6->fetchers_[0]->url());
EXPECT_EQ(GURL(kIconUrl2), notification6->fetchers_[1]->url());
- notification6->AddBitmapToFetchQueue(GURL(kIconUrl2));
- EXPECT_EQ(2, notification6->active_fetcher_count_);
+ notification6->CreateBitmapFetcher(GURL(kIconUrl2));
}
TEST_F(SyncedNotificationTest, OnFetchCompleteTest) {
- if (!UseRichNotifications())
- return;
-
- StubNotificationUIManager notification_manager;
-
// Set up the internal state that FetchBitmaps() would have set.
- notification1_->notification_manager_ = ¬ification_manager;
+ notification1_->notification_manager_ = notification_manager();
// Add the bitmaps to the queue for us to match up.
- notification1_->AddBitmapToFetchQueue(GURL(kIconUrl1));
- notification1_->AddBitmapToFetchQueue(GURL(kImageUrl1));
- notification1_->AddBitmapToFetchQueue(GURL(kButtonOneIconUrl));
- notification1_->AddBitmapToFetchQueue(GURL(kButtonTwoIconUrl));
-
- EXPECT_EQ(4, notification1_->active_fetcher_count_);
+ notification1_->CreateBitmapFetcher(GURL(kIconUrl1));
+ notification1_->CreateBitmapFetcher(GURL(kImageUrl1));
+ notification1_->CreateBitmapFetcher(GURL(kButtonOneIconUrl));
+ notification1_->CreateBitmapFetcher(GURL(kButtonTwoIconUrl));
// Put some realistic looking bitmap data into the url_fetcher.
SkBitmap bitmap;
AddButtonBitmaps(notification1_.get(), 2);
notification1_->OnFetchComplete(GURL(kIconUrl1), &bitmap);
- EXPECT_EQ(3, notification1_->active_fetcher_count_);
// When we call OnFetchComplete on the last bitmap, show should be called.
notification1_->OnFetchComplete(GURL(kImageUrl1), &bitmap);
- EXPECT_EQ(2, notification1_->active_fetcher_count_);
notification1_->OnFetchComplete(GURL(kButtonOneIconUrl), &bitmap);
- EXPECT_EQ(1, notification1_->active_fetcher_count_);
notification1_->OnFetchComplete(GURL(kButtonTwoIconUrl), &bitmap);
- EXPECT_EQ(0, notification1_->active_fetcher_count_);
+
+ // Expect that the app icon has some data in it.
+ EXPECT_FALSE(notification1_->GetAppIcon().IsEmpty());
+ EXPECT_FALSE(notification_manager()->notification().small_image().IsEmpty());
// Since we check Show() thoroughly in its own test, we only check cursorily.
EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE,
- notification_manager.notification().type());
+ notification_manager()->notification().type());
EXPECT_EQ(std::string(kTitle1),
- UTF16ToUTF8(notification_manager.notification().title()));
- EXPECT_EQ(std::string(kText1),
- UTF16ToUTF8(notification_manager.notification().message()));
+ base::UTF16ToUTF8(notification_manager()->notification().title()));
+ EXPECT_EQ(
+ std::string(kText1),
+ base::UTF16ToUTF8(notification_manager()->notification().message()));
// TODO(petewil): Check that the bitmap in the notification is what we expect.
// This fails today, the type info is different.
// image, notification1_->GetAppIconBitmap()));
}
-TEST_F(SyncedNotificationTest, QueueBitmapFetchJobsTest) {
- if (!UseRichNotifications())
- return;
+// TODO(petewil): Empty bitmap should count as a successful fetch.
+TEST_F(SyncedNotificationTest, EmptyBitmapTest) {
+ // Set up the internal state that FetchBitmaps() would have set.
+ notification1_->notification_manager_ = notification_manager();
+
+ // Add the bitmaps to the queue for us to match up.
+ notification1_->CreateBitmapFetcher(GURL(kIconUrl1));
+ notification1_->CreateBitmapFetcher(GURL(kImageUrl1));
+ notification1_->CreateBitmapFetcher(GURL(kButtonOneIconUrl));
+ notification1_->CreateBitmapFetcher(GURL(kButtonTwoIconUrl));
+
+ // Put some realistic looking bitmap data into the url_fetcher.
+ SkBitmap bitmap;
+ SkBitmap empty_bitmap;
+
+ // Put a real bitmap into "bitmap". 2x2 bitmap of green 32 bit pixels.
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
+ bitmap.allocPixels();
+ bitmap.eraseColor(SK_ColorGREEN);
+
+ // Put a null bitmap into "bitmap". 2x2 bitmap of green 32 bit pixels.
+ empty_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 0, 0);
+ empty_bitmap.allocPixels();
+ empty_bitmap.eraseColor(SK_ColorGREEN);
+
+ // Allocate the button_bitmaps_ array as the calling function normally would.
+ AddButtonBitmaps(notification1_.get(), 2);
+
+ notification1_->OnFetchComplete(GURL(kIconUrl1), &bitmap);
+
+ // When we call OnFetchComplete on the last bitmap, show should be called.
+ notification1_->OnFetchComplete(GURL(kImageUrl1), &bitmap);
+
+ notification1_->OnFetchComplete(GURL(kButtonOneIconUrl), &empty_bitmap);
+
+ notification1_->OnFetchComplete(GURL(kButtonTwoIconUrl), NULL);
+
+ // Since we check Show() thoroughly in its own test, we only check cursorily.
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE,
+ notification_manager()->notification().type());
+ EXPECT_EQ(std::string(kTitle1),
+ base::UTF16ToUTF8(notification_manager()->notification().title()));
+ EXPECT_EQ(
+ std::string(kText1),
+ base::UTF16ToUTF8(notification_manager()->notification().message()));
+}
- StubNotificationUIManager notification_manager;
+TEST_F(SyncedNotificationTest, ShowIfNewlyEnabledTest) {
+ // Call the method using the wrong app id, nothing should get shown.
+ notification1_->ShowAllForAppId(NULL, kAppId2);
- notification1_->QueueBitmapFetchJobs(¬ification_manager, NULL, NULL);
+ // Ensure no notification was generated and shown.
+ const Notification notification1 = notification_manager()->notification();
+ EXPECT_EQ(std::string(), base::UTF16ToUTF8(notification1.replace_id()));
+
+ // Call the method under test using the pre-populated data.
+ notification1_->ShowAllForAppId(NULL, kAppId1);
+
+ const Notification notification2 = notification_manager()->notification();
+
+ // Check the base fields of the notification.
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_IMAGE, notification2.type());
+ EXPECT_EQ(std::string(kTitle1), base::UTF16ToUTF8(notification2.title()));
+ EXPECT_EQ(std::string(kText1), base::UTF16ToUTF8(notification2.message()));
+ EXPECT_EQ(std::string(kExpectedOriginUrl), notification2.origin_url().spec());
+ EXPECT_EQ(std::string(kKey1), base::UTF16ToUTF8(notification2.replace_id()));
+
+ EXPECT_EQ(kFakeCreationTime, notification2.timestamp().ToDoubleT());
+ EXPECT_EQ(kNotificationPriority, notification2.priority());
+}
+
+TEST_F(SyncedNotificationTest, HideIfNewlyRemovedTest) {
+ // Add the notification to the notification manger, so it exists before we
+ // we remove it.
+ notification1_->Show(NULL);
+ const Notification* found1 = notification_manager()->FindById(kKey1);
+ EXPECT_NE(reinterpret_cast<Notification*>(NULL), found1);
+
+ // Call the method under test using the pre-populated data.
+ notification1_->HideAllForAppId(kAppId1);
- // There should be 4 urls in the queue, icon, image, and two buttons.
- EXPECT_EQ(4, notification1_->active_fetcher_count_);
+ // Ensure the notification was removed from the notification manager
+ EXPECT_EQ(std::string(kKey1), notification_manager()->dismissed_id());
}
// TODO(petewil): Add a test for a notification being read and or deleted.