github.com/status-im/status-go@v1.1.0/protocol/messenger_delete_message_for_me_test.go (about) 1 package protocol 2 3 import ( 4 "context" 5 "crypto/ecdsa" 6 "errors" 7 "testing" 8 9 "github.com/stretchr/testify/suite" 10 "go.uber.org/zap" 11 12 gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" 13 "github.com/status-im/status-go/eth-node/crypto" 14 "github.com/status-im/status-go/eth-node/types" 15 "github.com/status-im/status-go/protocol/common" 16 "github.com/status-im/status-go/protocol/encryption/multidevice" 17 "github.com/status-im/status-go/protocol/protobuf" 18 "github.com/status-im/status-go/protocol/tt" 19 "github.com/status-im/status-go/waku" 20 ) 21 22 func TestMessengerDeleteMessageForMeSuite(t *testing.T) { 23 suite.Run(t, new(MessengerDeleteMessageForMeSuite)) 24 } 25 26 type MessengerDeleteMessageForMeSuite struct { 27 suite.Suite 28 privateKey *ecdsa.PrivateKey // private key for the main instance of Messenger 29 alice1 *Messenger 30 alice2 *Messenger 31 // If one wants to send messages between different instances of Messenger, 32 // a single waku service should be shared. 33 shh types.Waku 34 logger *zap.Logger 35 } 36 37 func (s *MessengerDeleteMessageForMeSuite) newMessenger() *Messenger { 38 if s.privateKey == nil { 39 privateKey, err := crypto.GenerateKey() 40 s.Require().NoError(err) 41 42 s.privateKey = privateKey 43 } 44 45 messenger, err := newMessengerWithKey(s.shh, s.privateKey, s.logger, nil) 46 s.Require().NoError(err) 47 return messenger 48 } 49 50 func (s *MessengerDeleteMessageForMeSuite) otherNewMessenger() *Messenger { 51 privateKey, err := crypto.GenerateKey() 52 s.Require().NoError(err) 53 54 messenger, err := newMessengerWithKey(s.shh, privateKey, s.logger, nil) 55 s.Require().NoError(err) 56 return messenger 57 } 58 59 func (s *MessengerDeleteMessageForMeSuite) SetupTest() { 60 s.logger = tt.MustCreateTestLogger() 61 62 config := waku.DefaultConfig 63 config.MinimumAcceptedPoW = 0 64 shh := waku.New(&config, s.logger) 65 s.shh = gethbridge.NewGethWakuWrapper(shh) 66 s.Require().NoError(shh.Start()) 67 68 s.alice1 = s.newMessenger() 69 s.alice2 = s.newMessenger() 70 } 71 72 func (s *MessengerDeleteMessageForMeSuite) TearDownTest() { 73 TearDownMessenger(&s.Suite, s.alice1) 74 TearDownMessenger(&s.Suite, s.alice2) 75 _ = s.logger.Sync() 76 } 77 78 func (s *MessengerDeleteMessageForMeSuite) Pair() { 79 err := s.alice2.SetInstallationMetadata(s.alice2.installationID, &multidevice.InstallationMetadata{ 80 Name: "alice2", 81 DeviceType: "alice2", 82 }) 83 s.Require().NoError(err) 84 response, err := s.alice2.SendPairInstallation(context.Background(), nil) 85 s.Require().NoError(err) 86 s.Require().NotNil(response) 87 s.Require().Len(response.Chats(), 1) 88 s.Require().False(response.Chats()[0].Active) 89 90 // Wait for the message to reach its destination 91 response, err = WaitOnMessengerResponse( 92 s.alice1, 93 func(r *MessengerResponse) bool { return len(r.Installations()) > 0 }, 94 "installation not received", 95 ) 96 97 s.Require().NoError(err) 98 actualInstallation := response.Installations()[0] 99 s.Require().Equal(s.alice2.installationID, actualInstallation.ID) 100 s.Require().NotNil(actualInstallation.InstallationMetadata) 101 s.Require().Equal("alice2", actualInstallation.InstallationMetadata.Name) 102 s.Require().Equal("alice2", actualInstallation.InstallationMetadata.DeviceType) 103 104 err = s.alice1.EnableInstallation(s.alice2.installationID) 105 s.Require().NoError(err) 106 } 107 108 func (s *MessengerDeleteMessageForMeSuite) TestDeleteMessageForMe() { 109 s.Pair() 110 chatID := "foobarsynctest" 111 _, err := s.alice1.createPublicChat(chatID, &MessengerResponse{}) 112 s.Require().NoError(err) 113 114 _, err = s.alice2.createPublicChat(chatID, &MessengerResponse{}) 115 s.Require().NoError(err) 116 117 otherMessenger := s.otherNewMessenger() 118 _, err = otherMessenger.createPublicChat(chatID, &MessengerResponse{}) 119 s.Require().NoError(err) 120 121 chat := otherMessenger.Chat(chatID) 122 message := buildTestMessage(*chat) 123 124 response, err := otherMessenger.SendChatMessage(context.Background(), message) 125 s.Require().NoError(err) 126 messageID := response.Messages()[0].ID 127 128 var receivedPubChatMessage *common.Message 129 var alice1ReceivedMessage, alice2ReceivedMessage bool 130 var notReceivedMessageError = errors.New("not received all messages") 131 err = tt.RetryWithBackOff(func() error { 132 response, err = s.alice1.RetrieveAll() 133 if err != nil { 134 return err 135 } 136 if len(response.Messages()) > 0 { 137 alice1ReceivedMessage = true 138 } 139 140 response, err = s.alice2.RetrieveAll() 141 if err != nil { 142 return err 143 } 144 if len(response.Messages()) > 0 { 145 alice2ReceivedMessage = true 146 } 147 148 messages := response.Messages() 149 if len(messages) > 0 { 150 receivedPubChatMessage = messages[0] 151 if alice1ReceivedMessage && alice2ReceivedMessage { 152 return nil 153 } 154 } 155 156 return notReceivedMessageError 157 }) 158 s.Require().NoError(err) 159 s.Require().Equal(receivedPubChatMessage.ChatId, chatID) 160 s.Require().Equal(receivedPubChatMessage.ID, messageID) 161 s.Require().False(receivedPubChatMessage.DeletedForMe) 162 163 // message synced to alice1 164 alice1Msg, err := s.alice1.MessageByID(messageID) 165 s.Require().NoError(err) 166 s.Require().False(alice1Msg.DeletedForMe) 167 168 response, err = s.alice1.DeleteMessageForMeAndSync(context.Background(), chatID, messageID) 169 s.Require().NoError(err) 170 s.Require().True(response.Messages()[0].DeletedForMe) 171 s.Require().Equal(response.Chats()[0].LastMessage.ID, messageID) 172 s.Require().Equal(response.Chats()[0].LastMessage.DeletedForMe, true) 173 174 err = tt.RetryWithBackOff(func() error { 175 response, err = s.alice2.RetrieveAll() 176 if err != nil { 177 return err 178 } 179 180 if len(response.messages) > 0 { 181 return nil 182 } 183 184 return notReceivedMessageError 185 }) 186 s.Require().NoError(err) 187 188 deletedForMeMessage, err := s.alice2.MessageByID(messageID) 189 s.Require().NoError(err) 190 s.Require().True(deletedForMeMessage.DeletedForMe) 191 192 // no DeletedForMe in others' message 193 err = tt.RetryWithBackOff(func() error { 194 response, err = otherMessenger.RetrieveAll() 195 if err != nil { 196 return err 197 } 198 199 if len(response.messages) > 0 { 200 return nil 201 } 202 203 return notReceivedMessageError 204 }) 205 s.Require().ErrorIs(err, notReceivedMessageError) 206 otherMessage, err := otherMessenger.MessageByID(messageID) 207 s.Require().NoError(err) 208 s.Require().False(otherMessage.DeletedForMe) 209 } 210 211 func (s *MessengerDeleteMessageForMeSuite) TestDeleteImageMessageFromReceiverSide() { 212 213 alice := s.otherNewMessenger() 214 defer TearDownMessenger(&s.Suite, alice) 215 216 bob := s.otherNewMessenger() 217 defer TearDownMessenger(&s.Suite, bob) 218 219 theirChat := CreateOneToOneChat("Their 1TO1", &s.privateKey.PublicKey, alice.transport) 220 err := alice.SaveChat(theirChat) 221 s.Require().NoError(err) 222 223 ourChat := CreateOneToOneChat("Our 1TO1", &alice.identity.PublicKey, alice.transport) 224 err = bob.SaveChat(ourChat) 225 s.Require().NoError(err) 226 227 messageCount := 3 228 var album []*common.Message 229 for i := 0; i < messageCount; i++ { 230 image, err := buildImageWithoutAlbumIDMessage(*ourChat) 231 s.NoError(err) 232 album = append(album, image) 233 } 234 235 response, err := bob.SendChatMessages(context.Background(), album) 236 s.NoError(err) 237 238 // Check that album count was the number of the images sent 239 imagesCount := uint32(0) 240 for _, message := range response.Messages() { 241 if message.ContentType == protobuf.ChatMessage_IMAGE { 242 imagesCount++ 243 } 244 } 245 for _, message := range response.Messages() { 246 s.Require().NotNil(message.GetImage()) 247 s.Require().Equal(message.GetImage().AlbumImagesCount, imagesCount) 248 } 249 250 s.Require().Equal(messageCount, len(response.Messages()), "it returns the messages") 251 s.Require().NoError(err) 252 s.Require().Len(response.Messages(), messageCount) 253 254 response, err = WaitOnMessengerResponse( 255 alice, 256 func(r *MessengerResponse) bool { return len(r.messages) == messageCount }, 257 "no messages", 258 ) 259 260 s.Require().NoError(err) 261 s.Require().Len(response.Chats(), 1) 262 s.Require().Len(response.Messages(), messageCount) 263 for _, message := range response.Messages() { 264 image := message.GetImage() 265 s.Require().NotNil(image, "Message.ID=%s", message.ID) 266 s.Require().Equal(image.AlbumImagesCount, imagesCount) 267 s.Require().NotEmpty(image.AlbumId, "Message.ID=%s", message.ID) 268 } 269 270 messages := response.Messages() 271 firstMessageID := messages[0].ID 272 localChatID := messages[0].LocalChatID 273 sendResponse, err := alice.DeleteMessageForMeAndSync(context.Background(), localChatID, firstMessageID) 274 s.Require().NoError(err) 275 s.Require().Len(sendResponse.Messages(), 3) 276 s.Require().Len(sendResponse.Chats(), 1) 277 278 // LastMessage marked as deleted 279 s.Require().Equal(sendResponse.Chats()[0].LastMessage.ID, album[2].ID) 280 s.Require().Equal(sendResponse.Chats()[0].LastMessage.DeletedForMe, true) 281 }