chore: refresh gramsrv public release
This commit is contained in:
parent
75cebe8dbf
commit
70b6820474
1274 changed files with 378751 additions and 59919 deletions
|
|
@ -4,7 +4,9 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gotd/td/clock"
|
||||
"github.com/gotd/td/tg"
|
||||
"go.uber.org/zap/zaptest"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
|
@ -74,6 +76,297 @@ func TestMessagesGetAllStickersUsesTDesktopHashForNotModified(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAccountGetDefaultEmojiStatusesServesSynthesizedSet(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
files := &fakeFiles{
|
||||
docs: map[int64]domain.Document{
|
||||
101: {ID: 101, AccessHash: 1},
|
||||
102: {ID: 102, AccessHash: 2},
|
||||
},
|
||||
sets: map[domain.StickerSetKind][]domain.StickerSet{
|
||||
domain.StickerSetKindSystem: {
|
||||
{
|
||||
ID: 77,
|
||||
ShortName: "TelesrvDefaultStatuses",
|
||||
Kind: domain.StickerSetKindSystem,
|
||||
SystemKey: domain.StickerSetSystemKeyEmojiDefaultStatuses,
|
||||
Emojis: true,
|
||||
Count: 2,
|
||||
Hash: 12345,
|
||||
DocumentIDs: []int64{101, 102},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &Router{deps: Deps{Files: files}}
|
||||
|
||||
first, err := r.onAccountGetDefaultEmojiStatuses(ctx, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("first getDefaultEmojiStatuses: %v", err)
|
||||
}
|
||||
full, ok := first.(*tg.AccountEmojiStatuses)
|
||||
if !ok {
|
||||
t.Fatalf("first getDefaultEmojiStatuses = %T, want *tg.AccountEmojiStatuses", first)
|
||||
}
|
||||
if len(full.Statuses) != 2 {
|
||||
t.Fatalf("statuses = %d, want 2", len(full.Statuses))
|
||||
}
|
||||
status, ok := full.Statuses[0].(*tg.EmojiStatus)
|
||||
if !ok || status.DocumentID != 101 {
|
||||
t.Fatalf("statuses[0] = %#v, want EmojiStatus document 101", full.Statuses[0])
|
||||
}
|
||||
if full.Hash == 0 {
|
||||
t.Fatal("hash must be non-zero for cache round-trips")
|
||||
}
|
||||
|
||||
second, err := r.onAccountGetDefaultEmojiStatuses(ctx, full.Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("second getDefaultEmojiStatuses: %v", err)
|
||||
}
|
||||
if _, ok := second.(*tg.AccountEmojiStatusesNotModified); !ok {
|
||||
t.Fatalf("second getDefaultEmojiStatuses = %T, want notModified", second)
|
||||
}
|
||||
|
||||
// getStickerSet(inputStickerSetEmojiDefaultStatuses) 走同一系统集。
|
||||
resolved, err := r.onMessagesGetStickerSet(ctx, &tg.MessagesGetStickerSetRequest{
|
||||
Stickerset: &tg.InputStickerSetEmojiDefaultStatuses{},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("getStickerSet default statuses: %v", err)
|
||||
}
|
||||
setFull, ok := resolved.(*tg.MessagesStickerSet)
|
||||
if !ok {
|
||||
t.Fatalf("getStickerSet = %T, want *tg.MessagesStickerSet", resolved)
|
||||
}
|
||||
if setFull.Set.ID != 77 || len(setFull.Documents) != 2 {
|
||||
t.Fatalf("resolved set = %d with %d docs, want 77 with 2", setFull.Set.ID, len(setFull.Documents))
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountGetDefaultEmojiStatusesFallsBackWhenUnseeded(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r := &Router{deps: Deps{Files: &fakeFiles{}}}
|
||||
res, err := r.onAccountGetDefaultEmojiStatuses(ctx, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("getDefaultEmojiStatuses without seed: %v", err)
|
||||
}
|
||||
if _, ok := res.(*tg.AccountEmojiStatusesNotModified); !ok {
|
||||
t.Fatalf("unseeded result = %T, want compat notModified stub", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessagesGetStickerSetAndroidPlaceholderUsesSeededSet(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
docs := make(map[int64]domain.Document)
|
||||
documentIDs := make([]int64, 0, androidPlaceholderStickerMinDocuments)
|
||||
for i := 0; i < androidPlaceholderStickerMinDocuments; i++ {
|
||||
id := int64(100 + i)
|
||||
documentIDs = append(documentIDs, id)
|
||||
docs[id] = domain.Document{ID: id, AccessHash: id + 1000, DCID: 2}
|
||||
}
|
||||
files := &fakeFiles{
|
||||
docs: docs,
|
||||
sets: map[domain.StickerSetKind][]domain.StickerSet{
|
||||
domain.StickerSetKindSystem: {
|
||||
{
|
||||
ID: 77,
|
||||
AccessHash: 7700,
|
||||
ShortName: "AnimatedEmojies",
|
||||
Title: "Animated Emoji",
|
||||
Kind: domain.StickerSetKindSystem,
|
||||
SystemKey: "animated_emoji",
|
||||
Emojis: true,
|
||||
Count: len(documentIDs),
|
||||
Hash: 12345,
|
||||
DocumentIDs: documentIDs,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &Router{deps: Deps{Files: files}}
|
||||
|
||||
res, err := r.onMessagesGetStickerSet(ctx, &tg.MessagesGetStickerSetRequest{
|
||||
Stickerset: &tg.InputStickerSetShortName{ShortName: "tg_placeholders_android"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("getStickerSet placeholder: %v", err)
|
||||
}
|
||||
full, ok := res.(*tg.MessagesStickerSet)
|
||||
if !ok {
|
||||
t.Fatalf("getStickerSet placeholder = %T, want *tg.MessagesStickerSet", res)
|
||||
}
|
||||
if full.Set.ID != 77 {
|
||||
t.Fatalf("placeholder fallback set id = %d, want 77", full.Set.ID)
|
||||
}
|
||||
if len(full.Documents) < androidPlaceholderStickerMinDocuments {
|
||||
t.Fatalf("placeholder fallback documents = %d, want >= %d", len(full.Documents), androidPlaceholderStickerMinDocuments)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessagesGetStickerSetAndroidPlaceholderFallsBackToEmptyWithoutSeed(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r := &Router{deps: Deps{Files: &fakeFiles{}}}
|
||||
res, err := r.onMessagesGetStickerSet(ctx, &tg.MessagesGetStickerSetRequest{
|
||||
Stickerset: &tg.InputStickerSetShortName{ShortName: "tg_placeholders_android"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("getStickerSet placeholder without seed: %v", err)
|
||||
}
|
||||
full, ok := res.(*tg.MessagesStickerSet)
|
||||
if !ok {
|
||||
t.Fatalf("getStickerSet placeholder without seed = %T, want *tg.MessagesStickerSet", res)
|
||||
}
|
||||
if len(full.Documents) != 0 {
|
||||
t.Fatalf("placeholder without seed documents = %d, want empty compat set", len(full.Documents))
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessagesGetMaskStickersUsesMaskCatalog(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
files := &fakeFiles{
|
||||
sets: map[domain.StickerSetKind][]domain.StickerSet{
|
||||
domain.StickerSetKindStickers: {
|
||||
{ID: 10, AccessHash: 100, ShortName: "regular", Title: "Regular", Count: 1, Hash: 123, Installed: true},
|
||||
},
|
||||
domain.StickerSetKindMasks: {
|
||||
{ID: 20, AccessHash: 200, ShortName: "masks", Title: "Masks", Count: 1, Hash: 789, Installed: true},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &Router{deps: Deps{Files: files}}
|
||||
|
||||
first, err := r.onMessagesGetMaskStickers(ctx, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("first getMaskStickers: %v", err)
|
||||
}
|
||||
full, ok := first.(*tg.MessagesAllStickers)
|
||||
if !ok {
|
||||
t.Fatalf("first getMaskStickers = %T, want *tg.MessagesAllStickers", first)
|
||||
}
|
||||
if len(full.Sets) != 1 || full.Sets[0].ID != 20 {
|
||||
t.Fatalf("mask sets = %+v, want only mask set 20", full.Sets)
|
||||
}
|
||||
|
||||
second, err := r.onMessagesGetMaskStickers(ctx, full.Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("second getMaskStickers: %v", err)
|
||||
}
|
||||
if _, ok := second.(*tg.MessagesAllStickersNotModified); !ok {
|
||||
t.Fatalf("second getMaskStickers = %T, want *tg.MessagesAllStickersNotModified", second)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessagesGetFeaturedStickersSurfacesSeededSets(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
files := &fakeFiles{
|
||||
docs: map[int64]domain.Document{
|
||||
201: {ID: 201, AccessHash: 1, MimeType: "application/x-tgsticker"},
|
||||
202: {ID: 202, AccessHash: 2, MimeType: "application/x-tgsticker"},
|
||||
301: {ID: 301, AccessHash: 3, MimeType: "application/x-tgsticker"},
|
||||
},
|
||||
sets: map[domain.StickerSetKind][]domain.StickerSet{
|
||||
domain.StickerSetKindStickers: {
|
||||
{ID: 10, AccessHash: 100, ShortName: "one", Title: "One", Count: 2, Hash: 123, DocumentIDs: []int64{201, 202}},
|
||||
{ID: 11, AccessHash: 110, ShortName: "two", Title: "Two", Count: 1, Hash: 456, DocumentIDs: []int64{301}},
|
||||
{ID: 12, AccessHash: 120, ShortName: "arch", Title: "Arch", Hash: 789, Archived: true, DocumentIDs: []int64{301}},
|
||||
},
|
||||
domain.StickerSetKindEmoji: {
|
||||
{ID: 20, AccessHash: 200, ShortName: "emo", Title: "Emo", Count: 1, Hash: 999, Emojis: true, DocumentIDs: []int64{201}},
|
||||
},
|
||||
},
|
||||
}
|
||||
r := &Router{deps: Deps{Files: files}}
|
||||
|
||||
first, err := r.onMessagesGetFeaturedStickers(ctx, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("first getFeaturedStickers: %v", err)
|
||||
}
|
||||
full, ok := first.(*tg.MessagesFeaturedStickers)
|
||||
if !ok {
|
||||
t.Fatalf("first getFeaturedStickers = %T, want *tg.MessagesFeaturedStickers", first)
|
||||
}
|
||||
if full.Count != 2 || len(full.Sets) != 2 {
|
||||
t.Fatalf("featured = count %d / %d sets, want 2/2 (archived excluded)", full.Count, len(full.Sets))
|
||||
}
|
||||
covered, ok := full.Sets[0].(*tg.StickerSetMultiCovered)
|
||||
if !ok {
|
||||
t.Fatalf("featured set[0] = %T, want *tg.StickerSetMultiCovered", full.Sets[0])
|
||||
}
|
||||
if covered.Set.ID != 10 || len(covered.Covers) != 2 {
|
||||
t.Fatalf("featured set[0] = id %d with %d covers, want 10 with 2", covered.Set.ID, len(covered.Covers))
|
||||
}
|
||||
if full.Hash == 0 {
|
||||
t.Fatal("featured hash must be non-zero for cache round-trips")
|
||||
}
|
||||
|
||||
second, err := r.onMessagesGetFeaturedStickers(ctx, full.Hash)
|
||||
if err != nil {
|
||||
t.Fatalf("second getFeaturedStickers: %v", err)
|
||||
}
|
||||
if _, ok := second.(*tg.MessagesFeaturedStickersNotModified); !ok {
|
||||
t.Fatalf("second getFeaturedStickers = %T, want NotModified", second)
|
||||
}
|
||||
|
||||
// emoji featured 走 emoji 集。
|
||||
emoji, err := r.onMessagesGetFeaturedEmojiStickers(ctx, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("getFeaturedEmojiStickers: %v", err)
|
||||
}
|
||||
emojiFull, ok := emoji.(*tg.MessagesFeaturedStickers)
|
||||
if !ok || emojiFull.Count != 1 {
|
||||
t.Fatalf("featured emoji = %T count %v, want 1 emoji set", emoji, emojiFull)
|
||||
}
|
||||
}
|
||||
|
||||
// countingStickerFiles 包 *fakeFiles 计数 ListStickerSets,验证目录缓存短路。
|
||||
type countingStickerFiles struct {
|
||||
*fakeFiles
|
||||
listCalls int
|
||||
}
|
||||
|
||||
func (f *countingStickerFiles) ListStickerSets(ctx context.Context, kind domain.StickerSetKind) ([]domain.StickerSet, error) {
|
||||
f.listCalls++
|
||||
return f.fakeFiles.ListStickerSets(ctx, kind)
|
||||
}
|
||||
|
||||
// TestStickerCatalogCacheShortCircuitsListStickerSets 回归 P2-5:getAllStickers/
|
||||
// getFeaturedStickers 经目录缓存——同 kind 重复请求只 ListStickerSets 一次(TTL 内 0 PG)。
|
||||
func TestStickerCatalogCacheShortCircuitsListStickerSets(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
files := &countingStickerFiles{fakeFiles: &fakeFiles{
|
||||
docs: map[int64]domain.Document{201: {ID: 201, AccessHash: 1}},
|
||||
sets: map[domain.StickerSetKind][]domain.StickerSet{
|
||||
domain.StickerSetKindStickers: {{ID: 10, AccessHash: 100, ShortName: "one", Count: 1, Hash: 123, DocumentIDs: []int64{201}}},
|
||||
},
|
||||
}}
|
||||
r := New(Config{}, Deps{Files: files}, zaptest.NewLogger(t), clock.System)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
if _, err := r.onMessagesGetAllStickers(ctx, 0); err != nil {
|
||||
t.Fatalf("getAllStickers %d: %v", i, err)
|
||||
}
|
||||
}
|
||||
if _, err := r.onMessagesGetFeaturedStickers(ctx, 0); err != nil {
|
||||
t.Fatalf("getFeaturedStickers: %v", err)
|
||||
}
|
||||
if files.listCalls != 1 {
|
||||
t.Fatalf("ListStickerSets(stickers) calls = %d, want 1 (目录缓存应短路)", files.listCalls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessagesGetFeaturedStickersEmptyWithoutSeed(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
r := &Router{deps: Deps{Files: &fakeFiles{}}}
|
||||
res, err := r.onMessagesGetFeaturedStickers(ctx, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("getFeaturedStickers without seed: %v", err)
|
||||
}
|
||||
full, ok := res.(*tg.MessagesFeaturedStickers)
|
||||
if !ok || full.Count != 0 || len(full.Sets) != 0 {
|
||||
t.Fatalf("unseeded featured = %#v, want empty", res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessagesGetAvailableReactionsNotModified(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
reactions := []domain.AvailableReaction{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue