import { SuaveplanError } from "@suaveplan/error"; import { describe, expect, it } from "@suaveplan/testing/runner"; import { IDEMPOTENCY_CODES, IdempotencyConflictError, IdempotencyError, IdempotencyMismatchError, LockAcquisitionError, VersionConflictError, } from "./idempotency-error.js"; describe("IDEMPOTENCY_CODES", () => { it("contains all expected codes", { timeout: 5000 }, () => { expect(IDEMPOTENCY_CODES.CONFLICT).toBe("IDEMPOTENCY.CONFLICT"); expect(IDEMPOTENCY_CODES.MISMATCH).toBe("IDEMPOTENCY.MISMATCH"); expect(IDEMPOTENCY_CODES.STORE_ERROR).toBe("IDEMPOTENCY.STORE_ERROR"); expect(IDEMPOTENCY_CODES.LOCK_ACQUISITION_FAILED).toBe( "IDEMPOTENCY.LOCK_ACQUISITION_FAILED" ); expect(IDEMPOTENCY_CODES.KEY_GENERATION_FAILED).toBe( "IDEMPOTENCY.KEY_GENERATION_FAILED" ); expect(IDEMPOTENCY_CODES.VERSION_CONFLICT).toBe( "IDEMPOTENCY.VERSION_CONFLICT" ); expect(IDEMPOTENCY_CODES.KEY_EXPIRED).toBe("IDEMPOTENCY.KEY_EXPIRED"); expect(IDEMPOTENCY_CODES.KEY_INVALID).toBe("IDEMPOTENCY.KEY_INVALID"); }); }); describe("IdempotencyConflictError", () => { it("extends SuaveplanError and IdempotencyError", { timeout: 5000 }, () => { const err = new IdempotencyConflictError("key-1"); expect(err).toBeInstanceOf(SuaveplanError); expect(err).toBeInstanceOf(IdempotencyError); expect(err).toBeInstanceOf(IdempotencyConflictError); }); it("has the correct code", { timeout: 5000 }, () => { const err = new IdempotencyConflictError("key-1"); expect(err.code).toBe("IDEMPOTENCY.CONFLICT"); }); it("exposes the key via accessor", { timeout: 5000 }, () => { const err = new IdempotencyConflictError("my-key"); expect(err.key).toBe("my-key"); }); it("has a non-empty message", { timeout: 5000 }, () => { const err = new IdempotencyConflictError("k"); expect(err.message.length).toBeGreaterThan(0); }); it("captures context", { timeout: 5000 }, () => { const err = new IdempotencyConflictError("ctx-key"); expect(err.context?.["key"]).toBe("ctx-key"); }); }); describe("IdempotencyMismatchError", () => { it("extends SuaveplanError", { timeout: 5000 }, () => { expect(new IdempotencyMismatchError("k")).toBeInstanceOf( SuaveplanError ); }); it("has the correct code", { timeout: 5000 }, () => { expect(new IdempotencyMismatchError("k").code).toBe( "IDEMPOTENCY.MISMATCH" ); }); it("exposes key", { timeout: 5000 }, () => { expect(new IdempotencyMismatchError("mkey").key).toBe("mkey"); }); }); describe("LockAcquisitionError", () => { it("extends SuaveplanError", { timeout: 5000 }, () => { expect(new LockAcquisitionError("k", 3)).toBeInstanceOf(SuaveplanError); }); it("has the correct code", { timeout: 5000 }, () => { expect(new LockAcquisitionError("k", 3).code).toBe( "IDEMPOTENCY.LOCK_ACQUISITION_FAILED" ); }); it("exposes key and attempts", { timeout: 5000 }, () => { const err = new LockAcquisitionError("lk", 5); expect(err.key).toBe("lk"); expect(err.attempts).toBe(5); }); }); describe("VersionConflictError", () => { it("extends SuaveplanError", { timeout: 5000 }, () => { expect(new VersionConflictError("k", "fp1", "fp2")).toBeInstanceOf( SuaveplanError ); }); it("has the correct code", { timeout: 5000 }, () => { expect(new VersionConflictError("k", "fp1", "fp2").code).toBe( "IDEMPOTENCY.VERSION_CONFLICT" ); }); it("exposes key", { timeout: 5000 }, () => { expect(new VersionConflictError("vk", "a", "b").key).toBe("vk"); }); });