Files
cfw-autumn/server/tests/unit/webhooks/stripe-webhook-early-ack.test.ts
2026-04-28 17:31:50 +01:00

98 lines
2.5 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { Hono } from "hono";
import { stripeWebhookEarlyAckMiddleware } from "@/external/stripe/webhookMiddlewares/stripeWebhookEarlyAckMiddleware";
const waitForImmediate = () => new Promise((resolve) => setImmediate(resolve));
const createApp = () => {
const app = new Hono();
app.use("*", async (c, next) => {
(c as any).set("ctx", {
logger: {
error: () => {},
},
});
await next();
});
return app;
};
describe("stripeWebhookEarlyAckMiddleware", () => {
test("uses executionCtx.waitUntil when the runtime provides it", async () => {
const waits: Promise<unknown>[] = [];
let processed = false;
const response = await stripeWebhookEarlyAckMiddleware(
{
get: () => ({
logger: { error: () => {} },
}),
json: (body: unknown, status: number) =>
new Response(JSON.stringify(body), { status }),
executionCtx: {
waitUntil: (promise: Promise<unknown>) => waits.push(promise),
},
} as never,
async () => {
processed = true;
},
);
expect(response.status).toBe(200);
expect(await response.json()).toEqual({ received: true });
expect(waits).toHaveLength(1);
await waits[0];
expect(processed).toBe(true);
});
test("returns 200 before downstream webhook processing completes", async () => {
const app = createApp();
let resolveProcessing!: () => void;
let processed = false;
const processing = new Promise<void>((resolve) => {
resolveProcessing = resolve;
});
app.post(
"/webhook",
stripeWebhookEarlyAckMiddleware as never,
async (c) => {
await processing;
processed = true;
return c.json({ processed: true }, 200);
},
);
const response = await app.request("/webhook", { method: "POST" });
expect(response.status).toBe(200);
expect(await response.json()).toEqual({ received: true });
expect(processed).toBe(false);
resolveProcessing();
await waitForImmediate();
expect(processed).toBe(true);
});
test("does not run downstream webhook processing before returning", async () => {
const app = createApp();
let started = false;
app.post("/webhook", stripeWebhookEarlyAckMiddleware as never, (c) => {
started = true;
return c.json({ processed: true }, 200);
});
const response = await app.request("/webhook", { method: "POST" });
expect(response.status).toBe(200);
expect(await response.json()).toEqual({ received: true });
expect(started).toBe(false);
await waitForImmediate();
expect(started).toBe(true);
});
});