import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import type { DB, Kysely } from "@umt/db"; import { afterAll, describe, expect, it } from "vitest"; import { type Config, ConfigSchema } from "../src/config.ts"; import { runPreflight } from "../src/preflight.ts"; const dir = mkdtempSync(join(tmpdir(), "umt-pre-")); afterAll(() => rmSync(dir, { recursive: true, force: true })); // 最小假 Kysely:只需要 sql`select 1`.execute(db) 走得通或失败 const fakeDb = (ok: boolean) => ({ getExecutor: () => ({ transformQuery: (n: unknown) => n, compileQuery: (n: unknown) => ({ sql: "select 1", parameters: [], query: n }), executeQuery: async () => { if (!ok) throw new Error("connect ECONNREFUSED"); return { rows: [{ "?column?": 1 }] }; }, }), }) as unknown as Kysely; const cfg = (over: Record): Config => ConfigSchema.parse({ DATABASE_URL: "postgres://x/y", SECRET_MASTER_KEY: "a-real-random-secret-value-123", ...over }); describe("启动自检", () => { it("开发环境、DB 可达 → 通过", async () => { expect(await runPreflight({ config: cfg({}), db: fakeDb(true), uid: 0 })).toEqual([]); }); it("生产环境:占位符密钥、root、DB 不可达、WEB_ROOT 缺 index.html 都报出", async () => { const problems = await runPreflight({ config: cfg({ NODE_ENV: "production", SECRET_MASTER_KEY: "dev-only-change-me-dev-only", WEB_ROOT: dir }), db: fakeDb(false), uid: 0, }); expect(problems.map((p) => p.check).sort()).toEqual(["db", "secret", "user", "web"]); }); it("WEB_ROOT 有 index.html、非 root → 通过", async () => { writeFileSync(join(dir, "index.html"), ""); const config = cfg({ NODE_ENV: "production", WEB_ROOT: dir }); expect(await runPreflight({ config, db: fakeDb(true), uid: 1000 })).toEqual([]); }); });