Fix/duplicate accept cr messages (#4367)
* fix: Duplicate 'Contact Added' Notifications When Pair-Device User Accepts Request * bump version
This commit is contained in:
parent
058120fad9
commit
d7e7792b51
|
@ -177,6 +177,9 @@ type Messenger struct {
|
||||||
processBackedupMessages bool
|
processBackedupMessages bool
|
||||||
|
|
||||||
communityTokensService communitytokens.ServiceInterface
|
communityTokensService communitytokens.ServiceInterface
|
||||||
|
|
||||||
|
// used to track dispatched messages
|
||||||
|
dispatchMessageTestCallback func(common.RawMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
type connStatus int
|
type connStatus int
|
||||||
|
@ -2242,6 +2245,9 @@ func (m *Messenger) dispatchMessage(ctx context.Context, rawMessage common.RawMe
|
||||||
return rawMessage, err
|
return rawMessage, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.dispatchMessageTestCallback != nil {
|
||||||
|
m.dispatchMessageTestCallback(rawMessage)
|
||||||
|
}
|
||||||
return rawMessage, nil
|
return rawMessage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ func (m *Messenger) SendContactRequest(ctx context.Context, request *requests.Se
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, contactRequestID string) (*MessengerResponse, error) {
|
func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, contactRequestID string, fromSyncing bool) (*MessengerResponse, error) {
|
||||||
|
|
||||||
m.logger.Debug("updateAcceptedContactRequest", zap.String("contactRequestID", contactRequestID))
|
m.logger.Debug("updateAcceptedContactRequest", zap.String("contactRequestID", contactRequestID))
|
||||||
|
|
||||||
|
@ -286,23 +286,24 @@ func (m *Messenger) updateAcceptedContactRequest(response *MessengerResponse, co
|
||||||
clock, _ := chat.NextClockAndTimestamp(m.transport)
|
clock, _ := chat.NextClockAndTimestamp(m.transport)
|
||||||
contact.AcceptContactRequest(clock)
|
contact.AcceptContactRequest(clock)
|
||||||
|
|
||||||
acceptContactRequest := &protobuf.AcceptContactRequest{
|
if !fromSyncing {
|
||||||
Id: contactRequest.ID,
|
acceptContactRequest := &protobuf.AcceptContactRequest{
|
||||||
Clock: clock,
|
Id: contactRequest.ID,
|
||||||
}
|
Clock: clock,
|
||||||
encodedMessage, err := proto.Marshal(acceptContactRequest)
|
}
|
||||||
if err != nil {
|
encodedMessage, err := proto.Marshal(acceptContactRequest)
|
||||||
return nil, err
|
if err != nil {
|
||||||
}
|
return nil, err
|
||||||
|
}
|
||||||
_, err = m.dispatchMessage(context.Background(), common.RawMessage{
|
_, err = m.dispatchMessage(context.Background(), common.RawMessage{
|
||||||
LocalChatID: contactRequest.From,
|
LocalChatID: contactRequest.From,
|
||||||
Payload: encodedMessage,
|
Payload: encodedMessage,
|
||||||
MessageType: protobuf.ApplicationMetadataMessage_ACCEPT_CONTACT_REQUEST,
|
MessageType: protobuf.ApplicationMetadataMessage_ACCEPT_CONTACT_REQUEST,
|
||||||
ResendAutomatically: true,
|
ResendAutomatically: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if response == nil {
|
if response == nil {
|
||||||
|
@ -455,7 +456,7 @@ func (m *Messenger) addContact(ctx context.Context, pubKey, ensName, nickname, d
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(contactRequestID) != 0 {
|
if len(contactRequestID) != 0 {
|
||||||
updatedResponse, err := m.updateAcceptedContactRequest(response, contactRequestID)
|
updatedResponse, err := m.updateAcceptedContactRequest(response, contactRequestID, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3576,7 +3576,7 @@ func (m *Messenger) HandleSyncContactRequestDecision(state *ReceivedMessageState
|
||||||
var response *MessengerResponse
|
var response *MessengerResponse
|
||||||
|
|
||||||
if message.DecisionStatus == protobuf.SyncContactRequestDecision_ACCEPTED {
|
if message.DecisionStatus == protobuf.SyncContactRequestDecision_ACCEPTED {
|
||||||
response, err = m.updateAcceptedContactRequest(nil, message.RequestId)
|
response, err = m.updateAcceptedContactRequest(nil, message.RequestId, true)
|
||||||
} else {
|
} else {
|
||||||
response, err = m.declineContactRequest(message.RequestId, true)
|
response, err = m.declineContactRequest(message.RequestId, true)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package protocol
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
"github.com/status-im/status-go/protocol/common"
|
||||||
|
"github.com/status-im/status-go/protocol/protobuf"
|
||||||
|
"github.com/status-im/status-go/protocol/requests"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MessengerSyncContactRequestDecisionSuite struct {
|
||||||
|
MessengerBaseTestSuite
|
||||||
|
m2 *Messenger
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMessengerSyncContactRequestDecision(t *testing.T) {
|
||||||
|
suite.Run(t, new(MessengerSyncContactRequestDecisionSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerSyncContactRequestDecisionSuite) SetupTest() {
|
||||||
|
s.MessengerBaseTestSuite.SetupTest()
|
||||||
|
|
||||||
|
m2, err := newMessengerWithKey(s.shh, s.privateKey, s.logger, nil)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.m2 = m2
|
||||||
|
|
||||||
|
PairDevices(&s.Suite, m2, s.m)
|
||||||
|
PairDevices(&s.Suite, s.m, m2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerSyncContactRequestDecisionSuite) TearDownTest() {
|
||||||
|
s.Require().NoError(s.m2.Shutdown())
|
||||||
|
s.MessengerBaseTestSuite.TearDownTest()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerSyncContactRequestDecisionSuite) createUserB() *Messenger {
|
||||||
|
key, err := crypto.GenerateKey()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
userB, err := newMessengerWithKey(s.shh, key, s.logger, nil)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
return userB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MessengerSyncContactRequestDecisionSuite) TestSyncAcceptContactRequest() {
|
||||||
|
userB := s.createUserB()
|
||||||
|
defer func() {
|
||||||
|
s.Require().NoError(userB.Shutdown())
|
||||||
|
}()
|
||||||
|
|
||||||
|
numM1DispatchedAcceptContactRequest := 0
|
||||||
|
numM2DispatchedAcceptContactRequest := 0
|
||||||
|
s.m.dispatchMessageTestCallback = func(message common.RawMessage) {
|
||||||
|
if message.MessageType == protobuf.ApplicationMetadataMessage_ACCEPT_CONTACT_REQUEST {
|
||||||
|
numM1DispatchedAcceptContactRequest++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.m2.dispatchMessageTestCallback = func(message common.RawMessage) {
|
||||||
|
if message.MessageType == protobuf.ApplicationMetadataMessage_ACCEPT_CONTACT_REQUEST {
|
||||||
|
numM2DispatchedAcceptContactRequest++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// send contact request to m/m2, m and m2 are paired
|
||||||
|
request := &requests.AddContact{ID: common.PubkeyToHex(&s.m2.identity.PublicKey)}
|
||||||
|
_, err := userB.AddContact(context.Background(), request)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// check m and m2 received contact request
|
||||||
|
var contactRequestMessageID types.HexBytes
|
||||||
|
receivedContactRequestCondition := func(r *MessengerResponse) bool {
|
||||||
|
for _, n := range r.ActivityCenterNotifications() {
|
||||||
|
if n.Type == ActivityCenterNotificationTypeContactRequest {
|
||||||
|
contactRequestMessageID = n.ID
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
_, err = WaitOnMessengerResponse(s.m, receivedContactRequestCondition, "contact request not received on device 1")
|
||||||
|
s.Require().NoError(err)
|
||||||
|
_, err = WaitOnMessengerResponse(s.m2, receivedContactRequestCondition, "contact request not received on device 2")
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// m accept contact request from userB
|
||||||
|
_, err = s.m.AcceptContactRequest(context.Background(), &requests.AcceptContactRequest{ID: contactRequestMessageID})
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
// check sync contact request decision processed for m2
|
||||||
|
_, err = WaitOnMessengerResponse(s.m2, func(r *MessengerResponse) bool {
|
||||||
|
return len(r.Contacts) > 0
|
||||||
|
}, "contact request not accepted on device 2")
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
s.Require().Equal(1, numM1DispatchedAcceptContactRequest, "we should dispatch only 1 accept contact request message")
|
||||||
|
s.Require().Equal(0, numM2DispatchedAcceptContactRequest, "we should not dispatch accept contact request message")
|
||||||
|
}
|
Loading…
Reference in New Issue