142 lines
4.2 KiB
TypeScript
142 lines
4.2 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { PermissionKey } from "@capakraken/shared";
|
|
|
|
import { executeTool } from "../router/assistant-tools.js";
|
|
import { createToolContext } from "./assistant-tools-country-test-helpers.js";
|
|
|
|
describe("assistant country get tools", () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("gets a country by identifier and falls back from id to code and name lookup", async () => {
|
|
const db = {
|
|
country: {
|
|
findUnique: vi.fn().mockResolvedValue(null),
|
|
findFirst: vi
|
|
.fn()
|
|
.mockResolvedValueOnce({
|
|
id: "country_es",
|
|
code: "ES",
|
|
name: "Spain",
|
|
dailyWorkingHours: 8,
|
|
scheduleRules: {
|
|
type: "spain",
|
|
fridayHours: 6.5,
|
|
summerPeriod: { from: "07-01", to: "09-15" },
|
|
summerHours: 6.5,
|
|
regularHours: 9,
|
|
},
|
|
isActive: true,
|
|
metroCities: [{ id: "city_mad", name: "Madrid" }],
|
|
_count: { resources: 4 },
|
|
})
|
|
.mockResolvedValueOnce(null)
|
|
.mockResolvedValueOnce({
|
|
id: "country_de",
|
|
code: "DE",
|
|
name: "Germany",
|
|
dailyWorkingHours: 8,
|
|
scheduleRules: null,
|
|
isActive: true,
|
|
metroCities: [{ id: "city_muc", name: "Munich" }],
|
|
_count: { resources: 12 },
|
|
}),
|
|
},
|
|
};
|
|
const ctx = createToolContext(db, [PermissionKey.VIEW_ALL_RESOURCES]);
|
|
|
|
const result = await executeTool(
|
|
"get_country",
|
|
JSON.stringify({ identifier: "ES" }),
|
|
ctx,
|
|
);
|
|
|
|
const parsed = JSON.parse(result.content) as {
|
|
code: string;
|
|
resourceCount: number | null;
|
|
scheduleRules: { type: string };
|
|
metroCities: Array<{ name: string }>;
|
|
};
|
|
|
|
expect(parsed).toMatchObject({
|
|
code: "ES",
|
|
resourceCount: 4,
|
|
scheduleRules: { type: "spain" },
|
|
metroCities: [{ name: "Madrid" }],
|
|
});
|
|
|
|
const fallbackResult = await executeTool(
|
|
"get_country",
|
|
JSON.stringify({ identifier: "Germany" }),
|
|
ctx,
|
|
);
|
|
|
|
expect(db.country.findUnique).toHaveBeenNthCalledWith(1, {
|
|
where: { id: "ES" },
|
|
include: {
|
|
metroCities: { orderBy: { name: "asc" } },
|
|
_count: { select: { resources: true } },
|
|
},
|
|
});
|
|
expect(db.country.findUnique).toHaveBeenNthCalledWith(2, {
|
|
where: { id: "Germany" },
|
|
include: {
|
|
metroCities: { orderBy: { name: "asc" } },
|
|
_count: { select: { resources: true } },
|
|
},
|
|
});
|
|
expect(db.country.findFirst).toHaveBeenNthCalledWith(1, {
|
|
where: { code: { equals: "ES", mode: "insensitive" } },
|
|
include: {
|
|
metroCities: { orderBy: { name: "asc" } },
|
|
_count: { select: { resources: true } },
|
|
},
|
|
});
|
|
expect(db.country.findFirst).toHaveBeenNthCalledWith(2, {
|
|
where: { code: { equals: "GERMANY", mode: "insensitive" } },
|
|
include: {
|
|
metroCities: { orderBy: { name: "asc" } },
|
|
_count: { select: { resources: true } },
|
|
},
|
|
});
|
|
expect(db.country.findFirst).toHaveBeenNthCalledWith(3, {
|
|
where: { name: { equals: "Germany", mode: "insensitive" } },
|
|
include: {
|
|
metroCities: { orderBy: { name: "asc" } },
|
|
_count: { select: { resources: true } },
|
|
},
|
|
});
|
|
expect(JSON.parse(fallbackResult.content)).toEqual({
|
|
id: "country_de",
|
|
code: "DE",
|
|
name: "Germany",
|
|
dailyWorkingHours: 8,
|
|
scheduleRules: null,
|
|
isActive: true,
|
|
resourceCount: 12,
|
|
metroCities: [{ id: "city_muc", name: "Munich" }],
|
|
cities: ["Munich"],
|
|
});
|
|
});
|
|
|
|
it("returns a stable error when a country cannot be resolved", async () => {
|
|
const ctx = createToolContext({
|
|
country: {
|
|
findUnique: vi.fn().mockResolvedValue(null),
|
|
findFirst: vi.fn().mockResolvedValue(null),
|
|
},
|
|
}, [PermissionKey.VIEW_ALL_RESOURCES]);
|
|
|
|
const result = await executeTool(
|
|
"get_country",
|
|
JSON.stringify({ identifier: "Atlantis" }),
|
|
ctx,
|
|
);
|
|
|
|
expect(JSON.parse(result.content)).toEqual({
|
|
error: "Country not found with the given criteria.",
|
|
});
|
|
});
|
|
});
|