chore: 初始开源发布
iotlcm-worker-svr:异步执行中枢(RabbitMQ 消费者 + 全量同步编排)。 - Go module:iotlcm-worker-svr → git.5iot.com/iotlcm-public/iotlcm-worker-svr(214 文件) - 凭据与内部标识脱敏:MySQL/Redis 凭据、私网与生产 IP、内网域名、 库名 xiujie_admin → iotlcm、哨兵名占位 - 159 处真实手机号 → 合法 11 位编造号(保留号段与后 4 位,维持互异, 不破坏「校验 MSISDN 格式」等测试断言) - 移除内部资产:CI 触发器、Jenkins 触发测试文档、预演门禁与镜像 digest 记录 - Dockerfile 改用公共基础镜像(golang:1.25-alpine → alpine:3.23), 移除写死的 git 凭据 - README 重写(架构/全量同步模型/配置/已知失败),补 Apache-2.0 LICENSE,LF 行尾 + .gitattributes 已知:3 个测试包在源仓同一提交上同样失败(client/upstream、 service/allocate、service/inbound),属既有缺陷,本仓未引入亦未修复。
This commit is contained in:
@@ -0,0 +1,495 @@
|
||||
package renewchange
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/consts"
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/model/entity"
|
||||
rc "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/repository/renewchange"
|
||||
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
func TestPrepareExecutorCanReclaimStaleProcessingBatch(t *testing.T) {
|
||||
now := time.Date(2026, 8, 26, 14, 0, 0, 0, time.Local)
|
||||
executor := &PrepareExecutor{nowFunc: func() time.Time { return now }}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
main *entity.BatchMain
|
||||
canRun bool
|
||||
}{
|
||||
{
|
||||
name: "fresh processing batch",
|
||||
main: &entity.BatchMain{
|
||||
BatchType: consts.BatchTypePrepare,
|
||||
BatchAsyncStatus: consts.BatchAsyncStatusProcessing,
|
||||
StartTime: gtime.NewFromTime(now.Add(-prepareProcessingRetryAfter + time.Second)),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "stale processing batch",
|
||||
main: &entity.BatchMain{
|
||||
BatchType: consts.BatchTypePrepare,
|
||||
BatchAsyncStatus: consts.BatchAsyncStatusProcessing,
|
||||
StartTime: gtime.NewFromTime(now.Add(-prepareProcessingRetryAfter)),
|
||||
},
|
||||
canRun: true,
|
||||
},
|
||||
{
|
||||
name: "missing start time",
|
||||
main: &entity.BatchMain{
|
||||
BatchType: consts.BatchTypePrepare,
|
||||
BatchAsyncStatus: consts.BatchAsyncStatusProcessing,
|
||||
},
|
||||
canRun: true,
|
||||
},
|
||||
{
|
||||
name: "terminal batch",
|
||||
main: &entity.BatchMain{
|
||||
BatchType: consts.BatchTypePrepare,
|
||||
BatchAsyncStatus: consts.BatchAsyncStatusSuccess,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got, err := executor.CanExecuteProcessing(context.Background(), test.main)
|
||||
if err != nil {
|
||||
t.Fatalf("CanExecuteProcessing() error = %v", err)
|
||||
}
|
||||
if got != test.canRun {
|
||||
t.Fatalf("CanExecuteProcessing() = %v, want %v", got, test.canRun)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadPrepareOptionsDurationIsExplicitOnly(t *testing.T) {
|
||||
opts := loadPrepareOptions(gjson.New(map[string]any{
|
||||
"targetBatchType": 101,
|
||||
}))
|
||||
if opts.durationSet {
|
||||
t.Fatalf("durationSet = true, want false")
|
||||
}
|
||||
if opts.durationValue != 0 {
|
||||
t.Fatalf("durationValue = %d, want 0", opts.durationValue)
|
||||
}
|
||||
|
||||
opts = loadPrepareOptions(gjson.New(map[string]any{
|
||||
"durationMonths": 6,
|
||||
}))
|
||||
if !opts.durationSet {
|
||||
t.Fatalf("durationSet = false, want true")
|
||||
}
|
||||
if opts.durationValue != 6 {
|
||||
t.Fatalf("durationValue = %d, want 6", opts.durationValue)
|
||||
}
|
||||
|
||||
opts = loadPrepareOptions(gjson.New(map[string]any{
|
||||
"durationMonths": 12,
|
||||
}))
|
||||
if !opts.durationSet {
|
||||
t.Fatalf("durationSet = false, want true")
|
||||
}
|
||||
if opts.durationValue != 1 {
|
||||
t.Fatalf("durationValue = %d, want 1", opts.durationValue)
|
||||
}
|
||||
}
|
||||
|
||||
func TestChangeDurationOptionsUseMonthsAtExecutionBoundary(t *testing.T) {
|
||||
got, err := changeDurationOptions(gjson.New([]int{1, 2, 3}))
|
||||
if err != nil {
|
||||
t.Fatalf("changeDurationOptions(years) error = %v", err)
|
||||
}
|
||||
if want := []int{12, 24, 36}; len(got) != len(want) {
|
||||
t.Fatalf("changeDurationOptions(years) = %#v, want %#v", got, want)
|
||||
} else {
|
||||
for i := range want {
|
||||
if got[i] != want[i] {
|
||||
t.Fatalf("changeDurationOptions(years) = %#v, want %#v", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
got, err = changeDurationOptions(gjson.New([]int{12, 24, 36}))
|
||||
if err != nil {
|
||||
t.Fatalf("changeDurationOptions(legacy months) error = %v", err)
|
||||
}
|
||||
if want := []int{12, 24, 36}; len(got) != len(want) {
|
||||
t.Fatalf("changeDurationOptions(legacy months) = %#v, want %#v", got, want)
|
||||
} else {
|
||||
for i := range want {
|
||||
if got[i] != want[i] {
|
||||
t.Fatalf("changeDurationOptions(legacy months) = %#v, want %#v", got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeRowErrorsKeepsValidationReasons(t *testing.T) {
|
||||
got := mergeRowErrors(
|
||||
map[int]string{2: "parse failed"},
|
||||
map[int]string{1: "duration not allowed", 2: "validation failed", 0: "batch failed"},
|
||||
)
|
||||
|
||||
if got[1] != "duration not allowed" {
|
||||
t.Fatalf("row 1 reason = %q", got[1])
|
||||
}
|
||||
if got[2] != "parse failed" {
|
||||
t.Fatalf("row 2 reason = %q", got[2])
|
||||
}
|
||||
if got[0] != "batch failed" {
|
||||
t.Fatalf("row 0 reason = %q", got[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePrepareIdentityRowsFromCardsCanonicalizesMSISDN(t *testing.T) {
|
||||
rows := []*RenewRow{
|
||||
{RowNo: 1, ICCID: "13800008000"},
|
||||
{RowNo: 2, ICCID: "8986002", MSISDN: "bad-msisdn"},
|
||||
}
|
||||
rowErrors := map[int]string{}
|
||||
|
||||
resolvePrepareIdentityRowsFromCards(rows, rowErrors, []*rc.SimCardInfo{
|
||||
{Id: 1, Iccid: "8986001", Msisdn: "13800008000", Imsi: "460001"},
|
||||
{Id: 2, Iccid: "8986002", Msisdn: "13800008002", Imsi: "460002"},
|
||||
})
|
||||
|
||||
if rows[0].ICCID != "8986001" || rows[0].MSISDN != "13800008000" || rows[0].IMSI != "460001" {
|
||||
t.Fatalf("row 1 was not canonicalized: %#v", rows[0])
|
||||
}
|
||||
if rowErrors[1] != "" {
|
||||
t.Fatalf("row 1 error = %q, want empty", rowErrors[1])
|
||||
}
|
||||
if rowErrors[2] == "" {
|
||||
t.Fatal("row 2 should fail when ICCID and MSISDN point to different identities")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCollectPrepareIccidsMarksDuplicateAfterCanonicalization(t *testing.T) {
|
||||
rows := []*RenewRow{
|
||||
{RowNo: 1, ICCID: "8986001"},
|
||||
{RowNo: 2, ICCID: "8986001"},
|
||||
}
|
||||
rowErrors := map[int]string{}
|
||||
|
||||
got := collectPrepareIccids(rows, rowErrors)
|
||||
|
||||
if len(got) != 1 || got[0] != "8986001" {
|
||||
t.Fatalf("iccids = %#v, want single canonical ICCID", got)
|
||||
}
|
||||
if rowErrors[1] == "" || rowErrors[2] == "" {
|
||||
t.Fatalf("duplicate errors not marked: %#v", rowErrors)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPrepareInfoWritesRenewFlatContract(t *testing.T) {
|
||||
got := buildPrepareInfo(nil, 101, &prepareOutcome{
|
||||
customer: &customerInfo{
|
||||
AgentID: 9,
|
||||
DeptID: 117,
|
||||
Name: "customer",
|
||||
},
|
||||
priceSnap: &RenewPriceSnapshot{
|
||||
CustomerAgentId: 117,
|
||||
PackageCode: "PKG-1",
|
||||
PackageName: "package 1",
|
||||
PriceSource: PriceSourceSystem,
|
||||
AgentDefaultPriceId: 11,
|
||||
TargetPriceId: 22,
|
||||
RenewUnitPrice: 3.5,
|
||||
RenewableDurationOptions: []int{1, 3, 12},
|
||||
RenewBeginDate: "2026-08-31",
|
||||
RenewBeginDateMin: "2026-08-31",
|
||||
RenewBeginDateMax: "2026-08-31",
|
||||
SameRenewBeginDate: true,
|
||||
},
|
||||
}, 2)
|
||||
|
||||
if got["customerAgentId"] != int64(117) {
|
||||
t.Fatalf("customerAgentId = %v, want 117", got["customerAgentId"])
|
||||
}
|
||||
if got["packageCode"] != "PKG-1" {
|
||||
t.Fatalf("packageCode = %v, want PKG-1", got["packageCode"])
|
||||
}
|
||||
if got["quantity"] != 2 {
|
||||
t.Fatalf("quantity = %v, want 2", got["quantity"])
|
||||
}
|
||||
if got["renewUnitPrice"] != 3.5 {
|
||||
t.Fatalf("renewUnitPrice = %v, want 3.5", got["renewUnitPrice"])
|
||||
}
|
||||
if got["priceSnapshot"] == nil {
|
||||
t.Fatalf("priceSnapshot is nil")
|
||||
}
|
||||
if got["renewBeginDate"] != "2026-08-31" {
|
||||
t.Fatalf("renewBeginDate = %v, want 2026-08-31", got["renewBeginDate"])
|
||||
}
|
||||
if got["sameRenewBeginDate"] != true {
|
||||
t.Fatalf("sameRenewBeginDate = %v, want true", got["sameRenewBeginDate"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestFillRenewBeginSnapshotSummarizesRenewBeginDate(t *testing.T) {
|
||||
snapshot := &RenewPriceSnapshot{}
|
||||
fillRenewBeginSnapshot(snapshot, []*RenewRow{
|
||||
{RowNo: 1, OldExpireTime: gtime.NewFromStr("2026-09-10 00:00:00")},
|
||||
{RowNo: 2, OldExpireTime: gtime.NewFromStr("2026-08-31 23:59:59")},
|
||||
}, nil)
|
||||
|
||||
if snapshot.RenewBeginDate != "" {
|
||||
t.Fatalf("renewBeginDate = %q, want empty for mixed dates", snapshot.RenewBeginDate)
|
||||
}
|
||||
if snapshot.RenewBeginDateMin != "2026-08-31" {
|
||||
t.Fatalf("renewBeginDateMin = %q, want 2026-08-31", snapshot.RenewBeginDateMin)
|
||||
}
|
||||
if snapshot.RenewBeginDateMax != "2026-09-10" {
|
||||
t.Fatalf("renewBeginDateMax = %q, want 2026-09-10", snapshot.RenewBeginDateMax)
|
||||
}
|
||||
if snapshot.SameRenewBeginDate {
|
||||
t.Fatalf("sameRenewBeginDate = true, want false")
|
||||
}
|
||||
|
||||
fillRenewBeginSnapshot(snapshot, []*RenewRow{
|
||||
{RowNo: 1, OldExpireTime: gtime.NewFromStr("2026-10-01 00:00:00")},
|
||||
{RowNo: 2, OldExpireTime: gtime.NewFromStr("2026-10-01 23:59:59")},
|
||||
}, nil)
|
||||
|
||||
if snapshot.RenewBeginDate != "2026-10-01" {
|
||||
t.Fatalf("renewBeginDate = %q, want 2026-10-01", snapshot.RenewBeginDate)
|
||||
}
|
||||
if !snapshot.SameRenewBeginDate {
|
||||
t.Fatalf("sameRenewBeginDate = false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenewBeginDateFromExpireUsesExpireDate(t *testing.T) {
|
||||
beginAt := renewBeginDateFromExpire(gtime.NewFromStr("2026-08-15 00:00:00"))
|
||||
if beginAt == nil {
|
||||
t.Fatal("renew begin date is nil")
|
||||
}
|
||||
if got := beginAt.Format("Y-m-d H:i:s"); got != "2026-08-15 23:59:59" {
|
||||
t.Fatalf("renew begin date = %s, want 2026-08-15 23:59:59", got)
|
||||
}
|
||||
if got := addMonths(beginAt.Time, 12).Format("2006-01-02 15:04:05"); got != "2027-08-15 23:59:59" {
|
||||
t.Fatalf("renew end date = %s, want 2027-08-15 23:59:59", got)
|
||||
}
|
||||
|
||||
nextBeginAt := renewBeginDateFromExpire(gtime.NewFromStr("2027-07-31 00:00:00"))
|
||||
if nextBeginAt == nil {
|
||||
t.Fatal("next renew begin date is nil")
|
||||
}
|
||||
if got := nextBeginAt.Format("Y-m-d H:i:s"); got != "2027-07-31 23:59:59" {
|
||||
t.Fatalf("next renew begin date = %s, want 2027-07-31 23:59:59", got)
|
||||
}
|
||||
|
||||
giftBeginAt := renewBeginDateFromExpire(gtime.NewFromStr("2026-08-31 00:00:00"))
|
||||
if giftBeginAt == nil {
|
||||
t.Fatal("gift renew begin date is nil")
|
||||
}
|
||||
if got := giftBeginAt.Format("Y-m-d H:i:s"); got != "2026-08-31 23:59:59" {
|
||||
t.Fatalf("gift renew begin date = %s, want 2026-08-31 23:59:59", got)
|
||||
}
|
||||
if got := addMonths(giftBeginAt.Time, 13).Format("2006-01-02 15:04:05"); got != "2027-09-30 23:59:59" {
|
||||
t.Fatalf("renew end date with gift month = %s, want 2027-09-30 23:59:59", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateRenewSameCurrentPeriod(t *testing.T) {
|
||||
sameRows := []*RenewRow{
|
||||
{
|
||||
RowNo: 1,
|
||||
OldEffTime: gtime.NewFromStr("2026-01-01 00:00:00"),
|
||||
OldExpireTime: gtime.NewFromStr("2026-12-31 23:59:59"),
|
||||
},
|
||||
{
|
||||
RowNo: 2,
|
||||
OldEffTime: gtime.NewFromStr("2026-01-01 00:00:00"),
|
||||
OldExpireTime: gtime.NewFromStr("2026-12-31 23:59:59"),
|
||||
},
|
||||
}
|
||||
if err := validateRenewSameCurrentPeriod(sameRows, nil); err != nil {
|
||||
t.Fatalf("validateRenewSameCurrentPeriod() error = %v", err)
|
||||
}
|
||||
|
||||
diffBeginRows := []*RenewRow{
|
||||
{
|
||||
RowNo: 1,
|
||||
OldEffTime: gtime.NewFromStr("2026-01-01 00:00:00"),
|
||||
OldExpireTime: gtime.NewFromStr("2026-12-31 23:59:59"),
|
||||
},
|
||||
{
|
||||
RowNo: 2,
|
||||
OldEffTime: gtime.NewFromStr("2026-02-01 00:00:00"),
|
||||
OldExpireTime: gtime.NewFromStr("2026-12-31 23:59:59"),
|
||||
},
|
||||
}
|
||||
if err := validateRenewSameCurrentPeriod(diffBeginRows, nil); err == nil {
|
||||
t.Fatalf("validateRenewSameCurrentPeriod() error = nil, want begin mismatch")
|
||||
}
|
||||
|
||||
diffExpireRows := []*RenewRow{
|
||||
{
|
||||
RowNo: 1,
|
||||
OldEffTime: gtime.NewFromStr("2026-01-01 00:00:00"),
|
||||
OldExpireTime: gtime.NewFromStr("2026-12-31 23:59:59"),
|
||||
},
|
||||
{
|
||||
RowNo: 2,
|
||||
OldEffTime: gtime.NewFromStr("2026-01-01 00:00:00"),
|
||||
OldExpireTime: gtime.NewFromStr("2027-01-31 23:59:59"),
|
||||
},
|
||||
}
|
||||
if err := validateRenewSameCurrentPeriod(diffExpireRows, nil); err == nil {
|
||||
t.Fatalf("validateRenewSameCurrentPeriod() error = nil, want expire mismatch")
|
||||
}
|
||||
|
||||
missingTimeRows := []*RenewRow{
|
||||
{
|
||||
RowNo: 1,
|
||||
OldEffTime: gtime.NewFromStr("2026-01-01 00:00:00"),
|
||||
OldExpireTime: gtime.NewFromStr("2026-12-31 23:59:59"),
|
||||
},
|
||||
{RowNo: 2, OldEffTime: gtime.NewFromStr("2026-01-01 00:00:00")},
|
||||
}
|
||||
if err := validateRenewSameCurrentPeriod(missingTimeRows, nil); err == nil {
|
||||
t.Fatalf("validateRenewSameCurrentPeriod() error = nil, want missing time")
|
||||
}
|
||||
|
||||
rowErrors := map[int]string{2: "existing validation error"}
|
||||
if err := validateRenewSameCurrentPeriod(missingTimeRows, rowErrors); err != nil {
|
||||
t.Fatalf("validateRenewSameCurrentPeriod() with rowErrors error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenewPriceOwnerUsesCurrentCustomerParent(t *testing.T) {
|
||||
if got := renewPriceOwnerDeptID(&rc.SysDeptRow{DeptId: 117, ParentId: 100}); got != 100 {
|
||||
t.Fatalf("price owner dept = %d, want 100", got)
|
||||
}
|
||||
if got := renewPriceOwnerDeptID(&rc.SysDeptRow{DeptId: 100, ParentId: 0}); got != 0 {
|
||||
t.Fatalf("top-level price owner dept = %d, want 0", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRenewExpireAfterAllowedWindow(t *testing.T) {
|
||||
now := time.Date(2026, 8, 7, 16, 50, 39, 0, time.Local)
|
||||
|
||||
if renewExpireAfterAllowedWindow(nil, now) {
|
||||
t.Fatal("nil expire time should not be rejected")
|
||||
}
|
||||
if renewExpireAfterAllowedWindow(gtime.NewFromTime(now.AddDate(0, 6, 0)), now) {
|
||||
t.Fatal("exactly 6 months ahead should be allowed")
|
||||
}
|
||||
if !renewExpireAfterAllowedWindow(gtime.NewFromTime(now.AddDate(0, 6, 0).Add(time.Second)), now) {
|
||||
t.Fatal("beyond 6 months should be rejected")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPrepareInfoWritesChangeFlatContract(t *testing.T) {
|
||||
got := buildPrepareInfo(nil, 102, &prepareOutcome{
|
||||
customer: &customerInfo{
|
||||
DeptID: 117,
|
||||
Name: "customer",
|
||||
},
|
||||
changeSnap: &ChangePrepareSnapshot{
|
||||
SourceBatchNo: "CHG-1",
|
||||
CustomerAgentId: 117,
|
||||
CustomerName: "customer",
|
||||
OldPackageCode: "OLD",
|
||||
OldPackageName: "old package",
|
||||
OldPackageType: 101,
|
||||
OldPackageFlowMb: 1024,
|
||||
Quantity: 1,
|
||||
},
|
||||
changePrice: &ChangePriceSnapshot{
|
||||
CustomerAgentId: 117,
|
||||
NewPackageCode: "NEW",
|
||||
NewPackageName: "new package",
|
||||
PriceSource: PriceSourceAgentDefault,
|
||||
AgentDefaultPriceId: 33,
|
||||
TargetPriceId: 44,
|
||||
ChangeUnitPrice: 6.5,
|
||||
RenewableDurationOptions: []int{1, 2},
|
||||
},
|
||||
}, 1)
|
||||
|
||||
if got["customerAgentId"] != int64(117) {
|
||||
t.Fatalf("customerAgentId = %v, want 117", got["customerAgentId"])
|
||||
}
|
||||
if got["sourceBatchNo"] != "CHG-1" {
|
||||
t.Fatalf("sourceBatchNo = %v, want CHG-1", got["sourceBatchNo"])
|
||||
}
|
||||
if got["oldPackageCode"] != "OLD" {
|
||||
t.Fatalf("oldPackageCode = %v, want OLD", got["oldPackageCode"])
|
||||
}
|
||||
if got["newPackageCode"] != "NEW" {
|
||||
t.Fatalf("newPackageCode = %v, want NEW", got["newPackageCode"])
|
||||
}
|
||||
if got["changeUnitPrice"] != 6.5 {
|
||||
t.Fatalf("changeUnitPrice = %v, want 6.5", got["changeUnitPrice"])
|
||||
}
|
||||
if got["changePrepareSnapshot"] == nil || got["changePriceSnapshot"] == nil {
|
||||
t.Fatalf("change snapshots are missing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPrepareDetailSnapshotIncludesChangeSubscriptionContract(t *testing.T) {
|
||||
out := &prepareOutcome{
|
||||
rows: map[int]*RenewRow{
|
||||
1: {
|
||||
RowNo: 1,
|
||||
ICCID: "8986001",
|
||||
MSISDN: "13800000000",
|
||||
IMSI: "460001",
|
||||
OldPkgCode: "OLD",
|
||||
OldPkgName: "old package",
|
||||
OldBindSubNo: "SUB-OLD",
|
||||
OldBindOrdNo: "SO-OLD",
|
||||
SourceBatchNo: "OUT-1",
|
||||
},
|
||||
},
|
||||
changePrice: &ChangePriceSnapshot{
|
||||
NewPackageCode: "NEW",
|
||||
NewPackageName: "new package",
|
||||
},
|
||||
}
|
||||
snapshot := buildPrepareDetailSnapshot(&rc.BatchDetailRow{RowNo: 1}, out, 102)
|
||||
want := map[string]string{
|
||||
"oldPackageCode": "OLD",
|
||||
"oldPackageName": "old package",
|
||||
"oldSubscriptionNo": "SUB-OLD",
|
||||
"oldOrderSn": "SO-OLD",
|
||||
"sourceBatchNo": "OUT-1",
|
||||
"newPackageCode": "NEW",
|
||||
"newPackageName": "new package",
|
||||
}
|
||||
for key, expected := range want {
|
||||
if got := snapshot.Get(key).String(); got != expected {
|
||||
t.Fatalf("%s = %q, want %q", key, got, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPriceByPackageUsesAdminContractFormula(t *testing.T) {
|
||||
pkg := &rc.FlowPackageInfo{
|
||||
CostPrice: 10,
|
||||
SysDefaultRatio: 120,
|
||||
SysDefaultProfit: 1.23,
|
||||
}
|
||||
|
||||
if got := priceByPackage(pkg, nil); got != 13.23 {
|
||||
t.Fatalf("system price = %v, want 13.23", got)
|
||||
}
|
||||
|
||||
got := priceByPackage(pkg, &rc.FlowPackagePrice{
|
||||
AgentCostRatio: 80,
|
||||
AgentCostProfit: 2.5,
|
||||
})
|
||||
if got != 10.5 {
|
||||
t.Fatalf("override price = %v, want 10.5", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user