package trafficcutoffconfig import "testing" func TestValidateTaskAllowsDifferentCardStatusesAndMissingEffectivePackage(t *testing.T) { task := validConfigTask(512) task.Details = []*Detail{ validConfigDetail(1, "898600000000001"), validConfigDetail(2, "898600000000002"), validConfigDetail(3, "898600000000003"), } task.Details[0].Card.BossCardStatus = 1 task.Details[0].Card.PackageStatus = 0 task.Details[0].Card.PackageTotalFlowMb = 0 task.Details[1].Card.BossCardStatus = 4 task.Details[1].Card.PackageStatus = 1 task.Details[1].Card.PackageTotalFlowMb = 0 task.Details[2].Card.BossCardStatus = 9 task.Details[2].Card.PackageStatus = 3 task.Details[2].Card.PackageTotalFlowMb = 0 validateTask(task) if success, fail := countResult(task); success != 3 || fail != 0 { t.Fatalf("countResult() = (%d, %d), want (3, 0); task = %+v", success, fail, task) } } func TestValidateTaskAllowsPartialSuccessForThresholdGreaterThanPositivePackageTotal(t *testing.T) { task := validConfigTask(512) task.Details = []*Detail{ validConfigDetail(1, "898600000000001"), validConfigDetail(2, "898600000000002"), } task.Details[0].Card.PackageTotalFlowMb = 128 task.Details[1].Card.PackageTotalFlowMb = 0 validateTask(task) assertDetailReason(t, task.Details[0], packageTotalExceededReason) assertDetailReason(t, task.Details[1], "") if success, fail := countResult(task); success != 1 || fail != 1 { t.Fatalf("countResult() = (%d, %d), want (1, 1)", success, fail) } } func TestValidateTaskAllowsPartialSuccessForInvalidRows(t *testing.T) { tests := []struct { name string details []*Detail wantReason map[int]string }{ { name: "empty ICCID", details: []*Detail{ {RowNo: 1, ICCID: " ", Authorized: true, Card: validConfigCard(1, "")}, validConfigDetail(2, "898600000000002"), }, wantReason: map[int]string{1: emptyICCIDReason, 2: ""}, }, { name: "duplicate ICCID", details: []*Detail{ validConfigDetail(1, "898600000000001"), validConfigDetail(2, "898600000000001"), validConfigDetail(3, "898600000000003"), }, wantReason: map[int]string{1: duplicateICCIDReason, 2: duplicateICCIDReason, 3: ""}, }, { name: "unauthorized", details: []*Detail{ validConfigDetail(1, "898600000000001"), validConfigDetail(2, "898600000000002"), }, wantReason: map[int]string{1: unauthorizedReason, 2: ""}, }, { name: "missing card", details: []*Detail{ {RowNo: 1, ICCID: "898600000000001", Authorized: true}, validConfigDetail(2, "898600000000002"), }, wantReason: map[int]string{1: cardMissingReason, 2: ""}, }, { name: "MSISDN mismatch", details: []*Detail{ validConfigDetail(1, "898600000000001"), validConfigDetail(2, "898600000000002"), }, wantReason: map[int]string{1: msisdnMismatchReason, 2: ""}, }, { name: "IMSI mismatch", details: []*Detail{ validConfigDetail(1, "898600000000001"), validConfigDetail(2, "898600000000002"), }, wantReason: map[int]string{1: imsiMismatchReason, 2: ""}, }, { name: "flow pool card", details: []*Detail{ validConfigDetail(1, "898600000000001"), validConfigDetail(2, "898600000000002"), }, wantReason: map[int]string{1: flowPoolCardReason, 2: ""}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { task := validConfigTask(512) task.Details = tt.details switch tt.name { case "unauthorized": task.Details[0].Authorized = false case "MSISDN mismatch": task.Details[0].MSISDN = "13900009999" case "IMSI mismatch": task.Details[0].IMSI = "460009999999999" case "flow pool card": task.Details[0].Card.IsFlowPool = 1 } validateTask(task) for _, detail := range task.Details { assertDetailReason(t, detail, tt.wantReason[detail.RowNo]) } if success, fail := countResult(task); success != 1 || fail != len(task.Details)-1 { t.Fatalf("countResult() = (%d, %d), want (1, %d)", success, fail, len(task.Details)-1) } }) } } func validConfigTask(threshold float64) *Task { return &Task{ Batch: Batch{ BatchNo: "TCC-41", BatchType: 41, TenantID: "000000", CreatedBy: 7, }, Config: Config{ TrafficCutoffStatus: 1, TrafficCutoffThreshold: threshold, }, Details: []*Detail{validConfigDetail(1, "898600000000001")}, } } func validConfigDetail(rowNo int, iccid string) *Detail { card := validConfigCard(rowNo, iccid) return &Detail{ ID: int64(rowNo), RowNo: rowNo, ICCID: iccid, MSISDN: card.MSISDN, IMSI: card.IMSI, Authorized: true, Card: card, } } func validConfigCard(rowNo int, iccid string) *Card { return &Card{ ID: int64(rowNo), ICCID: iccid, MSISDN: "1380000000" + string(rune('0'+rowNo)), IMSI: "46000100000000" + string(rune('0'+rowNo)), PackageStatus: 0, BossCardStatus: rowNo, PackageTotalFlowMb: 1024, TrafficCutoffStatus: 0, TrafficCutoffThreshold: 0, } } func assertDetailReason(t *testing.T, detail *Detail, want string) { t.Helper() if detail == nil { t.Fatal("detail is nil") } if detail.Reason != want { t.Fatalf("row %d reason = %q, want %q", detail.RowNo, detail.Reason, want) } }