sync: 同步 v1.0.4 并脱敏配置与镜像
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
package iot
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity"
|
||||
)
|
||||
|
||||
func TestAddRenewDurationByUnitKeepsSameCalendarDate(t *testing.T) {
|
||||
begin := time.Date(2026, time.September, 1, 0, 0, 0, 0, time.Local)
|
||||
got := addRenewDurationByUnit(begin, "year", 1)
|
||||
want := time.Date(2027, time.September, 1, 23, 59, 59, 0, time.Local)
|
||||
if !got.Equal(want) {
|
||||
t.Fatalf(
|
||||
"addRenewDurationByUnit() = %s, want %s",
|
||||
got.Format(time.RFC3339),
|
||||
want.Format(time.RFC3339),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateRenewConfirmContract(t *testing.T) {
|
||||
snapshot := &model.TSimCardRenewPriceSnapshot{
|
||||
RenewableDurationOptions: []int{12, 24, 36},
|
||||
}
|
||||
if err := validateRenewConfirmContract(snapshot, 24); err != nil {
|
||||
t.Fatalf("valid renew contract rejected: %v", err)
|
||||
}
|
||||
if err := validateRenewConfirmContract(snapshot, 6); err == nil {
|
||||
t.Fatal("renew duration outside prepare contract was accepted")
|
||||
}
|
||||
if err := validateRenewConfirmContract(nil, 12); err == nil {
|
||||
t.Fatal("missing renew contract was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateChangeConfirmContract(t *testing.T) {
|
||||
prepareSnapshot := &model.TSimCardChangePrepareSnapshot{
|
||||
OldPackageCode: "PKG-OLD",
|
||||
}
|
||||
priceSnapshot := &model.TSimCardChangePriceSnapshot{
|
||||
NewPackageCode: "PKG-NEW",
|
||||
RenewableDurationOptions: []int{12, 24},
|
||||
}
|
||||
valid := &model.TSimCardChangeBatchSubmitParam{
|
||||
NewPackageCode: "PKG-NEW",
|
||||
DurationMonths: 12,
|
||||
EffectiveMode: cardChangeEffectiveNextMonth,
|
||||
}
|
||||
if err := validateChangeConfirmContract(prepareSnapshot, priceSnapshot, cardChangeEffectiveNextMonth, valid); err != nil {
|
||||
t.Fatalf("valid change contract rejected: %v", err)
|
||||
}
|
||||
if err := validateChangeConfirmContract(prepareSnapshot, priceSnapshot, "", valid); err != nil {
|
||||
t.Fatalf("legacy change contract without effective mode rejected: %v", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in model.TSimCardChangeBatchSubmitParam
|
||||
}{
|
||||
{
|
||||
name: "current package selected",
|
||||
in: model.TSimCardChangeBatchSubmitParam{
|
||||
NewPackageCode: "PKG-OLD",
|
||||
DurationMonths: 12,
|
||||
EffectiveMode: cardChangeEffectiveNextMonth,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "target package changed",
|
||||
in: model.TSimCardChangeBatchSubmitParam{
|
||||
NewPackageCode: "PKG-OTHER",
|
||||
DurationMonths: 12,
|
||||
EffectiveMode: cardChangeEffectiveNextMonth,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "duration outside contract",
|
||||
in: model.TSimCardChangeBatchSubmitParam{
|
||||
NewPackageCode: "PKG-NEW",
|
||||
DurationMonths: 6,
|
||||
EffectiveMode: cardChangeEffectiveNextMonth,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "effective mode changed",
|
||||
in: model.TSimCardChangeBatchSubmitParam{
|
||||
NewPackageCode: "PKG-NEW",
|
||||
DurationMonths: 12,
|
||||
EffectiveMode: cardChangeEffectiveImmediate,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := validateChangeConfirmContract(prepareSnapshot, priceSnapshot, cardChangeEffectiveNextMonth, &tt.in); err == nil {
|
||||
t.Fatal("invalid change contract was accepted")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if err := validateChangeConfirmContract(nil, priceSnapshot, cardChangeEffectiveNextMonth, valid); err == nil {
|
||||
t.Fatal("missing change contract was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeAddPackagePaymentIntent(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mode string
|
||||
confirmed bool
|
||||
isTopDept bool
|
||||
wantMode string
|
||||
wantConfirm bool
|
||||
wantErr string
|
||||
}{
|
||||
{name: "child default uses balance", wantMode: "balance"},
|
||||
{name: "top default uses balance", isTopDept: true, wantMode: "balance"},
|
||||
{name: "balance clears offline confirmation", mode: "balance", confirmed: true, isTopDept: true, wantMode: "balance"},
|
||||
{name: "child cannot use offline", mode: "offline", confirmed: true, wantErr: "必须使用余额支付"},
|
||||
{name: "top offline requires confirmation", mode: "offline", isTopDept: true, wantErr: "请确认线下合同"},
|
||||
{name: "top offline keeps confirmation", mode: "offline", confirmed: true, isTopDept: true, wantMode: "offline", wantConfirm: true},
|
||||
{name: "invalid payment mode", mode: "cash", isTopDept: true, wantErr: "付款方式不正确"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotMode, gotConfirm, err := normalizeAddPackagePaymentIntent(tt.mode, tt.confirmed, tt.isTopDept)
|
||||
if tt.wantErr != "" {
|
||||
if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
|
||||
t.Fatalf("error = %v, want substring %q", err, tt.wantErr)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("normalizeAddPackagePaymentIntent() error = %v", err)
|
||||
}
|
||||
if gotMode != tt.wantMode {
|
||||
t.Fatalf("payment mode = %q, want %q", gotMode, tt.wantMode)
|
||||
}
|
||||
if gotConfirm != tt.wantConfirm {
|
||||
t.Fatalf("offline confirmation = %v, want %v", gotConfirm, tt.wantConfirm)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizedChangePrepareSourceBatchNo(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sourceType int
|
||||
mainSource string
|
||||
snapshot string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "input ignores self reference",
|
||||
sourceType: consts.BatchSourceTypeBatchInput,
|
||||
mainSource: "CHG20260803170000INPUT",
|
||||
snapshot: "CHG20260803170000INPUT",
|
||||
},
|
||||
{
|
||||
name: "file ignores stale source",
|
||||
sourceType: consts.BatchSourceTypeFile,
|
||||
mainSource: "CHG20260803170000FILE",
|
||||
snapshot: "OUT20260803STALE",
|
||||
},
|
||||
{
|
||||
name: "batch selection keeps snapshot source",
|
||||
sourceType: consts.BatchSourceTypeBatchSelect,
|
||||
mainSource: "OUT20260803MAIN",
|
||||
snapshot: "OUT20260803CONFIRMED",
|
||||
want: "OUT20260803CONFIRMED",
|
||||
},
|
||||
{
|
||||
name: "batch selection repairs worker self reference",
|
||||
sourceType: consts.BatchSourceTypeBatchSelect,
|
||||
mainSource: "OUT20260803MAIN",
|
||||
snapshot: "CHG20260803170000BATCH",
|
||||
want: "OUT20260803MAIN",
|
||||
},
|
||||
{
|
||||
name: "legacy self reference without real source becomes empty",
|
||||
sourceType: consts.BatchSourceTypeBatchSelect,
|
||||
mainSource: "CHG20260803170000BATCH",
|
||||
snapshot: "CHG20260803170000BATCH",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
batchNo := "CHG20260803170000BATCH"
|
||||
if tt.sourceType == consts.BatchSourceTypeBatchInput {
|
||||
batchNo = "CHG20260803170000INPUT"
|
||||
}
|
||||
if tt.sourceType == consts.BatchSourceTypeFile {
|
||||
batchNo = "CHG20260803170000FILE"
|
||||
}
|
||||
batch := &entity.BatchMain{
|
||||
BatchNo: batchNo,
|
||||
SourceType: tt.sourceType,
|
||||
SourceBatchNo: tt.mainSource,
|
||||
}
|
||||
if got := normalizedChangePrepareSourceBatchNo(batch, tt.snapshot); got != tt.want {
|
||||
t.Fatalf("sourceBatchNo = %q, want %q", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user