chore: Fix types in tests 29/N.
This commit is contained in:
@@ -49,7 +49,7 @@ describe("fetchBrowserJson loopback auth", () => {
|
||||
});
|
||||
|
||||
it("adds bearer auth for loopback absolute HTTP URLs", async () => {
|
||||
const fetchMock = vi.fn(
|
||||
const fetchMock = vi.fn<(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>>(
|
||||
async () =>
|
||||
new Response(JSON.stringify({ ok: true }), {
|
||||
status: 200,
|
||||
@@ -61,13 +61,13 @@ describe("fetchBrowserJson loopback auth", () => {
|
||||
const res = await fetchBrowserJson<{ ok: boolean }>("http://127.0.0.1:18888/");
|
||||
expect(res.ok).toBe(true);
|
||||
|
||||
const init = fetchMock.mock.calls[0]?.[1] as RequestInit;
|
||||
const init = fetchMock.mock.calls[0]?.[1];
|
||||
const headers = new Headers(init?.headers);
|
||||
expect(headers.get("authorization")).toBe("Bearer loopback-token");
|
||||
});
|
||||
|
||||
it("does not inject auth for non-loopback absolute URLs", async () => {
|
||||
const fetchMock = vi.fn(
|
||||
const fetchMock = vi.fn<(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>>(
|
||||
async () =>
|
||||
new Response(JSON.stringify({ ok: true }), {
|
||||
status: 200,
|
||||
@@ -78,13 +78,13 @@ describe("fetchBrowserJson loopback auth", () => {
|
||||
|
||||
await fetchBrowserJson<{ ok: boolean }>("http://example.com/");
|
||||
|
||||
const init = fetchMock.mock.calls[0]?.[1] as RequestInit;
|
||||
const init = fetchMock.mock.calls[0]?.[1];
|
||||
const headers = new Headers(init?.headers);
|
||||
expect(headers.get("authorization")).toBeNull();
|
||||
});
|
||||
|
||||
it("keeps caller-supplied auth header", async () => {
|
||||
const fetchMock = vi.fn(
|
||||
const fetchMock = vi.fn<(input: RequestInfo | URL, init?: RequestInit) => Promise<Response>>(
|
||||
async () =>
|
||||
new Response(JSON.stringify({ ok: true }), {
|
||||
status: 200,
|
||||
@@ -99,7 +99,7 @@ describe("fetchBrowserJson loopback auth", () => {
|
||||
},
|
||||
});
|
||||
|
||||
const init = fetchMock.mock.calls[0]?.[1] as RequestInit;
|
||||
const init = fetchMock.mock.calls[0]?.[1];
|
||||
const headers = new Headers(init?.headers);
|
||||
expect(headers.get("authorization")).toBe("Bearer caller-token");
|
||||
});
|
||||
|
||||
@@ -51,7 +51,7 @@ describe("pw-tools-core", () => {
|
||||
});
|
||||
|
||||
const res = await p;
|
||||
const outPath = vi.mocked(saveAs).mock.calls[0]?.[0];
|
||||
const outPath = (vi.mocked(saveAs).mock.calls as unknown as Array<[string]>)[0]?.[0];
|
||||
return { res, outPath };
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ describe("server-context hot-reload profiles", () => {
|
||||
const resolved = resolveBrowserConfig(cfg.browser, cfg);
|
||||
|
||||
// Verify cache is primed (without desktop)
|
||||
expect(cfg.browser.profiles.desktop).toBeUndefined();
|
||||
expect(cfg.browser?.profiles?.desktop).toBeUndefined();
|
||||
const state = {
|
||||
server: null,
|
||||
port: 18791,
|
||||
@@ -79,7 +79,7 @@ describe("server-context hot-reload profiles", () => {
|
||||
|
||||
// 3. Verify without clearConfigCache, loadConfig() still returns stale cached value
|
||||
const staleCfg = loadConfig();
|
||||
expect(staleCfg.browser.profiles.desktop).toBeUndefined(); // Cache is stale!
|
||||
expect(staleCfg.browser?.profiles?.desktop).toBeUndefined(); // Cache is stale!
|
||||
|
||||
// 4. Hot-reload should read fresh config for the lookup (createConfigIO().loadConfig()),
|
||||
// without flushing the global loadConfig cache.
|
||||
@@ -97,7 +97,7 @@ describe("server-context hot-reload profiles", () => {
|
||||
// 6. Verify GLOBAL cache was NOT cleared - subsequent simple loadConfig() still sees STALE value
|
||||
// This confirms the fix: we read fresh config for the specific profile lookup without flushing the global cache
|
||||
const stillStaleCfg = loadConfig();
|
||||
expect(stillStaleCfg.browser.profiles.desktop).toBeUndefined();
|
||||
expect(stillStaleCfg.browser?.profiles?.desktop).toBeUndefined();
|
||||
});
|
||||
|
||||
it("forProfile still throws for profiles that don't exist in fresh config", async () => {
|
||||
|
||||
@@ -27,6 +27,8 @@ function makeState(
|
||||
cdpIsLoopback: profile !== "remote",
|
||||
remoteCdpTimeoutMs: 1500,
|
||||
remoteCdpHandshakeTimeoutMs: 3000,
|
||||
evaluateEnabled: false,
|
||||
extraArgs: [],
|
||||
color: "#FF4500",
|
||||
headless: true,
|
||||
noSandbox: false,
|
||||
@@ -62,7 +64,7 @@ describe("browser server-context remote profile tab operations", () => {
|
||||
listPagesViaPlaywright,
|
||||
createPageViaPlaywright,
|
||||
closePageByTargetIdViaPlaywright,
|
||||
} as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
} as unknown as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
|
||||
const fetchMock = vi.fn(async () => {
|
||||
throw new Error("unexpected fetch");
|
||||
@@ -127,7 +129,7 @@ describe("browser server-context remote profile tab operations", () => {
|
||||
closePageByTargetIdViaPlaywright: vi.fn(async () => {
|
||||
throw new Error("unexpected close");
|
||||
}),
|
||||
} as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
} as unknown as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
|
||||
const fetchMock = vi.fn(async () => {
|
||||
throw new Error("unexpected fetch");
|
||||
@@ -154,7 +156,7 @@ describe("browser server-context remote profile tab operations", () => {
|
||||
vi.spyOn(pwAiModule, "getPwAiModule").mockResolvedValue({
|
||||
listPagesViaPlaywright,
|
||||
focusPageByTargetIdViaPlaywright,
|
||||
} as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
} as unknown as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
|
||||
const fetchMock = vi.fn(async () => {
|
||||
throw new Error("unexpected fetch");
|
||||
@@ -180,7 +182,7 @@ describe("browser server-context remote profile tab operations", () => {
|
||||
listPagesViaPlaywright: vi.fn(async () => {
|
||||
throw new Error("boom");
|
||||
}),
|
||||
} as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
} as unknown as Awaited<ReturnType<typeof pwAiModule.getPwAiModule>>);
|
||||
|
||||
const fetchMock = vi.fn(async () => {
|
||||
throw new Error("unexpected fetch");
|
||||
|
||||
@@ -43,7 +43,7 @@ function mockConfig(
|
||||
home: string,
|
||||
storePath: string,
|
||||
agentOverrides?: Partial<NonNullable<NonNullable<OpenClawConfig["agents"]>["defaults"]>>,
|
||||
telegramOverrides?: Partial<NonNullable<OpenClawConfig["telegram"]>>,
|
||||
telegramOverrides?: Partial<NonNullable<NonNullable<OpenClawConfig["channels"]>["telegram"]>>,
|
||||
agentsList?: Array<{ id: string; default?: boolean }>,
|
||||
) {
|
||||
configSpy.mockReturnValue({
|
||||
@@ -57,7 +57,9 @@ function mockConfig(
|
||||
list: agentsList,
|
||||
},
|
||||
session: { store: storePath, mainKey: "main" },
|
||||
telegram: telegramOverrides ? { ...telegramOverrides } : undefined,
|
||||
channels: {
|
||||
telegram: telegramOverrides ? { ...telegramOverrides } : undefined,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -342,7 +344,7 @@ describe("agentCommand", () => {
|
||||
|
||||
await agentCommand({ message: "hi", to: "+1999", json: true }, runtime);
|
||||
|
||||
const logged = (runtime.log as MockInstance).mock.calls.at(-1)?.[0] as string;
|
||||
const logged = (runtime.log as unknown as MockInstance).mock.calls.at(-1)?.[0] as string;
|
||||
const parsed = JSON.parse(logged) as {
|
||||
payloads: Array<{ text: string; mediaUrl?: string | null }>;
|
||||
meta: { durationMs: number };
|
||||
@@ -376,6 +378,7 @@ describe("agentCommand", () => {
|
||||
const deps = {
|
||||
sendMessageWhatsApp: vi.fn(),
|
||||
sendMessageTelegram: vi.fn().mockResolvedValue({ messageId: "t1", chatId: "123" }),
|
||||
sendMessageSlack: vi.fn(),
|
||||
sendMessageDiscord: vi.fn(),
|
||||
sendMessageSignal: vi.fn(),
|
||||
sendMessageIMessage: vi.fn(),
|
||||
|
||||
@@ -29,22 +29,22 @@ vi.mock("../web/session.js", () => ({
|
||||
webAuthExists,
|
||||
}));
|
||||
|
||||
const handleDiscordAction = vi.fn(async () => ({ details: { ok: true } }));
|
||||
const handleDiscordAction = vi.fn(async (..._args: unknown[]) => ({ details: { ok: true } }));
|
||||
vi.mock("../agents/tools/discord-actions.js", () => ({
|
||||
handleDiscordAction,
|
||||
}));
|
||||
|
||||
const handleSlackAction = vi.fn(async () => ({ details: { ok: true } }));
|
||||
const handleSlackAction = vi.fn(async (..._args: unknown[]) => ({ details: { ok: true } }));
|
||||
vi.mock("../agents/tools/slack-actions.js", () => ({
|
||||
handleSlackAction,
|
||||
}));
|
||||
|
||||
const handleTelegramAction = vi.fn(async () => ({ details: { ok: true } }));
|
||||
const handleTelegramAction = vi.fn(async (..._args: unknown[]) => ({ details: { ok: true } }));
|
||||
vi.mock("../agents/tools/telegram-actions.js", () => ({
|
||||
handleTelegramAction,
|
||||
}));
|
||||
|
||||
const handleWhatsAppAction = vi.fn(async () => ({ details: { ok: true } }));
|
||||
const handleWhatsAppAction = vi.fn(async (..._args: unknown[]) => ({ details: { ok: true } }));
|
||||
vi.mock("../agents/tools/whatsapp-actions.js", () => ({
|
||||
handleWhatsAppAction,
|
||||
}));
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import type { OAuthCredentials } from "@mariozechner/pi-ai";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import {
|
||||
applyAuthProfileConfig,
|
||||
applyLitellmProviderConfig,
|
||||
@@ -36,12 +37,12 @@ import {
|
||||
|
||||
function createLegacyProviderConfig(params: {
|
||||
providerId: string;
|
||||
api: string;
|
||||
api: "anthropic-messages" | "openai-completions" | "openai-responses";
|
||||
modelId?: string;
|
||||
modelName?: string;
|
||||
baseUrl?: string;
|
||||
apiKey?: string;
|
||||
}) {
|
||||
}): OpenClawConfig {
|
||||
return {
|
||||
models: {
|
||||
providers: {
|
||||
@@ -63,7 +64,7 @@ function createLegacyProviderConfig(params: {
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
const EXPECTED_FALLBACKS = ["anthropic/claude-opus-4-5"] as const;
|
||||
|
||||
@@ -115,7 +115,7 @@ describe("resolveChannelCapabilities", () => {
|
||||
capabilities: { inlineButtons: "dm" },
|
||||
},
|
||||
},
|
||||
};
|
||||
} as unknown as Partial<OpenClawConfig>;
|
||||
|
||||
// Should return undefined (not crash), allowing channel-specific handlers to process it.
|
||||
expect(
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { migrateLegacyConfig, validateConfigObject } from "./config.js";
|
||||
|
||||
function getLegacyRouting(config: unknown) {
|
||||
return (config as { routing?: Record<string, unknown> } | undefined)?.routing;
|
||||
}
|
||||
|
||||
describe("legacy config detection", () => {
|
||||
it("rejects routing.allowFrom", async () => {
|
||||
const res = validateConfigObject({
|
||||
@@ -27,7 +31,7 @@ describe("legacy config detection", () => {
|
||||
});
|
||||
expect(res.changes).toContain("Moved routing.allowFrom → channels.whatsapp.allowFrom.");
|
||||
expect(res.config?.channels?.whatsapp?.allowFrom).toEqual(["+15555550123"]);
|
||||
expect(res.config?.routing?.allowFrom).toBeUndefined();
|
||||
expect(getLegacyRouting(res.config)?.allowFrom).toBeUndefined();
|
||||
});
|
||||
it("drops routing.allowFrom when whatsapp missing", async () => {
|
||||
const res = migrateLegacyConfig({
|
||||
@@ -35,7 +39,7 @@ describe("legacy config detection", () => {
|
||||
});
|
||||
expect(res.changes).toContain("Removed routing.allowFrom (channels.whatsapp not configured).");
|
||||
expect(res.config?.channels?.whatsapp).toBeUndefined();
|
||||
expect(res.config?.routing?.allowFrom).toBeUndefined();
|
||||
expect(getLegacyRouting(res.config)?.allowFrom).toBeUndefined();
|
||||
});
|
||||
it("migrates routing.groupChat.requireMention to channels whatsapp/telegram/imessage groups when whatsapp configured", async () => {
|
||||
const res = migrateLegacyConfig({
|
||||
@@ -54,7 +58,7 @@ describe("legacy config detection", () => {
|
||||
expect(res.config?.channels?.whatsapp?.groups?.["*"]?.requireMention).toBe(false);
|
||||
expect(res.config?.channels?.telegram?.groups?.["*"]?.requireMention).toBe(false);
|
||||
expect(res.config?.channels?.imessage?.groups?.["*"]?.requireMention).toBe(false);
|
||||
expect(res.config?.routing?.groupChat?.requireMention).toBeUndefined();
|
||||
expect(getLegacyRouting(res.config)?.groupChat).toBeUndefined();
|
||||
});
|
||||
it("migrates routing.groupChat.requireMention to telegram/imessage when whatsapp missing", async () => {
|
||||
const res = migrateLegacyConfig({
|
||||
@@ -72,7 +76,7 @@ describe("legacy config detection", () => {
|
||||
expect(res.config?.channels?.whatsapp).toBeUndefined();
|
||||
expect(res.config?.channels?.telegram?.groups?.["*"]?.requireMention).toBe(false);
|
||||
expect(res.config?.channels?.imessage?.groups?.["*"]?.requireMention).toBe(false);
|
||||
expect(res.config?.routing?.groupChat?.requireMention).toBeUndefined();
|
||||
expect(getLegacyRouting(res.config)?.groupChat).toBeUndefined();
|
||||
});
|
||||
it("migrates routing.groupChat.mentionPatterns to messages.groupChat.mentionPatterns", async () => {
|
||||
const res = migrateLegacyConfig({
|
||||
@@ -82,7 +86,7 @@ describe("legacy config detection", () => {
|
||||
"Moved routing.groupChat.mentionPatterns → messages.groupChat.mentionPatterns.",
|
||||
);
|
||||
expect(res.config?.messages?.groupChat?.mentionPatterns).toEqual(["@openclaw"]);
|
||||
expect(res.config?.routing?.groupChat?.mentionPatterns).toBeUndefined();
|
||||
expect(getLegacyRouting(res.config)?.groupChat).toBeUndefined();
|
||||
});
|
||||
it("migrates routing agentToAgent/queue/transcribeAudio to tools/messages/media", async () => {
|
||||
const res = migrateLegacyConfig({
|
||||
@@ -117,7 +121,7 @@ describe("legacy config detection", () => {
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(res.config?.routing).toBeUndefined();
|
||||
expect(getLegacyRouting(res.config)).toBeUndefined();
|
||||
});
|
||||
it("migrates audio.transcription with custom script names", async () => {
|
||||
const res = migrateLegacyConfig({
|
||||
|
||||
@@ -65,7 +65,17 @@ describe("applyModelDefaults", () => {
|
||||
baseUrl: "https://proxy.example/v1",
|
||||
apiKey: "sk-test",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "gpt-5.2", name: "GPT-5.2" }],
|
||||
models: [
|
||||
{
|
||||
id: "gpt-5.2",
|
||||
name: "GPT-5.2",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 200_000,
|
||||
maxTokens: 8192,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -86,8 +96,20 @@ describe("applyModelDefaults", () => {
|
||||
models: {
|
||||
providers: {
|
||||
myproxy: {
|
||||
baseUrl: "https://proxy.example/v1",
|
||||
apiKey: "sk-test",
|
||||
api: "openai-completions",
|
||||
models: [{ id: "gpt-5.2", name: "GPT-5.2", contextWindow: 32768, maxTokens: 40960 }],
|
||||
models: [
|
||||
{
|
||||
id: "gpt-5.2",
|
||||
name: "GPT-5.2",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 32768,
|
||||
maxTokens: 40960,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@ function makeSnapshot<TConfig extends Record<string, unknown>>(
|
||||
issues: [],
|
||||
warnings: [],
|
||||
legacyIssues: [],
|
||||
} as TestSnapshot<TConfig>;
|
||||
} as unknown as TestSnapshot<TConfig>;
|
||||
}
|
||||
|
||||
function restoreRedactedValues<TOriginal>(
|
||||
|
||||
@@ -151,7 +151,7 @@ describe("resolveCronSession", () => {
|
||||
updatedAt: Date.now() - 1000,
|
||||
modelOverride: "some-model",
|
||||
},
|
||||
} as ReturnType<typeof loadSessionStore>);
|
||||
} as unknown as ReturnType<typeof loadSessionStore>);
|
||||
vi.mocked(evaluateSessionFreshness).mockReturnValue({ fresh: true });
|
||||
|
||||
const result = resolveCronSession({
|
||||
|
||||
Reference in New Issue
Block a user