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

     1  package protocol
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/suite"
     9  	"go.uber.org/zap"
    10  
    11  	"github.com/status-im/status-go/deprecation"
    12  	"github.com/status-im/status-go/eth-node/crypto"
    13  	"github.com/status-im/status-go/eth-node/types"
    14  	multiaccountscommon "github.com/status-im/status-go/multiaccounts/common"
    15  	"github.com/status-im/status-go/multiaccounts/settings"
    16  	"github.com/status-im/status-go/protocol/common"
    17  	"github.com/status-im/status-go/protocol/protobuf"
    18  	"github.com/status-im/status-go/protocol/requests"
    19  	v1protocol "github.com/status-im/status-go/protocol/v1"
    20  )
    21  
    22  func TestMessengerContactRequestSuite(t *testing.T) {
    23  	suite.Run(t, new(MessengerContactRequestSuite))
    24  }
    25  
    26  type MessengerContactRequestSuite struct {
    27  	MessengerBaseTestSuite
    28  }
    29  
    30  func (s *MessengerContactRequestSuite) findFirstByContentType(messages []*common.Message, contentType protobuf.ChatMessage_ContentType) *common.Message {
    31  	return FindFirstByContentType(messages, contentType)
    32  }
    33  
    34  func (s *MessengerContactRequestSuite) sendContactRequest(request *requests.SendContactRequest, messenger *Messenger) {
    35  	s.logger.Info("sendContactRequest", zap.String("sender", messenger.IdentityPublicKeyString()), zap.String("receiver", request.ID))
    36  
    37  	// Send contact request
    38  	resp, err := messenger.SendContactRequest(context.Background(), request)
    39  	s.Require().NoError(err)
    40  	s.Require().NotNil(resp)
    41  
    42  	// Check CR and mutual state update messages
    43  	s.Require().Len(resp.Messages(), 2)
    44  
    45  	mutualStateUpdate := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_SENT)
    46  	s.Require().NotNil(mutualStateUpdate)
    47  
    48  	s.Require().NotNil(mutualStateUpdate.ID)
    49  	s.Require().Equal(mutualStateUpdate.From, messenger.myHexIdentity())
    50  	s.Require().Equal(mutualStateUpdate.ChatId, request.ID)
    51  	s.Require().Equal(mutualStateUpdate.Text, fmt.Sprintf(outgoingMutualStateEventSentDefaultText, request.ID))
    52  
    53  	contactRequest := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
    54  	s.Require().NotNil(contactRequest)
    55  
    56  	s.Require().Equal(common.ContactRequestStatePending, contactRequest.ContactRequestState)
    57  	s.Require().Equal(request.Message, contactRequest.Text)
    58  
    59  	// Check pending notification
    60  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
    61  	s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
    62  	s.Require().Equal(contactRequest.ID, resp.ActivityCenterNotifications()[0].Message.ID)
    63  	s.Require().Equal(contactRequest.ContactRequestState, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
    64  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true)
    65  
    66  	// Check contacts
    67  	s.Require().Len(resp.Contacts, 1)
    68  	contact := resp.Contacts[0]
    69  	s.Require().False(contact.mutual())
    70  
    71  	// Make sure it's not returned as coming from us
    72  	contactRequests, _, err := messenger.PendingContactRequests("", 10)
    73  	s.Require().NoError(err)
    74  	s.Require().Len(contactRequests, 0)
    75  
    76  	// Make sure contact is added on the sender side
    77  	contacts := messenger.AddedContacts()
    78  	s.Require().Len(contacts, 1)
    79  	s.Require().Equal(ContactRequestStateSent, contacts[0].ContactRequestLocalState)
    80  	s.Require().NotNil(contacts[0].DisplayName)
    81  
    82  	// Check contact's primary name matches notification's name
    83  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Name, contacts[0].PrimaryName())
    84  }
    85  
    86  func (s *MessengerContactRequestSuite) receiveContactRequest(messageText string, theirMessenger *Messenger) *common.Message {
    87  	s.logger.Info("receiveContactRequest", zap.String("receiver", theirMessenger.IdentityPublicKeyString()))
    88  
    89  	// Wait for the message to reach its destination
    90  	resp, err := WaitOnMessengerResponse(
    91  		theirMessenger,
    92  		func(r *MessengerResponse) bool {
    93  			return len(r.Contacts) == 1 && len(r.Messages()) >= 2 && len(r.ActivityCenterNotifications()) == 1
    94  		},
    95  		"no messages",
    96  	)
    97  
    98  	// Check contact request has been received
    99  	s.Require().NoError(err)
   100  	s.Require().NotNil(resp)
   101  
   102  	// Check CR and mutual state update messages
   103  	s.Require().Len(resp.Messages(), 2)
   104  
   105  	contactRequest := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   106  	s.Require().NotNil(contactRequest)
   107  
   108  	s.Require().Equal(common.ContactRequestStatePending, contactRequest.ContactRequestState)
   109  	s.Require().Equal(messageText, contactRequest.Text)
   110  
   111  	mutualStateUpdate := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_SENT)
   112  	s.Require().NotNil(mutualStateUpdate)
   113  
   114  	s.Require().Equal(mutualStateUpdate.From, contactRequest.From)
   115  	s.Require().Equal(mutualStateUpdate.ChatId, contactRequest.From)
   116  	s.Require().Equal(mutualStateUpdate.Text, fmt.Sprintf(incomingMutualStateEventSentDefaultText, contactRequest.From))
   117  
   118  	// Check activity center notification is of the right type
   119  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   120  	s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
   121  	s.Require().Equal(contactRequest.ID, resp.ActivityCenterNotifications()[0].Message.ID)
   122  	s.Require().Equal(contactRequest.ContactRequestState, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   123  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, false)
   124  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false)
   125  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false)
   126  
   127  	notifications, err := theirMessenger.ActivityCenterNotifications(ActivityCenterNotificationsRequest{
   128  		Cursor:        "",
   129  		Limit:         10,
   130  		ActivityTypes: []ActivityCenterType{ActivityCenterNotificationTypeContactRequest},
   131  		ReadType:      ActivityCenterQueryParamsReadUnread,
   132  	},
   133  	)
   134  	s.Require().NoError(err)
   135  	s.Require().Len(notifications.Notifications, 1)
   136  	s.Require().Equal(contactRequest.ID, notifications.Notifications[0].Message.ID)
   137  	s.Require().Equal(contactRequest.ContactRequestState, notifications.Notifications[0].Message.ContactRequestState)
   138  
   139  	// Check the contact state is correctly set
   140  	s.Require().Len(resp.Contacts, 1)
   141  	contact := resp.Contacts[0]
   142  	s.Require().Equal(ContactRequestStateReceived, contact.ContactRequestRemoteState)
   143  
   144  	// Check contact's primary name matches notification's name
   145  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Name, contact.PrimaryName())
   146  
   147  	// Make sure it's the latest pending contact requests
   148  	contactRequests, _, err := theirMessenger.PendingContactRequests("", 10)
   149  	s.Require().NoError(err)
   150  	s.Require().Greater(len(contactRequests), 0)
   151  	s.Require().Equal(contactRequests[0].ID, contactRequest.ID)
   152  
   153  	// Confirm latest pending contact request
   154  	resp, err = theirMessenger.GetLatestContactRequestForContact(contactRequest.From)
   155  	s.Require().NoError(err)
   156  	s.Require().Len(resp.Messages(), 1)
   157  	s.Require().Equal(contactRequest.ID, resp.Messages()[0].ID)
   158  	s.Require().Equal(common.ContactRequestStatePending, resp.Messages()[0].ContactRequestState)
   159  
   160  	return contactRequest
   161  }
   162  
   163  // This function partially logs given MessengerResponse with description.
   164  // This is helpful for testing response content during long tests.
   165  // Logged contents: Messages, Contacts, ActivityCenterNotifications
   166  func (s *MessengerContactRequestSuite) logResponse(response *MessengerResponse, description string) {
   167  	s.logger.Debug("MessengerResponse", zap.String("description", description))
   168  
   169  	for i, message := range response.Messages() {
   170  		s.logger.Debug("message",
   171  			zap.Int("index", i),
   172  			zap.String("Text", message.Text),
   173  			zap.Any("ContentType", message.ContentType),
   174  		)
   175  	}
   176  
   177  	for i, contact := range response.Contacts {
   178  		s.logger.Debug("contact",
   179  			zap.Int("index", i),
   180  			zap.Bool("Blocked", contact.Blocked),
   181  			zap.Bool("Removed", contact.Removed),
   182  			zap.Any("crRemoteState", contact.ContactRequestLocalState),
   183  			zap.Any("crLocalState", contact.ContactRequestRemoteState),
   184  		)
   185  	}
   186  
   187  	for i, notification := range response.ActivityCenterNotifications() {
   188  		messageText := ""
   189  		if notification.Message != nil {
   190  			messageText = notification.Message.Text
   191  		}
   192  		s.logger.Debug("acNotification",
   193  			zap.Int("index", i),
   194  			zap.Any("id", notification.ID),
   195  			zap.Any("Type", notification.Type),
   196  			zap.String("Message", messageText),
   197  			zap.String("Name", notification.Name),
   198  			zap.String("Author", notification.Author),
   199  		)
   200  	}
   201  }
   202  
   203  func (s *MessengerContactRequestSuite) acceptContactRequest(
   204  	contactRequest *common.Message, sender *Messenger, receiver *Messenger) {
   205  	s.logger.Info("acceptContactRequest",
   206  		zap.String("sender", sender.IdentityPublicKeyString()),
   207  		zap.String("receiver", receiver.IdentityPublicKeyString()))
   208  
   209  	// Accept contact request, receiver side
   210  	resp, err := receiver.AcceptContactRequest(context.Background(), &requests.AcceptContactRequest{ID: types.Hex2Bytes(contactRequest.ID)})
   211  	s.Require().NoError(err)
   212  
   213  	// Chack updated contact request message and mutual state update
   214  	s.Require().NotNil(resp)
   215  	s.Require().Len(resp.Messages(), 2)
   216  
   217  	contactRequestMsg := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   218  	s.Require().NotNil(contactRequestMsg)
   219  
   220  	mutualStateUpdate := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED)
   221  	s.Require().NotNil(mutualStateUpdate)
   222  
   223  	s.Require().Equal(contactRequestMsg.ID, contactRequest.ID)
   224  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequestMsg.ContactRequestState)
   225  
   226  	s.Require().Equal(mutualStateUpdate.ChatId, contactRequestMsg.From)
   227  	s.Require().Equal(mutualStateUpdate.From, contactRequestMsg.ChatId)
   228  	s.Require().Equal(mutualStateUpdate.Text, fmt.Sprintf(outgoingMutualStateEventAcceptedDefaultText, contactRequestMsg.From))
   229  
   230  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   231  	s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), contactRequest.ID)
   232  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
   233  	s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   234  
   235  	// Check the contact state is correctly set
   236  	s.Require().Len(resp.Contacts, 1)
   237  	s.Require().True(resp.Contacts[0].mutual())
   238  
   239  	// Check contact's primary name matches notification's name
   240  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Name, resp.Contacts[0].PrimaryName())
   241  
   242  	// Check we have active chat in the response
   243  	s.Require().Len(resp.Chats(), 1)
   244  	s.Require().True(resp.Chats()[0].Active)
   245  
   246  	// Make sure the sender is added to our contacts
   247  	contacts := receiver.AddedContacts()
   248  	s.Require().Len(contacts, 1)
   249  
   250  	// Make sure we consider them a mutual contact, receiver side
   251  	mutualContacts := receiver.MutualContacts()
   252  	s.Require().Len(mutualContacts, 1)
   253  
   254  	// Confirm latest pending contact request
   255  	resp, err = receiver.GetLatestContactRequestForContact(sender.IdentityPublicKeyString())
   256  	s.Require().NoError(err)
   257  	s.Require().Len(resp.Messages(), 1)
   258  	s.Require().Equal(contactRequest.ID, resp.Messages()[0].ID)
   259  	s.Require().Equal(common.ContactRequestStateAccepted, resp.Messages()[0].ContactRequestState)
   260  
   261  	// Wait for the message to reach its destination
   262  	resp, err = WaitOnMessengerResponse(sender,
   263  		func(r *MessengerResponse) bool {
   264  			return len(r.Contacts) == 1 && len(r.Messages()) == 2
   265  		},
   266  		"contact request acceptance not received",
   267  	)
   268  	s.logResponse(resp, "acceptContactRequest")
   269  	s.Require().NoError(err)
   270  	s.Require().NotNil(resp)
   271  
   272  	// Check activity center notification is of the right type
   273  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   274  	s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
   275  	s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   276  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true)
   277  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true)
   278  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false)
   279  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
   280  
   281  	// Make sure the message is updated, sender side
   282  	s.Require().Len(resp.Messages(), 2)
   283  
   284  	contactRequestMsg = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   285  	s.Require().NotNil(contactRequestMsg)
   286  
   287  	mutualStateUpdate = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED)
   288  	s.Require().NotNil(mutualStateUpdate)
   289  
   290  	s.Require().Equal(contactRequest.ID, contactRequestMsg.ID)
   291  	s.Require().Equal(contactRequest.Text, contactRequestMsg.Text)
   292  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequestMsg.ContactRequestState)
   293  
   294  	s.Require().Equal(mutualStateUpdate.From, contactRequestMsg.ChatId)
   295  	s.Require().Equal(mutualStateUpdate.ChatId, contactRequestMsg.ChatId)
   296  	s.Require().Equal(mutualStateUpdate.Text, fmt.Sprintf(incomingMutualStateEventAcceptedDefaultText, contactRequestMsg.ChatId))
   297  
   298  	// Make sure we consider them a mutual contact, sender side
   299  	mutualContacts = s.m.MutualContacts()
   300  	s.Require().Len(mutualContacts, 1)
   301  
   302  	// Check the contact state is correctly set
   303  	s.Require().Len(resp.Contacts, 1)
   304  	contact := resp.Contacts[0]
   305  	s.Require().True(contact.mutual())
   306  
   307  	// Check contact's primary name matches notification's name
   308  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Name, contact.PrimaryName())
   309  
   310  	// Sender's side chat should be active after the accepting the CR
   311  	chat, ok := s.m.allChats.Load(contact.ID)
   312  	s.Require().True(ok)
   313  	s.Require().NotNil(chat)
   314  	s.Require().True(chat.Active)
   315  
   316  	// Receiver's side chat should be also active after the accepting the CR
   317  	myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
   318  	chat, ok = receiver.allChats.Load(myID)
   319  	s.Require().True(ok)
   320  	s.Require().NotNil(chat)
   321  	s.Require().True(chat.Active)
   322  }
   323  
   324  func (s *MessengerContactRequestSuite) checkMutualContact(messenger *Messenger, contactPublicKey string) {
   325  	contacts := messenger.AddedContacts()
   326  	s.Require().Len(contacts, 1)
   327  	contact := contacts[0]
   328  	s.Require().Equal(contactPublicKey, contact.ID)
   329  	s.Require().True(contact.mutual())
   330  }
   331  
   332  func (s *MessengerContactRequestSuite) createContactRequest(contactPublicKey string, messageText string) *requests.SendContactRequest {
   333  	return &requests.SendContactRequest{
   334  		ID:      contactPublicKey,
   335  		Message: messageText,
   336  	}
   337  }
   338  
   339  func (s *MessengerContactRequestSuite) declineContactRequest(contactRequest *common.Message, theirMessenger *Messenger) {
   340  	// Dismiss contact request, receiver side
   341  	resp, err := theirMessenger.DeclineContactRequest(context.Background(), &requests.DeclineContactRequest{ID: types.Hex2Bytes(contactRequest.ID)})
   342  	s.Require().NoError(err)
   343  
   344  	// Check the contact state is correctly set
   345  	s.Require().Len(resp.Contacts, 1)
   346  	s.Require().Equal(ContactRequestStateDismissed, resp.Contacts[0].ContactRequestLocalState)
   347  
   348  	// Make sure the message is updated
   349  	s.Require().NotNil(resp)
   350  	s.Require().Len(resp.Messages(), 1)
   351  	s.Require().Equal(resp.Messages()[0].ID, contactRequest.ID)
   352  	s.Require().Equal(common.ContactRequestStateDismissed, resp.Messages()[0].ContactRequestState)
   353  
   354  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   355  	s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), contactRequest.ID)
   356  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
   357  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true)
   358  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, false)
   359  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, true)
   360  	s.Require().Equal(common.ContactRequestStateDismissed, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   361  
   362  	// Check contact's primary name matches notification's name
   363  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Name, resp.Contacts[0].PrimaryName())
   364  
   365  	// Make sure the sender is not added to our contacts
   366  	contacts := theirMessenger.AddedContacts()
   367  	s.Require().Len(contacts, 0)
   368  }
   369  
   370  func (s *MessengerContactRequestSuite) retractContactRequest(contactID string, theirMessenger *Messenger) {
   371  	resp, err := s.m.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(contactID)})
   372  	s.Require().NoError(err)
   373  	s.Require().NotNil(resp)
   374  	s.Require().Len(resp.Contacts, 1)
   375  	s.Require().False(resp.Contacts[0].hasAddedUs())
   376  	s.Require().False(resp.Contacts[0].added())
   377  
   378  	// Check the contact state is correctly set
   379  	s.Require().Len(resp.Contacts, 1)
   380  	s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestLocalState)
   381  	s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestRemoteState)
   382  
   383  	// Check outgoing mutual state message
   384  	s.Require().Len(resp.Messages(), 1)
   385  	mutualStateUpdate := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED)
   386  	s.Require().NotNil(mutualStateUpdate)
   387  
   388  	myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
   389  	s.Require().Equal(mutualStateUpdate.From, myID)
   390  	s.Require().Equal(mutualStateUpdate.ChatId, contactID)
   391  	s.Require().Equal(mutualStateUpdate.Text, fmt.Sprintf(outgoingMutualStateEventRemovedDefaultText, contactID))
   392  
   393  	// Wait for the message to reach its destination
   394  	resp, err = WaitOnMessengerResponse(
   395  		theirMessenger,
   396  		func(r *MessengerResponse) bool {
   397  			return len(r.Contacts) > 0 && len(r.ActivityCenterNotifications()) == 1
   398  		},
   399  		"no messages",
   400  	)
   401  	s.Require().NoError(err)
   402  	s.Require().NotNil(resp)
   403  	s.Require().Len(resp.Contacts, 1)
   404  
   405  	s.Require().Equal(myID, resp.Contacts[0].ID)
   406  
   407  	s.Require().False(resp.Contacts[0].added())
   408  	s.Require().False(resp.Contacts[0].hasAddedUs())
   409  	s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestLocalState)
   410  	s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestRemoteState)
   411  
   412  	// Check pending notification
   413  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   414  	s.Require().Equal(ActivityCenterNotificationTypeContactRemoved, resp.ActivityCenterNotifications()[0].Type)
   415  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, false)
   416  
   417  	// Check incoming mutual state message
   418  	s.Require().Len(resp.Messages(), 1)
   419  	mutualStateUpdate = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED)
   420  	s.Require().NotNil(mutualStateUpdate)
   421  
   422  	s.Require().Equal(mutualStateUpdate.From, myID)
   423  	s.Require().Equal(mutualStateUpdate.ChatId, myID)
   424  	s.Require().Equal(mutualStateUpdate.Text, fmt.Sprintf(incomingMutualStateEventRemovedDefaultText, myID))
   425  }
   426  
   427  func (s *MessengerContactRequestSuite) syncInstallationContactV2FromContact(contact *Contact) protobuf.SyncInstallationContactV2 {
   428  	return protobuf.SyncInstallationContactV2{
   429  		LastUpdatedLocally:        contact.LastUpdatedLocally,
   430  		LastUpdated:               contact.LastUpdated,
   431  		Id:                        contact.ID,
   432  		DisplayName:               contact.DisplayName,
   433  		EnsName:                   contact.EnsName,
   434  		LocalNickname:             contact.LocalNickname,
   435  		Added:                     contact.added(),
   436  		Blocked:                   contact.Blocked,
   437  		Muted:                     false,
   438  		HasAddedUs:                contact.hasAddedUs(),
   439  		Removed:                   contact.Removed,
   440  		ContactRequestLocalState:  int64(contact.ContactRequestLocalState),
   441  		ContactRequestRemoteState: int64(contact.ContactRequestRemoteState),
   442  		ContactRequestRemoteClock: int64(contact.ContactRequestRemoteClock),
   443  		ContactRequestLocalClock:  int64(contact.ContactRequestLocalClock),
   444  		VerificationStatus:        int64(contact.VerificationStatus),
   445  		TrustStatus:               int64(contact.TrustStatus),
   446  	}
   447  }
   448  
   449  func (s *MessengerContactRequestSuite) TestReceiveAndAcceptContactRequest() { //nolint: unused
   450  	messageText := "hello!"
   451  
   452  	theirMessenger := s.newMessenger()
   453  	defer TearDownMessenger(&s.Suite, theirMessenger)
   454  
   455  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
   456  	request := &requests.SendContactRequest{
   457  		ID:      contactID,
   458  		Message: messageText,
   459  	}
   460  	s.sendContactRequest(request, s.m)
   461  	contactRequest := s.receiveContactRequest(messageText, theirMessenger)
   462  	s.acceptContactRequest(contactRequest, s.m, theirMessenger)
   463  }
   464  
   465  func (s *MessengerContactRequestSuite) TestReceiveAndDismissContactRequest() {
   466  	messageText := "hello!"
   467  
   468  	theirMessenger := s.newMessenger()
   469  	defer TearDownMessenger(&s.Suite, theirMessenger)
   470  
   471  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
   472  	request := &requests.SendContactRequest{
   473  		ID:      contactID,
   474  		Message: messageText,
   475  	}
   476  	s.sendContactRequest(request, s.m)
   477  	contactRequest := s.receiveContactRequest(messageText, theirMessenger)
   478  	s.declineContactRequest(contactRequest, theirMessenger)
   479  }
   480  
   481  func (s *MessengerContactRequestSuite) TestReceiveAcceptAndRetractContactRequest() { //nolint: unused
   482  	messageText := "hello!"
   483  
   484  	theirMessenger := s.newMessenger()
   485  	defer TearDownMessenger(&s.Suite, theirMessenger)
   486  
   487  	s.Require().NoError(theirMessenger.settings.SaveSettingField(settings.MutualContactEnabled, true))
   488  
   489  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
   490  	request := &requests.SendContactRequest{
   491  		ID:      contactID,
   492  		Message: messageText,
   493  	}
   494  	s.sendContactRequest(request, s.m)
   495  	contactRequest := s.receiveContactRequest(messageText, theirMessenger)
   496  	s.acceptContactRequest(contactRequest, s.m, theirMessenger)
   497  	s.retractContactRequest(contactID, theirMessenger)
   498  }
   499  
   500  // The scenario tested is as follow:
   501  //  1. Repeat 5 times:
   502  //     2.1) Alice sends a contact request to Bob
   503  //     2.2) Bob accepts the contact request
   504  //     2.3) Alice removes bob from contacts
   505  func (s *MessengerContactRequestSuite) TestAcceptCRRemoveAndRepeat() {
   506  	theirMessenger := s.newMessenger()
   507  	defer TearDownMessenger(&s.Suite, theirMessenger)
   508  
   509  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
   510  
   511  	for i := 0; i < 5; i++ {
   512  		messageText := fmt.Sprintf("hello %d", i)
   513  		request := &requests.SendContactRequest{
   514  			ID:      contactID,
   515  			Message: messageText,
   516  		}
   517  		s.sendContactRequest(request, s.m)
   518  		contactRequest := s.receiveContactRequest(messageText, theirMessenger)
   519  		s.acceptContactRequest(contactRequest, s.m, theirMessenger)
   520  		s.retractContactRequest(contactID, theirMessenger)
   521  	}
   522  }
   523  
   524  // The scenario tested is as follow:
   525  // 1) Alice sends a contact request to Bob
   526  // 2) Bob declines the contact request
   527  // 3) Alice fails to send a new contact request to Bob
   528  func (s *MessengerContactRequestSuite) TestAliceTriesToSpamBobWithContactRequests() {
   529  	messageTextAlice := "You wanna play with fire, Bobby?!"
   530  	alice := s.m
   531  
   532  	bob := s.newMessenger()
   533  	defer TearDownMessenger(&s.Suite, bob)
   534  
   535  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
   536  
   537  	// Alice sends a contact request to Bob
   538  	request := &requests.SendContactRequest{
   539  		ID:      bobID,
   540  		Message: messageTextAlice,
   541  	}
   542  	s.sendContactRequest(request, alice)
   543  
   544  	contactRequest := s.receiveContactRequest(messageTextAlice, bob)
   545  	s.Require().NotNil(contactRequest)
   546  
   547  	// Bob declines the contact request
   548  	s.declineContactRequest(contactRequest, bob)
   549  
   550  	// Alice sends a new contact request
   551  	resp, err := alice.SendContactRequest(context.Background(), request)
   552  	s.Require().NoError(err)
   553  	s.Require().NotNil(resp)
   554  
   555  	// Check CR and mutual state update messages
   556  	s.Require().Len(resp.Messages(), 2)
   557  
   558  	contactRequest = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   559  	s.Require().NotNil(contactRequest)
   560  
   561  	s.Require().Equal(common.ContactRequestStatePending, contactRequest.ContactRequestState)
   562  	s.Require().Equal(request.Message, contactRequest.Text)
   563  
   564  	// We should not receive a CR from a rejected contact
   565  	_, err = WaitOnMessengerResponse(
   566  		bob,
   567  		func(r *MessengerResponse) bool {
   568  			return len(r.Messages()) > 0 &&
   569  				s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST) != nil
   570  		},
   571  		"no messages",
   572  	)
   573  	s.Require().Error(err)
   574  	s.Require().ErrorContains(err, "no messages")
   575  }
   576  
   577  // The scenario tested is as follow:
   578  // 1) Alice sends a contact request to Bob
   579  // 2) Bob accepts the contact
   580  // 3) Bob accepts the contact request (again!)
   581  // 4) No extra mesages on Alice's side
   582  func (s *MessengerContactRequestSuite) TestAliceSeesOnlyOneAcceptFromBob() {
   583  	messageTextAlice := "You wanna play with fire, Bobby?!"
   584  	alice := s.m
   585  
   586  	bob := s.newMessenger()
   587  	defer TearDownMessenger(&s.Suite, bob)
   588  
   589  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
   590  
   591  	// Alice sends a contact request to Bob
   592  	request := &requests.SendContactRequest{
   593  		ID:      bobID,
   594  		Message: messageTextAlice,
   595  	}
   596  	s.sendContactRequest(request, alice)
   597  
   598  	contactRequest := s.receiveContactRequest(messageTextAlice, bob)
   599  	s.Require().NotNil(contactRequest)
   600  
   601  	// Bob accepts the contact request
   602  	s.acceptContactRequest(contactRequest, alice, bob)
   603  
   604  	// Accept contact request again
   605  	_, err := bob.AcceptContactRequest(context.Background(), &requests.AcceptContactRequest{ID: types.Hex2Bytes(contactRequest.ID)})
   606  	s.Require().NoError(err)
   607  
   608  	// Check we don't have extra messages on Alice's side
   609  	resp, err := WaitOnMessengerResponse(alice,
   610  		func(r *MessengerResponse) bool {
   611  			return len(r.ActivityCenterNotifications()) == 1 && len(r.Messages()) == 1
   612  		},
   613  		"contact request acceptance not received",
   614  	)
   615  	s.Require().NoError(err)
   616  	s.Require().NotNil(resp)
   617  
   618  	// Check activity center notification is of the right type
   619  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   620  	s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
   621  	s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   622  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true)
   623  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Accepted, true)
   624  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Dismissed, false)
   625  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
   626  
   627  	// Make sure the message is updated, sender side
   628  	s.Require().Len(resp.Messages(), 1)
   629  
   630  	contactRequest = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   631  	s.Require().NotNil(contactRequest)
   632  
   633  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequest.ContactRequestState)
   634  	s.Require().Equal(request.Message, contactRequest.Text)
   635  }
   636  
   637  func (s *MessengerContactRequestSuite) TestReceiveAndAcceptContactRequestTwice() { //nolint: unused
   638  	messageText := "hello!"
   639  
   640  	theirMessenger := s.newMessenger()
   641  	defer TearDownMessenger(&s.Suite, theirMessenger)
   642  
   643  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
   644  	request := &requests.SendContactRequest{
   645  		ID:      contactID,
   646  		Message: messageText,
   647  	}
   648  	s.sendContactRequest(request, s.m)
   649  	contactRequest := s.receiveContactRequest(messageText, theirMessenger)
   650  	s.acceptContactRequest(contactRequest, s.m, theirMessenger)
   651  
   652  	// Resend contact request with higher clock value
   653  	resp, err := s.m.SendContactRequest(context.Background(), request)
   654  	s.Require().NoError(err)
   655  	s.Require().NotNil(resp)
   656  
   657  	// Check CR and mutual state update messages
   658  	s.Require().Len(resp.Messages(), 2)
   659  
   660  	contactRequest = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   661  	s.Require().NotNil(contactRequest)
   662  
   663  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequest.ContactRequestState)
   664  	s.Require().Equal(request.Message, contactRequest.Text)
   665  
   666  	// We should not receive a CR from a mutual contact
   667  	_, err = WaitOnMessengerResponse(
   668  		theirMessenger,
   669  		func(r *MessengerResponse) bool {
   670  			return len(r.Messages()) > 0 &&
   671  				s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST) != nil
   672  		},
   673  		"no messages",
   674  	)
   675  	s.Require().Error(err)
   676  	s.Require().ErrorContains(err, "no messages")
   677  }
   678  
   679  func (s *MessengerContactRequestSuite) TestAcceptLatestContactRequestForContact() {
   680  	messageText := "hello!"
   681  
   682  	theirMessenger := s.newMessenger()
   683  	defer TearDownMessenger(&s.Suite, theirMessenger)
   684  
   685  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
   686  	request := &requests.SendContactRequest{
   687  		ID:      contactID,
   688  		Message: messageText,
   689  	}
   690  	s.sendContactRequest(request, s.m)
   691  	contactRequest := s.receiveContactRequest(messageText, theirMessenger)
   692  
   693  	// Accept latest contact request, receiver side
   694  	myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
   695  	resp, err := theirMessenger.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
   696  	s.Require().NoError(err)
   697  
   698  	// Make sure the message is updated
   699  	s.Require().NotNil(resp)
   700  	s.Require().Len(resp.Messages(), 2)
   701  
   702  	contactRequestMsg := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   703  	s.Require().NotNil(contactRequestMsg)
   704  
   705  	mutualStateUpdate := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED)
   706  	s.Require().NotNil(mutualStateUpdate)
   707  
   708  	s.Require().Equal(contactRequestMsg.ID, contactRequest.ID)
   709  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequestMsg.ContactRequestState)
   710  
   711  	s.Require().Equal(mutualStateUpdate.From, contactRequest.ChatId)
   712  	s.Require().Equal(mutualStateUpdate.ChatId, contactRequest.From)
   713  
   714  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   715  	s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), contactRequest.ID)
   716  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
   717  	s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   718  
   719  	// Check the contact state is correctly set
   720  	s.Require().Len(resp.Contacts, 1)
   721  	s.Require().True(resp.Contacts[0].mutual())
   722  
   723  	// Make sure the sender is added to our contacts
   724  	contacts := theirMessenger.AddedContacts()
   725  	s.Require().Len(contacts, 1)
   726  
   727  	// Make sure we consider them a mutual contact, receiver side
   728  	mutualContacts := theirMessenger.MutualContacts()
   729  	s.Require().Len(mutualContacts, 1)
   730  
   731  	// Wait for the message to reach its destination
   732  	resp, err = WaitOnMessengerResponse(
   733  		s.m,
   734  		func(r *MessengerResponse) bool {
   735  			return len(r.Contacts) == 1 && len(r.Messages()) == 2 && len(r.ActivityCenterNotifications()) == 1
   736  		},
   737  		"no messages",
   738  	)
   739  	s.Require().NoError(err)
   740  
   741  	// Make sure the message is updated, sender side
   742  	s.Require().NotNil(resp)
   743  
   744  	s.Require().Len(resp.Messages(), 2)
   745  
   746  	contactRequestMsg = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
   747  	s.Require().NotNil(contactRequestMsg)
   748  
   749  	mutualStateUpdate = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED)
   750  	s.Require().NotNil(mutualStateUpdate)
   751  
   752  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequestMsg.ContactRequestState)
   753  
   754  	s.Require().Equal(mutualStateUpdate.From, contactRequest.ChatId)
   755  	s.Require().Equal(mutualStateUpdate.ChatId, contactRequest.ChatId)
   756  
   757  	// Check activity center notification is of the right type
   758  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   759  	s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
   760  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
   761  	s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   762  
   763  	// Make sure we consider them a mutual contact, sender side
   764  	mutualContacts = s.m.MutualContacts()
   765  	s.Require().Len(mutualContacts, 1)
   766  
   767  	// Check the contact state is correctly set
   768  	s.Require().Len(resp.Contacts, 1)
   769  	s.Require().True(resp.Contacts[0].mutual())
   770  }
   771  
   772  func (s *MessengerContactRequestSuite) TestDismissLatestContactRequestForContact() {
   773  	messageText := "hello!"
   774  
   775  	theirMessenger := s.newMessenger()
   776  	defer TearDownMessenger(&s.Suite, theirMessenger)
   777  
   778  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
   779  	request := &requests.SendContactRequest{
   780  		ID:      contactID,
   781  		Message: messageText,
   782  	}
   783  	s.sendContactRequest(request, s.m)
   784  	contactRequest := s.receiveContactRequest(messageText, theirMessenger)
   785  
   786  	// Dismiss latest contact request, receiver side
   787  	myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
   788  	resp, err := theirMessenger.DismissLatestContactRequestForContact(context.Background(), &requests.DismissLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
   789  	s.Require().NoError(err)
   790  
   791  	// Make sure the message is updated
   792  	s.Require().NotNil(resp)
   793  	s.Require().Len(resp.Messages(), 1)
   794  	s.Require().Equal(resp.Messages()[0].ID, contactRequest.ID)
   795  	s.Require().Equal(common.ContactRequestStateDismissed, resp.Messages()[0].ContactRequestState)
   796  
   797  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
   798  	s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), contactRequest.ID)
   799  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
   800  	s.Require().Equal(common.ContactRequestStateDismissed, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
   801  }
   802  
   803  func (s *MessengerContactRequestSuite) TestPairedDevicesRemoveContact() {
   804  	messageText := "hello!"
   805  
   806  	alice1 := s.m
   807  	alice2, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
   808  	s.Require().NoError(err)
   809  	defer TearDownMessenger(&s.Suite, alice2)
   810  
   811  	prepAliceMessengersForPairing(&s.Suite, alice1, alice2)
   812  
   813  	PairDevices(&s.Suite, alice1, alice2)
   814  	PairDevices(&s.Suite, alice2, alice1)
   815  
   816  	bob := s.newMessenger()
   817  	defer TearDownMessenger(&s.Suite, bob)
   818  
   819  	// Alice sends a contact request to bob
   820  	contactID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
   821  	request := &requests.SendContactRequest{
   822  		ID:      contactID,
   823  		Message: messageText,
   824  	}
   825  	s.sendContactRequest(request, alice1)
   826  	contactRequest := s.receiveContactRequest(messageText, bob)
   827  	s.acceptContactRequest(contactRequest, alice1, bob)
   828  
   829  	// Wait for the message to reach its destination
   830  	resp, err := WaitOnMessengerResponse(
   831  		alice2,
   832  		func(r *MessengerResponse) bool {
   833  			return len(r.Contacts) > 0
   834  		},
   835  		"no messages",
   836  	)
   837  	s.Require().NoError(err)
   838  
   839  	// Make sure we consider them a mutual contact, sender side
   840  	mutualContacts := alice2.MutualContacts()
   841  	s.Require().Len(mutualContacts, 1)
   842  
   843  	// Check the contact state is correctly set
   844  	s.Require().Len(resp.Contacts, 1)
   845  	s.Require().True(resp.Contacts[0].mutual())
   846  
   847  	s.retractContactRequest(contactID, bob)
   848  
   849  	// Check on alice2 side
   850  	resp, err = WaitOnMessengerResponse(
   851  		alice2,
   852  		func(r *MessengerResponse) bool {
   853  			return len(r.Contacts) > 0
   854  		},
   855  		"no messages",
   856  	)
   857  	s.Require().NoError(err)
   858  	s.Require().NotNil(resp)
   859  	s.Require().Len(resp.Contacts, 1)
   860  
   861  	// Check the contact state is correctly set
   862  	s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestLocalState)
   863  	s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestRemoteState)
   864  }
   865  
   866  // The scenario tested is as follow:
   867  // 1) Alice sends a contact request to Bob
   868  // 2) Bob accepts the contact request
   869  // 3) Alice restores state on a different device
   870  // 4) Alice sends a contact request to bob
   871  // Bob will need to help Alice recover her state, since as far as he can see
   872  // that's an already accepted contact request
   873  func (s *MessengerContactRequestSuite) TestAliceRecoverStateSendContactRequest() {
   874  	messageText := "hello!"
   875  
   876  	alice1 := s.m
   877  
   878  	bob := s.newMessenger()
   879  	defer TearDownMessenger(&s.Suite, bob)
   880  
   881  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
   882  
   883  	// Alice sends a contact request to bob
   884  	request := &requests.SendContactRequest{
   885  		ID:      bobID,
   886  		Message: messageText,
   887  	}
   888  	s.sendContactRequest(request, alice1)
   889  
   890  	contactRequest := s.receiveContactRequest(messageText, bob)
   891  	s.Require().NotNil(contactRequest)
   892  
   893  	// Bob accepts the contact request
   894  	s.acceptContactRequest(contactRequest, alice1, bob)
   895  
   896  	// Alice resets her device
   897  	alice2, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
   898  	s.Require().NoError(err)
   899  	defer TearDownMessenger(&s.Suite, alice2)
   900  
   901  	// adds bob again to her device
   902  	s.sendContactRequest(request, alice2)
   903  
   904  	// Wait for the message to reach its destination
   905  	_, err = WaitOnMessengerResponse(
   906  		bob,
   907  		func(r *MessengerResponse) bool {
   908  			return len(r.Contacts) > 0
   909  		},
   910  		"no messages",
   911  	)
   912  	s.Require().NoError(err)
   913  
   914  	// Bob should be a mutual contact with alice, nothing has changed
   915  	s.Require().Len(bob.MutualContacts(), 1)
   916  
   917  	// Alice retrieves her messages, she should have been notified by
   918  	// dear bobby that they were contacts
   919  	resp, err := WaitOnMessengerResponse(
   920  		alice2,
   921  		func(r *MessengerResponse) bool {
   922  			return len(r.Contacts) > 0
   923  		},
   924  		"no messages",
   925  	)
   926  	s.Require().NoError(err)
   927  	s.Require().NotNil(resp)
   928  	s.Require().Len(resp.Contacts, 1)
   929  
   930  	// Check the contact state is correctly set
   931  	s.Require().True(resp.Contacts[0].mutual())
   932  }
   933  
   934  // The scenario tested is as follow:
   935  // 1) Alice sends a contact request to Bob
   936  // 2) Bob accepts the contact request
   937  // 3) Alice restores state on a different device
   938  // 4) Bob sends a message to alice
   939  // Alice will show a contact request from bob
   940  func (s *MessengerContactRequestSuite) TestAliceRecoverStateReceiveContactRequest() {
   941  	messageText := "hello!"
   942  
   943  	alice1 := s.m
   944  
   945  	bob := s.newMessenger()
   946  	defer TearDownMessenger(&s.Suite, bob)
   947  
   948  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
   949  
   950  	// Alice sends a contact request to bob
   951  	request := &requests.SendContactRequest{
   952  		ID:      bobID,
   953  		Message: messageText,
   954  	}
   955  	s.sendContactRequest(request, alice1)
   956  
   957  	contactRequest := s.receiveContactRequest(messageText, bob)
   958  	s.Require().NotNil(contactRequest)
   959  
   960  	// Bob accepts the contact request
   961  	s.acceptContactRequest(contactRequest, alice1, bob)
   962  
   963  	// Alice resets her device
   964  	alice2, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
   965  	s.Require().NoError(err)
   966  	defer TearDownMessenger(&s.Suite, alice2)
   967  
   968  	// We want to facilitate the discovery of the x3dh bundl here, since bob does not know about alice device
   969  
   970  	alice2Bundle, err := alice2.encryptor.GetBundle(alice2.identity)
   971  	s.Require().NoError(err)
   972  
   973  	_, err = bob.encryptor.ProcessPublicBundle(bob.identity, alice2Bundle)
   974  	s.Require().NoError(err)
   975  
   976  	// Bob sends a chat message to alice
   977  
   978  	var chat Chat
   979  	chats := bob.Chats()
   980  	for i, c := range chats {
   981  		if c.ID == alice1.myHexIdentity() && c.OneToOne() {
   982  			chat = *chats[i]
   983  		}
   984  	}
   985  	s.Require().NotNil(chat)
   986  
   987  	inputMessage := buildTestMessage(chat)
   988  	_, err = bob.SendChatMessage(context.Background(), inputMessage)
   989  	s.NoError(err)
   990  
   991  	// Alice retrieves the chat message, it should be
   992  	resp, err := WaitOnMessengerResponse(
   993  		alice2,
   994  		func(r *MessengerResponse) bool {
   995  			return len(r.ActivityCenterNotifications()) == 1
   996  		},
   997  		"no messages",
   998  	)
   999  	s.Require().NoError(err)
  1000  	s.Require().NotNil(resp)
  1001  	s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
  1002  	s.Require().Len(resp.Contacts, 1)
  1003  
  1004  	// Check the contact state is correctly set
  1005  	s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestLocalState)
  1006  	s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestRemoteState)
  1007  }
  1008  
  1009  // The scenario tested is as follow:
  1010  // 1) Alice sends a contact request to Bob
  1011  // 2) Bob accepts the contact request
  1012  // 3) Bob goes offline
  1013  // 4) Alice retracts the contact request
  1014  // 5) Alice adds bob back to her contacts
  1015  // 6) Bob goes online, they receive 4 and 5 in the correct order
  1016  func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsCorrectOrder() {
  1017  	messageText := "hello!"
  1018  
  1019  	alice1 := s.m
  1020  
  1021  	bob := s.newMessenger()
  1022  	defer TearDownMessenger(&s.Suite, bob)
  1023  
  1024  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
  1025  
  1026  	// Alice sends a contact request to bob
  1027  	request := &requests.SendContactRequest{
  1028  		ID:      bobID,
  1029  		Message: messageText,
  1030  	}
  1031  	s.sendContactRequest(request, alice1)
  1032  
  1033  	contactRequest := s.receiveContactRequest(messageText, bob)
  1034  	s.Require().NotNil(contactRequest)
  1035  
  1036  	// Bob accepts the contact request
  1037  	s.acceptContactRequest(contactRequest, alice1, bob)
  1038  
  1039  	// Alice removes Bob from contacts
  1040  	_, err := alice1.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(bob.myHexIdentity())})
  1041  	s.Require().NoError(err)
  1042  
  1043  	// Adds bob again to her device
  1044  	s.sendContactRequest(request, alice1)
  1045  
  1046  	// Wait for the message to reach its destination
  1047  	_, err = WaitOnMessengerResponse(
  1048  		bob,
  1049  		func(r *MessengerResponse) bool {
  1050  			return len(r.ActivityCenterNotifications()) > 0
  1051  		},
  1052  		"no messages",
  1053  	)
  1054  	s.Require().NoError(err)
  1055  }
  1056  
  1057  // The scenario tested is as follow:
  1058  // 1) Alice sends a contact request to Bob
  1059  // 2) Bob accepts the contact request
  1060  // 3) Bob goes offline
  1061  // 4) Alice retracts the contact request
  1062  // 5) Alice adds bob back to her contacts
  1063  // 6) Bob goes online, they receive 4 and 5 in the wrong order
  1064  func (s *MessengerContactRequestSuite) TestAliceOfflineRetractsAndAddsWrongOrder() {
  1065  	messageText := "hello!"
  1066  
  1067  	alice1 := s.m
  1068  
  1069  	bob := s.newMessenger()
  1070  	defer TearDownMessenger(&s.Suite, bob)
  1071  
  1072  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
  1073  
  1074  	// Alice sends a contact request to bob
  1075  	request := &requests.SendContactRequest{
  1076  		ID:      bobID,
  1077  		Message: messageText,
  1078  	}
  1079  	s.sendContactRequest(request, alice1)
  1080  
  1081  	contactRequest := s.receiveContactRequest(messageText, bob)
  1082  	s.Require().NotNil(contactRequest)
  1083  
  1084  	// Bob accepts the contact request
  1085  	s.acceptContactRequest(contactRequest, alice1, bob)
  1086  
  1087  	// Alice removes Bob from contacts
  1088  	_, err := alice1.RetractContactRequest(&requests.RetractContactRequest{ID: types.Hex2Bytes(bob.myHexIdentity())})
  1089  	s.Require().NoError(err)
  1090  
  1091  	// Adds bob again to her device
  1092  	s.sendContactRequest(request, alice1)
  1093  
  1094  	// Get alice perspective of bob
  1095  	bobFromAlice := alice1.AddedContacts()[0]
  1096  
  1097  	// Get bob perspective of alice
  1098  	aliceFromBob := bob.MutualContacts()[0]
  1099  
  1100  	s.Require().NotNil(bobFromAlice)
  1101  	s.Require().NotNil(aliceFromBob)
  1102  
  1103  	// We can't simulate out-of-order messages easily, so we need to do
  1104  	// things manually here
  1105  	result := aliceFromBob.ContactRequestPropagatedStateReceived(bobFromAlice.ContactRequestPropagatedState())
  1106  	s.Require().True(result.newContactRequestReceived)
  1107  }
  1108  
  1109  // The scenario tested is as follow:
  1110  // 1) Alice sends a contact request to Bob
  1111  // 2) Bob accepts the contact request
  1112  // 3) Alice removes Bob from contacts
  1113  // 4) Make sure Alice and Bob are not mutual contacts
  1114  // 5) Alice sends new contact request
  1115  // 6) Bob accepts new contact request
  1116  func (s *MessengerContactRequestSuite) TestAliceResendsContactRequestAfterRemovingBobFromContacts() {
  1117  	messageTextFirst := "hello 1!"
  1118  
  1119  	theirMessenger := s.newMessenger()
  1120  	defer TearDownMessenger(&s.Suite, theirMessenger)
  1121  
  1122  	contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
  1123  
  1124  	// Alice sends a contact request to Bob
  1125  	request := &requests.SendContactRequest{
  1126  		ID:      contactID,
  1127  		Message: messageTextFirst,
  1128  	}
  1129  	s.sendContactRequest(request, s.m)
  1130  
  1131  	// Bob accepts the contact request
  1132  	contactRequest := s.receiveContactRequest(messageTextFirst, theirMessenger)
  1133  	s.Require().NotNil(contactRequest)
  1134  	s.acceptContactRequest(contactRequest, s.m, theirMessenger)
  1135  
  1136  	// Alice removes Bob from contacts
  1137  	s.retractContactRequest(contactID, theirMessenger)
  1138  
  1139  	// Send new contact request
  1140  	messageTextSecond := "hello 2!"
  1141  
  1142  	// Alice sends new contact request
  1143  	request = &requests.SendContactRequest{
  1144  		ID:      contactID,
  1145  		Message: messageTextSecond,
  1146  	}
  1147  	s.sendContactRequest(request, s.m)
  1148  
  1149  	// Make sure bob and alice are not mutual after sending CR
  1150  	s.Require().Len(s.m.MutualContacts(), 0)
  1151  	s.Require().Len(theirMessenger.MutualContacts(), 0)
  1152  
  1153  	// Bob accepts new contact request
  1154  	contactRequest = s.receiveContactRequest(messageTextSecond, theirMessenger)
  1155  	s.Require().NotNil(contactRequest)
  1156  	s.acceptContactRequest(contactRequest, s.m, theirMessenger)
  1157  
  1158  	// Make sure bob and alice are not mutual after sending CR
  1159  	s.Require().Len(s.m.MutualContacts(), 1)
  1160  	s.Require().Len(theirMessenger.MutualContacts(), 1)
  1161  }
  1162  
  1163  // The scenario tested is as follow:
  1164  // 1) Alice sends a contact request to Bob
  1165  // 2) Bob declines the contact request from Alice
  1166  // 3) Bob sends a contact request to Alice
  1167  // 4) Alice and Bob are mutual contacts (because Alice's CR is "pending" on her side), Both CRs are accepted
  1168  func (s *MessengerContactRequestSuite) TestBobSendsContactRequestAfterDecliningOneFromAlice() {
  1169  	messageTextAlice := "hello, Bobby!"
  1170  
  1171  	alice := s.m
  1172  
  1173  	bob := s.newMessenger()
  1174  	defer TearDownMessenger(&s.Suite, bob)
  1175  
  1176  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
  1177  
  1178  	// Alice sends a contact request to bob
  1179  	requestFromAlice := &requests.SendContactRequest{
  1180  		ID:      bobID,
  1181  		Message: messageTextAlice,
  1182  	}
  1183  	s.sendContactRequest(requestFromAlice, alice)
  1184  
  1185  	contactRequest := s.receiveContactRequest(messageTextAlice, bob)
  1186  	s.Require().NotNil(contactRequest)
  1187  
  1188  	// Bob declines the contact request
  1189  	s.declineContactRequest(contactRequest, bob)
  1190  
  1191  	messageTextBob := "hello, Alice!"
  1192  
  1193  	aliceID := types.EncodeHex(crypto.FromECDSAPub(&alice.identity.PublicKey))
  1194  
  1195  	// Bob sends a contact request to Alice
  1196  	requestFromBob := &requests.SendContactRequest{
  1197  		ID:      aliceID,
  1198  		Message: messageTextBob,
  1199  	}
  1200  
  1201  	// Send contact request
  1202  	resp, err := bob.SendContactRequest(context.Background(), requestFromBob)
  1203  	s.Require().NoError(err)
  1204  	s.Require().NotNil(resp)
  1205  
  1206  	// Check CR message, it should be accepted
  1207  	s.Require().Len(resp.Messages(), 2)
  1208  
  1209  	contactRequest = s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
  1210  	s.Require().NotNil(contactRequest)
  1211  
  1212  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequest.ContactRequestState)
  1213  	s.Require().Equal(requestFromBob.Message, contactRequest.Text)
  1214  
  1215  	// Check pending notification
  1216  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
  1217  	s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
  1218  	s.Require().Equal(contactRequest.ID, resp.ActivityCenterNotifications()[0].Message.ID)
  1219  	s.Require().Equal(contactRequest.ContactRequestState, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
  1220  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Read, true)
  1221  
  1222  	// Check contacts Bob's side
  1223  	s.Require().Len(resp.Contacts, 1)
  1224  	contact := resp.Contacts[0]
  1225  	s.Require().True(contact.mutual())
  1226  }
  1227  
  1228  func (s *MessengerContactRequestSuite) TestBuildContact() {
  1229  	contactKey, err := crypto.GenerateKey()
  1230  	s.Require().NoError(err)
  1231  	contactID := types.EncodeHex(crypto.FromECDSAPub(&contactKey.PublicKey))
  1232  
  1233  	contact, err := s.m.BuildContact(&requests.BuildContact{PublicKey: contactID})
  1234  	s.Require().NoError(err)
  1235  
  1236  	s.Require().Equal(contact.EnsName, "")
  1237  	s.Require().False(contact.ENSVerified)
  1238  
  1239  	contact, err = s.m.BuildContact(&requests.BuildContact{PublicKey: contactID, ENSName: "foobar"})
  1240  	s.Require().NoError(err)
  1241  
  1242  	s.Require().Equal(contact.EnsName, "foobar")
  1243  	s.Require().True(contact.ENSVerified)
  1244  }
  1245  
  1246  func (s *MessengerContactRequestSuite) TestReceiveAcceptAndRetractContactRequestOutOfOrder() {
  1247  	message := protobuf.ChatMessage{
  1248  		Clock:       4,
  1249  		Timestamp:   1,
  1250  		Text:        "some text",
  1251  		ChatId:      common.PubkeyToHex(&s.m.identity.PublicKey),
  1252  		MessageType: protobuf.MessageType_ONE_TO_ONE,
  1253  		ContentType: protobuf.ChatMessage_CONTACT_REQUEST,
  1254  	}
  1255  
  1256  	contactKey, err := crypto.GenerateKey()
  1257  	s.Require().NoError(err)
  1258  
  1259  	contact, err := BuildContactFromPublicKey(&contactKey.PublicKey)
  1260  	s.Require().NoError(err)
  1261  
  1262  	state := s.m.buildMessageState()
  1263  
  1264  	state.CurrentMessageState = &CurrentMessageState{
  1265  		PublicKey:        &contactKey.PublicKey,
  1266  		MessageID:        "0xa",
  1267  		StatusMessage:    &v1protocol.StatusMessage{TransportLayer: v1protocol.TransportLayer{Message: &types.Message{Timestamp: 1}}, ApplicationLayer: v1protocol.ApplicationLayer{ID: []byte("test-id")}},
  1268  		Contact:          contact,
  1269  		WhisperTimestamp: 1,
  1270  	}
  1271  
  1272  	response := state.Response
  1273  	err = s.m.HandleChatMessage(state, &message, nil, false)
  1274  	s.Require().NoError(err)
  1275  	s.Require().Len(response.ActivityCenterNotifications(), 1)
  1276  	contacts := s.m.Contacts()
  1277  	s.Require().Len(contacts, 1)
  1278  	s.Require().Equal(ContactRequestStateReceived, contacts[0].ContactRequestRemoteState)
  1279  
  1280  	retract := protobuf.RetractContactRequest{
  1281  		Clock: 2,
  1282  	}
  1283  	err = s.m.HandleRetractContactRequest(state, &retract, nil)
  1284  	s.Require().NoError(err)
  1285  
  1286  	// Nothing should have changed
  1287  	contacts = s.m.Contacts()
  1288  	s.Require().Len(contacts, 1)
  1289  	s.Require().Equal(ContactRequestStateReceived, contacts[0].ContactRequestRemoteState)
  1290  }
  1291  
  1292  // The scenario tested is as follow:
  1293  // 1) Alice sends a contact request to Bob
  1294  // 2) Bob receives CR from Alice
  1295  // 3) Bob resets his device
  1296  // 4) Bob restores Alice's contact from backup, CR is created
  1297  // 5) Bob succesefully accepts restored contact request
  1298  // 6) Alice get notified properly
  1299  func (s *MessengerContactRequestSuite) TestBobRestoresIncomingContactRequestFromSyncInstallationContactV2() {
  1300  	messageText := "hello, Bobby!"
  1301  
  1302  	alice := s.m
  1303  	alice.account.CustomizationColor = multiaccountscommon.CustomizationColorBeige
  1304  
  1305  	bob1 := s.newMessenger()
  1306  	defer TearDownMessenger(&s.Suite, bob1)
  1307  
  1308  	aliceID := types.EncodeHex(crypto.FromECDSAPub(&alice.identity.PublicKey))
  1309  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob1.identity.PublicKey))
  1310  
  1311  	// Alice sends a contact request to bob
  1312  	requestFromAlice := &requests.SendContactRequest{
  1313  		ID:      bobID,
  1314  		Message: messageText,
  1315  	}
  1316  	s.sendContactRequest(requestFromAlice, alice)
  1317  
  1318  	// Bob receives CR from Alice
  1319  	contactRequest := s.receiveContactRequest(messageText, bob1)
  1320  	s.Require().NotNil(contactRequest)
  1321  
  1322  	// Bob resets his device
  1323  	bob2, err := newMessengerWithKey(s.shh, bob1.identity, s.logger, nil)
  1324  	s.Require().NoError(err)
  1325  	defer TearDownMessenger(&s.Suite, bob2)
  1326  
  1327  	// Get bob perspective of alice for backup
  1328  	aliceFromBob := bob1.Contacts()[0]
  1329  	s.Require().Equal(aliceFromBob.CustomizationColor, alice.account.GetCustomizationColor())
  1330  	state := bob2.buildMessageState()
  1331  
  1332  	// Restore alice's contact from backup
  1333  	sync := s.syncInstallationContactV2FromContact(aliceFromBob)
  1334  	err = bob2.HandleSyncInstallationContactV2(state, &sync, nil)
  1335  	s.Require().NoError(err)
  1336  
  1337  	// Accept latest CR for a contact
  1338  	resp, err := bob2.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(aliceID)})
  1339  	s.Require().NoError(err)
  1340  	s.Require().Len(resp.Contacts, 1)
  1341  
  1342  	// Make sure the message is updated
  1343  	s.Require().NotNil(resp)
  1344  	s.Require().Len(resp.Messages(), 2)
  1345  
  1346  	contactRequestMsg := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
  1347  	s.Require().NotNil(contactRequestMsg)
  1348  
  1349  	// NOTE: We don't restore CR message
  1350  	// s.Require().Equal(resp.Messages()[0].ID, contactRequest.ID)
  1351  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequestMsg.ContactRequestState)
  1352  
  1353  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
  1354  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
  1355  	s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
  1356  
  1357  	// Check the contact state is correctly set
  1358  	s.Require().Len(resp.Contacts, 1)
  1359  	s.Require().True(resp.Contacts[0].mutual())
  1360  
  1361  	// Make sure the sender is added to our contacts
  1362  	contacts := bob2.AddedContacts()
  1363  	s.Require().Len(contacts, 1)
  1364  
  1365  	// Make sure we consider them a mutual contact, receiver side
  1366  	mutualContacts := bob2.MutualContacts()
  1367  	s.Require().Len(mutualContacts, 1)
  1368  }
  1369  
  1370  // The scenario tested is as follow:
  1371  // 1) Alice sends a contact request to Bob
  1372  // 2) Bob receives CR from Alice
  1373  // 3) Alice resets her device
  1374  // 4) Alice restores Bob's contact from backup, CR is created
  1375  // 5) Bob accepts contact request
  1376  // 6) Alice get notified properly
  1377  func (s *MessengerContactRequestSuite) TestAliceRestoresOutgoingContactRequestFromSyncInstallationContactV2() {
  1378  	messageText := "hello, Bobby!"
  1379  
  1380  	alice1 := s.m
  1381  
  1382  	bob := s.newMessenger()
  1383  	defer TearDownMessenger(&s.Suite, bob)
  1384  
  1385  	aliceID := types.EncodeHex(crypto.FromECDSAPub(&alice1.identity.PublicKey))
  1386  	bobID := types.EncodeHex(crypto.FromECDSAPub(&bob.identity.PublicKey))
  1387  
  1388  	// Alice sends a contact request to bob
  1389  	requestFromAlice := &requests.SendContactRequest{
  1390  		ID:      bobID,
  1391  		Message: messageText,
  1392  	}
  1393  	s.sendContactRequest(requestFromAlice, alice1)
  1394  
  1395  	// Bob receives CR from Alice
  1396  	contactRequest := s.receiveContactRequest(messageText, bob)
  1397  	s.Require().NotNil(contactRequest)
  1398  
  1399  	// Bob resets his device
  1400  	alice2, err := newMessengerWithKey(s.shh, alice1.identity, s.logger, nil)
  1401  	s.Require().NoError(err)
  1402  	defer TearDownMessenger(&s.Suite, alice2)
  1403  
  1404  	// Get bob perspective of alice for backup
  1405  	bobFromAlice := alice1.Contacts()[0]
  1406  	state := alice2.buildMessageState()
  1407  
  1408  	// Restore alice's contact from backup
  1409  	sync := s.syncInstallationContactV2FromContact(bobFromAlice)
  1410  	err = alice2.HandleSyncInstallationContactV2(state, &sync, nil)
  1411  	s.Require().NoError(err)
  1412  
  1413  	// Accept latest CR for a contact
  1414  	resp, err := bob.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(aliceID)})
  1415  	s.Require().NoError(err)
  1416  
  1417  	// Make sure the message is updated
  1418  	s.Require().NotNil(resp)
  1419  	s.Require().Len(resp.Messages(), 2)
  1420  
  1421  	contactRequestMsg := s.findFirstByContentType(resp.Messages(), protobuf.ChatMessage_CONTACT_REQUEST)
  1422  	s.Require().NotNil(contactRequestMsg)
  1423  
  1424  	// NOTE: We don't restore CR message
  1425  	// s.Require().Equal(resp.Messages()[0].ID, contactRequest.ID)
  1426  	s.Require().Equal(common.ContactRequestStateAccepted, contactRequestMsg.ContactRequestState)
  1427  
  1428  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
  1429  	s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
  1430  	s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
  1431  
  1432  	// Check the contact state is correctly set
  1433  	s.Require().Len(resp.Contacts, 1)
  1434  	s.Require().True(resp.Contacts[0].mutual())
  1435  
  1436  	// Make sure the sender is added to our contacts
  1437  	contacts := bob.AddedContacts()
  1438  	s.Require().Len(contacts, 1)
  1439  
  1440  	// Make sure we consider them a mutual contact, receiver side
  1441  	mutualContacts := bob.MutualContacts()
  1442  	s.Require().Len(mutualContacts, 1)
  1443  }
  1444  
  1445  /*
  1446  Makes Alice and Bob mutual contacts.
  1447  Verifies that Alice device-2 receives mutual contact information.
  1448  Contact request is sent from Alice device 1.
  1449  */
  1450  func (s *MessengerContactRequestSuite) makeMutualContactsAndSync(alice1 *Messenger, alice2 *Messenger, bob *Messenger, messageText string) {
  1451  	bobPublicKey := bob.IdentityPublicKeyString()
  1452  
  1453  	cr := s.createContactRequest(bobPublicKey, messageText)
  1454  	s.sendContactRequest(cr, alice1)
  1455  	receivedCR := s.receiveContactRequest(cr.Message, bob)
  1456  	s.acceptContactRequest(receivedCR, alice1, bob)
  1457  	s.checkMutualContact(alice1, bobPublicKey)
  1458  
  1459  	// Wait for Alice-2 to sync new contact
  1460  	resp, _ := WaitOnMessengerResponse(alice2, func(r *MessengerResponse) bool {
  1461  		// FIXME: https://github.com/status-im/status-go/issues/3803
  1462  		// 		  No condition here. There are randomly received 1-3 messages.
  1463  		return false // len(r.Contacts) == 1 && len(r.Messages()) == 3
  1464  	}, "alice-2 didn't receive bob contact")
  1465  	s.logResponse(resp, "Wait for Alice-2 to sync new contact")
  1466  	s.Require().NotNil(resp)
  1467  	//s.Require().NoError(err)	// WARNING: Uncomment when bug fixed. https://github.com/status-im/status-go/issues/3803
  1468  
  1469  	// Check that Alice-2 has Bob as a contact
  1470  	s.Require().Len(alice2.Contacts(), 1)
  1471  	s.Require().Equal(bobPublicKey, alice2.Contacts()[0].ID)
  1472  
  1473  	// TODO: https://github.com/status-im/status-go/issues/3803
  1474  	// 		 Check response messages and AC notifications when
  1475  }
  1476  
  1477  func (s *MessengerContactRequestSuite) blockContactAndSync(alice1 *Messenger, alice2 *Messenger, bob *Messenger) {
  1478  	bobPublicKey := bob.IdentityPublicKeyString()
  1479  	bobDisplayName, err := bob.settings.DisplayName()
  1480  	s.Require().NoError(err)
  1481  
  1482  	// Alice-1 blocks Bob
  1483  	_, err = alice1.BlockContact(context.Background(), bobPublicKey, false)
  1484  	s.Require().NoError(err)
  1485  	s.Require().Len(alice1.BlockedContacts(), 1)
  1486  	s.Require().Equal(bobPublicKey, alice1.BlockedContacts()[0].ID)
  1487  
  1488  	// Wait for Bob to receive message that he was removed as contact
  1489  	resp, err := WaitOnMessengerResponse(bob, func(r *MessengerResponse) bool {
  1490  		return len(r.Contacts) == 1 && len(r.Messages()) == 1
  1491  	}, "Bob didn't receive a message that he was removed as contact")
  1492  
  1493  	s.Require().NoError(err)
  1494  	s.Require().NotNil(resp)
  1495  	s.logResponse(resp, "Wait for Bob to receive message that he was removed as contact")
  1496  
  1497  	// Check response contacts
  1498  	s.Require().Len(resp.Contacts, 1)
  1499  	respContact := resp.Contacts[0]
  1500  	s.Require().Equal(respContact.ID, alice1.IdentityPublicKeyString())
  1501  	s.Require().Equal(ContactRequestStateNone, respContact.ContactRequestLocalState)
  1502  	s.Require().Equal(ContactRequestStateNone, respContact.ContactRequestRemoteState)
  1503  
  1504  	// Check response messages
  1505  	s.Require().Len(resp.Messages(), 1)
  1506  	s.Require().Equal(resp.Messages()[0].Text, fmt.Sprintf(incomingMutualStateEventRemovedDefaultText, alice1.IdentityPublicKeyString()))
  1507  
  1508  	// Check response AC notifications
  1509  	s.Require().Len(resp.ActivityCenterNotifications(), 1)
  1510  	s.Require().Equal(resp.ActivityCenterNotifications()[0].Type, ActivityCenterNotificationTypeContactRemoved)
  1511  
  1512  	alice2.logger.Info("STARTING")
  1513  	// Wait for Alice-2 to sync Bob blocked state
  1514  	resp, err = WaitOnMessengerResponse(alice2, func(r *MessengerResponse) bool {
  1515  		return len(r.Contacts) == 1
  1516  	}, "Alice-2 didn't receive blocking bob")
  1517  	s.logResponse(resp, "Wait for Alice-2 to sync Bob blocked state")
  1518  	s.Require().NoError(err)
  1519  	s.Require().NotNil(resp)
  1520  
  1521  	// Check that Bob contact is synced with correct display name and blocked
  1522  	s.Require().Len(alice2.Contacts(), 1)
  1523  	respContact = alice2.Contacts()[0]
  1524  	s.Require().True(respContact.Blocked)
  1525  	s.Require().True(respContact.Removed)
  1526  	s.Require().Equal(bobPublicKey, respContact.ID)
  1527  	s.Require().Equal(bobDisplayName, respContact.DisplayName)
  1528  	s.Require().Equal(ContactRequestStateDismissed, respContact.ContactRequestLocalState)
  1529  	s.Require().Equal(ContactRequestStateReceived, respContact.ContactRequestRemoteState)
  1530  
  1531  	// Check chats list
  1532  	s.Require().Len(alice2.Chats(), deprecation.AddChatsCount(2))
  1533  }
  1534  
  1535  func (s *MessengerContactRequestSuite) unblockContactAndSync(alice1 *Messenger, alice2 *Messenger, bob *Messenger) {
  1536  	bobPublicKey := bob.IdentityPublicKeyString()
  1537  
  1538  	_, err := alice1.UnblockContact(bobPublicKey)
  1539  	s.Require().NoError(err)
  1540  	s.Require().Len(alice1.BlockedContacts(), 0)
  1541  
  1542  	// Bob doesn't receive any message on blocking.
  1543  	// No response wait here.
  1544  
  1545  	// Wait for Alice-2 to receive Bob unblocked state
  1546  	resp, err := WaitOnMessengerResponse(alice2, func(r *MessengerResponse) bool {
  1547  		return len(r.Contacts) == 1
  1548  	}, "Alice-2 didn't receive Bob unblocked state")
  1549  	s.logResponse(resp, "Wait for Alice-2 to receive Bob unblocked state")
  1550  	s.Require().NoError(err)
  1551  	s.Require().NotNil(resp)
  1552  
  1553  	// Check that Alice-2 has Bob unblocked and removed
  1554  	s.Require().Len(alice2.Contacts(), 1)
  1555  	respContact := alice2.Contacts()[0]
  1556  	s.Require().Equal(bobPublicKey, respContact.ID)
  1557  	s.Require().False(respContact.Blocked)
  1558  	s.Require().True(respContact.Removed)
  1559  	s.Require().Equal(respContact.ContactRequestLocalState, ContactRequestStateNone)
  1560  	s.Require().Equal(respContact.ContactRequestRemoteState, ContactRequestStateNone)
  1561  
  1562  	// Check chats list
  1563  	s.Require().Len(alice2.Chats(), deprecation.AddChatsCount(2))
  1564  }
  1565  
  1566  func (s *MessengerContactRequestSuite) TestBlockedContactSyncing() {
  1567  	// Setup Bob
  1568  	bob := s.newMessenger()
  1569  	defer TearDownMessenger(&s.Suite, bob)
  1570  	_ = bob.SetDisplayName("bob-1")
  1571  	s.logger.Info("Bob account set up", zap.String("publicKey", bob.IdentityPublicKeyString()))
  1572  
  1573  	// Setup Alice-1
  1574  	alice1 := s.m
  1575  	s.logger.Info("Alice account set up", zap.String("publicKey", alice1.IdentityPublicKeyString()))
  1576  
  1577  	// Setup Alice-2
  1578  	alice2, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, nil)
  1579  	s.Require().NoError(err)
  1580  	defer TearDownMessenger(&s.Suite, alice2)
  1581  
  1582  	// Pair alice-1 <-> alice-2
  1583  	// NOTE: This doesn't include initial data sync. Local pairing could be used.
  1584  	s.logger.Info("pairing Alice-1 and Alice-2")
  1585  	prepAliceMessengersForPairing(&s.Suite, alice1, alice2)
  1586  	PairDevices(&s.Suite, alice1, alice2)
  1587  	PairDevices(&s.Suite, alice2, alice1)
  1588  	s.logger.Info("pairing Alice-1 and Alice-2 finished")
  1589  
  1590  	// Loop cr-block-unblock. Some bugs happen at second iteration.
  1591  	for i := 0; i < 2; i++ {
  1592  		crText := fmt.Sprintf("hello-%d", i)
  1593  		s.makeMutualContactsAndSync(alice1, alice2, bob, crText)
  1594  		s.blockContactAndSync(alice1, alice2, bob)
  1595  		s.unblockContactAndSync(alice1, alice2, bob)
  1596  	}
  1597  }