From 7bc783cb03faf5eda74a29e321261c9237923201 Mon Sep 17 00:00:00 2001 From: cpojer Date: Tue, 17 Feb 2026 11:59:29 +0900 Subject: [PATCH] chore: Fix types in tests 16/N. --- src/commands/message.e2e.test.ts | 12 ++--- src/commands/models.list.test.ts | 1 + src/commands/models/list.status.e2e.test.ts | 37 ++++++++++---- src/commands/openai-model-default.e2e.test.ts | 10 ++-- src/config/config.irc.test.ts | 48 ++++++++++++------- 5 files changed, 71 insertions(+), 37 deletions(-) diff --git a/src/commands/message.e2e.test.ts b/src/commands/message.e2e.test.ts index 08f0007b345..f4c69be3088 100644 --- a/src/commands/message.e2e.test.ts +++ b/src/commands/message.e2e.test.ts @@ -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; diff --git a/src/commands/models.list.test.ts b/src/commands/models.list.test.ts index cd269a184ee..cec01a3a4e0 100644 --- a/src/commands/models.list.test.ts +++ b/src/commands/models.list.test.ts @@ -98,6 +98,7 @@ function makeRuntime() { return { log: vi.fn(), error: vi.fn(), + exit: vi.fn(), }; } diff --git a/src/commands/models/list.status.e2e.test.ts b/src/commands/models/list.status.e2e.test.ts index 7a8a44be747..b2db4d922c0 100644 --- a/src/commands/models/list.status.e2e.test.ts +++ b/src/commands/models/list.status.e2e.test.ts @@ -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, }; return { @@ -152,16 +153,28 @@ async function withAgentScopeOverrides( 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(); + } } }); }); diff --git a/src/commands/openai-model-default.e2e.test.ts b/src/commands/openai-model-default.e2e.test.ts index c4d42752029..910c2c9c84d 100644 --- a/src/commands/openai-model-default.e2e.test.ts +++ b/src/commands/openai-model-default.e2e.test.ts @@ -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); diff --git a/src/config/config.irc.test.ts b/src/config/config.irc.test.ts index 680d10ba5e3..d778a14b342 100644 --- a/src/config/config.irc.test.ts +++ b/src/config/config.irc.test.ts @@ -1,6 +1,22 @@ import { describe, expect, it } from "vitest"; import { validateConfigObject } from "./config.js"; +function expectValidConfig(result: ReturnType) { + expect(result.ok).toBe(true); + if (!result.ok) { + throw new Error("expected config to be valid"); + } + return result.config; +} + +function expectInvalidConfig(result: ReturnType) { + 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); }); });