package service_test import ( "context" "testing" "time" roomv1 "hyapp.local/api/proto/room/v1" "hyapp/pkg/appcode" "hyapp/pkg/xerr" "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 TestRoomBackgroundSaveListSetFlow(t *testing.T) { ctx := context.Background() repository := mysqltest.NewRepository(t) svc := roomservice.New(roomservice.Config{ NodeID: "node-room-background-test", LeaseTTL: 10 * time.Second, RankLimit: 20, SnapshotEveryN: 1, }, router.NewMemoryDirectory(), repository, followTestWallet{}, integration.NewNoopRoomEventPublisher(), integration.NewNoopOutboxPublisher()) roomID := "room-background-flow" ownerID := int64(7101) if _, err := svc.CreateRoom(ctx, &roomv1.CreateRoomRequest{ Meta: roomservice.NewRequestMeta(roomID, ownerID), SeatCount: 10, Mode: "voice", VisibleRegionId: 1001, RoomName: "Background Flow", RoomAvatar: testRoomCoverURL, RoomShortId: "bg-flow", }); err != nil { t.Fatalf("create room failed: %v", err) } saveResp, err := svc.SaveRoomBackground(ctx, &roomv1.SaveRoomBackgroundRequest{ Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID, ActorUserId: ownerID}, RoomId: roomID, ImageUrl: " https://cdn.example.com/room-bg.png ", }) if err != nil { t.Fatalf("save background failed: %v", err) } if saveResp.GetBackground().GetBackgroundId() <= 0 || saveResp.GetBackground().GetImageUrl() != "https://cdn.example.com/room-bg.png" { t.Fatalf("save response mismatch: %+v", saveResp.GetBackground()) } listResp, err := svc.ListRoomBackgrounds(ctx, &roomv1.ListRoomBackgroundsRequest{ Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID}, RoomId: roomID, ViewerUserId: ownerID, }) if err != nil { t.Fatalf("list backgrounds failed: %v", err) } if len(listResp.GetBackgrounds()) != 1 || listResp.GetSelectedBackgroundUrl() != "" { t.Fatalf("list response before set mismatch: %+v", listResp) } setResp, err := svc.SetRoomBackground(ctx, &roomv1.SetRoomBackgroundRequest{ Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID, ActorUserId: ownerID, CommandId: "cmd-room-bg-set"}, BackgroundId: saveResp.GetBackground().GetBackgroundId(), }) if err != nil { t.Fatalf("set background failed: %v", err) } if !setResp.GetResult().GetApplied() || setResp.GetRoom().GetRoomExt()["background_url"] != "https://cdn.example.com/room-bg.png" { t.Fatalf("set response mismatch: %+v", setResp) } snapshotResp, err := svc.GetRoomSnapshot(ctx, &roomv1.GetRoomSnapshotRequest{ Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID}, RoomId: roomID, ViewerUserId: ownerID, }) if err != nil { t.Fatalf("snapshot after set failed: %v", err) } if snapshotResp.GetRoom().GetRoomExt()["background_url"] != "https://cdn.example.com/room-bg.png" { t.Fatalf("snapshot must expose selected background_url: %+v", snapshotResp.GetRoom().GetRoomExt()) } } func TestRoomBackgroundOnlyOwnerCanEdit(t *testing.T) { ctx := context.Background() repository := mysqltest.NewRepository(t) svc := roomservice.New(roomservice.Config{ NodeID: "node-room-background-owner-test", LeaseTTL: 10 * time.Second, RankLimit: 20, SnapshotEveryN: 1, }, router.NewMemoryDirectory(), repository, followTestWallet{}, integration.NewNoopRoomEventPublisher(), integration.NewNoopOutboxPublisher()) roomID := "room-background-owner" ownerID := int64(7201) otherID := int64(7202) if _, err := svc.CreateRoom(ctx, &roomv1.CreateRoomRequest{ Meta: roomservice.NewRequestMeta(roomID, ownerID), SeatCount: 10, Mode: "voice", VisibleRegionId: 1001, RoomName: "Background Owner", RoomAvatar: testRoomCoverURL, RoomShortId: "bg-owner", }); err != nil { t.Fatalf("create room failed: %v", err) } if _, err := svc.SaveRoomBackground(ctx, &roomv1.SaveRoomBackgroundRequest{ Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID, ActorUserId: otherID}, RoomId: roomID, ImageUrl: "https://cdn.example.com/other-bg.png", }); !xerr.IsCode(err, xerr.PermissionDenied) { t.Fatalf("non-owner save must be denied: %v", err) } saveResp, err := svc.SaveRoomBackground(ctx, &roomv1.SaveRoomBackgroundRequest{ Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID, ActorUserId: ownerID}, RoomId: roomID, ImageUrl: "https://cdn.example.com/owner-bg.png", }) if err != nil { t.Fatalf("owner save background failed: %v", err) } if _, err := svc.SetRoomBackground(ctx, &roomv1.SetRoomBackgroundRequest{ Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID, ActorUserId: otherID, CommandId: "cmd-room-bg-other"}, BackgroundId: saveResp.GetBackground().GetBackgroundId(), }); !xerr.IsCode(err, xerr.PermissionDenied) { t.Fatalf("non-owner set must be denied: %v", err) } }