package luckygift import ( "context" "fmt" "strings" "testing" "hyapp/pkg/xerr" domain "hyapp/services/lucky-gift-service/internal/domain/luckygift" ) type batchLimitRepository struct { Repository batchCalls int } func (r *batchLimitRepository) ExecuteLuckyGiftDrawBatch(_ context.Context, cmds []domain.DrawCommand, _ int64) ([]domain.DrawResult, error) { r.batchCalls++ return make([]domain.DrawResult, len(cmds)), nil } func TestNormalizeDrawCommandRejectsOversizedInternalGiftWork(t *testing.T) { base := domain.DrawCommand{ CommandID: "cmd-lucky", UserID: 1, DeviceID: "device-1", RoomID: "room-1", AnchorID: "2", GiftID: "rose", GiftCount: 1, CoinSpent: 10, TargetUserID: 2, } svc := &Service{} oversizedCount := base oversizedCount.GiftCount = 1_000 if _, err := svc.normalizeDrawCommand(oversizedCount); err == nil { t.Fatal("gift_count above 999 was accepted") } oversizedID := base oversizedID.CommandID = strings.Repeat("x", 129) if _, err := svc.normalizeDrawCommand(oversizedID); err == nil { t.Fatal("command_id above 128 bytes was accepted") } } func TestDrawBatchRejectsAggregateWorkAcrossTargets(t *testing.T) { repository := &batchLimitRepository{} svc := New(repository) commands := make([]domain.DrawCommand, 0, 6) for index := 0; index < 6; index++ { commands = append(commands, domain.DrawCommand{ CommandID: fmt.Sprintf("cmd-lucky-target-%d", index), UserID: 1, TargetUserID: int64(index + 10), DeviceID: "device-1", RoomID: "room-1", AnchorID: "2", GiftID: "rose", GiftCount: 999, CoinSpent: 999, }) } if _, err := svc.DrawBatch(context.Background(), commands); !xerr.IsCode(err, xerr.InvalidArgument) { t.Fatalf("5994 aggregate draw units should be rejected, got %v", err) } if repository.batchCalls != 0 { t.Fatalf("oversized batch reached repository %d times", repository.batchCalls) } if _, err := svc.DrawBatch(context.Background(), commands[:5]); err != nil { t.Fatalf("4995 aggregate draw units should be accepted: %v", err) } if repository.batchCalls != 1 { t.Fatalf("accepted batch repository calls=%d, want 1", repository.batchCalls) } }