diff --git a/src/discord/monitor/exec-approvals.test.ts b/src/discord/monitor/exec-approvals.test.ts index a1a03a3b2..de600ad52 100644 --- a/src/discord/monitor/exec-approvals.test.ts +++ b/src/discord/monitor/exec-approvals.test.ts @@ -79,7 +79,7 @@ function createHandler(config: DiscordExecApprovalConfig, accountId = "default") }); } -type ExecApprovalHandlerInternals = DiscordExecApprovalHandler & { +type ExecApprovalHandlerInternals = { pending: Map< string, { discordMessageId: string; discordChannelId: string; timeoutId: NodeJS.Timeout } diff --git a/src/discord/monitor/message-handler.process.test.ts b/src/discord/monitor/message-handler.process.test.ts index f11b6d80f..a5cd599ac 100644 --- a/src/discord/monitor/message-handler.process.test.ts +++ b/src/discord/monitor/message-handler.process.test.ts @@ -12,12 +12,12 @@ const readSessionUpdatedAt = vi.fn(() => undefined); const resolveStorePath = vi.fn(() => "/tmp/openclaw-discord-process-test-sessions.json"); vi.mock("../send.js", () => ({ - reactMessageDiscord: (...args: unknown[]) => reactMessageDiscord(...args), - removeReactionDiscord: (...args: unknown[]) => removeReactionDiscord(...args), + reactMessageDiscord, + removeReactionDiscord, })); vi.mock("../../auto-reply/dispatch.js", () => ({ - dispatchInboundMessage: (...args: unknown[]) => dispatchInboundMessage(...args), + dispatchInboundMessage, })); vi.mock("../../auto-reply/reply/reply-dispatcher.js", () => ({ @@ -36,12 +36,12 @@ vi.mock("../../auto-reply/reply/reply-dispatcher.js", () => ({ })); vi.mock("../../channels/session.js", () => ({ - recordInboundSession: (...args: unknown[]) => recordInboundSession(...args), + recordInboundSession, })); vi.mock("../../config/sessions.js", () => ({ - readSessionUpdatedAt: (...args: unknown[]) => readSessionUpdatedAt(...args), - resolveStorePath: (...args: unknown[]) => resolveStorePath(...args), + readSessionUpdatedAt, + resolveStorePath, })); const { processDiscordMessage } = await import("./message-handler.process.js"); diff --git a/src/discord/monitor/provider.rest-proxy.test.ts b/src/discord/monitor/provider.rest-proxy.test.ts index ec5e9ead9..17037b54f 100644 --- a/src/discord/monitor/provider.rest-proxy.test.ts +++ b/src/discord/monitor/provider.rest-proxy.test.ts @@ -27,6 +27,7 @@ describe("resolveDiscordRestFetch", () => { const runtime = { log: vi.fn(), error: vi.fn(), + exit: vi.fn(), } as const; undiciFetchMock.mockReset().mockResolvedValue(new Response("ok", { status: 200 })); proxyAgentSpy.mockReset(); @@ -51,6 +52,7 @@ describe("resolveDiscordRestFetch", () => { const runtime = { log: vi.fn(), error: vi.fn(), + exit: vi.fn(), } as const; const { __testing } = await import("./provider.js"); diff --git a/src/gateway/server.chat.gateway-server-chat.e2e.test.ts b/src/gateway/server.chat.gateway-server-chat.e2e.test.ts index 118aaf366..a2ab834f3 100644 --- a/src/gateway/server.chat.gateway-server-chat.e2e.test.ts +++ b/src/gateway/server.chat.gateway-server-chat.e2e.test.ts @@ -433,8 +433,8 @@ describe("gateway server chat", () => { const res = await waitP; expect(res.ok).toBe(true); - expect(res.payload.status).toBe("ok"); - expect(res.payload.startedAt).toBe(200); + expect(res.payload?.status).toBe("ok"); + expect(res.payload?.startedAt).toBe(200); } { @@ -449,8 +449,8 @@ describe("gateway server chat", () => { timeoutMs: 1000, }); expect(res.ok).toBe(true); - expect(res.payload.status).toBe("ok"); - expect(res.payload.startedAt).toBe(50); + expect(res.payload?.status).toBe("ok"); + expect(res.payload?.startedAt).toBe(50); } { @@ -459,7 +459,7 @@ describe("gateway server chat", () => { timeoutMs: 30, }); expect(res.ok).toBe(true); - expect(res.payload.status).toBe("timeout"); + expect(res.payload?.status).toBe("timeout"); } { @@ -478,8 +478,8 @@ describe("gateway server chat", () => { const res = await waitP; expect(res.ok).toBe(true); - expect(res.payload.status).toBe("error"); - expect(res.payload.error).toBe("boom"); + expect(res.payload?.status).toBe("error"); + expect(res.payload?.error).toBe("boom"); } { @@ -504,9 +504,9 @@ describe("gateway server chat", () => { const res = await waitP; expect(res.ok).toBe(true); - expect(res.payload.status).toBe("ok"); - expect(res.payload.startedAt).toBe(123); - expect(res.payload.endedAt).toBe(456); + expect(res.payload?.status).toBe("ok"); + expect(res.payload?.startedAt).toBe(123); + expect(res.payload?.endedAt).toBe(456); } } finally { webchatWs.close(); diff --git a/src/gateway/sessions-patch.test.ts b/src/gateway/sessions-patch.test.ts index a6f8059f4..cc54ceacd 100644 --- a/src/gateway/sessions-patch.test.ts +++ b/src/gateway/sessions-patch.test.ts @@ -10,7 +10,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { thinkingLevel: "off" }, + patch: { key: "agent:main:main", thinkingLevel: "off" }, }); expect(res.ok).toBe(true); if (!res.ok) { @@ -27,7 +27,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { thinkingLevel: null }, + patch: { key: "agent:main:main", thinkingLevel: null }, }); expect(res.ok).toBe(true); if (!res.ok) { @@ -42,7 +42,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { elevatedLevel: "off" }, + patch: { key: "agent:main:main", elevatedLevel: "off" }, }); expect(res.ok).toBe(true); if (!res.ok) { @@ -57,7 +57,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { elevatedLevel: "on" }, + patch: { key: "agent:main:main", elevatedLevel: "on" }, }); expect(res.ok).toBe(true); if (!res.ok) { @@ -74,7 +74,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { elevatedLevel: null }, + patch: { key: "agent:main:main", elevatedLevel: null }, }); expect(res.ok).toBe(true); if (!res.ok) { @@ -89,7 +89,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { elevatedLevel: "maybe" }, + patch: { key: "agent:main:main", elevatedLevel: "maybe" }, }); expect(res.ok).toBe(false); if (res.ok) { @@ -114,8 +114,8 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { model: "openai/gpt-5.2" }, - loadGatewayModelCatalog: async () => [{ provider: "openai", id: "gpt-5.2" }], + patch: { key: "agent:main:main", model: "openai/gpt-5.2" }, + loadGatewayModelCatalog: async () => [{ provider: "openai", id: "gpt-5.2", name: "gpt-5.2" }], }); expect(res.ok).toBe(true); if (!res.ok) { @@ -134,7 +134,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:subagent:child", - patch: { spawnDepth: 2 }, + patch: { key: "agent:main:subagent:child", spawnDepth: 2 }, }); expect(res.ok).toBe(true); if (!res.ok) { @@ -149,7 +149,7 @@ describe("gateway sessions patch", () => { cfg: {} as OpenClawConfig, store, storeKey: "agent:main:main", - patch: { spawnDepth: 1 }, + patch: { key: "agent:main:main", spawnDepth: 1 }, }); expect(res.ok).toBe(false); if (res.ok) { diff --git a/src/wizard/onboarding.completion.test.ts b/src/wizard/onboarding.completion.test.ts index 00c8ca288..031bad319 100644 --- a/src/wizard/onboarding.completion.test.ts +++ b/src/wizard/onboarding.completion.test.ts @@ -9,18 +9,19 @@ function createPrompter(confirmValue = false) { } function createDeps() { - return { + const deps: NonNullable[0]["deps"]> = { resolveCliName: () => "openclaw", - checkShellCompletionStatus: vi.fn(async () => ({ - shell: "zsh", + checkShellCompletionStatus: vi.fn(async (_binName: string) => ({ + shell: "zsh" as const, profileInstalled: false, cacheExists: false, cachePath: "/tmp/openclaw.zsh", usesSlowPattern: false, })), - ensureCompletionCacheExists: vi.fn(async () => true), + ensureCompletionCacheExists: vi.fn(async (_binName: string) => true), installCompletion: vi.fn(async () => {}), }; + return deps; } describe("setupOnboardingShellCompletion", () => { diff --git a/src/wizard/onboarding.gateway-config.test.ts b/src/wizard/onboarding.gateway-config.test.ts index dee6b236a..7e44e11cd 100644 --- a/src/wizard/onboarding.gateway-config.test.ts +++ b/src/wizard/onboarding.gateway-config.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; import type { RuntimeEnv } from "../runtime.js"; -import type { WizardPrompter } from "./prompts.js"; +import type { WizardPrompter, WizardSelectParams } from "./prompts.js"; const mocks = vi.hoisted(() => ({ randomToken: vi.fn(), @@ -24,12 +24,15 @@ describe("configureGatewayForOnboarding", () => { function createPrompter(params: { selectQueue: string[]; textQueue: Array }) { const selectQueue = [...params.selectQueue]; const textQueue = [...params.textQueue]; + const select = vi.fn( + async (_params: WizardSelectParams) => selectQueue.shift() as unknown, + ) as unknown as WizardPrompter["select"]; return { intro: vi.fn(async () => {}), outro: vi.fn(async () => {}), note: vi.fn(async () => {}), - select: vi.fn(async () => selectQueue.shift() as string), + select, multiselect: vi.fn(async () => []), text: vi.fn(async () => textQueue.shift() as string), confirm: vi.fn(async () => false), diff --git a/src/wizard/onboarding.test.ts b/src/wizard/onboarding.test.ts index e73fcea4f..7b9774413 100644 --- a/src/wizard/onboarding.test.ts +++ b/src/wizard/onboarding.test.ts @@ -5,7 +5,7 @@ import { afterAll, beforeAll, describe, expect, it, vi } from "vitest"; import { DEFAULT_BOOTSTRAP_FILENAME } from "../agents/workspace.js"; import type { RuntimeEnv } from "../runtime.js"; import { runOnboardingWizard } from "./onboarding.js"; -import type { WizardPrompter } from "./prompts.js"; +import type { WizardPrompter, WizardSelectParams } from "./prompts.js"; const ensureAuthProfileStore = vi.hoisted(() => vi.fn(() => ({ profiles: {} }))); const promptAuthChoiceGrouped = vi.hoisted(() => vi.fn(async () => "skip")); @@ -68,12 +68,23 @@ const healthCommand = vi.hoisted(() => vi.fn(async () => {})); const ensureWorkspaceAndSessions = vi.hoisted(() => vi.fn(async () => {})); const writeConfigFile = vi.hoisted(() => vi.fn(async () => {})); const readConfigFileSnapshot = vi.hoisted(() => - vi.fn(async () => ({ exists: false, valid: true, config: {} })), + vi.fn(async () => ({ + path: "/tmp/.openclaw/openclaw.json", + exists: false, + raw: null as string | null, + parsed: {}, + resolved: {}, + valid: true, + config: {}, + issues: [] as Array<{ path: string; message: string }>, + warnings: [] as Array<{ path: string; message: string }>, + legacyIssues: [] as Array<{ path: string; message: string }>, + })), ); const ensureSystemdUserLingerInteractive = vi.hoisted(() => vi.fn(async () => {})); const isSystemdUserServiceAvailable = vi.hoisted(() => vi.fn(async () => true)); const ensureControlUiAssetsBuilt = vi.hoisted(() => vi.fn(async () => ({ ok: true }))); -const runTui = vi.hoisted(() => vi.fn(async () => {})); +const runTui = vi.hoisted(() => vi.fn(async (_options: unknown) => {})); const setupOnboardingShellCompletion = vi.hoisted(() => vi.fn(async () => {})); vi.mock("../commands/onboard-channels.js", () => ({ @@ -184,11 +195,14 @@ vi.mock("./onboarding.completion.js", () => ({ })); function createWizardPrompter(overrides?: Partial): WizardPrompter { + const select = vi.fn( + async (_params: WizardSelectParams) => "quickstart", + ) as unknown as WizardPrompter["select"]; return { intro: vi.fn(async () => {}), outro: vi.fn(async () => {}), note: vi.fn(async () => {}), - select: vi.fn(async () => "quickstart"), + select, multiselect: vi.fn(async () => []), text: vi.fn(async () => ""), confirm: vi.fn(async () => false), @@ -241,13 +255,17 @@ describe("runOnboardingWizard", () => { exists: true, raw: "{}", parsed: {}, + resolved: {}, valid: false, config: {}, issues: [{ path: "routing.allowFrom", message: "Legacy key" }], + warnings: [], legacyIssues: [{ path: "routing.allowFrom", message: "Legacy key" }], }); - const select: WizardPrompter["select"] = vi.fn(async () => "quickstart"); + const select = vi.fn( + async (_params: WizardSelectParams) => "quickstart", + ) as unknown as WizardPrompter["select"]; const prompter = createWizardPrompter({ select }); const runtime = createRuntime({ throwsOnExit: true }); @@ -273,7 +291,9 @@ describe("runOnboardingWizard", () => { }); it("skips prompts and setup steps when flags are set", async () => { - const select: WizardPrompter["select"] = vi.fn(async () => "quickstart"); + const select = vi.fn( + async (_params: WizardSelectParams) => "quickstart", + ) as unknown as WizardPrompter["select"]; const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []); const prompter = createWizardPrompter({ select, multiselect }); const runtime = createRuntime({ throwsOnExit: true }); @@ -311,12 +331,12 @@ describe("runOnboardingWizard", () => { await fs.writeFile(path.join(workspaceDir, DEFAULT_BOOTSTRAP_FILENAME), "{}"); } - const select: WizardPrompter["select"] = vi.fn(async (opts) => { + const select = vi.fn(async (opts: WizardSelectParams) => { if (opts.message === "How do you want to hatch your bot?") { return "tui"; } return "quickstart"; - }); + }) as unknown as WizardPrompter["select"]; const prompter = createWizardPrompter({ select }); const runtime = createRuntime({ throwsOnExit: true });