import { VacationStatus } from "@capakraken/db"; import { TRPCError } from "@trpc/server"; import { describe, expect, it } from "vitest"; import { approvableVacationStatuses, assertVacationApprovable, assertVacationCancelable, assertVacationRejectable, buildApprovedVacationUpdateData, buildRejectedVacationUpdateData, buildVacationStatusUpdateData, canActorCancelVacation, isVacationManagerRole, } from "../router/vacation-management-support.js"; describe("vacation management support", () => { it("exposes approvable statuses and guards invalid transitions", () => { expect(approvableVacationStatuses).toEqual([ VacationStatus.PENDING, VacationStatus.CANCELLED, VacationStatus.REJECTED, ]); expect(() => assertVacationApprovable(VacationStatus.PENDING)).not.toThrow(); expect(() => assertVacationRejectable(VacationStatus.PENDING)).not.toThrow(); expect(() => assertVacationCancelable(VacationStatus.PENDING)).not.toThrow(); expect(() => assertVacationApprovable(VacationStatus.APPROVED)).toThrowError( new TRPCError({ code: "BAD_REQUEST", message: "Only PENDING, CANCELLED, or REJECTED vacations can be approved", }), ); expect(() => assertVacationRejectable(VacationStatus.APPROVED)).toThrowError( new TRPCError({ code: "BAD_REQUEST", message: "Only PENDING vacations can be rejected", }), ); expect(() => assertVacationCancelable(VacationStatus.CANCELLED)).toThrowError( new TRPCError({ code: "BAD_REQUEST", message: "Already cancelled", }), ); }); it("builds approval, rejection, and generic status payloads", () => { const approvedAt = new Date("2026-02-01T10:00:00.000Z"); expect(buildApprovedVacationUpdateData({ deductionSnapshotWriteData: { deductedDays: 3, deductionSnapshot: { reason: "calendar" } }, approvedById: "user_mgr", approvedAt, })).toEqual({ status: VacationStatus.APPROVED, rejectionReason: null, deductedDays: 3, deductionSnapshot: { reason: "calendar" }, approvedById: "user_mgr", approvedAt, }); expect(buildRejectedVacationUpdateData({ rejectionReason: "Capacity conflict", })).toEqual({ status: VacationStatus.REJECTED, rejectionReason: "Capacity conflict", }); expect(buildVacationStatusUpdateData({ status: "APPROVED", note: "Reviewed", approvedById: "user_mgr", approvedAt, })).toEqual({ status: "APPROVED", approvedById: "user_mgr", approvedAt, rejectionReason: null, note: "Reviewed", }); expect(buildVacationStatusUpdateData({ status: "CANCELLED", approvedById: "user_mgr", approvedAt, })).toEqual({ status: "CANCELLED", }); }); it("captures manager bypass and ownership-based cancellation access", () => { expect(isVacationManagerRole("ADMIN")).toBe(true); expect(isVacationManagerRole("MANAGER")).toBe(true); expect(isVacationManagerRole("USER")).toBe(false); expect(canActorCancelVacation({ actorId: "user_1", actorRole: "USER", requestedById: "user_1", resourceUserId: "user_2", })).toBe(true); expect(canActorCancelVacation({ actorId: "user_1", actorRole: "USER", requestedById: "user_2", resourceUserId: "user_1", })).toBe(true); expect(canActorCancelVacation({ actorId: "user_mgr", actorRole: "MANAGER", requestedById: "user_2", resourceUserId: null, })).toBe(true); expect(canActorCancelVacation({ actorId: "user_1", actorRole: "USER", requestedById: "user_2", resourceUserId: "user_3", })).toBe(false); }); });