109 lines
3.2 KiB
Go
109 lines
3.2 KiB
Go
package service_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
roomv1 "hyapp.local/api/proto/room/v1"
|
|
"hyapp/pkg/appcode"
|
|
"hyapp/services/room-service/internal/integration"
|
|
roomservice "hyapp/services/room-service/internal/room/service"
|
|
"hyapp/services/room-service/internal/router"
|
|
"hyapp/services/room-service/internal/testutil/mysqltest"
|
|
)
|
|
|
|
type fakeRTCUserRemover struct {
|
|
roomID string
|
|
userID int64
|
|
}
|
|
|
|
func (r *fakeRTCUserRemover) RemoveUserByStrRoomID(_ context.Context, roomID string, userID int64) error {
|
|
r.roomID = roomID
|
|
r.userID = userID
|
|
return nil
|
|
}
|
|
|
|
func TestKickUserRemovesPresenceBanAndRTCConnection(t *testing.T) {
|
|
ctx := context.Background()
|
|
repository := mysqltest.NewRepository(t)
|
|
rtc := &fakeRTCUserRemover{}
|
|
svc := roomservice.New(roomservice.Config{
|
|
NodeID: "node-kick-test",
|
|
LeaseTTL: 10 * time.Second,
|
|
RankLimit: 20,
|
|
SnapshotEveryN: 1,
|
|
RTCUserRemover: rtc,
|
|
}, router.NewMemoryDirectory(), repository, followTestWallet{}, integration.NewNoopRoomEventPublisher(), integration.NewNoopOutboxPublisher())
|
|
|
|
roomID := "room-kick-flow"
|
|
ownerID := int64(7101)
|
|
viewerID := int64(7201)
|
|
if _, err := svc.CreateRoom(ctx, &roomv1.CreateRoomRequest{
|
|
Meta: roomservice.NewRequestMeta(roomID, ownerID),
|
|
SeatCount: 10,
|
|
Mode: "voice",
|
|
VisibleRegionId: 8101,
|
|
RoomName: "Kick Flow",
|
|
RoomShortId: "kick-flow",
|
|
}); err != nil {
|
|
t.Fatalf("create kick room fixture failed: %v", err)
|
|
}
|
|
if _, err := svc.JoinRoom(ctx, &roomv1.JoinRoomRequest{
|
|
Meta: roomservice.NewRequestMeta(roomID, viewerID),
|
|
Role: "audience",
|
|
}); err != nil {
|
|
t.Fatalf("join kick target failed: %v", err)
|
|
}
|
|
|
|
kickResp, err := svc.KickUser(ctx, &roomv1.KickUserRequest{
|
|
Meta: roomservice.NewRequestMeta(roomID, ownerID),
|
|
TargetUserId: viewerID,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("kick user failed: %v", err)
|
|
}
|
|
if !kickResp.GetRtcKicked() || kickResp.GetRtcKickError() != "" || rtc.roomID != roomID || rtc.userID != viewerID {
|
|
t.Fatalf("kick must remove RTC user after Room Cell commit: resp=%+v rtc=%+v", kickResp, rtc)
|
|
}
|
|
if !containsInt64(kickResp.GetRoom().GetBanUserIds(), viewerID) || findRoomUser(kickResp.GetRoom(), viewerID) != nil {
|
|
t.Fatalf("kick response must ban and remove target presence: %+v", kickResp.GetRoom())
|
|
}
|
|
|
|
presenceResp, err := svc.VerifyRoomPresence(ctx, &roomv1.VerifyRoomPresenceRequest{
|
|
AppCode: appcode.Default,
|
|
RoomId: roomID,
|
|
UserId: viewerID,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("verify room presence after kick failed: %v", err)
|
|
}
|
|
if presenceResp.GetPresent() || presenceResp.GetReason() != "user_banned" {
|
|
t.Fatalf("kicked user must not pass IM presence guard: %+v", presenceResp)
|
|
}
|
|
if _, err := svc.JoinRoom(ctx, &roomv1.JoinRoomRequest{
|
|
Meta: roomservice.NewRequestMeta(roomID, viewerID),
|
|
Role: "audience",
|
|
}); err == nil {
|
|
t.Fatalf("kicked user must not join before unban")
|
|
}
|
|
}
|
|
|
|
func findRoomUser(snapshot *roomv1.RoomSnapshot, userID int64) *roomv1.RoomUser {
|
|
for _, user := range snapshot.GetOnlineUsers() {
|
|
if user.GetUserId() == userID {
|
|
return user
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func containsInt64(values []int64, target int64) bool {
|
|
for _, value := range values {
|
|
if value == target {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|