import { describe, expect, test } from "bun:test"; import { existsSync, readFileSync } from "node:fs"; import { join } from "node:path"; const showcaseRoot = join(import.meta.dir, ".."); function path(relativePath: string): string { return join(showcaseRoot, relativePath); } function read(relativePath: string): string { return readFileSync(path(relativePath), "utf8"); } describe("CAPTCHA showcase structure", () => { test("ships the required pages, routes, middleware, and component", () => { const requiredFiles = [ "app/pages/index.wrn", "app/pages/captcha.wrn", "app/pages/protected.wrn", "app/pages/styles.wrn", "app/components/Captcha.wrn", "app/api/contact.ts", "app/api/page-grant.ts", "app/schemas/contact.ts", "app/lib/captcha.ts", "app/middleware/captcha-page-gate.ts", "app/styles/global.css", "wrnexus.config.ts", ]; for (const relativePath of requiredFiles) { expect(existsSync(path(relativePath))).toBe(true); } }); test("configures Tailwind and Lucide Iconify utilities", () => { const packageJson = read("package.json"); const styles = read("app/styles/global.css"); expect(packageJson).toContain('"@iconify-json/lucide"'); expect(packageJson).toContain('"@iconify/tailwind4"'); expect(styles).toContain('@plugin "@iconify/tailwind4";'); expect(styles).toContain('@source "../../../packages/captcha/components/*.wrn";'); }); test("documents every bundled challenge mode", () => { const source = read("app/pages/index.wrn"); const expectedExamples = [ 'type="number"', 'type="alpha"', 'type="alphanumeric"', 'type="calculation"', 'type="image"', 'type="timing"', 'type="not-robot"', 'presentation="audio"', 'presentation="invisible"', ]; for (const example of expectedExamples) { expect(source).toContain(example); } expect(source.match(/ { const source = read("app/pages/styles.wrn"); const styles = [ "classic", "collision", "snow", "corrosion", "spiderweb", "cross-shadow", "split", "split2", "cut", "darts", "distortion", "stitch", "striped", "wave", "grid-noise", "scribble", "pixel", "broken-lines", ]; for (const style of styles) { expect(source).toContain(`imageStyle="${style}"`); } expect(source).toContain('imageStyle="random"'); expect(source).toContain('allowedStyles="classic,snow,distortion,wave"'); expect(source).toContain('excludedStyles="collision,split,split2,broken-lines"'); expect(source).toContain('difficulty="easy"'); expect(source).toContain('difficulty="normal"'); expect(source).toContain('difficulty="hard"'); expect(source.match(/ { const source = read("app/pages/index.wrn"); expect(source).toContain('action="/api/contact"'); expect(source).toContain('data-schema="contact"'); expect(source).toContain('action="contact-submit"'); expect(source).toContain('data-error="email"'); expect(source).toContain('data-error="message"'); expect(source).toContain('provider="turnstile"'); expect(source).toContain('provider="recaptcha"'); expect(source).toContain('provider="hcaptcha"'); }); }); describe("CAPTCHA showcase integration", () => { test("configures the self-hosted engine and HTTP handlers", () => { const source = read("app/lib/captcha.ts"); expect(source).toContain("createCaptchaEngine"); expect(source).toContain("createCaptchaHttpHandlers"); expect(source).toContain('basePath: "/api/captcha"'); expect(source).toContain("challengeTtlMs: 2 * 60_000"); expect(source).toContain("responseTokenTtlMs: 5 * 60_000"); expect(source).toContain("maxAttempts: 3"); }); test("protects the contact form with a server-side guard", () => { const source = read("app/api/contact.ts"); expect(source).toContain("captchaGuard"); expect(source).toContain('action: "contact-submit"'); expect(source).toContain('responseField: "wrn-captcha-response"'); expect(source).toContain("bindHostname: true"); expect(source).toContain("bindSession: true"); expect(source).toContain("parseBody"); expect(source).toContain("contactSchema"); expect(source).toContain("ctx.req.clone()"); }); test("protects the page route with a session grant", () => { const middleware = read("app/middleware/captcha-page-gate.ts"); const challengePage = read("app/pages/captcha.wrn"); expect(middleware).toContain("captchaPageGate"); expect(middleware).toContain('action: "protected-page-access"'); expect(middleware).toContain('mode: "session"'); expect(middleware).toContain("verifiedForMs: 15 * 60_000"); expect(middleware).toContain('routeGroups: ["/protected"]'); expect(middleware).toContain('ctx.url.pathname === "/api/page-grant"'); expect(challengePage).toContain('action="protected-page-access"'); expect(challengePage).toContain('action="/api/page-grant"'); expect(challengePage).toContain('name="returnTo"'); expect(challengePage).toContain("value='{returnTo}'"); const grantRoute = read("app/api/page-grant.ts"); expect(grantRoute).toContain("safeReturnPath"); expect(grantRoute).toContain('form.get("returnTo")'); expect(grantRoute).toContain("Response.redirect"); }); test("registers the CAPTCHA plugin and DevToolbar audit", () => { const source = read("wrnexus.config.ts"); expect(source).toContain("captchaPlugin"); expect(source).toContain("enableDevToolbar: true"); }); test("ships the expected component events and response field", () => { const source = read("app/components/Captcha.wrn"); const expectedEvents = [ "ready", "challenge", "input", "verify", "success", "failure", "expired", "refresh", "audioStart", "audioEnd", "error", ]; expect(source).toContain('name = "wrn-captcha-response"'); expect(source).toContain('responseField = "wrn-captcha-response"'); expect(source).toContain('disturbance = 50'); expect(source).toContain('size = "normal"'); expect(source).toContain('showListen = true'); expect(source).toContain('imageStyle = "random"'); expect(source).toContain('allowedStyles = ""'); expect(source).toContain('excludedStyles = ""'); expect(source).toContain('randomizeStyle = false'); expect(source).toContain('data-captcha-not-robot-button'); for (const eventName of expectedEvents) { expect(source).toContain(`@event ${eventName} = function`); } }); });