184 lines
5.3 KiB
TypeScript
184 lines
5.3 KiB
TypeScript
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
|
|
vi.mock("../lib/holiday-availability.js", () => ({
|
|
asHolidayResolverDb: vi.fn((db) => db),
|
|
getResolvedCalendarHolidays: vi.fn(),
|
|
}));
|
|
|
|
vi.mock("../router/timeline-read-shared.js", () => ({
|
|
loadTimelineEntriesReadModel: vi.fn(),
|
|
}));
|
|
|
|
import {
|
|
asHolidayResolverDb,
|
|
getResolvedCalendarHolidays,
|
|
} from "../lib/holiday-availability.js";
|
|
import { loadTimelineEntriesReadModel } from "../router/timeline-read-shared.js";
|
|
import {
|
|
loadTimelineHolidayOverlays,
|
|
loadTimelineHolidayOverlaysForReadModel,
|
|
} from "../router/timeline-holiday-load-support.js";
|
|
|
|
const asHolidayResolverDbMock = vi.mocked(asHolidayResolverDb);
|
|
const getResolvedCalendarHolidaysMock = vi.mocked(getResolvedCalendarHolidays);
|
|
const loadTimelineEntriesReadModelMock = vi.mocked(loadTimelineEntriesReadModel);
|
|
|
|
describe("timeline holiday load support", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("loads the timeline read model before building holiday overlays", async () => {
|
|
const resourceFindMany = vi
|
|
.fn()
|
|
.mockResolvedValueOnce([
|
|
{
|
|
id: "resource_1",
|
|
countryId: "country_1",
|
|
federalState: "BY",
|
|
metroCityId: "city_1",
|
|
country: { code: "DE", name: "Germany" },
|
|
metroCity: { name: "Munich" },
|
|
},
|
|
]);
|
|
const db = { resource: { findMany: resourceFindMany } } as never;
|
|
const input = {
|
|
startDate: new Date("2026-04-01T00:00:00.000Z"),
|
|
endDate: new Date("2026-04-07T00:00:00.000Z"),
|
|
};
|
|
|
|
loadTimelineEntriesReadModelMock.mockResolvedValueOnce({
|
|
assignments: [{ resourceId: "resource_1" }],
|
|
} as never);
|
|
getResolvedCalendarHolidaysMock.mockResolvedValueOnce([
|
|
{
|
|
date: "2026-04-03",
|
|
name: "Holiday",
|
|
scope: "COUNTRY",
|
|
calendarName: "System",
|
|
sourceType: "BUILTIN",
|
|
},
|
|
] as never);
|
|
|
|
await expect(loadTimelineHolidayOverlays(db, input)).resolves.toEqual([
|
|
expect.objectContaining({
|
|
id: "calendar-holiday:resource_1:2026-04-03",
|
|
resourceId: "resource_1",
|
|
note: "Holiday",
|
|
}),
|
|
]);
|
|
|
|
expect(loadTimelineEntriesReadModelMock).toHaveBeenCalledWith(db, input);
|
|
expect(asHolidayResolverDbMock).toHaveBeenCalledWith(db);
|
|
});
|
|
|
|
it("returns an empty list when no resource ids can be resolved", async () => {
|
|
const resourceFindMany = vi.fn();
|
|
const db = { resource: { findMany: resourceFindMany } } as never;
|
|
|
|
await expect(
|
|
loadTimelineHolidayOverlaysForReadModel(
|
|
db,
|
|
{
|
|
startDate: new Date("2026-04-01T00:00:00.000Z"),
|
|
endDate: new Date("2026-04-07T00:00:00.000Z"),
|
|
},
|
|
{
|
|
assignments: [{ resourceId: null }],
|
|
} as never,
|
|
),
|
|
).resolves.toEqual([]);
|
|
|
|
expect(resourceFindMany).not.toHaveBeenCalled();
|
|
expect(getResolvedCalendarHolidaysMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("resolves holidays for matching resources and returns overlays sorted by resource and date", async () => {
|
|
const resourceFindMany = vi
|
|
.fn()
|
|
.mockResolvedValueOnce([{ id: "resource_2" }])
|
|
.mockResolvedValueOnce([
|
|
{
|
|
id: "resource_2",
|
|
countryId: "country_2",
|
|
federalState: null,
|
|
metroCityId: null,
|
|
country: { code: "US", name: "United States" },
|
|
metroCity: null,
|
|
},
|
|
{
|
|
id: "resource_1",
|
|
countryId: "country_1",
|
|
federalState: "BY",
|
|
metroCityId: "city_1",
|
|
country: { code: "DE", name: "Germany" },
|
|
metroCity: { name: "Munich" },
|
|
},
|
|
]);
|
|
const db = { resource: { findMany: resourceFindMany } } as never;
|
|
|
|
getResolvedCalendarHolidaysMock
|
|
.mockResolvedValueOnce([
|
|
{
|
|
date: "2026-04-04",
|
|
name: "Holiday B",
|
|
scope: "COUNTRY",
|
|
calendarName: "System",
|
|
sourceType: "BUILTIN",
|
|
},
|
|
] as never)
|
|
.mockResolvedValueOnce([
|
|
{
|
|
date: "2026-04-03",
|
|
name: "Holiday A",
|
|
scope: "CITY",
|
|
calendarName: "Munich",
|
|
sourceType: "CUSTOM",
|
|
},
|
|
] as never);
|
|
|
|
await expect(
|
|
loadTimelineHolidayOverlaysForReadModel(
|
|
db,
|
|
{
|
|
startDate: new Date("2026-04-01T00:00:00.000Z"),
|
|
endDate: new Date("2026-04-07T00:00:00.000Z"),
|
|
chapters: ["3D"],
|
|
},
|
|
{
|
|
assignments: [{ resourceId: "resource_1" }],
|
|
} as never,
|
|
),
|
|
).resolves.toEqual([
|
|
expect.objectContaining({
|
|
id: "calendar-holiday:resource_1:2026-04-03",
|
|
resourceId: "resource_1",
|
|
note: "Holiday A",
|
|
countryCode: "DE",
|
|
}),
|
|
expect.objectContaining({
|
|
id: "calendar-holiday:resource_2:2026-04-04",
|
|
resourceId: "resource_2",
|
|
note: "Holiday B",
|
|
countryCode: "US",
|
|
}),
|
|
]);
|
|
|
|
expect(resourceFindMany).toHaveBeenNthCalledWith(1, {
|
|
where: { chapter: { in: ["3D"] } },
|
|
select: { id: true },
|
|
});
|
|
expect(resourceFindMany).toHaveBeenNthCalledWith(2, {
|
|
where: { id: { in: ["resource_1", "resource_2"] } },
|
|
select: {
|
|
id: true,
|
|
countryId: true,
|
|
federalState: true,
|
|
metroCityId: true,
|
|
country: { select: { code: true, name: true } },
|
|
metroCity: { select: { name: true } },
|
|
},
|
|
});
|
|
});
|
|
});
|