package renewchange import ( "testing" "time" "github.com/gogf/gf/v2/os/gtime" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/consts" rc "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/repository/renewchange" ) func TestResolveCurrentSubscriptionsSelectsEffectiveAndFuturePending(t *testing.T) { rows := []*rc.SimCardBindPkg{ {Iccid: "8986001", SubscriptionNo: "SUB-E", EffectiveStatus: consts.EffectiveStatusEffective}, {Iccid: "8986001", SubscriptionNo: "SUB-P", EffectiveStatus: consts.EffectiveStatusPending}, } current, future, err := resolveCurrentSubscriptions(rows, []string{"8986001"}) if err != nil { t.Fatalf("resolveCurrentSubscriptions() error = %v", err) } if current["8986001"].SubscriptionNo != "SUB-E" { t.Fatalf("current subscription = %q, want SUB-E", current["8986001"].SubscriptionNo) } if len(future["8986001"]) != 1 || future["8986001"][0].SubscriptionNo != "SUB-P" { t.Fatalf("future subscriptions = %+v, want SUB-P", future["8986001"]) } } func TestResolveCurrentSubscriptionsRejectsDuplicateCurrentSubscriptions(t *testing.T) { rows := []*rc.SimCardBindPkg{ {Iccid: "8986001", EffectiveStatus: consts.EffectiveStatusEffective}, {Iccid: "8986001", EffectiveStatus: consts.EffectiveStatusEffective}, } if _, _, err := resolveCurrentSubscriptions(rows, []string{"8986001"}); err == nil { t.Fatal("resolveCurrentSubscriptions() error = nil, want duplicate-current error") } } func TestResolveChangeBeginAtUsesConfirmedNextMonthContract(t *testing.T) { now := time.Date(2026, 8, 3, 10, 2, 0, 0, time.Local) confirmed := time.Date(2026, 9, 1, 0, 0, 0, 0, time.Local) contract := &ExecutionContract{ EffectiveMode: "next_month", PackageBeginTime: gtime.NewFromTime(confirmed), } got, err := resolveChangeBeginAt(contract, now) if err != nil { t.Fatalf("resolveChangeBeginAt() error = %v", err) } if !got.Equal(confirmed) { t.Fatalf("begin time = %v, want %v", got, confirmed) } } func TestResolveChangeBeginAtUsesExecutionTimeForImmediate(t *testing.T) { now := time.Date(2026, 8, 3, 10, 2, 0, 0, time.Local) contract := &ExecutionContract{ EffectiveMode: "immediate", PackageBeginTime: gtime.NewFromTime(now.Add(-time.Minute)), } got, err := resolveChangeBeginAt(contract, now) if err != nil { t.Fatalf("resolveChangeBeginAt() error = %v", err) } if !got.Equal(now) { t.Fatalf("begin time = %v, want %v", got, now) } } func TestChangeAmountAndServiceEndUseConfirmedDurationAndGift(t *testing.T) { contract := &ExecutionContract{UnitPrice: 8.5, Quantity: 2, DurationMonths: 12, GiftDurationMonths: 2} if got := contract.TotalAmount(); got != 204 { t.Fatalf("TotalAmount() = %v, want 204", got) } begin := time.Date(2026, 8, 3, 10, 2, 0, 0, time.Local) wantEnd := begin.AddDate(0, 14, 0) if got := contract.ServiceEnd(begin); !got.Equal(wantEnd) { t.Fatalf("ServiceEnd() = %v, want %v", got, wantEnd) } } func TestBuildChangeBindAndSuccessBatchKeepConfirmedContractAndAuditFields(t *testing.T) { contract := validExecutionContract() contract.BatchType = consts.BatchTypeChange contract.UnitPrice = 8.5 contract.Quantity = 2 contract.DurationMonths = 12 contract.GiftDurationMonths = 2 now := time.Date(2026, 8, 3, 10, 2, 0, 0, time.Local) begin := now.AddDate(0, 1, 0) end := contract.ServiceEnd(begin) pkg := &rc.FlowPackageInfo{Id: 300, PackageCode: contract.PackageCode, PackageName: "Changed package", PackageType: 1} card := &rc.SimCardInfo{Iccid: "8986001", Msisdn: "13800000000"} bind := buildChangeBind(contract, pkg, card, contract.BatchNo, "PKG-OLD", "SO-NEW", "SUB-NEW", consts.EffectiveStatusPending, begin, end, now) if bind.CreatedAt == nil || bind.UpdatedAt == nil || !bind.CreatedAt.Time.Equal(now) || !bind.UpdatedAt.Time.Equal(now) { t.Fatalf("subscription audit fields = %v/%v, want %v", bind.CreatedAt, bind.UpdatedAt, now) } if bind.DurationMonths != 12 || bind.GiftDurationMonths != 2 || bind.PackageCode != contract.PackageCode { t.Fatalf("subscription contract = package %q, duration %d+%d", bind.PackageCode, bind.DurationMonths, bind.GiftDurationMonths) } if bind.BusinessType != consts.PackageBusinessTypeChange { t.Fatalf("subscription business type = %d, want %d", bind.BusinessType, consts.PackageBusinessTypeChange) } if !bind.EffectiveTime.Time.Equal(begin) || !bind.ExpectedExpireTime.Time.Equal(end) { t.Fatalf("subscription service period = %v/%v, want %v/%v", bind.EffectiveTime, bind.ExpectedExpireTime, begin, end) } main := &rc.BatchMainRow{BatchType: consts.BatchTypeChange, TotalCount: 2, StartTime: gtime.NewFromTime(now.Add(-time.Minute))} batch := buildChangeSuccessBatchMain(main, contract, nil, "SO-NEW", main.StartTime, now, 2) if batch.TargetDeptId != contract.CustomerAgentID { t.Fatalf("target_dept_id = %d, want %d", batch.TargetDeptId, contract.CustomerAgentID) } }