2026-05-02 13:02:38 +08:00

64 lines
2.1 KiB
Go

package grpc
import (
"context"
"testing"
"time"
roomv1 "hyapp.local/api/proto/room/v1"
walletv1 "hyapp.local/api/proto/wallet/v1"
"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"
"google.golang.org/grpc/codes"
grpcstatus "google.golang.org/grpc/status"
)
// fakeWallet 只满足 room-service 构造依赖;本测试走参数校验失败分支,不触发扣费。
type fakeWallet struct{}
// DebitGift 返回固定结果,避免 transport 测试依赖 wallet-service 进程。
func (fakeWallet) DebitGift(context.Context, *walletv1.DebitGiftRequest) (*walletv1.DebitGiftResponse, error) {
return &walletv1.DebitGiftResponse{BillingReceiptId: "receipt-test"}, nil
}
// newTransportTestServer 构造完整领域服务,确保测试覆盖真实 service -> transport 错误边界。
func newTransportTestServer(t *testing.T) *Server {
t.Helper()
svc := roomservice.New(roomservice.Config{
NodeID: "node-transport-test",
LeaseTTL: 10 * time.Second,
RankLimit: 20,
SnapshotEveryN: 1,
}, router.NewMemoryDirectory(), mysqltest.NewRepository(t), fakeWallet{}, integration.NewNoopRoomEventPublisher(), integration.NewNoopOutboxPublisher())
return NewServer(svc)
}
func TestCreateRoomMapsDomainErrorToGRPCReason(t *testing.T) {
server := newTransportTestServer(t)
_, err := server.CreateRoom(context.Background(), &roomv1.CreateRoomRequest{
// room_id 缺失属于客户端参数错误,不能在 gRPC 边界丢失 reason 后变成 INTERNAL_ERROR。
SeatCount: 8,
Mode: "voice",
})
if err == nil {
t.Fatalf("CreateRoom without room_id should fail")
}
if got := grpcstatus.Code(err); got != codes.InvalidArgument {
t.Fatalf("gRPC code mismatch: got %s", got)
}
if got := xerr.ReasonFromGRPC(err); got != xerr.InvalidArgument {
t.Fatalf("reason mismatch: got %s", got)
}
if message := grpcstatus.Convert(err).Message(); message != "room_id is required" {
t.Fatalf("message mismatch: got %q", message)
}
}