Accept/Dismiss LastestContactRequestForContact endpoint (#2702)

This commit is contained in:
Andrea Maria Piana 2022-06-17 17:20:43 +01:00 committed by GitHub
parent c855272340
commit 961526556b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 293 additions and 0 deletions

View File

@ -670,6 +670,25 @@ func (db sqlitePersistence) PendingContactRequests(currCursor string, limit int)
return result, newCursor, nil return result, newCursor, nil
} }
func (db sqlitePersistence) LatestPendingContactRequestIDForContact(contactID string) (string, error) {
var id string
err := db.db.QueryRow(
`
SELECT
id
FROM
user_messages m1
WHERE
m1.local_chat_id = ? AND m1.content_type = ?
ORDER BY substr('0000000000000000000000000000000000000000000000000000000000000000' || m1.clock_value, -64, 64) || m1.id DESC
LIMIT 1
`, contactID, protobuf.ChatMessage_CONTACT_REQUEST).Scan(&id)
if err != nil {
return "", err
}
return id, nil
}
// AllMessageByChatIDWhichMatchPattern returns all messages which match the search // AllMessageByChatIDWhichMatchPattern returns all messages which match the search
// term, for a given chatID in descending order. // term, for a given chatID in descending order.
// Ordering is accomplished using two concatenated values: ClockValue and ID. // Ordering is accomplished using two concatenated values: ClockValue and ID.

View File

@ -604,6 +604,204 @@ func (s *MessengerContactRequestSuite) TestReceiveAndAcceptContactRequestTwice()
s.Require().Len(mutualContacts, 1) s.Require().Len(mutualContacts, 1)
} }
func (s *MessengerContactRequestSuite) TestAcceptLatestContactRequestForContact() {
messageText := "hello!"
theirMessenger := s.newMessenger(s.shh)
_, err := theirMessenger.Start()
s.Require().NoError(err)
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID),
Message: messageText,
}
// Send contact request
resp, err := s.m.SendContactRequest(context.Background(), request)
s.Require().NoError(err)
s.Require().NotNil(resp)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(common.ContactRequestStatePending, resp.Messages()[0].ContactRequestState)
// Make sure it's not returned as coming from us
contactRequests, _, err := s.m.PendingContactRequests("", 10)
s.Require().NoError(err)
s.Require().Len(contactRequests, 0)
// 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.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
// Check contact request has been received
s.Require().NoError(err)
// Check activity center notification is of the right type
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
s.Require().Equal(common.ContactRequestStatePending, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestState)
// Make sure it's the pending contact requests
contactRequests, _, err = theirMessenger.PendingContactRequests("", 10)
s.Require().NoError(err)
s.Require().Len(contactRequests, 1)
s.Require().Equal(contactRequests[0].ContactRequestState, common.ContactRequestStatePending)
// Accept latest contact request, receiver side
resp, err = theirMessenger.AcceptLatestContactRequestForContact(context.Background(), &requests.AcceptLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
s.Require().NoError(err)
// Make sure the message is updated
s.Require().NotNil(resp)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(resp.Messages()[0].ID, contactRequests[0].ID)
s.Require().Equal(common.ContactRequestStateAccepted, resp.Messages()[0].ContactRequestState)
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), contactRequests[0].ID)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateMutual, resp.Contacts[0].ContactRequestState)
// Make sure the sender is added to our contacts
contacts = theirMessenger.AddedContacts()
s.Require().Len(contacts, 1)
// Make sure we consider them a mutual contact, receiver side
mutualContacts := theirMessenger.MutualContacts()
s.Require().Len(mutualContacts, 1)
// Wait for the message to reach its destination
resp, err = WaitOnMessengerResponse(
s.m,
func(r *MessengerResponse) bool {
return len(r.Contacts) > 0 && len(r.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
s.Require().NoError(err)
// Check activity center notification is of the right type
s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
s.Require().Equal(common.ContactRequestStateAccepted, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
// Make sure the message is updated, sender s2de
s.Require().NotNil(resp)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(resp.Messages()[0].ID, contactRequests[0].ID)
s.Require().Equal(common.ContactRequestStateAccepted, resp.Messages()[0].ContactRequestState)
// Make sure we consider them a mutual contact, sender side
mutualContacts = s.m.MutualContacts()
s.Require().Len(mutualContacts, 1)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateMutual, resp.Contacts[0].ContactRequestState)
}
func (s *MessengerContactRequestSuite) TestDismissLatestContactRequestForContact() {
messageText := "hello!"
theirMessenger := s.newMessenger(s.shh)
_, err := theirMessenger.Start()
s.Require().NoError(err)
contactID := types.EncodeHex(crypto.FromECDSAPub(&theirMessenger.identity.PublicKey))
myID := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
request := &requests.SendContactRequest{
ID: types.Hex2Bytes(contactID),
Message: messageText,
}
// Send contact request
resp, err := s.m.SendContactRequest(context.Background(), request)
s.Require().NoError(err)
s.Require().NotNil(resp)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(common.ContactRequestStatePending, resp.Messages()[0].ContactRequestState)
// Make sure it's not returned as coming from us
contactRequests, _, err := s.m.PendingContactRequests("", 10)
s.Require().NoError(err)
s.Require().Len(contactRequests, 0)
// 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.Messages()) > 0 && len(r.ActivityCenterNotifications()) > 0
},
"no messages",
)
// Check contact request has been received
s.Require().NoError(err)
// Check activity center notification is of the right type
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(ActivityCenterNotificationTypeContactRequest, resp.ActivityCenterNotifications()[0].Type)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
s.Require().Equal(common.ContactRequestStatePending, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
// Check the contact state is correctly set
s.Require().Len(resp.Contacts, 1)
s.Require().Equal(ContactRequestStateReceived, resp.Contacts[0].ContactRequestState)
// Make sure it's the pending contact requests
contactRequests, _, err = theirMessenger.PendingContactRequests("", 10)
s.Require().NoError(err)
s.Require().Len(contactRequests, 1)
s.Require().Equal(contactRequests[0].ContactRequestState, common.ContactRequestStatePending)
// Dismiss latest contact request, receiver side
resp, err = theirMessenger.DismissLatestContactRequestForContact(context.Background(), &requests.DismissLatestContactRequestForContact{ID: types.Hex2Bytes(myID)})
s.Require().NoError(err)
// Make sure the message is updated
s.Require().NotNil(resp)
s.Require().Len(resp.Messages(), 1)
s.Require().Equal(resp.Messages()[0].ID, contactRequests[0].ID)
s.Require().Equal(common.ContactRequestStateDismissed, resp.Messages()[0].ContactRequestState)
s.Require().Len(resp.ActivityCenterNotifications(), 1)
s.Require().Equal(resp.ActivityCenterNotifications()[0].ID.String(), contactRequests[0].ID)
s.Require().NotNil(resp.ActivityCenterNotifications()[0].Message)
s.Require().Equal(common.ContactRequestStateDismissed, resp.ActivityCenterNotifications()[0].Message.ContactRequestState)
}
/* Disabling as currently there's an issue with duplicated contact requests /* Disabling as currently there's an issue with duplicated contact requests
func (s *MessengerContactRequestSuite) TestReceiveAndAcceptLegacyContactRequest() { func (s *MessengerContactRequestSuite) TestReceiveAndAcceptLegacyContactRequest() {

View File

@ -819,6 +819,32 @@ func (m *Messenger) RetractContactRequest(request *requests.RetractContactReques
return response, err return response, err
} }
func (m *Messenger) AcceptLatestContactRequestForContact(ctx context.Context, request *requests.AcceptLatestContactRequestForContact) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
contactRequestID, err := m.persistence.LatestPendingContactRequestIDForContact(request.ID.String())
if err != nil {
return nil, err
}
return m.AcceptContactRequest(ctx, &requests.AcceptContactRequest{ID: types.Hex2Bytes(contactRequestID)})
}
func (m *Messenger) DismissLatestContactRequestForContact(ctx context.Context, request *requests.DismissLatestContactRequestForContact) (*MessengerResponse, error) {
if err := request.Validate(); err != nil {
return nil, err
}
contactRequestID, err := m.persistence.LatestPendingContactRequestIDForContact(request.ID.String())
if err != nil {
return nil, err
}
return m.DismissContactRequest(ctx, &requests.DismissContactRequest{ID: types.Hex2Bytes(contactRequestID)})
}
func (m *Messenger) PendingContactRequests(cursor string, limit int) ([]*common.Message, string, error) { func (m *Messenger) PendingContactRequests(cursor string, limit int) ([]*common.Message, string, error) {
return m.persistence.PendingContactRequests(cursor, limit) return m.persistence.PendingContactRequests(cursor, limit)
} }

View File

@ -0,0 +1,21 @@
package requests
import (
"errors"
"github.com/status-im/status-go/eth-node/types"
)
var ErrAcceptLatestContactRequestForContactInvalidID = errors.New("accept-latest-contact-request-for-contact: invalid id")
type AcceptLatestContactRequestForContact struct {
ID types.HexBytes `json:"id"`
}
func (a *AcceptLatestContactRequestForContact) Validate() error {
if len(a.ID) == 0 {
return ErrAcceptLatestContactRequestForContactInvalidID
}
return nil
}

View File

@ -0,0 +1,21 @@
package requests
import (
"errors"
"github.com/status-im/status-go/eth-node/types"
)
var ErrDismissLatestContactRequestForContactInvalidID = errors.New("dismiss-latest-contact-request-for-contact: invalid id")
type DismissLatestContactRequestForContact struct {
ID types.HexBytes `json:"id"`
}
func (a *DismissLatestContactRequestForContact) Validate() error {
if len(a.ID) == 0 {
return ErrDismissLatestContactRequestForContactInvalidID
}
return nil
}

View File

@ -620,6 +620,14 @@ func (api *PublicAPI) AcceptContactRequest(ctx context.Context, request *request
return api.service.messenger.AcceptContactRequest(ctx, request) return api.service.messenger.AcceptContactRequest(ctx, request)
} }
func (api *PublicAPI) AcceptLatestContactRequestForContact(ctx context.Context, request *requests.AcceptLatestContactRequestForContact) (*protocol.MessengerResponse, error) {
return api.service.messenger.AcceptLatestContactRequestForContact(ctx, request)
}
func (api *PublicAPI) DismissLatestContactRequestForContact(ctx context.Context, request *requests.DismissLatestContactRequestForContact) (*protocol.MessengerResponse, error) {
return api.service.messenger.DismissLatestContactRequestForContact(ctx, request)
}
func (api *PublicAPI) RetractContactRequest(ctx context.Context, request *requests.RetractContactRequest) (*protocol.MessengerResponse, error) { func (api *PublicAPI) RetractContactRequest(ctx context.Context, request *requests.RetractContactRequest) (*protocol.MessengerResponse, error) {
return api.service.messenger.RetractContactRequest(request) return api.service.messenger.RetractContactRequest(request)
} }