import { describe, test, expect } from "bun:test"; import { SQL } from "bun"; /** 后台任务队列:入队 → worker 处理 → done 状态 */ describe("jobs 队列", () => { test("email.send 任务被 worker 消费并标记 done", async () => { const sql = new SQL(process.env.DATABASE_URL || "postgres://dusuniot:dusuniot@127.0.0.1:25432/dusuniot"); const [row]: any = await sql`INSERT INTO jobs (type, payload) VALUES ('email.send', ${JSON.stringify({ to: "t@t.io", subject: "s", body: "b" })}::jsonb) RETURNING id`.values(); const id = row[0]; // 跑一次 worker 主循环(10 秒后自动退出) const { runWorkerLoop } = await import("../src/server/jobs"); const controller = new AbortController(); // 用短超时跑一轮:直接调用 claimJob 的逻辑由 loop 内部处理,这里以 1 个任务处理完为标准 await Promise.race([runWorkerLoop(1500), Bun.sleep(4000)]); const [status]: any = await sql`SELECT status FROM jobs WHERE id=${id}`.values(); expect(status[0]).toBe("done"); await sql`DELETE FROM jobs WHERE id=${id}`; sql.end(); }, 10000); });