The PO Activity timeline rendered every partial payment as the generic "Partial payment confirmed". markPaid() already persists the instalment amount on the PARTIAL_PAYMENT_CONFIRMED action's metadata (metadata.paymentAmount), so surface it: the row now reads "Partial payment of <amount> confirmed" using the PO's own currency. Falls back to the plain label when paymentAmount is missing or non-numeric (older audit rows) so historical POs never render NaN. Extracted ACTION_LABELS + the new actionLabel() helper into lib/po-activity.ts so the label logic is unit-testable without pulling the server-only PoDetail component (and its storage/auth imports) into jsdom. Fixes #140
54 lines
2 KiB
TypeScript
54 lines
2 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { actionLabel } from "@/lib/po-activity";
|
|
import { formatCurrency } from "@/lib/utils";
|
|
|
|
describe("actionLabel (Activity timeline)", () => {
|
|
it("interpolates the instalment amount for a partial payment (issue #140)", () => {
|
|
const label = actionLabel(
|
|
{ actionType: "PARTIAL_PAYMENT_CONFIRMED", metadata: { paymentAmount: 5000 } },
|
|
"INR"
|
|
);
|
|
expect(label).toBe(`Partial payment of ${formatCurrency(5000, "INR")} confirmed`);
|
|
expect(label).toContain("5,000");
|
|
});
|
|
|
|
it("respects the PO currency", () => {
|
|
const label = actionLabel(
|
|
{ actionType: "PARTIAL_PAYMENT_CONFIRMED", metadata: { paymentAmount: 1200 } },
|
|
"USD"
|
|
);
|
|
expect(label).toBe(`Partial payment of ${formatCurrency(1200, "USD")} confirmed`);
|
|
});
|
|
|
|
it("falls back to the plain label when paymentAmount is missing (older audit rows)", () => {
|
|
expect(
|
|
actionLabel({ actionType: "PARTIAL_PAYMENT_CONFIRMED", metadata: null }, "INR")
|
|
).toBe("Partial payment confirmed");
|
|
expect(
|
|
actionLabel(
|
|
{ actionType: "PARTIAL_PAYMENT_CONFIRMED", metadata: { paymentRef: "TXN-1" } },
|
|
"INR"
|
|
)
|
|
).toBe("Partial payment confirmed");
|
|
});
|
|
|
|
it("falls back when paymentAmount is non-numeric, never rendering NaN", () => {
|
|
const label = actionLabel(
|
|
{ actionType: "PARTIAL_PAYMENT_CONFIRMED", metadata: { paymentAmount: "5000" } },
|
|
"INR"
|
|
);
|
|
expect(label).toBe("Partial payment confirmed");
|
|
expect(label).not.toContain("NaN");
|
|
});
|
|
|
|
it("leaves other action labels unchanged", () => {
|
|
expect(
|
|
actionLabel({ actionType: "PAYMENT_SENT", metadata: { paymentAmount: 5000 } }, "INR")
|
|
).toBe("Payment confirmed");
|
|
expect(actionLabel({ actionType: "APPROVED", metadata: null }, "INR")).toBe("Approved");
|
|
});
|
|
|
|
it("falls back to the raw action type for unknown actions", () => {
|
|
expect(actionLabel({ actionType: "MYSTERY", metadata: null }, "INR")).toBe("MYSTERY");
|
|
});
|
|
});
|