github.com/status-im/status-go@v1.1.0/protocol/messenger_unread_test.go (about) 1 package protocol 2 3 import ( 4 "context" 5 "errors" 6 7 _ "github.com/mutecomm/go-sqlcipher/v4" // require go-sqlcipher that overrides default implementation 8 9 "github.com/status-im/status-go/protocol/common" 10 "github.com/status-im/status-go/protocol/protobuf" 11 "github.com/status-im/status-go/protocol/requests" 12 "github.com/status-im/status-go/protocol/tt" 13 ) 14 15 func (s *MessengerSuite) checkMessageSeen(messageID string, expectedSeen bool) { 16 message, err := s.m.MessageByID(messageID) 17 18 s.Require().NoError(err) 19 s.Require().Equal(expectedSeen, message.Seen) 20 } 21 22 func (s *MessengerSuite) retrieveAllWithRetry(errorMessage string) (*MessengerResponse, error) { 23 var response *MessengerResponse 24 var err error 25 26 retryFunc := func() error { 27 response, err = s.m.RetrieveAll() 28 if err != nil { 29 return err 30 } 31 if len(response.messages) == 0 { 32 return errors.New(errorMessage) 33 } 34 return nil 35 } 36 37 err = tt.RetryWithBackOff(retryFunc) 38 return response, err 39 } 40 41 func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageListContainsSingleMessage() { 42 chat := CreatePublicChat("test-chat-1", s.m.transport) 43 44 chat.UnviewedMessagesCount = 2 45 chat.UnviewedMentionsCount = 2 46 chat.Highlight = true 47 48 err := s.m.SaveChat(chat) 49 s.Require().NoError(err) 50 51 inputMessage1 := buildTestMessage(*chat) 52 inputMessage1.ID = "1" 53 inputMessage1.Seen = true 54 inputMessage1.Mentioned = true 55 56 err = s.m.SaveMessages([]*common.Message{inputMessage1}) 57 s.Require().NoError(err) 58 59 _, err = s.m.MarkAllRead(context.Background(), chat.ID) 60 s.Require().NoError(err) 61 62 chats := s.m.allChats 63 64 actualChat, ok := chats.Load(chat.ID) 65 66 s.Require().True(ok) 67 s.Require().Equal(uint(0), actualChat.UnviewedMessagesCount) 68 s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount) 69 s.Require().False(actualChat.Highlight) 70 s.checkMessageSeen(inputMessage1.ID, true) 71 72 response, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID) 73 s.Require().NoError(err) 74 s.Require().Len(response.GetSeenAndUnseenMessages(), 1) 75 s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID) 76 s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].Count) 77 s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].CountWithMentions) 78 s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen) 79 s.Require().Len(response.ActivityCenterNotifications(), 0) 80 81 chats = s.m.allChats 82 83 actualChat, ok = chats.Load(chat.ID) 84 s.Require().True(ok) 85 s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount) 86 s.Require().Equal(uint(1), actualChat.UnviewedMentionsCount) 87 s.Require().False(actualChat.Highlight) 88 s.checkMessageSeen(inputMessage1.ID, false) 89 } 90 91 func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageListContainsSeveralMessages() { 92 chat := CreatePublicChat("test-chat-2", s.m.transport) 93 94 chat.UnviewedMessagesCount = 0 95 chat.UnviewedMentionsCount = 0 96 chat.Highlight = true 97 98 err := s.m.SaveChat(chat) 99 s.Require().NoError(err) 100 101 inputMessage1 := buildTestMessage(*chat) 102 inputMessage1.ID = "1" 103 inputMessage1.Seen = true 104 inputMessage1.Mentioned = true 105 inputMessage1.Timestamp = 1 106 107 inputMessage2 := buildTestMessage(*chat) 108 inputMessage2.ID = "2" 109 inputMessage2.Seen = true 110 inputMessage2.Mentioned = false 111 inputMessage2.Timestamp = 2 112 113 inputMessage3 := buildTestMessage(*chat) 114 inputMessage3.ID = "3" 115 inputMessage3.Seen = true 116 inputMessage3.Mentioned = false 117 inputMessage3.Timestamp = 3 118 119 err = s.m.SaveMessages([]*common.Message{ 120 inputMessage1, 121 inputMessage2, 122 inputMessage3, 123 }) 124 s.Require().NoError(err) 125 126 _, err = s.m.MarkAllRead(context.Background(), chat.ID) 127 s.Require().NoError(err) 128 129 chats := s.m.allChats 130 actualChat, ok := chats.Load(chat.ID) 131 132 s.Require().True(ok) 133 s.Require().Equal(uint(0), actualChat.UnviewedMessagesCount) 134 s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount) 135 s.Require().False(actualChat.Highlight) 136 s.checkMessageSeen(inputMessage1.ID, true) 137 s.checkMessageSeen(inputMessage2.ID, true) 138 s.checkMessageSeen(inputMessage3.ID, true) 139 140 response, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage2.ID) 141 s.Require().NoError(err) 142 143 // count is 2 because the messages are layout the following way : 144 // 145 // inputMessage1 read <-- mentioned 146 // ----------------------------- <-- marker 147 // inputMessage2 unread 148 // inputMessage3 unread 149 // 150 // And the inputMessage3 has greater timestamp than inputMessage2 151 // Similarly, the mentioned message is inputMessage1, therefore the 152 // countWithMentions is 0 153 s.Require().Len(response.GetSeenAndUnseenMessages(), 1) 154 s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID) 155 s.Require().Equal(uint64(2), response.GetSeenAndUnseenMessages()[0].Count) 156 s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].CountWithMentions) 157 s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen) 158 159 chats = s.m.allChats 160 actualChat, ok = chats.Load(chat.ID) 161 162 s.Require().True(ok) 163 s.Require().Equal(uint(2), actualChat.UnviewedMessagesCount) 164 s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount) 165 s.Require().False(actualChat.Highlight) 166 s.checkMessageSeen(inputMessage1.ID, true) 167 s.checkMessageSeen(inputMessage2.ID, false) 168 s.checkMessageSeen(inputMessage3.ID, false) 169 } 170 171 func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageIsAlreadyInUnreadState() { 172 chat := CreatePublicChat("test-chat-3", s.m.transport) 173 174 chat.UnviewedMessagesCount = 1 175 chat.UnviewedMentionsCount = 0 176 chat.Highlight = true 177 178 err := s.m.SaveChat(chat) 179 s.Require().NoError(err) 180 181 inputMessage1 := buildTestMessage(*chat) 182 inputMessage1.ID = "1" 183 inputMessage1.Seen = false 184 inputMessage1.Mentioned = false 185 186 err = s.m.SaveMessages([]*common.Message{inputMessage1}) 187 s.Require().NoError(err) 188 189 chats := s.m.allChats 190 actualChat, ok := chats.Load(chat.ID) 191 192 s.Require().True(ok) 193 s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount) 194 s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount) 195 s.Require().True(actualChat.Highlight) 196 s.checkMessageSeen(inputMessage1.ID, false) 197 198 response, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID) 199 s.Require().NoError(err) 200 s.Require().Len(response.GetSeenAndUnseenMessages(), 1) 201 s.Require().Equal(chat.ID, response.GetSeenAndUnseenMessages()[0].ChatID) 202 s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].Count) 203 s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].CountWithMentions) 204 s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen) 205 206 chats = s.m.allChats 207 actualChat, ok = chats.Load(chat.ID) 208 209 s.Require().True(ok) 210 s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount) 211 s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount) 212 s.Require().False(actualChat.Highlight) 213 s.checkMessageSeen(inputMessage1.ID, false) 214 } 215 216 func (s *MessengerSuite) TestMarkMessageAsUnreadInOneChatDoesNotImpactOtherChats() { 217 chat1 := CreatePublicChat("test-chat-1", s.m.transport) 218 err := s.m.SaveChat(chat1) 219 s.Require().NoError(err) 220 221 chat2 := CreatePublicChat("test-chat-2", s.m.transport) 222 err = s.m.SaveChat(chat2) 223 s.Require().NoError(err) 224 225 chat1.UnviewedMessagesCount = 2 226 chat1.UnviewedMentionsCount = 0 227 chat1.Highlight = true 228 229 inputMessage1 := buildTestMessage(*chat1) 230 inputMessage1.ID = "1" 231 inputMessage1.Seen = true 232 inputMessage1.Mentioned = false 233 234 inputMessage2 := buildTestMessage(*chat1) 235 inputMessage2.ID = "2" 236 inputMessage2.Seen = true 237 inputMessage2.Mentioned = false 238 239 err = s.m.SaveMessages([]*common.Message{inputMessage1, inputMessage2}) 240 s.Require().NoError(err) 241 242 chat2.UnviewedMessagesCount = 1 243 chat2.UnviewedMentionsCount = 0 244 chat2.Highlight = true 245 246 inputMessage3 := buildTestMessage(*chat2) 247 inputMessage3.ID = "3" 248 inputMessage3.Seen = false 249 inputMessage3.Mentioned = false 250 251 err = s.m.SaveMessages([]*common.Message{inputMessage3}) 252 s.Require().NoError(err) 253 254 _, err = s.m.MarkAllRead(context.Background(), chat1.ID) 255 s.Require().NoError(err) 256 s.checkMessageSeen(inputMessage1.ID, true) 257 s.checkMessageSeen(inputMessage2.ID, true) 258 259 response, err := s.m.MarkMessageAsUnread(chat1.ID, inputMessage1.ID) 260 261 s.Require().NoError(err) 262 s.Require().Len(response.GetSeenAndUnseenMessages(), 1) 263 s.Require().Equal(chat1.ID, response.GetSeenAndUnseenMessages()[0].ChatID) 264 s.Require().Equal(uint64(2), response.GetSeenAndUnseenMessages()[0].Count) 265 s.Require().Equal(uint64(0), response.GetSeenAndUnseenMessages()[0].CountWithMentions) 266 s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen) 267 s.Require().Len(response.ActivityCenterNotifications(), 0) 268 269 chats := s.m.allChats 270 actualChat, ok := chats.Load(chat1.ID) 271 272 s.Require().True(ok) 273 s.Require().Equal(uint(2), actualChat.UnviewedMessagesCount) 274 s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount) 275 s.Require().False(actualChat.Highlight) 276 s.checkMessageSeen(inputMessage1.ID, false) 277 s.checkMessageSeen(inputMessage2.ID, false) 278 279 actualChat, ok = chats.Load(chat2.ID) 280 s.Require().True(ok) 281 s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount) 282 s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount) 283 s.Require().True(actualChat.Highlight) 284 285 s.checkMessageSeen(inputMessage3.ID, false) 286 } 287 288 func (s *MessengerSuite) TestMarkMessageWithNotificationAsUnreadInCommunityChatSetsNotificationAsUnread() { 289 other := s.newMessenger() 290 291 description := &requests.CreateCommunity{ 292 Membership: protobuf.CommunityPermissions_AUTO_ACCEPT, 293 Name: "status", 294 Color: "#ffffff", 295 Description: "This is just a test description for the community", 296 } 297 298 response, err := other.CreateCommunity(description, true) 299 s.Require().NoError(err) 300 s.Require().NotNil(response) 301 s.Require().Len(response.Communities(), 1) 302 303 community := response.Communities()[0] 304 communityChat := response.Chats()[0] 305 306 _, err = community.AddMember(&s.m.identity.PublicKey, []protobuf.CommunityMember_Roles{}, community.Clock()) 307 s.Require().NoError(err) 308 309 err = other.communitiesManager.SaveCommunity(community) 310 s.Require().NoError(err) 311 312 advertiseCommunityToUserOldWay(&s.Suite, community, other, s.m) 313 314 inputMessage1 := buildTestMessage(*communityChat) 315 inputMessage1.ChatId = communityChat.ID 316 inputMessage1.ContentType = protobuf.ChatMessage_TEXT_PLAIN 317 inputMessage1.Text = "Hello @" + common.EveryoneMentionTag + " !" 318 319 sendResponse, err := other.SendChatMessage(context.Background(), inputMessage1) 320 s.NoError(err) 321 s.Require().Len(sendResponse.Messages(), 1) 322 323 response, err = s.retrieveAllWithRetry("message from other chatter not received") 324 325 s.Require().NoError(err) 326 s.Require().Len(response.Chats(), 1) 327 s.Require().Len(response.Messages(), 1) 328 s.Require().Len(response.ActivityCenterNotifications(), 1) 329 s.Require().False(response.ActivityCenterNotifications()[0].Read) 330 331 response, err = s.m.MarkAllRead(context.Background(), communityChat.ID) 332 333 s.Require().NoError(err) 334 s.Require().Len(response.ActivityCenterNotifications(), 1) 335 s.Require().True(response.ActivityCenterNotifications()[0].Read) 336 337 response, err = s.m.MarkMessageAsUnread(communityChat.ID, inputMessage1.ID) 338 339 s.Require().NoError(err) 340 s.Require().Len(response.GetSeenAndUnseenMessages(), 1) 341 s.Require().Equal(communityChat.ID, response.GetSeenAndUnseenMessages()[0].ChatID) 342 s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].Count) 343 s.Require().Equal(uint64(1), response.GetSeenAndUnseenMessages()[0].CountWithMentions) 344 s.Require().Equal(false, response.GetSeenAndUnseenMessages()[0].Seen) 345 s.Require().Len(response.ActivityCenterNotifications(), 1) 346 s.Require().False(response.ActivityCenterNotifications()[0].Read) 347 }