test: clear rebased ci helper typing

This commit is contained in:
Peter Steinberger
2026-05-10 16:51:46 +01:00
parent f3ee9e26f9
commit a89634da59
11 changed files with 53 additions and 23 deletions

View File

@@ -7,6 +7,18 @@ import type { CoreConfig, ResolvedClickClackAccount } from "./types.js";
const sendClickClackTextMock = vi.hoisted(() => vi.fn());
type LlmCompleteMock = ReturnType<
typeof vi.fn<
(params: {
agentId?: string;
model?: string;
maxTokens?: number;
purpose?: string;
messages?: unknown[];
}) => Promise<unknown>
>
>;
vi.mock("./outbound.js", () => ({
sendClickClackText: sendClickClackTextMock,
}));
@@ -115,7 +127,7 @@ describe("handleClickClackInbound", () => {
expect(runtime.channel.turn.runPrepared).not.toHaveBeenCalled();
expect(runtime.agent.runEmbeddedPiAgent).not.toHaveBeenCalled();
const completionRequest = runtime.llm.complete.mock.calls[0]?.[0];
const completionRequest = (runtime.llm.complete as LlmCompleteMock).mock.calls[0]?.[0];
expect(completionRequest?.agentId).toBe("service-bot");
expect(completionRequest?.model).toBe("openai/gpt-5.4-mini");
expect(completionRequest?.maxTokens).toBe(96);

View File

@@ -624,7 +624,7 @@ function createMockBrowser(
options?: { boundingBox?: { x: number; y: number; width: number; height: number } },
) {
const browser = {
newPage: vi.fn(async () => {
newPage: vi.fn(async (_options?: unknown) => {
const page = createMockPage(options);
pages.push(page);
return page;

View File

@@ -88,7 +88,7 @@ describe("bridge/tools/remind", () => {
});
it("supports injected cron scheduler dependencies for engine-level tests", async () => {
const callCron = vi.fn(async () => ({ id: "job-1" }));
const callCron = vi.fn(async (_params: unknown) => ({ id: "job-1" }));
const tool = createRemindTool(
{
senderIsOwner: true,
@@ -118,7 +118,7 @@ describe("bridge/tools/remind", () => {
});
it("does not schedule when sender ownership is missing", async () => {
const callCron = vi.fn(async () => ({ id: "job-1" }));
const callCron = vi.fn(async (_params: unknown) => ({ id: "job-1" }));
const tool = createRemindTool(
{
deliveryContext: { to: "qqbot:c2c:user-openid", accountId: "bot2" },

View File

@@ -5,8 +5,6 @@ import { getWrittenQQBotConfig, installCommandRuntime } from "./slash-command-te
import { getFrameworkCommands, matchSlashCommand } from "./slash-commands-impl.js";
import { SlashCommandRegistry, type SlashCommandContext } from "./slash-commands.js";
type FrameworkCommand = ReturnType<typeof getFrameworkCommands>[number];
function createStreamingContext(overrides: Partial<SlashCommandContext> = {}): SlashCommandContext {
return {
type: "c2c",
@@ -66,8 +64,8 @@ describe("QQBot framework slash commands", () => {
expect(commands.map((command) => command.name)).toEqual(["private-admin", "shared-admin"]);
const privateAdmin = commands.find((command) => command.name === "private-admin");
const sharedAdmin = commands.find((command) => command.name === "shared-admin");
expect((privateAdmin as FrameworkCommand | undefined)?.c2cOnly).toBe(true);
expect((sharedAdmin as FrameworkCommand | undefined)?.c2cOnly).toBeUndefined();
expect(privateAdmin?.c2cOnly).toBe(true);
expect(sharedAdmin?.c2cOnly).toBeUndefined();
});
it("routes bot-streaming through the auth-gated framework registry", () => {

View File

@@ -7,7 +7,7 @@ const sendVoiceMessageMock = vi.hoisted(() =>
vi.fn(async () => ({ id: "voice-1", timestamp: "2026-04-25T00:00:00.000Z" })),
);
const sendMediaMock = vi.hoisted(() =>
vi.fn(async () => ({ id: "media-1", timestamp: "2026-04-25T00:00:00.000Z" })),
vi.fn(async (_params: unknown) => ({ id: "media-1", timestamp: "2026-04-25T00:00:00.000Z" })),
);
const sendTextMock = vi.hoisted(() =>
vi.fn(async () => ({ id: "text-1", timestamp: "2026-04-25T00:00:00.000Z" })),

View File

@@ -101,11 +101,17 @@ describe("searxng client", () => {
expect(result.provider).toBe("searxng");
expect(result.query).toBe("beijing hourly weather");
expect(result.count).toBe(1);
expect(result.results).toHaveLength(1);
expect(result.results[0]?.url).toBe("https://example.com/weather");
expect(result.results[0]?.siteName).toBe("example.com");
expect(result.results[0]?.title).toContain("Beijing hourly weather");
expect(result.results[0]?.snippet).toContain("Hourly forecast");
const results = result.results as Array<{
url?: string;
siteName?: string;
title?: string;
snippet?: string;
}>;
expect(results).toHaveLength(1);
expect(results[0]?.url).toBe("https://example.com/weather");
expect(results[0]?.siteName).toBe("example.com");
expect(results[0]?.title).toContain("Beijing hourly weather");
expect(results[0]?.snippet).toContain("Hourly forecast");
expect(result.externalContent).toEqual({
provider: "searxng",
source: "web_search",

View File

@@ -18,6 +18,13 @@ const { runTavilySearch, runTavilyExtract } = vi.hoisted(() => ({
runTavilyExtract: vi.fn(async (params: unknown) => ({ ok: true, params })),
}));
type TavilyExtractParams = {
cfg?: unknown;
urls?: string[];
query?: string;
chunksPerSource?: number;
};
vi.mock("./tavily-client.js", () => ({
runTavilySearch,
runTavilyExtract,
@@ -211,7 +218,7 @@ describe("tavily tools", () => {
const searchParams = runTavilySearch.mock.calls[0]?.[0];
expect(searchParams?.cfg).toBe(runtimeConfig);
expect(searchParams?.query).toBe("openclaw");
const extractParams = runTavilyExtract.mock.calls[0]?.[0];
const extractParams = runTavilyExtract.mock.calls[0]?.[0] as TavilyExtractParams | undefined;
expect(extractParams?.cfg).toBe(runtimeConfig);
expect(extractParams?.urls).toEqual(["https://example.com"]);
});
@@ -249,7 +256,7 @@ describe("tavily tools", () => {
chunks_per_source: 2,
});
const extractParams = runTavilyExtract.mock.calls[0]?.[0];
const extractParams = runTavilyExtract.mock.calls[0]?.[0] as TavilyExtractParams | undefined;
expect(extractParams?.cfg).toEqual({});
expect(extractParams?.urls).toEqual(["https://example.com"]);
expect(extractParams?.query).toBe("pricing");

View File

@@ -54,7 +54,7 @@ function makeGatewayService(
} as unknown as GatewayService;
}
function firstCallArg<T>(mock: { mock: { calls: unknown[][] } }): T {
function firstCallArg<T>(mock: { mock: { calls: unknown[][] } }, _type?: (value: T) => T): T {
const call = mock.mock.calls[0];
expect(call).toBeDefined();
return call?.[0] as T;

View File

@@ -627,7 +627,10 @@ describe("applyAuthChoice", () => {
expect(profile?.mode).toBe(expected.mode);
}
function promptMessages(mock: { mock: { calls: unknown[][] } }): string[] {
return mock.mock.calls.map((call) => String((call[0] as { message?: unknown })?.message ?? ""));
return mock.mock.calls.map((call) => {
const message = (call[0] as { message?: unknown }).message;
return typeof message === "string" ? message : "";
});
}
function expectPromptMessageContaining(mock: { mock: { calls: unknown[][] } }, expected: string) {
expect(promptMessages(mock).some((message) => message.includes(expected))).toBe(true);
@@ -635,7 +638,7 @@ describe("applyAuthChoice", () => {
function expectPromptMessage(mock: { mock: { calls: unknown[][] } }, expected: string) {
expect(promptMessages(mock)).toContain(expected);
}
function firstCallArg<T>(mock: { mock: { calls: unknown[][] } }): T {
function firstCallArg<T>(mock: { mock: { calls: unknown[][] } }, _type?: (value: T) => T): T {
const call = mock.mock.calls[0];
expect(call).toBeDefined();
return call?.[0] as T;

View File

@@ -175,7 +175,7 @@ test("sessions.reset emits enriched session_end and session_start hooks", async
expect(endEvent.sessionKey).toBe("agent:main:main");
expect(endEvent.reason).toBe("new");
expect(endEvent.transcriptArchived).toBe(true);
expect(String(endEvent.sessionFile ?? "")).toContain(".jsonl.reset.");
expect(endEvent.sessionFile).toEqual(expect.stringContaining(".jsonl.reset."));
expect(endEvent.nextSessionId).toBe(startEvent.sessionId);
expectMainHookContext(endContext, "sess-main");
expect(startEvent.sessionKey).toBe("agent:main:main");
@@ -371,7 +371,7 @@ test("sessions.create with emitCommandHooks=true emits reset lifecycle hooks aga
expect(startEvent.resumedFrom).toBe("sess-parent-hooks");
expect(startEvent.sessionId).toBeTypeOf("string");
expect(startEvent.sessionId).not.toBe("");
expect(String(startEvent.sessionKey ?? "")).toMatch(/^agent:main:dashboard:/);
expect(startEvent.sessionKey).toEqual(expect.stringMatching(/^agent:main:dashboard:/));
});
test("sessions.create with emitCommandHooks=true resets parent in place when session.dmScope is 'main' (#77434)", async () => {

View File

@@ -22,14 +22,18 @@ vi.mock("./channel-resolution.js", () => ({
resolveOutboundChannelMessageAdapter: resolveOutboundChannelMessageAdapterMock,
}));
function mockCallArg<T>(mock: { mock: { calls: unknown[][] } }, index = 0): T {
function mockCallArg<T>(
mock: { mock: { calls: unknown[][] } },
index = 0,
_type?: (value: T) => T,
): T {
const call = mock.mock.calls[index];
expect(call).toBeDefined();
return call[0] as T;
}
function expectMockMessageContaining(mock: { mock: { calls: unknown[][] } }, expected: string) {
const messages = mock.mock.calls.map((call) => String(call[0] ?? ""));
const messages = mock.mock.calls.map((call) => (typeof call[0] === "string" ? call[0] : ""));
expect(messages.some((message) => message.includes(expected))).toBe(true);
}