package change import ( "context" "os" "path/filepath" "testing" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchimport" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity" "github.com/xuri/excelize/v2" ) func TestExcelTemplateHeaders(t *testing.T) { got := ExcelTemplateHeaders() want := []string{"ICCID", "MSISDN", "IMSI", "newPackageCode", "durationMonths", "giftDurationMonths", "effectiveMode", "offlineContractCompleted"} if len(got) != len(want) { t.Fatalf("headers len = %d, want %d", len(got), len(want)) } for i := range want { if got[i] != want[i] { t.Fatalf("header[%d] = %q, want %q", i, got[i], want[i]) } } } func TestParseExcelFileRows(t *testing.T) { path := buildTestExcelFile(t, [][]string{ ExcelTemplateHeaders(), {"8986001", "", "", "PKG_NEW", "12", "", "immediate", "true"}, }) rows, opts, err := ParseExcelFileRows(context.Background(), path) if err != nil { t.Fatalf("ParseExcelFileRows error = %v", err) } if len(rows) != 1 { t.Fatalf("rows len = %d, want 1", len(rows)) } if rows[0].GiftDurationMonths != 0 { t.Fatalf("giftDurationMonths = %d, want 0", rows[0].GiftDurationMonths) } if opts == nil || opts.GiftDurationMonths != 0 || !opts.OfflineContractCompleted { t.Fatalf("opts = %#v", opts) } } func TestParseExcelFileRowsRequireTrueOfflineContractCompleted(t *testing.T) { path := buildTestExcelFile(t, [][]string{ ExcelTemplateHeaders(), {"8986001", "", "", "PKG_NEW", "12", "", "immediate", "false"}, }) rows, _, err := ParseExcelFileRows(context.Background(), path) if err != nil { t.Fatalf("ParseExcelFileRows error = %v", err) } if len(rows) != 1 { t.Fatalf("rows len = %d, want 1", len(rows)) } if rows[0].Reason == "" { t.Fatal("expected row error when offlineContractCompleted is false") } } func TestValidateChangeRowSourceBatchOptional(t *testing.T) { operator := batchimport.OperatorContext{DeptId: 100} row := &Row{Iccid: "8986001"} card := &entity.TSimCardInfo{ Iccid: "8986001", Msisdn: "13800008000", Imsi: "460001234567890", DeptId: 100, CurrentPackageCode: "PKG_OLD", PackageStatus: 1, } bind := &entity.TSimCardBindPkg{ Iccid: "8986001", Msisdn: "13800008000", PackageCode: "PKG_OLD", BatchNo: "BATCH-OTHER", } if reason := validateChangeRow("", operator, row, card, bind); reason != "" { t.Fatalf("validateChangeRow without sourceBatchNo = %q, want empty", reason) } if reason := validateChangeRow("BATCH-REQ", operator, row, card, bind); reason == "" { t.Fatal("expected sourceBatchNo mismatch error") } } func TestValidateChangeRowIdentityMatch(t *testing.T) { operator := batchimport.OperatorContext{DeptId: 100} card := &entity.TSimCardInfo{ Iccid: "8986001", Msisdn: "13800008000", Imsi: "460001234567890", DeptId: 100, CurrentPackageCode: "PKG_OLD", PackageStatus: 1, } bind := &entity.TSimCardBindPkg{ Iccid: "8986001", Msisdn: "13800008000", PackageCode: "PKG_OLD", } if reason := validateChangeRow("", operator, &Row{Iccid: "8986001", Msisdn: "bad"}, card, bind); reason == "" { t.Fatal("expected MSISDN mismatch error") } if reason := validateChangeRow("", operator, &Row{Iccid: "8986001", Imsi: "bad"}, card, bind); reason == "" { t.Fatal("expected IMSI mismatch error") } } func TestBuildBatchInfoOmitsEmptySourceBatchNo(t *testing.T) { p := NewProcessor() info := p.BuildBatchInfo(context.Background(), batchimport.SubmitRequest{ BizParams: &model.TSimCardChangeBatchSubmitParam{ NewPackageCode: "PKG_NEW", DurationMonths: 12, GiftDurationMonths: 0, EffectiveMode: "immediate", OfflineContractCompleted: true, }, ExecutionResult: &CompleteOutput{ SourceBatchNo: "", SourceMode: 0, NewPackageCode: "PKG_NEW", NewPackageName: "New Package", OldPackageCode: "PKG_OLD", OldPackageName: "Old Package", DurationMonths: 12, GiftDurationMonths: 0, EffectiveMode: "immediate", OfflineContractCompleted: true, }, }, nil, nil, nil, 0) if info == nil { t.Fatal("info is nil") } data := info.Map() if _, ok := data["sourceBatchNo"]; ok { t.Fatalf("sourceBatchNo should be omitted when empty: %#v", data) } if _, ok := data["remark"]; ok { t.Fatalf("remark should not exist: %#v", data) } if _, ok := data["buyerNote"]; ok { t.Fatalf("buyerNote should not exist: %#v", data) } if _, ok := data["adminNote"]; ok { t.Fatalf("adminNote should not exist: %#v", data) } } func buildTestExcelFile(t *testing.T, rows [][]string) string { t.Helper() dir := t.TempDir() path := filepath.Join(dir, "change.xlsx") f := excelize.NewFile() for i, row := range rows { cell, err := excelize.CoordinatesToCellName(1, i+1) if err != nil { t.Fatalf("CoordinatesToCellName error = %v", err) } if err = f.SetSheetRow("Sheet1", cell, &row); err != nil { t.Fatalf("SetSheetRow error = %v", err) } } if err := f.SaveAs(path); err != nil { t.Fatalf("SaveAs error = %v", err) } _ = f.Close() if _, err := os.Stat(path); err != nil { t.Fatalf("Stat error = %v", err) } return path }