108 行
2.7 KiB
JavaScript
108 行
2.7 KiB
JavaScript
const {
|
|
calculateRequestedDays,
|
|
leaveRangesOverlap,
|
|
summarizeLeaveLedgerEntries,
|
|
} = require("../../../src/services/leave");
|
|
|
|
describe("Leave Service", () => {
|
|
describe("calculateRequestedDays", () => {
|
|
it("supports same-day half-day requests", () => {
|
|
expect(
|
|
calculateRequestedDays({
|
|
startDate: "2026-03-10",
|
|
endDate: "2026-03-10",
|
|
startSession: "am",
|
|
endSession: "am",
|
|
}),
|
|
).toBe(0.5);
|
|
|
|
expect(
|
|
calculateRequestedDays({
|
|
startDate: "2026-03-10",
|
|
endDate: "2026-03-10",
|
|
startSession: "pm",
|
|
endSession: "pm",
|
|
}),
|
|
).toBe(0.5);
|
|
});
|
|
|
|
it("supports cross-day half-day boundaries", () => {
|
|
expect(
|
|
calculateRequestedDays({
|
|
startDate: "2026-03-10",
|
|
endDate: "2026-03-12",
|
|
startSession: "pm",
|
|
endSession: "am",
|
|
}),
|
|
).toBe(2);
|
|
});
|
|
|
|
it("rejects invalid session ranges", () => {
|
|
expect(() =>
|
|
calculateRequestedDays({
|
|
startDate: "2026-03-10",
|
|
endDate: "2026-03-10",
|
|
startSession: "pm",
|
|
endSession: "am",
|
|
}),
|
|
).toThrow(/参数校验失败/);
|
|
});
|
|
});
|
|
|
|
describe("leaveRangesOverlap", () => {
|
|
it("detects overlapping half-day ranges", () => {
|
|
expect(
|
|
leaveRangesOverlap(
|
|
{
|
|
startDate: "2026-03-10",
|
|
endDate: "2026-03-11",
|
|
startSession: "pm",
|
|
endSession: "pm",
|
|
},
|
|
{
|
|
startDate: "2026-03-11",
|
|
endDate: "2026-03-12",
|
|
startSession: "am",
|
|
endSession: "am",
|
|
},
|
|
),
|
|
).toBe(true);
|
|
});
|
|
|
|
it("does not flag non-overlapping adjacent ranges", () => {
|
|
expect(
|
|
leaveRangesOverlap(
|
|
{
|
|
startDate: "2026-03-10",
|
|
endDate: "2026-03-10",
|
|
startSession: "am",
|
|
endSession: "am",
|
|
},
|
|
{
|
|
startDate: "2026-03-10",
|
|
endDate: "2026-03-10",
|
|
startSession: "pm",
|
|
endSession: "pm",
|
|
},
|
|
),
|
|
).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("summarizeLeaveLedgerEntries", () => {
|
|
it("calculates reserve / consume / release balances correctly", () => {
|
|
const summary = summarizeLeaveLedgerEntries([
|
|
{ entry_type: "grant", days: 10 },
|
|
{ entry_type: "reserve", days: 2.5 },
|
|
{ entry_type: "release", days: 1 },
|
|
{ entry_type: "consume", days: 1.5 },
|
|
]);
|
|
|
|
expect(summary.granted).toBe(10);
|
|
expect(summary.reserved).toBe(1.5);
|
|
expect(summary.used).toBe(1.5);
|
|
expect(summary.available).toBe(7);
|
|
});
|
|
});
|
|
});
|