chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
188
internal/store/postgres/message_grouped_integration_test.go
Normal file
188
internal/store/postgres/message_grouped_integration_test.go
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
// TestSendPrivateGroupedIDSurvivesReadPaths 回归迁移 0008:相册 grouped_id 经私聊
|
||||
// 全部读路径保真——发送结果双盒、history、GetByIDs、以及更新事件重建路径(离线
|
||||
// difference / 在线推送共用)。这是「漏一处读站点=分组静默丢失」最易踩的地方。
|
||||
func TestSendPrivateGroupedIDSurvivesReadPaths(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
suffix := randomSuffix(t)
|
||||
|
||||
users := NewUserStore(pool)
|
||||
sender, err := users.Create(ctx, domain.User{AccessHash: 81, Phone: "+1995" + suffix + "01", FirstName: "AlbumSender"})
|
||||
if err != nil {
|
||||
t.Fatalf("create sender: %v", err)
|
||||
}
|
||||
recipient, err := users.Create(ctx, domain.User{AccessHash: 82, Phone: "+1995" + suffix + "02", FirstName: "AlbumRecipient"})
|
||||
if err != nil {
|
||||
t.Fatalf("create recipient: %v", err)
|
||||
}
|
||||
ids := []int64{sender.ID, recipient.ID}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM dispatch_outbox WHERE target_user_id = ANY($1::bigint[])", ids)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM user_update_events WHERE user_id = ANY($1::bigint[])", ids)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM message_boxes WHERE owner_user_id = ANY($1::bigint[])", ids)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM private_messages WHERE sender_user_id = ANY($1::bigint[])", ids)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM dialogs WHERE user_id = ANY($1::bigint[])", ids)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = ANY($1::bigint[])", ids)
|
||||
})
|
||||
|
||||
messages := NewMessageStore(pool, WithMessageAllocators(&perUserCounterAllocator{}))
|
||||
const groupedID = int64(880000000123)
|
||||
|
||||
// 同一 album 的两条消息共享 grouped_id。
|
||||
var senderMsgIDs []int
|
||||
for i := 0; i < 2; i++ {
|
||||
res, err := messages.SendPrivateText(ctx, domain.SendPrivateTextRequest{
|
||||
SenderUserID: sender.ID,
|
||||
RecipientUserID: recipient.ID,
|
||||
RandomID: time.Now().UnixNano() + int64(i),
|
||||
Message: "album item",
|
||||
GroupedID: groupedID,
|
||||
Date: int(time.Now().Unix()),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("send album item %d: %v", i, err)
|
||||
}
|
||||
if res.SenderMessage.GroupedID != groupedID || res.RecipientMessage.GroupedID != groupedID {
|
||||
t.Fatalf("send result grouped = sender %d recipient %d, want %d", res.SenderMessage.GroupedID, res.RecipientMessage.GroupedID, groupedID)
|
||||
}
|
||||
senderMsgIDs = append(senderMsgIDs, res.SenderMessage.ID)
|
||||
}
|
||||
|
||||
// history:两条都带同一 grouped_id(客户端据此分组)。
|
||||
hist, err := messages.ListByUser(ctx, recipient.ID, domain.MessageFilter{Limit: 10})
|
||||
if err != nil {
|
||||
t.Fatalf("recipient history: %v", err)
|
||||
}
|
||||
album := 0
|
||||
for _, m := range hist.Messages {
|
||||
if m.GroupedID == groupedID {
|
||||
album++
|
||||
}
|
||||
}
|
||||
if album != 2 {
|
||||
t.Fatalf("recipient history grouped count = %d, want 2", album)
|
||||
}
|
||||
|
||||
// GetByIDs 带 grouped_id。
|
||||
byID, err := messages.GetByIDs(ctx, sender.ID, senderMsgIDs)
|
||||
if err != nil {
|
||||
t.Fatalf("sender get by ids: %v", err)
|
||||
}
|
||||
if len(byID.Messages) != 2 {
|
||||
t.Fatalf("get by ids = %d, want 2", len(byID.Messages))
|
||||
}
|
||||
for _, m := range byID.Messages {
|
||||
if m.GroupedID != groupedID {
|
||||
t.Fatalf("get-by-id grouped = %d, want %d", m.GroupedID, groupedID)
|
||||
}
|
||||
}
|
||||
|
||||
// 更新事件重建路径(关键:getDifference/推送共用)带 grouped_id。
|
||||
events := NewUpdateEventStore(pool)
|
||||
got, err := events.ListAfter(ctx, recipient.ID, 0, 20)
|
||||
if err != nil {
|
||||
t.Fatalf("list recipient events: %v", err)
|
||||
}
|
||||
rebuilt := 0
|
||||
for _, ev := range got {
|
||||
if ev.Type == domain.UpdateEventNewMessage && ev.Message.ID != 0 {
|
||||
if ev.Message.GroupedID != groupedID {
|
||||
t.Fatalf("update-event grouped = %d, want %d(重建路径丢失分组)", ev.Message.GroupedID, groupedID)
|
||||
}
|
||||
rebuilt++
|
||||
}
|
||||
}
|
||||
if rebuilt != 2 {
|
||||
t.Fatalf("rebuilt new_message events with grouped = %d, want 2", rebuilt)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSendChannelGroupedIDSurvivesReadPaths 回归迁移 0008:频道侧(手写 SQL)相册
|
||||
// grouped_id 经发送结果/事件/history/GetChannelMessages 保真。
|
||||
func TestSendChannelGroupedIDSurvivesReadPaths(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
suffix := randomSuffix(t)
|
||||
|
||||
users := NewUserStore(pool)
|
||||
owner, err := users.Create(ctx, domain.User{AccessHash: 3201, Phone: "+1887" + suffix + "01", FirstName: "AlbumChannelOwner"})
|
||||
if err != nil {
|
||||
t.Fatalf("create owner: %v", err)
|
||||
}
|
||||
var channelID int64
|
||||
t.Cleanup(func() {
|
||||
if channelID != 0 {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM channels WHERE id = $1", channelID)
|
||||
}
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = $1", owner.ID)
|
||||
})
|
||||
|
||||
channels := NewChannelStore(pool)
|
||||
created, err := channels.CreateChannel(ctx, domain.CreateChannelRequest{
|
||||
CreatorUserID: owner.ID,
|
||||
Title: "Album Channel " + suffix,
|
||||
Megagroup: true,
|
||||
Date: 1700002100,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create channel: %v", err)
|
||||
}
|
||||
channelID = created.Channel.ID
|
||||
const groupedID = int64(990000000456)
|
||||
|
||||
var msgIDs []int
|
||||
for i := 0; i < 2; i++ {
|
||||
sent, err := channels.SendChannelMessage(ctx, domain.SendChannelMessageRequest{
|
||||
UserID: owner.ID,
|
||||
ChannelID: channelID,
|
||||
RandomID: int64(990401 + i),
|
||||
Message: "channel album item",
|
||||
GroupedID: groupedID,
|
||||
Date: 1700002101 + i,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("send channel album item %d: %v", i, err)
|
||||
}
|
||||
if sent.Message.GroupedID != groupedID || sent.Event.Message.GroupedID != groupedID {
|
||||
t.Fatalf("sent grouped = msg %d event %d, want %d", sent.Message.GroupedID, sent.Event.Message.GroupedID, groupedID)
|
||||
}
|
||||
msgIDs = append(msgIDs, sent.Message.ID)
|
||||
}
|
||||
|
||||
hist, err := channels.ListChannelHistory(ctx, owner.ID, domain.ChannelHistoryFilter{ChannelID: channelID, Limit: 10})
|
||||
if err != nil {
|
||||
t.Fatalf("channel history: %v", err)
|
||||
}
|
||||
album := 0
|
||||
for _, m := range hist.Messages {
|
||||
if m.GroupedID == groupedID {
|
||||
album++
|
||||
}
|
||||
}
|
||||
if album != 2 {
|
||||
t.Fatalf("channel history grouped count = %d, want 2", album)
|
||||
}
|
||||
|
||||
byID, err := channels.GetChannelMessages(ctx, owner.ID, channelID, msgIDs)
|
||||
if err != nil {
|
||||
t.Fatalf("get channel messages: %v", err)
|
||||
}
|
||||
if len(byID.Messages) != 2 {
|
||||
t.Fatalf("get channel messages = %d, want 2", len(byID.Messages))
|
||||
}
|
||||
for _, m := range byID.Messages {
|
||||
if m.GroupedID != groupedID {
|
||||
t.Fatalf("channel get-by-id grouped = %d, want %d", m.GroupedID, groupedID)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue