chore: refresh gramsrv public release

This commit is contained in:
A 2026-06-30 14:37:43 +08:00
parent 75cebe8dbf
commit 70b6820474
1274 changed files with 378751 additions and 59919 deletions

View file

@ -0,0 +1,100 @@
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)
}
}
}