Files
NetMesh/components/ai/claudeConfigEnv.test.ts

89 lines
3.2 KiB
TypeScript
Raw Normal View History

import test from "node:test";
import assert from "node:assert/strict";
import {
splitClaudeEnv,
buildClaudeEnv,
parseEnvLines,
serializeEnvLines,
} from "../settings/tabs/ai/claudeConfigEnv";
test("splitClaudeEnv pulls out config dir and hides CLAUDE_CODE_EXECUTABLE", () => {
const result = splitClaudeEnv({
CLAUDE_CONFIG_DIR: "/cfg",
CLAUDE_CODE_EXECUTABLE: "/usr/bin/claude",
ANTHROPIC_API_KEY: "sk-x",
});
assert.equal(result.configDir, "/cfg");
assert.equal(result.settingsPath, "");
assert.equal(result.envText, "ANTHROPIC_API_KEY=sk-x");
});
test("splitClaudeEnv handles undefined env", () => {
assert.deepEqual(splitClaudeEnv(undefined), { configDir: "", settingsPath: "", envText: "" });
});
test("parseEnvLines parses KEY=VALUE, trims keys, keeps value as-is, skips blanks/comments", () => {
assert.deepEqual(
parseEnvLines("ANTHROPIC_API_KEY = sk-x\n# comment\n\nANTHROPIC_BASE_URL=https://h/?a=b"),
{ ANTHROPIC_API_KEY: "sk-x", ANTHROPIC_BASE_URL: "https://h/?a=b" },
);
});
test("serializeEnvLines is the inverse for simple entries", () => {
assert.equal(serializeEnvLines({ A: "1", B: "2" }), "A=1\nB=2");
});
test("buildClaudeEnv merges config dir + parsed env, preserves CLAUDE_CODE_EXECUTABLE, drops empties", () => {
const prev = { CLAUDE_CODE_EXECUTABLE: "/usr/bin/claude", OLD: "x" };
const next = buildClaudeEnv(prev, "/cfg", "", "ANTHROPIC_API_KEY=sk-x");
assert.deepEqual(next, {
CLAUDE_CODE_EXECUTABLE: "/usr/bin/claude",
CLAUDE_CONFIG_DIR: "/cfg",
ANTHROPIC_API_KEY: "sk-x",
});
});
test("buildClaudeEnv omits config dir when blank and returns undefined when empty", () => {
assert.equal(buildClaudeEnv(undefined, " ", " ", ""), undefined);
});
test("buildClaudeEnv ignores managed keys typed into the env editor", () => {
const next = buildClaudeEnv(
{ CLAUDE_CODE_EXECUTABLE: "/usr/bin/claude" },
"/cfg",
"",
"CLAUDE_CODE_EXECUTABLE=/evil/claude\nCLAUDE_CONFIG_DIR=/evil/dir\nNETCATTY_CLAUDE_SETTINGS=/evil/settings.json\nANTHROPIC_API_KEY=sk-x",
);
assert.deepEqual(next, {
CLAUDE_CODE_EXECUTABLE: "/usr/bin/claude",
CLAUDE_CONFIG_DIR: "/cfg",
ANTHROPIC_API_KEY: "sk-x",
});
});
test("splitClaudeEnv + buildClaudeEnv round-trip the settings marker (NETCATTY_CLAUDE_SETTINGS)", () => {
const split = splitClaudeEnv({
CLAUDE_CONFIG_DIR: "/cfg",
NETCATTY_CLAUDE_SETTINGS: "/team/settings.json",
ANTHROPIC_API_KEY: "sk-x",
});
assert.equal(split.settingsPath, "/team/settings.json");
assert.equal(split.configDir, "/cfg");
// the marker is kept out of the free-text env editor
assert.equal(split.envText, "ANTHROPIC_API_KEY=sk-x");
// config dir + settings coexist (settings is additive, not a replacement for CLAUDE_CONFIG_DIR)
const rebuilt = buildClaudeEnv(undefined, "/cfg", "/team/settings.json", "ANTHROPIC_API_KEY=sk-x");
assert.deepEqual(rebuilt, {
CLAUDE_CONFIG_DIR: "/cfg",
NETCATTY_CLAUDE_SETTINGS: "/team/settings.json",
ANTHROPIC_API_KEY: "sk-x",
});
// settings alone (no config dir) is allowed
assert.deepEqual(buildClaudeEnv(undefined, "", "/only/settings.json", ""), {
NETCATTY_CLAUDE_SETTINGS: "/only/settings.json",
});
});