// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/message_center/notification_list.h"

#include <stddef.h>

#include <utility>

#include "base/i18n/time_formatting.h"
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/message_center/fake_message_center.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/public/cpp/notifier_id.h"

using base::UTF8ToUTF16;

namespace message_center {

using NotificationState = NotificationList::NotificationState;

class NotificationListTest : public testing::Test {
 public:
  NotificationListTest() {}
  ~NotificationListTest() override {}

  void SetUp() override {
    message_center_.reset(new FakeMessageCenter());
    notification_list_.reset(new NotificationList(message_center_.get()));
    counter_ = 0;
  }

 protected:
  // Currently NotificationListTest doesn't care about some fields like title or
  // message, so put a simple template on it. Returns the id of the new
  // notification.
  std::string AddNotification(const RichNotificationData& optional_fields) {
    std::string new_id;
    std::unique_ptr<Notification> notification(
        MakeNotification(optional_fields, &new_id));
    notification_list_->AddNotification(std::move(notification));
    counter_++;
    return new_id;
  }

  std::string AddNotification() {
    return AddNotification(RichNotificationData());
  }

  // Construct a new notification for testing, but don't add it to the list yet.
  std::unique_ptr<Notification> MakeNotification(
      const RichNotificationData& optional_fields,
      std::string* id_out) {
    *id_out = base::StringPrintf(kIdFormat, counter_);
    std::unique_ptr<Notification> notification(new Notification(
        NOTIFICATION_TYPE_SIMPLE, *id_out,
        UTF8ToUTF16(base::StringPrintf(kTitleFormat, counter_)),
        UTF8ToUTF16(base::StringPrintf(kMessageFormat, counter_)), gfx::Image(),
        UTF8ToUTF16(kDisplaySource), GURL(),
        NotifierId(NotifierType::APPLICATION, kExtensionId), optional_fields,
        NULL));
    return notification;
  }

  std::unique_ptr<Notification> MakeNotification(std::string* id_out) {
    return MakeNotification(RichNotificationData(), id_out);
  }

  // Utility methods of AddNotification.
  std::string AddPriorityNotification(NotificationPriority priority) {
    RichNotificationData optional;
    optional.priority = priority;
    return AddNotification(optional);
  }

  NotificationList::PopupNotifications GetPopups() {
    return notification_list_->GetPopupNotifications(blockers_, NULL);
  }

  size_t GetPopupCounts() {
    return GetPopups().size();
  }

  Notification* GetNotification(const std::string& id) {
    auto iter = notification_list_->GetNotification(id);
    if (iter == notification_list_->notifications_.end())
      return NULL;
    return iter->first.get();
  }

  NotificationState GetNotificationState(const std::string& id) {
    auto iter = notification_list_->GetNotification(id);
    EXPECT_FALSE(iter == notification_list_->notifications_.end());
    return iter->second;
  }

  static const char kIdFormat[];
  static const char kTitleFormat[];
  static const char kMessageFormat[];
  static const char kDisplaySource[];
  static const char kExtensionId[];

  std::unique_ptr<FakeMessageCenter> message_center_;
  std::unique_ptr<NotificationList> notification_list_;
  NotificationBlockers blockers_;
  size_t counter_;

 private:
  DISALLOW_COPY_AND_ASSIGN(NotificationListTest);
};

bool IsInNotifications(const NotificationList::Notifications& notifications,
                       const std::string& id) {
  for (auto iter = notifications.begin(); iter != notifications.end(); ++iter) {
    if ((*iter)->id() == id)
      return true;
  }
  return false;
}

const char NotificationListTest::kIdFormat[] = "id%ld";
const char NotificationListTest::kTitleFormat[] = "id%ld";
const char NotificationListTest::kMessageFormat[] = "message%ld";
const char NotificationListTest::kDisplaySource[] = "source";
const char NotificationListTest::kExtensionId[] = "ext";

TEST_F(NotificationListTest, Basic) {
  ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));

  std::string id0 = AddNotification();
  EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
  std::string id1 = AddNotification();
  EXPECT_EQ(2u, notification_list_->NotificationCount(blockers_));

  EXPECT_TRUE(notification_list_->HasPopupNotifications(blockers_));
  EXPECT_TRUE(notification_list_->GetNotificationById(id0));
  EXPECT_TRUE(notification_list_->GetNotificationById(id1));
  EXPECT_FALSE(notification_list_->GetNotificationById(id1 + "foo"));

  EXPECT_EQ(2u, GetPopupCounts());

  notification_list_->MarkSinglePopupAsShown(id0, true);
  notification_list_->MarkSinglePopupAsShown(id1, true);
  EXPECT_EQ(2u, notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(0u, GetPopupCounts());

  notification_list_->RemoveNotification(id0);
  EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));

  AddNotification();
  EXPECT_EQ(2u, notification_list_->NotificationCount(blockers_));
}

TEST_F(NotificationListTest, MessageCenterVisible) {
  AddNotification();
  EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
  ASSERT_EQ(1u, GetPopupCounts());

  // Resets the unread count and popup counts.
  notification_list_->SetNotificationsShown(blockers_, NULL);
  ASSERT_EQ(0u, GetPopupCounts());
}

TEST_F(NotificationListTest, UpdateNotification) {
  std::string id0 = AddNotification();
  std::string replaced = id0 + "_replaced";
  EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
  std::unique_ptr<Notification> notification(new Notification(
      NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
      UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
      NotifierId(NotifierType::APPLICATION, kExtensionId),
      RichNotificationData(), NULL));
  notification_list_->UpdateNotificationMessage(id0, std::move(notification));
  EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
  const NotificationList::Notifications notifications =
      notification_list_->GetVisibleNotifications(blockers_);
  EXPECT_EQ(replaced, (*notifications.begin())->id());
  EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
  EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
}

TEST_F(NotificationListTest, UpdateNotificationWithRenotifyAndQuietMode) {
  for (size_t quiet_mode = 0u; quiet_mode < 2u; ++quiet_mode) {
    // Set Do Not Disturb mode.
    notification_list_->SetQuietMode(static_cast<bool>(quiet_mode));

    // Create notification.
    std::string old_id;
    auto old_notification = MakeNotification(&old_id);
    notification_list_->AddNotification(std::move(old_notification));
    notification_list_->MarkSinglePopupAsShown(old_id, true);
    EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));

    std::string new_id;
    auto new_notification = MakeNotification(&new_id);
    // Set the renotify flag and update.
    new_notification->set_renotify(true);
    notification_list_->UpdateNotificationMessage(old_id,
                                                  std::move(new_notification));
    const NotificationList::Notifications notifications =
        notification_list_->GetVisibleNotifications(blockers_);
    EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
    EXPECT_EQ(new_id, (*notifications.begin())->id());

    // Normally, |shown_as_popup| should be reset in order to show the popup
    // again.
    // In quiet mode, |shown_as_popup| should not be reset, as popup should not
    // be shown even though renotify was set.
    const NotificationList::PopupNotifications popup_notifications =
        notification_list_->GetPopupNotifications(blockers_, nullptr);
    if (quiet_mode) {
      ASSERT_EQ(0U, popup_notifications.size());
    } else {
      ASSERT_EQ(1U, popup_notifications.size());
      EXPECT_EQ(new_id, (*popup_notifications.begin())->id());
    }
  }
}

TEST_F(NotificationListTest, GetNotificationsByNotifierId) {
  NotifierId id0(NotifierType::APPLICATION, "ext0");
  NotifierId id1(NotifierType::APPLICATION, "ext1");
  NotifierId id2(GURL("http://example.com"));
  NotifierId id3(NotifierType::SYSTEM_COMPONENT, "system-notifier");
  std::unique_ptr<Notification> notification(new Notification(
      NOTIFICATION_TYPE_SIMPLE, "id0", UTF8ToUTF16("title0"),
      UTF8ToUTF16("message0"), gfx::Image(), UTF8ToUTF16("source0"), GURL(),
      id0, RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, "id1", UTF8ToUTF16("title1"),
      UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source0"), GURL(),
      id0, RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, "id2", UTF8ToUTF16("title1"),
      UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source1"), GURL(),
      id0, RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, "id3", UTF8ToUTF16("title1"),
      UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
      id1, RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, "id4", UTF8ToUTF16("title1"),
      UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
      id2, RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, "id5", UTF8ToUTF16("title1"),
      UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
      id3, RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));

  NotificationList::Notifications by_notifier_id =
      notification_list_->GetNotificationsByNotifierId(id0);
  EXPECT_TRUE(IsInNotifications(by_notifier_id, "id0"));
  EXPECT_TRUE(IsInNotifications(by_notifier_id, "id1"));
  EXPECT_TRUE(IsInNotifications(by_notifier_id, "id2"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));

  by_notifier_id = notification_list_->GetNotificationsByNotifierId(id1);
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
  EXPECT_TRUE(IsInNotifications(by_notifier_id, "id3"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));

  by_notifier_id = notification_list_->GetNotificationsByNotifierId(id2);
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
  EXPECT_TRUE(IsInNotifications(by_notifier_id, "id4"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id5"));

  by_notifier_id = notification_list_->GetNotificationsByNotifierId(id3);
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id0"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id1"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id2"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id3"));
  EXPECT_FALSE(IsInNotifications(by_notifier_id, "id4"));
  EXPECT_TRUE(IsInNotifications(by_notifier_id, "id5"));
}

TEST_F(NotificationListTest, OldPopupShouldNotBeHidden) {
  std::vector<std::string> ids;
  for (size_t i = 0; i <= kMaxVisiblePopupNotifications; i++)
    ids.push_back(AddNotification());

  NotificationList::PopupNotifications popups = GetPopups();
  // The popup should contain the oldest kMaxVisiblePopupNotifications. Newer
  // one should come earlier in the popup list. It means, the last element
  // of |popups| should be the firstly added one, and so on.
  EXPECT_EQ(kMaxVisiblePopupNotifications, popups.size());
  auto iter = popups.rbegin();
  for (size_t i = 0; i < kMaxVisiblePopupNotifications; ++i, ++iter) {
    EXPECT_EQ(ids[i], (*iter)->id()) << i;
  }

  for (auto iter = popups.begin(); iter != popups.end(); ++iter) {
    notification_list_->MarkSinglePopupAsShown((*iter)->id(), false);
  }
  popups.clear();
  popups = GetPopups();
  ASSERT_EQ(1u, popups.size());
  EXPECT_EQ(ids.back(), (*popups.begin())->id());
}

TEST_F(NotificationListTest, Priority) {
  ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));

  // Default priority has the limit on the number of the popups.
  for (size_t i = 0; i <= kMaxVisiblePopupNotifications; ++i)
    AddNotification();
  EXPECT_EQ(kMaxVisiblePopupNotifications + 1,
            notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(kMaxVisiblePopupNotifications, GetPopupCounts());

  // Low priority: not visible to popups.
  notification_list_->SetNotificationsShown(blockers_, NULL);
  AddPriorityNotification(LOW_PRIORITY);
  EXPECT_EQ(kMaxVisiblePopupNotifications + 2,
            notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(0u, GetPopupCounts());

  // Minimum priority: doesn't update the unread count.
  AddPriorityNotification(MIN_PRIORITY);
  EXPECT_EQ(kMaxVisiblePopupNotifications + 3,
            notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(0u, GetPopupCounts());

  NotificationList::Notifications notifications =
      notification_list_->GetVisibleNotifications(blockers_);
  for (auto iter = notifications.begin(); iter != notifications.end(); ++iter) {
    notification_list_->RemoveNotification((*iter)->id());
  }

  // Higher priority: no limits to the number of popups.
  for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
    AddPriorityNotification(HIGH_PRIORITY);
  for (size_t i = 0; i < kMaxVisiblePopupNotifications * 2; ++i)
    AddPriorityNotification(MAX_PRIORITY);
  EXPECT_EQ(kMaxVisiblePopupNotifications * 4,
            notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(kMaxVisiblePopupNotifications * 4, GetPopupCounts());
}

// Tests that GetNotificationsByAppId returns notifications regardless of their
// visibility.
TEST_F(NotificationListTest, GetNotificationsByAppId) {
  // Add a notification for |app_id1|.
  const std::string app_id1("app_id1");
  const std::string id1("id1");
  std::unique_ptr<Notification> notification(
      new Notification(NOTIFICATION_TYPE_PROGRESS, id1, UTF8ToUTF16("updated"),
                       UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
                       GURL(), NotifierId(NotifierType::APPLICATION, app_id1),
                       RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id1).size());

  // Mark the popup as shown but not read.
  notification_list_->MarkSinglePopupAsShown(id1, false);
  EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id1).size());

  // Mark the popup as shown and read.
  notification_list_->MarkSinglePopupAsShown(id1, true);
  EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id1).size());

  // Remove the notification.
  notification_list_->RemoveNotification(id1);
  EXPECT_EQ(0u, notification_list_->GetNotificationsByAppId(app_id1).size());

  // Add two notifications for |app_id1| and one for |app_id2|.
  notification.reset(
      new Notification(NOTIFICATION_TYPE_PROGRESS, id1, UTF8ToUTF16("updated"),
                       UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
                       GURL(), NotifierId(NotifierType::APPLICATION, app_id1),
                       RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));

  const std::string id2("id2");
  notification.reset(
      new Notification(NOTIFICATION_TYPE_PROGRESS, id2, UTF8ToUTF16("updated"),
                       UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
                       GURL(), NotifierId(NotifierType::APPLICATION, app_id1),
                       RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  EXPECT_EQ(2u, notification_list_->GetNotificationsByAppId(app_id1).size());

  const std::string id3("id3");
  const std::string app_id2("app_id2");
  notification.reset(
      new Notification(NOTIFICATION_TYPE_PROGRESS, id3, UTF8ToUTF16("updated"),
                       UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
                       GURL(), NotifierId(NotifierType::APPLICATION, app_id2),
                       RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(notification));
  EXPECT_EQ(2u, notification_list_->GetNotificationsByAppId(app_id1).size());
  EXPECT_EQ(1u, notification_list_->GetNotificationsByAppId(app_id2).size());

  for (std::string app_id : {app_id1, app_id2}) {
    for (auto* notification :
         notification_list_->GetNotificationsByAppId(app_id)) {
      EXPECT_EQ(app_id, notification->notifier_id().id);
    }
  }
}

TEST_F(NotificationListTest, HasPopupsWithPriority) {
  ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));

  AddPriorityNotification(MIN_PRIORITY);
  AddPriorityNotification(MAX_PRIORITY);

  EXPECT_EQ(1u, GetPopupCounts());
}

