mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
chore: Fix types in tests 38/N.
This commit is contained in:
@@ -7,10 +7,15 @@ function createLimiterSpy(): AuthRateLimiter & {
|
||||
recordFailure: ReturnType<typeof vi.fn>;
|
||||
reset: ReturnType<typeof vi.fn>;
|
||||
} {
|
||||
const check = vi.fn<AuthRateLimiter["check"]>(
|
||||
(_ip, _scope) => ({ allowed: true, remaining: 10, retryAfterMs: 0 }) as const,
|
||||
);
|
||||
const recordFailure = vi.fn<AuthRateLimiter["recordFailure"]>((_ip, _scope) => {});
|
||||
const reset = vi.fn<AuthRateLimiter["reset"]>((_ip, _scope) => {});
|
||||
return {
|
||||
check: vi.fn(() => ({ allowed: true, remaining: 10, retryAfterMs: 0 })),
|
||||
recordFailure: vi.fn(),
|
||||
reset: vi.fn(),
|
||||
check,
|
||||
recordFailure,
|
||||
reset,
|
||||
size: () => 0,
|
||||
prune: () => {},
|
||||
dispose: () => {},
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { SessionScope } from "../config/sessions/types.js";
|
||||
|
||||
const agentCommand = vi.fn();
|
||||
|
||||
@@ -14,7 +15,12 @@ const { resolveStorePath } = await import("../config/sessions/paths.js");
|
||||
const { loadSessionStore, saveSessionStore } = await import("../config/sessions/store.js");
|
||||
|
||||
describe("runBootOnce", () => {
|
||||
const resolveMainStore = (cfg: { session?: { store?: string } } = {}) => {
|
||||
const resolveMainStore = (
|
||||
cfg: {
|
||||
session?: { store?: string; scope?: SessionScope; mainKey?: string };
|
||||
agents?: { list?: Array<{ id?: string; default?: boolean }> };
|
||||
} = {},
|
||||
) => {
|
||||
const sessionKey = resolveMainSessionKey(cfg);
|
||||
const agentId = resolveAgentIdFromSessionKey(sessionKey);
|
||||
const storePath = resolveStorePath(cfg.session?.store, { agentId });
|
||||
|
||||
@@ -7,6 +7,7 @@ import { parseModelRef } from "../agents/model-selection.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import { getFreePortBlockWithPermissionFallback } from "../test-utils/ports.js";
|
||||
import { GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||
import { GatewayClient } from "./client.js";
|
||||
import { renderCatNoncePngBase64 } from "./live-image-probe.js";
|
||||
import { startGatewayServer } from "./server.js";
|
||||
@@ -144,7 +145,7 @@ async function connectClient(params: { url: string; token: string }) {
|
||||
const client = new GatewayClient({
|
||||
url: params.url,
|
||||
token: params.token,
|
||||
clientName: "vitest-live-cli-backend",
|
||||
clientName: GATEWAY_CLIENT_NAMES.TEST,
|
||||
clientVersion: "dev",
|
||||
mode: "test",
|
||||
onHelloOk: () => stop(undefined, client),
|
||||
|
||||
@@ -36,11 +36,10 @@ describe("GatewayClient", () => {
|
||||
wsMockState.last = null;
|
||||
const client = new GatewayClient({ url: "ws://127.0.0.1:1" });
|
||||
client.start();
|
||||
const last = wsMockState.last as { url: unknown; opts: unknown } | null;
|
||||
|
||||
expect(wsMockState.last?.url).toBe("ws://127.0.0.1:1");
|
||||
expect(wsMockState.last?.opts).toEqual(
|
||||
expect.objectContaining({ maxPayload: 25 * 1024 * 1024 }),
|
||||
);
|
||||
expect(last?.url).toBe("ws://127.0.0.1:1");
|
||||
expect(last?.opts).toEqual(expect.objectContaining({ maxPayload: 25 * 1024 * 1024 }));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -153,7 +152,8 @@ describe("late-arriving invoke results", () => {
|
||||
context,
|
||||
});
|
||||
|
||||
const [ok, payload, error] = respond.mock.lastCall ?? [];
|
||||
const [ok, rawPayload, error] = respond.mock.lastCall ?? [];
|
||||
const payload = rawPayload as { ok?: boolean; ignored?: boolean } | undefined;
|
||||
|
||||
// Late-arriving results return success instead of error to reduce log noise.
|
||||
expect(ok).toBe(true);
|
||||
|
||||
@@ -22,7 +22,7 @@ import { getApiKeyForModel } from "../agents/model-auth.js";
|
||||
import { ensureOpenClawModelsJson } from "../agents/models-config.js";
|
||||
import { discoverAuthStorage, discoverModels } from "../agents/pi-model-discovery.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import type { OpenClawConfig, ModelProviderConfig } from "../config/types.js";
|
||||
import type { ModelsConfig, OpenClawConfig, ModelProviderConfig } from "../config/types.js";
|
||||
import { isTruthyEnvValue } from "../infra/env.js";
|
||||
import { DEFAULT_AGENT_ID } from "../routing/session-key.js";
|
||||
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../utils/message-channel.js";
|
||||
@@ -401,6 +401,7 @@ function buildLiveGatewayConfig(params: {
|
||||
...providerOverrides,
|
||||
};
|
||||
const providers = Object.keys(nextProviders).length > 0 ? nextProviders : baseProviders;
|
||||
const baseModels = params.cfg.models;
|
||||
return {
|
||||
...params.cfg,
|
||||
agents: {
|
||||
@@ -418,7 +419,9 @@ function buildLiveGatewayConfig(params: {
|
||||
},
|
||||
},
|
||||
models:
|
||||
Object.keys(providers).length > 0 ? { ...params.cfg.models, providers } : params.cfg.models,
|
||||
Object.keys(providers).length > 0
|
||||
? ({ ...baseModels, providers } as ModelsConfig)
|
||||
: baseModels,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1149,10 +1152,10 @@ describeLive("gateway live (dev agent, profile keys)", () => {
|
||||
await fs.writeFile(toolProbePath, `nonceA=${nonceA}\nnonceB=${nonceB}\n`);
|
||||
|
||||
const port = await getFreeGatewayPort();
|
||||
const server = await startGatewayServer({
|
||||
configPath: cfg.__meta?.path,
|
||||
port,
|
||||
token,
|
||||
const server = await startGatewayServer(port, {
|
||||
bind: "loopback",
|
||||
auth: { mode: "token", token },
|
||||
controlUiEnabled: false,
|
||||
});
|
||||
|
||||
const client = await connectClient({
|
||||
|
||||
@@ -109,7 +109,7 @@ describe("hooks mapping", () => {
|
||||
],
|
||||
});
|
||||
expect(result?.ok).toBe(true);
|
||||
if (result?.ok && result.action.kind === "agent") {
|
||||
if (result?.ok && result.action && result.action.kind === "agent") {
|
||||
expect(result.action.model).toBe("openai/gpt-4.1-mini");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -126,7 +126,8 @@ function createErrnoError(code: string) {
|
||||
}
|
||||
|
||||
function mockWorkspaceStateRead(params: { onboardingCompletedAt?: string; errorCode?: string }) {
|
||||
mocks.fsReadFile.mockImplementation(async (filePath: string | URL | number) => {
|
||||
mocks.fsReadFile.mockImplementation(async (...args: unknown[]) => {
|
||||
const filePath = args[0];
|
||||
if (String(filePath).endsWith("workspace-state.json")) {
|
||||
if (params.errorCode) {
|
||||
throw createErrnoError(params.errorCode);
|
||||
|
||||
@@ -107,6 +107,9 @@ describe("chat abort transcript persistence", () => {
|
||||
params: { sessionKey: "main", runId },
|
||||
respond,
|
||||
context: context as never,
|
||||
req: {} as never,
|
||||
client: null,
|
||||
isWebchatConnect: () => false,
|
||||
});
|
||||
|
||||
const [ok1, payload1] = respond.mock.calls.at(-1) ?? [];
|
||||
@@ -121,6 +124,9 @@ describe("chat abort transcript persistence", () => {
|
||||
params: { sessionKey: "main", runId },
|
||||
respond,
|
||||
context: context as never,
|
||||
req: {} as never,
|
||||
client: null,
|
||||
isWebchatConnect: () => false,
|
||||
});
|
||||
|
||||
const lines = await readTranscriptLines(transcriptPath);
|
||||
@@ -178,6 +184,9 @@ describe("chat abort transcript persistence", () => {
|
||||
params: { sessionKey: "main" },
|
||||
respond,
|
||||
context: context as never,
|
||||
req: {} as never,
|
||||
client: null,
|
||||
isWebchatConnect: () => false,
|
||||
});
|
||||
|
||||
const [ok, payload] = respond.mock.calls.at(-1) ?? [];
|
||||
@@ -235,7 +244,9 @@ describe("chat abort transcript persistence", () => {
|
||||
},
|
||||
respond,
|
||||
context: context as never,
|
||||
client: undefined,
|
||||
req: {} as never,
|
||||
client: null,
|
||||
isWebchatConnect: () => false,
|
||||
});
|
||||
|
||||
const [ok, payload] = respond.mock.calls.at(-1) ?? [];
|
||||
|
||||
@@ -26,7 +26,7 @@ describe("gateway chat.inject transcript writes", () => {
|
||||
);
|
||||
|
||||
vi.doMock("../session-utils.js", async (importOriginal) => {
|
||||
const original = await importOriginal();
|
||||
const original = await importOriginal<typeof import("../session-utils.js")>();
|
||||
return {
|
||||
...original,
|
||||
loadSessionEntry: () => ({
|
||||
@@ -50,7 +50,10 @@ describe("gateway chat.inject transcript writes", () => {
|
||||
await chatHandlers["chat.inject"]({
|
||||
params: { sessionKey: "k1", message: "hello" },
|
||||
respond,
|
||||
context,
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: context as unknown as GatewayRequestContext,
|
||||
});
|
||||
|
||||
expect(respond).toHaveBeenCalled();
|
||||
|
||||
@@ -28,6 +28,10 @@ describe("skills.update", () => {
|
||||
skillKey: "brave-search",
|
||||
apiKey: "abc\r\ndef",
|
||||
},
|
||||
req: {} as never,
|
||||
client: null as never,
|
||||
isWebchatConnect: () => false,
|
||||
context: {} as never,
|
||||
respond: (success, _result, err) => {
|
||||
ok = success;
|
||||
error = err;
|
||||
|
||||
@@ -106,7 +106,9 @@ describe("sessions.usage", () => {
|
||||
|
||||
expect(respond).toHaveBeenCalledTimes(1);
|
||||
expect(respond.mock.calls[0]?.[0]).toBe(true);
|
||||
const result = respond.mock.calls[0]?.[1] as unknown as { sessions: Array<unknown> };
|
||||
const result = respond.mock.calls[0]?.[1] as unknown as {
|
||||
sessions: Array<{ key: string; agentId: string }>;
|
||||
};
|
||||
expect(result.sessions).toHaveLength(2);
|
||||
|
||||
// Sorted by most recent first (mtime=200 -> opus first).
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
|
||||
vi.mock("../../infra/session-cost-usage.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("../../infra/session-cost-usage.js")>(
|
||||
@@ -63,7 +64,7 @@ describe("gateway usage helpers", () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-02-05T00:00:00.000Z"));
|
||||
|
||||
const config = {} as unknown as ReturnType<import("../../config/config.js").loadConfig>;
|
||||
const config = {} as OpenClawConfig;
|
||||
const a = await __test.loadCostUsageSummaryCached({
|
||||
startMs: 1,
|
||||
endMs: 2,
|
||||
|
||||
@@ -15,6 +15,7 @@ const createRegistry = (diagnostics: PluginDiagnostic[]): PluginRegistry => ({
|
||||
hooks: [],
|
||||
typedHooks: [],
|
||||
channels: [],
|
||||
commands: [],
|
||||
providers: [],
|
||||
gatewayHandlers: {},
|
||||
httpHandlers: [],
|
||||
|
||||
@@ -306,9 +306,14 @@ describe("gateway server agent", () => {
|
||||
|
||||
const ack = await ackP;
|
||||
const final = await finalP;
|
||||
expect(ack.payload.runId).toBeDefined();
|
||||
expect(final.payload.runId).toBe(ack.payload.runId);
|
||||
expect(final.payload.status).toBe("ok");
|
||||
const ackPayload = ack.payload;
|
||||
const finalPayload = final.payload;
|
||||
if (!ackPayload || !finalPayload) {
|
||||
throw new Error("missing websocket payload");
|
||||
}
|
||||
expect(ackPayload.runId).toBeDefined();
|
||||
expect(finalPayload.runId).toBe(ackPayload.runId);
|
||||
expect(finalPayload.status).toBe("ok");
|
||||
});
|
||||
|
||||
test("agent dedupes by idempotencyKey after completion", async () => {
|
||||
|
||||
@@ -63,6 +63,7 @@ async function withCanvasGatewayHarness(params: {
|
||||
const canvasWss = new WebSocketServer({ noServer: true });
|
||||
const canvasHost: CanvasHostHandler = {
|
||||
rootDir: "test",
|
||||
basePath: "/canvas",
|
||||
close: async () => {},
|
||||
handleUpgrade: (req, socket, head) => {
|
||||
const url = new URL(req.url ?? "/", "http://localhost");
|
||||
|
||||
@@ -270,7 +270,7 @@ describe("gateway server chat", () => {
|
||||
test("smoke: supports abort and idempotent completion", async () => {
|
||||
const tempDirs: string[] = [];
|
||||
const { server, ws } = await startServerWithClient();
|
||||
const spy = vi.mocked(getReplyFromConfig);
|
||||
const spy = vi.mocked(getReplyFromConfig) as unknown as ReturnType<typeof vi.fn>;
|
||||
let aborted = false;
|
||||
|
||||
try {
|
||||
|
||||
@@ -44,10 +44,10 @@ describe("gateway config.apply", () => {
|
||||
},
|
||||
}),
|
||||
);
|
||||
const res = await onceMessage<{ ok: boolean; error?: { message?: string } }>(
|
||||
ws,
|
||||
(o) => o.type === "res" && o.id === id,
|
||||
);
|
||||
const res = await onceMessage<{ ok: boolean; error?: { message?: string } }>(ws, (o) => {
|
||||
const msg = o as { type?: string; id?: string };
|
||||
return msg.type === "res" && msg.id === id;
|
||||
});
|
||||
expect(res.ok).toBe(false);
|
||||
expect(res.error?.message ?? "").toMatch(/invalid|SyntaxError/i);
|
||||
} finally {
|
||||
@@ -69,10 +69,10 @@ describe("gateway config.apply", () => {
|
||||
},
|
||||
}),
|
||||
);
|
||||
const res = await onceMessage<{ ok: boolean; error?: { message?: string } }>(
|
||||
ws,
|
||||
(o) => o.type === "res" && o.id === id,
|
||||
);
|
||||
const res = await onceMessage<{ ok: boolean; error?: { message?: string } }>(ws, (o) => {
|
||||
const msg = o as { type?: string; id?: string };
|
||||
return msg.type === "res" && msg.id === id;
|
||||
});
|
||||
expect(res.ok).toBe(false);
|
||||
expect(res.error?.message ?? "").toContain("raw");
|
||||
} finally {
|
||||
|
||||
@@ -561,7 +561,7 @@ describe("gateway server cron", () => {
|
||||
await yieldToEventLoop();
|
||||
expect(fetchMock).toHaveBeenCalledTimes(2);
|
||||
|
||||
cronIsolatedRun.mockResolvedValueOnce({ status: "ok" });
|
||||
cronIsolatedRun.mockResolvedValueOnce({ status: "ok", summary: "" });
|
||||
const noSummaryRes = await rpcReq(ws, "cron.add", {
|
||||
name: "webhook no summary",
|
||||
enabled: true,
|
||||
|
||||
@@ -268,10 +268,11 @@ describe("node.invoke approval bypass", () => {
|
||||
});
|
||||
expect(invoke.ok).toBe(true);
|
||||
|
||||
expect(lastInvokeParams).toBeTruthy();
|
||||
expect(lastInvokeParams?.approved).toBe(true);
|
||||
expect(lastInvokeParams?.approvalDecision).toBe("allow-once");
|
||||
expect(lastInvokeParams?.injected).toBeUndefined();
|
||||
const invokeParams = lastInvokeParams as Record<string, unknown> | null;
|
||||
expect(invokeParams).toBeTruthy();
|
||||
expect(invokeParams?.["approved"]).toBe(true);
|
||||
expect(invokeParams?.["approvalDecision"]).toBe("allow-once");
|
||||
expect(invokeParams?.["injected"]).toBeUndefined();
|
||||
|
||||
ws.close();
|
||||
ws2.close();
|
||||
|
||||
Reference in New Issue
Block a user