123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- // Copyright 2020 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 "ash/components/phonehub/notification_manager_impl.h"
- #include <memory>
- #include "ash/components/phonehub/fake_message_sender.h"
- #include "ash/components/phonehub/fake_user_action_recorder.h"
- #include "ash/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
- #include "base/containers/flat_map.h"
- #include "base/strings/utf_string_conversions.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace ash {
- namespace phonehub {
- namespace {
- using multidevice_setup::mojom::Feature;
- using multidevice_setup::mojom::FeatureState;
- const char16_t kAppName[] = u"Test App";
- const char kPackageName[] = "com.google.testapp";
- const int64_t kUserId = 1;
- const char16_t kTitle[] = u"Test notification";
- const char16_t kTextContent[] = u"This is a test notification";
- enum class NotificationState { kAdded, kUpdated, kRemoved };
- Notification CreateNotification(int64_t id) {
- return phonehub::Notification(
- id,
- phonehub::Notification::AppMetadata(kAppName, kPackageName,
- /*icon=*/gfx::Image(),
- /*icon_color=*/absl::nullopt,
- /*icon_is_monochrome=*/true, kUserId),
- base::Time::Now(), Notification::Importance::kDefault,
- Notification::Category::kConversation,
- {{Notification::ActionType::kInlineReply, /*action_id=*/0}},
- Notification::InteractionBehavior::kNone, kTitle, kTextContent);
- }
- class FakeObserver : public NotificationManager::Observer {
- public:
- FakeObserver() = default;
- ~FakeObserver() override = default;
- absl::optional<NotificationState> GetState(int64_t notification_id) const {
- const auto it = id_to_state_map_.find(notification_id);
- if (it == id_to_state_map_.end())
- return absl::nullopt;
- return it->second;
- }
- private:
- // NotificationManager::Observer:
- void OnNotificationsAdded(
- const base::flat_set<int64_t>& notification_ids) override {
- for (int64_t id : notification_ids)
- id_to_state_map_[id] = NotificationState::kAdded;
- }
- void OnNotificationsUpdated(
- const base::flat_set<int64_t>& notification_ids) override {
- for (int64_t id : notification_ids)
- id_to_state_map_[id] = NotificationState::kUpdated;
- }
- void OnNotificationsRemoved(
- const base::flat_set<int64_t>& notification_ids) override {
- for (int64_t id : notification_ids)
- id_to_state_map_[id] = NotificationState::kRemoved;
- }
- base::flat_map<int64_t, NotificationState> id_to_state_map_;
- };
- } // namespace
- class NotificationManagerImplTest : public testing::Test {
- protected:
- NotificationManagerImplTest() = default;
- NotificationManagerImplTest(const NotificationManagerImplTest&) = delete;
- NotificationManagerImplTest& operator=(const NotificationManagerImplTest&) =
- delete;
- ~NotificationManagerImplTest() override = default;
- // testing::Test:
- void SetUp() override {
- manager_ = std::make_unique<NotificationManagerImpl>(
- &fake_message_sender_, &fake_user_action_recorder_,
- &fake_multidevice_setup_client_);
- manager_->AddObserver(&fake_observer_);
- }
- void TearDown() override { manager_->RemoveObserver(&fake_observer_); }
- NotificationManager& manager() { return *manager_; }
- FakeMessageSender& fake_message_sender() { return fake_message_sender_; }
- void SetNotificationsInternal(
- const base::flat_set<Notification>& notifications) {
- manager_->SetNotificationsInternal(notifications);
- }
- void ClearNotificationsInternal() { manager_->ClearNotificationsInternal(); }
- size_t GetNumNotifications() {
- return manager_->id_to_notification_map_.size();
- }
- absl::optional<NotificationState> GetNotificationState(
- int64_t notification_id) {
- return fake_observer_.GetState(notification_id);
- }
- void SetNotificationFeatureStatus(FeatureState feature_state) {
- fake_multidevice_setup_client_.SetFeatureState(
- Feature::kPhoneHubNotifications, feature_state);
- }
- FakeUserActionRecorder fake_user_action_recorder_;
- private:
- FakeObserver fake_observer_;
- FakeMessageSender fake_message_sender_;
- multidevice_setup::FakeMultiDeviceSetupClient fake_multidevice_setup_client_;
- std::unique_ptr<NotificationManager> manager_;
- };
- TEST_F(NotificationManagerImplTest, SetAndClearNotificationsInternal) {
- EXPECT_EQ(0u, GetNumNotifications());
- const int64_t expected_id1 = 0;
- const int64_t expected_id2 = 1;
- SetNotificationsInternal(base::flat_set<Notification>{
- CreateNotification(expected_id1), CreateNotification(expected_id2)});
- EXPECT_EQ(2u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
- ClearNotificationsInternal();
- EXPECT_EQ(0u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id1));
- EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id2));
- }
- TEST_F(NotificationManagerImplTest, GetNotification) {
- EXPECT_EQ(0u, GetNumNotifications());
- const int64_t expected_id1 = 0;
- SetNotificationsInternal(
- base::flat_set<Notification>{CreateNotification(expected_id1)});
- EXPECT_EQ(1u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- // Call GetNotification() on an existent notification id. Expect a non-null
- // pointer.
- EXPECT_TRUE(manager().GetNotification(expected_id1));
- // Call GetNotification() on a non-existent notification id. Expect a null
- // pointer.
- EXPECT_FALSE(manager().GetNotification(/*notification_id=*/4));
- // Remove |expected_id1| and expect that GetNotification() returns a null
- // pointer.
- manager().DismissNotification(expected_id1);
- EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount());
- EXPECT_EQ(expected_id1,
- fake_message_sender().GetRecentDismissNotificationRequest());
- EXPECT_FALSE(manager().GetNotification(expected_id1));
- }
- TEST_F(NotificationManagerImplTest, DismissNotifications) {
- EXPECT_EQ(0u, GetNumNotifications());
- const int64_t expected_id1 = 0;
- const int64_t expected_id2 = 1;
- SetNotificationsInternal(base::flat_set<Notification>{
- CreateNotification(expected_id1), CreateNotification(expected_id2)});
- EXPECT_EQ(2u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
- manager().DismissNotification(expected_id2);
- EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_dismissals());
- EXPECT_EQ(1u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id2));
- EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount());
- EXPECT_EQ(expected_id2,
- fake_message_sender().GetRecentDismissNotificationRequest());
- // Dismiss the same notification again, verify nothing happens.
- manager().DismissNotification(expected_id2);
- EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_dismissals());
- EXPECT_EQ(1u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id2));
- EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount());
- EXPECT_EQ(expected_id2,
- fake_message_sender().GetRecentDismissNotificationRequest());
- }
- TEST_F(NotificationManagerImplTest, UpdatedNotification) {
- EXPECT_EQ(0u, GetNumNotifications());
- const int64_t expected_id1 = 0;
- const int64_t expected_id2 = 1;
- SetNotificationsInternal(base::flat_set<Notification>{
- CreateNotification(expected_id1), CreateNotification(expected_id2)});
- EXPECT_EQ(2u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
- // Simulate updating a notification.
- SetNotificationsInternal(
- base::flat_set<Notification>{CreateNotification(expected_id1)});
- EXPECT_EQ(2u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kUpdated, GetNotificationState(expected_id1));
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
- }
- TEST_F(NotificationManagerImplTest, SendInlineReply) {
- EXPECT_EQ(0u, GetNumNotifications());
- const int64_t expected_id1 = 0;
- SetNotificationsInternal(
- base::flat_set<Notification>{CreateNotification(expected_id1)});
- EXPECT_EQ(1u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- // Simulate sending an inline reply to a notification.
- const std::u16string& expected_reply(u"test reply");
- manager().SendInlineReply(expected_id1, expected_reply);
- EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_replies());
- EXPECT_EQ(1u, GetNumNotifications());
- EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
- EXPECT_EQ(1u,
- fake_message_sender().GetNotificationInlineReplyRequestCallCount());
- std::pair<int64_t, std::u16string> pair =
- fake_message_sender().GetRecentNotificationInlineReplyRequest();
- EXPECT_EQ(expected_id1, pair.first);
- EXPECT_EQ(expected_reply, pair.second);
- // Simulate sending an inline reply to a non-existent notification. Expect
- // that no new reply calls were called and that the most recent reply is the
- // same as the previous inline reply call.
- manager().SendInlineReply(/*notification_id=*/5, /*reply=*/std::u16string());
- EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_replies());
- EXPECT_EQ(1u,
- fake_message_sender().GetNotificationInlineReplyRequestCallCount());
- pair = fake_message_sender().GetRecentNotificationInlineReplyRequest();
- EXPECT_EQ(expected_id1, pair.first);
- EXPECT_EQ(expected_reply, pair.second);
- }
- TEST_F(NotificationManagerImplTest, ClearNotificationsOnFeatureStatusChanged) {
- // Simulate enabling notification feature state.
- SetNotificationFeatureStatus(FeatureState::kEnabledByUser);
- // Set an internal notification.
- SetNotificationsInternal(
- base::flat_set<Notification>{CreateNotification(/*notification_id=*/1)});
- EXPECT_EQ(1u, GetNumNotifications());
- // Change notification feature state to disabled, expect internal
- // notifications to be cleared.
- SetNotificationFeatureStatus(FeatureState::kDisabledByUser);
- EXPECT_EQ(0u, GetNumNotifications());
- }
- } // namespace phonehub
- } // namespace ash
|