TEST_F(NotificationListTest, HasPopupsWithSystemPriority) {
  ASSERT_EQ(0u, notification_list_->NotificationCount(blockers_));

  std::string normal_id = AddPriorityNotification(DEFAULT_PRIORITY);
  std::string system_id = AddNotification();
  GetNotification(system_id)->SetSystemPriority();

  EXPECT_EQ(2u, GetPopupCounts());

  notification_list_->MarkSinglePopupAsDisplayed(normal_id);
  notification_list_->MarkSinglePopupAsDisplayed(system_id);

  notification_list_->MarkSinglePopupAsShown(normal_id, false);
  notification_list_->MarkSinglePopupAsShown(system_id, false);

  notification_list_->SetNotificationsShown(blockers_, NULL);
  EXPECT_EQ(1u, GetPopupCounts());

  // Mark as read -- emulation of mouse click.
  notification_list_->MarkSinglePopupAsShown(system_id, true);
  EXPECT_EQ(0u, GetPopupCounts());
}

// Verifies that notification updates will re-show the toast when there is no
// message center view (i.e. the bubble anchored to the status bar).
TEST_F(NotificationListTest, UpdateWithoutMessageCenterView) {
  auto run_test = [this](bool has_message_center_view) {
    message_center_->SetHasMessageCenterView(has_message_center_view);
    std::string id0 = AddNotification();
    std::string replaced = id0 + "_replaced";
    notification_list_->MarkSinglePopupAsShown(id0, false);
    EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
    EXPECT_EQ(0u, GetPopupCounts());

    RichNotificationData optional;
    std::unique_ptr<Notification> notification(new Notification(
        NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
        UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource),
        GURL(), NotifierId(NotifierType::APPLICATION, kExtensionId), optional,
        NULL));
    notification_list_->UpdateNotificationMessage(id0, std::move(notification));
    EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
    EXPECT_EQ(has_message_center_view ? 0U : 1U, GetPopupCounts());
    const NotificationList::Notifications notifications =
        notification_list_->GetVisibleNotifications(blockers_);
    EXPECT_EQ(replaced, (*notifications.begin())->id());
    EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
    EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());

    notification_list_->RemoveNotification(replaced);
    EXPECT_EQ(0U,
              notification_list_->GetVisibleNotifications(blockers_).size());
  };

  run_test(false);
  run_test(true);
}

TEST_F(NotificationListTest, Renotify) {
  std::string id0 = AddNotification();
  std::string replaced = id0 + "_replaced";
  notification_list_->MarkSinglePopupAsShown(id0, false);
  EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(0u, GetPopupCounts());
  RichNotificationData optional;
  optional.renotify = true;
  std::unique_ptr<Notification> notification(new Notification(
      NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
      UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
      NotifierId(NotifierType::APPLICATION, kExtensionId), optional, NULL));
  notification_list_->UpdateNotificationMessage(id0, std::move(notification));
  EXPECT_EQ(1u, notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(1u, GetPopupCounts());
  const NotificationList::Notifications notifications =
      notification_list_->GetVisibleNotifications(blockers_);
  EXPECT_EQ(replaced, (*notifications.begin())->id());
  EXPECT_EQ(UTF8ToUTF16("newtitle"), (*notifications.begin())->title());
  EXPECT_EQ(UTF8ToUTF16("newbody"), (*notifications.begin())->message());
}

TEST_F(NotificationListTest, PriorityAndRenotify) {
  std::string id0 = AddPriorityNotification(LOW_PRIORITY);
  std::string id1 = AddPriorityNotification(DEFAULT_PRIORITY);
  EXPECT_EQ(1u, GetPopupCounts());
  notification_list_->MarkSinglePopupAsShown(id1, true);
  EXPECT_EQ(0u, GetPopupCounts());

  // id0 promoted to LOW->DEFAULT, it'll appear as toast (popup).
  RichNotificationData priority;
  priority.priority = DEFAULT_PRIORITY;
  std::unique_ptr<Notification> notification(new Notification(
      NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle"),
      UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
      NotifierId(NotifierType::APPLICATION, kExtensionId), priority, NULL));
  notification_list_->UpdateNotificationMessage(id0, std::move(notification));
  EXPECT_EQ(1u, GetPopupCounts());
  notification_list_->MarkSinglePopupAsShown(id0, true);
  EXPECT_EQ(0u, GetPopupCounts());

  // update with no promotion change for id0, it won't appear as a toast.
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle2"),
      UTF8ToUTF16("newbody2"), gfx::Image(), UTF8ToUTF16(kDisplaySource),
      GURL(), NotifierId(NotifierType::APPLICATION, kExtensionId), priority,
      NULL));
  notification_list_->UpdateNotificationMessage(id0, std::move(notification));
  EXPECT_EQ(0u, GetPopupCounts());

  // id1 promoted to DEFAULT->HIGH, it won't reappear as a toast (popup).
  priority.priority = HIGH_PRIORITY;
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle"),
      UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
      NotifierId(NotifierType::APPLICATION, kExtensionId), priority, NULL));
  notification_list_->UpdateNotificationMessage(id1, std::move(notification));
  EXPECT_EQ(0u, GetPopupCounts());

  // |renotify| will make it reappear as a toast (popup).
  priority.renotify = true;
  notification.reset(new Notification(
      NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle"),
      UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
      NotifierId(NotifierType::APPLICATION, kExtensionId), priority, NULL));
  notification_list_->UpdateNotificationMessage(id1, std::move(notification));
  EXPECT_EQ(1u, GetPopupCounts());
  notification_list_->MarkSinglePopupAsShown(id1, true);
  EXPECT_EQ(0u, GetPopupCounts());
}

TEST_F(NotificationListTest, NotificationOrderAndPriority) {
  base::Time now = base::Time::Now();
  RichNotificationData optional;
  optional.timestamp = now;
  optional.priority = 2;
  std::string max_id = AddNotification(optional);

  now += base::TimeDelta::FromSeconds(1);
  optional.timestamp = now;
  optional.priority = 1;
  std::string high_id = AddNotification(optional);

  now += base::TimeDelta::FromSeconds(1);
  optional.timestamp = now;
  optional.priority = 0;
  std::string default_id = AddNotification(optional);

  {
    // Popups: latest comes first.
    NotificationList::PopupNotifications popups = GetPopups();
    EXPECT_EQ(3u, popups.size());
    auto iter = popups.begin();
    EXPECT_EQ(default_id, (*iter)->id());
    iter++;
    EXPECT_EQ(high_id, (*iter)->id());
    iter++;
    EXPECT_EQ(max_id, (*iter)->id());
  }
  {
    // Notifications: high priority comes earlier.
    const NotificationList::Notifications notifications =
        notification_list_->GetVisibleNotifications(blockers_);
    EXPECT_EQ(3u, notifications.size());
    auto iter = notifications.begin();
    EXPECT_EQ(max_id, (*iter)->id());
    iter++;
    EXPECT_EQ(high_id, (*iter)->id());
    iter++;
    EXPECT_EQ(default_id, (*iter)->id());
  }
}

