chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
234
internal/rpc/send_media_geo_test.go
Normal file
234
internal/rpc/send_media_geo_test.go
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gotd/td/tg"
|
||||
"github.com/gotd/td/tgerr"
|
||||
)
|
||||
|
||||
func TestSendMediaPrivateGeoPoint(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
point := &tg.InputGeoPoint{Lat: 39.9042, Long: 116.4074}
|
||||
point.SetAccuracyRadius(30) // gotd flag 字段必须 Set*() 置 flag 位,直接赋字段 getter 读不到
|
||||
updates, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Media: &tg.InputMediaGeoPoint{GeoPoint: point},
|
||||
RandomID: 2001,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("sendMedia geo: %v", err)
|
||||
}
|
||||
msg := newMessageFromUpdates(t, updates)
|
||||
media, ok := msg.Media.(*tg.MessageMediaGeo)
|
||||
if !ok {
|
||||
t.Fatalf("expected MessageMediaGeo, got %T", msg.Media)
|
||||
}
|
||||
geo, ok := media.Geo.(*tg.GeoPoint)
|
||||
if !ok {
|
||||
t.Fatalf("expected tg.GeoPoint, got %T", media.Geo)
|
||||
}
|
||||
if geo.Lat != 39.9042 || geo.Long != 116.4074 {
|
||||
t.Errorf("geo = (%v, %v), want (39.9042, 116.4074)", geo.Lat, geo.Long)
|
||||
}
|
||||
if geo.AccessHash == 0 {
|
||||
t.Error("geo access_hash should be non-zero (clients echo it to upload.getWebFile)")
|
||||
}
|
||||
if radius, ok := geo.GetAccuracyRadius(); !ok || radius != 30 {
|
||||
t.Errorf("accuracy_radius = %d (%v), want 30", radius, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMediaGeoPointOutOfRange(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
for _, point := range []*tg.InputGeoPoint{
|
||||
{Lat: 90.5, Long: 0},
|
||||
{Lat: -91, Long: 0},
|
||||
{Lat: 0, Long: 180.01},
|
||||
{Lat: 0, Long: -181},
|
||||
} {
|
||||
_, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Media: &tg.InputMediaGeoPoint{GeoPoint: point},
|
||||
RandomID: 2002,
|
||||
})
|
||||
if err == nil || !tgerr.Is(err, "MEDIA_INVALID") {
|
||||
t.Errorf("geo (%v,%v): err = %v, want MEDIA_INVALID", point.Lat, point.Long, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMediaGeoPointEmpty(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
_, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Media: &tg.InputMediaGeoPoint{GeoPoint: &tg.InputGeoPointEmpty{}},
|
||||
RandomID: 2003,
|
||||
})
|
||||
if err == nil || !tgerr.Is(err, "MEDIA_EMPTY") {
|
||||
t.Fatalf("err = %v, want MEDIA_EMPTY", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMediaPrivateVenue(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
updates, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Media: &tg.InputMediaVenue{
|
||||
GeoPoint: &tg.InputGeoPoint{Lat: 31.2304, Long: 121.4737},
|
||||
Title: "People's Square",
|
||||
Address: "Huangpu, Shanghai",
|
||||
Provider: "foursquare",
|
||||
VenueID: "4b5b3c4ff964a520fd0029e3",
|
||||
VenueType: "arts_entertainment/default",
|
||||
},
|
||||
RandomID: 2004,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("sendMedia venue: %v", err)
|
||||
}
|
||||
msg := newMessageFromUpdates(t, updates)
|
||||
media, ok := msg.Media.(*tg.MessageMediaVenue)
|
||||
if !ok {
|
||||
t.Fatalf("expected MessageMediaVenue, got %T", msg.Media)
|
||||
}
|
||||
if media.Title != "People's Square" || media.Address != "Huangpu, Shanghai" ||
|
||||
media.Provider != "foursquare" || media.VenueID != "4b5b3c4ff964a520fd0029e3" ||
|
||||
media.VenueType != "arts_entertainment/default" {
|
||||
t.Fatalf("venue media = %+v, want preserved venue payload", media)
|
||||
}
|
||||
geo, ok := media.Geo.(*tg.GeoPoint)
|
||||
if !ok || geo.Lat != 31.2304 || geo.Long != 121.4737 {
|
||||
t.Fatalf("venue geo = %#v, want (31.2304, 121.4737)", media.Geo)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMediaVenueWithoutTitle(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
_, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Media: &tg.InputMediaVenue{
|
||||
GeoPoint: &tg.InputGeoPoint{Lat: 1, Long: 1},
|
||||
Title: " ",
|
||||
},
|
||||
RandomID: 2005,
|
||||
})
|
||||
if err == nil || !tgerr.Is(err, "MEDIA_EMPTY") {
|
||||
t.Fatalf("err = %v, want MEDIA_EMPTY", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMediaPrivateDiceValueRanges(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
cases := []struct {
|
||||
emoticon string
|
||||
want string
|
||||
max int
|
||||
}{
|
||||
{"\U0001F3B2", "\U0001F3B2", 6}, // 🎲
|
||||
{"\U0001F3AF", "\U0001F3AF", 6}, // 🎯
|
||||
{"\U0001F3B3", "\U0001F3B3", 6}, // 🎳
|
||||
{"\U0001F3C0", "\U0001F3C0", 5}, // 🏀
|
||||
{"⚽", "⚽", 5}, // 裸足球
|
||||
{"⚽️", "⚽", 5}, // 带 U+FE0F 变体,须归一
|
||||
{"\U0001F3B0", "\U0001F3B0", 64}, // 🎰
|
||||
}
|
||||
randomID := int64(3000)
|
||||
for _, tc := range cases {
|
||||
// 多抽几次覆盖取值边界;value 必须始终落在 [1, max]。
|
||||
for i := 0; i < 8; i++ {
|
||||
randomID++
|
||||
updates, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Media: &tg.InputMediaDice{Emoticon: tc.emoticon},
|
||||
RandomID: randomID,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("sendMedia dice %q: %v", tc.emoticon, err)
|
||||
}
|
||||
msg := newMessageFromUpdates(t, updates)
|
||||
media, ok := msg.Media.(*tg.MessageMediaDice)
|
||||
if !ok {
|
||||
t.Fatalf("expected MessageMediaDice, got %T", msg.Media)
|
||||
}
|
||||
if media.Emoticon != tc.want {
|
||||
t.Fatalf("dice emoticon = %q, want %q", media.Emoticon, tc.want)
|
||||
}
|
||||
if media.Value < 1 || media.Value > tc.max {
|
||||
t.Fatalf("dice %q value = %d, want in [1, %d]", tc.emoticon, media.Value, tc.max)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMediaDiceUnknownEmoticon(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, friend := newMediaTestRouter(t)
|
||||
|
||||
_, err := r.onMessagesSendMedia(WithUserID(ctx, owner.ID), &tg.MessagesSendMediaRequest{
|
||||
Peer: &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash},
|
||||
Media: &tg.InputMediaDice{Emoticon: "\U0001F600"},
|
||||
RandomID: 3100,
|
||||
})
|
||||
if err == nil || !tgerr.Is(err, "EMOTICON_INVALID") {
|
||||
t.Fatalf("err = %v, want EMOTICON_INVALID", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUploadGetWebFileGeoTile(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r, owner, _ := newMediaTestRouter(t)
|
||||
|
||||
req := &tg.UploadGetWebFileRequest{
|
||||
Location: &tg.InputWebFileGeoPointLocation{
|
||||
GeoPoint: &tg.InputGeoPoint{Lat: 39.9, Long: 116.4},
|
||||
AccessHash: 12345,
|
||||
W: 100, H: 100, Zoom: 15, Scale: 1,
|
||||
},
|
||||
Offset: 0,
|
||||
Limit: 1 << 17,
|
||||
}
|
||||
file, err := r.onUploadGetWebFile(WithUserID(ctx, owner.ID), req)
|
||||
if err != nil {
|
||||
t.Fatalf("getWebFile: %v", err)
|
||||
}
|
||||
if file.Size != 12 || len(file.Bytes) != 12 {
|
||||
t.Fatalf("size = %d bytes = %d, want 12/12 (fake tile)", file.Size, len(file.Bytes))
|
||||
}
|
||||
if file.MimeType != "image/png" {
|
||||
t.Errorf("mime = %q, want image/png", file.MimeType)
|
||||
}
|
||||
|
||||
// offset 续传按字节切片,size 始终是全量大小。
|
||||
req.Offset = 4
|
||||
req.Limit = 4
|
||||
chunk, err := r.onUploadGetWebFile(WithUserID(ctx, owner.ID), req)
|
||||
if err != nil {
|
||||
t.Fatalf("getWebFile offset: %v", err)
|
||||
}
|
||||
if chunk.Size != 12 || !bytes.Equal(chunk.Bytes, []byte{0x0D, 0x0A, 0x1A, 0x0A}) {
|
||||
t.Fatalf("offset chunk = %v (size %d), want bytes 4..8 of tile", chunk.Bytes, chunk.Size)
|
||||
}
|
||||
|
||||
// URL 形态当前无来源,必须显式拒绝而非静默。
|
||||
if _, err := r.onUploadGetWebFile(WithUserID(ctx, owner.ID), &tg.UploadGetWebFileRequest{
|
||||
Location: &tg.InputWebFileLocation{URL: "https://example.com/a.png", AccessHash: 1},
|
||||
Limit: 4096,
|
||||
}); err == nil || !tgerr.Is(err, "LOCATION_INVALID") {
|
||||
t.Fatalf("url webfile err = %v, want LOCATION_INVALID", err)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue