import { expect, test } from "bun:test"; import { readFile } from "node:fs/promises"; import { join } from "node:path"; const packageRoot = join(import.meta.dir, ".."); test("Captcha browser runtime is valid JavaScript and exposes the expected lifecycle", async () => { const source = await readFile(join(packageRoot, "assets/client/captcha.js"), "utf8"); expect(() => new Function(source)).not.toThrow(); expect(source).toContain("__wrnexusCaptchaRuntime"); expect(source).toContain("createChallenge"); expect(source).toContain("verify(state)"); expect(source).toContain("mountExternal"); expect(source).toContain("captchaDisturbance"); expect(source).toContain("captchaImageStyle"); expect(source).toContain("captchaAllowedStyles"); expect(source).toContain("captchaExcludedStyles"); expect(source).toContain("captchaRandomizeStyle"); expect(source).toContain("captchaResolvedImageStyle"); expect(source).toContain("captchaShowListen"); expect(source).toContain("captchaResetOnError"); expect(source).toContain("normalizeSize"); expect(source).toContain("verifyNotRobot"); expect(source).toContain("stopImmediatePropagation"); expect(source).toContain("__wireSubmitGuards"); expect(source).toContain("__wireValidateBound"); expect(source).toContain("passesSubmitGuard"); expect(source).toContain('addEventListener("submit"'); expect(source).toContain('addEventListener("wire:error"'); expect(source).toContain("state.config.resetOnError || captchaFailed"); expect(source).toContain('state.status !== "ready" && state.status !== "incorrect"'); expect(source).toContain('state.status === "incorrect") setStatus(state, "ready", "")'); expect(source).toContain("Verified response tokens are single-use"); expect(source).toContain("MutationObserver"); expect(source).toContain("new CustomEvent(name"); }); test("Captcha component delegates native browser work to the packaged runtime", async () => { const source = await readFile(join(packageRoot, "components/Captcha.wrn"), "utf8"); expect(source).toContain('data-wrnexus-runtime="captcha"'); expect(source).not.toContain("