pelagia-portal/App/tests/unit/utils.test.ts
2026-05-18 23:18:58 +05:30

109 lines
3.2 KiB
TypeScript

import { describe, it, expect } from "vitest";
import {
formatCurrency, formatDate, formatDateTime,
generatePoNumber, PO_STATUS_LABELS, PO_STATUS_VARIANTS,
} from "@/lib/utils";
describe("formatCurrency", () => {
it("formats numbers as INR by default", () => {
const result = formatCurrency(1000);
expect(result).toMatch(/1,000/);
expect(result).toMatch(/₹|INR/);
});
it("formats decimal amounts to 2 decimal places", () => {
const result = formatCurrency(1234.5);
expect(result).toMatch(/1,234/);
});
it("accepts string input and formats it", () => {
const result = formatCurrency("500");
expect(result).toMatch(/500/);
});
it("formats zero without error", () => {
const result = formatCurrency(0);
expect(result).toMatch(/0/);
});
it("formats large numbers with commas", () => {
const result = formatCurrency(225498);
expect(result).toMatch(/2,25,498|225,498/); // en-IN uses 2,25,498 grouping
});
});
describe("formatDate", () => {
it("returns a readable date string", () => {
const result = formatDate(new Date("2026-04-29"));
expect(result).toMatch(/2026/);
expect(result).toMatch(/Apr|29/);
});
it("accepts a date string as input", () => {
const result = formatDate("2026-01-15");
expect(result).toMatch(/2026/);
});
});
describe("formatDateTime", () => {
it("includes both date and time", () => {
const result = formatDateTime(new Date("2026-04-29T14:30:00"));
expect(result).toMatch(/2026/);
// Should contain hours
expect(result).toMatch(/\d{1,2}:\d{2}/);
});
});
describe("generatePoNumber", () => {
it("starts with PO-", () => {
expect(generatePoNumber()).toMatch(/^PO-/);
});
it("includes the current year", () => {
const year = new Date().getFullYear().toString();
expect(generatePoNumber()).toContain(year);
});
it("generates a 5-digit zero-padded sequence", () => {
const result = generatePoNumber();
// Format: PO-YYYY-NNNNN
expect(result).toMatch(/^PO-\d{4}-\d{5}$/);
});
it("generates unique values across calls", () => {
const numbers = new Set(Array.from({ length: 20 }, () => generatePoNumber()));
// Very unlikely to get a collision with 20 draws from 100000
expect(numbers.size).toBeGreaterThan(1);
});
});
describe("PO_STATUS_LABELS", () => {
it("maps every status to a non-empty label", () => {
const statuses = [
"DRAFT", "SUBMITTED", "MGR_REVIEW", "VENDOR_ID_PENDING",
"EDITS_REQUESTED", "REJECTED", "MGR_APPROVED",
"SENT_FOR_PAYMENT", "PAID_DELIVERED", "CLOSED",
] as const;
for (const s of statuses) {
expect(PO_STATUS_LABELS[s]).toBeTruthy();
}
});
});
describe("PO_STATUS_VARIANTS", () => {
it("assigns danger variant to REJECTED", () => {
expect(PO_STATUS_VARIANTS["REJECTED"]).toBe("danger");
});
it("assigns success variant to MGR_APPROVED", () => {
expect(PO_STATUS_VARIANTS["MGR_APPROVED"]).toBe("success");
});
it("assigns warning variant to EDITS_REQUESTED", () => {
expect(PO_STATUS_VARIANTS["EDITS_REQUESTED"]).toBe("warning");
});
it("assigns outline variant to DRAFT", () => {
expect(PO_STATUS_VARIANTS["DRAFT"]).toBe("outline");
});
});