512 lines
17 KiB
Go
512 lines
17 KiB
Go
package voiceroomredpacket
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"chatapp3-golang/internal/config"
|
|
"chatapp3-golang/internal/integration"
|
|
"chatapp3-golang/internal/model"
|
|
|
|
"github.com/alicebob/miniredis/v2"
|
|
"github.com/redis/go-redis/v9"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
func TestSplitRandomAmountsKeepsTotalAndMinimum(t *testing.T) {
|
|
amounts, err := splitRandomAmounts(15000, 50, 1)
|
|
if err != nil {
|
|
t.Fatalf("splitRandomAmounts() error = %v", err)
|
|
}
|
|
if len(amounts) != 50 {
|
|
t.Fatalf("len(amounts) = %d, want 50", len(amounts))
|
|
}
|
|
if got := sumAmounts(amounts); got != 15000 {
|
|
t.Fatalf("sumAmounts() = %d, want 15000", got)
|
|
}
|
|
for _, amount := range amounts {
|
|
if amount <= 0 {
|
|
t.Fatalf("amount = %d, want > 0", amount)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSendAndClaimImmediatePacket(t *testing.T) {
|
|
service, wallet, _ := newVoiceRoomRedPacketTestService(t)
|
|
ctx := context.Background()
|
|
sender := AuthUser{UserID: 1001, SysOrigin: "LIKEI"}
|
|
claimer := AuthUser{UserID: 1002, SysOrigin: "LIKEI"}
|
|
|
|
if _, err := service.Heartbeat(ctx, sender, PresenceRequest{RoomID: 9001}); err != nil {
|
|
t.Fatalf("sender Heartbeat() error = %v", err)
|
|
}
|
|
if _, err := service.Heartbeat(ctx, claimer, PresenceRequest{RoomID: 9001}); err != nil {
|
|
t.Fatalf("claimer Heartbeat() error = %v", err)
|
|
}
|
|
sendResp, err := service.Send(ctx, sender, SendRequest{
|
|
RequestID: "req-send-1",
|
|
RoomID: 9001,
|
|
PacketMode: packetModeImmediate,
|
|
TotalAmount: 15000,
|
|
TotalCount: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Send() error = %v", err)
|
|
}
|
|
if sendResp.PacketNo == "" || sendResp.Status != packetStatusActive {
|
|
t.Fatalf("Send() response = %+v", sendResp)
|
|
}
|
|
claimResp, err := service.Claim(ctx, claimer, ClaimRequest{PacketNo: sendResp.PacketNo})
|
|
if err != nil {
|
|
t.Fatalf("Claim() error = %v", err)
|
|
}
|
|
if claimResp.Amount <= 0 || claimResp.RemainCount != 4 {
|
|
t.Fatalf("Claim() response = %+v", claimResp)
|
|
}
|
|
if wallet.balance[1001] != 85000 {
|
|
t.Fatalf("sender balance = %d, want 85000", wallet.balance[1001])
|
|
}
|
|
if wallet.balance[1002] != 100000+claimResp.Amount {
|
|
t.Fatalf("claimer balance = %d, want %d", wallet.balance[1002], 100000+claimResp.Amount)
|
|
}
|
|
|
|
repeated, err := service.Claim(ctx, claimer, ClaimRequest{PacketNo: sendResp.PacketNo})
|
|
if err != nil {
|
|
t.Fatalf("repeat Claim() error = %v", err)
|
|
}
|
|
if repeated.Amount != claimResp.Amount || repeated.RemainCount != claimResp.RemainCount {
|
|
t.Fatalf("repeat Claim() = %+v, want original %+v", repeated, claimResp)
|
|
}
|
|
assertWalletCommandsFitWalletSchema(t, wallet.calls)
|
|
if wallet.calls[0].CustomizeOriginDesc != walletOriginSendDesc {
|
|
t.Fatalf("send wallet desc = %q, want %q", wallet.calls[0].CustomizeOriginDesc, walletOriginSendDesc)
|
|
}
|
|
if wallet.calls[1].CustomizeOriginDesc != walletOriginClaimDesc {
|
|
t.Fatalf("claim wallet desc = %q, want %q", wallet.calls[1].CustomizeOriginDesc, walletOriginClaimDesc)
|
|
}
|
|
|
|
claimRecords, err := service.ListClaimRecords(ctx, sender, sendResp.PacketNo)
|
|
if err != nil {
|
|
t.Fatalf("ListClaimRecords() error = %v", err)
|
|
}
|
|
if claimRecords.PacketNo != sendResp.PacketNo ||
|
|
claimRecords.TotalCount != 5 ||
|
|
claimRecords.ClaimedCount != 1 ||
|
|
claimRecords.ClaimedAmount != claimResp.Amount {
|
|
t.Fatalf("ListClaimRecords() = %+v, claimResp = %+v", claimRecords, claimResp)
|
|
}
|
|
if len(claimRecords.Records) != 1 {
|
|
t.Fatalf("records len = %d, want 1", len(claimRecords.Records))
|
|
}
|
|
record := claimRecords.Records[0]
|
|
if record.UserID != claimer.UserID ||
|
|
record.Account != "1002" ||
|
|
record.UserNickname != "claimer" ||
|
|
record.UserAvatar != "claimer.png" ||
|
|
record.Amount != claimResp.Amount ||
|
|
record.ClaimTime == "" {
|
|
t.Fatalf("claim record = %+v, claimResp = %+v", record, claimResp)
|
|
}
|
|
}
|
|
|
|
func TestDelayedPacketRejectsEarlyClaim(t *testing.T) {
|
|
service, _, _ := newVoiceRoomRedPacketTestService(t)
|
|
ctx := context.Background()
|
|
sender := AuthUser{UserID: 1001, SysOrigin: "LIKEI"}
|
|
claimer := AuthUser{UserID: 1002, SysOrigin: "LIKEI"}
|
|
_, _ = service.Heartbeat(ctx, sender, PresenceRequest{RoomID: 9001})
|
|
_, _ = service.Heartbeat(ctx, claimer, PresenceRequest{RoomID: 9001})
|
|
|
|
sendResp, err := service.Send(ctx, sender, SendRequest{
|
|
RequestID: "req-delayed-1",
|
|
RoomID: 9001,
|
|
PacketMode: packetModeDelayed,
|
|
TotalAmount: 15000,
|
|
TotalCount: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Send() error = %v", err)
|
|
}
|
|
if _, err := service.Claim(ctx, claimer, ClaimRequest{PacketNo: sendResp.PacketNo}); err == nil {
|
|
t.Fatalf("Claim() error = nil, want not started")
|
|
}
|
|
}
|
|
|
|
func TestDelayedPacketSendsRegionIMBroadcastOnly(t *testing.T) {
|
|
service, _, _ := newVoiceRoomRedPacketTestService(t)
|
|
fakeRegionIM := &fakeRegionIMGateway{}
|
|
service.regionIM = fakeRegionIM
|
|
ctx := context.Background()
|
|
sender := AuthUser{UserID: 1001, SysOrigin: "LIKEI"}
|
|
if _, err := service.Heartbeat(ctx, sender, PresenceRequest{RoomID: 9001}); err != nil {
|
|
t.Fatalf("Heartbeat() error = %v", err)
|
|
}
|
|
sendResp, err := service.Send(ctx, sender, SendRequest{
|
|
RequestID: "req-delayed-im-1",
|
|
RoomID: 9001,
|
|
PacketMode: packetModeDelayed,
|
|
TotalAmount: 15000,
|
|
TotalCount: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Send() error = %v", err)
|
|
}
|
|
if len(fakeRegionIM.sent) != 1 {
|
|
t.Fatalf("sent messages = %+v, want one region message", fakeRegionIM.sent)
|
|
}
|
|
if fakeRegionIM.sent[0].sysOrigin != "LIKEI" || fakeRegionIM.sent[0].regionCode != "AR" {
|
|
t.Fatalf("sent target = %+v, want LIKEI/AR", fakeRegionIM.sent[0])
|
|
}
|
|
body, ok := fakeRegionIM.sent[0].body.(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("sent body type = %T", fakeRegionIM.sent[0].body)
|
|
}
|
|
if body["type"] != "ROOM_RED_PACKET" {
|
|
t.Fatalf("sent type = %v, want ROOM_RED_PACKET", body["type"])
|
|
}
|
|
data, ok := body["data"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("sent data type = %T", body["data"])
|
|
}
|
|
if data["roomId"] != "9001" || data["packetId"] != sendResp.PacketNo || data["regionCode"] != "AR" {
|
|
t.Fatalf("sent data = %+v", data)
|
|
}
|
|
}
|
|
|
|
func TestResolveUserRegionPrefersJavaRegionResolver(t *testing.T) {
|
|
service, _, _ := newVoiceRoomRedPacketTestService(t)
|
|
service.SetRegionResolver(fakeRegionResolver{
|
|
regions: map[string]string{"LIKEI|SA": "中东区"},
|
|
})
|
|
fakeRegionIM := &fakeRegionIMGateway{}
|
|
service.regionIM = fakeRegionIM
|
|
ctx := context.Background()
|
|
sender := AuthUser{UserID: 1001, SysOrigin: "LIKEI"}
|
|
presence, err := service.Heartbeat(ctx, sender, PresenceRequest{RoomID: 9001})
|
|
if err != nil {
|
|
t.Fatalf("Heartbeat() error = %v", err)
|
|
}
|
|
if presence.RegionCode != "中东区" {
|
|
t.Fatalf("presence region = %q, want Java region", presence.RegionCode)
|
|
}
|
|
|
|
_, err = service.Send(ctx, sender, SendRequest{
|
|
RequestID: "req-delayed-java-region",
|
|
RoomID: 9001,
|
|
PacketMode: packetModeDelayed,
|
|
TotalAmount: 15000,
|
|
TotalCount: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Send() error = %v", err)
|
|
}
|
|
if len(fakeRegionIM.sent) != 1 || fakeRegionIM.sent[0].regionCode != "中东区" {
|
|
t.Fatalf("sent region messages = %+v, want one Java-region message", fakeRegionIM.sent)
|
|
}
|
|
}
|
|
|
|
func TestImmediatePacketSendsRoomIMMessage(t *testing.T) {
|
|
service, _, _ := newVoiceRoomRedPacketTestService(t)
|
|
fakeIM := &fakeIMGateway{}
|
|
service.im = fakeIM
|
|
service.roomProfiles = fakeRoomProfileGateway{
|
|
profiles: map[int64]integration.RoomProfile{
|
|
9001: {
|
|
ID: integration.Int64Value(9001),
|
|
RoomAccount: "900100",
|
|
},
|
|
},
|
|
}
|
|
ctx := context.Background()
|
|
sender := AuthUser{UserID: 1001, SysOrigin: "LIKEI"}
|
|
if _, err := service.Heartbeat(ctx, sender, PresenceRequest{RoomID: 9001}); err != nil {
|
|
t.Fatalf("Heartbeat() error = %v", err)
|
|
}
|
|
sendResp, err := service.Send(ctx, sender, SendRequest{
|
|
RequestID: "req-immediate-im-1",
|
|
RoomID: 9001,
|
|
PacketMode: packetModeImmediate,
|
|
TotalAmount: 15000,
|
|
TotalCount: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Send() error = %v", err)
|
|
}
|
|
if len(fakeIM.sent) != 1 {
|
|
t.Fatalf("sent messages = %+v, want one room message", fakeIM.sent)
|
|
}
|
|
if fakeIM.sent[0].groupID != "900100" {
|
|
t.Fatalf("sent group = %s, want 900100", fakeIM.sent[0].groupID)
|
|
}
|
|
body, ok := fakeIM.sent[0].body.(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("sent body type = %T", fakeIM.sent[0].body)
|
|
}
|
|
if body["type"] != "ROOM_RED_PACKET" {
|
|
t.Fatalf("sent type = %v, want ROOM_RED_PACKET", body["type"])
|
|
}
|
|
data, ok := body["data"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("sent data type = %T", body["data"])
|
|
}
|
|
if data["roomId"] != "9001" || data["roomAccount"] != "900100" ||
|
|
data["packetId"] != sendResp.PacketNo || data["packetMode"] != packetModeImmediate {
|
|
t.Fatalf("sent data = %+v", data)
|
|
}
|
|
}
|
|
|
|
func TestProcessExpiredRefundsUnclaimedSlices(t *testing.T) {
|
|
service, wallet, db := newVoiceRoomRedPacketTestService(t)
|
|
ctx := context.Background()
|
|
sender := AuthUser{UserID: 1001, SysOrigin: "LIKEI"}
|
|
claimer := AuthUser{UserID: 1002, SysOrigin: "LIKEI"}
|
|
_, _ = service.Heartbeat(ctx, sender, PresenceRequest{RoomID: 9001})
|
|
_, _ = service.Heartbeat(ctx, claimer, PresenceRequest{RoomID: 9001})
|
|
|
|
sendResp, err := service.Send(ctx, sender, SendRequest{
|
|
RequestID: "req-refund-1",
|
|
RoomID: 9001,
|
|
PacketMode: packetModeImmediate,
|
|
TotalAmount: 15000,
|
|
TotalCount: 5,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Send() error = %v", err)
|
|
}
|
|
claimResp, err := service.Claim(ctx, claimer, ClaimRequest{PacketNo: sendResp.PacketNo})
|
|
if err != nil {
|
|
t.Fatalf("Claim() error = %v", err)
|
|
}
|
|
if err := db.Model(&model.VoiceRoomRedPacket{}).
|
|
Where("packet_no = ?", sendResp.PacketNo).
|
|
Update("expire_time", time.Now().Add(-time.Minute)).Error; err != nil {
|
|
t.Fatalf("force expire: %v", err)
|
|
}
|
|
result, err := service.ProcessExpired(ctx, 10)
|
|
if err != nil {
|
|
t.Fatalf("ProcessExpired() error = %v", err)
|
|
}
|
|
if result.Success != 1 || result.Failed != 0 {
|
|
t.Fatalf("ProcessExpired() = %+v", result)
|
|
}
|
|
wantSenderBalance := int64(100000 - 15000 + (15000 - claimResp.Amount))
|
|
if wallet.balance[1001] != wantSenderBalance {
|
|
t.Fatalf("sender balance = %d, want %d", wallet.balance[1001], wantSenderBalance)
|
|
}
|
|
var packet model.VoiceRoomRedPacket
|
|
if err := db.Where("packet_no = ?", sendResp.PacketNo).First(&packet).Error; err != nil {
|
|
t.Fatalf("load packet: %v", err)
|
|
}
|
|
if packet.Status != packetStatusRefunded || packet.RefundAmount != 15000-claimResp.Amount {
|
|
t.Fatalf("packet after refund = %+v", packet)
|
|
}
|
|
assertWalletCommandsFitWalletSchema(t, wallet.calls)
|
|
if wallet.calls[len(wallet.calls)-1].CustomizeOriginDesc != walletOriginRefundDesc {
|
|
t.Fatalf("refund wallet desc = %q, want %q", wallet.calls[len(wallet.calls)-1].CustomizeOriginDesc, walletOriginRefundDesc)
|
|
}
|
|
}
|
|
|
|
func TestWalletEventIDFitsJavaWalletSchema(t *testing.T) {
|
|
packetNo := buildPacketNo(time.Date(2026, 5, 8, 10, 18, 53, 0, time.UTC), 2052649421790744577)
|
|
cases := map[string]string{
|
|
"send": walletEventID(walletOriginSend, "LIKEI", packetNo, 0),
|
|
"claim": walletEventID(walletOriginClaim, "LIKEI", packetNo, 2052643780674195456),
|
|
"refund": walletEventID(walletOriginRefund, "LIKEI", packetNo, 0),
|
|
}
|
|
for name, eventID := range cases {
|
|
if len(eventID) > 50 {
|
|
t.Fatalf("%s wallet event ID length = %d, want <= 50: %s", name, len(eventID), eventID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func newVoiceRoomRedPacketTestService(t *testing.T) (*Service, *fakeWalletGateway, *gorm.DB) {
|
|
t.Helper()
|
|
db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
|
|
if err != nil {
|
|
t.Fatalf("open sqlite: %v", err)
|
|
}
|
|
if err := db.AutoMigrate(
|
|
&model.UserBaseInfo{},
|
|
&model.VoiceRoomRedPacketConfig{},
|
|
&model.VoiceRoomRegionCountry{},
|
|
&model.VoiceRoomRegionIMGroup{},
|
|
&model.RoomLiveBroadcastVIP{},
|
|
&model.VoiceRoomRedPacket{},
|
|
&model.VoiceRoomRedPacketSlice{},
|
|
&model.VoiceRoomRedPacketClaim{},
|
|
&model.VoiceRoomRedPacketDailyCounter{},
|
|
); err != nil {
|
|
t.Fatalf("auto migrate: %v", err)
|
|
}
|
|
now := time.Now()
|
|
if err := db.Create(&[]model.UserBaseInfo{
|
|
{ID: 1001, Account: "1001", UserNickname: "sender", UserAvatar: "sender.png", OriginSys: "LIKEI", CountryCode: "SA", CountryName: "Saudi Arabia", CreateTime: now},
|
|
{ID: 1002, Account: "1002", UserNickname: "claimer", UserAvatar: "claimer.png", OriginSys: "LIKEI", CountryCode: "SA", CountryName: "Saudi Arabia", CreateTime: now},
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed users: %v", err)
|
|
}
|
|
if err := db.Create(&model.VoiceRoomRegionCountry{
|
|
ID: 1,
|
|
SysOrigin: "LIKEI",
|
|
RegionCode: "AR",
|
|
CountryCode: "SA",
|
|
Enabled: true,
|
|
CreateTime: now,
|
|
UpdateTime: now,
|
|
}).Error; err != nil {
|
|
t.Fatalf("seed region: %v", err)
|
|
}
|
|
mr := miniredis.RunT(t)
|
|
redisClient := redis.NewClient(&redis.Options{Addr: mr.Addr()})
|
|
t.Cleanup(func() { _ = redisClient.Close() })
|
|
wallet := &fakeWalletGateway{balance: map[int64]int64{1001: 100000, 1002: 100000}, events: map[string]struct{}{}}
|
|
service := NewService(config.Config{
|
|
VoiceRoomRedPacket: config.VoiceRoomRedPacketConfig{
|
|
PresenceTTLSeconds: 60,
|
|
RefundScanIntervalSeconds: 10,
|
|
RefundBatchSize: 100,
|
|
NotifyStreamKey: "test:voice_room:red_packet:notify",
|
|
ExpireZSetKey: "test:voice_room:red_packet:expire",
|
|
},
|
|
}, db, redisClient, wallet, nil)
|
|
if _, err := service.SaveAdminConfig(context.Background(), SaveConfigRequest{
|
|
SysOrigin: "LIKEI",
|
|
Enabled: true,
|
|
DailySendLimit: 10,
|
|
DelaySeconds: 300,
|
|
RefundAfterSeconds: 7200,
|
|
Timezone: "Asia/Riyadh",
|
|
AmountOptions: []int64{15000, 30000, 70000, 100000},
|
|
CountOptions: []int{5, 10, 20, 50},
|
|
}); err != nil {
|
|
t.Fatalf("SaveAdminConfig() error = %v", err)
|
|
}
|
|
return service, wallet, db
|
|
}
|
|
|
|
type fakeRoomProfileGateway struct {
|
|
profiles map[int64]integration.RoomProfile
|
|
}
|
|
|
|
func (g fakeRoomProfileGateway) MapRoomProfiles(_ context.Context, roomIDs []int64) (map[int64]integration.RoomProfile, error) {
|
|
result := make(map[int64]integration.RoomProfile, len(roomIDs))
|
|
for _, roomID := range roomIDs {
|
|
if profile, ok := g.profiles[roomID]; ok {
|
|
result[roomID] = profile
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
type fakeIMCreateRecord struct {
|
|
groupID string
|
|
groupName string
|
|
}
|
|
|
|
type fakeIMSendRecord struct {
|
|
groupID string
|
|
body any
|
|
}
|
|
|
|
type fakeIMGateway struct {
|
|
created []fakeIMCreateRecord
|
|
sent []fakeIMSendRecord
|
|
}
|
|
|
|
func (g *fakeIMGateway) CreateAVChatRoom(_ context.Context, groupID string, groupName string) (string, error) {
|
|
g.created = append(g.created, fakeIMCreateRecord{groupID: groupID, groupName: groupName})
|
|
return groupID, nil
|
|
}
|
|
|
|
func (g *fakeIMGateway) SendCustomGroupMessage(_ context.Context, groupID string, body any) error {
|
|
g.sent = append(g.sent, fakeIMSendRecord{groupID: groupID, body: body})
|
|
return nil
|
|
}
|
|
|
|
type fakeRegionIMSendRecord struct {
|
|
sysOrigin string
|
|
regionCode string
|
|
body any
|
|
}
|
|
|
|
type fakeRegionIMGateway struct {
|
|
sent []fakeRegionIMSendRecord
|
|
}
|
|
|
|
func (g *fakeRegionIMGateway) SendRegionCustomMessage(_ context.Context, sysOrigin string, regionCode string, body any) (string, error) {
|
|
g.sent = append(g.sent, fakeRegionIMSendRecord{sysOrigin: sysOrigin, regionCode: regionCode, body: body})
|
|
return "@region-" + strings.ToLower(regionCode), nil
|
|
}
|
|
|
|
type fakeRegionResolver struct {
|
|
regions map[string]string
|
|
err error
|
|
}
|
|
|
|
func (g fakeRegionResolver) ResolveRegionCodeByCountryCode(_ context.Context, sysOrigin string, countryCode string) (string, error) {
|
|
if g.err != nil {
|
|
return "", g.err
|
|
}
|
|
key := strings.ToUpper(strings.TrimSpace(sysOrigin)) + "|" + strings.ToUpper(strings.TrimSpace(countryCode))
|
|
return strings.TrimSpace(g.regions[key]), nil
|
|
}
|
|
|
|
type fakeWalletGateway struct {
|
|
balance map[int64]int64
|
|
events map[string]struct{}
|
|
calls []integration.GoldReceiptCommand
|
|
}
|
|
|
|
func (g *fakeWalletGateway) ExistsGoldEvent(_ context.Context, eventID string) (bool, error) {
|
|
_, ok := g.events[eventID]
|
|
return ok, nil
|
|
}
|
|
|
|
func (g *fakeWalletGateway) ChangeGoldBalance(_ context.Context, cmd integration.GoldReceiptCommand) error {
|
|
if _, exists := g.events[cmd.EventID]; exists {
|
|
return nil
|
|
}
|
|
g.calls = append(g.calls, cmd)
|
|
switch cmd.ReceiptType {
|
|
case walletReceiptExpenditure:
|
|
g.balance[cmd.UserID] -= cmd.Amount.DollarAmount
|
|
case walletReceiptIncome:
|
|
g.balance[cmd.UserID] += cmd.Amount.DollarAmount
|
|
}
|
|
g.events[cmd.EventID] = struct{}{}
|
|
return nil
|
|
}
|
|
|
|
func (g *fakeWalletGateway) MapGoldBalance(_ context.Context, userIDs []int64) (map[int64]int64, error) {
|
|
result := make(map[int64]int64, len(userIDs))
|
|
for _, userID := range userIDs {
|
|
result[userID] = g.balance[userID]
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func assertWalletCommandsFitWalletSchema(t *testing.T, commands []integration.GoldReceiptCommand) {
|
|
t.Helper()
|
|
if len(commands) == 0 {
|
|
t.Fatalf("wallet commands are empty")
|
|
}
|
|
for _, command := range commands {
|
|
if len(command.EventID) > 50 {
|
|
t.Fatalf("wallet event ID length = %d, want <= 50: %+v", len(command.EventID), command)
|
|
}
|
|
if len(command.CustomizeOrigin) > 50 {
|
|
t.Fatalf("wallet event type length = %d, want <= 50: %+v", len(command.CustomizeOrigin), command)
|
|
}
|
|
if len(command.CustomizeOriginDesc) > 150 {
|
|
t.Fatalf("wallet event desc length = %d, want <= 150: %+v", len(command.CustomizeOriginDesc), command)
|
|
}
|
|
if command.OpUserType != "APP" && command.OpUserType != "BACK" {
|
|
t.Fatalf("wallet op user type = %q, want APP or BACK: %+v", command.OpUserType, command)
|
|
}
|
|
}
|
|
}
|