2026-06-04 18:31:06 +08:00

128 lines
4.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"
)
func TestRoomPasswordControlsJoinAndListLockedFlag(t *testing.T) {
ctx := context.Background()
repository := mysqltest.NewRepository(t)
svc := roomservice.New(roomservice.Config{
NodeID: "node-lock-test",
LeaseTTL: 10 * time.Second,
RankLimit: 20,
SnapshotEveryN: 1,
}, router.NewMemoryDirectory(), repository, followTestWallet{}, integration.NewNoopRoomEventPublisher(), integration.NewNoopOutboxPublisher())
roomID := "room-lock-flow"
ownerID := int64(5101)
viewerID := int64(5201)
if _, err := svc.CreateRoom(ctx, &roomv1.CreateRoomRequest{
Meta: roomservice.NewRequestMeta(roomID, ownerID),
SeatCount: 10,
Mode: "voice",
VisibleRegionId: 6101,
RoomName: "Locked Room",
RoomShortId: "lock-flow",
}); err != nil {
t.Fatalf("create locked room fixture failed: %v", err)
}
lockMeta := roomservice.NewRequestMeta(roomID, ownerID)
lockResp, err := svc.SetRoomPassword(ctx, &roomv1.SetRoomPasswordRequest{
Meta: lockMeta,
Locked: true,
Password: "1234",
})
if err != nil {
t.Fatalf("set room password failed: %v", err)
}
if _, err := svc.SetRoomPassword(ctx, &roomv1.SetRoomPasswordRequest{
Meta: lockMeta,
Locked: true,
Password: "1234",
}); err != nil {
t.Fatalf("same command id and same password should be idempotent: %v", err)
}
if _, err := svc.SetRoomPassword(ctx, &roomv1.SetRoomPasswordRequest{
Meta: lockMeta,
Locked: true,
Password: "9999",
}); err == nil {
t.Fatalf("same command id must reject a different room password")
}
if !lockResp.GetRoom().GetLocked() {
t.Fatalf("password response must expose locked snapshot: %+v", lockResp.GetRoom())
}
meta, exists, err := repository.GetRoomMeta(ctx, roomID)
if err != nil || !exists || meta.RoomPasswordHash == "" || meta.RoomPasswordHash == "1234" {
t.Fatalf("room meta must persist only password hash: meta=%+v exists=%t err=%v", meta, exists, err)
}
listResp, err := svc.ListRooms(ctx, &roomv1.ListRoomsRequest{
Meta: &roomv1.RequestMeta{AppCode: appcode.Default},
ViewerUserId: viewerID,
VisibleRegionId: 6101,
Tab: "hot",
Limit: 20,
Query: "lock-flow",
})
if err != nil {
t.Fatalf("list locked room failed: %v", err)
}
if len(listResp.GetRooms()) != 1 || !listResp.GetRooms()[0].GetLocked() {
t.Fatalf("list/search must return locked flag: %+v", listResp.GetRooms())
}
if _, err := svc.JoinRoom(ctx, &roomv1.JoinRoomRequest{
Meta: roomservice.NewRequestMeta(roomID, viewerID),
Role: "audience",
Password: "wrong",
}); err == nil {
t.Fatalf("wrong password must not join locked room")
}
joinResp, err := svc.JoinRoom(ctx, &roomv1.JoinRoomRequest{
Meta: roomservice.NewRequestMeta(roomID, viewerID),
Role: "audience",
Password: "1234",
})
if err != nil {
t.Fatalf("correct password should join locked room: %v", err)
}
if joinResp.GetUser().GetUserId() != viewerID || !joinResp.GetRoom().GetLocked() {
t.Fatalf("join response mismatch: user=%+v room=%+v", joinResp.GetUser(), joinResp.GetRoom())
}
if _, err := svc.SetRoomPassword(ctx, &roomv1.SetRoomPasswordRequest{
Meta: roomservice.NewRequestMeta(roomID, ownerID),
Locked: true,
Password: "5678",
}); err != nil {
t.Fatalf("change room password after viewer joined failed: %v", err)
}
if _, err := svc.JoinRoom(ctx, &roomv1.JoinRoomRequest{
Meta: roomservice.NewRequestMeta(roomID, viewerID),
Role: "audience",
Password: "1234",
}); err == nil {
t.Fatalf("existing online user must not bypass changed room password")
}
if _, err := svc.JoinRoom(ctx, &roomv1.JoinRoomRequest{
Meta: roomservice.NewRequestMeta(roomID, viewerID),
Role: "audience",
Password: "5678",
}); err != nil {
t.Fatalf("existing online user should reconnect with latest room password: %v", err)
}
}