129 lines
4.3 KiB
Go
129 lines
4.3 KiB
Go
package rpc
|
||
|
||
import (
|
||
"context"
|
||
"testing"
|
||
|
||
"github.com/gotd/td/tg"
|
||
"github.com/gotd/td/tgerr"
|
||
)
|
||
|
||
func sendTestLiveLocation(t *testing.T, r *Router, fromID int64, peer tg.InputPeerClass, randomID int64, period int) *tg.Message {
|
||
t.Helper()
|
||
point := &tg.InputGeoPoint{Lat: 39.9, Long: 116.4}
|
||
media := &tg.InputMediaGeoLive{GeoPoint: point}
|
||
media.SetPeriod(period)
|
||
media.SetHeading(90)
|
||
updates, err := r.onMessagesSendMedia(WithUserID(context.Background(), fromID), &tg.MessagesSendMediaRequest{
|
||
Peer: peer,
|
||
Media: media,
|
||
RandomID: randomID,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("sendMedia geolive: %v", err)
|
||
}
|
||
return newMessageFromUpdates(t, updates)
|
||
}
|
||
|
||
func TestSendMediaGeoLive(t *testing.T) {
|
||
r, owner, friend := newMediaTestRouter(t)
|
||
msg := sendTestLiveLocation(t, r, owner.ID, &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash}, 6001, 900)
|
||
media, ok := msg.Media.(*tg.MessageMediaGeoLive)
|
||
if !ok {
|
||
t.Fatalf("expected MessageMediaGeoLive, got %T", msg.Media)
|
||
}
|
||
if media.Period != 900 {
|
||
t.Errorf("period = %d, want 900", media.Period)
|
||
}
|
||
if heading, ok := media.GetHeading(); !ok || heading != 90 {
|
||
t.Errorf("heading = %d (%v), want 90", heading, ok)
|
||
}
|
||
geo, ok := media.Geo.(*tg.GeoPoint)
|
||
if !ok || geo.Lat != 39.9 || geo.Long != 116.4 {
|
||
t.Fatalf("geo = %#v, want (39.9, 116.4)", media.Geo)
|
||
}
|
||
}
|
||
|
||
func TestEditMessageLiveLocationUpdateAndStop(t *testing.T) {
|
||
ctx := context.Background()
|
||
r, owner, friend := newMediaTestRouter(t)
|
||
ownerPeer := &tg.InputPeerUser{UserID: friend.ID, AccessHash: friend.AccessHash}
|
||
ownerCtx := WithUserID(ctx, owner.ID)
|
||
|
||
msg := sendTestLiveLocation(t, r, owner.ID, ownerPeer, 6002, 3600)
|
||
|
||
// 续报新坐标。
|
||
editReq := &tg.MessagesEditMessageRequest{Peer: ownerPeer, ID: msg.ID}
|
||
next := &tg.InputMediaGeoLive{GeoPoint: &tg.InputGeoPoint{Lat: 40.0, Long: 116.5}}
|
||
next.SetHeading(180)
|
||
editReq.SetMedia(next)
|
||
updates, err := r.onMessagesEditMessage(ownerCtx, editReq)
|
||
if err != nil {
|
||
t.Fatalf("editMessage live update: %v", err)
|
||
}
|
||
edited := editedMessageFromUpdates(t, updates)
|
||
live, ok := edited.Media.(*tg.MessageMediaGeoLive)
|
||
if !ok {
|
||
t.Fatalf("expected MessageMediaGeoLive after edit, got %T", edited.Media)
|
||
}
|
||
geo := live.Geo.(*tg.GeoPoint)
|
||
if geo.Lat != 40.0 || geo.Long != 116.5 {
|
||
t.Fatalf("edited geo = (%v, %v), want (40.0, 116.5)", geo.Lat, geo.Long)
|
||
}
|
||
if heading, ok := live.GetHeading(); !ok || heading != 180 {
|
||
t.Fatalf("edited heading = %d (%v), want 180", heading, ok)
|
||
}
|
||
if live.Period != 3600 {
|
||
t.Fatalf("edited period = %d, want preserved 3600", live.Period)
|
||
}
|
||
|
||
// 停止共享:period 收口为已逝时长(≤ 原 period 且 ≥1),客户端立即判定过期。
|
||
stopReq := &tg.MessagesEditMessageRequest{Peer: ownerPeer, ID: msg.ID}
|
||
stopped := &tg.InputMediaGeoLive{GeoPoint: &tg.InputGeoPointEmpty{}, Stopped: true}
|
||
stopReq.SetMedia(stopped)
|
||
updates, err = r.onMessagesEditMessage(ownerCtx, stopReq)
|
||
if err != nil {
|
||
t.Fatalf("editMessage live stop: %v", err)
|
||
}
|
||
edited = editedMessageFromUpdates(t, updates)
|
||
live, ok = edited.Media.(*tg.MessageMediaGeoLive)
|
||
if !ok {
|
||
t.Fatalf("expected MessageMediaGeoLive after stop, got %T", edited.Media)
|
||
}
|
||
if live.Period < 1 || live.Period > 60 {
|
||
t.Fatalf("stopped period = %d, want small elapsed value", live.Period)
|
||
}
|
||
|
||
// 非 geolive 消息不可走 live 编辑。
|
||
plain, err := r.onMessagesSendMessage(ownerCtx, &tg.MessagesSendMessageRequest{
|
||
Peer: ownerPeer, Message: "hello", RandomID: 6003,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("send plain: %v", err)
|
||
}
|
||
plainMsg := newMessageFromUpdates(t, plain)
|
||
badReq := &tg.MessagesEditMessageRequest{Peer: ownerPeer, ID: plainMsg.ID}
|
||
badReq.SetMedia(&tg.InputMediaGeoLive{GeoPoint: &tg.InputGeoPoint{Lat: 1, Long: 1}})
|
||
if _, err := r.onMessagesEditMessage(ownerCtx, badReq); err == nil || !tgerr.Is(err, "MESSAGE_ID_INVALID") {
|
||
t.Fatalf("live edit on text message err = %v, want MESSAGE_ID_INVALID", err)
|
||
}
|
||
}
|
||
|
||
func editedMessageFromUpdates(t *testing.T, updates tg.UpdatesClass) *tg.Message {
|
||
t.Helper()
|
||
upd, ok := updates.(*tg.Updates)
|
||
if !ok {
|
||
t.Fatalf("expected *tg.Updates, got %T", updates)
|
||
}
|
||
for _, u := range upd.Updates {
|
||
if em, ok := u.(*tg.UpdateEditMessage); ok {
|
||
msg, ok := em.Message.(*tg.Message)
|
||
if !ok {
|
||
t.Fatalf("expected *tg.Message, got %T", em.Message)
|
||
}
|
||
return msg
|
||
}
|
||
}
|
||
t.Fatal("no updateEditMessage found")
|
||
return nil
|
||
}
|