2023-12-11 08:17:01 +00:00
|
|
|
package protocol
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
_ "github.com/mutecomm/go-sqlcipher/v4" // require go-sqlcipher that overrides default implementation
|
|
|
|
|
|
|
|
"github.com/status-im/status-go/protocol/common"
|
|
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
|
|
|
"github.com/status-im/status-go/protocol/requests"
|
|
|
|
"github.com/status-im/status-go/protocol/tt"
|
|
|
|
)
|
|
|
|
|
|
|
|
func (s *MessengerSuite) checkMessageSeen(messageID string, expectedSeen bool) {
|
|
|
|
message, err := s.m.MessageByID(messageID)
|
|
|
|
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(expectedSeen, message.Seen)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerSuite) retrieveAllWithRetry(errorMessage string) (*MessengerResponse, error) {
|
|
|
|
var response *MessengerResponse
|
|
|
|
var err error
|
|
|
|
|
|
|
|
retryFunc := func() error {
|
|
|
|
response, err = s.m.RetrieveAll()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if len(response.messages) == 0 {
|
|
|
|
return errors.New(errorMessage)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tt.RetryWithBackOff(retryFunc)
|
|
|
|
return response, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageListContainsSingleMessage() {
|
|
|
|
chat := CreatePublicChat("test-chat-1", s.m.transport)
|
|
|
|
|
|
|
|
chat.UnviewedMessagesCount = 2
|
|
|
|
chat.UnviewedMentionsCount = 2
|
|
|
|
chat.Highlight = true
|
|
|
|
|
|
|
|
err := s.m.SaveChat(chat)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
inputMessage1 := buildTestMessage(*chat)
|
|
|
|
inputMessage1.ID = "1"
|
|
|
|
inputMessage1.Seen = true
|
|
|
|
inputMessage1.Mentioned = true
|
|
|
|
|
|
|
|
err = s.m.SaveMessages([]*common.Message{inputMessage1})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
_, err = s.m.MarkAllRead(context.Background(), chat.ID)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
chats := s.m.allChats
|
|
|
|
|
|
|
|
actualChat, ok := chats.Load(chat.ID)
|
|
|
|
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().False(actualChat.Highlight)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, true)
|
|
|
|
|
|
|
|
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(uint64(1), count)
|
|
|
|
s.Require().Equal(uint64(1), countWithMentions)
|
|
|
|
s.Require().Len(notifications, 0)
|
|
|
|
|
|
|
|
chats = s.m.allChats
|
|
|
|
|
|
|
|
actualChat, ok = chats.Load(chat.ID)
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(1), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().False(actualChat.Highlight)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageListContainsSeveralMessages() {
|
|
|
|
chat := CreatePublicChat("test-chat-2", s.m.transport)
|
|
|
|
|
|
|
|
chat.UnviewedMessagesCount = 0
|
|
|
|
chat.UnviewedMentionsCount = 0
|
|
|
|
chat.Highlight = true
|
|
|
|
|
|
|
|
err := s.m.SaveChat(chat)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
inputMessage1 := buildTestMessage(*chat)
|
|
|
|
inputMessage1.ID = "1"
|
|
|
|
inputMessage1.Seen = true
|
|
|
|
inputMessage1.Mentioned = true
|
|
|
|
inputMessage1.Timestamp = 1
|
|
|
|
|
|
|
|
inputMessage2 := buildTestMessage(*chat)
|
|
|
|
inputMessage2.ID = "2"
|
|
|
|
inputMessage2.Seen = true
|
|
|
|
inputMessage2.Mentioned = false
|
|
|
|
inputMessage2.Timestamp = 2
|
|
|
|
|
|
|
|
inputMessage3 := buildTestMessage(*chat)
|
|
|
|
inputMessage3.ID = "3"
|
|
|
|
inputMessage3.Seen = true
|
|
|
|
inputMessage3.Mentioned = false
|
|
|
|
inputMessage3.Timestamp = 3
|
|
|
|
|
|
|
|
err = s.m.SaveMessages([]*common.Message{
|
|
|
|
inputMessage1,
|
|
|
|
inputMessage2,
|
|
|
|
inputMessage3,
|
|
|
|
})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
_, err = s.m.MarkAllRead(context.Background(), chat.ID)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
chats := s.m.allChats
|
|
|
|
actualChat, ok := chats.Load(chat.ID)
|
|
|
|
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().False(actualChat.Highlight)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, true)
|
|
|
|
s.checkMessageSeen(inputMessage2.ID, true)
|
|
|
|
s.checkMessageSeen(inputMessage3.ID, true)
|
|
|
|
|
|
|
|
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage2.ID)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
// count is 2 because the messages are layout the following way :
|
|
|
|
//
|
|
|
|
// inputMessage1 read <-- mentioned
|
|
|
|
// ----------------------------- <-- marker
|
|
|
|
// inputMessage2 unread
|
|
|
|
// inputMessage3 unread
|
|
|
|
//
|
|
|
|
// And the inputMessage3 has greater timestamp than inputMessage2
|
|
|
|
// Similarly, the mentioned message is inputMessage1, therefore the
|
|
|
|
// countWithMentions is 0
|
|
|
|
s.Require().Equal(uint64(2), count)
|
|
|
|
s.Require().Equal(uint64(0), countWithMentions)
|
|
|
|
s.Require().Len(notifications, 0)
|
|
|
|
|
|
|
|
chats = s.m.allChats
|
|
|
|
actualChat, ok = chats.Load(chat.ID)
|
|
|
|
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(2), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().False(actualChat.Highlight)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, true)
|
|
|
|
s.checkMessageSeen(inputMessage2.ID, false)
|
|
|
|
s.checkMessageSeen(inputMessage3.ID, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerSuite) TestMarkMessageAsUnreadWhenMessageIsAlreadyInUnreadState() {
|
|
|
|
chat := CreatePublicChat("test-chat-3", s.m.transport)
|
|
|
|
|
|
|
|
chat.UnviewedMessagesCount = 1
|
|
|
|
chat.UnviewedMentionsCount = 0
|
|
|
|
chat.Highlight = true
|
|
|
|
|
|
|
|
err := s.m.SaveChat(chat)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
inputMessage1 := buildTestMessage(*chat)
|
|
|
|
inputMessage1.ID = "1"
|
|
|
|
inputMessage1.Seen = false
|
|
|
|
inputMessage1.Mentioned = false
|
|
|
|
|
|
|
|
err = s.m.SaveMessages([]*common.Message{inputMessage1})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
chats := s.m.allChats
|
|
|
|
actualChat, ok := chats.Load(chat.ID)
|
|
|
|
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().True(actualChat.Highlight)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, false)
|
|
|
|
|
|
|
|
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat.ID, inputMessage1.ID)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(uint64(1), count)
|
|
|
|
s.Require().Equal(uint64(0), countWithMentions)
|
|
|
|
s.Require().Len(notifications, 0)
|
|
|
|
|
|
|
|
chats = s.m.allChats
|
|
|
|
actualChat, ok = chats.Load(chat.ID)
|
|
|
|
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().False(actualChat.Highlight)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerSuite) TestMarkMessageAsUnreadInOneChatDoesNotImpactOtherChats() {
|
|
|
|
chat1 := CreatePublicChat("test-chat-1", s.m.transport)
|
|
|
|
err := s.m.SaveChat(chat1)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
chat2 := CreatePublicChat("test-chat-2", s.m.transport)
|
|
|
|
err = s.m.SaveChat(chat2)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
chat1.UnviewedMessagesCount = 2
|
|
|
|
chat1.UnviewedMentionsCount = 0
|
|
|
|
chat1.Highlight = true
|
|
|
|
|
|
|
|
inputMessage1 := buildTestMessage(*chat1)
|
|
|
|
inputMessage1.ID = "1"
|
|
|
|
inputMessage1.Seen = true
|
|
|
|
inputMessage1.Mentioned = false
|
|
|
|
|
|
|
|
inputMessage2 := buildTestMessage(*chat1)
|
|
|
|
inputMessage2.ID = "2"
|
|
|
|
inputMessage2.Seen = true
|
|
|
|
inputMessage2.Mentioned = false
|
|
|
|
|
|
|
|
err = s.m.SaveMessages([]*common.Message{inputMessage1, inputMessage2})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
chat2.UnviewedMessagesCount = 1
|
|
|
|
chat2.UnviewedMentionsCount = 0
|
|
|
|
chat2.Highlight = true
|
|
|
|
|
|
|
|
inputMessage3 := buildTestMessage(*chat2)
|
|
|
|
inputMessage3.ID = "3"
|
|
|
|
inputMessage3.Seen = false
|
|
|
|
inputMessage3.Mentioned = false
|
|
|
|
|
|
|
|
err = s.m.SaveMessages([]*common.Message{inputMessage3})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
_, err = s.m.MarkAllRead(context.Background(), chat1.ID)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, true)
|
|
|
|
s.checkMessageSeen(inputMessage2.ID, true)
|
|
|
|
|
|
|
|
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(chat1.ID, inputMessage1.ID)
|
|
|
|
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(uint(1), chat2.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint64(2), count)
|
|
|
|
s.Require().Equal(uint64(0), countWithMentions)
|
|
|
|
s.Require().Len(notifications, 0)
|
|
|
|
|
|
|
|
chats := s.m.allChats
|
|
|
|
actualChat, ok := chats.Load(chat1.ID)
|
|
|
|
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(2), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().False(actualChat.Highlight)
|
|
|
|
s.checkMessageSeen(inputMessage1.ID, false)
|
|
|
|
s.checkMessageSeen(inputMessage2.ID, false)
|
|
|
|
|
|
|
|
actualChat, ok = chats.Load(chat2.ID)
|
|
|
|
s.Require().True(ok)
|
|
|
|
s.Require().Equal(uint(1), actualChat.UnviewedMessagesCount)
|
|
|
|
s.Require().Equal(uint(0), actualChat.UnviewedMentionsCount)
|
|
|
|
s.Require().True(actualChat.Highlight)
|
|
|
|
|
|
|
|
s.checkMessageSeen(inputMessage3.ID, false)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerSuite) TestMarkMessageWithNotificationAsUnreadInCommunityChatSetsNotificationAsUnread() {
|
|
|
|
other := s.newMessenger()
|
|
|
|
|
|
|
|
description := &requests.CreateCommunity{
|
|
|
|
Membership: protobuf.CommunityPermissions_AUTO_ACCEPT,
|
|
|
|
Name: "status",
|
|
|
|
Color: "#ffffff",
|
|
|
|
Description: "This is just a test description for the community",
|
|
|
|
}
|
|
|
|
|
|
|
|
response, err := other.CreateCommunity(description, true)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().NotNil(response)
|
|
|
|
s.Require().Len(response.Communities(), 1)
|
|
|
|
|
|
|
|
community := response.Communities()[0]
|
|
|
|
communityChat := response.Chats()[0]
|
|
|
|
|
|
|
|
_, err = community.AddMember(&s.m.identity.PublicKey, []protobuf.CommunityMember_Roles{})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
err = other.communitiesManager.SaveCommunity(community)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
2023-12-15 11:55:32 +00:00
|
|
|
advertiseCommunityToUserOldWay(&s.Suite, community, other, s.m)
|
2023-12-11 08:17:01 +00:00
|
|
|
|
|
|
|
inputMessage1 := buildTestMessage(*communityChat)
|
|
|
|
inputMessage1.ChatId = communityChat.ID
|
|
|
|
inputMessage1.ContentType = protobuf.ChatMessage_TEXT_PLAIN
|
|
|
|
inputMessage1.Text = "Hello @" + common.EveryoneMentionTag + " !"
|
|
|
|
|
|
|
|
sendResponse, err := other.SendChatMessage(context.Background(), inputMessage1)
|
|
|
|
s.NoError(err)
|
|
|
|
s.Require().Len(sendResponse.Messages(), 1)
|
|
|
|
|
|
|
|
response, err = s.retrieveAllWithRetry("message from other chatter not received")
|
|
|
|
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Len(response.Chats(), 1)
|
|
|
|
s.Require().Len(response.Messages(), 1)
|
|
|
|
s.Require().Len(response.ActivityCenterNotifications(), 1)
|
|
|
|
s.Require().False(response.ActivityCenterNotifications()[0].Read)
|
|
|
|
|
|
|
|
response, err = s.m.MarkAllRead(context.Background(), communityChat.ID)
|
|
|
|
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Len(response.ActivityCenterNotifications(), 1)
|
|
|
|
s.Require().True(response.ActivityCenterNotifications()[0].Read)
|
|
|
|
|
|
|
|
count, countWithMentions, notifications, err := s.m.MarkMessageAsUnread(communityChat.ID, inputMessage1.ID)
|
|
|
|
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Equal(count, uint64(1))
|
|
|
|
s.Require().Equal(countWithMentions, uint64(1))
|
|
|
|
s.Require().Len(notifications, 1)
|
|
|
|
s.Require().False(notifications[0].Read)
|
|
|
|
}
|