openclaw/src/commands/models.set.test.ts

129 lines
3.7 KiB
TypeScript

import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
const readConfigFileSnapshot = vi.fn();
const writeConfigFile = vi.fn().mockResolvedValue(undefined);
const loadConfig = vi.fn().mockReturnValue({});
vi.mock("../config/config.js", () => ({
CONFIG_PATH: "/tmp/openclaw.json",
readConfigFileSnapshot,
writeConfigFile,
loadConfig,
}));
function mockConfigSnapshot(config: Record<string, unknown> = {}) {
readConfigFileSnapshot.mockResolvedValue({
path: "/tmp/openclaw.json",
exists: true,
raw: "{}",
parsed: {},
valid: true,
config,
issues: [],
legacyIssues: [],
});
}
function makeRuntime() {
return { log: vi.fn(), error: vi.fn(), exit: vi.fn() };
}
function getWrittenConfig() {
return writeConfigFile.mock.calls[0]?.[0] as Record<string, unknown>;
}
function expectWrittenPrimaryModel(model: string) {
expect(writeConfigFile).toHaveBeenCalledTimes(1);
const written = getWrittenConfig();
expect(written.agents).toEqual({
defaults: {
model: { primary: model },
models: { [model]: {} },
},
});
}
let modelsSetCommand: typeof import("./models/set.js").modelsSetCommand;
let modelsFallbacksAddCommand: typeof import("./models/fallbacks.js").modelsFallbacksAddCommand;
describe("models set + fallbacks", () => {
beforeAll(async () => {
({ modelsSetCommand } = await import("./models/set.js"));
({ modelsFallbacksAddCommand } = await import("./models/fallbacks.js"));
});
beforeEach(() => {
readConfigFileSnapshot.mockClear();
writeConfigFile.mockClear();
});
it("normalizes z.ai provider in models set", async () => {
mockConfigSnapshot({});
const runtime = makeRuntime();
await modelsSetCommand("z.ai/glm-4.7", runtime);
expectWrittenPrimaryModel("zai/glm-4.7");
});
it("normalizes z-ai provider in models fallbacks add", async () => {
mockConfigSnapshot({ agents: { defaults: { model: { fallbacks: [] } } } });
const runtime = makeRuntime();
await modelsFallbacksAddCommand("z-ai/glm-4.7", runtime);
expect(writeConfigFile).toHaveBeenCalledTimes(1);
const written = getWrittenConfig();
expect(written.agents).toEqual({
defaults: {
model: { fallbacks: ["zai/glm-4.7"] },
models: { "zai/glm-4.7": {} },
},
});
});
it("preserves primary when adding fallbacks to string defaults.model", async () => {
mockConfigSnapshot({ agents: { defaults: { model: "openai/gpt-4.1-mini" } } });
const runtime = makeRuntime();
await modelsFallbacksAddCommand("anthropic/claude-opus-4-6", runtime);
expect(writeConfigFile).toHaveBeenCalledTimes(1);
const written = getWrittenConfig();
expect(written.agents).toEqual({
defaults: {
model: {
primary: "openai/gpt-4.1-mini",
fallbacks: ["anthropic/claude-opus-4-6"],
},
models: { "anthropic/claude-opus-4-6": {} },
},
});
});
it("normalizes provider casing in models set", async () => {
mockConfigSnapshot({});
const runtime = makeRuntime();
await modelsSetCommand("Z.AI/glm-4.7", runtime);
expectWrittenPrimaryModel("zai/glm-4.7");
});
it("rewrites string defaults.model to object form when setting primary", async () => {
mockConfigSnapshot({ agents: { defaults: { model: "openai/gpt-4.1-mini" } } });
const runtime = makeRuntime();
await modelsSetCommand("anthropic/claude-opus-4-6", runtime);
expect(writeConfigFile).toHaveBeenCalledTimes(1);
const written = getWrittenConfig();
expect(written.agents).toEqual({
defaults: {
model: { primary: "anthropic/claude-opus-4-6" },
models: { "anthropic/claude-opus-4-6": {} },
},
});
});
});