github.com/status-im/status-go@v1.1.0/protocol/messenger_remove_message_test.go (about)

     1  package protocol
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/suite"
     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/server"
    12  )
    13  
    14  func TestMessengerRemoveMessageSuite(t *testing.T) {
    15  	suite.Run(t, new(MessengerRemoveMessageSuite))
    16  }
    17  
    18  type MessengerRemoveMessageSuite struct {
    19  	MessengerBaseTestSuite
    20  }
    21  
    22  func (s *MessengerRemoveMessageSuite) TestDeleteMessage() {
    23  	theirMessenger := s.newMessenger()
    24  	defer TearDownMessenger(&s.Suite, theirMessenger)
    25  
    26  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
    27  	err := theirMessenger.SaveChat(theirChat)
    28  	s.Require().NoError(err)
    29  
    30  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
    31  	err = s.m.SaveChat(ourChat)
    32  	s.Require().NoError(err)
    33  
    34  	inputMessage := buildTestMessage(*theirChat)
    35  	sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
    36  	s.NoError(err)
    37  	s.Require().Len(sendResponse.Messages(), 1)
    38  
    39  	messageID := sendResponse.Messages()[0].ID
    40  
    41  	response, err := WaitOnMessengerResponse(
    42  		s.m,
    43  		func(r *MessengerResponse) bool { return len(r.messages) > 0 },
    44  		"no messages",
    45  	)
    46  	s.Require().NoError(err)
    47  	s.Require().Len(response.Chats(), 1)
    48  	s.Require().Len(response.Messages(), 1)
    49  
    50  	ogMessage := sendResponse.Messages()[0]
    51  
    52  	sendResponse, err = theirMessenger.DeleteMessageAndSend(context.Background(), ogMessage.ID)
    53  
    54  	s.Require().NoError(err)
    55  	s.Require().Len(sendResponse.Messages(), 0)
    56  	s.Require().Len(sendResponse.RemovedMessages(), 1)
    57  	s.Require().Equal(messageID, sendResponse.RemovedMessages()[0].MessageID)
    58  	s.Require().Equal(sendResponse.RemovedMessages()[0].DeletedBy, "")
    59  	s.Require().Len(sendResponse.Chats(), 1)
    60  	// LastMessage is marked as deleted
    61  	lastRemovedMessage := sendResponse.Chats()[0].LastMessage
    62  	s.Require().Equal(lastRemovedMessage.ID, messageID)
    63  	s.Require().Equal(lastRemovedMessage.Deleted, true)
    64  
    65  	// Main instance user attempts to delete the message it received from theirMessenger
    66  	_, err = s.m.DeleteMessageAndSend(context.Background(), ogMessage.ID)
    67  
    68  	s.Require().ErrorContains(err, "can't find chat")
    69  }
    70  
    71  func (s *MessengerRemoveMessageSuite) TestDeleteMessagePreviousLastMessage() {
    72  	theirMessenger := s.newMessenger()
    73  	defer TearDownMessenger(&s.Suite, theirMessenger)
    74  
    75  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
    76  	err := theirMessenger.SaveChat(theirChat)
    77  	s.Require().NoError(err)
    78  
    79  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
    80  	err = s.m.SaveChat(ourChat)
    81  	s.Require().NoError(err)
    82  
    83  	inputMessage1 := buildTestMessage(*theirChat)
    84  	sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage1)
    85  	s.NoError(err)
    86  	s.Require().Len(sendResponse.Messages(), 1)
    87  
    88  	inputMessage2 := buildTestMessage(*theirChat)
    89  	sendResponse, err = theirMessenger.SendChatMessage(context.Background(), inputMessage2)
    90  	s.NoError(err)
    91  	s.Require().Len(sendResponse.Messages(), 1)
    92  
    93  	messageID := sendResponse.Messages()[0].ID
    94  
    95  	response, err := WaitOnMessengerResponse(
    96  		s.m,
    97  		func(r *MessengerResponse) bool { return len(r.messages) > 0 },
    98  		"no messages",
    99  	)
   100  	s.Require().NoError(err)
   101  	s.Require().Len(response.Chats(), 1)
   102  	s.Require().Len(response.Messages(), 2)
   103  
   104  	ogMessage := sendResponse.Messages()[0]
   105  
   106  	sendResponse, err = theirMessenger.DeleteMessageAndSend(context.Background(), ogMessage.ID)
   107  
   108  	s.Require().NoError(err)
   109  	s.Require().Len(sendResponse.Messages(), 0)
   110  	s.Require().Len(sendResponse.RemovedMessages(), 1)
   111  	s.Require().Equal(messageID, sendResponse.RemovedMessages()[0].MessageID)
   112  	s.Require().Len(sendResponse.Chats(), 1)
   113  	// LastMessage is updated and marked as deleted
   114  	s.Require().NotNil(sendResponse.Chats()[0].LastMessage)
   115  	s.Require().Equal(inputMessage2.ID, sendResponse.Chats()[0].LastMessage.ID)
   116  	s.Require().Equal(sendResponse.Chats()[0].LastMessage.Deleted, true)
   117  
   118  }
   119  
   120  func (s *MessengerRemoveMessageSuite) TestDeleteWrongMessageType() {
   121  	theirMessenger := s.newMessenger()
   122  	defer TearDownMessenger(&s.Suite, theirMessenger)
   123  
   124  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   125  	err := theirMessenger.SaveChat(theirChat)
   126  	s.Require().NoError(err)
   127  
   128  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   129  	err = s.m.SaveChat(ourChat)
   130  	s.Require().NoError(err)
   131  
   132  	inputMessage := buildTestGapMessage(*theirChat)
   133  	sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
   134  	s.NoError(err)
   135  	s.Require().Len(sendResponse.Messages(), 1)
   136  
   137  	ogMessage := sendResponse.Messages()[0]
   138  
   139  	// Delete should not work
   140  	_, err = theirMessenger.DeleteMessageAndSend(context.Background(), ogMessage.ID)
   141  
   142  	s.Require().Equal(ErrInvalidDeleteTypeAuthor, err)
   143  }
   144  
   145  // TODO fix activity center notifications not being deleted when a message is deleted
   146  
   147  func (s *MessengerRemoveMessageSuite) TestDeleteMessageFirstThenMessage() {
   148  	theirMessenger := s.newMessenger()
   149  	defer TearDownMessenger(&s.Suite, theirMessenger)
   150  
   151  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   152  	err := theirMessenger.SaveChat(theirChat)
   153  	s.Require().NoError(err)
   154  
   155  	contact, err := BuildContactFromPublicKey(&theirMessenger.identity.PublicKey)
   156  	s.Require().NoError(err)
   157  
   158  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   159  	err = s.m.SaveChat(ourChat)
   160  	s.Require().NoError(err)
   161  	messageID := "message-id"
   162  
   163  	inputMessage := buildTestMessage(*theirChat)
   164  	inputMessage.Clock = 1
   165  	deleteMessage := &DeleteMessage{
   166  		DeleteMessage: &protobuf.DeleteMessage{
   167  			Clock:       2,
   168  			MessageType: protobuf.MessageType_ONE_TO_ONE,
   169  			MessageId:   messageID,
   170  			ChatId:      theirChat.ID,
   171  		},
   172  		From: common.PubkeyToHex(&theirMessenger.identity.PublicKey),
   173  	}
   174  
   175  	state := &ReceivedMessageState{
   176  		Response: &MessengerResponse{},
   177  	}
   178  
   179  	// Handle Delete first
   180  	err = s.m.handleDeleteMessage(state, deleteMessage)
   181  	s.Require().NoError(err)
   182  
   183  	// // Handle chat message
   184  	state = &ReceivedMessageState{
   185  		Response: &MessengerResponse{},
   186  		CurrentMessageState: &CurrentMessageState{
   187  			MessageID:        messageID,
   188  			WhisperTimestamp: s.m.getTimesource().GetCurrentTime(),
   189  			Contact:          contact,
   190  			PublicKey:        &theirMessenger.identity.PublicKey,
   191  		},
   192  	}
   193  	err = s.m.HandleChatMessage(state, inputMessage.ChatMessage, nil, false)
   194  	s.Require().NoError(err)
   195  	s.Require().Len(state.Response.Messages(), 0) // Message should not be added to response
   196  	s.Require().Len(state.Response.RemovedMessages(), 0)
   197  	s.Require().Nil(state.Response.Chats()[0].LastMessage)
   198  }
   199  
   200  func (s *MessengerRemoveMessageSuite) TestDeleteImageMessage() {
   201  	theirMessenger := s.newMessenger()
   202  	defer TearDownMessenger(&s.Suite, theirMessenger)
   203  
   204  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   205  	err := theirMessenger.SaveChat(theirChat)
   206  	s.Require().NoError(err)
   207  
   208  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   209  	err = s.m.SaveChat(ourChat)
   210  	s.Require().NoError(err)
   211  
   212  	messageCount := 3
   213  	var album []*common.Message
   214  	for i := 0; i < messageCount; i++ {
   215  		image, err := buildImageWithoutAlbumIDMessage(*ourChat)
   216  		s.NoError(err)
   217  		album = append(album, image)
   218  	}
   219  
   220  	response, err := s.m.SendChatMessages(context.Background(), album)
   221  	s.NoError(err)
   222  
   223  	// Check that album count was the number of the images sent
   224  	imagesCount := uint32(0)
   225  	for _, message := range response.Messages() {
   226  		if message.ContentType == protobuf.ChatMessage_IMAGE {
   227  			imagesCount++
   228  		}
   229  	}
   230  	for _, message := range response.Messages() {
   231  		s.Require().NotNil(message.GetImage())
   232  		s.Require().Equal(message.GetImage().AlbumImagesCount, imagesCount)
   233  	}
   234  
   235  	s.Require().Equal(messageCount, len(response.Messages()), "it returns the messages")
   236  	s.Require().NoError(err)
   237  	s.Require().Len(response.Messages(), messageCount)
   238  
   239  	response, err = WaitOnMessengerResponse(
   240  		theirMessenger,
   241  		func(r *MessengerResponse) bool { return len(r.messages) == messageCount },
   242  		"no messages",
   243  	)
   244  
   245  	s.Require().NoError(err)
   246  	s.Require().Len(response.Chats(), 1)
   247  	s.Require().Len(response.Messages(), messageCount)
   248  	for _, message := range response.Messages() {
   249  		image := message.GetImage()
   250  		s.Require().NotNil(image, "Message.ID=%s", message.ID)
   251  		s.Require().Equal(image.AlbumImagesCount, imagesCount)
   252  		s.Require().NotEmpty(image.AlbumId, "Message.ID=%s", message.ID)
   253  	}
   254  
   255  	firstMessageID := response.Messages()[0].ID
   256  	sendResponse, err := s.m.DeleteMessageAndSend(context.Background(), firstMessageID)
   257  
   258  	s.Require().NoError(err)
   259  	s.Require().Len(sendResponse.Messages(), 0)
   260  	s.Require().Len(sendResponse.RemovedMessages(), 3)
   261  	s.Require().Equal(sendResponse.RemovedMessages()[0].DeletedBy, "")
   262  	s.Require().Len(sendResponse.Chats(), 1)
   263  
   264  	// LastMessage marked as deleted
   265  	s.Require().Equal(sendResponse.Chats()[0].LastMessage.ID, album[2].ID)
   266  	s.Require().Equal(sendResponse.Chats()[0].LastMessage.Deleted, true)
   267  
   268  	// Main instance user attempts to delete the message it received from theirMessenger
   269  	_, err = theirMessenger.DeleteMessageAndSend(context.Background(), firstMessageID)
   270  
   271  	s.Require().ErrorContains(err, "can't find chat")
   272  }
   273  
   274  func (s *MessengerRemoveMessageSuite) TestDeleteImageMessageFirstThenMessage() {
   275  	theirMessenger := s.newMessenger()
   276  	defer TearDownMessenger(&s.Suite, theirMessenger)
   277  
   278  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   279  	err := theirMessenger.SaveChat(theirChat)
   280  	s.Require().NoError(err)
   281  
   282  	contact, err := BuildContactFromPublicKey(&theirMessenger.identity.PublicKey)
   283  	s.Require().NoError(err)
   284  
   285  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   286  	err = s.m.SaveChat(ourChat)
   287  	s.Require().NoError(err)
   288  	messageID1 := "message-id1"
   289  	messageID2 := "message-id2"
   290  	albumID := "album-id1"
   291  
   292  	messageCount := 2
   293  	var album []*common.Message
   294  	for i := 0; i < messageCount; i++ {
   295  		image, err := buildImageWithAlbumIDMessage(*ourChat, albumID)
   296  		image.Clock = 1
   297  		s.NoError(err)
   298  		album = append(album, image)
   299  	}
   300  
   301  	deleteMessage := &DeleteMessage{
   302  		DeleteMessage: &protobuf.DeleteMessage{
   303  			Clock:       2,
   304  			MessageType: protobuf.MessageType_ONE_TO_ONE,
   305  			MessageId:   messageID1,
   306  			ChatId:      theirChat.ID,
   307  		},
   308  		From: common.PubkeyToHex(&theirMessenger.identity.PublicKey),
   309  	}
   310  
   311  	state := &ReceivedMessageState{
   312  		Response: &MessengerResponse{},
   313  	}
   314  
   315  	// Handle Delete first
   316  	err = s.m.handleDeleteMessage(state, deleteMessage)
   317  	s.Require().NoError(err)
   318  
   319  	// Handle first image message
   320  	state = &ReceivedMessageState{
   321  		Response: &MessengerResponse{},
   322  		CurrentMessageState: &CurrentMessageState{
   323  			MessageID:        messageID1,
   324  			WhisperTimestamp: s.m.getTimesource().GetCurrentTime(),
   325  			Contact:          contact,
   326  			PublicKey:        &theirMessenger.identity.PublicKey,
   327  		},
   328  	}
   329  	err = s.m.HandleChatMessage(state, album[0].ChatMessage, nil, false)
   330  	s.Require().NoError(err)
   331  	s.Require().Len(state.Response.Messages(), 0) // Message should not be added to response
   332  	s.Require().Len(state.Response.RemovedMessages(), 0)
   333  	s.Require().Nil(state.Response.Chats()[0].LastMessage)
   334  
   335  	// Handle second  image message
   336  	state = &ReceivedMessageState{
   337  		Response: &MessengerResponse{},
   338  		CurrentMessageState: &CurrentMessageState{
   339  			MessageID:        messageID2,
   340  			WhisperTimestamp: s.m.getTimesource().GetCurrentTime(),
   341  			Contact:          contact,
   342  			PublicKey:        &theirMessenger.identity.PublicKey,
   343  		},
   344  	}
   345  	err = s.m.HandleChatMessage(state, album[1].ChatMessage, nil, false)
   346  	s.Require().NoError(err)
   347  	s.Require().Len(state.Response.Messages(), 0) // Message should not be added to response even if we didn't delete that ID
   348  	s.Require().Len(state.Response.RemovedMessages(), 0)
   349  	s.Require().Nil(state.Response.Chats()[0].LastMessage)
   350  }
   351  
   352  func (s *MessengerRemoveMessageSuite) TestDeleteMessageWithAMention() {
   353  	theirMessenger := s.newMessenger()
   354  	defer TearDownMessenger(&s.Suite, theirMessenger)
   355  
   356  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   357  	err := theirMessenger.SaveChat(theirChat)
   358  	s.Require().NoError(err)
   359  
   360  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   361  	err = s.m.SaveChat(ourChat)
   362  	s.Require().NoError(err)
   363  
   364  	inputMessage := buildTestMessage(*theirChat)
   365  	inputMessage.Text = "text with a mention @" + common.PubkeyToHex(&s.privateKey.PublicKey)
   366  	sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
   367  	s.NoError(err)
   368  	s.Require().Len(sendResponse.Messages(), 1)
   369  
   370  	messageID := sendResponse.Messages()[0].ID
   371  
   372  	response, err := WaitOnMessengerResponse(
   373  		s.m,
   374  		func(r *MessengerResponse) bool { return len(r.messages) == 1 },
   375  		"no messages",
   376  	)
   377  	s.Require().NoError(err)
   378  	s.Require().Len(response.Chats(), 1)
   379  	s.Require().Len(response.Messages(), 1)
   380  	// Receiver (us) is mentioned
   381  	s.Require().Equal(int(response.Chats()[0].UnviewedMessagesCount), 1)
   382  	s.Require().Equal(int(response.Chats()[0].UnviewedMentionsCount), 1)
   383  	s.Require().True(response.Messages()[0].Mentioned)
   384  
   385  	deleteMessage := &DeleteMessage{
   386  		DeleteMessage: &protobuf.DeleteMessage{
   387  			Clock:       2,
   388  			MessageType: protobuf.MessageType_ONE_TO_ONE,
   389  			MessageId:   messageID,
   390  			ChatId:      theirChat.ID,
   391  		},
   392  		From: common.PubkeyToHex(&theirMessenger.identity.PublicKey),
   393  	}
   394  
   395  	state := &ReceivedMessageState{
   396  		Response: &MessengerResponse{},
   397  	}
   398  
   399  	// Handle Delete first
   400  	err = s.m.handleDeleteMessage(state, deleteMessage)
   401  
   402  	s.Require().NoError(err)
   403  	s.Require().Len(response.Chats(), 1)
   404  	s.Require().Len(response.Messages(), 1)
   405  	// Receiver (us) is  no longer mentioned
   406  	s.Require().Equal(int(state.Response.Chats()[0].UnviewedMessagesCount), 0)
   407  	s.Require().Equal(int(state.Response.Chats()[0].UnviewedMentionsCount), 0)
   408  }
   409  
   410  // This test makes sure the UnviewMessageCount doesn't go below 0 in a very rare case where the Chat could be marked
   411  // as read but the message still unseen (Seen == false)
   412  func (s *MessengerRemoveMessageSuite) TestDeleteMessageAndChatIsAlreadyRead() {
   413  	theirMessenger := s.newMessenger()
   414  	defer TearDownMessenger(&s.Suite, theirMessenger)
   415  
   416  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   417  	err := theirMessenger.SaveChat(theirChat)
   418  	s.Require().NoError(err)
   419  
   420  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   421  	err = s.m.SaveChat(ourChat)
   422  	s.Require().NoError(err)
   423  
   424  	inputMessage := buildTestMessage(*theirChat)
   425  	sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
   426  	s.NoError(err)
   427  	s.Require().Len(sendResponse.Messages(), 1)
   428  
   429  	response, err := WaitOnMessengerResponse(
   430  		s.m,
   431  		func(r *MessengerResponse) bool { return len(r.messages) == 1 },
   432  		"no messages",
   433  	)
   434  	s.Require().NoError(err)
   435  	s.Require().Len(response.Chats(), 1)
   436  	s.Require().Equal(response.Chats()[0].UnviewedMessagesCount, uint(1))
   437  	s.Require().Len(response.Messages(), 1)
   438  
   439  	// Force UnviewedMessagesCount to 0 to test if the uint validation is done correctly
   440  	ourChat.UnviewedMessagesCount = 0
   441  	err = s.m.saveChat(ourChat)
   442  
   443  	s.Require().NoError(err)
   444  
   445  	ogMessage := sendResponse.Messages()[0]
   446  
   447  	deleteMessage := &DeleteMessage{
   448  		DeleteMessage: &protobuf.DeleteMessage{
   449  			Clock:       2,
   450  			MessageType: protobuf.MessageType_ONE_TO_ONE,
   451  			MessageId:   ogMessage.ID,
   452  			ChatId:      theirChat.ID,
   453  		},
   454  		From: common.PubkeyToHex(&theirMessenger.identity.PublicKey),
   455  	}
   456  
   457  	state := &ReceivedMessageState{
   458  		Response: &MessengerResponse{},
   459  	}
   460  
   461  	// Handle Delete first
   462  	err = s.m.handleDeleteMessage(state, deleteMessage)
   463  
   464  	s.Require().NoError(err)
   465  	s.Require().Len(response.Chats(), 1)
   466  	s.Require().Len(response.Messages(), 1)
   467  	// Receiver (us) no longer has unread messages and it's not negative
   468  	s.Require().Equal(0, int(state.Response.Chats()[0].UnviewedMessagesCount))
   469  }
   470  
   471  func (s *MessengerRemoveMessageSuite) TestDeleteMessageReplyToImage() {
   472  	theirMessenger := s.newMessenger()
   473  	defer TearDownMessenger(&s.Suite, theirMessenger)
   474  
   475  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   476  	err := theirMessenger.SaveChat(theirChat)
   477  	s.Require().NoError(err)
   478  
   479  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   480  	err = s.m.SaveChat(ourChat)
   481  	s.Require().NoError(err)
   482  
   483  	inputMessage := buildTestMessage(*theirChat)
   484  	sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
   485  	s.NoError(err)
   486  	s.Require().Len(sendResponse.Messages(), 1)
   487  
   488  	response, err := WaitOnMessengerResponse(
   489  		s.m,
   490  		func(r *MessengerResponse) bool { return len(r.messages) == 1 },
   491  		"no messages",
   492  	)
   493  	s.Require().NoError(err)
   494  	s.Require().Len(response.Chats(), 1)
   495  	s.Require().Len(response.Messages(), 1)
   496  
   497  	ogMessage := sendResponse.Messages()[0]
   498  
   499  	// create an http server
   500  	mediaServer, err := server.NewMediaServer(nil, nil, nil, nil)
   501  	s.Require().NoError(err)
   502  	s.Require().NotNil(mediaServer)
   503  	s.Require().NoError(mediaServer.Start())
   504  
   505  	theirMessenger.SetMediaServer(mediaServer)
   506  
   507  	// We reply to our own message with an image
   508  	imageMessage, err := buildImageWithoutAlbumIDMessage(*theirChat)
   509  	s.NoError(err)
   510  
   511  	imageMessage.ResponseTo = ogMessage.ID
   512  
   513  	_, err = theirMessenger.SendChatMessages(context.Background(), []*common.Message{imageMessage})
   514  	s.NoError(err)
   515  
   516  	// We check that the URL is correctly returned
   517  	sendResponse, err = theirMessenger.DeleteMessageAndSend(context.Background(), ogMessage.ID)
   518  
   519  	s.Require().NoError(err)
   520  	s.Require().Len(sendResponse.Messages(), 1)
   521  	s.Require().NotEmpty(sendResponse.Messages()[0].ImageLocalURL)
   522  }
   523  
   524  func (s *MessengerRemoveMessageSuite) TestDeleteMessageForMeReplyToImage() {
   525  	theirMessenger := s.newMessenger()
   526  	defer TearDownMessenger(&s.Suite, theirMessenger)
   527  
   528  	theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, s.m.transport)
   529  	err := theirMessenger.SaveChat(theirChat)
   530  	s.Require().NoError(err)
   531  
   532  	ourChat := CreateOneToOneChat("Our 1TO1", &theirMessenger.identity.PublicKey, s.m.transport)
   533  	err = s.m.SaveChat(ourChat)
   534  	s.Require().NoError(err)
   535  
   536  	inputMessage := buildTestMessage(*theirChat)
   537  	sendResponse, err := theirMessenger.SendChatMessage(context.Background(), inputMessage)
   538  	s.NoError(err)
   539  	s.Require().Len(sendResponse.Messages(), 1)
   540  
   541  	response, err := WaitOnMessengerResponse(
   542  		s.m,
   543  		func(r *MessengerResponse) bool { return len(r.messages) == 1 },
   544  		"no messages",
   545  	)
   546  	s.Require().NoError(err)
   547  	s.Require().Len(response.Chats(), 1)
   548  	s.Require().Len(response.Messages(), 1)
   549  
   550  	ogMessage := sendResponse.Messages()[0]
   551  
   552  	// create an http server
   553  	mediaServer, err := server.NewMediaServer(nil, nil, nil, nil)
   554  	s.Require().NoError(err)
   555  	s.Require().NotNil(mediaServer)
   556  	s.Require().NoError(mediaServer.Start())
   557  
   558  	theirMessenger.SetMediaServer(mediaServer)
   559  
   560  	// We reply to our own message with an image
   561  	imageMessage, err := buildImageWithoutAlbumIDMessage(*theirChat)
   562  	s.NoError(err)
   563  
   564  	imageMessage.ResponseTo = ogMessage.ID
   565  
   566  	_, err = theirMessenger.SendChatMessages(context.Background(), []*common.Message{imageMessage})
   567  	s.NoError(err)
   568  
   569  	// We check that the URL is correctly returned
   570  	sendResponse, err = theirMessenger.DeleteMessageForMeAndSync(context.Background(), theirChat.ID, ogMessage.ID)
   571  
   572  	s.Require().NoError(err)
   573  	messages := sendResponse.Messages()
   574  	s.Require().Len(messages, 2)
   575  
   576  	var deletedMessage, replyMessage *common.Message
   577  	if messages[0].ID == ogMessage.ID {
   578  		deletedMessage = messages[0]
   579  		replyMessage = messages[1]
   580  	} else {
   581  		deletedMessage = messages[1]
   582  		replyMessage = messages[0]
   583  	}
   584  
   585  	s.Require().True(deletedMessage.DeletedForMe)
   586  	s.Require().NotEmpty(replyMessage.ImageLocalURL)
   587  }