forward chat msg fix

This commit is contained in:
Krispire Admin
2026-09-02 23:00:55 +05:30
parent 0fee56d272
commit 6633d0cca3
3 changed files with 134 additions and 0 deletions
+7
View File
@@ -1090,6 +1090,13 @@ func (s *ChatService) ForwardMessage(ctx context.Context, userID, messageID, toC
return nil, err
}
if created {
// Carry the attachments across. Without this a quote, sticker, photo
// or shared post forwards as an empty bubble: its content lives in an
// attachment row, not in the body.
if err := s.chat.CopyAttachments(ctx, messageID, msg.ID, toConversationID); err != nil {
s.logger.Warn("chat: forwarding attachments failed",
zap.String("message_id", messageID), zap.Error(err))
}
msg = s.hydrateSent(ctx, userID, toConversationID, msg)
s.publish(ctx, toConversationID, userID, msg)
}
+93
View File
@@ -2609,3 +2609,96 @@ func TestStickers_SaveFromChat(t *testing.T) {
}
}
}
// A quote, sticker, photo or shared post lives in an attachment row, not in
// the body — so forwarding one has to carry the attachments across or the
// recipient gets an empty bubble.
func TestForward_CarriesAttachments(t *testing.T) {
svc, _, pg := testChatService(t)
ctx := context.Background()
a, b, c := chatUser(t, pg, "A"), chatUser(t, pg, "B"), chatUser(t, pg, "C")
source, err := svc.OpenDM(ctx, a, b)
if err != nil {
t.Fatal(err)
}
cleanupConv(t, pg, source.ID)
target, err := svc.OpenDM(ctx, a, c)
if err != nil {
t.Fatal(err)
}
cleanupConv(t, pg, target.ID)
// A quote with no body at all — the case that forwarded blank.
sent, err := svc.Send(ctx, a, source.ID, SendRequest{
Quote: &QuoteAttachment{
Path: "/books/bg/2/13?hl=abc",
Title: "Bhagavad-gītā 2.13",
Text: "As the embodied soul continually passes…",
},
})
if err != nil {
t.Fatal(err)
}
if sent.Body != "" {
t.Fatalf("setup: expected a body-less quote, got %q", sent.Body)
}
fwd, err := svc.ForwardMessage(ctx, a, sent.ID, target.ID)
if err != nil {
t.Fatal(err)
}
msgs, err := svc.Messages(ctx, c, target.ID, 0, 10)
if err != nil {
t.Fatal(err)
}
var quote *model.Attachment
for i := range msgs {
if msgs[i].ID != fwd.ID {
continue
}
for j := range msgs[i].Attachments {
if msgs[i].Attachments[j].Kind == model.AttachmentQuote {
quote = &msgs[i].Attachments[j]
}
}
}
if quote == nil {
t.Fatal("the forwarded message has no quote — it would render empty")
}
if quote.Description == nil || *quote.Description == "" {
t.Error("the forwarded quote lost its passage")
}
if quote.URL == nil || *quote.URL != "/books/bg/2/13?hl=abc" {
t.Errorf("the forwarded quote lost its deep link: %v", quote.URL)
}
// The copy belongs to the DESTINATION thread: reads authorize against the
// attachment's own conversation, so a copy still scoped to the source
// would be unreadable to the recipient.
var convID string
if err := pg.Pool.QueryRow(ctx,
`SELECT conversation_id FROM message_attachments WHERE message_id = $1`,
fwd.ID).Scan(&convID); err != nil {
t.Fatal(err)
}
if convID != target.ID {
t.Errorf("copied attachment is scoped to %s, want the destination %s", convID, target.ID)
}
// The original is untouched.
back, err := svc.Messages(ctx, b, source.ID, 0, 10)
if err != nil {
t.Fatal(err)
}
found := false
for i := range back {
if back[i].ID == sent.ID && len(back[i].Attachments) == 1 {
found = true
}
}
if !found {
t.Error("forwarding disturbed the original message's attachment")
}
}