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  }