64 lines
2.1 KiB
TypeScript
64 lines
2.1 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import {
|
|
captchaContext,
|
|
captchaResultResponse,
|
|
captchaTokenFrom,
|
|
verifyCaptchaOrThrow,
|
|
} from "../src/helpers.ts";
|
|
|
|
describe("CAPTCHA helper boundaries", () => {
|
|
test("extracts JSON request fallbacks without consuming the caller's request", async () => {
|
|
const request = new Request("https://example.test/verify", {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ captchaToken: 12345 }),
|
|
});
|
|
expect(await captchaTokenFrom(request)).toBe("12345");
|
|
expect(await request.json()).toEqual({ captchaToken: 12345 });
|
|
});
|
|
|
|
test("turns verification failures into stable errors and no-store responses", async () => {
|
|
const provider = {
|
|
name: "custom" as const,
|
|
client: { responseField: "captchaToken" },
|
|
verify: async () => ({
|
|
success: false as const,
|
|
code: "expired",
|
|
message: "Try again",
|
|
provider: "custom" as const,
|
|
action: "login",
|
|
}),
|
|
};
|
|
await expect(
|
|
verifyCaptchaOrThrow(provider, { providerToken: "x", action: "login" }),
|
|
).rejects.toThrow("WRN-CAPTCHA-EXPIRED: Try again");
|
|
const response = captchaResultResponse({
|
|
success: false,
|
|
code: "invalid",
|
|
provider: "custom",
|
|
action: "login",
|
|
});
|
|
expect(response.status).toBe(403);
|
|
expect(response.headers.get("cache-control")).toBe("no-store");
|
|
expect(
|
|
captchaContext({
|
|
locals: { captcha: { success: true, provider: "custom", action: "login" } },
|
|
} as never),
|
|
).toEqual({ success: true, provider: "custom", action: "login" });
|
|
expect(captchaContext({ locals: { captcha: "forged" } } as never)).toBeNull();
|
|
});
|
|
|
|
test("does not convert provider transport failures into successful verification", async () => {
|
|
const provider = {
|
|
name: "custom" as const,
|
|
client: { responseField: "captchaToken" },
|
|
verify: async () => {
|
|
throw new Error("provider timeout");
|
|
},
|
|
};
|
|
await expect(
|
|
verifyCaptchaOrThrow(provider, { providerToken: "x", action: "checkout" }),
|
|
).rejects.toThrow("provider timeout");
|
|
});
|
|
});
|