Add default contact request
If a contact update or a legacy contact request is sent, we create a notification for the user in the activity center so it can be replied to. If at a later date a new contact request is received from the same user, this will replace it, so the proper message can be displayed.
This commit is contained in:
parent
4f722b6fe8
commit
22669d0423
|
@ -435,7 +435,11 @@ func (db sqlitePersistence) GetActivityCenterNotificationByID(id types.HexBytes)
|
|||
c.id = a.chat_id
|
||||
WHERE a.id = ?`, id)
|
||||
|
||||
return db.unmarshalActivityCenterNotificationRow(row)
|
||||
notification, err := db.unmarshalActivityCenterNotificationRow(row)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
return notification, err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) ActivityCenterNotifications(currCursor string, limit uint64) (string, []*ActivityCenterNotification, error) {
|
||||
|
@ -673,3 +677,40 @@ func (db sqlitePersistence) UnreadActivityCenterNotificationsCount() (uint64, er
|
|||
err := db.db.QueryRow(`SELECT COUNT(1) FROM activity_center_notifications WHERE NOT read AND NOT dismissed AND NOT accepted`).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) ActiveContactRequestNotification(contactID string) (*ActivityCenterNotification, error) {
|
||||
row := db.db.QueryRow(`
|
||||
SELECT
|
||||
a.id,
|
||||
a.timestamp,
|
||||
a.notification_type,
|
||||
a.chat_id,
|
||||
a.read,
|
||||
a.accepted,
|
||||
a.dismissed,
|
||||
a.message,
|
||||
c.last_message,
|
||||
a.reply_message,
|
||||
c.name,
|
||||
a.author
|
||||
FROM activity_center_notifications a
|
||||
LEFT JOIN chats c
|
||||
ON
|
||||
c.id = a.chat_id
|
||||
WHERE NOT dismissed AND NOT a.accepted AND notification_type = ? AND author = ?`, ActivityCenterNotificationTypeContactRequest, contactID)
|
||||
notification, err := db.unmarshalActivityCenterNotificationRow(row)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
return notification, err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) RemoveAllContactRequestActivityCenterNotifications(chatID string) error {
|
||||
_, err := db.db.Exec(`
|
||||
DELETE FROM activity_center_notifications
|
||||
WHERE
|
||||
chat_id = ?
|
||||
AND notification_type = ?
|
||||
`, chatID, ActivityCenterNotificationTypeContactRequest)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -330,8 +330,9 @@ func (s *MessengerContactRequestSuite) TestReceiveAcceptAndRetractContactRequest
|
|||
s.Require().Len(contactRequests, 1)
|
||||
s.Require().Equal(contactRequests[0].ContactRequestState, common.ContactRequestStatePending)
|
||||
|
||||
cid := resp.ActivityCenterNotifications()[0].Message.ID
|
||||
// Accept contact request, receiver side
|
||||
resp, err = theirMessenger.AcceptContactRequest(context.Background(), &requests.AcceptContactRequest{ID: types.Hex2Bytes(contactRequests[0].ID)})
|
||||
resp, err = theirMessenger.AcceptContactRequest(context.Background(), &requests.AcceptContactRequest{ID: types.Hex2Bytes(cid)})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Make sure the message is updated
|
||||
|
@ -802,7 +803,6 @@ func (s *MessengerContactRequestSuite) TestDismissLatestContactRequestForContact
|
|||
|
||||
}
|
||||
|
||||
/* Disabling as currently there's an issue with duplicated contact requests
|
||||
func (s *MessengerContactRequestSuite) TestReceiveAndAcceptLegacyContactRequest() {
|
||||
|
||||
theirMessenger := s.newMessenger(s.shh)
|
||||
|
@ -873,4 +873,202 @@ func (s *MessengerContactRequestSuite) TestReceiveAndAcceptLegacyContactRequest(
|
|||
// Make sure we consider them a mutual contact, receiver side
|
||||
mutualContacts := theirMessenger.MutualContacts()
|
||||
s.Require().Len(mutualContacts, 1)
|
||||
} */
|
||||
}
|
||||
|
||||
func (s *MessengerContactRequestSuite) TestLegacyContactRequestNotifications() {
|
||||
|
||||
theirMessenger := s.newMessenger(s.shh)
|
||||
_, err := theirMessenger.Start()
|
||||
s.Require().NoError(err)
|
||||
|
||||
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
|
||||
request := &requests.AddContact{
|
||||
ID: types.Hex2Bytes(contactID),
|
||||
}
|
||||
|
||||
// Send legacy contact request
|
||||
resp, err := s.m.AddContact(context.Background(), request)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().NotNil(resp)
|
||||
|
||||
// Make sure contact is added on the sender side
|
||||
contacts := s.m.AddedContacts()
|
||||
s.Require().Len(contacts, 1)
|
||||
s.Require().Equal(ContactRequestStateSent, contacts[0].ContactRequestState)
|
||||
|
||||
// Wait for the message to reach its destination
|
||||
resp, err = WaitOnMessengerResponse(
|
||||
theirMessenger,
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.Contacts) > 0 && len(r.ActivityCenterNotifications()) == 1
|
||||
},
|
||||
"no messages",
|
||||
)
|
||||
|
||||
s.Require().NoError(err)
|
||||
|
||||
notification := resp.ActivityCenterNotifications()[0]
|
||||
|
||||
// Check contact request has been received
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Check activity center notification is of the right type
|
||||
s.Require().Equal(ActivityCenterNotificationTypeContactRequest, notification.Type)
|
||||
s.Require().NotNil(notification.Type)
|
||||
s.Require().Equal(common.ContactRequestStatePending, notification.Message.ContactRequestState)
|
||||
|
||||
// Check the contact state is correctly set
|
||||
s.Require().Len(resp.Contacts, 1)
|
||||
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestState)
|
||||
|
||||
// Send new contact request
|
||||
resp, err = s.m.AddContact(context.Background(), request)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().NotNil(resp)
|
||||
|
||||
crRequest := &requests.SendContactRequest{
|
||||
ID: types.Hex2Bytes(contactID),
|
||||
Message: "hello",
|
||||
}
|
||||
|
||||
myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
|
||||
|
||||
// Send contact request
|
||||
resp, err = s.m.SendContactRequest(context.Background(), crRequest)
|
||||
s.Require().NoError(err)
|
||||
|
||||
paginationResponse, err := theirMessenger.ActivityCenterNotifications("", 10)
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(paginationResponse.Notifications, 1)
|
||||
|
||||
// Wait for the message to reach its destination
|
||||
resp, err = WaitOnMessengerResponse(
|
||||
theirMessenger,
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.ActivityCenterNotifications()) == 2
|
||||
},
|
||||
"no messages",
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
activityCenterNotifications := resp.ActivityCenterNotifications()
|
||||
var newNotification, oldNotification *ActivityCenterNotification
|
||||
if activityCenterNotifications[0].Message.ID == defaultContactRequestID(myID) {
|
||||
oldNotification = activityCenterNotifications[0]
|
||||
newNotification = activityCenterNotifications[1]
|
||||
} else {
|
||||
newNotification = activityCenterNotifications[0]
|
||||
oldNotification = activityCenterNotifications[1]
|
||||
}
|
||||
|
||||
s.Require().True(oldNotification.Dismissed)
|
||||
s.Require().False(newNotification.Dismissed)
|
||||
|
||||
paginationResponse, err = theirMessenger.ActivityCenterNotifications("", 10)
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(paginationResponse.Notifications, 1)
|
||||
}
|
||||
|
||||
func (s *MessengerContactRequestSuite) TestReceiveMultipleLegacy() {
|
||||
|
||||
theirMessenger := s.newMessenger(s.shh)
|
||||
_, err := theirMessenger.Start()
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().NoError(theirMessenger.settings.SaveSettingField(settings.MutualContactEnabled, true))
|
||||
s.Require().NoError(s.m.settings.SaveSettingField(settings.MutualContactEnabled, true))
|
||||
|
||||
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
|
||||
request := &requests.AddContact{
|
||||
ID: types.Hex2Bytes(contactID),
|
||||
}
|
||||
|
||||
// Send legacy contact request
|
||||
resp, err := s.m.AddContact(context.Background(), request)
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().NotNil(resp)
|
||||
|
||||
// Make sure contact is added on the sender side
|
||||
contacts := s.m.AddedContacts()
|
||||
s.Require().Len(contacts, 1)
|
||||
s.Require().Equal(ContactRequestStateSent, contacts[0].ContactRequestState)
|
||||
|
||||
// Wait for the message to reach its destination
|
||||
resp, err = WaitOnMessengerResponse(
|
||||
theirMessenger,
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.Contacts) > 0 && len(r.ActivityCenterNotifications()) == 1
|
||||
},
|
||||
"no messages",
|
||||
)
|
||||
|
||||
s.Require().NoError(err)
|
||||
|
||||
notification := resp.ActivityCenterNotifications()[0]
|
||||
|
||||
// Check contact request has been received
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Check activity center notification is of the right type
|
||||
s.Require().Equal(ActivityCenterNotificationTypeContactRequest, notification.Type)
|
||||
s.Require().NotNil(notification.Type)
|
||||
s.Require().Equal(common.ContactRequestStatePending, notification.Message.ContactRequestState)
|
||||
|
||||
// Check the contact state is correctly set
|
||||
s.Require().Len(resp.Contacts, 1)
|
||||
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestState)
|
||||
|
||||
// Remove contact
|
||||
|
||||
_, err = s.m.RetractContactRequest(&requests.RetractContactRequest{ContactID: types.Hex2Bytes(contactID)})
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Wait for the message to reach its destination
|
||||
resp, err = WaitOnMessengerResponse(
|
||||
theirMessenger,
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.Contacts) == 1
|
||||
},
|
||||
"no messages",
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Make sure it's not a contact anymore
|
||||
s.Require().Equal(ContactRequestStateNone, resp.Contacts[0].ContactRequestState)
|
||||
|
||||
// Re-add user
|
||||
resp, err = s.m.AddContact(context.Background(), request)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(resp)
|
||||
|
||||
// Wait for the message to reach its destination
|
||||
resp, err = WaitOnMessengerResponse(
|
||||
theirMessenger,
|
||||
func(r *MessengerResponse) bool {
|
||||
return len(r.Contacts) > 0 && len(r.ActivityCenterNotifications()) == 1
|
||||
},
|
||||
"no messages",
|
||||
)
|
||||
|
||||
s.Require().NoError(err)
|
||||
|
||||
notification = resp.ActivityCenterNotifications()[0]
|
||||
|
||||
// Check contact request has been received
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Check activity center notification is of the right type
|
||||
s.Require().Equal(ActivityCenterNotificationTypeContactRequest, notification.Type)
|
||||
s.Require().NotNil(notification.Type)
|
||||
s.Require().Equal(common.ContactRequestStatePending, notification.Message.ContactRequestState)
|
||||
|
||||
// Check the contact state is correctly set
|
||||
s.Require().Len(resp.Contacts, 1)
|
||||
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestState)
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"errors"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/protocol/common"
|
||||
|
@ -22,6 +23,7 @@ func (m *Messenger) AcceptContactRequest(ctx context.Context, request *requests.
|
|||
|
||||
contactRequest, err := m.persistence.MessageByID(request.ID.String())
|
||||
if err != nil {
|
||||
m.logger.Error("could not find contact request message", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -848,3 +850,7 @@ func (m *Messenger) DismissLatestContactRequestForContact(ctx context.Context, r
|
|||
func (m *Messenger) PendingContactRequests(cursor string, limit int) ([]*common.Message, string, error) {
|
||||
return m.persistence.PendingContactRequests(cursor, limit)
|
||||
}
|
||||
|
||||
func defaultContactRequestID(contactID string) string {
|
||||
return "0x" + types.Bytes2Hex(append(types.Hex2Bytes(contactID), 0x20))
|
||||
}
|
||||
|
|
|
@ -231,14 +231,68 @@ func (m *Messenger) createMessageNotification(chat *Chat, messageState *Received
|
|||
}
|
||||
}
|
||||
|
||||
func (m *Messenger) PendingNotificationContactRequest(contactID string) (*ActivityCenterNotification, error) {
|
||||
return m.persistence.ActiveContactRequestNotification(contactID)
|
||||
}
|
||||
|
||||
func (m *Messenger) createContactRequestNotification(contact *Contact, messageState *ReceivedMessageState, contactRequest *common.Message) error {
|
||||
|
||||
// Legacy contact request
|
||||
if contactRequest == nil {
|
||||
if contactRequest == nil || contactRequest.ContactRequestState == common.ContactRequestStatePending {
|
||||
notification, err := m.PendingNotificationContactRequest(contact.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If there's already a notification, we will check whether is a default notification
|
||||
// that has not been dismissed (nor accepted???)
|
||||
// If it is, we replace it with a non-default, since it contains a message
|
||||
if notification != nil {
|
||||
// Check if it's the default notification
|
||||
if notification.Message.ID == defaultContactRequestID(contact.ID) {
|
||||
// Nothing to do, we already have a default notification
|
||||
if contactRequest == nil {
|
||||
return nil
|
||||
}
|
||||
// We first dismiss it in the database
|
||||
err := m.persistence.DismissActivityCenterNotifications([]types.HexBytes{types.Hex2Bytes(notification.Message.ID)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// we mark the notification as dismissed
|
||||
notification.Dismissed = true
|
||||
// We remove it from the response, since the client has never seen it, better to just remove it
|
||||
found := messageState.Response.RemoveActivityCenterNotification(notification.Message.ID)
|
||||
// Otherwise, it means we have already passed it to the client, so we add it with a `dismissed` flag
|
||||
// so it can clean up
|
||||
if !found {
|
||||
messageState.Response.AddActivityCenterNotification(notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy//ContactUpdate contact request
|
||||
if contactRequest == nil {
|
||||
if messageState.CurrentMessageState == nil || messageState.CurrentMessageState.MessageID == "" {
|
||||
return errors.New("no available id")
|
||||
}
|
||||
// We use a known id so that we can check if already in the database
|
||||
defaultID := defaultContactRequestID(contact.ID)
|
||||
|
||||
// Pull one from the db if there
|
||||
notification, err := m.persistence.GetActivityCenterNotificationByID(types.FromHex(defaultID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if the notification is accepted, we clear it, as this one will replace it
|
||||
if notification != nil && notification.Accepted {
|
||||
err = m.persistence.DeleteActivityCenterNotification(types.FromHex(defaultID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
contactRequest = &common.Message{}
|
||||
|
||||
contactRequest.WhisperTimestamp = messageState.CurrentMessageState.WhisperTimestamp
|
||||
|
@ -247,9 +301,9 @@ func (m *Messenger) createContactRequestNotification(contact *Contact, messageSt
|
|||
contactRequest.From = contact.ID
|
||||
contactRequest.ContentType = protobuf.ChatMessage_CONTACT_REQUEST
|
||||
contactRequest.Clock = messageState.CurrentMessageState.Message.Clock
|
||||
contactRequest.ID = messageState.CurrentMessageState.MessageID
|
||||
contactRequest.ID = defaultID
|
||||
contactRequest.ContactRequestState = common.ContactRequestStatePending
|
||||
err := contactRequest.PrepareContent(common.PubkeyToHex(&m.identity.PublicKey))
|
||||
err = contactRequest.PrepareContent(common.PubkeyToHex(&m.identity.PublicKey))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -260,7 +314,6 @@ func (m *Messenger) createContactRequestNotification(contact *Contact, messageSt
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
notification := &ActivityCenterNotification{
|
||||
|
@ -669,7 +722,6 @@ func (m *Messenger) HandleAcceptContactRequest(state *ReceivedMessageState, mess
|
|||
|
||||
state.Response.AddMessage(request)
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (m *Messenger) HandleRetractContactRequest(state *ReceivedMessageState, message protobuf.RetractContactRequest) error {
|
||||
|
@ -687,7 +739,14 @@ func (m *Messenger) HandleRetractContactRequest(state *ReceivedMessageState, mes
|
|||
// We remove from our old contacts only if mutual contacts are enabled
|
||||
if mutualContactEnabled {
|
||||
contact.Added = false
|
||||
|
||||
}
|
||||
// We remove anything that's related to this contact request
|
||||
err = m.persistence.RemoveAllContactRequestActivityCenterNotifications(contact.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
contact.HasAddedUs = false
|
||||
contact.ContactRequestClock = message.Clock
|
||||
contact.ContactRequestRetracted()
|
||||
|
@ -738,7 +797,7 @@ func (m *Messenger) HandleContactUpdate(state *ReceivedMessageState, message pro
|
|||
contact.LastUpdated = message.Clock
|
||||
state.ModifiedContacts.Store(contact.ID, true)
|
||||
state.AllContacts.Store(contact.ID, contact)
|
||||
/* Disabling for now in order to avoid duplicated contact requests in activity center
|
||||
// Has the user added us?
|
||||
if contact.ContactRequestState == ContactRequestStateNone {
|
||||
contact.ContactRequestState = ContactRequestStateReceived
|
||||
err = m.createContactRequestNotification(contact, state, nil)
|
||||
|
@ -746,7 +805,11 @@ func (m *Messenger) HandleContactUpdate(state *ReceivedMessageState, message pro
|
|||
m.logger.Warn("could not create contact request notification", zap.Error(err))
|
||||
}
|
||||
|
||||
}*/
|
||||
// Has the user replied to a default contact request
|
||||
} else if contact.ContactRequestState == ContactRequestStateSent {
|
||||
contact.ContactRequestState = ContactRequestStateMutual
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if chat.LastClockValue < message.Clock {
|
||||
|
|
|
@ -360,6 +360,19 @@ func (r *MessengerResponse) AddActivityCenterNotification(n *ActivityCenterNotif
|
|||
r.activityCenterNotifications[n.ID.String()] = n
|
||||
}
|
||||
|
||||
func (r *MessengerResponse) RemoveActivityCenterNotification(id string) bool {
|
||||
if r.activityCenterNotifications == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, ok := r.activityCenterNotifications[id]; ok {
|
||||
delete(r.activityCenterNotifications, id)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (r *MessengerResponse) ActivityCenterNotifications() []*ActivityCenterNotification {
|
||||
var ns []*ActivityCenterNotification
|
||||
for _, n := range r.activityCenterNotifications {
|
||||
|
|
|
@ -977,3 +977,189 @@ func (s *MessengerPushNotificationSuite) TestReceivePushNotificationCommunityReq
|
|||
s.Require().NoError(alice.Shutdown())
|
||||
s.Require().NoError(server.Shutdown())
|
||||
}
|
||||
|
||||
func (s *MessengerPushNotificationSuite) TestReceivePushNotificationPairedDevices() {
|
||||
|
||||
bob1 := s.m
|
||||
bob2, err := newMessengerWithKey(s.shh, s.m.identity, s.logger, []Option{WithPushNotifications()})
|
||||
s.Require().NoError(err)
|
||||
|
||||
serverKey, err := crypto.GenerateKey()
|
||||
s.Require().NoError(err)
|
||||
server := s.newPushNotificationServer(s.shh, serverKey)
|
||||
|
||||
alice := s.newMessenger(s.shh)
|
||||
// start alice and enable sending push notifications
|
||||
_, err = alice.Start()
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(alice.EnableSendingPushNotifications())
|
||||
bobInstallationIDs := []string{bob1.installationID, bob2.installationID}
|
||||
|
||||
// Register bob1
|
||||
err = bob1.AddPushNotificationsServer(context.Background(), &server.identity.PublicKey, pushnotificationclient.ServerTypeCustom)
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = bob1.RegisterForPushNotifications(context.Background(), bob1DeviceToken, testAPNTopic, protobuf.PushNotificationRegistration_APN_TOKEN)
|
||||
|
||||
// Pull servers and check we registered
|
||||
err = tt.RetryWithBackOff(func() error {
|
||||
_, err = server.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = bob1.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
registered, err := bob1.RegisteredForPushNotifications()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !registered {
|
||||
return errors.New("not registered")
|
||||
}
|
||||
bobServers, err := bob1.GetPushNotificationsServers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(bobServers) == 0 {
|
||||
return errors.New("not registered")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
// Make sure we receive it
|
||||
s.Require().NoError(err)
|
||||
bob1Servers, err := bob1.GetPushNotificationsServers()
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Register bob2
|
||||
err = bob2.AddPushNotificationsServer(context.Background(), &server.identity.PublicKey, pushnotificationclient.ServerTypeCustom)
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = bob2.RegisterForPushNotifications(context.Background(), bob2DeviceToken, testAPNTopic, protobuf.PushNotificationRegistration_APN_TOKEN)
|
||||
s.Require().NoError(err)
|
||||
|
||||
err = tt.RetryWithBackOff(func() error {
|
||||
_, err = server.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = bob2.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
registered, err := bob2.RegisteredForPushNotifications()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !registered {
|
||||
return errors.New("not registered")
|
||||
}
|
||||
bobServers, err := bob2.GetPushNotificationsServers()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(bobServers) == 0 {
|
||||
return errors.New("not registered")
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
// Make sure we receive it
|
||||
s.Require().NoError(err)
|
||||
bob2Servers, err := bob2.GetPushNotificationsServers()
|
||||
s.Require().NoError(err)
|
||||
|
||||
// Create one to one chat & send message
|
||||
pkString := hex.EncodeToString(crypto.FromECDSAPub(&s.m.identity.PublicKey))
|
||||
chat := CreateOneToOneChat(pkString, &s.m.identity.PublicKey, alice.transport)
|
||||
s.Require().NoError(alice.SaveChat(chat))
|
||||
inputMessage := buildTestMessage(*chat)
|
||||
response, err := alice.SendChatMessage(context.Background(), inputMessage)
|
||||
s.Require().NoError(err)
|
||||
messageIDString := response.Messages()[0].ID
|
||||
messageID, err := hex.DecodeString(messageIDString[2:])
|
||||
s.Require().NoError(err)
|
||||
|
||||
infoMap := make(map[string]*pushnotificationclient.PushNotificationInfo)
|
||||
err = tt.RetryWithBackOff(func() error {
|
||||
_, err = server.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = alice.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info, err := alice.pushNotificationClient.GetPushNotificationInfo(&bob1.identity.PublicKey, bobInstallationIDs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, i := range info {
|
||||
infoMap[i.AccessToken] = i
|
||||
}
|
||||
|
||||
// Check we have replies for both bob1 and bob2
|
||||
if len(infoMap) != 2 {
|
||||
return errors.New("info not fetched")
|
||||
}
|
||||
return nil
|
||||
|
||||
})
|
||||
|
||||
s.Require().Len(infoMap, 2)
|
||||
|
||||
// Check we have replies for both bob1 and bob2
|
||||
var bob1Info, bob2Info *pushnotificationclient.PushNotificationInfo
|
||||
|
||||
bob1Info = infoMap[bob1Servers[0].AccessToken]
|
||||
bob2Info = infoMap[bob2Servers[0].AccessToken]
|
||||
|
||||
s.Require().NotNil(bob1Info)
|
||||
s.Require().Equal(bob1.installationID, bob1Info.InstallationID)
|
||||
s.Require().Equal(bob1Servers[0].AccessToken, bob1Info.AccessToken)
|
||||
s.Require().Equal(&bob1.identity.PublicKey, bob1Info.PublicKey)
|
||||
|
||||
s.Require().NotNil(bob2Info)
|
||||
s.Require().Equal(bob2.installationID, bob2Info.InstallationID)
|
||||
s.Require().Equal(bob2Servers[0].AccessToken, bob2Info.AccessToken)
|
||||
s.Require().Equal(&bob2.identity.PublicKey, bob2Info.PublicKey)
|
||||
|
||||
retrievedNotificationInfo, err := alice.pushNotificationClient.GetPushNotificationInfo(&bob1.identity.PublicKey, bobInstallationIDs)
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(retrievedNotificationInfo)
|
||||
s.Require().Len(retrievedNotificationInfo, 2)
|
||||
|
||||
var sentNotification *pushnotificationclient.SentNotification
|
||||
err = tt.RetryWithBackOff(func() error {
|
||||
_, err = server.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = alice.RetrieveAll()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sentNotification, err = alice.pushNotificationClient.GetSentNotification(common.HashPublicKey(&bob1.identity.PublicKey), bob1.installationID, messageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sentNotification == nil {
|
||||
return errors.New("sent notification not found")
|
||||
}
|
||||
if !sentNotification.Success {
|
||||
return errors.New("sent notification not successul")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(bob2.Shutdown())
|
||||
s.Require().NoError(alice.Shutdown())
|
||||
s.Require().NoError(server.Shutdown())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue