feat(planning): ship holiday-aware planning and assistant upgrades
This commit is contained in:
@@ -9,12 +9,30 @@ vi.mock("../sse/event-bus.js", () => ({
|
||||
emitVacationUpdated: vi.fn(),
|
||||
emitVacationDeleted: vi.fn(),
|
||||
emitNotificationCreated: vi.fn(),
|
||||
emitTaskAssigned: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../lib/email.js", () => ({
|
||||
sendEmail: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("../lib/create-notification.js", () => ({
|
||||
createNotification: vi.fn().mockResolvedValue("notif_1"),
|
||||
}));
|
||||
|
||||
vi.mock("../lib/vacation-conflicts.js", () => ({
|
||||
checkVacationConflicts: vi.fn().mockResolvedValue({ warnings: [] }),
|
||||
checkBatchVacationConflicts: vi.fn().mockResolvedValue(new Map()),
|
||||
}));
|
||||
|
||||
vi.mock("../lib/webhook-dispatcher.js", () => ({
|
||||
dispatchWebhooks: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
vi.mock("../lib/audit.js", () => ({
|
||||
createAuditEntry: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
const createCaller = createCallerFactory(vacationRouter);
|
||||
|
||||
function createProtectedCaller(db: Record<string, unknown>) {
|
||||
@@ -91,6 +109,56 @@ const sampleVacation = {
|
||||
approvedBy: null,
|
||||
};
|
||||
|
||||
function createVacationDb(overrides: Record<string, unknown> = {}) {
|
||||
const db = {
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "user_1", systemRole: "USER" }),
|
||||
findMany: vi.fn().mockResolvedValue([{ id: "mgr_1" }, { id: "admin_1" }]),
|
||||
},
|
||||
resource: {
|
||||
findUnique: vi.fn().mockImplementation(async (args?: { select?: Record<string, unknown> }) => {
|
||||
const select = args?.select ?? {};
|
||||
return {
|
||||
...(select.userId ? { userId: "user_1" } : {}),
|
||||
...(select.displayName ? { displayName: "Alice" } : {}),
|
||||
...(select.user ? { user: null } : {}),
|
||||
...(select.federalState ? { federalState: "BY" } : {}),
|
||||
...(select.country ? { country: { code: "DE", name: "Germany" } } : {}),
|
||||
...(select.metroCity ? { metroCity: null } : {}),
|
||||
};
|
||||
}),
|
||||
count: vi.fn().mockResolvedValue(0),
|
||||
},
|
||||
vacation: {
|
||||
findFirst: vi.fn().mockResolvedValue(null),
|
||||
findUnique: vi.fn().mockResolvedValue(sampleVacation),
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
create: vi.fn().mockResolvedValue(sampleVacation),
|
||||
update: vi.fn().mockResolvedValue(sampleVacation),
|
||||
updateMany: vi.fn().mockResolvedValue({ count: 1 }),
|
||||
},
|
||||
notification: {
|
||||
updateMany: vi.fn().mockResolvedValue({ count: 1 }),
|
||||
},
|
||||
auditLog: {
|
||||
create: vi.fn().mockResolvedValue({}),
|
||||
},
|
||||
};
|
||||
|
||||
return {
|
||||
...db,
|
||||
...overrides,
|
||||
user: { ...db.user, ...(overrides.user as Record<string, unknown> | undefined) },
|
||||
resource: { ...db.resource, ...(overrides.resource as Record<string, unknown> | undefined) },
|
||||
vacation: { ...db.vacation, ...(overrides.vacation as Record<string, unknown> | undefined) },
|
||||
notification: {
|
||||
...db.notification,
|
||||
...(overrides.notification as Record<string, unknown> | undefined),
|
||||
},
|
||||
auditLog: { ...db.auditLog, ...(overrides.auditLog as Record<string, unknown> | undefined) },
|
||||
};
|
||||
}
|
||||
|
||||
describe("vacation router", () => {
|
||||
describe("list", () => {
|
||||
it("returns vacations with default filters", async () => {
|
||||
@@ -199,18 +267,11 @@ describe("vacation router", () => {
|
||||
status: VacationStatus.PENDING,
|
||||
};
|
||||
|
||||
const db = {
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "user_1", systemRole: "USER" }),
|
||||
},
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue({ userId: "user_1" }),
|
||||
},
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findFirst: vi.fn().mockResolvedValue(null),
|
||||
create: vi.fn().mockResolvedValue(createdVacation),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.create({
|
||||
@@ -239,15 +300,14 @@ describe("vacation router", () => {
|
||||
approvedById: "mgr_1",
|
||||
};
|
||||
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "mgr_1", systemRole: "MANAGER" }),
|
||||
},
|
||||
vacation: {
|
||||
findFirst: vi.fn().mockResolvedValue(null),
|
||||
create: vi.fn().mockResolvedValue(createdVacation),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
const result = await caller.create({
|
||||
@@ -269,17 +329,11 @@ describe("vacation router", () => {
|
||||
});
|
||||
|
||||
it("rejects overlapping vacation", async () => {
|
||||
const db = {
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "user_1", systemRole: "USER" }),
|
||||
},
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue({ userId: "user_1" }),
|
||||
},
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findFirst: vi.fn().mockResolvedValue({ id: "existing_vac" }),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
await expect(
|
||||
@@ -293,10 +347,10 @@ describe("vacation router", () => {
|
||||
});
|
||||
|
||||
it("rejects when end date is before start date", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
user: { findUnique: vi.fn() },
|
||||
vacation: { findFirst: vi.fn() },
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
await expect(
|
||||
@@ -316,18 +370,11 @@ describe("vacation router", () => {
|
||||
halfDayPart: "MORNING",
|
||||
};
|
||||
|
||||
const db = {
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "user_1", systemRole: "USER" }),
|
||||
},
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue({ userId: "user_1" }),
|
||||
},
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findFirst: vi.fn().mockResolvedValue(null),
|
||||
create: vi.fn().mockResolvedValue(createdVacation),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.create({
|
||||
@@ -349,6 +396,235 @@ describe("vacation router", () => {
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects multi-day half-day vacations", async () => {
|
||||
const db = createVacationDb();
|
||||
const caller = createProtectedCaller(db);
|
||||
|
||||
await expect(caller.create({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2026-06-01"),
|
||||
endDate: new Date("2026-06-02"),
|
||||
isHalfDay: true,
|
||||
halfDayPart: "MORNING",
|
||||
})).rejects.toThrow();
|
||||
|
||||
expect(db.vacation.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects half-day vacations without a half-day part", async () => {
|
||||
const db = createVacationDb();
|
||||
const caller = createProtectedCaller(db);
|
||||
|
||||
await expect(caller.create({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2026-06-01"),
|
||||
endDate: new Date("2026-06-01"),
|
||||
isHalfDay: true,
|
||||
})).rejects.toThrow();
|
||||
|
||||
expect(db.vacation.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects half-day parts on full-day vacations", async () => {
|
||||
const db = createVacationDb();
|
||||
const caller = createProtectedCaller(db);
|
||||
|
||||
await expect(caller.create({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2026-06-01"),
|
||||
endDate: new Date("2026-06-01"),
|
||||
halfDayPart: "AFTERNOON",
|
||||
})).rejects.toThrow();
|
||||
|
||||
expect(db.vacation.create).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("rejects leave requests that only hit public holidays", async () => {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
|
||||
await expect(caller.create({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2026-01-06T00:00:00.000Z"),
|
||||
endDate: new Date("2026-01-06T00:00:00.000Z"),
|
||||
})).rejects.toThrow("does not deduct any vacation days");
|
||||
|
||||
expect(db.vacation.create).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("previewRequest", () => {
|
||||
it("shows public holidays as non-deductible leave days", async () => {
|
||||
const db = createVacationDb({
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
userId: "user_1",
|
||||
federalState: "BY",
|
||||
country: { code: "DE", name: "Germany" },
|
||||
metroCity: { name: "Augsburg" },
|
||||
}),
|
||||
},
|
||||
vacation: {
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.previewRequest({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2028-08-08T00:00:00.000Z"),
|
||||
endDate: new Date("2028-08-08T00:00:00.000Z"),
|
||||
});
|
||||
|
||||
expect(result.requestedDays).toBe(1);
|
||||
expect(result.effectiveDays).toBe(0);
|
||||
expect(result.deductedDays).toBe(0);
|
||||
expect(result.publicHolidayDates).toContain("2028-08-08");
|
||||
expect(result.holidayContext).toEqual({
|
||||
countryCode: "DE",
|
||||
countryName: "Germany",
|
||||
federalState: "BY",
|
||||
metroCityName: "Augsburg",
|
||||
sources: {
|
||||
hasCalendarHolidays: true,
|
||||
hasLegacyPublicHolidayEntries: false,
|
||||
},
|
||||
});
|
||||
expect(result.holidayDetails).toContainEqual({
|
||||
date: "2028-08-08",
|
||||
source: "CALENDAR",
|
||||
});
|
||||
});
|
||||
|
||||
it("uses custom city holiday calendars for non-deductible leave days", async () => {
|
||||
const db = createVacationDb({
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
userId: "user_1",
|
||||
countryId: "country_de",
|
||||
metroCityId: "city_muc",
|
||||
federalState: "BY",
|
||||
country: { code: "DE", name: "Germany" },
|
||||
metroCity: { name: "Muenchen" },
|
||||
}),
|
||||
},
|
||||
holidayCalendar: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "cal_muc",
|
||||
name: "Muenchen lokal",
|
||||
scopeType: "CITY",
|
||||
priority: 10,
|
||||
createdAt: new Date("2026-01-01T00:00:00.000Z"),
|
||||
entries: [
|
||||
{
|
||||
date: new Date("2020-11-15T00:00:00.000Z"),
|
||||
name: "Lokaler Stadtfeiertag",
|
||||
isRecurringAnnual: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
]),
|
||||
},
|
||||
vacation: {
|
||||
findMany: vi.fn().mockResolvedValue([]),
|
||||
},
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.previewRequest({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2026-11-15T00:00:00.000Z"),
|
||||
endDate: new Date("2026-11-15T00:00:00.000Z"),
|
||||
});
|
||||
|
||||
expect(result.requestedDays).toBe(1);
|
||||
expect(result.effectiveDays).toBe(0);
|
||||
expect(result.publicHolidayDates).toContain("2026-11-15");
|
||||
expect(result.holidayContext.countryName).toBe("Germany");
|
||||
expect(result.holidayContext.metroCityName).toBe("Muenchen");
|
||||
expect(db.holidayCalendar.findMany).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("marks legacy public holiday entries as a separate preview source", async () => {
|
||||
const db = createVacationDb({
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
userId: "user_1",
|
||||
federalState: "HH",
|
||||
country: { code: "DE", name: "Germany" },
|
||||
metroCity: { name: "Hamburg" },
|
||||
}),
|
||||
},
|
||||
vacation: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{
|
||||
startDate: new Date("2026-05-01T00:00:00.000Z"),
|
||||
endDate: new Date("2026-05-01T00:00:00.000Z"),
|
||||
},
|
||||
]),
|
||||
},
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.previewRequest({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2026-05-01T00:00:00.000Z"),
|
||||
endDate: new Date("2026-05-01T00:00:00.000Z"),
|
||||
});
|
||||
|
||||
expect(result.publicHolidayDates).toContain("2026-05-01");
|
||||
expect(result.holidayContext.sources).toEqual({
|
||||
hasCalendarHolidays: true,
|
||||
hasLegacyPublicHolidayEntries: true,
|
||||
});
|
||||
expect(result.holidayDetails).toContainEqual({
|
||||
date: "2026-05-01",
|
||||
source: "CALENDAR_AND_LEGACY",
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects multi-day half-day previews", async () => {
|
||||
const db = createVacationDb();
|
||||
const caller = createProtectedCaller(db);
|
||||
|
||||
await expect(caller.previewRequest({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.ANNUAL,
|
||||
startDate: new Date("2026-06-01"),
|
||||
endDate: new Date("2026-06-02"),
|
||||
isHalfDay: true,
|
||||
})).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("create manual public holiday handling", () => {
|
||||
it("rejects manual public holiday creation requests", async () => {
|
||||
const db = createVacationDb();
|
||||
const caller = createManagerCaller(db);
|
||||
|
||||
await expect(caller.create({
|
||||
resourceId: "res_1",
|
||||
type: VacationType.PUBLIC_HOLIDAY,
|
||||
startDate: new Date("2026-05-01T00:00:00.000Z"),
|
||||
endDate: new Date("2026-05-01T00:00:00.000Z"),
|
||||
})).rejects.toThrow("Public holidays must be managed via Holiday Calendars or the legacy holiday import");
|
||||
|
||||
expect(db.vacation.create).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("approve", () => {
|
||||
@@ -359,7 +635,7 @@ describe("vacation router", () => {
|
||||
approvedById: "mgr_1",
|
||||
};
|
||||
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue(sampleVacation),
|
||||
update: vi.fn().mockResolvedValue(updatedVacation),
|
||||
@@ -370,7 +646,7 @@ describe("vacation router", () => {
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
const result = await caller.approve({ id: "vac_1" });
|
||||
@@ -388,25 +664,25 @@ describe("vacation router", () => {
|
||||
});
|
||||
|
||||
it("throws NOT_FOUND for missing vacation", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
await expect(caller.approve({ id: "missing" })).rejects.toThrow("Vacation not found");
|
||||
});
|
||||
|
||||
it("rejects approving an already APPROVED vacation", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
...sampleVacation,
|
||||
status: VacationStatus.APPROVED,
|
||||
}),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
await expect(caller.approve({ id: "vac_1" })).rejects.toThrow(
|
||||
@@ -429,7 +705,7 @@ describe("vacation router", () => {
|
||||
rejectionReason: "Team conflict",
|
||||
};
|
||||
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue(sampleVacation),
|
||||
update: vi.fn().mockResolvedValue(updatedVacation),
|
||||
@@ -437,7 +713,7 @@ describe("vacation router", () => {
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
const result = await caller.reject({ id: "vac_1", rejectionReason: "Team conflict" });
|
||||
@@ -454,14 +730,14 @@ describe("vacation router", () => {
|
||||
});
|
||||
|
||||
it("throws when rejecting non-PENDING vacation", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
...sampleVacation,
|
||||
status: VacationStatus.APPROVED,
|
||||
}),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
await expect(caller.reject({ id: "vac_1" })).rejects.toThrow(
|
||||
@@ -477,15 +753,12 @@ describe("vacation router", () => {
|
||||
status: VacationStatus.CANCELLED,
|
||||
};
|
||||
|
||||
const db = {
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "user_1", systemRole: "USER" }),
|
||||
},
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue(sampleVacation),
|
||||
update: vi.fn().mockResolvedValue(updatedVacation),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
const result = await caller.cancel({ id: "vac_1" });
|
||||
@@ -494,25 +767,25 @@ describe("vacation router", () => {
|
||||
});
|
||||
|
||||
it("throws NOT_FOUND for missing vacation", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
await expect(caller.cancel({ id: "missing" })).rejects.toThrow("Vacation not found");
|
||||
});
|
||||
|
||||
it("throws when already cancelled", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
vacation: {
|
||||
findUnique: vi.fn().mockResolvedValue({
|
||||
...sampleVacation,
|
||||
status: VacationStatus.CANCELLED,
|
||||
}),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createProtectedCaller(db);
|
||||
await expect(caller.cancel({ id: "vac_1" })).rejects.toThrow("Already cancelled");
|
||||
@@ -521,7 +794,7 @@ describe("vacation router", () => {
|
||||
|
||||
describe("batchApprove", () => {
|
||||
it("approves multiple pending vacations", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "mgr_1" }),
|
||||
},
|
||||
@@ -535,7 +808,7 @@ describe("vacation router", () => {
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
const result = await caller.batchApprove({ ids: ["vac_1", "vac_2"] });
|
||||
@@ -552,7 +825,7 @@ describe("vacation router", () => {
|
||||
});
|
||||
|
||||
it("only approves PENDING vacations from the requested set", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "mgr_1" }),
|
||||
},
|
||||
@@ -565,7 +838,7 @@ describe("vacation router", () => {
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
const result = await caller.batchApprove({ ids: ["vac_1", "vac_already_approved"] });
|
||||
@@ -581,7 +854,10 @@ describe("vacation router", () => {
|
||||
|
||||
describe("batchReject", () => {
|
||||
it("rejects multiple pending vacations with optional reason", async () => {
|
||||
const db = {
|
||||
const db = createVacationDb({
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "mgr_1" }),
|
||||
},
|
||||
vacation: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{ id: "vac_1", resourceId: "res_1" },
|
||||
@@ -591,7 +867,7 @@ describe("vacation router", () => {
|
||||
resource: {
|
||||
findUnique: vi.fn().mockResolvedValue(null),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const caller = createManagerCaller(db);
|
||||
const result = await caller.batchReject({
|
||||
@@ -731,8 +1007,8 @@ describe("vacation router", () => {
|
||||
const db = {
|
||||
resource: {
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{ id: "res_1" },
|
||||
{ id: "res_2" },
|
||||
{ id: "res_1", federalState: "BY", country: { code: "DE" }, metroCity: null },
|
||||
{ id: "res_2", federalState: "BY", country: { code: "DE" }, metroCity: null },
|
||||
]),
|
||||
},
|
||||
user: {
|
||||
@@ -759,7 +1035,9 @@ describe("vacation router", () => {
|
||||
it("skips already existing holidays", async () => {
|
||||
const db = {
|
||||
resource: {
|
||||
findMany: vi.fn().mockResolvedValue([{ id: "res_1" }]),
|
||||
findMany: vi.fn().mockResolvedValue([
|
||||
{ id: "res_1", federalState: "BY", country: { code: "DE" }, metroCity: null },
|
||||
]),
|
||||
},
|
||||
user: {
|
||||
findUnique: vi.fn().mockResolvedValue({ id: "admin_1" }),
|
||||
|
||||
Reference in New Issue
Block a user