// @ts-nocheck /** * 每个 Jest worker 在任何被测模块被 import 之前执行(setupFiles 阶段)。 * * 职责:把数据源**无条件**钉死到 /tmp 的一次性库,并在钉死之前先做守卫断言。 * 这一步是必须的:src/lib/db.ts 里 `new PrismaClient()` 无参构造,运行时读 env("DATABASE_URL"), * 只要该变量残留成 prisma/dev.db,测试就会写真库 —— 所以宁可在这里直接抛错。 */ const fs = require('fs'); const { TextEncoder, TextDecoder } = require('util'); const guard = require('./env.js'); // 1) 取 globalSetup 落盘的 URL;拿不到就退回固定路径,但两种来源都必须通过守卫 let url = process.env.DATABASE_URL; try { const manifest = JSON.parse(fs.readFileSync(guard.MANIFEST_PATH, 'utf8')); url = manifest.datasourceUrl; } catch { url = guard.DATASOURCE_URL; } // 2) 守卫:绝对 file: URL、位于 realpath(os.tmpdir()) 之下、不是仓库内路径、不是 dev.db/data.db const resolved = guard.assertSafeDatasourceUrl(url, 'setupFiles'); // 3) 项目库指纹必须仍与 setup 阶段一致(worker 起来就已经是最早的写入者之前) try { const manifest = JSON.parse(fs.readFileSync(guard.MANIFEST_PATH, 'utf8')); const now = guard.devDbBaselines(); const drift = Object.keys(manifest.baseline || {}).filter( (k) => !guard.sameFingerprint(manifest.baseline[k], now[k]), ); if (drift.length > 0) { throw new Error(`[itest:setupFiles] 项目数据源指纹漂移:${drift.join(', ')}`); } } catch (e) { if (String(e.message).includes('指纹漂移')) throw e; /* manifest 缺失时由 globalSetup 的断言负责 */ } process.env.DATABASE_URL = url; process.env.NOVALON_ITEST_DB = resolved; // 测试专用 JWT 密钥:刻意不读 .env*,保证集成层与本机开发密钥完全隔离 process.env.JWT_SECRET = 'novalon-integration-only-access-secret'; process.env.JWT_REFRESH_SECRET = 'novalon-integration-only-refresh-secret'; process.env.NEXT_PUBLIC_APP_URL = 'http://localhost:3000'; // 4) jsdom 环境的最小 Node 能力补齐(与 jest.setup.js:4-6 同源,但本文件不加载全局 mock) if (typeof globalThis.TextEncoder === 'undefined') globalThis.TextEncoder = TextEncoder; if (typeof globalThis.TextDecoder === 'undefined') globalThis.TextDecoder = TextDecoder; console.log(`[itest:worker] DATABASE_URL pinned to ${url} (resolved ${resolved})`);