internal/mtprotoedge/help_legacy_test.go
Rama main · réplica de lectura del repositorio original.
package mtprotoedge
import (
"testing"
"time"
"github.com/iamxvbaba/td/bin"
"github.com/iamxvbaba/td/mt"
"github.com/iamxvbaba/td/proto"
"github.com/iamxvbaba/td/tg"
)
type trailingHelpTestRequest struct{}
func (*trailingHelpTestRequest) Encode(b *bin.Buffer) error {
b.PutID(helpTestRequestTypeID)
b.PutID(0xdeadbeef)
return nil
}
func (*trailingHelpTestRequest) Decode(b *bin.Buffer) error {
if err := b.ConsumeID(helpTestRequestTypeID); err != nil {
return err
}
_, err := b.ID()
return err
}
// TestHelpTestLegacyTerminal verifies that the removed help.test#c0e202f7 = Bool
// method is answered with a fixed boolTrue both bare and along the official
// invokeWithLayer/initConnection wrapper path, and that the connection survives.
func TestHelpTestLegacyTerminal(t *testing.T) {
tests := []struct {
name string
layer int
wrapped bool
}{
{name: "bare"},
{name: "layer227_wrapped", layer: 227, wrapped: true},
{name: "layer228_wrapped", layer: 228, wrapped: true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
const dc = 2
addr, pub, _ := startTestServer(t, Options{DC: dc, LayerRPC: newAdmissionOnlyLayerRPC()})
conn, auth, cipher := dialHandshake(t, addr, dc, pub)
var request bin.Encoder = &helpTestRequest{}
if test.wrapped {
request = &tg.InvokeWithLayerRequest{
Layer: test.layer,
Query: &tg.InitConnectionRequest{
APIID: 1, DeviceModel: "help-test", SystemVersion: "test",
AppVersion: "test", SystemLangCode: "en", LangCode: "en",
Query: &helpTestRequest{},
},
}
}
clientMsgID := proto.NewMessageIDGen(time.Now)
reqMsgID := clientMsgID.New(proto.MessageFromClient)
sendEncrypted(t, conn, cipher, auth, reqMsgID, request)
replies := collectReplies(t, conn, cipher, auth.AuthKey, proto.ResultTypeID)
assertHelpTestRPCResult(t, mustHave(t, replies, proto.ResultTypeID, "help.test rpc_result"), reqMsgID)
pingMsgID := clientMsgID.New(proto.MessageFromClient)
sendEncryptedWithSeq(t, conn, cipher, auth, pingMsgID, 3, &mt.PingRequest{PingID: 97})
pongReplies := collectReplies(t, conn, cipher, auth.AuthKey, mt.PongTypeID)
var pong mt.Pong
if err := pong.Decode(mustHave(t, pongReplies, mt.PongTypeID, "pong after help.test")); err != nil {
t.Fatalf("decode pong after help.test: %v", err)
}
if pong.MsgID != pingMsgID || pong.PingID != 97 {
t.Fatalf("pong after help.test = %+v", pong)
}
})
}
}
// TestWrappedHelpTestTrailingBytesRejected keeps the compatibility terminal
// exactly one word: trailing bytes stay a correlated INPUT_REQUEST_INVALID.
func TestWrappedHelpTestTrailingBytesRejected(t *testing.T) {
const dc = 2
addr, pub, _ := startTestServer(t, Options{DC: dc, LayerRPC: newAdmissionOnlyLayerRPC()})
conn, auth, cipher := dialHandshake(t, addr, dc, pub)
reqMsgID := proto.NewMessageIDGen(time.Now).New(proto.MessageFromClient)
request := &tg.InvokeWithLayerRequest{
Layer: 228,
Query: &tg.InitConnectionRequest{
APIID: 1, DeviceModel: "malformed-help-test", SystemVersion: "test",
AppVersion: "test", SystemLangCode: "en", LangCode: "en",
Query: &trailingHelpTestRequest{},
},
}
sendEncrypted(t, conn, cipher, auth, reqMsgID, request)
replies := collectReplies(t, conn, cipher, auth.AuthKey, proto.ResultTypeID)
var result proto.Result
if err := result.Decode(mustHave(t, replies, proto.ResultTypeID, "malformed help.test rpc_result")); err != nil {
t.Fatalf("decode malformed help.test rpc_result: %v", err)
}
if result.RequestMessageID != reqMsgID {
t.Fatalf("malformed help.test req_msg_id = %d, want %d", result.RequestMessageID, reqMsgID)
}
var rpcErr mt.RPCError
if err := rpcErr.Decode(&bin.Buffer{Buf: result.Result}); err != nil {
t.Fatalf("decode malformed help.test RPC error: %v", err)
}
if rpcErr.ErrorCode != 400 || rpcErr.ErrorMessage != "INPUT_REQUEST_INVALID" {
t.Fatalf("malformed help.test RPC error = %+v", rpcErr)
}
}
func assertHelpTestRPCResult(t *testing.T, b *bin.Buffer, reqMsgID int64) {
t.Helper()
var result proto.Result
if err := result.Decode(b); err != nil {
t.Fatalf("decode help.test rpc_result: %v", err)
}
if result.RequestMessageID != reqMsgID {
t.Fatalf("help.test rpc_result.req_msg_id = %d, want %d", result.RequestMessageID, reqMsgID)
}
inner := &bin.Buffer{Buf: result.Result}
innerID, err := inner.PeekID()
if err != nil {
t.Fatalf("peek help.test rpc_result inner: %v", err)
}
if innerID != boolTrueTypeID || inner.Len() != bin.Word {
t.Fatalf("help.test rpc_result inner = %#x/%d bytes, want %#x/%d", innerID, inner.Len(), boolTrueTypeID, bin.Word)
}
}