Files
status-go/internal/protocol/messenger_handler_test.go
Igor Sirotin f9cc782a6f refactor: move services to pkg/services
Part of the Go project layout migration, item 31.

Pure move plus import-path rewrite across 687 files. No API or behaviour
change.

The services keep their grouping under pkg/services/<name> rather than
being promoted to pkg/<name>: 27 top-level directories in pkg/ would read
worse than what we have, and the grouping is what makes "an RPC service"
identifiable at a glance.

Paths that follow the move: the logosstorage test target and generate
step, the two wallet token-list tools, the migration-order check (and the
pre-rebase hook symlinked to it), and the storage env helper.

refs #7067
2026-08-21 10:11:05 +02:00

176 lines
5.2 KiB
Go

package protocol
import (
"context"
"testing"
"github.com/stretchr/testify/suite"
"github.com/status-im/status-go/internal/crypto"
"github.com/status-im/status-go/internal/crypto/types"
"github.com/status-im/status-go/internal/protocol/contacts"
"github.com/status-im/status-go/internal/protocol/protobuf"
v1protocol "github.com/status-im/status-go/internal/protocol/v1"
localnotifications "github.com/status-im/status-go/pkg/services/local-notifications"
)
func TestEventToSystemMessageSuite(t *testing.T) {
suite.Run(t, new(EventToSystemMessageSuite))
}
type EventToSystemMessageSuite struct {
MessengerBaseTestSuite
}
func (s *EventToSystemMessageSuite) TestRun() {
testCases := []struct {
Name string
Event v1protocol.MembershipUpdateEvent
Expected string
From string
}{
{
Name: "chat created event",
Event: v1protocol.NewChatCreatedEvent("chat-name", "#7cda00", 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: "chat color changed event",
Event: v1protocol.NewColorChangedEvent("#7cda00", 12),
From: "admin",
Expected: "@admin changed the group's color",
},
{
Name: "chat image changed event",
Event: v1protocol.NewImageChangedEvent([]byte{1, 2, 3}, 12),
From: "admin",
Expected: "@admin changed the group's image",
},
{
Name: "members added event",
Event: v1protocol.NewMembersAddedEvent([]string{"a", "b", "c"}, 12),
From: "admin",
Expected: "@admin has added @a, @b, @c",
},
{
Name: "member joined event",
Event: v1protocol.NewMemberJoinedEvent(12),
From: "admin",
Expected: "", // joined events are deprecated
},
{
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 := contacts.BuildContactFromPublicKey(&adminPrivateKey.PublicKey)
s.Require().NoError(err)
contact.ContactRequestLocalState = contacts.ContactRequestStateSent
currentMessageState := &CurrentMessageState{
Contact: contact,
}
state := &ReceivedMessageState{
Response: &MessengerResponse{},
Timesource: s.m.getTimesource(),
CurrentMessageState: currentMessageState,
ExistingMessagesMap: map[string]bool{},
AllChats: s.m.allChats,
}
err = s.m.HandleMembershipUpdate(context.Background(), 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(context.Background(), 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)
}