test(api): cover assistant holiday resolution reads
This commit is contained in:
+162
@@ -0,0 +1,162 @@
|
|||||||
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
import { SystemRole } from "@capakraken/shared";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createToolContext,
|
||||||
|
executeTool,
|
||||||
|
} from "./assistant-tools-holiday-read-test-helpers.js";
|
||||||
|
|
||||||
|
describe("assistant holiday resolution calendar preview tools", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("previews resolved holiday calendars for a scope and shows the source calendar", async () => {
|
||||||
|
const ctx = createToolContext({
|
||||||
|
country: {
|
||||||
|
findUnique: vi.fn().mockResolvedValue({
|
||||||
|
id: "country_de",
|
||||||
|
code: "DE",
|
||||||
|
name: "Deutschland",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
metroCity: {
|
||||||
|
findUnique: vi.fn().mockResolvedValue({
|
||||||
|
id: "city_augsburg",
|
||||||
|
name: "Augsburg",
|
||||||
|
countryId: "country_de",
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
holidayCalendar: {
|
||||||
|
findMany: vi.fn().mockResolvedValue([
|
||||||
|
{
|
||||||
|
id: "cal_city",
|
||||||
|
name: "Augsburg lokal",
|
||||||
|
scopeType: "CITY",
|
||||||
|
priority: 5,
|
||||||
|
createdAt: new Date("2026-01-01T00:00:00.000Z"),
|
||||||
|
entries: [
|
||||||
|
{
|
||||||
|
id: "entry_1",
|
||||||
|
date: new Date("2020-08-08T00:00:00.000Z"),
|
||||||
|
name: "Friedensfest lokal",
|
||||||
|
isRecurringAnnual: true,
|
||||||
|
source: "manual",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await executeTool(
|
||||||
|
"preview_resolved_holiday_calendar",
|
||||||
|
JSON.stringify({ countryId: "country_de", metroCityId: "city_augsburg", year: 2026 }),
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
|
||||||
|
const parsed = JSON.parse(result.content) as {
|
||||||
|
count: number;
|
||||||
|
locationContext: { countryCode: string; metroCity: string | null; year: number };
|
||||||
|
holidays: Array<{ name: string; calendarName: string; scope: string; date: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(parsed.count).toBeGreaterThan(0);
|
||||||
|
expect(parsed.locationContext).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
countryCode: "DE",
|
||||||
|
metroCity: "Augsburg",
|
||||||
|
year: 2026,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(parsed.holidays).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
name: "Friedensfest lokal",
|
||||||
|
calendarName: "Augsburg lokal",
|
||||||
|
scope: "CITY",
|
||||||
|
date: "2026-08-08",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
expect(ctx.db.country.findUnique).toHaveBeenCalledWith({
|
||||||
|
where: { id: "country_de" },
|
||||||
|
select: { id: true, code: true, name: true },
|
||||||
|
});
|
||||||
|
expect(ctx.db.metroCity.findUnique).toHaveBeenCalledWith({
|
||||||
|
where: { id: "city_augsburg" },
|
||||||
|
select: { id: true, name: true, countryId: true },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("previews resolved holiday calendars through the real holiday router path", async () => {
|
||||||
|
const holidayCallerDb = {
|
||||||
|
country: {
|
||||||
|
findUnique: vi.fn().mockResolvedValue({ id: "country_de", code: "DE", name: "Germany" }),
|
||||||
|
},
|
||||||
|
metroCity: {
|
||||||
|
findUnique: vi
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue({ id: "city_muc", name: "Munich", countryId: "country_de" }),
|
||||||
|
},
|
||||||
|
holidayCalendar: {
|
||||||
|
findMany: vi.fn().mockResolvedValue([]),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const ctx = createToolContext(holidayCallerDb, [], SystemRole.USER);
|
||||||
|
|
||||||
|
const result = await executeTool(
|
||||||
|
"preview_resolved_holiday_calendar",
|
||||||
|
JSON.stringify({
|
||||||
|
countryId: "country_de",
|
||||||
|
stateCode: "BY",
|
||||||
|
metroCityId: "city_muc",
|
||||||
|
year: 2026,
|
||||||
|
}),
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(holidayCallerDb.country.findUnique).toHaveBeenCalledWith({
|
||||||
|
where: { id: "country_de" },
|
||||||
|
select: { id: true, code: true, name: true },
|
||||||
|
});
|
||||||
|
expect(holidayCallerDb.metroCity.findUnique).toHaveBeenCalledWith({
|
||||||
|
where: { id: "city_muc" },
|
||||||
|
select: { id: true, name: true, countryId: true },
|
||||||
|
});
|
||||||
|
expect(JSON.parse(result.content)).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
count: expect.any(Number),
|
||||||
|
locationContext: {
|
||||||
|
countryId: "country_de",
|
||||||
|
countryCode: "DE",
|
||||||
|
stateCode: "BY",
|
||||||
|
metroCityId: "city_muc",
|
||||||
|
metroCity: "Munich",
|
||||||
|
year: 2026,
|
||||||
|
},
|
||||||
|
summary: expect.objectContaining({
|
||||||
|
byCalendar: expect.any(Array),
|
||||||
|
byScope: expect.any(Array),
|
||||||
|
bySourceType: expect.arrayContaining([
|
||||||
|
expect.objectContaining({ sourceType: "BUILTIN" }),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
holidays: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
date: "2026-01-01",
|
||||||
|
name: "Neujahr",
|
||||||
|
scope: "COUNTRY",
|
||||||
|
sourceType: "BUILTIN",
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
date: "2026-01-06",
|
||||||
|
name: "Heilige Drei Könige",
|
||||||
|
scope: "STATE",
|
||||||
|
sourceType: "BUILTIN",
|
||||||
|
}),
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||||
|
|
||||||
|
import {
|
||||||
|
createToolContext,
|
||||||
|
executeTool,
|
||||||
|
} from "./assistant-tools-holiday-read-test-helpers.js";
|
||||||
|
|
||||||
|
describe("assistant holiday resolution regional and resource tools", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("lists regional holidays and distinguishes Bavaria from Hamburg", async () => {
|
||||||
|
const ctx = createToolContext({});
|
||||||
|
|
||||||
|
const bavaria = await executeTool(
|
||||||
|
"list_holidays_by_region",
|
||||||
|
JSON.stringify({ countryCode: "DE", federalState: "BY", year: 2026 }),
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
const hamburg = await executeTool(
|
||||||
|
"list_holidays_by_region",
|
||||||
|
JSON.stringify({ countryCode: "DE", federalState: "HH", year: 2026 }),
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
|
||||||
|
const bavariaResult = JSON.parse(bavaria.content) as {
|
||||||
|
count: number;
|
||||||
|
locationContext: { federalState: string | null };
|
||||||
|
summary: { byScope: Array<{ scope: string; count: number }> };
|
||||||
|
holidays: Array<{ name: string; date: string }>;
|
||||||
|
};
|
||||||
|
const hamburgResult = JSON.parse(hamburg.content) as {
|
||||||
|
count: number;
|
||||||
|
locationContext: { federalState: string | null };
|
||||||
|
holidays: Array<{ name: string; date: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(bavariaResult.count).toBeGreaterThan(hamburgResult.count);
|
||||||
|
expect(bavariaResult.locationContext.federalState).toBe("BY");
|
||||||
|
expect(bavariaResult.summary.byScope).toEqual(
|
||||||
|
expect.arrayContaining([expect.objectContaining({ scope: "STATE" })]),
|
||||||
|
);
|
||||||
|
expect(bavariaResult.holidays).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({ name: "Heilige Drei Könige", date: "2026-01-06" }),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
expect(hamburgResult.holidays).not.toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({ name: "Heilige Drei Könige", date: "2026-01-06" }),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("resolves resource-specific holidays including city-local dates", async () => {
|
||||||
|
const db = {
|
||||||
|
resource: {
|
||||||
|
findUnique: vi
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValueOnce(null)
|
||||||
|
.mockResolvedValueOnce({ id: "res_1", eid: "bruce.banner", displayName: "Bruce Banner" })
|
||||||
|
.mockResolvedValueOnce({
|
||||||
|
id: "res_1",
|
||||||
|
eid: "bruce.banner",
|
||||||
|
displayName: "Bruce Banner",
|
||||||
|
federalState: "BY",
|
||||||
|
countryId: "country_de",
|
||||||
|
metroCityId: "city_augsburg",
|
||||||
|
country: { code: "DE", name: "Deutschland" },
|
||||||
|
metroCity: { name: "Augsburg" },
|
||||||
|
}),
|
||||||
|
findFirst: vi.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const ctx = createToolContext(db);
|
||||||
|
|
||||||
|
const result = await executeTool(
|
||||||
|
"get_resource_holidays",
|
||||||
|
JSON.stringify({ identifier: "bruce.banner", year: 2026 }),
|
||||||
|
ctx,
|
||||||
|
);
|
||||||
|
|
||||||
|
const parsed = JSON.parse(result.content) as {
|
||||||
|
resource: { eid: string; federalState: string | null; metroCity: string | null };
|
||||||
|
summary: { byScope: Array<{ scope: string; count: number }> };
|
||||||
|
holidays: Array<{ name: string; date: string }>;
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(parsed.resource).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
eid: "bruce.banner",
|
||||||
|
federalState: "BY",
|
||||||
|
metroCity: "Augsburg",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(parsed.holidays).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
expect.objectContaining({ name: "Augsburger Friedensfest", date: "2026-08-08" }),
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
expect(parsed.summary.byScope).toEqual(
|
||||||
|
expect.arrayContaining([expect.objectContaining({ scope: "CITY" })]),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user