package protocol import ( "encoding/json" "testing" "github.com/stretchr/testify/suite" "github.com/status-im/status-go/protocol/common" ) type ChatTestSuite struct { suite.Suite } func TestChatSuite(t *testing.T) { suite.Run(t, new(ChatTestSuite)) } func (s *ChatTestSuite) TestValidateChat() { testCases := []struct { Name string Valid bool Chat Chat }{ { Name: "valid one to one chat", Valid: true, Chat: Chat{ ID: "0x0424a68f89ba5fcd5e0640c1e1f591d561fa4125ca4e2a43592bc4123eca10ce064e522c254bb83079ba404327f6eafc01ec90a1444331fe769d3f3a7f90b0dde1", Name: "", ChatType: ChatTypeOneToOne, }, }, { Name: "valid public chat", Valid: true, Chat: Chat{ ID: "status", Name: "status", ChatType: ChatTypePublic, }, }, { Name: "empty chatID", Valid: false, Chat: Chat{ ID: "", Name: "status", ChatType: ChatTypePublic, }, }, { Name: "invalid one to one chat, wrong public key", Valid: false, Chat: Chat{ ID: "0xnotvalid", Name: "", ChatType: ChatTypeOneToOne, }, }, } for _, tc := range testCases { s.Run(tc.Name, func() { err := tc.Chat.Validate() if tc.Valid { s.Require().NoError(err) } else { s.Require().Error(err) } }) } } func (s *ChatTestSuite) TestUpdateFromMessage() { // Base case, clock is higher message := common.NewMessage() chat := &Chat{} message.Clock = 1 s.Require().NoError(chat.UpdateFromMessage(message, &testTimeSource{})) s.Require().NotNil(chat.LastMessage) s.Require().Equal(uint64(1), chat.LastClockValue) // Clock is lower and lastMessage is not nil message = common.NewMessage() lastMessage := message chat = &Chat{LastClockValue: 2, LastMessage: lastMessage} message.Clock = 1 s.Require().NoError(chat.UpdateFromMessage(message, &testTimeSource{})) s.Require().Equal(lastMessage, chat.LastMessage) s.Require().Equal(uint64(2), chat.LastClockValue) // Clock is lower and lastMessage is nil message = common.NewMessage() chat = &Chat{LastClockValue: 2} message.Clock = 1 s.Require().NoError(chat.UpdateFromMessage(message, &testTimeSource{})) s.Require().NotNil(chat.LastMessage) s.Require().Equal(uint64(2), chat.LastClockValue) // Clock is higher but lastMessage has lower clock message then the receiving one message = common.NewMessage() chat = &Chat{LastClockValue: 2} message.Clock = 1 s.Require().NoError(chat.UpdateFromMessage(message, &testTimeSource{})) s.Require().NotNil(chat.LastMessage) s.Require().Equal(uint64(2), chat.LastClockValue) chat.LastClockValue = 4 message = common.NewMessage() message.Clock = 3 s.Require().NoError(chat.UpdateFromMessage(message, &testTimeSource{})) s.Require().Equal(chat.LastMessage, message) s.Require().Equal(uint64(4), chat.LastClockValue) } func (s *ChatTestSuite) TestSerializeJSON() { message := common.NewMessage() chat := &Chat{} message.From = "0x04deaafa03e3a646e54a36ec3f6968c1d3686847d88420f00c0ab6ee517ee1893398fca28aacd2af74f2654738c21d10bad3d88dc64201ebe0de5cf1e313970d3d" message.Clock = 1 message.Text = "`some markdown text` https://status.im" s.Require().NoError(message.PrepareContent("")) message.ParsedTextAst = nil chat.LastMessage = message encodedJSON, err := json.Marshal(chat) s.Require().NoError(err) decodedChat := &Chat{} s.Require().NoError(json.Unmarshal(encodedJSON, decodedChat)) s.Require().Equal(chat, decodedChat) } func (s *ChatTestSuite) TestUpdateFirstMessageTimestamp() { chat := &Chat{ FirstMessageTimestamp: 0, } setAndCheck := func(newValue uint32, success bool, expectedValue uint32) { s.Equal(success, chat.UpdateFirstMessageTimestamp(newValue)) s.Equal(expectedValue, chat.FirstMessageTimestamp) } setAndCheck(FirstMessageTimestampUndefined, false, FirstMessageTimestampUndefined) setAndCheck(FirstMessageTimestampNoMessage, true, FirstMessageTimestampNoMessage) setAndCheck(FirstMessageTimestampUndefined, false, FirstMessageTimestampNoMessage) setAndCheck(FirstMessageTimestampNoMessage, false, FirstMessageTimestampNoMessage) setAndCheck(200, true, 200) setAndCheck(FirstMessageTimestampUndefined, false, 200) setAndCheck(FirstMessageTimestampNoMessage, false, 200) setAndCheck(100, true, 100) } func (s *ChatTestSuite) TestDefaultResendType() { testID := "some-id" testCases := []struct { Name string ExpectedResendType common.ResendType Chat Chat }{ { Name: "one to one chat", ExpectedResendType: common.ResendTypeDataSync, Chat: Chat{ ID: testID, ChatType: ChatTypeOneToOne, }, }, { Name: "private group chat", ExpectedResendType: common.ResendTypeDataSync, Chat: Chat{ ID: testID, ChatType: ChatTypePrivateGroupChat, }, }, { Name: "community chat", ExpectedResendType: common.ResendTypeRawMessage, Chat: Chat{ ID: testID, ChatType: ChatTypeCommunityChat, }, }, } for _, tc := range testCases { s.Run(tc.Name, func() { s.Require().Equal(tc.ExpectedResendType, tc.Chat.DefaultResendType()) }) } } func (s *ChatTestSuite) TestDeepLink() { chat := &Chat{ CommunityID: "0x02b1188c997e666cd5505ffd5c4b5fdbe3084b78a486d8e709da3b32ad3708a89e", ID: "0x02b1188c997e666cd5505ffd5c4b5fdbe3084b78a486d8e709da3b32ad3708a89ec432709e-fc73-440d-bb67-cb3a0929dfda", ChatType: ChatTypeCommunityChat, } s.Require().Equal(chat.DeepLink(), "status-app://cc/c432709e-fc73-440d-bb67-cb3a0929dfda#zQ3shZL6dXiFCbDyxnXxwQa9v8QFC2q19subFtyxd7kVszMVo") } func (s *ChatTestSuite) TestGetChatContextFromChatType() { chat := &Chat{ CommunityID: "0x02b1", ID: "0x02b1", ChatType: ChatTypeCommunityChat, } s.Require().Equal(GetChatContextFromChatType(chat.ChatType), publicChat) chat = &Chat{ CommunityID: "0x02b1", ID: "0x02b1", ChatType: ChatTypeOneToOne, } s.Require().Equal(GetChatContextFromChatType(chat.ChatType), privateChat) chat = &Chat{ CommunityID: "0x02b1", ID: "0x02b1", ChatType: ChatTypePrivateGroupChat, } s.Require().Equal(GetChatContextFromChatType(chat.ChatType), privateChat) }