chore: Fix types in tests 16/N.

This commit is contained in:
cpojer
2026-02-17 11:59:29 +09:00
parent a76a9c375f
commit 7bc783cb03
5 changed files with 71 additions and 37 deletions

View File

@@ -20,33 +20,33 @@ vi.mock("../config/config.js", async (importOriginal) => {
const callGatewayMock = vi.fn();
vi.mock("../gateway/call.js", () => ({
callGateway: (...args: unknown[]) => callGatewayMock(...args),
callGateway: callGatewayMock,
randomIdempotencyKey: () => "idem-1",
}));
const webAuthExists = vi.fn(async () => false);
vi.mock("../web/session.js", () => ({
webAuthExists: (...args: unknown[]) => webAuthExists(...args),
webAuthExists,
}));
const handleDiscordAction = vi.fn(async () => ({ details: { ok: true } }));
vi.mock("../agents/tools/discord-actions.js", () => ({
handleDiscordAction: (...args: unknown[]) => handleDiscordAction(...args),
handleDiscordAction,
}));
const handleSlackAction = vi.fn(async () => ({ details: { ok: true } }));
vi.mock("../agents/tools/slack-actions.js", () => ({
handleSlackAction: (...args: unknown[]) => handleSlackAction(...args),
handleSlackAction,
}));
const handleTelegramAction = vi.fn(async () => ({ details: { ok: true } }));
vi.mock("../agents/tools/telegram-actions.js", () => ({
handleTelegramAction: (...args: unknown[]) => handleTelegramAction(...args),
handleTelegramAction,
}));
const handleWhatsAppAction = vi.fn(async () => ({ details: { ok: true } }));
vi.mock("../agents/tools/whatsapp-actions.js", () => ({
handleWhatsAppAction: (...args: unknown[]) => handleWhatsAppAction(...args),
handleWhatsAppAction,
}));
const originalTelegramToken = process.env.TELEGRAM_BOT_TOKEN;

View File

@@ -98,6 +98,7 @@ function makeRuntime() {
return {
log: vi.fn(),
error: vi.fn(),
exit: vi.fn(),
};
}

View File

@@ -1,6 +1,7 @@
import { describe, expect, it, vi } from "vitest";
import { describe, expect, it, type Mock, vi } from "vitest";
const mocks = vi.hoisted(() => {
type MockAuthProfile = { provider: string; [key: string]: unknown };
const store = {
version: 1,
profiles: {
@@ -24,7 +25,7 @@ const mocks = vi.hoisted(() => {
refresh: "oai-refresh-1234567890",
expires: Date.now() + 60_000,
},
},
} as Record<string, MockAuthProfile>,
};
return {
@@ -152,16 +153,28 @@ async function withAgentScopeOverrides<T>(
try {
return await run();
} finally {
mocks.resolveAgentModelPrimary.mockImplementation(originalPrimary);
mocks.resolveAgentModelFallbacksOverride.mockImplementation(originalFallbacks);
mocks.resolveAgentDir.mockImplementation(originalAgentDir);
if (originalPrimary) {
mocks.resolveAgentModelPrimary.mockImplementation(originalPrimary);
} else {
mocks.resolveAgentModelPrimary.mockReset();
}
if (originalFallbacks) {
mocks.resolveAgentModelFallbacksOverride.mockImplementation(originalFallbacks);
} else {
mocks.resolveAgentModelFallbacksOverride.mockReset();
}
if (originalAgentDir) {
mocks.resolveAgentDir.mockImplementation(originalAgentDir);
} else {
mocks.resolveAgentDir.mockReturnValue("/tmp/openclaw-agent");
}
}
}
describe("modelsStatusCommand auth overview", () => {
it("includes masked auth sources in JSON output", async () => {
await modelsStatusCommand({ json: true }, runtime as never);
const payload = JSON.parse(String((runtime.log as vi.Mock).mock.calls[0][0]));
const payload = JSON.parse(String((runtime.log as Mock).mock.calls[0]?.[0]));
expect(mocks.resolveOpenClawAgentDir).toHaveBeenCalled();
expect(payload.defaultModel).toBe("anthropic/claude-opus-4-5");
@@ -205,7 +218,7 @@ describe("modelsStatusCommand auth overview", () => {
async () => {
await modelsStatusCommand({ json: true, agent: "Jeremiah" }, localRuntime as never);
expect(mocks.resolveAgentDir).toHaveBeenCalledWith(expect.anything(), "jeremiah");
const payload = JSON.parse(String((localRuntime.log as vi.Mock).mock.calls[0][0]));
const payload = JSON.parse(String((localRuntime.log as Mock).mock.calls[0]?.[0]));
expect(payload.agentId).toBe("jeremiah");
expect(payload.agentDir).toBe("/tmp/openclaw-agent-custom");
expect(payload.defaultModel).toBe("openai/gpt-4");
@@ -227,8 +240,8 @@ describe("modelsStatusCommand auth overview", () => {
},
async () => {
await modelsStatusCommand({ agent: "main" }, localRuntime as never);
const output = (localRuntime.log as vi.Mock).mock.calls
.map((call) => String(call[0]))
const output = (localRuntime.log as Mock).mock.calls
.map((call: unknown[]) => String(call[0]))
.join("\n");
expect(output).toContain("Default (defaults)");
expect(output).toContain("Fallbacks (0) (defaults)");
@@ -254,7 +267,11 @@ describe("modelsStatusCommand auth overview", () => {
expect(localRuntime.exit).toHaveBeenCalledWith(1);
} finally {
mocks.store.profiles = originalProfiles;
mocks.resolveEnvApiKey.mockImplementation(originalEnvImpl);
if (originalEnvImpl) {
mocks.resolveEnvApiKey.mockImplementation(originalEnvImpl);
} else {
mocks.resolveEnvApiKey.mockReset();
}
}
});
});

View File

@@ -118,7 +118,7 @@ describe("applyGoogleGeminiModelDefault", () => {
it("overrides existing model", () => {
const cfg: OpenClawConfig = {
agents: { defaults: { model: "anthropic/claude-opus-4-5" } },
agents: { defaults: { model: { primary: "anthropic/claude-opus-4-5" } } },
};
const applied = applyGoogleGeminiModelDefault(cfg);
expectPrimaryModelChanged(applied, GOOGLE_GEMINI_DEFAULT_MODEL);
@@ -126,7 +126,7 @@ describe("applyGoogleGeminiModelDefault", () => {
it("no-ops when already gemini default", () => {
const cfg: OpenClawConfig = {
agents: { defaults: { model: GOOGLE_GEMINI_DEFAULT_MODEL } },
agents: { defaults: { model: { primary: GOOGLE_GEMINI_DEFAULT_MODEL } } },
};
const applied = applyGoogleGeminiModelDefault(cfg);
expectConfigUnchanged(applied, cfg);
@@ -176,7 +176,7 @@ describe("applyOpenAICodexModelDefault", () => {
it("sets openai-codex default when model is openai/*", () => {
const cfg: OpenClawConfig = {
agents: { defaults: { model: OPENAI_DEFAULT_MODEL } },
agents: { defaults: { model: { primary: OPENAI_DEFAULT_MODEL } } },
};
const applied = applyOpenAICodexModelDefault(cfg);
expectPrimaryModelChanged(applied, OPENAI_CODEX_DEFAULT_MODEL);
@@ -184,7 +184,7 @@ describe("applyOpenAICodexModelDefault", () => {
it("does not override openai-codex/*", () => {
const cfg: OpenClawConfig = {
agents: { defaults: { model: OPENAI_CODEX_DEFAULT_MODEL } },
agents: { defaults: { model: { primary: OPENAI_CODEX_DEFAULT_MODEL } } },
};
const applied = applyOpenAICodexModelDefault(cfg);
expectConfigUnchanged(applied, cfg);
@@ -192,7 +192,7 @@ describe("applyOpenAICodexModelDefault", () => {
it("does not override non-openai models", () => {
const cfg: OpenClawConfig = {
agents: { defaults: { model: "anthropic/claude-opus-4-5" } },
agents: { defaults: { model: { primary: "anthropic/claude-opus-4-5" } } },
};
const applied = applyOpenAICodexModelDefault(cfg);
expectConfigUnchanged(applied, cfg);

View File

@@ -1,6 +1,22 @@
import { describe, expect, it } from "vitest";
import { validateConfigObject } from "./config.js";
function expectValidConfig(result: ReturnType<typeof validateConfigObject>) {
expect(result.ok).toBe(true);
if (!result.ok) {
throw new Error("expected config to be valid");
}
return result.config;
}
function expectInvalidConfig(result: ReturnType<typeof validateConfigObject>) {
expect(result.ok).toBe(false);
if (result.ok) {
throw new Error("expected config to be invalid");
}
return result.issues;
}
describe("config irc", () => {
it("accepts basic irc config", () => {
const res = validateConfigObject({
@@ -13,9 +29,9 @@ describe("config irc", () => {
},
});
expect(res.ok).toBe(true);
expect(res.config.channels?.irc?.host).toBe("irc.libera.chat");
expect(res.config.channels?.irc?.nick).toBe("openclaw-bot");
const config = expectValidConfig(res);
expect(config.channels?.irc?.host).toBe("irc.libera.chat");
expect(config.channels?.irc?.nick).toBe("openclaw-bot");
});
it('rejects irc.dmPolicy="open" without allowFrom "*"', () => {
@@ -28,8 +44,8 @@ describe("config irc", () => {
},
});
expect(res.ok).toBe(false);
expect(res.issues[0]?.path).toBe("channels.irc.allowFrom");
const issues = expectInvalidConfig(res);
expect(issues[0]?.path).toBe("channels.irc.allowFrom");
});
it('accepts irc.dmPolicy="open" with allowFrom "*"', () => {
@@ -42,8 +58,8 @@ describe("config irc", () => {
},
});
expect(res.ok).toBe(true);
expect(res.config.channels?.irc?.dmPolicy).toBe("open");
const config = expectValidConfig(res);
expect(config.channels?.irc?.dmPolicy).toBe("open");
});
it("accepts mixed allowFrom value types for IRC", () => {
@@ -61,10 +77,10 @@ describe("config irc", () => {
},
});
expect(res.ok).toBe(true);
expect(res.config.channels?.irc?.allowFrom).toEqual([12345, "alice"]);
expect(res.config.channels?.irc?.groupAllowFrom).toEqual([67890, "alice!ident@example.org"]);
expect(res.config.channels?.irc?.groups?.["#ops"]?.allowFrom).toEqual([42, "alice"]);
const config = expectValidConfig(res);
expect(config.channels?.irc?.allowFrom).toEqual([12345, "alice"]);
expect(config.channels?.irc?.groupAllowFrom).toEqual([67890, "alice!ident@example.org"]);
expect(config.channels?.irc?.groups?.["#ops"]?.allowFrom).toEqual([42, "alice"]);
});
it("rejects nickserv register without registerEmail", () => {
@@ -79,8 +95,8 @@ describe("config irc", () => {
},
});
expect(res.ok).toBe(false);
expect(res.issues[0]?.path).toBe("channels.irc.nickserv.registerEmail");
const issues = expectInvalidConfig(res);
expect(issues[0]?.path).toBe("channels.irc.nickserv.registerEmail");
});
it("accepts nickserv register with password and registerEmail", () => {
@@ -96,8 +112,8 @@ describe("config irc", () => {
},
});
expect(res.ok).toBe(true);
expect(res.config.channels?.irc?.nickserv?.register).toBe(true);
const config = expectValidConfig(res);
expect(config.channels?.irc?.nickserv?.register).toBe(true);
});
it("accepts nickserv register with registerEmail only (password may come from env)", () => {
@@ -112,6 +128,6 @@ describe("config irc", () => {
},
});
expect(res.ok).toBe(true);
expectValidConfig(res);
});
});