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

100 lines
3.3 KiB
Go
Raw 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"
"telesrv/internal/domain"
)
// TestChannelDialogTopMessageCarriesMentionFlags 复现 @ 角标重启回潮:
// getDialogs 的 channel top message 必须按 viewer 携带 mentioned/media_unread,
// 否则 TDesktop 先入缓存的残缺版永不触发 contents-read,服务端 unread
// 提及挂死、每次冷启动 unread_mentions_count 把 @ 角标带回来。
func TestChannelDialogTopMessageCarriesMentionFlags(t *testing.T) {
pool := testPool(t)
ctx := context.Background()
suffix := randomSuffix(t)
users := NewUserStore(pool)
owner, err := users.Create(ctx, domain.User{AccessHash: 97, Phone: "+1675" + suffix + "01", FirstName: "MentionOwner"})
if err != nil {
t.Fatalf("create owner: %v", err)
}
member, err := users.Create(ctx, domain.User{AccessHash: 98, Phone: "+1675" + suffix + "02", FirstName: "MentionMember"})
if err != nil {
t.Fatalf("create member: %v", err)
}
t.Cleanup(func() {
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = ANY($1::bigint[])", []int64{owner.ID, member.ID})
})
channels := NewChannelStore(pool)
created, err := channels.CreateChannel(ctx, domain.CreateChannelRequest{
CreatorUserID: owner.ID,
Title: "MentionDialog " + suffix,
Megagroup: true,
MemberUserIDs: []int64{member.ID},
Date: 1700000910,
})
if err != nil {
t.Fatalf("create channel: %v", err)
}
sent, err := channels.SendChannelMessage(ctx, domain.SendChannelMessageRequest{
UserID: owner.ID,
ChannelID: created.Channel.ID,
RandomID: 851001,
Message: "ping member",
MentionUserIDs: []int64{member.ID},
Date: 1700000911,
})
if err != nil {
t.Fatalf("send mention: %v", err)
}
assertFlags := func(name string, list domain.ChannelDialogList) {
t.Helper()
found := false
for _, msg := range list.Messages {
if msg.ChannelID != created.Channel.ID || msg.ID != sent.Message.ID {
continue
}
found = true
if !msg.Mentioned || !msg.MediaUnread {
t.Fatalf("%s top message flags = mentioned %v media_unread %v, want both true(缺失会让 @ 角标重启回潮)", name, msg.Mentioned, msg.MediaUnread)
}
}
if !found {
t.Fatalf("%s lacks top message %d: %+v", name, sent.Message.ID, list.Messages)
}
}
list, err := channels.ListChannelDialogs(ctx, member.ID, domain.DialogFilter{Limit: 50})
if err != nil {
t.Fatalf("list channel dialogs: %v", err)
}
assertFlags("ListChannelDialogs", list)
got, err := channels.GetChannelDialogs(ctx, member.ID, []int64{created.Channel.ID})
if err != nil {
t.Fatalf("get channel dialogs: %v", err)
}
assertFlags("GetChannelDialogs", got)
// 提及读掉后:mentioned 永久保留、media_unread 翻为 false。
if _, err := channels.ReadChannelMentions(ctx, domain.ReadChannelMentionsRequest{
UserID: member.ID,
ChannelID: created.Channel.ID,
}); err != nil {
t.Fatalf("read mentions: %v", err)
}
after, err := channels.GetChannelDialogs(ctx, member.ID, []int64{created.Channel.ID})
if err != nil {
t.Fatalf("get channel dialogs after read: %v", err)
}
for _, msg := range after.Messages {
if msg.ID == sent.Message.ID && (!msg.Mentioned || msg.MediaUnread) {
t.Fatalf("after read flags = mentioned %v media_unread %v, want mentioned kept with media_unread cleared", msg.Mentioned, msg.MediaUnread)
}
}
}