chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
184
internal/rpc/messages_rich_message_rpc_test.go
Normal file
184
internal/rpc/messages_rich_message_rpc_test.go
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gotd/td/tg"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
// richTextBlocks 构造一组纯文本 IV 页面块,用于富文本往返断言。
|
||||
func richTextBlocks() []tg.PageBlockClass {
|
||||
return []tg.PageBlockClass{
|
||||
&tg.PageBlockTitle{Text: &tg.TextPlain{Text: "Rich Title"}},
|
||||
&tg.PageBlockParagraph{Text: &tg.TextPlain{Text: "First paragraph."}},
|
||||
}
|
||||
}
|
||||
|
||||
// assertRichTextBlocks 校验投影出的 RichMessage 携带 richTextBlocks 的两个块(标题+段落)。
|
||||
func assertRichTextBlocks(t *testing.T, label string, rich tg.RichMessage) {
|
||||
t.Helper()
|
||||
if !rich.Rtl {
|
||||
t.Errorf("%s: rtl = false, want true", label)
|
||||
}
|
||||
if len(rich.Blocks) != 2 {
|
||||
t.Fatalf("%s: blocks = %d, want 2", label, len(rich.Blocks))
|
||||
}
|
||||
title, ok := rich.Blocks[0].(*tg.PageBlockTitle)
|
||||
if !ok {
|
||||
t.Fatalf("%s: block[0] = %T, want *tg.PageBlockTitle", label, rich.Blocks[0])
|
||||
}
|
||||
if tp, ok := title.Text.(*tg.TextPlain); !ok || tp.Text != "Rich Title" {
|
||||
t.Errorf("%s: title text = %+v, want plain %q", label, title.Text, "Rich Title")
|
||||
}
|
||||
para, ok := rich.Blocks[1].(*tg.PageBlockParagraph)
|
||||
if !ok {
|
||||
t.Fatalf("%s: block[1] = %T, want *tg.PageBlockParagraph", label, rich.Blocks[1])
|
||||
}
|
||||
if tp, ok := para.Text.(*tg.TextPlain); !ok || tp.Text != "First paragraph." {
|
||||
t.Errorf("%s: paragraph text = %+v, want plain %q", label, para.Text, "First paragraph.")
|
||||
}
|
||||
}
|
||||
|
||||
// TestSendMessageRichMessageTextBlocksRoundTrip 验证 Layer 227 富文本(inputRichMessage 的
|
||||
// blocks 形态)经 send → 发送方 echo / getMessages / getRichMessage 全链路原样往返。
|
||||
func TestSendMessageRichMessageTextBlocksRoundTrip(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Message: "rich",
|
||||
RandomID: 7001,
|
||||
RichMessage: &tg.InputRichMessage{
|
||||
Rtl: true,
|
||||
Blocks: richTextBlocks(),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("send rich message: %v", err)
|
||||
}
|
||||
echo := newMessageFromUpdates(t, updates)
|
||||
rich, ok := echo.GetRichMessage()
|
||||
if !ok {
|
||||
t.Fatalf("send echo missing rich message")
|
||||
}
|
||||
assertRichTextBlocks(t, "send echo", rich)
|
||||
|
||||
// getMessages(发送方按 box id 拉取)也应带富文本。
|
||||
got, err := r.onMessagesGetMessages(WithUserID(ctx, owner.ID), []tg.InputMessageClass{&tg.InputMessageID{ID: echo.ID}})
|
||||
if err != nil {
|
||||
t.Fatalf("get messages: %v", err)
|
||||
}
|
||||
stored := singleStoredMessage(t, got)
|
||||
rich, ok = stored.GetRichMessage()
|
||||
if !ok {
|
||||
t.Fatalf("getMessages missing rich message")
|
||||
}
|
||||
assertRichTextBlocks(t, "getMessages", rich)
|
||||
|
||||
// getRichMessage(按 peer+id 拉取完整富文本)应带富文本。
|
||||
gotRich, err := r.onMessagesGetRichMessage(WithUserID(ctx, owner.ID), &tg.MessagesGetRichMessageRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
ID: echo.ID,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("get rich message: %v", err)
|
||||
}
|
||||
stored = singleStoredMessage(t, gotRich)
|
||||
rich, ok = stored.GetRichMessage()
|
||||
if !ok {
|
||||
t.Fatalf("getRichMessage missing rich message")
|
||||
}
|
||||
assertRichTextBlocks(t, "getRichMessage", rich)
|
||||
}
|
||||
|
||||
// TestGetRichMessageWrongPeerReturnsEmpty 验证 getRichMessage 的 peer 校验:用不匹配的 peer
|
||||
// 拉取应返回 messageEmpty(不跨会话泄漏)。
|
||||
func TestGetRichMessageWrongPeerReturnsEmpty(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Message: "rich",
|
||||
RandomID: 7002,
|
||||
RichMessage: &tg.InputRichMessage{Rtl: true, Blocks: richTextBlocks()},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("send rich message: %v", err)
|
||||
}
|
||||
echo := newMessageFromUpdates(t, updates)
|
||||
|
||||
// 用 self peer(≠ 该消息盒的 peer=friend)拉取 → messageEmpty。
|
||||
gotRich, err := r.onMessagesGetRichMessage(WithUserID(ctx, owner.ID), &tg.MessagesGetRichMessageRequest{
|
||||
Peer: &tg.InputPeerSelf{},
|
||||
ID: echo.ID,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("get rich message wrong peer: %v", err)
|
||||
}
|
||||
box, ok := gotRich.(*tg.MessagesMessages)
|
||||
if !ok || len(box.Messages) != 1 {
|
||||
t.Fatalf("getRichMessage wrong peer = %T %+v, want one messages.messages", gotRich, gotRich)
|
||||
}
|
||||
if _, ok := box.Messages[0].(*tg.MessageEmpty); !ok {
|
||||
t.Fatalf("getRichMessage wrong peer message = %T, want *tg.MessageEmpty", box.Messages[0])
|
||||
}
|
||||
}
|
||||
|
||||
// TestSendMessageRichMessageEmbeddedPhoto 验证富文本内嵌图片:按 id 解析为媒体快照存储,
|
||||
// 投影时复用 tgPhoto 还原。
|
||||
func TestSendMessageRichMessageEmbeddedPhoto(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
files, ok := r.deps.Files.(*fakeFiles)
|
||||
if !ok {
|
||||
t.Fatalf("deps.Files = %T, want *fakeFiles", r.deps.Files)
|
||||
}
|
||||
files.photos[889] = domain.Photo{ID: 889, AccessHash: 42, DCID: 2, Sizes: []domain.PhotoSize{{Kind: domain.PhotoSizeKindDefault, Type: "x", W: 800, H: 600}}}
|
||||
|
||||
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Message: "rich+photo",
|
||||
RandomID: 7003,
|
||||
RichMessage: &tg.InputRichMessage{
|
||||
Blocks: []tg.PageBlockClass{&tg.PageBlockParagraph{Text: &tg.TextPlain{Text: "see photo"}}},
|
||||
Photos: []tg.InputPhotoClass{&tg.InputPhoto{ID: 889, AccessHash: 42}},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("send rich message with photo: %v", err)
|
||||
}
|
||||
echo := newMessageFromUpdates(t, updates)
|
||||
rich, ok := echo.GetRichMessage()
|
||||
if !ok {
|
||||
t.Fatalf("send echo missing rich message")
|
||||
}
|
||||
if len(rich.Photos) != 1 {
|
||||
t.Fatalf("rich photos = %d, want 1", len(rich.Photos))
|
||||
}
|
||||
photo, ok := rich.Photos[0].(*tg.Photo)
|
||||
if !ok {
|
||||
t.Fatalf("rich photo = %T, want *tg.Photo", rich.Photos[0])
|
||||
}
|
||||
if photo.ID != 889 {
|
||||
t.Errorf("rich photo id = %d, want 889", photo.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// singleStoredMessage 从 messages.messages 取出唯一一条非空 *tg.Message。
|
||||
func singleStoredMessage(t *testing.T, res tg.MessagesMessagesClass) *tg.Message {
|
||||
t.Helper()
|
||||
box, ok := res.(*tg.MessagesMessages)
|
||||
if !ok || len(box.Messages) != 1 {
|
||||
t.Fatalf("messages = %T %+v, want one messages.messages", res, res)
|
||||
}
|
||||
msg, ok := box.Messages[0].(*tg.Message)
|
||||
if !ok {
|
||||
t.Fatalf("stored message = %T, want *tg.Message", box.Messages[0])
|
||||
}
|
||||
return msg
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue