refactor(api): extract timeline holiday load support
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
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 } },
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user