Use local chat-id for matching messages
This commit is contained in:
parent
d067b56fc2
commit
29f25c5486
|
@ -129,7 +129,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesWrapped() {
|
|||
s.Require().Equal(1, len(decodedMessages))
|
||||
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
||||
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
||||
parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
|
||||
parsedMessage := decodedMessages[0].ParsedMessage.Interface().(protobuf.ChatMessage)
|
||||
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
||||
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
||||
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
||||
|
@ -167,7 +167,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasync() {
|
|||
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
||||
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
||||
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
||||
parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
|
||||
parsedMessage := decodedMessages[0].ParsedMessage.Interface().(protobuf.ChatMessage)
|
||||
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
||||
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ func (s *MessageProcessorSuite) TestHandleDecodedMessagesDatasyncEncrypted() {
|
|||
s.Require().Equal(&authorKey.PublicKey, decodedMessages[0].SigPubKey())
|
||||
s.Require().Equal(v1protocol.MessageID(&authorKey.PublicKey, wrappedPayload), decodedMessages[0].ID)
|
||||
s.Require().Equal(encodedPayload, decodedMessages[0].DecryptedPayload)
|
||||
parsedMessage := decodedMessages[0].ParsedMessage.(protobuf.ChatMessage)
|
||||
parsedMessage := decodedMessages[0].ParsedMessage.Interface().(protobuf.ChatMessage)
|
||||
s.Require().True(proto.Equal(&s.testMessage, &parsedMessage))
|
||||
s.Require().Equal(protobuf.ApplicationMetadataMessage_CHAT_MESSAGE, decodedMessages[0].Type)
|
||||
}
|
||||
|
|
|
@ -22,11 +22,14 @@ type EmojiReaction struct {
|
|||
|
||||
// SigPubKey is the ecdsa encoded public key of the emoji reaction author
|
||||
SigPubKey *ecdsa.PublicKey `json:"-"`
|
||||
|
||||
// LocalChatID is the chatID of the local chat (one-to-one are not symmetric)
|
||||
LocalChatID string `json:"localChatId"`
|
||||
}
|
||||
|
||||
// ID is the Keccak256() contatenation of From-ChatID-MessageID-EmojiType
|
||||
// ID is the Keccak256() contatenation of From-MessageID-EmojiType
|
||||
func (e EmojiReaction) ID() string {
|
||||
return types.EncodeHex(crypto.Keccak256([]byte(fmt.Sprintf("%s%s%s%d", e.From, e.ChatId, e.MessageId, e.Type))))
|
||||
return types.EncodeHex(crypto.Keccak256([]byte(fmt.Sprintf("%s%s%d", e.From, e.MessageId, e.Type))))
|
||||
}
|
||||
|
||||
// GetSigPubKey returns an ecdsa encoded public key
|
||||
|
|
|
@ -670,10 +670,20 @@ func (m *MessageHandler) messageExists(messageID string, existingMessagesMap map
|
|||
|
||||
func (m *MessageHandler) HandleEmojiReaction(state *ReceivedMessageState, pbEmojiR protobuf.EmojiReaction) error {
|
||||
logger := m.logger.With(zap.String("site", "HandleEmojiReaction"))
|
||||
if err := ValidateReceivedEmojiReaction(&pbEmojiR, state.Timesource.GetCurrentTime()); err != nil {
|
||||
logger.Error("invalid emoji reaction", zap.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
from := state.CurrentMessageState.Contact.ID
|
||||
|
||||
// check that the user can actually send an emoji for this message
|
||||
existingEmoji, err := m.persistence.EmojiReactionByFromMessageIDAndType(from, pbEmojiR.MessageId, pbEmojiR.Type)
|
||||
emojiReaction := &EmojiReaction{
|
||||
EmojiReaction: pbEmojiR,
|
||||
From: from,
|
||||
SigPubKey: state.CurrentMessageState.PublicKey,
|
||||
}
|
||||
|
||||
existingEmoji, err := m.persistence.EmojiReactionByID(emojiReaction.ID())
|
||||
if err != errRecordNotFound && err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -683,18 +693,15 @@ func (m *MessageHandler) HandleEmojiReaction(state *ReceivedMessageState, pbEmoj
|
|||
return nil
|
||||
}
|
||||
|
||||
emojiReaction := &EmojiReaction{
|
||||
EmojiReaction: pbEmojiR,
|
||||
From: from,
|
||||
SigPubKey: state.CurrentMessageState.PublicKey,
|
||||
}
|
||||
chat, err := m.matchChatEntity(emojiReaction, state.AllChats, state.Timesource)
|
||||
if err != nil {
|
||||
return err // matchChatEntity returns a descriptive error message
|
||||
}
|
||||
|
||||
// TODO: make sure the user can actualy send an emoji for this chat.
|
||||
logger.Info("Handling emoji reaction")
|
||||
// Set local chat id
|
||||
emojiReaction.LocalChatID = chat.ID
|
||||
|
||||
logger.Debug("Handling emoji reaction")
|
||||
|
||||
if chat.LastClockValue < pbEmojiR.Clock {
|
||||
chat.LastClockValue = pbEmojiR.Clock
|
||||
|
|
|
@ -408,6 +408,7 @@ func (db sqlitePersistence) MessagesByIDs(ids []string) ([]*Message, error) {
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []*Message
|
||||
for rows.Next() {
|
||||
var message Message
|
||||
|
@ -496,14 +497,14 @@ func (db sqlitePersistence) EmojiReactionsByChatID(chatID string, currCursor str
|
|||
if currCursor != "" {
|
||||
cursorWhere = "AND substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) || m.id <= ?"
|
||||
}
|
||||
args := []interface{}{chatID}
|
||||
args := []interface{}{chatID, chatID}
|
||||
if currCursor != "" {
|
||||
args = append(args, currCursor)
|
||||
}
|
||||
args = append(args, limit)
|
||||
// Build a new column `cursor` at the query time by having a fixed-sized clock value at the beginning
|
||||
// concatenated with message ID. Results are sorted using this new column.
|
||||
// This new column values can also be returned as a cursor for subsequent requests.
|
||||
// NOTE: We match against local_chat_id for security reasons.
|
||||
// As a user could potentially send an emoji reaction for a one to
|
||||
// one/group chat that has no access to.
|
||||
query := fmt.Sprintf(`
|
||||
SELECT
|
||||
e.clock_value,
|
||||
|
@ -511,11 +512,14 @@ func (db sqlitePersistence) EmojiReactionsByChatID(chatID string, currCursor str
|
|||
e.emoji_id,
|
||||
e.message_id,
|
||||
e.chat_id,
|
||||
e.local_chat_id,
|
||||
e.retracted
|
||||
FROM
|
||||
emoji_reactions e
|
||||
WHERE NOT(e.retracted)
|
||||
AND
|
||||
e.local_chat_id = ?
|
||||
AND
|
||||
e.message_id IN
|
||||
(SELECT id FROM user_messages m WHERE NOT(m.hide) AND m.local_chat_id = ? %s
|
||||
ORDER BY substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) || m.id DESC LIMIT ?)
|
||||
|
@ -539,6 +543,7 @@ func (db sqlitePersistence) EmojiReactionsByChatID(chatID string, currCursor str
|
|||
&emojiReaction.Type,
|
||||
&emojiReaction.MessageId,
|
||||
&emojiReaction.ChatId,
|
||||
&emojiReaction.LocalChatID,
|
||||
&emojiReaction.Retracted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -768,7 +773,7 @@ func (db sqlitePersistence) BlockContact(contact *Contact) ([]*Chat, error) {
|
|||
}
|
||||
|
||||
func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err error) {
|
||||
query := "INSERT INTO emoji_reactions(id,clock_value,source,emoji_id,message_id,chat_id,retracted) VALUES (?,?,?,?,?,?,?)"
|
||||
query := "INSERT INTO emoji_reactions(id,clock_value,source,emoji_id,message_id,chat_id,local_chat_id,retracted) VALUES (?,?,?,?,?,?,?,?)"
|
||||
stmt, err := db.db.Prepare(query)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -781,6 +786,7 @@ func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err
|
|||
emojiReaction.Type,
|
||||
emojiReaction.MessageId,
|
||||
emojiReaction.ChatId,
|
||||
emojiReaction.LocalChatID,
|
||||
emojiReaction.Retracted,
|
||||
)
|
||||
|
||||
|
@ -788,26 +794,14 @@ func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err
|
|||
}
|
||||
|
||||
func (db sqlitePersistence) EmojiReactionByID(id string) (*EmojiReaction, error) {
|
||||
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
err = tx.Commit()
|
||||
return
|
||||
}
|
||||
// don't shadow original error
|
||||
_ = tx.Rollback()
|
||||
}()
|
||||
|
||||
row := tx.QueryRow(
|
||||
row := db.db.QueryRow(
|
||||
`SELECT
|
||||
clock_value,
|
||||
source,
|
||||
emoji_id,
|
||||
message_id,
|
||||
chat_id,
|
||||
local_chat_id,
|
||||
retracted
|
||||
FROM
|
||||
emoji_reactions
|
||||
|
@ -816,71 +810,15 @@ func (db sqlitePersistence) EmojiReactionByID(id string) (*EmojiReaction, error)
|
|||
`, id)
|
||||
|
||||
emojiReaction := new(EmojiReaction)
|
||||
args := []interface{}{
|
||||
&emojiReaction.Clock,
|
||||
err := row.Scan(&emojiReaction.Clock,
|
||||
&emojiReaction.From,
|
||||
&emojiReaction.Type,
|
||||
&emojiReaction.MessageId,
|
||||
&emojiReaction.ChatId,
|
||||
&emojiReaction.LocalChatID,
|
||||
&emojiReaction.Retracted,
|
||||
}
|
||||
err = row.Scan(args...)
|
||||
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
return nil, errRecordNotFound
|
||||
case nil:
|
||||
return emojiReaction, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) EmojiReactionByFromMessageIDAndType(from string, messageID string, emojiType protobuf.EmojiReaction_Type) (*EmojiReaction, error) {
|
||||
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
err = tx.Commit()
|
||||
return
|
||||
}
|
||||
// don't shadow original error
|
||||
_ = tx.Rollback()
|
||||
}()
|
||||
|
||||
row := tx.QueryRow(
|
||||
`SELECT
|
||||
clock_value,
|
||||
source,
|
||||
emoji_id,
|
||||
message_id,
|
||||
chat_id,
|
||||
retracted
|
||||
|
||||
FROM
|
||||
emoji_reactions
|
||||
WHERE
|
||||
emoji_reactions.source = ?
|
||||
AND
|
||||
emoji_reactions.message_id = ?
|
||||
AND
|
||||
emoji_reactions.emoji_id = ?
|
||||
`,
|
||||
from,
|
||||
messageID,
|
||||
emojiType,
|
||||
)
|
||||
|
||||
emojiReaction := new(EmojiReaction)
|
||||
err = row.Scan(&emojiReaction.Clock,
|
||||
&emojiReaction.From,
|
||||
&emojiReaction.Type,
|
||||
&emojiReaction.MessageId,
|
||||
&emojiReaction.ChatId,
|
||||
&emojiReaction.Retracted)
|
||||
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
return nil, errRecordNotFound
|
||||
|
@ -890,8 +828,3 @@ func (db sqlitePersistence) EmojiReactionByFromMessageIDAndType(from string, mes
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) RetractEmojiReaction(id string) error {
|
||||
_, err := db.db.Exec(`UPDATE emoji_reactions SET retracted = 1 WHERE id = ?`, id)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -225,3 +225,27 @@ func ValidateReceivedChatMessage(message *protobuf.ChatMessage, whisperTimestamp
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateReceivedEmojiReaction(emoji *protobuf.EmojiReaction, whisperTimestamp uint64) error {
|
||||
if err := validateClockValue(emoji.Clock, whisperTimestamp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(emoji.MessageId) == 0 {
|
||||
return errors.New("message-id can't be empty")
|
||||
}
|
||||
|
||||
if len(emoji.ChatId) == 0 {
|
||||
return errors.New("chat-id can't be empty")
|
||||
}
|
||||
|
||||
if emoji.Type == protobuf.EmojiReaction_UNKNOWN_EMOJI_REACTION_TYPE {
|
||||
return errors.New("unknown emoji reaction type")
|
||||
}
|
||||
|
||||
if emoji.MessageType == protobuf.MessageType_UNKNOWN_MESSAGE_TYPE {
|
||||
return errors.New("unknown message type")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -477,3 +477,105 @@ func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *MessageValidatorSuite) TestValidateEmojiReaction() {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Valid bool
|
||||
WhisperTimestamp uint64
|
||||
Message protobuf.EmojiReaction
|
||||
}{
|
||||
{
|
||||
Name: "valid emoji reaction",
|
||||
Valid: true,
|
||||
WhisperTimestamp: 30,
|
||||
Message: protobuf.EmojiReaction{
|
||||
Clock: 30,
|
||||
ChatId: "chat-id",
|
||||
MessageId: "message-id",
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
Type: protobuf.EmojiReaction_LOVE,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "valid emoji retraction",
|
||||
Valid: true,
|
||||
WhisperTimestamp: 30,
|
||||
Message: protobuf.EmojiReaction{
|
||||
Clock: 30,
|
||||
ChatId: "0.34",
|
||||
MessageId: "message-id",
|
||||
Type: protobuf.EmojiReaction_LOVE,
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
Retracted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "missing chatID",
|
||||
Valid: false,
|
||||
WhisperTimestamp: 30,
|
||||
Message: protobuf.EmojiReaction{
|
||||
Clock: 30,
|
||||
MessageId: "message-id",
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
Type: protobuf.EmojiReaction_LOVE,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "missing messageID",
|
||||
Valid: false,
|
||||
WhisperTimestamp: 30,
|
||||
Message: protobuf.EmojiReaction{
|
||||
Clock: 30,
|
||||
ChatId: "chat-id",
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
Type: protobuf.EmojiReaction_LOVE,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "missing type",
|
||||
Valid: false,
|
||||
WhisperTimestamp: 30,
|
||||
Message: protobuf.EmojiReaction{
|
||||
Clock: 30,
|
||||
ChatId: "chat-id",
|
||||
MessageId: "message-id",
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "missing message type",
|
||||
Valid: false,
|
||||
WhisperTimestamp: 30,
|
||||
Message: protobuf.EmojiReaction{
|
||||
Clock: 30,
|
||||
ChatId: "chat-id",
|
||||
MessageId: "message-id",
|
||||
Type: protobuf.EmojiReaction_LOVE,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "clock value too high",
|
||||
Valid: false,
|
||||
WhisperTimestamp: 30,
|
||||
Message: protobuf.EmojiReaction{
|
||||
Clock: 900000,
|
||||
ChatId: "chat-id",
|
||||
MessageId: "message-id",
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
Type: protobuf.EmojiReaction_LOVE,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
s.Run(tc.Name, func() {
|
||||
err := ValidateReceivedEmojiReaction(&tc.Message, tc.WhisperTimestamp)
|
||||
if tc.Valid {
|
||||
s.Nil(err)
|
||||
} else {
|
||||
s.NotNil(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3245,7 +3245,8 @@ func (m *Messenger) SendEmojiReaction(ctx context.Context, chatID, messageID str
|
|||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_Type(emojiID),
|
||||
},
|
||||
From: types.EncodeHex(crypto.FromECDSAPub(&m.identity.PublicKey)),
|
||||
LocalChatID: chatID,
|
||||
From: types.EncodeHex(crypto.FromECDSAPub(&m.identity.PublicKey)),
|
||||
}
|
||||
encodedMessage, err := m.encodeChatEntity(chat, emojiR)
|
||||
if err != nil {
|
||||
|
@ -3334,7 +3335,7 @@ func (m *Messenger) SendEmojiReactionRetraction(ctx context.Context, emojiReacti
|
|||
response.Chats = []*Chat{chat}
|
||||
|
||||
// Persist retraction state for emoji reaction
|
||||
err = m.persistence.RetractEmojiReaction(emojiReactionID)
|
||||
err = m.persistence.SaveEmojiReaction(emojiR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
// 1595862781_add_audio_data.down.sql (0)
|
||||
// 1595862781_add_audio_data.up.sql (246B)
|
||||
// 1595865249_create_emoji_reactions_table.down.sql (27B)
|
||||
// 1595865249_create_emoji_reactions_table.up.sql (265B)
|
||||
// 1595865249_create_emoji_reactions_table.up.sql (300B)
|
||||
// doc.go (850B)
|
||||
|
||||
package migrations
|
||||
|
@ -427,7 +427,7 @@ func _1595865249_create_emoji_reactions_tableDownSql() (*asset, error) {
|
|||
return a, nil
|
||||
}
|
||||
|
||||
var __1595865249_create_emoji_reactions_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\xce\xbf\x4e\xc3\x30\x10\xc7\xf1\x3d\x52\xde\xe1\x37\x82\xc4\xc0\xce\x64\xcc\x45\x58\x18\xa7\x72\xaf\xa8\x9d\x22\xcb\x3d\x81\xa1\xc5\x92\xed\xf0\xfc\x88\x64\xe1\x8f\x98\x3f\x77\xdf\x3b\xed\x49\x31\x81\xd5\xad\x25\x98\x01\x6e\x64\xd0\xde\x6c\x79\x0b\x39\xe7\xd7\x34\x15\x09\xb1\xa5\xfc\x5e\x71\xd1\x77\x40\x3a\xe2\x49\x79\x7d\xaf\x3c\x36\xde\x3c\x2a\x7f\xc0\x03\x1d\x30\x3a\xe8\xd1\x0d\xd6\x68\x86\xa7\x8d\x55\x9a\xae\xbe\xc6\xe3\x29\xc7\xb7\xe9\x23\x9c\x66\x81\x71\xbc\xe4\xdd\xce\xda\x05\x6b\x9e\x4b\x14\x30\xed\x7f\xc1\x7a\x39\x1d\xff\xae\x9c\xa5\xd6\xf0\x2c\xd3\xb7\x37\x7e\x78\x7c\x09\xed\x5f\x2c\xd2\x4a\x88\x4d\xd6\xee\x1d\x0d\x6a\x67\x19\xd7\x7d\x77\x79\xd3\x77\x9f\x01\x00\x00\xff\xff\xf2\xdf\x03\x4e\x09\x01\x00\x00")
|
||||
var __1595865249_create_emoji_reactions_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\xce\xbd\x4e\x03\x31\x10\x04\xe0\xfe\xa4\x7b\x87\x29\x41\xa2\xa0\xa7\x32\x66\x4f\x58\x18\x5f\xe4\x6c\x50\x52\x9d\x2c\x67\x05\x07\x0e\x96\x6c\x87\xe7\x47\xe4\x1a\x7e\x44\xea\x6f\x76\x67\xb4\x27\xc5\x04\x56\xb7\x96\x60\x06\xb8\x91\x41\x5b\xb3\xe6\x35\xe4\x90\x5f\xe7\xa9\x48\x88\x6d\xce\xef\x15\x17\x7d\x07\xcc\x7b\x3c\x29\xaf\xef\x95\xc7\xca\x9b\x47\xe5\x77\x78\xa0\x1d\x46\x07\x3d\xba\xc1\x1a\xcd\xf0\xb4\xb2\x4a\xd3\xd5\x57\x3c\xa6\x1c\xdf\xa6\x8f\x90\x8e\x02\xe3\xf8\xf4\xde\x6d\xac\x3d\x61\xcd\xc7\x12\x05\x4c\xdb\x5f\xb0\x34\xcf\xfb\xbf\x27\x07\xa9\x35\x3c\xcb\xf4\x6d\xc6\x0f\x8f\x2f\xa1\xfd\x8b\x29\xc7\x90\xa6\xb3\x91\x22\xad\x84\xd8\x64\xa9\xbe\xa3\x41\x6d\x2c\xe3\xba\xef\x2e\x6f\xfa\xee\x33\x00\x00\xff\xff\xe4\x28\x05\xe0\x2c\x01\x00\x00")
|
||||
|
||||
func _1595865249_create_emoji_reactions_tableUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
|
@ -442,8 +442,8 @@ func _1595865249_create_emoji_reactions_tableUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1595865239, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x13, 0x28, 0xa4, 0x70, 0xf0, 0xfe, 0xd, 0xc2, 0x16, 0xc3, 0x1d, 0xbb, 0x3c, 0x1, 0xf6, 0x58, 0x69, 0x2a, 0x27, 0x21, 0xbc, 0x8b, 0xc8, 0x1a, 0xd, 0x36, 0x2d, 0x29, 0x0, 0xc3, 0xfa, 0xad}}
|
||||
info := bindataFileInfo{name: "1595865249_create_emoji_reactions_table.up.sql", size: 300, mode: os.FileMode(0644), modTime: time.Unix(1595921491, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xc5, 0x43, 0x5c, 0x3d, 0x53, 0x43, 0x2c, 0x1a, 0xa5, 0xb6, 0xbf, 0x7, 0x4, 0x5a, 0x3e, 0x40, 0x8b, 0xa4, 0x57, 0x12, 0x58, 0xbc, 0x42, 0xe2, 0xc3, 0xde, 0x76, 0x98, 0x80, 0xe2, 0xbe}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -5,5 +5,6 @@ CREATE TABLE IF NOT EXISTS emoji_reactions (
|
|||
emoji_id INT NOT NULL,
|
||||
message_id VARCHAR NOT NULL,
|
||||
chat_id VARCHAR NOT NULL,
|
||||
local_chat_id VARCHAR NOT NULL,
|
||||
retracted INT DEFAULT 0
|
||||
);
|
||||
|
|
|
@ -407,7 +407,8 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_SAD,
|
||||
},
|
||||
From: from1,
|
||||
LocalChatID: chatID,
|
||||
From: from1,
|
||||
}))
|
||||
|
||||
// Insert retracted emoji reaction
|
||||
|
@ -419,7 +420,8 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||
Type: protobuf.EmojiReaction_SAD,
|
||||
Retracted: true,
|
||||
},
|
||||
From: from2,
|
||||
LocalChatID: chatID,
|
||||
From: from2,
|
||||
}))
|
||||
|
||||
// Insert retracted emoji reaction out of pagination
|
||||
|
@ -430,7 +432,8 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_SAD,
|
||||
},
|
||||
From: from2,
|
||||
LocalChatID: chatID,
|
||||
From: from2,
|
||||
}))
|
||||
|
||||
// Insert retracted emoji reaction out of pagination
|
||||
|
@ -441,7 +444,20 @@ func TestPersistenceEmojiReactions(t *testing.T) {
|
|||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_SAD,
|
||||
},
|
||||
From: from3,
|
||||
LocalChatID: chatID,
|
||||
From: from3,
|
||||
}))
|
||||
|
||||
// Wrong local chat id
|
||||
require.NoError(t, p.SaveEmojiReaction(&EmojiReaction{
|
||||
EmojiReaction: protobuf.EmojiReaction{
|
||||
Clock: 1,
|
||||
MessageId: id1,
|
||||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_LOVE,
|
||||
},
|
||||
LocalChatID: "wrong-chat-id",
|
||||
From: from3,
|
||||
}))
|
||||
|
||||
reactions, err := p.EmojiReactionsByChatID(chatID, "", 1)
|
||||
|
|
|
@ -54,7 +54,8 @@ func TestSignMembershipUpdate(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// Encode message
|
||||
encodedMessage := testMembershipUpdateMessageStruct.ToProtobuf()
|
||||
encodedMessage, err := testMembershipUpdateMessageStruct.ToProtobuf()
|
||||
require.NoError(t, err)
|
||||
// Verify it
|
||||
verifiedMessage, err := MembershipUpdateMessageFromProtobuf(encodedMessage)
|
||||
require.NoError(t, err)
|
||||
|
|
Loading…
Reference in New Issue