import { describe, it, expect, vi } from "vitest"; import { InMemoryJobQueue } from "@/jobs/in-memory-job-queue"; import type { IJobQueue } from "@/jobs/job-queue.interface"; describe("InMemoryJobQueue", () => { it("returns a synthetic jobId on enqueue", async () => { const handler = vi.fn(); const queue: IJobQueue = new InMemoryJobQueue({ "test.task": handler, }); const result = await queue.enqueue("test.task", { x: 1 }); expect(result.jobId).toMatch(/^in-memory-/); }); it("invokes the registered handler asynchronously with the input", async () => { const handler = vi.fn(); const queue = new InMemoryJobQueue({ "test.task": handler }); await queue.enqueue("test.task", { x: 42 }); await new Promise((r) => setImmediate(r)); expect(handler).toHaveBeenCalledWith({ x: 42 }); }); it("throws if the task slug has no registered handler", async () => { const queue = new InMemoryJobQueue({}); await expect(queue.enqueue("missing.task", {})).rejects.toThrow( /no handler registered for task slug: missing\.task/, ); }); it("delays execution when runAt is in the future", async () => { vi.useFakeTimers(); try { const handler = vi.fn(); const queue = new InMemoryJobQueue({ "test.task": handler }); const future = new Date(Date.now() + 1000); await queue.enqueue("test.task", {}, { runAt: future }); expect(handler).not.toHaveBeenCalled(); vi.advanceTimersByTime(1000); await Promise.resolve(); expect(handler).toHaveBeenCalledTimes(1); } finally { vi.useRealTimers(); } }); it("register adds a handler that can be enqueued against", async () => { const queue = new InMemoryJobQueue(); const handler = vi.fn(); queue.register("late.task", handler); await queue.enqueue("late.task", { z: 1 }); await new Promise((r) => setImmediate(r)); expect(handler).toHaveBeenCalledWith({ z: 1 }); }); });