package protocol import ( "encoding/json" "fmt" "strings" "testing" "github.com/stretchr/testify/suite" "github.com/status-im/status-go/protocol/common" "github.com/status-im/status-go/protocol/protobuf" "github.com/status-im/status-go/server" ) func TestMessengerPrepareMessage(t *testing.T) { suite.Run(t, new(TestMessengerPrepareMessageSuite)) } type TestMessengerPrepareMessageSuite struct { MessengerBaseTestSuite chatID string p *sqlitePersistence } func (s *TestMessengerPrepareMessageSuite) SetupTest() { s.MessengerBaseTestSuite.SetupTest() s.chatID, s.p = s.setUpTestDatabase() } func (s *TestMessengerPrepareMessageSuite) setUpTestDatabase() (string, *sqlitePersistence) { chat := CreatePublicChat("test-chat", s.m.transport) err := s.m.SaveChat(chat) s.NoError(err) db, err := openTestDB() s.NoError(err) p := newSQLitePersistence(db) return chat.ID, p } func (s *TestMessengerPrepareMessageSuite) generateTextMessage(ID string, From string, Clock uint64, responseTo string) *common.Message { return &common.Message{ ID: ID, From: From, LocalChatID: s.chatID, ChatMessage: &protobuf.ChatMessage{ Text: RandomLettersString(5), Clock: Clock, ResponseTo: responseTo, }, } } func (s *TestMessengerPrepareMessageSuite) testMessageContainsImage(testAlbum bool) { message1 := s.generateTextMessage("id-1", "1", 1, "") message1.ContentType = protobuf.ChatMessage_IMAGE message1.Payload = &protobuf.ChatMessage_Image{ Image: &protobuf.ImageMessage{ Format: 1, Payload: RandomBytes(10), }, } message2 := s.generateTextMessage("id-2", "2", 2, message1.ID) messages := []*common.Message{message1, message2} var message3 *common.Message if testAlbum { albumID := RandomLettersString(5) message1.GetImage().AlbumId = albumID message3 = s.generateTextMessage("id-3", "1", 0, "") message3.ContentType = protobuf.ChatMessage_IMAGE message3.Payload = &protobuf.ChatMessage_Image{ Image: &protobuf.ImageMessage{ Format: 1, Payload: RandomBytes(10), AlbumId: albumID, }, } messages = append(messages, message3) } err := s.m.SaveMessages(messages) s.Require().NoError(err) err = s.p.SaveMessages(messages) s.Require().NoError(err) mediaServer, err := server.NewMediaServer(s.m.database, nil, nil, nil) s.Require().NoError(err) s.Require().NoError(mediaServer.Start()) retrievedMessages, _, err := s.p.MessageByChatID(s.chatID, "", 10) s.Require().NoError(err) if testAlbum { s.Require().Len(retrievedMessages, 3) } else { s.Require().Len(retrievedMessages, 2) } s.Require().Equal(message2.ID, retrievedMessages[0].ID) s.Require().Equal(message1.ID, retrievedMessages[0].ResponseTo) err = s.m.prepareMessage(retrievedMessages[0], mediaServer) s.Require().NoError(err) mediaServerImageLink := func(messageID string) string { return fmt.Sprintf(`https://Localhost:%d/messages/images?messageId=%s`, mediaServer.GetPort(), messageID) } if testAlbum { expectedJSON := fmt.Sprintf(`["%s","%s"]`, mediaServerImageLink(message1.ID), mediaServerImageLink(message3.ID), ) s.Require().Equal(json.RawMessage(expectedJSON), retrievedMessages[0].QuotedMessage.AlbumImages) } else { expectedURL := mediaServerImageLink(message1.ID) s.Require().Equal(expectedURL, retrievedMessages[0].QuotedMessage.ImageLocalURL) } } func (s *TestMessengerPrepareMessageSuite) Test_WHEN_MessageContainsImage_THEN_preparedMessageAddsAlbumImageWithImageGeneratedLink() { testCases := []struct { name string album bool }{ { name: "single image", album: false, }, { name: "album", album: true, }, } for _, tc := range testCases { s.Run(tc.name, func() { s.testMessageContainsImage(tc.album) }) } } func (s *TestMessengerPrepareMessageSuite) Test_WHEN_NoQuotedMessage_THEN_RetrievedMessageDoesNotContainQuotedMessage() { message1 := s.generateTextMessage("id-1", "1", 1, "") message2 := s.generateTextMessage("id-2", "2", 2, "") messages := []*common.Message{message1, message2} err := s.m.SaveMessages([]*common.Message{message1, message2}) s.Require().NoError(err) err = s.p.SaveMessages(messages) s.Require().NoError(err) mediaServer, err := server.NewMediaServer(s.m.database, nil, nil, nil) s.Require().NoError(err) s.Require().NoError(mediaServer.Start()) retrievedMessages, _, err := s.p.MessageByChatID(s.chatID, "", 10) s.Require().NoError(err) s.Require().Equal(message2.ID, retrievedMessages[0].ID) s.Require().Empty(retrievedMessages[0].ResponseTo) err = s.m.prepareMessage(retrievedMessages[0], mediaServer) s.Require().NoError(err) s.Require().Equal((*common.QuotedMessage)(nil), retrievedMessages[0].QuotedMessage) } func (s *TestMessengerPrepareMessageSuite) Test_WHEN_QuotedMessageDoesNotContainsImage_THEN_RetrievedMessageContainsNoImages() { message1 := s.generateTextMessage("id-1", "1", 1, "") message2 := s.generateTextMessage("id-2", "2", 2, message1.ID) messages := []*common.Message{message1, message2} err := s.m.SaveMessages([]*common.Message{message1, message2}) s.Require().NoError(err) err = s.p.SaveMessages(messages) s.Require().NoError(err) mediaServer, err := server.NewMediaServer(s.m.database, nil, nil, nil) s.Require().NoError(err) s.Require().NoError(mediaServer.Start()) retrievedMessages, _, err := s.p.MessageByChatID(s.chatID, "", 10) s.Require().NoError(err) s.Require().Equal(message2.ID, retrievedMessages[0].ID) s.Require().Equal(message1.ID, retrievedMessages[0].ResponseTo) err = s.m.prepareMessage(retrievedMessages[0], mediaServer) s.Require().NoError(err) s.Require().Equal(json.RawMessage(nil), retrievedMessages[0].QuotedMessage.AlbumImages) } func (s *TestMessengerPrepareMessageSuite) Test_WHEN_MessageContainsImage_THEN_PreparedMessageByIDContainsLink() { // GIVEN: message with image saved to DB message := s.generateTextMessage("id-1", "1", 1, "") message.ContentType = protobuf.ChatMessage_IMAGE message.Payload = &protobuf.ChatMessage_Image{ Image: &protobuf.ImageMessage{ Format: 1, Payload: RandomBytes(100), }, } err := s.m.SaveMessages([]*common.Message{message}) s.Require().NoError(err) mediaServer, err := server.NewMediaServer(s.m.database, nil, nil, nil) s.Require().NoError(err) s.Require().NoError(mediaServer.Start()) s.m.SetMediaServer(mediaServer) // WHEN: message is prepared loadedMessage, err := s.m.MessageByID(message.ID) s.Require().NoError(err) // THEN: message contains image link s.Require().True(strings.HasPrefix(loadedMessage.ImageLocalURL, "https://Localhost")) }