status-go/protocol/messenger_handler_test.go

200 lines
5.7 KiB
Go

package protocol
import (
"context"
"crypto/ecdsa"
"testing"
"github.com/stretchr/testify/suite"
"go.uber.org/zap"
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/tt"
v1protocol "github.com/status-im/status-go/protocol/v1"
localnotifications "github.com/status-im/status-go/services/local-notifications"
"github.com/status-im/status-go/waku"
)
func TestEventToSystemMessageSuite(t *testing.T) {
suite.Run(t, new(EventToSystemMessageSuite))
}
type EventToSystemMessageSuite struct {
suite.Suite
m *Messenger // main instance of Messenger
privateKey *ecdsa.PrivateKey // private key for the main instance of Messenger
// If one wants to send messages between different instances of Messenger,
// a single waku service should be shared.
shh types.Waku
logger *zap.Logger
}
func (s *EventToSystemMessageSuite) newMessenger() *Messenger {
privateKey, err := crypto.GenerateKey()
s.Require().NoError(err)
messenger, err := newMessengerWithKey(s.shh, privateKey, s.logger, nil)
s.Require().NoError(err)
return messenger
}
func (s *EventToSystemMessageSuite) SetupTest() {
s.logger = tt.MustCreateTestLogger()
config := waku.DefaultConfig
config.MinimumAcceptedPoW = 0
shh := waku.New(&config, s.logger)
s.shh = gethbridge.NewGethWakuWrapper(shh)
s.Require().NoError(shh.Start())
s.m = s.newMessenger()
s.privateKey = s.m.identity
_, err := s.m.Start()
s.Require().NoError(err)
}
func (s *EventToSystemMessageSuite) TestRun() {
testCases := []struct {
Name string
Event v1protocol.MembershipUpdateEvent
Expected string
From string
}{
{
Name: "chat created event",
Event: v1protocol.NewChatCreatedEvent("chat-name", 12),
From: "admin",
Expected: "@admin created the group chat-name",
},
{
Name: "chat name changed event",
Event: v1protocol.NewNameChangedEvent("chat-name-2", 12),
From: "admin",
Expected: "@admin changed the group's name to chat-name-2",
},
{
Name: "members added event",
Event: v1protocol.NewMembersAddedEvent([]string{"a", "b", "c"}, 12),
From: "admin",
Expected: "@admin has invited @a, @b, @c",
},
{
Name: "member joined event",
Event: v1protocol.NewMemberJoinedEvent(12),
From: "admin",
Expected: "@admin joined the group",
},
{
Name: "admins added event",
Event: v1protocol.NewAdminsAddedEvent([]string{"a", "b", "c"}, 12),
From: "admin",
Expected: "@admin has made @a, @b, @c admin",
},
{
Name: "member removed event",
Event: v1protocol.NewMemberRemovedEvent("a", 12),
From: "admin",
Expected: "@a left the group",
},
{
Name: "admin removed event",
Event: v1protocol.NewAdminRemovedEvent("a", 12),
From: "admin",
Expected: "@a is not admin anymore",
},
}
for _, tc := range testCases {
s.Run(tc.Name, func() {
tc.Event.From = tc.From
systemMessage := eventToSystemMessage(tc.Event, defaultSystemMessagesTranslations)
s.Equal(systemMessage.Text, tc.Expected)
})
}
}
func (s *EventToSystemMessageSuite) TestHandleMembershipUpdate() {
adminPrivateKey, err := crypto.GenerateKey()
s.Require().NoError(err)
adminPublicKey := types.EncodeHex(crypto.FromECDSAPub(&adminPrivateKey.PublicKey))
ourPublicKey := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
event1 := v1protocol.MembershipUpdateEvent{
Type: protobuf.MembershipUpdateEvent_CHAT_CREATED,
Name: "test",
ChatID: "test-" + adminPublicKey,
ClockValue: 100,
}
err = event1.Sign(adminPrivateKey)
s.Require().NoError(err)
event2 := v1protocol.MembershipUpdateEvent{
Type: protobuf.MembershipUpdateEvent_MEMBERS_ADDED,
Members: []string{adminPublicKey, ourPublicKey},
ChatID: "test-" + adminPublicKey,
ClockValue: 100,
}
err = event2.Sign(adminPrivateKey)
s.Require().NoError(err)
testMembershipUpdateMessageStruct2 := v1protocol.MembershipUpdateMessage{
ChatID: "test-" + adminPublicKey,
Events: []v1protocol.MembershipUpdateEvent{
event1,
event2,
},
}
rawMembershipUpdateMessage2, err := testMembershipUpdateMessageStruct2.ToProtobuf()
s.Require().NoError(err)
contact, err := BuildContactFromPublicKey(&adminPrivateKey.PublicKey)
s.Require().NoError(err)
contact.Added = true
currentMessageState := &CurrentMessageState{
Contact: contact,
}
state := &ReceivedMessageState{
Response: &MessengerResponse{},
Timesource: s.m.transport,
CurrentMessageState: currentMessageState,
ExistingMessagesMap: map[string]bool{},
AllChats: s.m.allChats,
}
err = s.m.HandleMembershipUpdate(state, nil, *rawMembershipUpdateMessage2, defaultSystemMessagesTranslations)
s.Require().NoError(err)
s.Require().Len(state.Response.Notifications(), 1)
s.Require().Equal(state.Response.Notifications()[0].Category, localnotifications.CategoryGroupInvite)
s.Require().Len(state.Response.Chats(), 1)
chat := state.Response.Chats()[0]
// Decline event, setting chat inactive
response, err := s.m.LeaveGroupChat(context.Background(), chat.ID, true)
s.Require().NoError(err)
s.Require().Len(response.Chats(), 1)
chat = response.Chats()[0]
// If the same response is handled, it should not show another notification & the chat should remain inactive
state.Response = &MessengerResponse{}
err = s.m.HandleMembershipUpdate(state, chat, *rawMembershipUpdateMessage2, defaultSystemMessagesTranslations)
s.Require().NoError(err)
s.Require().Len(state.Response.Notifications(), 0)
s.Require().Len(state.Response.Chats(), 1)
s.Require().False(state.Response.Chats()[0].Active)
}