owpengram-server/internal/rpc/messages_send_webpage_rpc_test.go

203 lines
7.1 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 rpc
import (
"context"
"testing"
"github.com/iamxvbaba/td/tg"
"telesrv/internal/domain"
)
// "see https://example.com/x" 的 URL 在 UTF-16 偏移 4、长度 21。
const (
wpTestMessage = "see https://example.com/x"
wpTestURL = "https://example.com/x"
wpURLEntityOff = 4
wpURLEntityLen = 21
)
func wpURLEntities() []tg.MessageEntityClass {
return []tg.MessageEntityClass{&tg.MessageEntityURL{Offset: wpURLEntityOff, Length: wpURLEntityLen}}
}
// TestSendMessageAttachesWebPagePending 验证启用预览时,带 URL 的文本消息挂上 pending 占位
// (id==url_hash 保证与 done 解析关联),并投影 invert_media。
func TestSendMessageAttachesWebPagePending(t *testing.T) {
ctx := context.Background()
r, owner, friend := newMediaTestRouter(t)
r.deps.Files.(*fakeFiles).webPagePreviewOn = true
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
Message: wpTestMessage,
Entities: wpURLEntities(),
RandomID: 5101,
InvertMedia: true,
})
if err != nil {
t.Fatalf("sendMessage: %v", err)
}
msg := newMessageFromUpdates(t, updates)
wrap, ok := msg.Media.(*tg.MessageMediaWebPage)
if !ok {
t.Fatalf("media = %T, want *tg.MessageMediaWebPage", msg.Media)
}
pending, ok := wrap.Webpage.(*tg.WebPagePending)
if !ok {
t.Fatalf("webpage = %T, want *tg.WebPagePending", wrap.Webpage)
}
wantID := domain.WebPageURLHash(wpTestURL)
if pending.ID != wantID {
t.Errorf("pending id = %d, want url_hash %d", pending.ID, wantID)
}
if url, _ := pending.GetURL(); url != wpTestURL {
t.Errorf("pending url = %q, want %q", url, wpTestURL)
}
if !msg.InvertMedia {
t.Errorf("invert_media not projected onto message")
}
}
// TestSendMessageAttachesCachedDoneCard 验证URL 已缓存解析时,发送 echo 直接带 done 卡片
// (非 pending——官方行为TDesktop 据此立即渲染、不依赖异步换卡。
func TestSendMessageAttachesCachedDoneCard(t *testing.T) {
ctx := context.Background()
r, owner, friend := newMediaTestRouter(t)
f := r.deps.Files.(*fakeFiles)
f.webPagePreviewOn = true
f.lookupWebPageFn = func(u string) (domain.MessageWebPage, bool) {
return domain.MessageWebPage{State: domain.MessageWebPageStateDone, ID: domain.WebPageURLHash(u), URL: u, DisplayURL: "example.com", Title: "Cached"}, true
}
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash}, Message: wpTestMessage, Entities: wpURLEntities(), RandomID: 5201,
})
if err != nil {
t.Fatalf("sendMessage: %v", err)
}
msg := newMessageFromUpdates(t, updates)
wrap, ok := msg.Media.(*tg.MessageMediaWebPage)
if !ok {
t.Fatalf("media = %T, want *tg.MessageMediaWebPage", msg.Media)
}
page, ok := wrap.Webpage.(*tg.WebPage)
if !ok {
t.Fatalf("echo webpage = %T, want *tg.WebPage (done card directly)", wrap.Webpage)
}
if v, _ := page.GetTitle(); v != "Cached" {
t.Errorf("title = %q, want Cached", v)
}
}
// TestSendMessageNoWebpageSuppressesPreview 验证 no_webpage 抑制占位。
func TestSendMessageNoWebpageSuppressesPreview(t *testing.T) {
ctx := context.Background()
r, owner, friend := newMediaTestRouter(t)
r.deps.Files.(*fakeFiles).webPagePreviewOn = true
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
Message: wpTestMessage,
Entities: wpURLEntities(),
RandomID: 5102,
NoWebpage: true,
})
if err != nil {
t.Fatalf("sendMessage: %v", err)
}
if msg := newMessageFromUpdates(t, updates); msg.Media != nil {
t.Fatalf("media = %T, want nil (no_webpage)", msg.Media)
}
}
// TestSendMessagePreviewDisabledNoPlaceholder 验证未启用预览时不挂占位(否则永久 pending)。
func TestSendMessagePreviewDisabledNoPlaceholder(t *testing.T) {
ctx := context.Background()
r, owner, friend := newMediaTestRouter(t)
// webPagePreviewOn 默认 false。
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
Message: wpTestMessage,
Entities: wpURLEntities(),
RandomID: 5103,
})
if err != nil {
t.Fatalf("sendMessage: %v", err)
}
if msg := newMessageFromUpdates(t, updates); msg.Media != nil {
t.Fatalf("media = %T, want nil (preview disabled)", msg.Media)
}
}
// TestSendMediaInputWebPageAttachesPending 验证 sendMedia 的 InputMediaWebPage 经降级到
// sendMessage 后,仍从文本 URL 挂上 pending 占位(启用预览时)。
func TestSendMediaInputWebPageAttachesPending(t *testing.T) {
ctx := context.Background()
r, owner, friend := newMediaTestRouter(t)
r.deps.Files.(*fakeFiles).webPagePreviewOn = true
updates, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
Media: &tg.InputMediaWebPage{URL: wpTestURL},
Message: wpTestMessage,
Entities: wpURLEntities(),
RandomID: 5105,
})
if err != nil {
t.Fatalf("sendMedia webpage: %v", err)
}
msg := newMessageFromUpdates(t, updates)
wrap, ok := msg.Media.(*tg.MessageMediaWebPage)
if !ok {
t.Fatalf("media = %T, want *tg.MessageMediaWebPage", msg.Media)
}
if _, ok := wrap.Webpage.(*tg.WebPagePending); !ok {
t.Fatalf("webpage = %T, want *tg.WebPagePending", wrap.Webpage)
}
}
// TestSendMessageHighlightsBareURL 验证服务端为不带 url 实体的消息(如 TDesktop 发的)补
// MessageEntityURL使链接高亮——独立于预览是否启用。
func TestSendMessageHighlightsBareURL(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: "see https://example.com/x",
RandomID: 5301, // 无 entities模拟 TDesktop
})
if err != nil {
t.Fatalf("sendMessage: %v", err)
}
msg := newMessageFromUpdates(t, updates)
var found bool
for _, e := range msg.Entities {
if u, ok := e.(*tg.MessageEntityURL); ok && u.Offset == 4 && u.Length == 21 {
found = true
}
}
if !found {
t.Fatalf("sent message missing url highlight entity: %+v", msg.Entities)
}
}
// TestSendMessageNoURLNoPlaceholder 验证无 URL 实体时不挂占位。
func TestSendMessageNoURLNoPlaceholder(t *testing.T) {
ctx := context.Background()
r, owner, friend := newMediaTestRouter(t)
r.deps.Files.(*fakeFiles).webPagePreviewOn = true
updates, err := r.onMessagesSendMessage(WithUserID(ctx, owner.ID), &tg.MessagesSendMessageRequest{
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
Message: "just plain text, no link",
RandomID: 5104,
})
if err != nil {
t.Fatalf("sendMessage: %v", err)
}
if msg := newMessageFromUpdates(t, updates); msg.Media != nil {
t.Fatalf("media = %T, want nil (no url)", msg.Media)
}
}