156 lines
5.4 KiB
Go
156 lines
5.4 KiB
Go
package service_test
|
||
|
||
import (
|
||
"context"
|
||
"testing"
|
||
"time"
|
||
|
||
roomv1 "hyapp.local/api/proto/room/v1"
|
||
walletv1 "hyapp.local/api/proto/wallet/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 followTestWallet struct{}
|
||
|
||
func (followTestWallet) DebitGift(context.Context, *walletv1.DebitGiftRequest) (*walletv1.DebitGiftResponse, error) {
|
||
return &walletv1.DebitGiftResponse{BillingReceiptId: "receipt-follow-test"}, nil
|
||
}
|
||
|
||
func (followTestWallet) BatchDebitGift(context.Context, *walletv1.BatchDebitGiftRequest) (*walletv1.BatchDebitGiftResponse, error) {
|
||
return &walletv1.BatchDebitGiftResponse{Aggregate: &walletv1.DebitGiftResponse{BillingReceiptId: "receipt-follow-test"}}, nil
|
||
}
|
||
|
||
func (followTestWallet) DebitRobotGift(context.Context, *walletv1.DebitRobotGiftRequest) (*walletv1.DebitGiftResponse, error) {
|
||
return &walletv1.DebitGiftResponse{BillingReceiptId: "receipt-robot-follow-test"}, nil
|
||
}
|
||
|
||
func (followTestWallet) GrantResourceGroup(context.Context, *walletv1.GrantResourceGroupRequest) (*walletv1.ResourceGrantResponse, error) {
|
||
return &walletv1.ResourceGrantResponse{Grant: &walletv1.ResourceGrant{GrantId: "grant-follow-test"}}, nil
|
||
}
|
||
|
||
func (followTestWallet) GetMyVip(_ context.Context, req *walletv1.GetMyVipRequest) (*walletv1.GetMyVipResponse, error) {
|
||
return legacyVIPResponse(req.GetUserId()), nil
|
||
}
|
||
|
||
func legacyVIPResponse(userID int64) *walletv1.GetMyVipResponse {
|
||
// 大多数既有 room-service 测试运行在 Lalu;显式返回 legacy program,验证新增门禁不会暗改旧 App 行为。
|
||
return &walletv1.GetMyVipResponse{
|
||
State: &walletv1.VipState{
|
||
ProgramConfig: &walletv1.VipProgramConfig{AppCode: appcode.Default, ProgramType: "legacy_timed", Status: "active"},
|
||
EffectiveVip: &walletv1.UserVip{UserId: userID},
|
||
},
|
||
}
|
||
}
|
||
|
||
func TestRoomFollowAffectsSnapshotAndFollowedFeed(t *testing.T) {
|
||
ctx := context.Background()
|
||
repository := mysqltest.NewRepository(t)
|
||
svc := roomservice.New(roomservice.Config{
|
||
NodeID: "node-follow-test",
|
||
LeaseTTL: 10 * time.Second,
|
||
RankLimit: 20,
|
||
SnapshotEveryN: 1,
|
||
}, router.NewMemoryDirectory(), repository, followTestWallet{}, integration.NewNoopRoomEventPublisher(), integration.NewNoopOutboxPublisher())
|
||
|
||
roomID := "room-follow-flow"
|
||
ownerID := int64(1001)
|
||
viewerID := int64(2002)
|
||
if _, err := svc.CreateRoom(ctx, &roomv1.CreateRoomRequest{
|
||
Meta: roomservice.NewRequestMeta(roomID, ownerID),
|
||
SeatCount: 10,
|
||
Mode: "voice",
|
||
VisibleRegionId: 1001,
|
||
RoomName: "Follow Flow",
|
||
RoomAvatar: testRoomCoverURL,
|
||
RoomShortId: "follow-flow",
|
||
}); err != nil {
|
||
t.Fatalf("create room failed: %v", err)
|
||
}
|
||
if _, err := svc.JoinRoom(ctx, &roomv1.JoinRoomRequest{
|
||
Meta: roomservice.NewRequestMeta(roomID, viewerID),
|
||
Role: "audience",
|
||
}); err != nil {
|
||
t.Fatalf("join room failed: %v", err)
|
||
}
|
||
|
||
beforeFollow, err := svc.GetRoomSnapshot(ctx, &roomv1.GetRoomSnapshotRequest{
|
||
Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID},
|
||
RoomId: roomID,
|
||
ViewerUserId: viewerID,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("snapshot before follow failed: %v", err)
|
||
}
|
||
if beforeFollow.GetIsFollowed() {
|
||
t.Fatalf("new viewer must not be followed before FollowRoom")
|
||
}
|
||
|
||
followResp, err := svc.FollowRoom(ctx, &roomv1.FollowRoomRequest{
|
||
Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID},
|
||
RoomId: roomID,
|
||
UserId: viewerID,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("follow room failed: %v", err)
|
||
}
|
||
if !followResp.GetFollowed() || followResp.GetFollowedAtMs() <= 0 {
|
||
t.Fatalf("follow response mismatch: %+v", followResp)
|
||
}
|
||
|
||
afterFollow, err := svc.GetRoomSnapshot(ctx, &roomv1.GetRoomSnapshotRequest{
|
||
Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID},
|
||
RoomId: roomID,
|
||
ViewerUserId: viewerID,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("snapshot after follow failed: %v", err)
|
||
}
|
||
if !afterFollow.GetIsFollowed() {
|
||
t.Fatalf("snapshot must expose is_followed=true after FollowRoom")
|
||
}
|
||
|
||
feedResp, err := svc.ListRoomFeeds(ctx, &roomv1.ListRoomFeedsRequest{
|
||
Meta: &roomv1.RequestMeta{AppCode: appcode.Default},
|
||
ViewerUserId: viewerID,
|
||
VisibleRegionId: 1001,
|
||
Tab: "followed",
|
||
Limit: 20,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("followed feed failed: %v", err)
|
||
}
|
||
if len(feedResp.GetRooms()) != 1 || feedResp.GetRooms()[0].GetRoomId() != roomID {
|
||
t.Fatalf("followed feed must return followed room: %+v", feedResp.GetRooms())
|
||
}
|
||
|
||
unfollowResp, err := svc.UnfollowRoom(ctx, &roomv1.UnfollowRoomRequest{
|
||
Meta: &roomv1.RequestMeta{AppCode: appcode.Default, RoomId: roomID},
|
||
RoomId: roomID,
|
||
UserId: viewerID,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("unfollow room failed: %v", err)
|
||
}
|
||
if unfollowResp.GetFollowed() {
|
||
t.Fatalf("unfollow response mismatch: %+v", unfollowResp)
|
||
}
|
||
|
||
emptyFeedResp, err := svc.ListRoomFeeds(ctx, &roomv1.ListRoomFeedsRequest{
|
||
Meta: &roomv1.RequestMeta{AppCode: appcode.Default},
|
||
ViewerUserId: viewerID,
|
||
VisibleRegionId: 1001,
|
||
Tab: "followed",
|
||
Limit: 20,
|
||
})
|
||
if err != nil {
|
||
t.Fatalf("followed feed after unfollow failed: %v", err)
|
||
}
|
||
if len(emptyFeedResp.GetRooms()) != 0 {
|
||
t.Fatalf("followed feed must be empty after UnfollowRoom: %+v", emptyFeedResp.GetRooms())
|
||
}
|
||
}
|