notification_manager_impl_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. // Copyright 2020 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.
  4. #include "ash/components/phonehub/notification_manager_impl.h"
  5. #include <memory>
  6. #include "ash/components/phonehub/fake_message_sender.h"
  7. #include "ash/components/phonehub/fake_user_action_recorder.h"
  8. #include "ash/services/multidevice_setup/public/cpp/fake_multidevice_setup_client.h"
  9. #include "base/containers/flat_map.h"
  10. #include "base/strings/utf_string_conversions.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. namespace ash {
  14. namespace phonehub {
  15. namespace {
  16. using multidevice_setup::mojom::Feature;
  17. using multidevice_setup::mojom::FeatureState;
  18. const char16_t kAppName[] = u"Test App";
  19. const char kPackageName[] = "com.google.testapp";
  20. const int64_t kUserId = 1;
  21. const char16_t kTitle[] = u"Test notification";
  22. const char16_t kTextContent[] = u"This is a test notification";
  23. enum class NotificationState { kAdded, kUpdated, kRemoved };
  24. Notification CreateNotification(int64_t id) {
  25. return phonehub::Notification(
  26. id,
  27. phonehub::Notification::AppMetadata(kAppName, kPackageName,
  28. /*icon=*/gfx::Image(),
  29. /*icon_color=*/absl::nullopt,
  30. /*icon_is_monochrome=*/true, kUserId),
  31. base::Time::Now(), Notification::Importance::kDefault,
  32. Notification::Category::kConversation,
  33. {{Notification::ActionType::kInlineReply, /*action_id=*/0}},
  34. Notification::InteractionBehavior::kNone, kTitle, kTextContent);
  35. }
  36. class FakeObserver : public NotificationManager::Observer {
  37. public:
  38. FakeObserver() = default;
  39. ~FakeObserver() override = default;
  40. absl::optional<NotificationState> GetState(int64_t notification_id) const {
  41. const auto it = id_to_state_map_.find(notification_id);
  42. if (it == id_to_state_map_.end())
  43. return absl::nullopt;
  44. return it->second;
  45. }
  46. private:
  47. // NotificationManager::Observer:
  48. void OnNotificationsAdded(
  49. const base::flat_set<int64_t>& notification_ids) override {
  50. for (int64_t id : notification_ids)
  51. id_to_state_map_[id] = NotificationState::kAdded;
  52. }
  53. void OnNotificationsUpdated(
  54. const base::flat_set<int64_t>& notification_ids) override {
  55. for (int64_t id : notification_ids)
  56. id_to_state_map_[id] = NotificationState::kUpdated;
  57. }
  58. void OnNotificationsRemoved(
  59. const base::flat_set<int64_t>& notification_ids) override {
  60. for (int64_t id : notification_ids)
  61. id_to_state_map_[id] = NotificationState::kRemoved;
  62. }
  63. base::flat_map<int64_t, NotificationState> id_to_state_map_;
  64. };
  65. } // namespace
  66. class NotificationManagerImplTest : public testing::Test {
  67. protected:
  68. NotificationManagerImplTest() = default;
  69. NotificationManagerImplTest(const NotificationManagerImplTest&) = delete;
  70. NotificationManagerImplTest& operator=(const NotificationManagerImplTest&) =
  71. delete;
  72. ~NotificationManagerImplTest() override = default;
  73. // testing::Test:
  74. void SetUp() override {
  75. manager_ = std::make_unique<NotificationManagerImpl>(
  76. &fake_message_sender_, &fake_user_action_recorder_,
  77. &fake_multidevice_setup_client_);
  78. manager_->AddObserver(&fake_observer_);
  79. }
  80. void TearDown() override { manager_->RemoveObserver(&fake_observer_); }
  81. NotificationManager& manager() { return *manager_; }
  82. FakeMessageSender& fake_message_sender() { return fake_message_sender_; }
  83. void SetNotificationsInternal(
  84. const base::flat_set<Notification>& notifications) {
  85. manager_->SetNotificationsInternal(notifications);
  86. }
  87. void ClearNotificationsInternal() { manager_->ClearNotificationsInternal(); }
  88. size_t GetNumNotifications() {
  89. return manager_->id_to_notification_map_.size();
  90. }
  91. absl::optional<NotificationState> GetNotificationState(
  92. int64_t notification_id) {
  93. return fake_observer_.GetState(notification_id);
  94. }
  95. void SetNotificationFeatureStatus(FeatureState feature_state) {
  96. fake_multidevice_setup_client_.SetFeatureState(
  97. Feature::kPhoneHubNotifications, feature_state);
  98. }
  99. FakeUserActionRecorder fake_user_action_recorder_;
  100. private:
  101. FakeObserver fake_observer_;
  102. FakeMessageSender fake_message_sender_;
  103. multidevice_setup::FakeMultiDeviceSetupClient fake_multidevice_setup_client_;
  104. std::unique_ptr<NotificationManager> manager_;
  105. };
  106. TEST_F(NotificationManagerImplTest, SetAndClearNotificationsInternal) {
  107. EXPECT_EQ(0u, GetNumNotifications());
  108. const int64_t expected_id1 = 0;
  109. const int64_t expected_id2 = 1;
  110. SetNotificationsInternal(base::flat_set<Notification>{
  111. CreateNotification(expected_id1), CreateNotification(expected_id2)});
  112. EXPECT_EQ(2u, GetNumNotifications());
  113. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  114. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
  115. ClearNotificationsInternal();
  116. EXPECT_EQ(0u, GetNumNotifications());
  117. EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id1));
  118. EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id2));
  119. }
  120. TEST_F(NotificationManagerImplTest, GetNotification) {
  121. EXPECT_EQ(0u, GetNumNotifications());
  122. const int64_t expected_id1 = 0;
  123. SetNotificationsInternal(
  124. base::flat_set<Notification>{CreateNotification(expected_id1)});
  125. EXPECT_EQ(1u, GetNumNotifications());
  126. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  127. // Call GetNotification() on an existent notification id. Expect a non-null
  128. // pointer.
  129. EXPECT_TRUE(manager().GetNotification(expected_id1));
  130. // Call GetNotification() on a non-existent notification id. Expect a null
  131. // pointer.
  132. EXPECT_FALSE(manager().GetNotification(/*notification_id=*/4));
  133. // Remove |expected_id1| and expect that GetNotification() returns a null
  134. // pointer.
  135. manager().DismissNotification(expected_id1);
  136. EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount());
  137. EXPECT_EQ(expected_id1,
  138. fake_message_sender().GetRecentDismissNotificationRequest());
  139. EXPECT_FALSE(manager().GetNotification(expected_id1));
  140. }
  141. TEST_F(NotificationManagerImplTest, DismissNotifications) {
  142. EXPECT_EQ(0u, GetNumNotifications());
  143. const int64_t expected_id1 = 0;
  144. const int64_t expected_id2 = 1;
  145. SetNotificationsInternal(base::flat_set<Notification>{
  146. CreateNotification(expected_id1), CreateNotification(expected_id2)});
  147. EXPECT_EQ(2u, GetNumNotifications());
  148. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  149. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
  150. manager().DismissNotification(expected_id2);
  151. EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_dismissals());
  152. EXPECT_EQ(1u, GetNumNotifications());
  153. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  154. EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id2));
  155. EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount());
  156. EXPECT_EQ(expected_id2,
  157. fake_message_sender().GetRecentDismissNotificationRequest());
  158. // Dismiss the same notification again, verify nothing happens.
  159. manager().DismissNotification(expected_id2);
  160. EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_dismissals());
  161. EXPECT_EQ(1u, GetNumNotifications());
  162. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  163. EXPECT_EQ(NotificationState::kRemoved, GetNotificationState(expected_id2));
  164. EXPECT_EQ(1u, fake_message_sender().GetDismissNotificationRequestCallCount());
  165. EXPECT_EQ(expected_id2,
  166. fake_message_sender().GetRecentDismissNotificationRequest());
  167. }
  168. TEST_F(NotificationManagerImplTest, UpdatedNotification) {
  169. EXPECT_EQ(0u, GetNumNotifications());
  170. const int64_t expected_id1 = 0;
  171. const int64_t expected_id2 = 1;
  172. SetNotificationsInternal(base::flat_set<Notification>{
  173. CreateNotification(expected_id1), CreateNotification(expected_id2)});
  174. EXPECT_EQ(2u, GetNumNotifications());
  175. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  176. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
  177. // Simulate updating a notification.
  178. SetNotificationsInternal(
  179. base::flat_set<Notification>{CreateNotification(expected_id1)});
  180. EXPECT_EQ(2u, GetNumNotifications());
  181. EXPECT_EQ(NotificationState::kUpdated, GetNotificationState(expected_id1));
  182. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id2));
  183. }
  184. TEST_F(NotificationManagerImplTest, SendInlineReply) {
  185. EXPECT_EQ(0u, GetNumNotifications());
  186. const int64_t expected_id1 = 0;
  187. SetNotificationsInternal(
  188. base::flat_set<Notification>{CreateNotification(expected_id1)});
  189. EXPECT_EQ(1u, GetNumNotifications());
  190. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  191. // Simulate sending an inline reply to a notification.
  192. const std::u16string& expected_reply(u"test reply");
  193. manager().SendInlineReply(expected_id1, expected_reply);
  194. EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_replies());
  195. EXPECT_EQ(1u, GetNumNotifications());
  196. EXPECT_EQ(NotificationState::kAdded, GetNotificationState(expected_id1));
  197. EXPECT_EQ(1u,
  198. fake_message_sender().GetNotificationInlineReplyRequestCallCount());
  199. std::pair<int64_t, std::u16string> pair =
  200. fake_message_sender().GetRecentNotificationInlineReplyRequest();
  201. EXPECT_EQ(expected_id1, pair.first);
  202. EXPECT_EQ(expected_reply, pair.second);
  203. // Simulate sending an inline reply to a non-existent notification. Expect
  204. // that no new reply calls were called and that the most recent reply is the
  205. // same as the previous inline reply call.
  206. manager().SendInlineReply(/*notification_id=*/5, /*reply=*/std::u16string());
  207. EXPECT_EQ(1u, fake_user_action_recorder_.num_notification_replies());
  208. EXPECT_EQ(1u,
  209. fake_message_sender().GetNotificationInlineReplyRequestCallCount());
  210. pair = fake_message_sender().GetRecentNotificationInlineReplyRequest();
  211. EXPECT_EQ(expected_id1, pair.first);
  212. EXPECT_EQ(expected_reply, pair.second);
  213. }
  214. TEST_F(NotificationManagerImplTest, ClearNotificationsOnFeatureStatusChanged) {
  215. // Simulate enabling notification feature state.
  216. SetNotificationFeatureStatus(FeatureState::kEnabledByUser);
  217. // Set an internal notification.
  218. SetNotificationsInternal(
  219. base::flat_set<Notification>{CreateNotification(/*notification_id=*/1)});
  220. EXPECT_EQ(1u, GetNumNotifications());
  221. // Change notification feature state to disabled, expect internal
  222. // notifications to be cleared.
  223. SetNotificationFeatureStatus(FeatureState::kDisabledByUser);
  224. EXPECT_EQ(0u, GetNumNotifications());
  225. }
  226. } // namespace phonehub
  227. } // namespace ash