feat: sync group call livestream support
This commit is contained in:
parent
56d995474c
commit
f1a27996d3
37 changed files with 2219 additions and 83 deletions
113
internal/rpc/phone_group_call_joinas_test.go
Normal file
113
internal/rpc/phone_group_call_joinas_test.go
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gotd/td/tg"
|
||||
)
|
||||
|
||||
// TestGroupCallJoinAsChannel 覆盖 join_as 身份闭环:admin 以频道身份入会 →
|
||||
// 参与者行 peer=PeerChannel(本人与对端视角一致);非 admin 以频道身份被拒;
|
||||
// getGroupCallJoinAs 对 admin 返回 self+频道两个候选、普通成员只返回 self。
|
||||
func TestGroupCallJoinAsChannel(t *testing.T) {
|
||||
f := newGroupCallFixture(t)
|
||||
ownerCtx := f.userCtx(f.owner, 11)
|
||||
memberCtx := f.userCtx(f.member, 22)
|
||||
channelPeer := &tg.InputPeerChannel{ChannelID: f.channel.ID, AccessHash: f.channel.AccessHash}
|
||||
|
||||
// --- getGroupCallJoinAs 候选 ---
|
||||
ownerJoinAs, err := f.router.onPhoneGetGroupCallJoinAs(ownerCtx, channelPeer)
|
||||
if err != nil {
|
||||
t.Fatalf("owner getGroupCallJoinAs: %v", err)
|
||||
}
|
||||
if len(ownerJoinAs.Peers) != 2 {
|
||||
t.Fatalf("owner join-as peers = %d, want 2 (self + channel): %+v", len(ownerJoinAs.Peers), ownerJoinAs.Peers)
|
||||
}
|
||||
if _, ok := ownerJoinAs.Peers[1].(*tg.PeerChannel); !ok {
|
||||
t.Fatalf("owner join-as second peer = %T, want PeerChannel", ownerJoinAs.Peers[1])
|
||||
}
|
||||
memberJoinAs, err := f.router.onPhoneGetGroupCallJoinAs(memberCtx, channelPeer)
|
||||
if err != nil {
|
||||
t.Fatalf("member getGroupCallJoinAs: %v", err)
|
||||
}
|
||||
if len(memberJoinAs.Peers) != 1 {
|
||||
t.Fatalf("member join-as peers = %d, want 1 (self only)", len(memberJoinAs.Peers))
|
||||
}
|
||||
|
||||
// --- create + owner 以频道身份 join ---
|
||||
createRes, err := f.router.onPhoneCreateGroupCall(ownerCtx, &tg.PhoneCreateGroupCallRequest{
|
||||
Peer: channelPeer, RandomID: 1,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("createGroupCall: %v", err)
|
||||
}
|
||||
call := findUpdate[*tg.UpdateGroupCall](t, createRes).Call.(*tg.GroupCall)
|
||||
input := &tg.InputGroupCall{ID: call.ID, AccessHash: call.AccessHash}
|
||||
|
||||
joinRes, err := f.router.onPhoneJoinGroupCall(ownerCtx, &tg.PhoneJoinGroupCallRequest{
|
||||
Call: input,
|
||||
JoinAs: channelPeer,
|
||||
Params: groupCallJoinParams(t, 8001),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("owner joinGroupCall(join_as=channel): %v", err)
|
||||
}
|
||||
participants := findUpdate[*tg.UpdateGroupCallParticipants](t, joinRes)
|
||||
if len(participants.Participants) != 1 {
|
||||
t.Fatalf("participants = %d, want 1", len(participants.Participants))
|
||||
}
|
||||
self := participants.Participants[0]
|
||||
peerCh, ok := self.Peer.(*tg.PeerChannel)
|
||||
if !ok || peerCh.ChannelID != f.channel.ID {
|
||||
t.Fatalf("self participant peer = %#v, want PeerChannel(%d)", self.Peer, f.channel.ID)
|
||||
}
|
||||
if !self.Self {
|
||||
t.Fatalf("join_as channel row missing self flag for the joining user")
|
||||
}
|
||||
|
||||
// --- 对端视角:member 拉参与者列表也看到频道身份 ---
|
||||
page, err := f.router.onPhoneGetGroupParticipants(memberCtx, &tg.PhoneGetGroupParticipantsRequest{
|
||||
Call: input, Limit: 10,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("member getGroupParticipants: %v", err)
|
||||
}
|
||||
if len(page.Participants) != 1 {
|
||||
t.Fatalf("member sees %d participants, want 1", len(page.Participants))
|
||||
}
|
||||
if pc, ok := page.Participants[0].Peer.(*tg.PeerChannel); !ok || pc.ChannelID != f.channel.ID {
|
||||
t.Fatalf("member view participant peer = %#v, want PeerChannel(%d)", page.Participants[0].Peer, f.channel.ID)
|
||||
}
|
||||
if page.Participants[0].Self {
|
||||
t.Fatalf("member view incorrectly flags channel row as self")
|
||||
}
|
||||
|
||||
// --- 非 admin 以频道身份 join 被拒 ---
|
||||
if _, err := f.router.onPhoneJoinGroupCall(memberCtx, &tg.PhoneJoinGroupCallRequest{
|
||||
Call: input,
|
||||
JoinAs: channelPeer,
|
||||
Params: groupCallJoinParams(t, 8002),
|
||||
}); err == nil {
|
||||
t.Fatalf("non-admin joined as channel")
|
||||
} else {
|
||||
assertPhoneRPCErr(t, err, "JOIN_AS_PEER_INVALID")
|
||||
}
|
||||
|
||||
// --- rejoin 换回本人身份:行替换而非新增 ---
|
||||
rejoinRes, err := f.router.onPhoneJoinGroupCall(ownerCtx, &tg.PhoneJoinGroupCallRequest{
|
||||
Call: input,
|
||||
JoinAs: &tg.InputPeerSelf{},
|
||||
Params: groupCallJoinParams(t, 8003),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("owner rejoin as self: %v", err)
|
||||
}
|
||||
rejoined := findUpdate[*tg.UpdateGroupCallParticipants](t, rejoinRes).Participants[0]
|
||||
if _, ok := rejoined.Peer.(*tg.PeerUser); !ok {
|
||||
t.Fatalf("rejoin-as-self participant peer = %#v, want PeerUser", rejoined.Peer)
|
||||
}
|
||||
page2, _ := f.router.onPhoneGetGroupParticipants(memberCtx, &tg.PhoneGetGroupParticipantsRequest{Call: input, Limit: 10})
|
||||
if len(page2.Participants) != 1 {
|
||||
t.Fatalf("after identity switch participants = %d, want 1 (replace not add)", len(page2.Participants))
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue