package contract_test import ( "testing" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/fullsync/contract" ) // TestSyncKindForOperationCoversEveryChain pins the operation→kind mapping for // all five full-sync chains. A missing case makes the run invisible in the // admin monitor, because the catalog filters runs by SyncKind. func TestSyncKindForOperationCoversEveryChain(t *testing.T) { cases := []struct { operation string want contract.SyncKind }{ {"current_month_usage_full_sync", contract.SyncKindTrafficUsage}, {"sim_status_queue_full_sync", contract.SyncKindSimStatus}, {"previous_day_usage_full_sync", contract.SyncKindTrafficUsageDaily}, {"previous_month_usage_full_sync", contract.SyncKindTrafficUsageMonthly}, {"imei_full_sync", contract.SyncKindImei}, } for _, tc := range cases { got := contract.SyncKindForOperation(tc.operation) if got != tc.want { t.Fatalf("SyncKindForOperation(%q) = %q, want %q", tc.operation, got, tc.want) } if !got.Valid() { t.Fatalf("%q 应通过 Valid()", got) } } } // TestSyncKindForOperationRejectsUnknown 未知 operation 返回空 kind, // 由调用方决定是跳过还是报错。 func TestSyncKindForOperationRejectsUnknown(t *testing.T) { for _, operation := range []string{"", "unknown", "IMEI_FULL_SYNC"} { got := contract.SyncKindForOperation(operation) if got != "" { t.Fatalf("SyncKindForOperation(%q) = %q, want empty", operation, got) } if got.Valid() { t.Fatalf("空 kind 不应通过 Valid()") } } } // TestSyncKindValidRejectsUnknown 只有五个已注册的 kind 有效。 func TestSyncKindValidRejectsUnknown(t *testing.T) { valid := []contract.SyncKind{ contract.SyncKindTrafficUsage, contract.SyncKindSimStatus, contract.SyncKindTrafficUsageDaily, contract.SyncKindTrafficUsageMonthly, contract.SyncKindImei, } for _, kind := range valid { if !kind.Valid() { t.Fatalf("%q 应有效", kind) } } invalid := []contract.SyncKind{"", "imei_full_sync", "IMEI", "traffic", "sim-status"} for _, kind := range invalid { if kind.Valid() { t.Fatalf("%q 不应有效", kind) } } } // TestSyncKindValuesAreStable 枚举字符串是持久化契约(写入 Run 元数据、 // 归档 JSON 与 admin 查询参数),不得随意改动。 func TestSyncKindValuesAreStable(t *testing.T) { cases := map[contract.SyncKind]string{ contract.SyncKindTrafficUsage: "traffic_usage", contract.SyncKindSimStatus: "sim_status", contract.SyncKindTrafficUsageDaily: "traffic_usage_daily", contract.SyncKindTrafficUsageMonthly: "traffic_usage_monthly", contract.SyncKindImei: "imei", } for kind, want := range cases { if string(kind) != want { t.Fatalf("kind = %q, want %q(持久化契约不得改动)", kind, want) } } }