package app import ( "context" "github.com/gogf/gf/v2/encoding/gjson" "testing" "git.5iot.com/iotlcm-public/iotlcm-app/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/batchmetadata" "git.5iot.com/iotlcm-public/iotlcm-app/internal/model" "git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity" ) func TestAppAllocateParentMatchesWorkerContract(t *testing.T) { batch := &appAllocateBatchContext{Target: &entity.SysDept{DeptId: 2}, Cards: []*appAllocateCardContext{{Card: &appCardQueryRow{TSimCardInfo: entity.TSimCardInfo{Iccid: "A", DeptId: 1}}}}} info := appAllocateParentInfo(batch, "test") if info.Get("jobRole").String() != "allocate_parent" || !info.Get("splitCompleted").Bool() || info.Get("chunkCount").Int() != 1 || info.Get("targetBatchType").Int() != consts.BatchTypeAllocate { t.Fatal("worker parent contract mismatch", info) } } func TestAppAllocateRejectsCanceledCard(t *testing.T) { card := &appCardQueryRow{TSimCardInfo: entity.TSimCardInfo{Iccid: "A", BossCardStatus: 9}} if err := NewAppCard().validateAllocateCardBusinessRules(context.Background(), nil, card); err == nil { t.Fatal("canceled card accepted") } } func TestAppAllocateQueuedResponseRetainsFinalStatus(t *testing.T) { batch := &entity.BatchMain{BatchNo: "ALC1", BatchType: 3, BatchStatus: 3, BatchAsyncStatus: 3, TotalCount: 2} if res := appAllocateQueuedResponse(batch); res.Status != "success" || res.BatchNo != batch.BatchNo || res.Quantity != 2 { t.Fatal("retry lost final result", res) } } func TestAppAllocateRetryRejectsChangedSelection(t *testing.T) { batch := &appAllocateBatchContext{Target: &entity.SysDept{DeptId: 2}, Cards: []*appAllocateCardContext{{Card: &appCardQueryRow{TSimCardInfo: entity.TSimCardInfo{Iccid: "A"}}}}} main := &entity.BatchMain{TargetDeptId: 2, BatchInfo: appAllocateParentInfo(batch, "")} for _, param := range []*model.AppCardAllocateBatchSubmitParam{{TargetDeptId: 3}, {CardValues: []string{"B"}}} { if appValidateAllocateRetry(main, param) == nil { t.Fatal("changed request accepted") } } if err := appValidateAllocateRetry(main, &model.AppCardAllocateBatchSubmitParam{CardValues: []string{"A"}, TargetDeptId: 2}); err != nil { t.Fatal(err) } if appAllocateExecutionMode(0) != batchmetadata.Bulk || appAllocateExecutionMode(2) != batchmetadata.Bulk || appAllocateExecutionMode(1) != batchmetadata.Single { t.Fatal("request shape lost") } } func TestAppAllocateQueuedResponsePreservesFailure(t *testing.T) { batch := &entity.BatchMain{BatchNo: "ALC1", BatchAsyncStatus: consts.BatchAsyncStatusFailed, FailReason: "卡已停机,不能划拨", TotalCount: 1, FailCount: 1} res := appAllocateQueuedResponse(batch) if res.Status != "failed" || res.FailReason != batch.FailReason || res.FailCount != 1 { t.Fatal("retry hid failure", res) } } func TestAppAllocateRequestRejectsChangedHashAndScope(t *testing.T) { user := &entity.SysUser{DeptId: 1} batch := &entity.BatchMain{BatchType: 3, CreatedDept: 1, BatchInfo: gjson.New(map[string]any{"jobRole": "allocate_parent", "requestHash": "hash"})} if err := appValidateAllocateRequest(batch, user, "hash"); err != nil { t.Fatal(err) } if appValidateAllocateRequest(batch, user, "changed") == nil { t.Fatal("changed request accepted") } user.DeptId = 2 if appValidateAllocateRequest(batch, user, "hash") == nil { t.Fatal("changed department accepted") } user.DeptId = 1 batch.SourceBatchNo = "parent" if appValidateAllocateRequest(batch, user, "hash") == nil { t.Fatal("child accepted") } }