import { describe, expect, it } from "@suaveplan/testing/runner"; import { USER_CODES, UserError } from "./error-codes.js"; describe("USER_CODES registry", () => { it("declares 7 stable codes", { timeout: 5000 }, () => { const values = Object.values(USER_CODES); expect(values.length).toBe(7); expect(new Set(values).size).toBe(7); for (const v of values) { expect(v.startsWith("USER.")).toBe(true); } }); it("carries each documented name", { timeout: 5000 }, () => { const names: Array = [ "NOT_FOUND", "INVALID_INPUT", "SELF_DELETE_DISABLED", "PROFILE_UPDATE_FAILED", "SERVICE_NOT_AVAILABLE", "SCHEMA_APPLY_FAILED", "ROUTE_PREFIX_COLLISION", ]; for (const n of names) { expect(typeof USER_CODES[n]).toBe("string"); } }); }); describe("UserError class", () => { it("narrows code to userCode and stores message", { timeout: 5000 }, () => { const err = new UserError(USER_CODES.NOT_FOUND, "boom", { context: { statusCode: 404 }, }); expect(err).toBeInstanceOf(UserError); expect(err.code).toBe(USER_CODES.NOT_FOUND); expect(err.userCode).toBe(USER_CODES.NOT_FOUND); expect(err.message).toBe("boom"); }); it("preserves cause chain", { timeout: 5000 }, () => { const inner = new Error("inner"); const err = new UserError(USER_CODES.PROFILE_UPDATE_FAILED, "outer", { cause: inner, }); expect(err.cause).toBe(inner); }); });