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,140 @@
package postgres
import (
"context"
"reflect"
"testing"
"telesrv/internal/domain"
)
// TestChannelPollFanoutViewsPostgres 验证 Phase 4 poll 模板化的 postgres 路径:新批量 SQL
// (batchPollViewerOptions / batchChannelMemberAvailableMinID + pollViewerAggregates(viewer=0))
// 正确运行,且 ChannelPollFanoutViews 对每个 viewer 与逐 viewer GetChannelMessages(旧 fan-out 路径)
// 的 enrich poll 字节等价、可见性一致。门控于 TELESRV_TEST_POSTGRES_DSN。
func TestChannelPollFanoutViewsPostgres(t *testing.T) {
pool := testPool(t)
ctx := context.Background()
suffix := randomSuffix(t)
users := NewUserStore(pool)
owner, err := users.Create(ctx, domain.User{AccessHash: 71, Phone: "+1893" + suffix + "01", FirstName: "PollOwner"})
if err != nil {
t.Fatalf("create owner: %v", err)
}
voted, err := users.Create(ctx, domain.User{AccessHash: 72, Phone: "+1893" + suffix + "02", FirstName: "PollVoted"})
if err != nil {
t.Fatalf("create voted: %v", err)
}
unvoted, err := users.Create(ctx, domain.User{AccessHash: 73, Phone: "+1893" + suffix + "03", FirstName: "PollUnvoted"})
if err != nil {
t.Fatalf("create unvoted: %v", err)
}
stranger, err := users.Create(ctx, domain.User{AccessHash: 74, Phone: "+1893" + suffix + "04", FirstName: "PollStranger"})
if err != nil {
t.Fatalf("create stranger: %v", err)
}
channels := NewChannelStore(pool)
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 = ANY($1::bigint[])", []int64{owner.ID, voted.ID, unvoted.ID, stranger.ID})
})
created, err := channels.CreateChannel(ctx, domain.CreateChannelRequest{
CreatorUserID: owner.ID,
Title: "Poll Fanout " + suffix,
Megagroup: true,
MemberUserIDs: []int64{voted.ID, unvoted.ID},
Date: 1700002000,
})
if err != nil {
t.Fatalf("create channel: %v", err)
}
channelID = created.Channel.ID
pollID := int64(9300000000) + (channelID % 1000)
opt1, opt2 := []byte{1}, []byte{2}
polls := NewPollStore(pool)
if err := polls.CreatePoll(ctx, domain.PollDefinition{
ID: pollID,
CreatorUserID: owner.ID,
Options: [][]byte{opt1, opt2},
PublicVoters: true,
}); err != nil {
t.Fatalf("create poll: %v", err)
}
sent, err := channels.SendChannelMessage(ctx, domain.SendChannelMessageRequest{
UserID: owner.ID,
ChannelID: channelID,
RandomID: 93_001,
Date: 1700002001,
Media: &domain.MessageMedia{
Kind: domain.MessageMediaKindPoll,
Poll: &domain.MessagePoll{
ID: pollID,
Question: "Q?",
Answers: []domain.MessagePollAnswer{{Text: "A", Option: opt1}, {Text: "B", Option: opt2}},
PublicVoters: true,
},
},
})
if err != nil {
t.Fatalf("send poll message: %v", err)
}
msgID := sent.Message.ID
if _, err := channels.VoteChannelMessagePoll(ctx, domain.VoteChannelMessagePollRequest{
UserID: voted.ID, ChannelID: channelID, MessageID: msgID, Options: [][]byte{opt1}, Date: 1700002002,
}); err != nil {
t.Fatalf("vote: %v", err)
}
viewers := []int64{owner.ID, voted.ID, unvoted.ID, stranger.ID}
views, err := channels.ChannelPollFanoutViews(ctx, channelID, msgID, viewers, 1700002100)
if err != nil {
t.Fatalf("ChannelPollFanoutViews: %v", err)
}
if !views.Found {
t.Fatal("Found=false, want true")
}
for _, viewer := range viewers {
got, evaluated := views.Polls[viewer]
if !evaluated {
t.Fatalf("viewer %d not evaluated", viewer)
}
ref, err := channels.GetChannelMessages(ctx, viewer, channelID, []int{msgID})
var refPoll *domain.MessagePoll
if err == nil {
for _, m := range ref.Messages {
if m.ID == msgID && m.Media != nil {
refPoll = m.Media.Poll
}
}
}
if (got != nil) != (refPoll != nil) {
t.Fatalf("viewer %d visibility mismatch: batch nil=%v old nil=%v (err=%v)", viewer, got == nil, refPoll == nil, err)
}
if got != nil && !reflect.DeepEqual(got.Results, refPoll.Results) {
t.Fatalf("viewer %d Results mismatch:\n batch=%+v\n old=%+v", viewer, got.Results, refPoll.Results)
}
}
// members 可见、stranger(非成员)不可见。
if views.Polls[owner.ID] == nil || views.Polls[voted.ID] == nil || views.Polls[unvoted.ID] == nil {
t.Fatal("members should be visible")
}
if views.Polls[stranger.ID] != nil {
t.Fatal("non-member stranger must be invisible (nil)")
}
// voted 视角应见自己 chosen。
sawChosen := false
for _, v := range views.Polls[voted.ID].Results.Voters {
if v.Chosen {
sawChosen = true
}
}
if !sawChosen {
t.Fatal("voted viewer should see own chosen option")
}
}