owpengram-server/internal/store/postgres/message_reactions_viewpoint_integration_test.go

94 lines
3.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package postgres
import (
"context"
"testing"
"time"
"telesrv/internal/domain"
)
// TestSetMessageReactionsPeerViewpoint 回归chosen/My 是 per-viewer 字段,
// SetMessageReactions 返回的双方 owner 副本必须各按自己的视角解析——
// 修复前统一用发起者视角,对端推送会把发起者的 reaction 标成"对端自己选的"
// TDesktop 非 min 更新用 chosen_order 直接覆盖本地 my 状态)。
func TestSetMessageReactionsPeerViewpoint(t *testing.T) {
pool := testPool(t)
ctx := context.Background()
suffix := randomSuffix(t)
users := NewUserStore(pool)
owner, err := users.Create(ctx, domain.User{AccessHash: 1, Phone: "+1666" + suffix + "01", FirstName: "Owner"})
if err != nil {
t.Fatalf("create owner: %v", err)
}
friend, err := users.Create(ctx, domain.User{AccessHash: 2, Phone: "+1666" + suffix + "02", FirstName: "Friend"})
if err != nil {
t.Fatalf("create friend: %v", err)
}
t.Cleanup(func() {
for _, id := range []int64{owner.ID, friend.ID} {
_, _ = pool.Exec(ctx, "DELETE FROM private_message_reactions WHERE user_id = $1 OR message_sender_id = $1", id)
_, _ = pool.Exec(ctx, "DELETE FROM message_boxes WHERE owner_user_id = $1", id)
_, _ = pool.Exec(ctx, "DELETE FROM private_messages WHERE sender_user_id = $1", id)
_, _ = pool.Exec(ctx, "DELETE FROM user_update_events WHERE user_id = $1", id)
_, _ = pool.Exec(ctx, "DELETE FROM dialogs WHERE user_id = $1", id)
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = $1", id)
}
})
messages := NewMessageStore(pool)
now := int(time.Now().Unix())
sent, err := messages.SendPrivateText(ctx, domain.SendPrivateTextRequest{
SenderUserID: owner.ID,
RecipientUserID: friend.ID,
RandomID: time.Now().UnixNano(),
Message: "react to me",
Date: now,
})
if err != nil {
t.Fatalf("send private text: %v", err)
}
if sent.RecipientMessage.ID == 0 {
t.Fatal("recipient box id missing")
}
// friend 给 owner 的消息点 👍(用 friend 自己视角的 box id 与 peer
res, err := messages.SetMessageReactions(ctx, domain.SetPrivateMessageReactionsRequest{
UserID: friend.ID,
Peer: domain.Peer{Type: domain.PeerTypeUser, ID: owner.ID},
MessageID: sent.RecipientMessage.ID,
Reactions: []domain.MessageReaction{{Type: domain.MessageReactionEmoji, Emoticon: "\U0001F44D"}},
Date: now + 1,
})
if err != nil {
t.Fatalf("set message reactions: %v", err)
}
if len(res.Messages) != 2 {
t.Fatalf("reaction result messages = %d, want both owners' copies", len(res.Messages))
}
for _, msg := range res.Messages {
if msg.Reactions == nil || len(msg.Reactions.Results) != 1 {
t.Fatalf("owner %d reactions = %+v, want one aggregate", msg.OwnerUserID, msg.Reactions)
}
result := msg.Reactions.Results[0]
switch msg.OwnerUserID {
case friend.ID:
if result.ChosenOrder == 0 {
t.Errorf("reactor's own copy should carry chosen_order, got %+v", result)
}
if len(msg.Reactions.Recent) != 1 || !msg.Reactions.Recent[0].My {
t.Errorf("reactor's recent entry should be My, got %+v", msg.Reactions.Recent)
}
case owner.ID:
if result.ChosenOrder != 0 {
t.Errorf("peer copy must NOT carry reactor's chosen_order (viewpoint bleed), got %+v", result)
}
if len(msg.Reactions.Recent) != 1 || msg.Reactions.Recent[0].My {
t.Errorf("peer copy recent entry must NOT be My, got %+v", msg.Reactions.Recent)
}
default:
t.Errorf("unexpected owner %d in reaction result", msg.OwnerUserID)
}
}
}