101 lines
3.3 KiB
Go
101 lines
3.3 KiB
Go
package gift
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"hyapp/pkg/xerr"
|
|
"hyapp/services/wallet-service/internal/domain/ledger"
|
|
)
|
|
|
|
type fakeGiftLedgerStore struct {
|
|
debitCalls int
|
|
batchCalls int
|
|
lastDebit ledger.DebitGiftCommand
|
|
}
|
|
|
|
func (f *fakeGiftLedgerStore) DebitGift(_ context.Context, command ledger.DebitGiftCommand) (ledger.Receipt, error) {
|
|
f.debitCalls++
|
|
f.lastDebit = command
|
|
return ledger.Receipt{TransactionID: "tx-direct"}, nil
|
|
}
|
|
|
|
func (f *fakeGiftLedgerStore) BatchDebitGift(_ context.Context, _ ledger.BatchDebitGiftCommand) (ledger.BatchGiftReceipt, error) {
|
|
f.batchCalls++
|
|
return ledger.BatchGiftReceipt{}, nil
|
|
}
|
|
|
|
func TestDebitGiftAllowsDirectGiftWithoutRoomID(t *testing.T) {
|
|
store := &fakeGiftLedgerStore{}
|
|
svc := New(store)
|
|
|
|
_, err := svc.DebitGift(context.Background(), ledger.DebitGiftCommand{
|
|
AppCode: "lalu",
|
|
CommandID: "cmd-direct-gift",
|
|
DirectGift: true,
|
|
SenderUserID: 10001,
|
|
TargetUserID: 10002,
|
|
GiftID: "rose",
|
|
GiftCount: 1,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("direct gift without room_id must reach repository: %v", err)
|
|
}
|
|
if store.debitCalls != 1 || !store.lastDebit.DirectGift || store.lastDebit.RoomID != "" {
|
|
t.Fatalf("direct gift command was not preserved: calls=%d command=%+v", store.debitCalls, store.lastDebit)
|
|
}
|
|
}
|
|
|
|
func TestDebitGiftRejectsOversizedCountAndCommandIDBeforeRepository(t *testing.T) {
|
|
for _, command := range []ledger.DebitGiftCommand{
|
|
{AppCode: "lalu", CommandID: "cmd-too-many", RoomID: "room-1", SenderUserID: 1, TargetUserID: 2, GiftID: "rose", GiftCount: 1_000},
|
|
{AppCode: "lalu", CommandID: strings.Repeat("x", 129), RoomID: "room-1", SenderUserID: 1, TargetUserID: 2, GiftID: "rose", GiftCount: 1},
|
|
} {
|
|
store := &fakeGiftLedgerStore{}
|
|
if _, err := New(store).DebitGift(context.Background(), command); !xerr.IsCode(err, xerr.InvalidArgument) || store.debitCalls != 0 {
|
|
t.Fatalf("invalid command reached wallet repository: command=%+v err=%v calls=%d", command, err, store.debitCalls)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBatchDebitGiftRejectsCountTimesTargetsAboveHardLimit(t *testing.T) {
|
|
targets := make([]ledger.DebitGiftTargetCommand, 0, 6)
|
|
for userID := int64(1); userID <= 6; userID++ {
|
|
targets = append(targets, ledger.DebitGiftTargetCommand{CommandID: "target-" + string(rune('0'+userID)), TargetUserID: userID})
|
|
}
|
|
store := &fakeGiftLedgerStore{}
|
|
_, err := New(store).BatchDebitGift(context.Background(), ledger.BatchDebitGiftCommand{
|
|
AppCode: "lalu",
|
|
CommandID: "batch-too-large",
|
|
RoomID: "room-1",
|
|
SenderUserID: 100,
|
|
GiftID: "rose",
|
|
GiftCount: 999,
|
|
Targets: targets,
|
|
})
|
|
if !xerr.IsCode(err, xerr.InvalidArgument) || store.batchCalls != 0 {
|
|
t.Fatalf("oversized batch reached wallet repository: err=%v calls=%d", err, store.batchCalls)
|
|
}
|
|
}
|
|
|
|
func TestDebitGiftRequiresRoomIDForRoomGift(t *testing.T) {
|
|
store := &fakeGiftLedgerStore{}
|
|
svc := New(store)
|
|
|
|
_, err := svc.DebitGift(context.Background(), ledger.DebitGiftCommand{
|
|
AppCode: "lalu",
|
|
CommandID: "cmd-room-gift",
|
|
SenderUserID: 10001,
|
|
TargetUserID: 10002,
|
|
GiftID: "rose",
|
|
GiftCount: 1,
|
|
})
|
|
if !xerr.IsCode(err, xerr.InvalidArgument) {
|
|
t.Fatalf("room gift without room_id must be invalid argument, got %v", err)
|
|
}
|
|
if store.debitCalls != 0 {
|
|
t.Fatalf("invalid room gift must not reach repository, calls=%d", store.debitCalls)
|
|
}
|
|
}
|