import { describe, expect, it } from "vitest"; import { cardPeriods, closingOnOrAfter, dueDate, estimateOverdraftInterest, installmentSchedule, minimumPayment, minimumRateBp, nextPeriod, periodContaining, } from "./card-periods"; describe("dönem hesabı", () => { it("kesim günü dahil hesap kesim dönemine girer; ertesi gün yeni dönem", () => { expect(periodContaining("2026-10-29", 29)).toEqual({ start: "2026-09-30", end: "2026-10-29" }); expect(periodContaining("2026-10-30", 29)).toEqual({ start: "2026-10-30", end: "2026-11-29" }); }); it("kesim günü ayda yoksa ayın son günü (31 → Şubat 28/29)", () => { expect(closingOnOrAfter("2026-02-10", 31)).toBe("2026-02-28"); expect(periodContaining("2028-03-05", 31)).toEqual({ start: "2028-03-01", end: "2028-03-31" }); expect(periodContaining("2026-03-01", 30)).toEqual({ start: "2026-03-01", end: "2026-03-30" }); expect(periodContaining("2026-02-28", 30)).toEqual({ start: "2026-01-31", end: "2026-02-28" }); }); it("yıl dönümü ve sonraki dönem", () => { const p = periodContaining("2026-12-31", 15); expect(p).toEqual({ start: "2026-12-16", end: "2027-01-15" }); expect(nextPeriod(p, 15)).toEqual({ start: "2027-01-16", end: "2027-02-15" }); }); it("güncel dönem ve son ekstre; kesim günü bugün iken dönem henüz kapanmamış", () => { expect(cardPeriods("2026-11-05", 29)).toEqual({ current: { start: "2026-10-30", end: "2026-11-29" }, statement: { start: "2026-09-30", end: "2026-10-29" }, }); expect(cardPeriods("2026-11-29", 29).current.end).toBe("2026-11-29"); }); it("son ödeme tarihi", () => { expect(dueDate("2026-10-29", { kind: "daysAfter", value: 10 })).toBe("2026-11-08"); expect(dueDate("2026-10-29", { kind: "fixedDay", value: 9 })).toBe("2026-11-09"); expect(dueDate("2026-10-05", { kind: "fixedDay", value: 20 })).toBe("2026-10-20"); expect(dueDate("2026-01-29", { kind: "fixedDay", value: 31 })).toBe("2026-01-31"); }); }); describe("asgari ödeme", () => { it("limite göre %20 / %40; kart bazında oran öncelikli; yukarı yuvarlama", () => { expect(minimumRateBp(49_999_99, null)).toBe(2000); expect(minimumRateBp(50_000_00, null)).toBe(4000); expect(minimumRateBp(60_000_00, 2500)).toBe(2500); expect(minimumPayment(10_000_01, 2000)).toBe(2_000_01); expect(minimumPayment(-5, 2000)).toBe(0); }); }); describe("taksit planı", () => { it("eşit bölme (kuruş farkı ilk taksitlerde), aylık tarihler, ay sonu", () => { const s = installmentSchedule("2026-01-31", 10_000_00, 3); expect(s.map((x) => x.amountMinor)).toEqual([3_333_34, 3_333_33, 3_333_33]); expect(s.reduce((a, x) => a + x.amountMinor, 0)).toBe(10_000_00); expect(s.map((x) => x.date)).toEqual(["2026-01-31", "2026-02-28", "2026-03-31"]); }); }); describe("KMH faiz tahmini", () => { it("gün sonu eksi bakiyeler üzerinden", () => { const period = { start: "2026-11-01", end: "2026-11-30" }; // 10 gün boyunca -3.000 TL; sonra sıfır. const deltas = new Map([ ["2026-11-01", -3_000_00], ["2026-11-11", 3_000_00], ]); const r = estimateOverdraftInterest(period, 0, deltas, 425); // 10 gün × 3.000 TL × %4,25 / 30 = 42,50 TL expect(r.interestMinor).toBe(42_50); expect(r.days).toBe(30); expect(estimateOverdraftInterest(period, 5_000_00, deltas, 425).interestMinor).toBe(0); }); });