import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest" ;
import { withEnv } from "../test-utils/env.js" ;
const loggerMocks = vi.hoisted(() => ({
info: vi.fn(),
}));
vi.mock("../logging/subsystem.js" , () => ({
createSubsystemLogger: () => ({
info: loggerMocks.info,
}),
}));
type EnvModule = typeof import ("./env.js" );
let isTruthyEnvValue: EnvModule["isTruthyEnvValue" ];
let logAcceptedEnvOption: EnvModule["logAcceptedEnvOption" ];
let normalizeEnv: EnvModule["normalizeEnv" ];
let normalizeZaiEnv: EnvModule["normalizeZaiEnv" ];
beforeAll(async () => {
vi.resetModules();
({ isTruthyEnvValue, logAcceptedEnvOption, normalizeEnv, normalizeZaiEnv } =
await import ("./env.js" ));
});
beforeEach(() => {
loggerMocks.info.mockClear();
});
describe("normalizeZaiEnv" , () => {
it("copies Z_AI_API_KEY to ZAI_API_KEY when missing" , () => {
withEnv({ ZAI_API_KEY: "" , Z_AI_API_KEY: "zai-legacy" }, () => {
normalizeZaiEnv();
expect(process.env.ZAI_API_KEY).toBe("zai-legacy" );
});
});
it("does not override existing ZAI_API_KEY" , () => {
withEnv({ ZAI_API_KEY: "zai-current" , Z_AI_API_KEY: "zai-legacy" }, () => {
normalizeZaiEnv();
expect(process.env.ZAI_API_KEY).toBe("zai-current" );
});
});
it("ignores blank legacy Z_AI_API_KEY values" , () => {
withEnv({ ZAI_API_KEY: "" , Z_AI_API_KEY: " " }, () => {
normalizeZaiEnv();
expect(process.env.ZAI_API_KEY).toBe("" );
});
});
it("does not copy when legacy Z_AI_API_KEY is unset" , () => {
withEnv({ ZAI_API_KEY: "" , Z_AI_API_KEY: undefined }, () => {
normalizeZaiEnv();
expect(process.env.ZAI_API_KEY).toBe("" );
});
});
});
describe("isTruthyEnvValue" , () => {
it("accepts common truthy values" , () => {
expect(isTruthyEnvValue("1" )).toBe(true );
expect(isTruthyEnvValue("true" )).toBe(true );
expect(isTruthyEnvValue(" yes " )).toBe(true );
expect(isTruthyEnvValue("ON" )).toBe(true );
});
it("rejects other values" , () => {
expect(isTruthyEnvValue("0" )).toBe(false );
expect(isTruthyEnvValue("false" )).toBe(false );
expect(isTruthyEnvValue("" )).toBe(false );
expect(isTruthyEnvValue(undefined)).toBe(false );
});
});
describe("logAcceptedEnvOption" , () => {
it("logs accepted env options once with redaction and formatting" , () => {
loggerMocks.info.mockClear();
withEnv(
{
VITEST: "" ,
NODE_ENV: "development" ,
OPENCLAW_TEST_ENV: " line one\nline two " ,
},
() => {
logAcceptedEnvOption({
key: "OPENCLAW_TEST_ENV" ,
description: "test option" ,
redact: true ,
});
logAcceptedEnvOption({
key: "OPENCLAW_TEST_ENV" ,
description: "test option" ,
redact: true ,
});
},
);
expect(loggerMocks.info).toHaveBeenCalledTimes(1 );
expect(loggerMocks.info).toHaveBeenCalledWith(
"env: OPENCLAW_TEST_ENV=<redacted> (test option)" ,
);
});
it("skips blank values and test-mode logging" , () => {
loggerMocks.info.mockClear();
withEnv(
{
VITEST: "1" ,
NODE_ENV: "development" ,
OPENCLAW_BLANK_ENV: "value" ,
},
() => {
logAcceptedEnvOption({
key: "OPENCLAW_BLANK_ENV" ,
description: "skipped in vitest" ,
});
},
);
withEnv(
{
VITEST: "" ,
NODE_ENV: "development" ,
OPENCLAW_BLANK_ENV: " " ,
},
() => {
logAcceptedEnvOption({
key: "OPENCLAW_BLANK_ENV" ,
description: "blank value" ,
});
},
);
expect(loggerMocks.info).not.toHaveBeenCalled();
});
});
describe("normalizeEnv" , () => {
it("normalizes the legacy ZAI env alias" , () => {
withEnv({ ZAI_API_KEY: "" , Z_AI_API_KEY: "zai-legacy" }, () => {
normalizeEnv();
expect(process.env.ZAI_API_KEY).toBe("zai-legacy" );
});
});
});
Messung V0.5 in Prozent C=100 H=100 G=100
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-09)
¤
*© Formatika GbR, Deutschland