TEST_F(NotificationListTest, MarkSinglePopupAsShown) {
  std::string id1 = AddNotification();
  std::string id2 = AddNotification();
  std::string id3 = AddNotification();
  ASSERT_EQ(3u, notification_list_->NotificationCount(blockers_));
  ASSERT_EQ(std::min(static_cast<size_t>(3u), kMaxVisiblePopupNotifications),
            GetPopupCounts());
  notification_list_->MarkSinglePopupAsDisplayed(id1);
  notification_list_->MarkSinglePopupAsDisplayed(id2);
  notification_list_->MarkSinglePopupAsDisplayed(id3);

  notification_list_->MarkSinglePopupAsShown(id2, true);
  notification_list_->MarkSinglePopupAsShown(id3, false);
  EXPECT_EQ(3u, notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(1u, GetPopupCounts());
  NotificationList::PopupNotifications popups = GetPopups();
  EXPECT_EQ(id1, (*popups.begin())->id());

  // The notifications in the NotificationCenter are unaffected by popups shown.
  NotificationList::Notifications notifications =
      notification_list_->GetVisibleNotifications(blockers_);
  auto iter = notifications.begin();
  EXPECT_EQ(id3, (*iter)->id());
  iter++;
  EXPECT_EQ(id2, (*iter)->id());
  iter++;
  EXPECT_EQ(id1, (*iter)->id());
}

TEST_F(NotificationListTest, UpdateAfterMarkedAsShown) {
  std::string id1 = AddNotification();
  std::string id2 = AddNotification();
  notification_list_->MarkSinglePopupAsDisplayed(id1);
  notification_list_->MarkSinglePopupAsDisplayed(id2);

  EXPECT_EQ(2u, GetPopupCounts());

  NotificationState n1_state = GetNotificationState(id1);
  EXPECT_FALSE(n1_state.shown_as_popup);
  EXPECT_TRUE(n1_state.is_read);

  notification_list_->MarkSinglePopupAsShown(id1, true);

  n1_state = GetNotificationState(id1);
  EXPECT_TRUE(n1_state.shown_as_popup);
  EXPECT_TRUE(n1_state.is_read);

  const std::string replaced("test-replaced-id");
  std::unique_ptr<Notification> notification(new Notification(
      NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
      UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
      NotifierId(NotifierType::APPLICATION, kExtensionId),
      RichNotificationData(), NULL));
  notification_list_->UpdateNotificationMessage(id1, std::move(notification));
  Notification* n1 = GetNotification(id1);
  EXPECT_TRUE(n1 == NULL);
  const NotificationState nr_state = GetNotificationState(replaced);
  EXPECT_TRUE(nr_state.shown_as_popup);
  EXPECT_TRUE(nr_state.is_read);
}

TEST_F(NotificationListTest, QuietMode) {
  notification_list_->SetQuietMode(true);
  AddNotification();
  AddPriorityNotification(HIGH_PRIORITY);
  AddPriorityNotification(MAX_PRIORITY);
  EXPECT_EQ(3u, notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(0u, GetPopupCounts());

  notification_list_->SetQuietMode(false);
  AddNotification();
  EXPECT_EQ(4u, notification_list_->NotificationCount(blockers_));
  EXPECT_EQ(1u, GetPopupCounts());

  // TODO(mukai): Add test of quiet mode with expiration.
}

TEST_F(NotificationListTest, TestHasNotificationOfType) {
  std::string id = AddNotification();

  EXPECT_TRUE(
      notification_list_->HasNotificationOfType(id, NOTIFICATION_TYPE_SIMPLE));
  EXPECT_FALSE(notification_list_->HasNotificationOfType(
      id, NOTIFICATION_TYPE_PROGRESS));

  std::unique_ptr<Notification> updated_notification(
      new Notification(NOTIFICATION_TYPE_PROGRESS, id, UTF8ToUTF16("updated"),
                       UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
                       GURL(), NotifierId(), RichNotificationData(), NULL));
  notification_list_->AddNotification(std::move(updated_notification));

  EXPECT_FALSE(
      notification_list_->HasNotificationOfType(id, NOTIFICATION_TYPE_SIMPLE));
  EXPECT_TRUE(notification_list_->HasNotificationOfType(
      id, NOTIFICATION_TYPE_PROGRESS));
}

}  // namespace message_center
