import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
const env: Record<string, string | undefined> = {};
mock.module("cloudflare:workers", () => ({ env, waitUntil: () => undefined }));
mock.module("./limits", () => ({ rawRequestIp: () => "203.0.113.9" }));
const { requireTurnstile, turnstileSiteKey } = await import("./turnstile");
const realFetch = globalThis.fetch;
let calls: URLSearchParams[] = [];
let reply: { status: number; body: unknown } = { status: 200, body: {} };
beforeEach(() => {
Object.assign(env, {
PUBLIC_URL: "https://gitfor.dev",
TURNSTILE_SITEKEY: "0x4AAAAAAFUg9PmDIBH5nisz",
TURNSTILE_SECRET: "secret",
TURNSTILE_HOSTNAMES: "",
});
calls = [];
reply = { status: 200, body: { success: true, action: "signup", hostname: "gitfor.dev" } };
globalThis.fetch = (async (_url: string, init: RequestInit) => {
calls.push(new URLSearchParams(String(init.body)));
return new Response(JSON.stringify(reply.body), { status: reply.status });
}) as unknown as typeof fetch;
});
afterEach(() => {
globalThis.fetch = realFetch;
});
describe("requireTurnstile", () => {
test("accepts a token Siteverify vouches for, sending secret, token and client IP", async () => {
await requireTurnstile("tok", "signup");
expect(calls).toHaveLength(1);
expect(calls[0].get("secret")).toBe("secret");
expect(calls[0].get("response")).toBe("tok");
expect(calls[0].get("remoteip")).toBe("203.0.113.9");
});