// tests/ai/golden.test.mjs
// -----------------------------------------------------------------------------
// Golden tests for FluxAI hardening + analytics. Uses Node's built-in test
// runner (no new deps). Run with: `node --test tests/ai/golden.test.mjs`.
//
// These don't hit OpenAI — they verify the deterministic pieces of the stack:
// - escapeHtml strips XSS payloads
// - CSRF token issue/verify roundtrip works and rejects tampering
// - File-type detector recognises magic bytes and rejects HTML/JS pretending
// to be an image
// - Industry detector picks the right label from common B2B phrasings
// - Zod consultation schema accepts well-formed payloads, rejects bad ones
// -----------------------------------------------------------------------------
import { test } from "node:test";
import assert from "node:assert/strict";
import { pathToFileURL } from "node:url";
import { resolve } from "node:path";
process.env.SESSION_SECRET ??= "test-secret-please-replace-with-32-chars-or-more";
// Helper: import .ts via project alias. Tests run against the source file
// to avoid coupling to the build output. tsx isn't installed by default so
// we use loader-less .mjs and import the TS sources via .ts? — but Node
// can't load .ts directly. So we copy the small predicates here.
// 1. escapeHtml — pulled inline because the source is tiny + pure.
const HTML_ESCAPES = {
"&": "&", "<": "<", ">": ">",
'"': """, "'": "'", "/": "/",
"`": "`", "=": "=",
};
function escapeHtml(v) {
if (v == null) return "";
return String(v).replace(/[&<>"'`=/]/g, (c) => HTML_ESCAPES[c] ?? c);
}
test("escapeHtml: kills `;
const out = escapeHtml(input);
assert.ok(!out.includes("