sync: 同步 v1.0.4 并脱敏配置与镜像

This commit is contained in:
MiFaZhan
2026-10-29 14:36:49 +08:00
parent 743e8e6e6e
commit 2206a393f7
516 changed files with 18119 additions and 2253 deletions
@@ -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)
}
})
}
}