/// import { afterEach, describe, expect, mock, test } from "bun:test"; import type { BackgroundJob } from "../../web/src/server/jobs/queue"; import { sendScheduledInvoice } from "../src/send-invoice"; const originalFetch = globalThis.fetch; const originalAppUrl = process.env.APP_INTERNAL_URL; const originalSecret = process.env.CRON_SECRET; function scheduledJob(): BackgroundJob { const now = new Date("2026-08-17T16:00:00.000Z"); return { id: "job-1", type: "invoice.send_scheduled", payload: { invoiceId: "invoice-1", actorUserId: "user-1", customMessage: "Thanks!", timeZone: "America/New_York", }, status: "processing", idempotencyKey: "invoice.send_scheduled:invoice-1:once", runAt: now, attempts: 1, maxAttempts: 5, lockedAt: now, lockedBy: "worker-1", lastError: null, completedAt: null, createdAt: now, updatedAt: now, }; } afterEach(() => { globalThis.fetch = originalFetch; if (originalAppUrl === undefined) delete process.env.APP_INTERNAL_URL; else process.env.APP_INTERNAL_URL = originalAppUrl; if (originalSecret === undefined) delete process.env.CRON_SECRET; else process.env.CRON_SECRET = originalSecret; }); describe("scheduled invoice delivery", () => { test("calls the internal app endpoint with auth and an idempotency key", async () => { process.env.APP_INTERNAL_URL = "http://app:3000/"; process.env.CRON_SECRET = "worker-secret"; const fetchMock = mock( async (_url: string | URL | Request, _request?: RequestInit) => Response.json({ success: true, emailId: "email-1" }), ); globalThis.fetch = fetchMock as unknown as typeof fetch; await sendScheduledInvoice(scheduledJob()); expect(fetchMock).toHaveBeenCalledTimes(1); const [url, request] = fetchMock.mock.calls[0]!; expect(url).toBe("http://app:3000/api/internal/jobs/send-invoice"); expect(request?.headers).toEqual({ Authorization: "Bearer worker-secret", "Content-Type": "application/json", }); expect(JSON.parse(String(request?.body))).toMatchObject({ jobId: "job-1", invoiceId: "invoice-1", actorUserId: "user-1", idempotencyKey: "invoice.send_scheduled:invoice-1:once", timeZone: "America/New_York", }); }); test("surfaces retryable delivery errors to the worker", async () => { process.env.APP_INTERNAL_URL = "http://app:3000"; process.env.CRON_SECRET = "worker-secret"; globalThis.fetch = mock( async (_url: string | URL | Request, _request?: RequestInit) => Response.json( { error: "Email service is unavailable" }, { status: 503 }, ), ) as unknown as typeof fetch; await expect(sendScheduledInvoice(scheduledJob())).rejects.toThrow( "Email service is unavailable", ); }); });