mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 22:30:22 +00:00
154 lines
4.5 KiB
TypeScript
154 lines
4.5 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { createConfigIO } from "./io.js";
|
|
import { withTempHome } from "./test-helpers.js";
|
|
|
|
describe("config io write", () => {
|
|
it("persists caller changes onto resolved config without leaking runtime defaults", async () => {
|
|
await withTempHome(async (home) => {
|
|
const configPath = path.join(home, ".openclaw", "openclaw.json");
|
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
await fs.writeFile(
|
|
configPath,
|
|
JSON.stringify({ gateway: { port: 18789 } }, null, 2),
|
|
"utf-8",
|
|
);
|
|
|
|
const io = createConfigIO({
|
|
env: {} as NodeJS.ProcessEnv,
|
|
homedir: () => home,
|
|
});
|
|
|
|
const snapshot = await io.readConfigFileSnapshot();
|
|
expect(snapshot.valid).toBe(true);
|
|
|
|
const next = structuredClone(snapshot.config);
|
|
next.gateway = {
|
|
...next.gateway,
|
|
auth: { mode: "token" },
|
|
};
|
|
|
|
await io.writeConfigFile(next);
|
|
|
|
const persisted = JSON.parse(await fs.readFile(configPath, "utf-8")) as Record<
|
|
string,
|
|
unknown
|
|
>;
|
|
expect(persisted.gateway).toEqual({
|
|
port: 18789,
|
|
auth: { mode: "token" },
|
|
});
|
|
expect(persisted).not.toHaveProperty("agents.defaults");
|
|
expect(persisted).not.toHaveProperty("messages.ackReaction");
|
|
expect(persisted).not.toHaveProperty("sessions.persistence");
|
|
});
|
|
});
|
|
|
|
it("preserves env var references when writing", async () => {
|
|
await withTempHome(async (home) => {
|
|
const configPath = path.join(home, ".openclaw", "openclaw.json");
|
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
await fs.writeFile(
|
|
configPath,
|
|
JSON.stringify(
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
cliBackends: {
|
|
codex: {
|
|
env: {
|
|
OPENAI_API_KEY: "${OPENAI_API_KEY}",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
gateway: { port: 18789 },
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
"utf-8",
|
|
);
|
|
|
|
const io = createConfigIO({
|
|
env: { OPENAI_API_KEY: "sk-secret" } as NodeJS.ProcessEnv,
|
|
homedir: () => home,
|
|
});
|
|
|
|
const snapshot = await io.readConfigFileSnapshot();
|
|
expect(snapshot.valid).toBe(true);
|
|
|
|
const next = structuredClone(snapshot.config);
|
|
next.gateway = {
|
|
...next.gateway,
|
|
auth: { mode: "token" },
|
|
};
|
|
|
|
await io.writeConfigFile(next);
|
|
|
|
const persisted = JSON.parse(await fs.readFile(configPath, "utf-8")) as {
|
|
agents: { defaults: { cliBackends: { codex: { env: { OPENAI_API_KEY: string } } } } };
|
|
gateway: { port: number; auth: { mode: string } };
|
|
};
|
|
expect(persisted.agents.defaults.cliBackends.codex.env.OPENAI_API_KEY).toBe(
|
|
"${OPENAI_API_KEY}",
|
|
);
|
|
expect(persisted.gateway).toEqual({
|
|
port: 18789,
|
|
auth: { mode: "token" },
|
|
});
|
|
});
|
|
});
|
|
|
|
it("keeps env refs in arrays when appending entries", async () => {
|
|
await withTempHome(async (home) => {
|
|
const configPath = path.join(home, ".openclaw", "openclaw.json");
|
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
await fs.writeFile(
|
|
configPath,
|
|
JSON.stringify(
|
|
{
|
|
channels: {
|
|
discord: {
|
|
allowFrom: ["${DISCORD_USER_ID}", "123"],
|
|
},
|
|
},
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
"utf-8",
|
|
);
|
|
|
|
const io = createConfigIO({
|
|
env: { DISCORD_USER_ID: "999" } as NodeJS.ProcessEnv,
|
|
homedir: () => home,
|
|
});
|
|
|
|
const snapshot = await io.readConfigFileSnapshot();
|
|
expect(snapshot.valid).toBe(true);
|
|
|
|
const next = structuredClone(snapshot.config);
|
|
const allowFrom = Array.isArray(next.channels?.discord?.allowFrom)
|
|
? next.channels?.discord?.allowFrom
|
|
: [];
|
|
next.channels = {
|
|
...next.channels,
|
|
discord: {
|
|
...next.channels?.discord,
|
|
allowFrom: [...allowFrom, "456"],
|
|
},
|
|
};
|
|
|
|
await io.writeConfigFile(next);
|
|
|
|
const persisted = JSON.parse(await fs.readFile(configPath, "utf-8")) as {
|
|
channels: { discord?: { allowFrom?: string[] } };
|
|
};
|
|
expect(persisted.channels.discord?.allowFrom).toEqual(["${DISCORD_USER_ID}", "123", "456"]);
|
|
});
|
|
});
|
|
});
|