文件
hyb-oa/server/tests/unit/services/leave.test.js
T

157 行
4.1 KiB
JavaScript

const {
calculateRequestedDays,
calculateRequestedDaysByWorkingCalendar,
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("calculateRequestedDaysByWorkingCalendar", () => {
it("skips weekend days by default and respects adjusted workdays", () => {
expect(
calculateRequestedDaysByWorkingCalendar({
startDate: "2026-03-20",
endDate: "2026-03-22",
startSession: "am",
endSession: "pm",
calendarDays: [],
}),
).toBe(1);
expect(
calculateRequestedDaysByWorkingCalendar({
startDate: "2026-03-20",
endDate: "2026-03-22",
startSession: "am",
endSession: "pm",
calendarDays: [{ date: "2026-03-21", day_type: "adjusted_workday" }],
}),
).toBe(2);
});
it("skips configured holidays inside a weekday span", () => {
expect(
calculateRequestedDaysByWorkingCalendar({
startDate: "2026-03-16",
endDate: "2026-03-17",
startSession: "am",
endSession: "pm",
calendarDays: [{ date: "2026-03-17", day_type: "holiday" }],
}),
).toBe(1);
});
it("rejects ranges that become fully non-working after calendar adjustment", () => {
expect(() =>
calculateRequestedDaysByWorkingCalendar({
startDate: "2026-03-21",
endDate: "2026-03-22",
startSession: "am",
endSession: "pm",
calendarDays: [],
}),
).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);
});
});
});