- Replace hardcoded planCategoryEnum z.enum with z.string().trim().min(1) - Add assertActiveCategory() helper that rejects inactive/unknown keys - Add resolveCategoryLabel() helper that resolves the Czech label from plan_categories DB table, falling back to built-in map - Change PlanAuditDescriptionInput.category -> categoryLabel (pre-resolved string) - Update buildPlanAuditDescription to use opts.categoryLabel directly - Update all 6 buildPlanAuditDescription call sites in plan.service.ts to await resolveCategoryLabel(row.category) - Add category validation in createEntry, updateEntry, createOverride, updateOverride - Update planAuditDescription tests to pass categoryLabel instead of category Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
96 lines
3.0 KiB
TypeScript
96 lines
3.0 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
||
import {
|
||
planCategoryLabel,
|
||
buildPlanAuditDescription,
|
||
} from "../utils/planAuditDescription";
|
||
|
||
describe("planCategoryLabel", () => {
|
||
it("maps known plan categories to Czech labels", () => {
|
||
expect(planCategoryLabel("work")).toBe("Práce");
|
||
expect(planCategoryLabel("preparation")).toBe("Příprava");
|
||
expect(planCategoryLabel("travel")).toBe("Cesta / Montáž");
|
||
expect(planCategoryLabel("leave")).toBe("Dovolená");
|
||
expect(planCategoryLabel("sick")).toBe("Nemoc");
|
||
expect(planCategoryLabel("training")).toBe("Školení");
|
||
expect(planCategoryLabel("other")).toBe("Jiné");
|
||
});
|
||
|
||
it("falls back to the raw value for an unknown category", () => {
|
||
expect(planCategoryLabel("unknown_xyz")).toBe("unknown_xyz");
|
||
});
|
||
});
|
||
|
||
describe("buildPlanAuditDescription", () => {
|
||
it("describes a multi-day entry with project", () => {
|
||
const desc = buildPlanAuditDescription({
|
||
userName: "Jan Novák",
|
||
categoryLabel: "Práce",
|
||
projectName: "Rekonstrukce haly",
|
||
dateFrom: "2026-06-08",
|
||
dateTo: "2026-06-12",
|
||
});
|
||
expect(desc).toBe(
|
||
"Jan Novák · 08.06.2026 – 12.06.2026 · Práce · Rekonstrukce haly",
|
||
);
|
||
});
|
||
|
||
it("collapses a single-day range to one date", () => {
|
||
const desc = buildPlanAuditDescription({
|
||
userName: "Jan Novák",
|
||
categoryLabel: "Práce",
|
||
projectName: "Rekonstrukce haly",
|
||
dateFrom: "2026-06-08",
|
||
dateTo: "2026-06-08",
|
||
});
|
||
expect(desc).toBe("Jan Novák · 08.06.2026 · Práce · Rekonstrukce haly");
|
||
});
|
||
|
||
it("omits the project segment when there is no project", () => {
|
||
const desc = buildPlanAuditDescription({
|
||
userName: "Petr Svoboda",
|
||
categoryLabel: "Dovolená",
|
||
projectName: null,
|
||
dateFrom: "2026-06-10",
|
||
dateTo: "2026-06-10",
|
||
});
|
||
expect(desc).toBe("Petr Svoboda · 10.06.2026 · Dovolená");
|
||
});
|
||
|
||
it("appends the emergency-edit note when force is set", () => {
|
||
const desc = buildPlanAuditDescription({
|
||
userName: "Jan Novák",
|
||
categoryLabel: "Práce",
|
||
projectName: null,
|
||
dateFrom: "2026-01-02",
|
||
dateTo: "2026-01-02",
|
||
force: true,
|
||
});
|
||
expect(desc).toBe("Jan Novák · 02.01.2026 · Práce · nouzová úprava");
|
||
});
|
||
|
||
it("appends a custom suffix (e.g. replaced override)", () => {
|
||
const desc = buildPlanAuditDescription({
|
||
userName: "Jan Novák",
|
||
categoryLabel: "Nemoc",
|
||
projectName: null,
|
||
dateFrom: "2026-06-10",
|
||
dateTo: "2026-06-10",
|
||
suffix: "nahrazeno novým záznamem",
|
||
});
|
||
expect(desc).toBe(
|
||
"Jan Novák · 10.06.2026 · Nemoc · nahrazeno novým záznamem",
|
||
);
|
||
});
|
||
|
||
it("treats a whitespace-only project name as no project", () => {
|
||
const desc = buildPlanAuditDescription({
|
||
userName: "Jan Novák",
|
||
categoryLabel: "Práce",
|
||
projectName: " ",
|
||
dateFrom: "2026-06-08",
|
||
dateTo: "2026-06-08",
|
||
});
|
||
expect(desc).toBe("Jan Novák · 08.06.2026 · Práce");
|
||
});
|
||
});
|