move gotd fork into repo. (#111)
- update to latest telegram layer - remove some references to fields in tg.Entities that don't exist in the schema - originally added here: https://github.com/beeper/td/commit/820929062a2ba0104397bc01235ab58a9cff780e - referenced here - https://github.com/mautrix/telegramgo/commit/124f0967ed195b5a380c9bd02e170ada9710dde3 - https://github.com/mautrix/telegramgo/commit/4205047aab2e0639217148b5d125bfaab668bd8e
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
// Package e2e contains end-to-end updates processing test.
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/go-faster/errors"
|
||||
|
||||
"go.mau.fi/mautrix-telegram/pkg/gotd/tg"
|
||||
)
|
||||
|
||||
// Server for testing gaps.
|
||||
type server struct {
|
||||
date int
|
||||
peers *peerDatabase
|
||||
messages *messageDatabase
|
||||
|
||||
mux sync.Mutex
|
||||
}
|
||||
|
||||
// NewServer creates new test server.
|
||||
func newServer() *server {
|
||||
return &server{
|
||||
date: 1,
|
||||
peers: &peerDatabase{
|
||||
users: make(map[int64]*tg.User),
|
||||
chats: make(map[int64]*tg.Chat),
|
||||
channels: make(map[int64]*tg.Channel),
|
||||
},
|
||||
messages: &messageDatabase{
|
||||
channels: make(map[int64][]tg.MessageClass),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// UpdatesGetState returns current remote state.
|
||||
func (s *server) UpdatesGetState(ctx context.Context) (*tg.UpdatesState, error) {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
return &tg.UpdatesState{
|
||||
Pts: len(s.messages.common),
|
||||
Qts: len(s.messages.secret),
|
||||
Date: s.date,
|
||||
Seq: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdatesGetDifference returns difference between local and remote states.
|
||||
func (s *server) UpdatesGetDifference(ctx context.Context, request *tg.UpdatesGetDifferenceRequest) (tg.UpdatesDifferenceClass, error) {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
ents := NewEntities()
|
||||
var common []tg.MessageClass
|
||||
for i := request.Pts + 1; i <= len(s.messages.common); i++ {
|
||||
common = append(common, s.messages.common[i-1])
|
||||
s.fillMessageEnts(s.messages.common[i-1], ents)
|
||||
}
|
||||
|
||||
var secret []tg.EncryptedMessageClass
|
||||
for i := request.Qts + 1; i <= len(s.messages.secret); i++ {
|
||||
secret = append(secret, s.messages.secret[i-1])
|
||||
}
|
||||
|
||||
var others []tg.UpdateClass
|
||||
for _, msgs := range s.messages.channels {
|
||||
for i, msg := range msgs {
|
||||
if msg.(*tg.Message).Date > request.Date {
|
||||
others = append(others, &tg.UpdateNewChannelMessage{
|
||||
Message: msg,
|
||||
Pts: i + 1,
|
||||
PtsCount: 1,
|
||||
})
|
||||
s.fillMessageEnts(msg, ents)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(common) == 0 && len(secret) == 0 && len(others) == 0 {
|
||||
return &tg.UpdatesDifferenceEmpty{
|
||||
Date: s.date,
|
||||
Seq: 0,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &tg.UpdatesDifference{
|
||||
NewMessages: common,
|
||||
NewEncryptedMessages: secret,
|
||||
OtherUpdates: others,
|
||||
Users: ents.AsUsers(),
|
||||
Chats: ents.AsChats(),
|
||||
State: tg.UpdatesState{
|
||||
Pts: len(s.messages.common),
|
||||
Qts: len(s.messages.secret),
|
||||
Date: s.date,
|
||||
Seq: 0,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdatesGetChannelDifference returns difference between local and remote channel states.
|
||||
func (s *server) UpdatesGetChannelDifference(
|
||||
ctx context.Context, request *tg.UpdatesGetChannelDifferenceRequest,
|
||||
) (tg.UpdatesChannelDifferenceClass, error) {
|
||||
s.mux.Lock()
|
||||
defer s.mux.Unlock()
|
||||
|
||||
channel, ok := request.Channel.(*tg.InputChannel)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("bad InputChannelClass type: %T", request.Channel)
|
||||
}
|
||||
|
||||
if peer, ok := s.peers.channels[channel.ChannelID]; true {
|
||||
if !ok {
|
||||
return nil, errors.Errorf("channel %d not found", channel.ChannelID)
|
||||
}
|
||||
|
||||
if peer.AccessHash != channel.AccessHash {
|
||||
return nil, errors.New("invalid access hash")
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
channelMsgs = s.messages.channels[channel.ChannelID]
|
||||
ents = NewEntities()
|
||||
prepared []tg.MessageClass
|
||||
)
|
||||
|
||||
for i := request.Pts + 1; i <= len(channelMsgs); i++ {
|
||||
prepared = append(prepared, channelMsgs[i-1])
|
||||
s.fillMessageEnts(channelMsgs[i-1], ents)
|
||||
}
|
||||
|
||||
if len(prepared) == 0 {
|
||||
return &tg.UpdatesChannelDifferenceEmpty{
|
||||
Pts: len(channelMsgs),
|
||||
Final: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &tg.UpdatesChannelDifference{
|
||||
NewMessages: prepared,
|
||||
Users: ents.AsUsers(),
|
||||
Chats: ents.AsChats(),
|
||||
Pts: len(channelMsgs),
|
||||
Final: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *server) fillMessageEnts(msg tg.MessageClass, ents *Entities) {
|
||||
switch peer := msg.(*tg.Message).PeerID.(type) {
|
||||
case *tg.PeerUser:
|
||||
user, ok := s.peers.users[peer.UserID]
|
||||
if !ok {
|
||||
panic("bad user")
|
||||
}
|
||||
|
||||
ents.Users[user.ID] = user
|
||||
case *tg.PeerChat:
|
||||
chat, ok := s.peers.chats[peer.ChatID]
|
||||
if !ok {
|
||||
panic("bad chat")
|
||||
}
|
||||
|
||||
ents.Chats[chat.ID] = chat
|
||||
case *tg.PeerChannel:
|
||||
channel, ok := s.peers.channels[peer.ChannelID]
|
||||
if !ok {
|
||||
panic("bad channel")
|
||||
}
|
||||
|
||||
ents.Channels[channel.ID] = channel
|
||||
default:
|
||||
panic("unexpected peer type")
|
||||
}
|
||||
|
||||
peerUser, ok := msg.(*tg.Message).FromID.(*tg.PeerUser)
|
||||
if !ok {
|
||||
panic("bad fromID")
|
||||
}
|
||||
|
||||
user, ok := s.peers.users[peerUser.UserID]
|
||||
if !ok {
|
||||
panic("bad user")
|
||||
}
|
||||
|
||||
ents.Users[user.ID] = user
|
||||
}
|
||||
Reference in New Issue
Block a user