2021-05-14 21:22:50 +00:00
|
|
|
package protocol
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
|
|
|
|
"github.com/status-im/status-go/protocol/common"
|
2023-04-17 14:44:48 +00:00
|
|
|
"github.com/status-im/status-go/protocol/protobuf"
|
2021-05-14 21:22:50 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestMessengerPinMessageSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(MessengerPinMessageSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
type MessengerPinMessageSuite struct {
|
2023-04-17 14:44:48 +00:00
|
|
|
MessengerBaseTestSuite
|
2021-05-14 21:22:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerPinMessageSuite) TestPinMessage() {
|
|
|
|
theirMessenger := s.newMessenger()
|
|
|
|
_, err := theirMessenger.Start()
|
|
|
|
s.Require().NoError(err)
|
2023-06-22 12:16:21 +00:00
|
|
|
defer theirMessenger.Shutdown() // nolint: errcheck
|
2021-05-14 21:22:50 +00:00
|
|
|
|
|
|
|
theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
|
|
|
|
err = theirMessenger.SaveChat(theirChat)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
|
|
|
|
err = s.m.SaveChat(ourChat)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
inputMessage := buildTestMessage(*theirChat)
|
|
|
|
sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
|
|
|
|
s.NoError(err)
|
2021-06-03 13:11:55 +00:00
|
|
|
s.Require().Len(sendResponse.Messages(), 1)
|
2021-05-14 21:22:50 +00:00
|
|
|
|
|
|
|
response, err := WaitOnMessengerResponse(
|
|
|
|
s.m,
|
2021-06-03 13:11:55 +00:00
|
|
|
func(r *MessengerResponse) bool { return len(r.Messages()) > 0 },
|
2021-05-14 21:22:50 +00:00
|
|
|
"no messages",
|
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Len(response.Chats(), 1)
|
|
|
|
|
2023-08-18 11:39:59 +00:00
|
|
|
pinMessage := common.NewPinMessage()
|
|
|
|
pinMessage.LocalChatID = theirChat.ID
|
2021-05-14 21:22:50 +00:00
|
|
|
pinMessage.MessageId = inputMessage.ID
|
|
|
|
pinMessage.Pinned = true
|
|
|
|
pinMessage.ChatId = theirChat.ID
|
|
|
|
sendResponse, err = theirMessenger.SendPinMessage(context.Background(), pinMessage)
|
|
|
|
s.NoError(err)
|
|
|
|
s.Require().Len(sendResponse.PinMessages(), 1)
|
|
|
|
|
|
|
|
// Wait for the message to reach its destination
|
|
|
|
response, err = WaitOnMessengerResponse(
|
|
|
|
s.m,
|
|
|
|
func(r *MessengerResponse) bool {
|
2023-04-17 14:44:48 +00:00
|
|
|
// we pull as well the original pinned message
|
|
|
|
return len(r.PinMessages()) == 1 && len(r.Messages()) == 2
|
2021-05-14 21:22:50 +00:00
|
|
|
},
|
|
|
|
"pin message not received",
|
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
receivedPinMessage := response.PinMessages()[0]
|
|
|
|
s.Require().True(receivedPinMessage.Pinned)
|
2023-04-17 14:44:48 +00:00
|
|
|
s.Require().NotNil(receivedPinMessage.Message)
|
|
|
|
s.Require().Equal(inputMessage.ID, receivedPinMessage.Message.Message.ID)
|
|
|
|
messages := response.Messages()
|
|
|
|
|
|
|
|
var originalMessage *common.Message
|
|
|
|
var notificationMessage *common.Message
|
|
|
|
|
|
|
|
if messages[0].ID == inputMessage.ID {
|
|
|
|
originalMessage = messages[0]
|
|
|
|
notificationMessage = messages[1]
|
|
|
|
} else {
|
|
|
|
originalMessage = messages[1]
|
|
|
|
notificationMessage = messages[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
s.Require().Equal(theirMessenger.myHexIdentity(), notificationMessage.From)
|
|
|
|
s.Require().Equal(inputMessage.ID, notificationMessage.ResponseTo)
|
|
|
|
s.Require().Equal(protobuf.ChatMessage_SYSTEM_MESSAGE_PINNED_MESSAGE, notificationMessage.ContentType)
|
|
|
|
|
|
|
|
s.Require().Equal(inputMessage.ID, originalMessage.ID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *MessengerPinMessageSuite) TestPinMessageOutOfOrder() {
|
|
|
|
theirMessenger := s.newMessenger()
|
|
|
|
_, err := theirMessenger.Start()
|
|
|
|
s.Require().NoError(err)
|
2023-06-22 12:16:21 +00:00
|
|
|
defer theirMessenger.Shutdown() // nolint: errcheck
|
2023-04-17 14:44:48 +00:00
|
|
|
|
|
|
|
theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
|
|
|
|
err = theirMessenger.SaveChat(theirChat)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
|
|
|
|
err = s.m.SaveChat(ourChat)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
inputMessage := buildTestMessage(*theirChat)
|
|
|
|
sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
|
|
|
|
s.NoError(err)
|
|
|
|
s.Require().Len(sendResponse.Messages(), 1)
|
|
|
|
|
|
|
|
response, err := WaitOnMessengerResponse(
|
|
|
|
s.m,
|
|
|
|
func(r *MessengerResponse) bool { return len(r.Messages()) > 0 },
|
|
|
|
"no messages",
|
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
s.Require().Len(response.Chats(), 1)
|
2023-05-05 15:26:19 +00:00
|
|
|
s.Require().Equal(response.Chats()[0].UnviewedMessagesCount, uint(1))
|
2023-04-17 14:44:48 +00:00
|
|
|
|
|
|
|
// Unpin with higher clock
|
|
|
|
|
|
|
|
unpinMessage := protobuf.PinMessage{
|
|
|
|
ChatId: theirChat.ID,
|
|
|
|
MessageId: inputMessage.ID,
|
|
|
|
Pinned: false,
|
|
|
|
Clock: 3,
|
|
|
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
|
|
|
}
|
|
|
|
|
|
|
|
handlePinMessageResponse := &MessengerResponse{}
|
|
|
|
err = theirMessenger.handlePinMessage(
|
|
|
|
&Contact{ID: s.m.myHexIdentity()},
|
|
|
|
1000,
|
|
|
|
handlePinMessageResponse,
|
2023-08-18 11:39:59 +00:00
|
|
|
&unpinMessage,
|
2023-04-17 14:44:48 +00:00
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
s.Require().Len(handlePinMessageResponse.PinMessages(), 1)
|
|
|
|
s.Require().False(handlePinMessageResponse.PinMessages()[0].Pinned)
|
2023-05-05 15:26:19 +00:00
|
|
|
s.Require().Len(handlePinMessageResponse.Chats(), 1)
|
|
|
|
s.Require().Equal(handlePinMessageResponse.Chats()[0].UnviewedMessagesCount, uint(0))
|
2023-04-17 14:44:48 +00:00
|
|
|
|
|
|
|
// Pin with lower clock in response
|
|
|
|
|
|
|
|
pinMessage := protobuf.PinMessage{
|
|
|
|
ChatId: theirChat.ID,
|
|
|
|
MessageId: inputMessage.ID,
|
|
|
|
Pinned: true,
|
|
|
|
Clock: 2,
|
|
|
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = theirMessenger.handlePinMessage(
|
|
|
|
&Contact{ID: s.m.myHexIdentity()},
|
|
|
|
1000,
|
|
|
|
handlePinMessageResponse,
|
2023-08-18 11:39:59 +00:00
|
|
|
&pinMessage,
|
2023-04-17 14:44:48 +00:00
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
s.Require().Len(handlePinMessageResponse.PinMessages(), 1)
|
|
|
|
s.Require().False(handlePinMessageResponse.PinMessages()[0].Pinned)
|
2023-05-05 15:26:19 +00:00
|
|
|
s.Require().Len(handlePinMessageResponse.Chats(), 1)
|
|
|
|
s.Require().Equal(handlePinMessageResponse.Chats()[0].UnviewedMessagesCount, uint(0))
|
2023-04-17 14:44:48 +00:00
|
|
|
|
|
|
|
// Pin with lower clock not in response
|
|
|
|
|
|
|
|
handlePinMessageResponse = &MessengerResponse{}
|
|
|
|
pinMessage = protobuf.PinMessage{
|
|
|
|
ChatId: theirChat.ID,
|
|
|
|
MessageId: inputMessage.ID,
|
|
|
|
Pinned: true,
|
|
|
|
Clock: 1,
|
|
|
|
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
|
|
|
}
|
|
|
|
|
|
|
|
err = theirMessenger.handlePinMessage(
|
|
|
|
&Contact{ID: s.m.myHexIdentity()},
|
|
|
|
1000,
|
|
|
|
handlePinMessageResponse,
|
2023-08-18 11:39:59 +00:00
|
|
|
&pinMessage,
|
2023-04-17 14:44:48 +00:00
|
|
|
)
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
s.Require().Len(handlePinMessageResponse.PinMessages(), 0)
|
2021-05-14 21:22:50 +00:00
|
|
|
}
|