From d244267f9aa9f2a22115d42d642211d479d35d73 Mon Sep 17 00:00:00 2001 From: "John M. Ngei" Date: Fri, 11 Mar 2022 00:05:17 +0300 Subject: [PATCH] Fix: recieved shared image message not being displayed --- protocol/message_persistence.go | 8 +- protocol/messenger.go | 43 ++++++++ protocol/messenger_chats.go | 41 ------- protocol/messenger_share_image_test.go | 142 +++++++++++++++++++++++++ 4 files changed, 192 insertions(+), 42 deletions(-) create mode 100644 protocol/messenger_share_image_test.go diff --git a/protocol/message_persistence.go b/protocol/message_persistence.go index 9c1bc195c..2729e1924 100644 --- a/protocol/message_persistence.go +++ b/protocol/message_persistence.go @@ -75,6 +75,7 @@ func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string { m1.sticker_pack, m1.sticker_hash, m1.image_payload, + m1.image_type, COALESCE(m1.audio_duration_ms,0), m1.community_id, m1.mentions, @@ -152,6 +153,7 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message &sticker.Pack, &sticker.Hash, &image.Payload, + &image.Type, &audio.DurationMs, &communityID, &serializedMentions, @@ -241,7 +243,11 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message message.CommandParameters = command case protobuf.ChatMessage_IMAGE: - message.Payload = &protobuf.ChatMessage_Image{Image: image} + img := protobuf.ImageMessage{ + Payload: image.Payload, + Type: image.Type, + } + message.Payload = &protobuf.ChatMessage_Image{Image: &img} } return nil diff --git a/protocol/messenger.go b/protocol/messenger.go index ce33097db..f423f8b27 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -52,6 +52,7 @@ import ( "github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/protocol/pushnotificationclient" "github.com/status-im/status-go/protocol/pushnotificationserver" + "github.com/status-im/status-go/protocol/requests" "github.com/status-im/status-go/protocol/sqlite" "github.com/status-im/status-go/protocol/transport" v1protocol "github.com/status-im/status-go/protocol/v1" @@ -2427,6 +2428,48 @@ func (m *Messenger) sendChatMessage(ctx context.Context, message *common.Message return &response, m.saveChat(chat) } +func (m *Messenger) ShareImageMessage(request *requests.ShareImageMessage) (*MessengerResponse, error) { + if err := request.Validate(); err != nil { + return nil, err + } + response := &MessengerResponse{} + + msg, err := m.persistence.MessageByID(request.MessageID) + if err != nil { + return nil, err + } + + var messages []*common.Message + for _, pk := range request.Users { + message := &common.Message{} + message.ChatId = pk.String() + message.Payload = msg.Payload + message.Text = "This message has been shared with you" + message.ContentType = protobuf.ChatMessage_IMAGE + messages = append(messages, message) + + r, err := m.CreateOneToOneChat(&requests.CreateOneToOneChat{ID: pk}) + if err != nil { + return nil, err + } + + if err := response.Merge(r); err != nil { + return nil, err + } + } + + sendMessagesResponse, err := m.SendChatMessages(context.Background(), messages) + if err != nil { + return nil, err + } + + if err := response.Merge(sendMessagesResponse); err != nil { + return nil, err + } + + return response, nil +} + // SyncDevices sends all public chats and contacts to paired devices // TODO remove use of photoPath in contacts func (m *Messenger) SyncDevices(ctx context.Context, ensName, photoPath string) (err error) { diff --git a/protocol/messenger_chats.go b/protocol/messenger_chats.go index c04f395e5..821d23e1f 100644 --- a/protocol/messenger_chats.go +++ b/protocol/messenger_chats.go @@ -575,44 +575,3 @@ func (m *Messenger) clearHistory(id string) (*MessengerResponse, error) { response.AddChat(chat) return response, nil } - -func (m *Messenger) ShareImageMessage(request *requests.ShareImageMessage) (*MessengerResponse, error) { - if err := request.Validate(); err != nil { - return nil, err - } - response := &MessengerResponse{} - - msg, err := m.persistence.MessageByID(request.MessageID) - if err != nil { - return nil, err - } - - var messages []*common.Message - for _, pk := range request.Users { - message := &common.Message{} - message.ChatId = pk.String() - message.Payload = msg.Payload - message.ContentType = protobuf.ChatMessage_IMAGE - messages = append(messages, message) - - r, err := m.CreateOneToOneChat(&requests.CreateOneToOneChat{ID: pk}) - if err != nil { - return nil, err - } - - if err := response.Merge(r); err != nil { - return nil, err - } - } - - sendMessagesResponse, err := m.SendChatMessages(context.Background(), messages) - if err != nil { - return nil, err - } - - if err := response.Merge(sendMessagesResponse); err != nil { - return nil, err - } - - return response, nil -} diff --git a/protocol/messenger_share_image_test.go b/protocol/messenger_share_image_test.go new file mode 100644 index 000000000..aa7c023e9 --- /dev/null +++ b/protocol/messenger_share_image_test.go @@ -0,0 +1,142 @@ +package protocol + +import ( + "context" + "crypto/ecdsa" + "io/ioutil" + "os" + "testing" + + "github.com/stretchr/testify/suite" + "go.uber.org/zap" + + gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" + "github.com/status-im/status-go/eth-node/crypto" + "github.com/status-im/status-go/eth-node/types" + "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/requests" + "github.com/status-im/status-go/protocol/tt" + "github.com/status-im/status-go/waku" +) + +func TestMessengerShareMessageSuite(t *testing.T) { + suite.Run(t, new(MessengerShareMessageSuite)) +} + +type MessengerShareMessageSuite struct { + suite.Suite + m *Messenger + privateKey *ecdsa.PrivateKey // private key for the main instance of Messenger + // If one wants to send messages between different instances of Messenger, + // a single waku service should be shared. + shh types.Waku + logger *zap.Logger +} + +func (s *MessengerShareMessageSuite) SetupTest() { + s.logger = tt.MustCreateTestLogger() + + config := waku.DefaultConfig + config.MinimumAcceptedPoW = 0 + shh := waku.New(&config, s.logger) + s.shh = gethbridge.NewGethWakuWrapper(shh) + s.Require().NoError(shh.Start()) + + s.m = s.newMessenger() + s.privateKey = s.m.identity + _, err := s.m.Start() + s.Require().NoError(err) + +} + +func (s *MessengerShareMessageSuite) TearDownTest() { + s.Require().NoError(s.m.Shutdown()) +} + +func (s *MessengerShareMessageSuite) newMessenger() *Messenger { + privateKey, err := crypto.GenerateKey() + s.Require().NoError(err) + + messenger, err := newMessengerWithKey(s.shh, privateKey, s.logger, nil) + s.Require().NoError(err) + return messenger +} + +func buildImageMessage(s *MessengerShareMessageSuite, chat Chat) *common.Message { + file, err := os.Open("../_assets/tests/test.jpg") + s.Require().NoError(err) + defer file.Close() + + payload, err := ioutil.ReadAll(file) + s.Require().NoError(err) + + clock, timestamp := chat.NextClockAndTimestamp(&testTimeSource{}) + message := &common.Message{} + message.ChatId = chat.ID + message.Clock = clock + message.Timestamp = timestamp + message.WhisperTimestamp = clock + message.LocalChatID = chat.ID + message.MessageType = protobuf.MessageType_ONE_TO_ONE + message.ContentType = protobuf.ChatMessage_IMAGE + message.Text = "An image" + + image := protobuf.ImageMessage{ + Payload: payload, + Type: protobuf.ImageType_JPEG, + } + message.Payload = &protobuf.ChatMessage_Image{Image: &image} + return message +} + +func (s *MessengerShareMessageSuite) TestImageMessageSharing() { + theirMessenger := s.newMessenger() + _, err := theirMessenger.Start() + s.Require().NoError(err) + + 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 := buildImageMessage(s, *ourChat) + err = s.m.SaveChat(ourChat) + s.NoError(err) + response, err := s.m.SendChatMessage(context.Background(), inputMessage) + s.NoError(err) + s.Require().Equal(1, len(response.Messages()), "it returns the message") + + outputMessage := response.Messages()[0] + + MessageID := outputMessage.ID + + s.Require().NoError(err) + s.Require().Len(response.Messages(), 1) + + shareResponse, err := s.m.ShareImageMessage( + &requests.ShareImageMessage{ + MessageID: MessageID, + Users: []types.HexBytes{common.PubkeyToHexBytes(&theirMessenger.identity.PublicKey)}, + }, + ) + + s.NoError(err) + s.Require().NotNil(shareResponse) + s.Require().Len(shareResponse.Messages(), 1) + + response, err = WaitOnMessengerResponse( + theirMessenger, + func(r *MessengerResponse) bool { return len(r.messages) > 0 }, + "no messages", + ) + s.Require().NoError(err) + s.Require().Len(response.Chats(), 1) + s.Require().Len(response.Messages(), 2) + +}