Files
laimiaoai-agent-new/tests/config.test.ts
T
light 6ec9778d45 chore: initial commit
Laimiao agent v2 service: agent orchestration, sessions, billing,
gateway client, skills catalog, auth, config, plus tests.
2026-11-07 10:40:07 +08:00

94 lines
3.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { join } from "node:path";
import { loadConfig } from "../src/config.js";
import { tempRoot } from "./helpers.js";
describe("loadConfig", () => {
it("applies safe defaults", () => {
const root = tempRoot();
const config = loadConfig({ APP_ROOT: root });
expect(config.port).toBe(8100);
expect(config.billing.mode).toBe("live");
expect(config.billing.currency).toBe("credits");
expect(config.gateway.mock).toBe(false);
expect(config.gateway.pollTimeoutMs).toBe(900_000);
expect(config.llm.modelId).toBe("deepseek-chat");
expect(config.dataDir).toBe(join(root, "data"));
expect(config.mysql.host).toBe("127.0.0.1");
expect(config.mysql.database).toBe("laimiaodb");
expect(config.skillDefaults.model).toBe("gpt-image-2");
expect(config.toolConfirmation.enabled).toBe(true);
expect(config.toolConfirmation.tools).toEqual(["generate_image"]);
expect(config.toolConfirmation.timeoutMs).toBe(300_000);
expect(config.modelsFile).toBe(join(root, "data", "pi", "models.json"));
});
it("parses booleans and integers from env strings", () => {
const config = loadConfig({
APP_ROOT: tempRoot(),
PORT: "9001",
GATEWAY_MOCK: "TRUE",
BILLING_MODE: "off",
LAIMIAO_LLM_REASONING: "1",
GATEWAY_POLL_INTERVAL_MS: "250",
TOOL_CONFIRMATION_TOOLS: "generate_image, quote_image",
});
expect(config.port).toBe(9001);
expect(config.gateway.mock).toBe(true);
expect(config.billing.mode).toBe("off");
expect(config.llm.reasoning).toBe(true);
expect(config.gateway.pollIntervalMs).toBe(250);
expect(config.toolConfirmation.tools).toEqual(["generate_image", "quote_image"]);
});
it("treats an empty integer as the default", () => {
const config = loadConfig({ APP_ROOT: tempRoot(), PORT: "" });
expect(config.port).toBe(8100);
});
it("rejects invalid port and billing mode", () => {
expect(() => loadConfig({ APP_ROOT: tempRoot(), PORT: "0" })).toThrow(/PORT/);
expect(() => loadConfig({ APP_ROOT: tempRoot(), BILLING_MODE: "always" })).toThrow(/BILLING_MODE/);
});
it("rejects malformed gateway and LLM URLs", () => {
expect(() => loadConfig({ APP_ROOT: tempRoot(), GATEWAY_CN_URL: "not-a-url" })).toThrow(/GATEWAY_CN_URL/);
expect(() => loadConfig({ APP_ROOT: tempRoot(), LAIMIAO_LLM_BASE_URL: "ftp://x" })).toThrow(
/LAIMIAO_LLM_BASE_URL/,
);
});
it("enforces production security requirements", () => {
const base = {
APP_ROOT: tempRoot(),
NODE_ENV: "production",
JWT_KEY: "secret",
CORS_ORIGIN: "https://app.example.com",
FILE_FETCH_ALLOWED_HOSTS: "cdn.example.com,*.oss.example.com",
};
expect(() => loadConfig({ ...base, JWT_KEY: "" })).toThrow(/JWT_KEY/);
expect(() => loadConfig({ ...base, CORS_ORIGIN: "*" })).toThrow(/CORS_ORIGIN/);
expect(() => loadConfig({ ...base, CORS_ORIGIN: "https://app.example.com/path" })).toThrow(/CORS_ORIGIN/);
expect(() => loadConfig({ ...base, FILE_FETCH_ALLOWED_HOSTS: "" })).toThrow(/FILE_FETCH_ALLOWED_HOSTS/);
const config = loadConfig(base);
expect(config.isProduction).toBe(true);
expect(config.fileFetchAllowedHosts).toEqual(["cdn.example.com", "*.oss.example.com"]);
});
it("keeps permissive defaults outside production", () => {
const config = loadConfig({ APP_ROOT: tempRoot() });
expect(config.nodeEnv).toBe("development");
expect(config.isProduction).toBe(false);
expect(config.fileFetchAllowedHosts).toEqual([]);
});
it("resolves relative paths against APP_ROOT", () => {
const root = tempRoot();
const config = loadConfig({ APP_ROOT: root, DATA_DIR: "var/state" });
expect(config.dataDir).toBe(join(root, "var/state"));
expect(config.ledgerFile).toBe(join(root, "var/state/usage-ledger.jsonl"));
});
});